babylon.camera.js 34 KB

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