babylon.camera.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. var __extends = (this && this.__extends) || function (d, b) {
  2. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  3. function __() { this.constructor = d; }
  4. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5. };
  6. var BABYLON;
  7. (function (BABYLON) {
  8. var VRCameraMetrics = (function () {
  9. function VRCameraMetrics() {
  10. this.compensateDistortion = true;
  11. }
  12. Object.defineProperty(VRCameraMetrics.prototype, "aspectRatio", {
  13. get: function () {
  14. return this.hResolution / (2 * this.vResolution);
  15. },
  16. enumerable: true,
  17. configurable: true
  18. });
  19. Object.defineProperty(VRCameraMetrics.prototype, "aspectRatioFov", {
  20. get: function () {
  21. return (2 * Math.atan((this.postProcessScaleFactor * this.vScreenSize) / (2 * this.eyeToScreenDistance)));
  22. },
  23. enumerable: true,
  24. configurable: true
  25. });
  26. Object.defineProperty(VRCameraMetrics.prototype, "leftHMatrix", {
  27. get: function () {
  28. var meters = (this.hScreenSize / 4) - (this.lensSeparationDistance / 2);
  29. var h = (4 * meters) / this.hScreenSize;
  30. return BABYLON.Matrix.Translation(h, 0, 0);
  31. },
  32. enumerable: true,
  33. configurable: true
  34. });
  35. Object.defineProperty(VRCameraMetrics.prototype, "rightHMatrix", {
  36. get: function () {
  37. var meters = (this.hScreenSize / 4) - (this.lensSeparationDistance / 2);
  38. var h = (4 * meters) / this.hScreenSize;
  39. return BABYLON.Matrix.Translation(-h, 0, 0);
  40. },
  41. enumerable: true,
  42. configurable: true
  43. });
  44. Object.defineProperty(VRCameraMetrics.prototype, "leftPreViewMatrix", {
  45. get: function () {
  46. return BABYLON.Matrix.Translation(0.5 * this.interpupillaryDistance, 0, 0);
  47. },
  48. enumerable: true,
  49. configurable: true
  50. });
  51. Object.defineProperty(VRCameraMetrics.prototype, "rightPreViewMatrix", {
  52. get: function () {
  53. return BABYLON.Matrix.Translation(-0.5 * this.interpupillaryDistance, 0, 0);
  54. },
  55. enumerable: true,
  56. configurable: true
  57. });
  58. VRCameraMetrics.GetDefault = function () {
  59. var result = new VRCameraMetrics();
  60. result.hResolution = 1280;
  61. result.vResolution = 800;
  62. result.hScreenSize = 0.149759993;
  63. result.vScreenSize = 0.0935999975;
  64. result.vScreenCenter = 0.0467999987,
  65. result.eyeToScreenDistance = 0.0410000011;
  66. result.lensSeparationDistance = 0.0635000020;
  67. result.interpupillaryDistance = 0.0640000030;
  68. result.distortionK = [1.0, 0.219999999, 0.239999995, 0.0];
  69. result.chromaAbCorrection = [0.995999992, -0.00400000019, 1.01400006, 0.0];
  70. result.postProcessScaleFactor = 1.714605507808412;
  71. result.lensCenterOffset = 0.151976421;
  72. return result;
  73. };
  74. return VRCameraMetrics;
  75. })();
  76. BABYLON.VRCameraMetrics = VRCameraMetrics;
  77. var Camera = (function (_super) {
  78. __extends(Camera, _super);
  79. function Camera(name, position, scene) {
  80. _super.call(this, name, scene);
  81. this.position = position;
  82. // Members
  83. this.upVector = BABYLON.Vector3.Up();
  84. this.orthoLeft = null;
  85. this.orthoRight = null;
  86. this.orthoBottom = null;
  87. this.orthoTop = null;
  88. this.fov = 0.8;
  89. this.minZ = 1.0;
  90. this.maxZ = 10000.0;
  91. this.inertia = 0.9;
  92. this.mode = Camera.PERSPECTIVE_CAMERA;
  93. this.isIntermediate = false;
  94. this.viewport = new BABYLON.Viewport(0, 0, 1.0, 1.0);
  95. this.layerMask = 0x0FFFFFFF;
  96. this.fovMode = Camera.FOVMODE_VERTICAL_FIXED;
  97. // Camera rig members
  98. this.cameraRigMode = Camera.RIG_MODE_NONE;
  99. this._rigCameras = new Array();
  100. // Cache
  101. this._computedViewMatrix = BABYLON.Matrix.Identity();
  102. this._projectionMatrix = new BABYLON.Matrix();
  103. this._postProcesses = new Array();
  104. this._postProcessesTakenIndices = [];
  105. this._activeMeshes = new BABYLON.SmartArray(256);
  106. this._globalPosition = BABYLON.Vector3.Zero();
  107. scene.addCamera(this);
  108. if (!scene.activeCamera) {
  109. scene.activeCamera = this;
  110. }
  111. }
  112. Object.defineProperty(Camera, "PERSPECTIVE_CAMERA", {
  113. get: function () {
  114. return Camera._PERSPECTIVE_CAMERA;
  115. },
  116. enumerable: true,
  117. configurable: true
  118. });
  119. Object.defineProperty(Camera, "ORTHOGRAPHIC_CAMERA", {
  120. get: function () {
  121. return Camera._ORTHOGRAPHIC_CAMERA;
  122. },
  123. enumerable: true,
  124. configurable: true
  125. });
  126. Object.defineProperty(Camera, "FOVMODE_VERTICAL_FIXED", {
  127. get: function () {
  128. return Camera._FOVMODE_VERTICAL_FIXED;
  129. },
  130. enumerable: true,
  131. configurable: true
  132. });
  133. Object.defineProperty(Camera, "FOVMODE_HORIZONTAL_FIXED", {
  134. get: function () {
  135. return Camera._FOVMODE_HORIZONTAL_FIXED;
  136. },
  137. enumerable: true,
  138. configurable: true
  139. });
  140. Object.defineProperty(Camera, "RIG_MODE_NONE", {
  141. get: function () {
  142. return Camera._RIG_MODE_NONE;
  143. },
  144. enumerable: true,
  145. configurable: true
  146. });
  147. Object.defineProperty(Camera, "RIG_MODE_STEREOSCOPIC_ANAGLYPH", {
  148. get: function () {
  149. return Camera._RIG_MODE_STEREOSCOPIC_ANAGLYPH;
  150. },
  151. enumerable: true,
  152. configurable: true
  153. });
  154. Object.defineProperty(Camera, "RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL", {
  155. get: function () {
  156. return Camera._RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL;
  157. },
  158. enumerable: true,
  159. configurable: true
  160. });
  161. Object.defineProperty(Camera, "RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED", {
  162. get: function () {
  163. return Camera._RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;
  164. },
  165. enumerable: true,
  166. configurable: true
  167. });
  168. Object.defineProperty(Camera, "RIG_MODE_STEREOSCOPIC_OVERUNDER", {
  169. get: function () {
  170. return Camera._RIG_MODE_STEREOSCOPIC_OVERUNDER;
  171. },
  172. enumerable: true,
  173. configurable: true
  174. });
  175. Object.defineProperty(Camera, "RIG_MODE_VR", {
  176. get: function () {
  177. return Camera._RIG_MODE_VR;
  178. },
  179. enumerable: true,
  180. configurable: true
  181. });
  182. Object.defineProperty(Camera.prototype, "globalPosition", {
  183. get: function () {
  184. return this._globalPosition;
  185. },
  186. enumerable: true,
  187. configurable: true
  188. });
  189. Camera.prototype.getActiveMeshes = function () {
  190. return this._activeMeshes;
  191. };
  192. Camera.prototype.isActiveMesh = function (mesh) {
  193. return (this._activeMeshes.indexOf(mesh) !== -1);
  194. };
  195. //Cache
  196. Camera.prototype._initCache = function () {
  197. _super.prototype._initCache.call(this);
  198. this._cache.position = new BABYLON.Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
  199. this._cache.upVector = new BABYLON.Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
  200. this._cache.mode = undefined;
  201. this._cache.minZ = undefined;
  202. this._cache.maxZ = undefined;
  203. this._cache.fov = undefined;
  204. this._cache.aspectRatio = undefined;
  205. this._cache.orthoLeft = undefined;
  206. this._cache.orthoRight = undefined;
  207. this._cache.orthoBottom = undefined;
  208. this._cache.orthoTop = undefined;
  209. this._cache.renderWidth = undefined;
  210. this._cache.renderHeight = undefined;
  211. };
  212. Camera.prototype._updateCache = function (ignoreParentClass) {
  213. if (!ignoreParentClass) {
  214. _super.prototype._updateCache.call(this);
  215. }
  216. var engine = this.getEngine();
  217. this._cache.position.copyFrom(this.position);
  218. this._cache.upVector.copyFrom(this.upVector);
  219. this._cache.mode = this.mode;
  220. this._cache.minZ = this.minZ;
  221. this._cache.maxZ = this.maxZ;
  222. this._cache.fov = this.fov;
  223. this._cache.aspectRatio = engine.getAspectRatio(this);
  224. this._cache.orthoLeft = this.orthoLeft;
  225. this._cache.orthoRight = this.orthoRight;
  226. this._cache.orthoBottom = this.orthoBottom;
  227. this._cache.orthoTop = this.orthoTop;
  228. this._cache.renderWidth = engine.getRenderWidth();
  229. this._cache.renderHeight = engine.getRenderHeight();
  230. };
  231. Camera.prototype._updateFromScene = function () {
  232. this.updateCache();
  233. this._update();
  234. };
  235. // Synchronized
  236. Camera.prototype._isSynchronized = function () {
  237. return this._isSynchronizedViewMatrix() && this._isSynchronizedProjectionMatrix();
  238. };
  239. Camera.prototype._isSynchronizedViewMatrix = function () {
  240. if (!_super.prototype._isSynchronized.call(this))
  241. return false;
  242. return this._cache.position.equals(this.position)
  243. && this._cache.upVector.equals(this.upVector)
  244. && this.isSynchronizedWithParent();
  245. };
  246. Camera.prototype._isSynchronizedProjectionMatrix = function () {
  247. var check = this._cache.mode === this.mode
  248. && this._cache.minZ === this.minZ
  249. && this._cache.maxZ === this.maxZ;
  250. if (!check) {
  251. return false;
  252. }
  253. var engine = this.getEngine();
  254. if (this.mode === Camera.PERSPECTIVE_CAMERA) {
  255. check = this._cache.fov === this.fov
  256. && this._cache.aspectRatio === engine.getAspectRatio(this);
  257. }
  258. else {
  259. check = this._cache.orthoLeft === this.orthoLeft
  260. && this._cache.orthoRight === this.orthoRight
  261. && this._cache.orthoBottom === this.orthoBottom
  262. && this._cache.orthoTop === this.orthoTop
  263. && this._cache.renderWidth === engine.getRenderWidth()
  264. && this._cache.renderHeight === engine.getRenderHeight();
  265. }
  266. return check;
  267. };
  268. // Controls
  269. Camera.prototype.attachControl = function (element) {
  270. };
  271. Camera.prototype.detachControl = function (element) {
  272. };
  273. Camera.prototype._update = function () {
  274. if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {
  275. this._updateRigCameras();
  276. }
  277. this._checkInputs();
  278. };
  279. Camera.prototype._checkInputs = function () {
  280. };
  281. Camera.prototype.attachPostProcess = function (postProcess, insertAt) {
  282. if (insertAt === void 0) { insertAt = null; }
  283. if (!postProcess.isReusable() && this._postProcesses.indexOf(postProcess) > -1) {
  284. BABYLON.Tools.Error("You're trying to reuse a post process not defined as reusable.");
  285. return 0;
  286. }
  287. if (insertAt == null || insertAt < 0) {
  288. this._postProcesses.push(postProcess);
  289. this._postProcessesTakenIndices.push(this._postProcesses.length - 1);
  290. return this._postProcesses.length - 1;
  291. }
  292. var add = 0;
  293. var i;
  294. var start;
  295. if (this._postProcesses[insertAt]) {
  296. start = this._postProcesses.length - 1;
  297. for (i = start; i >= insertAt + 1; --i) {
  298. this._postProcesses[i + 1] = this._postProcesses[i];
  299. }
  300. add = 1;
  301. }
  302. for (i = 0; i < this._postProcessesTakenIndices.length; ++i) {
  303. if (this._postProcessesTakenIndices[i] < insertAt) {
  304. continue;
  305. }
  306. start = this._postProcessesTakenIndices.length - 1;
  307. for (var j = start; j >= i; --j) {
  308. this._postProcessesTakenIndices[j + 1] = this._postProcessesTakenIndices[j] + add;
  309. }
  310. this._postProcessesTakenIndices[i] = insertAt;
  311. break;
  312. }
  313. if (!add && this._postProcessesTakenIndices.indexOf(insertAt) === -1) {
  314. this._postProcessesTakenIndices.push(insertAt);
  315. }
  316. var result = insertAt + add;
  317. this._postProcesses[result] = postProcess;
  318. return result;
  319. };
  320. Camera.prototype.detachPostProcess = function (postProcess, atIndices) {
  321. if (atIndices === void 0) { atIndices = null; }
  322. var result = [];
  323. var i;
  324. var index;
  325. if (!atIndices) {
  326. var length = this._postProcesses.length;
  327. for (i = 0; i < length; i++) {
  328. if (this._postProcesses[i] !== postProcess) {
  329. continue;
  330. }
  331. delete this._postProcesses[i];
  332. index = this._postProcessesTakenIndices.indexOf(i);
  333. this._postProcessesTakenIndices.splice(index, 1);
  334. }
  335. }
  336. else {
  337. atIndices = (atIndices instanceof Array) ? atIndices : [atIndices];
  338. for (i = 0; i < atIndices.length; i++) {
  339. var foundPostProcess = this._postProcesses[atIndices[i]];
  340. if (foundPostProcess !== postProcess) {
  341. result.push(i);
  342. continue;
  343. }
  344. delete this._postProcesses[atIndices[i]];
  345. index = this._postProcessesTakenIndices.indexOf(atIndices[i]);
  346. this._postProcessesTakenIndices.splice(index, 1);
  347. }
  348. }
  349. return result;
  350. };
  351. Camera.prototype.getWorldMatrix = function () {
  352. if (!this._worldMatrix) {
  353. this._worldMatrix = BABYLON.Matrix.Identity();
  354. }
  355. var viewMatrix = this.getViewMatrix();
  356. viewMatrix.invertToRef(this._worldMatrix);
  357. return this._worldMatrix;
  358. };
  359. Camera.prototype._getViewMatrix = function () {
  360. return BABYLON.Matrix.Identity();
  361. };
  362. Camera.prototype.getViewMatrix = function (force) {
  363. this._computedViewMatrix = this._computeViewMatrix(force);
  364. if (!force && this._isSynchronizedViewMatrix()) {
  365. return this._computedViewMatrix;
  366. }
  367. if (!this.parent || !this.parent.getWorldMatrix) {
  368. this._globalPosition.copyFrom(this.position);
  369. }
  370. else {
  371. if (!this._worldMatrix) {
  372. this._worldMatrix = BABYLON.Matrix.Identity();
  373. }
  374. this._computedViewMatrix.invertToRef(this._worldMatrix);
  375. this._worldMatrix.multiplyToRef(this.parent.getWorldMatrix(), this._computedViewMatrix);
  376. this._globalPosition.copyFromFloats(this._computedViewMatrix.m[12], this._computedViewMatrix.m[13], this._computedViewMatrix.m[14]);
  377. this._computedViewMatrix.invert();
  378. this._markSyncedWithParent();
  379. }
  380. this._currentRenderId = this.getScene().getRenderId();
  381. return this._computedViewMatrix;
  382. };
  383. Camera.prototype._computeViewMatrix = function (force) {
  384. if (!force && this._isSynchronizedViewMatrix()) {
  385. return this._computedViewMatrix;
  386. }
  387. this._computedViewMatrix = this._getViewMatrix();
  388. this._currentRenderId = this.getScene().getRenderId();
  389. return this._computedViewMatrix;
  390. };
  391. Camera.prototype.getProjectionMatrix = function (force) {
  392. if (!force && this._isSynchronizedProjectionMatrix()) {
  393. return this._projectionMatrix;
  394. }
  395. var engine = this.getEngine();
  396. if (this.mode === Camera.PERSPECTIVE_CAMERA) {
  397. if (this.minZ <= 0) {
  398. this.minZ = 0.1;
  399. }
  400. BABYLON.Matrix.PerspectiveFovLHToRef(this.fov, engine.getAspectRatio(this), this.minZ, this.maxZ, this._projectionMatrix, this.fovMode);
  401. return this._projectionMatrix;
  402. }
  403. var halfWidth = engine.getRenderWidth() / 2.0;
  404. var halfHeight = engine.getRenderHeight() / 2.0;
  405. BABYLON.Matrix.OrthoOffCenterLHToRef(this.orthoLeft || -halfWidth, this.orthoRight || halfWidth, this.orthoBottom || -halfHeight, this.orthoTop || halfHeight, this.minZ, this.maxZ, this._projectionMatrix);
  406. return this._projectionMatrix;
  407. };
  408. Camera.prototype.dispose = function () {
  409. // Animations
  410. this.getScene().stopAnimation(this);
  411. // Remove from scene
  412. this.getScene().removeCamera(this);
  413. while (this._rigCameras.length > 0) {
  414. this._rigCameras.pop().dispose();
  415. }
  416. // Postprocesses
  417. for (var i = 0; i < this._postProcessesTakenIndices.length; ++i) {
  418. this._postProcesses[this._postProcessesTakenIndices[i]].dispose(this);
  419. }
  420. };
  421. // ---- Camera rigs section ----
  422. Camera.prototype.setCameraRigMode = function (mode, rigParams) {
  423. while (this._rigCameras.length > 0) {
  424. this._rigCameras.pop().dispose();
  425. }
  426. this.cameraRigMode = mode;
  427. this._cameraRigParams = {};
  428. switch (this.cameraRigMode) {
  429. case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
  430. case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
  431. case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
  432. case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
  433. this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
  434. //we have to implement stereo camera calcultating left and right viewpoints from interaxialDistance and target,
  435. //not from a given angle as it is now, but until that complete code rewriting provisional stereoHalfAngle value is introduced
  436. this._cameraRigParams.stereoHalfAngle = BABYLON.Tools.ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
  437. this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
  438. this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
  439. break;
  440. }
  441. var postProcesses = new Array();
  442. switch (this.cameraRigMode) {
  443. case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
  444. postProcesses.push(new BABYLON.PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[0]));
  445. this._rigCameras[0].isIntermediate = true;
  446. postProcesses.push(new BABYLON.AnaglyphPostProcess(this.name + "_anaglyph", 1.0, this._rigCameras[1]));
  447. postProcesses[1].onApply = function (effect) {
  448. effect.setTextureFromPostProcess("leftSampler", postProcesses[0]);
  449. };
  450. break;
  451. case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
  452. case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
  453. case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
  454. var isStereoscopicHoriz = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED);
  455. var firstCamIndex = (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : 0;
  456. var secondCamIndex = 1 - firstCamIndex;
  457. postProcesses.push(new BABYLON.PassPostProcess(this.name + "_passthru", 1.0, this._rigCameras[firstCamIndex]));
  458. this._rigCameras[firstCamIndex].isIntermediate = true;
  459. postProcesses.push(new BABYLON.StereoscopicInterlacePostProcess(this.name + "_stereoInterlace", this._rigCameras[secondCamIndex], postProcesses[0], isStereoscopicHoriz));
  460. break;
  461. case Camera.RIG_MODE_VR:
  462. this._rigCameras.push(this.createRigCamera(this.name + "_L", 0));
  463. this._rigCameras.push(this.createRigCamera(this.name + "_R", 1));
  464. var metrics = rigParams.vrCameraMetrics || VRCameraMetrics.GetDefault();
  465. this._rigCameras[0]._cameraRigParams.vrMetrics = metrics;
  466. this._rigCameras[0].viewport = new BABYLON.Viewport(0, 0, 0.5, 1.0);
  467. this._rigCameras[0]._cameraRigParams.vrWorkMatrix = new BABYLON.Matrix();
  468. this._rigCameras[0]._cameraRigParams.vrHMatrix = metrics.leftHMatrix;
  469. this._rigCameras[0]._cameraRigParams.vrPreViewMatrix = metrics.leftPreViewMatrix;
  470. this._rigCameras[0].getProjectionMatrix = this._rigCameras[0]._getVRProjectionMatrix;
  471. if (metrics.compensateDistortion) {
  472. postProcesses.push(new BABYLON.VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Left", this._rigCameras[0], false, metrics));
  473. }
  474. this._rigCameras[1]._cameraRigParams.vrMetrics = this._rigCameras[0]._cameraRigParams.vrMetrics;
  475. this._rigCameras[1].viewport = new BABYLON.Viewport(0.5, 0, 0.5, 1.0);
  476. this._rigCameras[1]._cameraRigParams.vrWorkMatrix = new BABYLON.Matrix();
  477. this._rigCameras[1]._cameraRigParams.vrHMatrix = metrics.rightHMatrix;
  478. this._rigCameras[1]._cameraRigParams.vrPreViewMatrix = metrics.rightPreViewMatrix;
  479. this._rigCameras[1].getProjectionMatrix = this._rigCameras[1]._getVRProjectionMatrix;
  480. if (metrics.compensateDistortion) {
  481. postProcesses.push(new BABYLON.VRDistortionCorrectionPostProcess("VR_Distort_Compensation_Right", this._rigCameras[1], true, metrics));
  482. }
  483. break;
  484. }
  485. this._update();
  486. };
  487. Camera.prototype._getVRProjectionMatrix = function () {
  488. BABYLON.Matrix.PerspectiveFovLHToRef(this._cameraRigParams.vrMetrics.aspectRatioFov, this._cameraRigParams.vrMetrics.aspectRatio, this.minZ, this.maxZ, this._cameraRigParams.vrWorkMatrix);
  489. this._cameraRigParams.vrWorkMatrix.multiplyToRef(this._cameraRigParams.vrHMatrix, this._projectionMatrix);
  490. return this._projectionMatrix;
  491. };
  492. Camera.prototype.setCameraRigParameter = function (name, value) {
  493. this._cameraRigParams[name] = value;
  494. //provisionnally:
  495. if (name === "interaxialDistance") {
  496. this._cameraRigParams.stereoHalfAngle = BABYLON.Tools.ToRadians(value / 0.0637);
  497. }
  498. };
  499. /**
  500. * May needs to be overridden by children so sub has required properties to be copied
  501. */
  502. Camera.prototype.createRigCamera = function (name, cameraIndex) {
  503. return null;
  504. };
  505. /**
  506. * May needs to be overridden by children
  507. */
  508. Camera.prototype._updateRigCameras = function () {
  509. for (var i = 0; i < this._rigCameras.length; i++) {
  510. this._rigCameras[i].minZ = this.minZ;
  511. this._rigCameras[i].maxZ = this.maxZ;
  512. this._rigCameras[i].fov = this.fov;
  513. }
  514. // only update viewport when ANAGLYPH
  515. if (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH) {
  516. this._rigCameras[0].viewport = this._rigCameras[1].viewport = this.viewport;
  517. }
  518. };
  519. Camera.prototype.serialize = function () {
  520. var serializationObject = {};
  521. serializationObject.name = this.name;
  522. serializationObject.tags = BABYLON.Tags.GetTags(this);
  523. serializationObject.id = this.id;
  524. serializationObject.position = this.position.asArray();
  525. // Parent
  526. if (this.parent) {
  527. serializationObject.parentId = this.parent.id;
  528. }
  529. serializationObject.fov = this.fov;
  530. serializationObject.minZ = this.minZ;
  531. serializationObject.maxZ = this.maxZ;
  532. serializationObject.inertia = this.inertia;
  533. // Animations
  534. BABYLON.Animation.AppendSerializedAnimations(this, serializationObject);
  535. serializationObject.ranges = this.serializeAnimationRanges();
  536. // Layer mask
  537. serializationObject.layerMask = this.layerMask;
  538. return serializationObject;
  539. };
  540. Camera.Parse = function (parsedCamera, scene) {
  541. var camera;
  542. var position = BABYLON.Vector3.FromArray(parsedCamera.position);
  543. var lockedTargetMesh = (parsedCamera.lockedTargetId) ? scene.getLastMeshByID(parsedCamera.lockedTargetId) : null;
  544. var interaxial_distance;
  545. if (parsedCamera.type === "AnaglyphArcRotateCamera" || parsedCamera.type === "ArcRotateCamera") {
  546. var alpha = parsedCamera.alpha;
  547. var beta = parsedCamera.beta;
  548. var radius = parsedCamera.radius;
  549. if (parsedCamera.type === "AnaglyphArcRotateCamera") {
  550. interaxial_distance = parsedCamera.interaxial_distance;
  551. camera = new BABYLON.AnaglyphArcRotateCamera(parsedCamera.name, alpha, beta, radius, lockedTargetMesh, interaxial_distance, scene);
  552. }
  553. else {
  554. camera = new BABYLON.ArcRotateCamera(parsedCamera.name, alpha, beta, radius, lockedTargetMesh, scene);
  555. }
  556. }
  557. else if (parsedCamera.type === "AnaglyphFreeCamera") {
  558. interaxial_distance = parsedCamera.interaxial_distance;
  559. camera = new BABYLON.AnaglyphFreeCamera(parsedCamera.name, position, interaxial_distance, scene);
  560. }
  561. else if (parsedCamera.type === "DeviceOrientationCamera") {
  562. camera = new BABYLON.DeviceOrientationCamera(parsedCamera.name, position, scene);
  563. }
  564. else if (parsedCamera.type === "FollowCamera") {
  565. camera = new BABYLON.FollowCamera(parsedCamera.name, position, scene);
  566. camera.heightOffset = parsedCamera.heightOffset;
  567. camera.radius = parsedCamera.radius;
  568. camera.rotationOffset = parsedCamera.rotationOffset;
  569. if (lockedTargetMesh)
  570. camera.target = lockedTargetMesh;
  571. }
  572. else if (parsedCamera.type === "GamepadCamera") {
  573. camera = new BABYLON.GamepadCamera(parsedCamera.name, position, scene);
  574. }
  575. else if (parsedCamera.type === "TouchCamera") {
  576. camera = new BABYLON.TouchCamera(parsedCamera.name, position, scene);
  577. }
  578. else if (parsedCamera.type === "VirtualJoysticksCamera") {
  579. camera = new BABYLON.VirtualJoysticksCamera(parsedCamera.name, position, scene);
  580. }
  581. else if (parsedCamera.type === "WebVRFreeCamera") {
  582. camera = new BABYLON.WebVRFreeCamera(parsedCamera.name, position, scene);
  583. }
  584. else if (parsedCamera.type === "VRDeviceOrientationFreeCamera") {
  585. camera = new BABYLON.VRDeviceOrientationFreeCamera(parsedCamera.name, position, scene);
  586. }
  587. else if (parsedCamera.type === "FreeCamera") {
  588. camera = new BABYLON.UniversalCamera(parsedCamera.name, position, scene); // Forcing Universal here
  589. }
  590. else {
  591. // Universal Camera is the default value
  592. camera = new BABYLON.UniversalCamera(parsedCamera.name, position, scene);
  593. }
  594. // apply 3d rig, when found
  595. if (parsedCamera.cameraRigMode) {
  596. var rigParams = (parsedCamera.interaxial_distance) ? { interaxialDistance: parsedCamera.interaxial_distance } : {};
  597. camera.setCameraRigMode(parsedCamera.cameraRigMode, rigParams);
  598. }
  599. // Test for lockedTargetMesh & FreeCamera outside of if-else-if nest, since things like GamepadCamera extend FreeCamera
  600. if (lockedTargetMesh && camera instanceof BABYLON.FreeCamera) {
  601. camera.lockedTarget = lockedTargetMesh;
  602. }
  603. camera.id = parsedCamera.id;
  604. BABYLON.Tags.AddTagsTo(camera, parsedCamera.tags);
  605. // Parent
  606. if (parsedCamera.parentId) {
  607. camera._waitingParentId = parsedCamera.parentId;
  608. }
  609. // Target
  610. if (parsedCamera.target) {
  611. if (camera.setTarget) {
  612. camera.setTarget(BABYLON.Vector3.FromArray(parsedCamera.target));
  613. }
  614. else {
  615. //For ArcRotate
  616. camera.target = BABYLON.Vector3.FromArray(parsedCamera.target);
  617. }
  618. }
  619. else {
  620. camera.rotation = BABYLON.Vector3.FromArray(parsedCamera.rotation);
  621. }
  622. camera.fov = parsedCamera.fov;
  623. camera.minZ = parsedCamera.minZ;
  624. camera.maxZ = parsedCamera.maxZ;
  625. camera.speed = parsedCamera.speed;
  626. camera.inertia = parsedCamera.inertia;
  627. camera.checkCollisions = parsedCamera.checkCollisions;
  628. camera.applyGravity = parsedCamera.applyGravity;
  629. if (parsedCamera.ellipsoid) {
  630. camera.ellipsoid = BABYLON.Vector3.FromArray(parsedCamera.ellipsoid);
  631. }
  632. // Animations
  633. if (parsedCamera.animations) {
  634. for (var animationIndex = 0; animationIndex < parsedCamera.animations.length; animationIndex++) {
  635. var parsedAnimation = parsedCamera.animations[animationIndex];
  636. camera.animations.push(BABYLON.Animation.Parse(parsedAnimation));
  637. }
  638. BABYLON.Node.ParseAnimationRanges(camera, parsedCamera, scene);
  639. }
  640. if (parsedCamera.autoAnimate) {
  641. scene.beginAnimation(camera, parsedCamera.autoAnimateFrom, parsedCamera.autoAnimateTo, parsedCamera.autoAnimateLoop, 1.0);
  642. }
  643. // Layer Mask
  644. if (parsedCamera.layerMask && (!isNaN(parsedCamera.layerMask))) {
  645. camera.layerMask = Math.abs(parseInt(parsedCamera.layerMask));
  646. }
  647. else {
  648. camera.layerMask = 0x0FFFFFFF;
  649. }
  650. return camera;
  651. };
  652. // Statics
  653. Camera._PERSPECTIVE_CAMERA = 0;
  654. Camera._ORTHOGRAPHIC_CAMERA = 1;
  655. Camera._FOVMODE_VERTICAL_FIXED = 0;
  656. Camera._FOVMODE_HORIZONTAL_FIXED = 1;
  657. Camera._RIG_MODE_NONE = 0;
  658. Camera._RIG_MODE_STEREOSCOPIC_ANAGLYPH = 10;
  659. Camera._RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL = 11;
  660. Camera._RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED = 12;
  661. Camera._RIG_MODE_STEREOSCOPIC_OVERUNDER = 13;
  662. Camera._RIG_MODE_VR = 20;
  663. return Camera;
  664. })(BABYLON.Node);
  665. BABYLON.Camera = Camera;
  666. })(BABYLON || (BABYLON = {}));