babylon.abstractMesh.js 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  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 AbstractMesh = (function (_super) {
  9. __extends(AbstractMesh, _super);
  10. // Constructor
  11. function AbstractMesh(name, scene) {
  12. var _this = this;
  13. _super.call(this, name, scene);
  14. // Events
  15. /**
  16. * An event triggered when the mesh is disposed.
  17. * @type {BABYLON.Observable}
  18. */
  19. this.onDisposeObservable = new BABYLON.Observable();
  20. /**
  21. * An event triggered when this mesh collides with another one
  22. * @type {BABYLON.Observable}
  23. */
  24. this.onCollideObservable = new BABYLON.Observable();
  25. /**
  26. * An event triggered when the collision's position changes
  27. * @type {BABYLON.Observable}
  28. */
  29. this.onCollisionPositionChangeObservable = new BABYLON.Observable();
  30. /**
  31. * An event triggered after the world matrix is updated
  32. * @type {BABYLON.Observable}
  33. */
  34. this.onAfterWorldMatrixUpdateObservable = new BABYLON.Observable();
  35. // Properties
  36. this.definedFacingForward = true; // orientation for POV movement & rotation
  37. this.position = new BABYLON.Vector3(0, 0, 0);
  38. this._rotation = new BABYLON.Vector3(0, 0, 0);
  39. this._scaling = new BABYLON.Vector3(1, 1, 1);
  40. this.billboardMode = AbstractMesh.BILLBOARDMODE_NONE;
  41. this.visibility = 1.0;
  42. this.alphaIndex = Number.MAX_VALUE;
  43. this.infiniteDistance = false;
  44. this.isVisible = true;
  45. this.isPickable = true;
  46. this.showBoundingBox = false;
  47. this.showSubMeshesBoundingBox = false;
  48. this.isBlocker = false;
  49. this.renderingGroupId = 0;
  50. this.receiveShadows = false;
  51. this.renderOutline = false;
  52. this.outlineColor = BABYLON.Color3.Red();
  53. this.outlineWidth = 0.02;
  54. this.renderOverlay = false;
  55. this.overlayColor = BABYLON.Color3.Red();
  56. this.overlayAlpha = 0.5;
  57. this.hasVertexAlpha = false;
  58. this.useVertexColors = true;
  59. this.applyFog = true;
  60. this.computeBonesUsingShaders = true;
  61. this.scalingDeterminant = 1;
  62. this.numBoneInfluencers = 4;
  63. this.useOctreeForRenderingSelection = true;
  64. this.useOctreeForPicking = true;
  65. this.useOctreeForCollisions = true;
  66. this.layerMask = 0x0FFFFFFF;
  67. this.alwaysSelectAsActiveMesh = false;
  68. // Collisions
  69. this._checkCollisions = false;
  70. this.ellipsoid = new BABYLON.Vector3(0.5, 1, 0.5);
  71. this.ellipsoidOffset = new BABYLON.Vector3(0, 0, 0);
  72. this._collider = new BABYLON.Collider();
  73. this._oldPositionForCollisions = new BABYLON.Vector3(0, 0, 0);
  74. this._diffPositionForCollisions = new BABYLON.Vector3(0, 0, 0);
  75. this._newPositionForCollisions = new BABYLON.Vector3(0, 0, 0);
  76. // Edges
  77. this.edgesWidth = 1;
  78. this.edgesColor = new BABYLON.Color4(1, 0, 0, 1);
  79. // Cache
  80. this._localWorld = BABYLON.Matrix.Zero();
  81. this._worldMatrix = BABYLON.Matrix.Zero();
  82. this._rotateYByPI = BABYLON.Matrix.RotationY(Math.PI);
  83. this._absolutePosition = BABYLON.Vector3.Zero();
  84. this._collisionsTransformMatrix = BABYLON.Matrix.Zero();
  85. this._collisionsScalingMatrix = BABYLON.Matrix.Zero();
  86. this._isDirty = false;
  87. this._pivotMatrix = BABYLON.Matrix.Identity();
  88. this._isDisposed = false;
  89. this._renderId = 0;
  90. this._intersectionsInProgress = new Array();
  91. this._isWorldMatrixFrozen = false;
  92. this._unIndexed = false;
  93. this._onCollisionPositionChange = function (collisionId, newPosition, collidedMesh) {
  94. if (collidedMesh === void 0) { collidedMesh = null; }
  95. //TODO move this to the collision coordinator!
  96. if (_this.getScene().workerCollisions)
  97. newPosition.multiplyInPlace(_this._collider.radius);
  98. newPosition.subtractToRef(_this._oldPositionForCollisions, _this._diffPositionForCollisions);
  99. if (_this._diffPositionForCollisions.length() > BABYLON.Engine.CollisionsEpsilon) {
  100. _this.position.addInPlace(_this._diffPositionForCollisions);
  101. }
  102. if (collidedMesh) {
  103. _this.onCollideObservable.notifyObservers(collidedMesh);
  104. }
  105. _this.onCollisionPositionChangeObservable.notifyObservers(_this.position);
  106. };
  107. scene.addMesh(this);
  108. }
  109. Object.defineProperty(AbstractMesh, "BILLBOARDMODE_NONE", {
  110. get: function () {
  111. return AbstractMesh._BILLBOARDMODE_NONE;
  112. },
  113. enumerable: true,
  114. configurable: true
  115. });
  116. Object.defineProperty(AbstractMesh, "BILLBOARDMODE_X", {
  117. get: function () {
  118. return AbstractMesh._BILLBOARDMODE_X;
  119. },
  120. enumerable: true,
  121. configurable: true
  122. });
  123. Object.defineProperty(AbstractMesh, "BILLBOARDMODE_Y", {
  124. get: function () {
  125. return AbstractMesh._BILLBOARDMODE_Y;
  126. },
  127. enumerable: true,
  128. configurable: true
  129. });
  130. Object.defineProperty(AbstractMesh, "BILLBOARDMODE_Z", {
  131. get: function () {
  132. return AbstractMesh._BILLBOARDMODE_Z;
  133. },
  134. enumerable: true,
  135. configurable: true
  136. });
  137. Object.defineProperty(AbstractMesh, "BILLBOARDMODE_ALL", {
  138. get: function () {
  139. return AbstractMesh._BILLBOARDMODE_ALL;
  140. },
  141. enumerable: true,
  142. configurable: true
  143. });
  144. Object.defineProperty(AbstractMesh.prototype, "onDispose", {
  145. set: function (callback) {
  146. if (this._onDisposeObserver) {
  147. this.onDisposeObservable.remove(this._onDisposeObserver);
  148. }
  149. this._onDisposeObserver = this.onDisposeObservable.add(callback);
  150. },
  151. enumerable: true,
  152. configurable: true
  153. });
  154. Object.defineProperty(AbstractMesh.prototype, "onCollide", {
  155. set: function (callback) {
  156. if (this._onCollideObserver) {
  157. this.onCollideObservable.remove(this._onCollideObserver);
  158. }
  159. this._onCollideObserver = this.onCollideObservable.add(callback);
  160. },
  161. enumerable: true,
  162. configurable: true
  163. });
  164. Object.defineProperty(AbstractMesh.prototype, "onCollisionPositionChange", {
  165. set: function (callback) {
  166. if (this._onCollisionPositionChangeObserver) {
  167. this.onCollisionPositionChangeObservable.remove(this._onCollisionPositionChangeObserver);
  168. }
  169. this._onCollisionPositionChangeObserver = this.onCollisionPositionChangeObservable.add(callback);
  170. },
  171. enumerable: true,
  172. configurable: true
  173. });
  174. Object.defineProperty(AbstractMesh.prototype, "skeleton", {
  175. get: function () {
  176. return this._skeleton;
  177. },
  178. set: function (value) {
  179. if (this._skeleton && this._skeleton.needInitialSkinMatrix) {
  180. this._skeleton._unregisterMeshWithPoseMatrix(this);
  181. }
  182. if (value && value.needInitialSkinMatrix) {
  183. value._registerMeshWithPoseMatrix(this);
  184. }
  185. this._skeleton = value;
  186. if (!this._skeleton) {
  187. this._bonesTransformMatrices = null;
  188. }
  189. },
  190. enumerable: true,
  191. configurable: true
  192. });
  193. /**
  194. * @param {boolean} fullDetails - support for multiple levels of logging within scene loading
  195. */
  196. AbstractMesh.prototype.toString = function (fullDetails) {
  197. var ret = "Name: " + this.name + ", isInstance: " + (this instanceof BABYLON.InstancedMesh ? "YES" : "NO");
  198. ret += ", # of submeshes: " + (this.subMeshes ? this.subMeshes.length : 0);
  199. if (this._skeleton) {
  200. ret += ", skeleton: " + this._skeleton.name;
  201. }
  202. if (fullDetails) {
  203. ret += ", billboard mode: " + (["NONE", "X", "Y", null, "Z", null, null, "ALL"])[this.billboardMode];
  204. ret += ", freeze wrld mat: " + (this._isWorldMatrixFrozen || this._waitingFreezeWorldMatrix ? "YES" : "NO");
  205. }
  206. return ret;
  207. };
  208. Object.defineProperty(AbstractMesh.prototype, "rotation", {
  209. /**
  210. * Getting the rotation object.
  211. * If rotation quaternion is set, this vector will (almost always) be the Zero vector!
  212. */
  213. get: function () {
  214. return this._rotation;
  215. },
  216. set: function (newRotation) {
  217. this._rotation = newRotation;
  218. },
  219. enumerable: true,
  220. configurable: true
  221. });
  222. Object.defineProperty(AbstractMesh.prototype, "scaling", {
  223. get: function () {
  224. return this._scaling;
  225. },
  226. set: function (newScaling) {
  227. this._scaling = newScaling;
  228. if (this.physicsImpostor) {
  229. this.physicsImpostor.forceUpdate();
  230. }
  231. },
  232. enumerable: true,
  233. configurable: true
  234. });
  235. Object.defineProperty(AbstractMesh.prototype, "rotationQuaternion", {
  236. get: function () {
  237. return this._rotationQuaternion;
  238. },
  239. set: function (quaternion) {
  240. this._rotationQuaternion = quaternion;
  241. //reset the rotation vector.
  242. if (quaternion && this.rotation.length()) {
  243. this.rotation.copyFromFloats(0, 0, 0);
  244. }
  245. },
  246. enumerable: true,
  247. configurable: true
  248. });
  249. // Methods
  250. AbstractMesh.prototype.updatePoseMatrix = function (matrix) {
  251. this._poseMatrix.copyFrom(matrix);
  252. };
  253. AbstractMesh.prototype.getPoseMatrix = function () {
  254. return this._poseMatrix;
  255. };
  256. AbstractMesh.prototype.disableEdgesRendering = function () {
  257. if (this._edgesRenderer !== undefined) {
  258. this._edgesRenderer.dispose();
  259. this._edgesRenderer = undefined;
  260. }
  261. };
  262. AbstractMesh.prototype.enableEdgesRendering = function (epsilon, checkVerticesInsteadOfIndices) {
  263. if (epsilon === void 0) { epsilon = 0.95; }
  264. if (checkVerticesInsteadOfIndices === void 0) { checkVerticesInsteadOfIndices = false; }
  265. this.disableEdgesRendering();
  266. this._edgesRenderer = new BABYLON.EdgesRenderer(this, epsilon, checkVerticesInsteadOfIndices);
  267. };
  268. Object.defineProperty(AbstractMesh.prototype, "isBlocked", {
  269. get: function () {
  270. return false;
  271. },
  272. enumerable: true,
  273. configurable: true
  274. });
  275. AbstractMesh.prototype.getLOD = function (camera) {
  276. return this;
  277. };
  278. AbstractMesh.prototype.getTotalVertices = function () {
  279. return 0;
  280. };
  281. AbstractMesh.prototype.getIndices = function () {
  282. return null;
  283. };
  284. AbstractMesh.prototype.getVerticesData = function (kind) {
  285. return null;
  286. };
  287. AbstractMesh.prototype.isVerticesDataPresent = function (kind) {
  288. return false;
  289. };
  290. AbstractMesh.prototype.getBoundingInfo = function () {
  291. if (this._masterMesh) {
  292. return this._masterMesh.getBoundingInfo();
  293. }
  294. if (!this._boundingInfo) {
  295. this._updateBoundingInfo();
  296. }
  297. return this._boundingInfo;
  298. };
  299. AbstractMesh.prototype.setBoundingInfo = function (boundingInfo) {
  300. this._boundingInfo = boundingInfo;
  301. };
  302. Object.defineProperty(AbstractMesh.prototype, "useBones", {
  303. get: function () {
  304. return this.skeleton && this.getScene().skeletonsEnabled && this.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind) && this.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind);
  305. },
  306. enumerable: true,
  307. configurable: true
  308. });
  309. AbstractMesh.prototype._preActivate = function () {
  310. };
  311. AbstractMesh.prototype._preActivateForIntermediateRendering = function (renderId) {
  312. };
  313. AbstractMesh.prototype._activate = function (renderId) {
  314. this._renderId = renderId;
  315. };
  316. AbstractMesh.prototype.getWorldMatrix = function () {
  317. if (this._masterMesh) {
  318. return this._masterMesh.getWorldMatrix();
  319. }
  320. if (this._currentRenderId !== this.getScene().getRenderId()) {
  321. this.computeWorldMatrix();
  322. }
  323. return this._worldMatrix;
  324. };
  325. Object.defineProperty(AbstractMesh.prototype, "worldMatrixFromCache", {
  326. get: function () {
  327. return this._worldMatrix;
  328. },
  329. enumerable: true,
  330. configurable: true
  331. });
  332. Object.defineProperty(AbstractMesh.prototype, "absolutePosition", {
  333. get: function () {
  334. return this._absolutePosition;
  335. },
  336. enumerable: true,
  337. configurable: true
  338. });
  339. AbstractMesh.prototype.freezeWorldMatrix = function () {
  340. this._isWorldMatrixFrozen = false; // no guarantee world is not already frozen, switch off temporarily
  341. this.computeWorldMatrix(true);
  342. this._isWorldMatrixFrozen = true;
  343. };
  344. AbstractMesh.prototype.unfreezeWorldMatrix = function () {
  345. this._isWorldMatrixFrozen = false;
  346. this.computeWorldMatrix(true);
  347. };
  348. Object.defineProperty(AbstractMesh.prototype, "isWorldMatrixFrozen", {
  349. get: function () {
  350. return this._isWorldMatrixFrozen;
  351. },
  352. enumerable: true,
  353. configurable: true
  354. });
  355. AbstractMesh.prototype.rotate = function (axis, amount, space) {
  356. axis.normalize();
  357. if (!this.rotationQuaternion) {
  358. this.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
  359. this.rotation = BABYLON.Vector3.Zero();
  360. }
  361. var rotationQuaternion;
  362. if (!space || space === BABYLON.Space.LOCAL) {
  363. rotationQuaternion = BABYLON.Quaternion.RotationAxisToRef(axis, amount, AbstractMesh._rotationAxisCache);
  364. this.rotationQuaternion.multiplyToRef(rotationQuaternion, this.rotationQuaternion);
  365. }
  366. else {
  367. if (this.parent) {
  368. var invertParentWorldMatrix = this.parent.getWorldMatrix().clone();
  369. invertParentWorldMatrix.invert();
  370. axis = BABYLON.Vector3.TransformNormal(axis, invertParentWorldMatrix);
  371. }
  372. rotationQuaternion = BABYLON.Quaternion.RotationAxisToRef(axis, amount, AbstractMesh._rotationAxisCache);
  373. rotationQuaternion.multiplyToRef(this.rotationQuaternion, this.rotationQuaternion);
  374. }
  375. };
  376. AbstractMesh.prototype.translate = function (axis, distance, space) {
  377. var displacementVector = axis.scale(distance);
  378. if (!space || space === BABYLON.Space.LOCAL) {
  379. var tempV3 = this.getPositionExpressedInLocalSpace().add(displacementVector);
  380. this.setPositionWithLocalVector(tempV3);
  381. }
  382. else {
  383. this.setAbsolutePosition(this.getAbsolutePosition().add(displacementVector));
  384. }
  385. };
  386. AbstractMesh.prototype.getAbsolutePosition = function () {
  387. this.computeWorldMatrix();
  388. return this._absolutePosition;
  389. };
  390. AbstractMesh.prototype.setAbsolutePosition = function (absolutePosition) {
  391. if (!absolutePosition) {
  392. return;
  393. }
  394. var absolutePositionX;
  395. var absolutePositionY;
  396. var absolutePositionZ;
  397. if (absolutePosition.x === undefined) {
  398. if (arguments.length < 3) {
  399. return;
  400. }
  401. absolutePositionX = arguments[0];
  402. absolutePositionY = arguments[1];
  403. absolutePositionZ = arguments[2];
  404. }
  405. else {
  406. absolutePositionX = absolutePosition.x;
  407. absolutePositionY = absolutePosition.y;
  408. absolutePositionZ = absolutePosition.z;
  409. }
  410. if (this.parent) {
  411. var invertParentWorldMatrix = this.parent.getWorldMatrix().clone();
  412. invertParentWorldMatrix.invert();
  413. var worldPosition = new BABYLON.Vector3(absolutePositionX, absolutePositionY, absolutePositionZ);
  414. this.position = BABYLON.Vector3.TransformCoordinates(worldPosition, invertParentWorldMatrix);
  415. }
  416. else {
  417. this.position.x = absolutePositionX;
  418. this.position.y = absolutePositionY;
  419. this.position.z = absolutePositionZ;
  420. }
  421. };
  422. // ================================== Point of View Movement =================================
  423. /**
  424. * Perform relative position change from the point of view of behind the front of the mesh.
  425. * This is performed taking into account the meshes current rotation, so you do not have to care.
  426. * Supports definition of mesh facing forward or backward.
  427. * @param {number} amountRight
  428. * @param {number} amountUp
  429. * @param {number} amountForward
  430. */
  431. AbstractMesh.prototype.movePOV = function (amountRight, amountUp, amountForward) {
  432. this.position.addInPlace(this.calcMovePOV(amountRight, amountUp, amountForward));
  433. };
  434. /**
  435. * Calculate relative position change from the point of view of behind the front of the mesh.
  436. * This is performed taking into account the meshes current rotation, so you do not have to care.
  437. * Supports definition of mesh facing forward or backward.
  438. * @param {number} amountRight
  439. * @param {number} amountUp
  440. * @param {number} amountForward
  441. */
  442. AbstractMesh.prototype.calcMovePOV = function (amountRight, amountUp, amountForward) {
  443. var rotMatrix = new BABYLON.Matrix();
  444. var rotQuaternion = (this.rotationQuaternion) ? this.rotationQuaternion : BABYLON.Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
  445. rotQuaternion.toRotationMatrix(rotMatrix);
  446. var translationDelta = BABYLON.Vector3.Zero();
  447. var defForwardMult = this.definedFacingForward ? -1 : 1;
  448. BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(amountRight * defForwardMult, amountUp, amountForward * defForwardMult, rotMatrix, translationDelta);
  449. return translationDelta;
  450. };
  451. // ================================== Point of View Rotation =================================
  452. /**
  453. * Perform relative rotation change from the point of view of behind the front of the mesh.
  454. * Supports definition of mesh facing forward or backward.
  455. * @param {number} flipBack
  456. * @param {number} twirlClockwise
  457. * @param {number} tiltRight
  458. */
  459. AbstractMesh.prototype.rotatePOV = function (flipBack, twirlClockwise, tiltRight) {
  460. this.rotation.addInPlace(this.calcRotatePOV(flipBack, twirlClockwise, tiltRight));
  461. };
  462. /**
  463. * Calculate relative rotation change from the point of view of behind the front of the mesh.
  464. * Supports definition of mesh facing forward or backward.
  465. * @param {number} flipBack
  466. * @param {number} twirlClockwise
  467. * @param {number} tiltRight
  468. */
  469. AbstractMesh.prototype.calcRotatePOV = function (flipBack, twirlClockwise, tiltRight) {
  470. var defForwardMult = this.definedFacingForward ? 1 : -1;
  471. return new BABYLON.Vector3(flipBack * defForwardMult, twirlClockwise, tiltRight * defForwardMult);
  472. };
  473. AbstractMesh.prototype.setPivotMatrix = function (matrix) {
  474. this._pivotMatrix = matrix;
  475. this._cache.pivotMatrixUpdated = true;
  476. };
  477. AbstractMesh.prototype.getPivotMatrix = function () {
  478. return this._pivotMatrix;
  479. };
  480. AbstractMesh.prototype._isSynchronized = function () {
  481. if (this._isDirty) {
  482. return false;
  483. }
  484. if (this.billboardMode !== this._cache.billboardMode || this.billboardMode !== AbstractMesh.BILLBOARDMODE_NONE)
  485. return false;
  486. if (this._cache.pivotMatrixUpdated) {
  487. return false;
  488. }
  489. if (this.infiniteDistance) {
  490. return false;
  491. }
  492. if (!this._cache.position.equals(this.position))
  493. return false;
  494. if (this.rotationQuaternion) {
  495. if (!this._cache.rotationQuaternion.equals(this.rotationQuaternion))
  496. return false;
  497. }
  498. else {
  499. if (!this._cache.rotation.equals(this.rotation))
  500. return false;
  501. }
  502. if (!this._cache.scaling.equals(this.scaling))
  503. return false;
  504. return true;
  505. };
  506. AbstractMesh.prototype._initCache = function () {
  507. _super.prototype._initCache.call(this);
  508. this._cache.localMatrixUpdated = false;
  509. this._cache.position = BABYLON.Vector3.Zero();
  510. this._cache.scaling = BABYLON.Vector3.Zero();
  511. this._cache.rotation = BABYLON.Vector3.Zero();
  512. this._cache.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 0);
  513. this._cache.billboardMode = -1;
  514. };
  515. AbstractMesh.prototype.markAsDirty = function (property) {
  516. if (property === "rotation") {
  517. this.rotationQuaternion = null;
  518. }
  519. this._currentRenderId = Number.MAX_VALUE;
  520. this._isDirty = true;
  521. };
  522. AbstractMesh.prototype._updateBoundingInfo = function () {
  523. this._boundingInfo = this._boundingInfo || new BABYLON.BoundingInfo(this.absolutePosition, this.absolutePosition);
  524. this._boundingInfo.update(this.worldMatrixFromCache);
  525. this._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);
  526. };
  527. AbstractMesh.prototype._updateSubMeshesBoundingInfo = function (matrix) {
  528. if (!this.subMeshes) {
  529. return;
  530. }
  531. for (var subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {
  532. var subMesh = this.subMeshes[subIndex];
  533. if (!subMesh.IsGlobal) {
  534. subMesh.updateBoundingInfo(matrix);
  535. }
  536. }
  537. };
  538. AbstractMesh.prototype.computeWorldMatrix = function (force) {
  539. if (this._isWorldMatrixFrozen) {
  540. return this._worldMatrix;
  541. }
  542. if (!force && (this._currentRenderId === this.getScene().getRenderId() || this.isSynchronized(true))) {
  543. this._currentRenderId = this.getScene().getRenderId();
  544. return this._worldMatrix;
  545. }
  546. this._cache.position.copyFrom(this.position);
  547. this._cache.scaling.copyFrom(this.scaling);
  548. this._cache.pivotMatrixUpdated = false;
  549. this._cache.billboardMode = this.billboardMode;
  550. this._currentRenderId = this.getScene().getRenderId();
  551. this._isDirty = false;
  552. // Scaling
  553. BABYLON.Matrix.ScalingToRef(this.scaling.x * this.scalingDeterminant, this.scaling.y * this.scalingDeterminant, this.scaling.z * this.scalingDeterminant, BABYLON.Tmp.Matrix[1]);
  554. // Rotation
  555. //rotate, if quaternion is set and rotation was used
  556. if (this.rotationQuaternion) {
  557. var len = this.rotation.length();
  558. if (len) {
  559. this.rotationQuaternion.multiplyInPlace(BABYLON.Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z));
  560. this.rotation.copyFromFloats(0, 0, 0);
  561. }
  562. }
  563. if (this.rotationQuaternion) {
  564. this.rotationQuaternion.toRotationMatrix(BABYLON.Tmp.Matrix[0]);
  565. this._cache.rotationQuaternion.copyFrom(this.rotationQuaternion);
  566. }
  567. else {
  568. BABYLON.Matrix.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, BABYLON.Tmp.Matrix[0]);
  569. this._cache.rotation.copyFrom(this.rotation);
  570. }
  571. // Translation
  572. if (this.infiniteDistance && !this.parent) {
  573. var camera = this.getScene().activeCamera;
  574. if (camera) {
  575. var cameraWorldMatrix = camera.getWorldMatrix();
  576. var cameraGlobalPosition = new BABYLON.Vector3(cameraWorldMatrix.m[12], cameraWorldMatrix.m[13], cameraWorldMatrix.m[14]);
  577. BABYLON.Matrix.TranslationToRef(this.position.x + cameraGlobalPosition.x, this.position.y + cameraGlobalPosition.y, this.position.z + cameraGlobalPosition.z, BABYLON.Tmp.Matrix[2]);
  578. }
  579. }
  580. else {
  581. BABYLON.Matrix.TranslationToRef(this.position.x, this.position.y, this.position.z, BABYLON.Tmp.Matrix[2]);
  582. }
  583. // Composing transformations
  584. this._pivotMatrix.multiplyToRef(BABYLON.Tmp.Matrix[1], BABYLON.Tmp.Matrix[4]);
  585. BABYLON.Tmp.Matrix[4].multiplyToRef(BABYLON.Tmp.Matrix[0], BABYLON.Tmp.Matrix[5]);
  586. // Billboarding
  587. if (this.billboardMode !== AbstractMesh.BILLBOARDMODE_NONE && this.getScene().activeCamera) {
  588. BABYLON.Tmp.Vector3[0].copyFrom(this.position);
  589. var localPosition = BABYLON.Tmp.Vector3[0];
  590. if (this.parent && this.parent.getWorldMatrix) {
  591. this._markSyncedWithParent();
  592. var parentMatrix;
  593. if (this._meshToBoneReferal) {
  594. this.parent.getWorldMatrix().multiplyToRef(this._meshToBoneReferal.getWorldMatrix(), BABYLON.Tmp.Matrix[6]);
  595. parentMatrix = BABYLON.Tmp.Matrix[6];
  596. }
  597. else {
  598. parentMatrix = this.parent.getWorldMatrix();
  599. }
  600. BABYLON.Vector3.TransformNormalToRef(localPosition, parentMatrix, BABYLON.Tmp.Vector3[1]);
  601. localPosition = BABYLON.Tmp.Vector3[1];
  602. }
  603. var zero = this.getScene().activeCamera.globalPosition.clone();
  604. if (this.parent && this.parent.position) {
  605. localPosition.addInPlace(this.parent.position);
  606. BABYLON.Matrix.TranslationToRef(localPosition.x, localPosition.y, localPosition.z, BABYLON.Tmp.Matrix[2]);
  607. }
  608. if ((this.billboardMode & AbstractMesh.BILLBOARDMODE_ALL) !== AbstractMesh.BILLBOARDMODE_ALL) {
  609. if (this.billboardMode & AbstractMesh.BILLBOARDMODE_X)
  610. zero.x = localPosition.x + BABYLON.Epsilon;
  611. if (this.billboardMode & AbstractMesh.BILLBOARDMODE_Y)
  612. zero.y = localPosition.y + BABYLON.Epsilon;
  613. if (this.billboardMode & AbstractMesh.BILLBOARDMODE_Z)
  614. zero.z = localPosition.z + BABYLON.Epsilon;
  615. }
  616. BABYLON.Matrix.LookAtLHToRef(localPosition, zero, BABYLON.Vector3.Up(), BABYLON.Tmp.Matrix[3]);
  617. BABYLON.Tmp.Matrix[3].m[12] = BABYLON.Tmp.Matrix[3].m[13] = BABYLON.Tmp.Matrix[3].m[14] = 0;
  618. BABYLON.Tmp.Matrix[3].invert();
  619. BABYLON.Tmp.Matrix[5].multiplyToRef(BABYLON.Tmp.Matrix[3], this._localWorld);
  620. this._rotateYByPI.multiplyToRef(this._localWorld, BABYLON.Tmp.Matrix[5]);
  621. }
  622. // Local world
  623. BABYLON.Tmp.Matrix[5].multiplyToRef(BABYLON.Tmp.Matrix[2], this._localWorld);
  624. // Parent
  625. if (this.parent && this.parent.getWorldMatrix && this.billboardMode === AbstractMesh.BILLBOARDMODE_NONE) {
  626. this._markSyncedWithParent();
  627. if (this._meshToBoneReferal) {
  628. this._localWorld.multiplyToRef(this.parent.getWorldMatrix(), BABYLON.Tmp.Matrix[6]);
  629. BABYLON.Tmp.Matrix[6].multiplyToRef(this._meshToBoneReferal.getWorldMatrix(), this._worldMatrix);
  630. }
  631. else {
  632. this._localWorld.multiplyToRef(this.parent.getWorldMatrix(), this._worldMatrix);
  633. }
  634. }
  635. else {
  636. this._worldMatrix.copyFrom(this._localWorld);
  637. }
  638. // Bounding info
  639. this._updateBoundingInfo();
  640. // Absolute position
  641. this._absolutePosition.copyFromFloats(this._worldMatrix.m[12], this._worldMatrix.m[13], this._worldMatrix.m[14]);
  642. // Callbacks
  643. this.onAfterWorldMatrixUpdateObservable.notifyObservers(this);
  644. if (!this._poseMatrix) {
  645. this._poseMatrix = BABYLON.Matrix.Invert(this._worldMatrix);
  646. }
  647. return this._worldMatrix;
  648. };
  649. /**
  650. * If you'd like to be callbacked after the mesh position, rotation or scaling has been updated
  651. * @param func: callback function to add
  652. */
  653. AbstractMesh.prototype.registerAfterWorldMatrixUpdate = function (func) {
  654. this.onAfterWorldMatrixUpdateObservable.add(func);
  655. };
  656. AbstractMesh.prototype.unregisterAfterWorldMatrixUpdate = function (func) {
  657. this.onAfterWorldMatrixUpdateObservable.removeCallback(func);
  658. };
  659. AbstractMesh.prototype.setPositionWithLocalVector = function (vector3) {
  660. this.computeWorldMatrix();
  661. this.position = BABYLON.Vector3.TransformNormal(vector3, this._localWorld);
  662. };
  663. AbstractMesh.prototype.getPositionExpressedInLocalSpace = function () {
  664. this.computeWorldMatrix();
  665. var invLocalWorldMatrix = this._localWorld.clone();
  666. invLocalWorldMatrix.invert();
  667. return BABYLON.Vector3.TransformNormal(this.position, invLocalWorldMatrix);
  668. };
  669. AbstractMesh.prototype.locallyTranslate = function (vector3) {
  670. this.computeWorldMatrix(true);
  671. this.position = BABYLON.Vector3.TransformCoordinates(vector3, this._localWorld);
  672. };
  673. AbstractMesh.prototype.lookAt = function (targetPoint, yawCor, pitchCor, rollCor, space) {
  674. /// <summary>Orients a mesh towards a target point. Mesh must be drawn facing user.</summary>
  675. /// <param name="targetPoint" type="Vector3">The position (must be in same space as current mesh) to look at</param>
  676. /// <param name="yawCor" type="Number">optional yaw (y-axis) correction in radians</param>
  677. /// <param name="pitchCor" type="Number">optional pitch (x-axis) correction in radians</param>
  678. /// <param name="rollCor" type="Number">optional roll (z-axis) correction in radians</param>
  679. /// <returns>Mesh oriented towards targetMesh</returns>
  680. if (yawCor === void 0) { yawCor = 0; }
  681. if (pitchCor === void 0) { pitchCor = 0; }
  682. if (rollCor === void 0) { rollCor = 0; }
  683. if (space === void 0) { space = BABYLON.Space.LOCAL; }
  684. var dv = AbstractMesh._lookAtVectorCache;
  685. var pos = space === BABYLON.Space.LOCAL ? this.position : this.getAbsolutePosition();
  686. targetPoint.subtractToRef(pos, dv);
  687. var yaw = -Math.atan2(dv.z, dv.x) - Math.PI / 2;
  688. var len = Math.sqrt(dv.x * dv.x + dv.z * dv.z);
  689. var pitch = Math.atan2(dv.y, len);
  690. this.rotationQuaternion = this.rotationQuaternion || new BABYLON.Quaternion();
  691. BABYLON.Quaternion.RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);
  692. };
  693. AbstractMesh.prototype.attachToBone = function (bone, affectedMesh) {
  694. this._meshToBoneReferal = affectedMesh;
  695. this.parent = bone;
  696. if (bone.getWorldMatrix().determinant() < 0) {
  697. this.scalingDeterminant *= -1;
  698. }
  699. };
  700. AbstractMesh.prototype.detachFromBone = function () {
  701. if (this.parent.getWorldMatrix().determinant() < 0) {
  702. this.scalingDeterminant *= -1;
  703. }
  704. this._meshToBoneReferal = null;
  705. this.parent = null;
  706. };
  707. AbstractMesh.prototype.isInFrustum = function (frustumPlanes) {
  708. return this._boundingInfo.isInFrustum(frustumPlanes);
  709. };
  710. AbstractMesh.prototype.isCompletelyInFrustum = function (frustumPlanes) {
  711. return this._boundingInfo.isCompletelyInFrustum(frustumPlanes);
  712. ;
  713. };
  714. AbstractMesh.prototype.intersectsMesh = function (mesh, precise) {
  715. if (!this._boundingInfo || !mesh._boundingInfo) {
  716. return false;
  717. }
  718. return this._boundingInfo.intersects(mesh._boundingInfo, precise);
  719. };
  720. AbstractMesh.prototype.intersectsPoint = function (point) {
  721. if (!this._boundingInfo) {
  722. return false;
  723. }
  724. return this._boundingInfo.intersectsPoint(point);
  725. };
  726. // Physics
  727. /**
  728. * @Deprecated. Use new PhysicsImpostor instead.
  729. * */
  730. AbstractMesh.prototype.setPhysicsState = function (impostor, options) {
  731. //legacy support
  732. if (impostor.impostor) {
  733. options = impostor;
  734. impostor = impostor.impostor;
  735. }
  736. this.physicsImpostor = new BABYLON.PhysicsImpostor(this, impostor, options, this.getScene());
  737. return this.physicsImpostor.physicsBody;
  738. };
  739. AbstractMesh.prototype.getPhysicsImpostor = function () {
  740. return this.physicsImpostor;
  741. };
  742. /**
  743. * @Deprecated. Use getPhysicsImpostor().getParam("mass");
  744. */
  745. AbstractMesh.prototype.getPhysicsMass = function () {
  746. return this.physicsImpostor.getParam("mass");
  747. };
  748. /**
  749. * @Deprecated. Use getPhysicsImpostor().getParam("friction");
  750. */
  751. AbstractMesh.prototype.getPhysicsFriction = function () {
  752. return this.physicsImpostor.getParam("friction");
  753. };
  754. /**
  755. * @Deprecated. Use getPhysicsImpostor().getParam("restitution");
  756. */
  757. AbstractMesh.prototype.getPhysicsRestitution = function () {
  758. return this.physicsImpostor.getParam("resitution");
  759. };
  760. AbstractMesh.prototype.getPositionInCameraSpace = function (camera) {
  761. if (!camera) {
  762. camera = this.getScene().activeCamera;
  763. }
  764. return BABYLON.Vector3.TransformCoordinates(this.absolutePosition, camera.getViewMatrix());
  765. };
  766. AbstractMesh.prototype.getDistanceToCamera = function (camera) {
  767. if (!camera) {
  768. camera = this.getScene().activeCamera;
  769. }
  770. return this.absolutePosition.subtract(camera.position).length();
  771. };
  772. AbstractMesh.prototype.applyImpulse = function (force, contactPoint) {
  773. if (!this.physicsImpostor) {
  774. return;
  775. }
  776. this.physicsImpostor.applyImpulse(force, contactPoint);
  777. };
  778. AbstractMesh.prototype.setPhysicsLinkWith = function (otherMesh, pivot1, pivot2, options) {
  779. if (!this.physicsImpostor || !otherMesh.physicsImpostor) {
  780. return;
  781. }
  782. this.physicsImpostor.createJoint(otherMesh.physicsImpostor, BABYLON.PhysicsJoint.HingeJoint, {
  783. mainPivot: pivot1,
  784. connectedPivot: pivot2,
  785. nativeParams: options
  786. });
  787. };
  788. /**
  789. * @Deprecated
  790. */
  791. AbstractMesh.prototype.updatePhysicsBodyPosition = function () {
  792. BABYLON.Tools.Warn("updatePhysicsBodyPosition() is deprecated, please use updatePhysicsBody()");
  793. this.updatePhysicsBody();
  794. };
  795. /**
  796. * @Deprecated
  797. * Calling this function is not needed anymore.
  798. * The physics engine takes care of transofmration automatically.
  799. */
  800. AbstractMesh.prototype.updatePhysicsBody = function () {
  801. //Unneeded
  802. };
  803. Object.defineProperty(AbstractMesh.prototype, "checkCollisions", {
  804. // Collisions
  805. get: function () {
  806. return this._checkCollisions;
  807. },
  808. set: function (collisionEnabled) {
  809. this._checkCollisions = collisionEnabled;
  810. if (this.getScene().workerCollisions) {
  811. this.getScene().collisionCoordinator.onMeshUpdated(this);
  812. }
  813. },
  814. enumerable: true,
  815. configurable: true
  816. });
  817. AbstractMesh.prototype.moveWithCollisions = function (velocity) {
  818. var globalPosition = this.getAbsolutePosition();
  819. globalPosition.subtractFromFloatsToRef(0, this.ellipsoid.y, 0, this._oldPositionForCollisions);
  820. this._oldPositionForCollisions.addInPlace(this.ellipsoidOffset);
  821. this._collider.radius = this.ellipsoid;
  822. this.getScene().collisionCoordinator.getNewPosition(this._oldPositionForCollisions, velocity, this._collider, 3, this, this._onCollisionPositionChange, this.uniqueId);
  823. };
  824. // Submeshes octree
  825. /**
  826. * This function will create an octree to help select the right submeshes for rendering, picking and collisions
  827. * Please note that you must have a decent number of submeshes to get performance improvements when using octree
  828. */
  829. AbstractMesh.prototype.createOrUpdateSubmeshesOctree = function (maxCapacity, maxDepth) {
  830. if (maxCapacity === void 0) { maxCapacity = 64; }
  831. if (maxDepth === void 0) { maxDepth = 2; }
  832. if (!this._submeshesOctree) {
  833. this._submeshesOctree = new BABYLON.Octree(BABYLON.Octree.CreationFuncForSubMeshes, maxCapacity, maxDepth);
  834. }
  835. this.computeWorldMatrix(true);
  836. // Update octree
  837. var bbox = this.getBoundingInfo().boundingBox;
  838. this._submeshesOctree.update(bbox.minimumWorld, bbox.maximumWorld, this.subMeshes);
  839. return this._submeshesOctree;
  840. };
  841. // Collisions
  842. AbstractMesh.prototype._collideForSubMesh = function (subMesh, transformMatrix, collider) {
  843. this._generatePointsArray();
  844. // Transformation
  845. if (!subMesh._lastColliderWorldVertices || !subMesh._lastColliderTransformMatrix.equals(transformMatrix)) {
  846. subMesh._lastColliderTransformMatrix = transformMatrix.clone();
  847. subMesh._lastColliderWorldVertices = [];
  848. subMesh._trianglePlanes = [];
  849. var start = subMesh.verticesStart;
  850. var end = (subMesh.verticesStart + subMesh.verticesCount);
  851. for (var i = start; i < end; i++) {
  852. subMesh._lastColliderWorldVertices.push(BABYLON.Vector3.TransformCoordinates(this._positions[i], transformMatrix));
  853. }
  854. }
  855. // Collide
  856. collider._collide(subMesh._trianglePlanes, subMesh._lastColliderWorldVertices, this.getIndices(), subMesh.indexStart, subMesh.indexStart + subMesh.indexCount, subMesh.verticesStart, !!subMesh.getMaterial());
  857. if (collider.collisionFound) {
  858. collider.collidedMesh = this;
  859. }
  860. };
  861. AbstractMesh.prototype._processCollisionsForSubMeshes = function (collider, transformMatrix) {
  862. var subMeshes;
  863. var len;
  864. // Octrees
  865. if (this._submeshesOctree && this.useOctreeForCollisions) {
  866. var radius = collider.velocityWorldLength + Math.max(collider.radius.x, collider.radius.y, collider.radius.z);
  867. var intersections = this._submeshesOctree.intersects(collider.basePointWorld, radius);
  868. len = intersections.length;
  869. subMeshes = intersections.data;
  870. }
  871. else {
  872. subMeshes = this.subMeshes;
  873. len = subMeshes.length;
  874. }
  875. for (var index = 0; index < len; index++) {
  876. var subMesh = subMeshes[index];
  877. // Bounding test
  878. if (len > 1 && !subMesh._checkCollision(collider))
  879. continue;
  880. this._collideForSubMesh(subMesh, transformMatrix, collider);
  881. }
  882. };
  883. AbstractMesh.prototype._checkCollision = function (collider) {
  884. // Bounding box test
  885. if (!this._boundingInfo._checkCollision(collider))
  886. return;
  887. // Transformation matrix
  888. BABYLON.Matrix.ScalingToRef(1.0 / collider.radius.x, 1.0 / collider.radius.y, 1.0 / collider.radius.z, this._collisionsScalingMatrix);
  889. this.worldMatrixFromCache.multiplyToRef(this._collisionsScalingMatrix, this._collisionsTransformMatrix);
  890. this._processCollisionsForSubMeshes(collider, this._collisionsTransformMatrix);
  891. };
  892. // Picking
  893. AbstractMesh.prototype._generatePointsArray = function () {
  894. return false;
  895. };
  896. AbstractMesh.prototype.intersects = function (ray, fastCheck) {
  897. var pickingInfo = new BABYLON.PickingInfo();
  898. if (!this.subMeshes || !this._boundingInfo || !ray.intersectsSphere(this._boundingInfo.boundingSphere) || !ray.intersectsBox(this._boundingInfo.boundingBox)) {
  899. return pickingInfo;
  900. }
  901. if (!this._generatePointsArray()) {
  902. return pickingInfo;
  903. }
  904. var intersectInfo = null;
  905. // Octrees
  906. var subMeshes;
  907. var len;
  908. if (this._submeshesOctree && this.useOctreeForPicking) {
  909. var worldRay = BABYLON.Ray.Transform(ray, this.getWorldMatrix());
  910. var intersections = this._submeshesOctree.intersectsRay(worldRay);
  911. len = intersections.length;
  912. subMeshes = intersections.data;
  913. }
  914. else {
  915. subMeshes = this.subMeshes;
  916. len = subMeshes.length;
  917. }
  918. for (var index = 0; index < len; index++) {
  919. var subMesh = subMeshes[index];
  920. // Bounding test
  921. if (len > 1 && !subMesh.canIntersects(ray))
  922. continue;
  923. var currentIntersectInfo = subMesh.intersects(ray, this._positions, this.getIndices(), fastCheck);
  924. if (currentIntersectInfo) {
  925. if (fastCheck || !intersectInfo || currentIntersectInfo.distance < intersectInfo.distance) {
  926. intersectInfo = currentIntersectInfo;
  927. intersectInfo.subMeshId = index;
  928. if (fastCheck) {
  929. break;
  930. }
  931. }
  932. }
  933. }
  934. if (intersectInfo) {
  935. // Get picked point
  936. var world = this.getWorldMatrix();
  937. var worldOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, world);
  938. var direction = ray.direction.clone();
  939. direction = direction.scale(intersectInfo.distance);
  940. var worldDirection = BABYLON.Vector3.TransformNormal(direction, world);
  941. var pickedPoint = worldOrigin.add(worldDirection);
  942. // Return result
  943. pickingInfo.hit = true;
  944. pickingInfo.distance = BABYLON.Vector3.Distance(worldOrigin, pickedPoint);
  945. pickingInfo.pickedPoint = pickedPoint;
  946. pickingInfo.pickedMesh = this;
  947. pickingInfo.bu = intersectInfo.bu;
  948. pickingInfo.bv = intersectInfo.bv;
  949. pickingInfo.faceId = intersectInfo.faceId;
  950. pickingInfo.subMeshId = intersectInfo.subMeshId;
  951. return pickingInfo;
  952. }
  953. return pickingInfo;
  954. };
  955. AbstractMesh.prototype.clone = function (name, newParent, doNotCloneChildren) {
  956. return null;
  957. };
  958. AbstractMesh.prototype.releaseSubMeshes = function () {
  959. if (this.subMeshes) {
  960. while (this.subMeshes.length) {
  961. this.subMeshes[0].dispose();
  962. }
  963. }
  964. else {
  965. this.subMeshes = new Array();
  966. }
  967. };
  968. AbstractMesh.prototype.dispose = function (doNotRecurse) {
  969. var _this = this;
  970. var index;
  971. // Action manager
  972. if (this.actionManager) {
  973. this.actionManager.dispose();
  974. this.actionManager = null;
  975. }
  976. // Skeleton
  977. this.skeleton = null;
  978. // Animations
  979. this.getScene().stopAnimation(this);
  980. // Physics
  981. if (this.physicsImpostor) {
  982. this.physicsImpostor.dispose();
  983. }
  984. // Intersections in progress
  985. for (index = 0; index < this._intersectionsInProgress.length; index++) {
  986. var other = this._intersectionsInProgress[index];
  987. var pos = other._intersectionsInProgress.indexOf(this);
  988. other._intersectionsInProgress.splice(pos, 1);
  989. }
  990. this._intersectionsInProgress = [];
  991. // Lights
  992. var lights = this.getScene().lights;
  993. lights.forEach(function (light) {
  994. var meshIndex = light.includedOnlyMeshes.indexOf(_this);
  995. if (meshIndex !== -1) {
  996. light.includedOnlyMeshes.splice(meshIndex, 1);
  997. }
  998. meshIndex = light.excludedMeshes.indexOf(_this);
  999. if (meshIndex !== -1) {
  1000. light.excludedMeshes.splice(meshIndex, 1);
  1001. }
  1002. });
  1003. // Edges
  1004. if (this._edgesRenderer) {
  1005. this._edgesRenderer.dispose();
  1006. this._edgesRenderer = null;
  1007. }
  1008. // SubMeshes
  1009. this.releaseSubMeshes();
  1010. // Remove from scene
  1011. this.getScene().removeMesh(this);
  1012. if (!doNotRecurse) {
  1013. // Particles
  1014. for (index = 0; index < this.getScene().particleSystems.length; index++) {
  1015. if (this.getScene().particleSystems[index].emitter === this) {
  1016. this.getScene().particleSystems[index].dispose();
  1017. index--;
  1018. }
  1019. }
  1020. // Children
  1021. var objects = this.getDescendants(true);
  1022. for (index = 0; index < objects.length; index++) {
  1023. objects[index].dispose();
  1024. }
  1025. }
  1026. else {
  1027. var childMeshes = this.getChildMeshes(true);
  1028. for (index = 0; index < childMeshes.length; index++) {
  1029. var child = childMeshes[index];
  1030. child.parent = null;
  1031. child.computeWorldMatrix(true);
  1032. }
  1033. }
  1034. _super.prototype.dispose.call(this);
  1035. this.onAfterWorldMatrixUpdateObservable.clear();
  1036. this.onCollideObservable.clear();
  1037. this.onCollisionPositionChangeObservable.clear();
  1038. this._isDisposed = true;
  1039. // Callback
  1040. this.onDisposeObservable.notifyObservers(this);
  1041. this.onDisposeObservable.clear();
  1042. };
  1043. // Statics
  1044. AbstractMesh._BILLBOARDMODE_NONE = 0;
  1045. AbstractMesh._BILLBOARDMODE_X = 1;
  1046. AbstractMesh._BILLBOARDMODE_Y = 2;
  1047. AbstractMesh._BILLBOARDMODE_Z = 4;
  1048. AbstractMesh._BILLBOARDMODE_ALL = 7;
  1049. AbstractMesh._rotationAxisCache = new BABYLON.Quaternion();
  1050. AbstractMesh._lookAtVectorCache = new BABYLON.Vector3(0, 0, 0);
  1051. return AbstractMesh;
  1052. })(BABYLON.Node);
  1053. BABYLON.AbstractMesh = AbstractMesh;
  1054. })(BABYLON || (BABYLON = {}));