babylon.mesh.js 124 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376
  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 _InstancesBatch = (function () {
  9. function _InstancesBatch() {
  10. this.mustReturn = false;
  11. this.visibleInstances = new Array();
  12. this.renderSelf = new Array();
  13. }
  14. return _InstancesBatch;
  15. }());
  16. BABYLON._InstancesBatch = _InstancesBatch;
  17. var Mesh = (function (_super) {
  18. __extends(Mesh, _super);
  19. /**
  20. * @constructor
  21. * @param {string} name The value used by scene.getMeshByName() to do a lookup.
  22. * @param {Scene} scene The scene to add this mesh to.
  23. * @param {Node} parent The parent of this mesh, if it has one
  24. * @param {Mesh} source An optional Mesh from which geometry is shared, cloned.
  25. * @param {boolean} doNotCloneChildren When cloning, skip cloning child meshes of source, default False.
  26. * When false, achieved by calling a clone(), also passing False.
  27. * This will make creation of children, recursive.
  28. */
  29. function Mesh(name, scene, parent, source, doNotCloneChildren, clonePhysicsImpostor) {
  30. if (parent === void 0) { parent = null; }
  31. if (clonePhysicsImpostor === void 0) { clonePhysicsImpostor = true; }
  32. _super.call(this, name, scene);
  33. // Events
  34. /**
  35. * An event triggered before rendering the mesh
  36. * @type {BABYLON.Observable}
  37. */
  38. this.onBeforeRenderObservable = new BABYLON.Observable();
  39. /**
  40. * An event triggered after rendering the mesh
  41. * @type {BABYLON.Observable}
  42. */
  43. this.onAfterRenderObservable = new BABYLON.Observable();
  44. /**
  45. * An event triggered before drawing the mesh
  46. * @type {BABYLON.Observable}
  47. */
  48. this.onBeforeDrawObservable = new BABYLON.Observable();
  49. // Members
  50. this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NONE;
  51. this.instances = new Array();
  52. this._LODLevels = new Array();
  53. this._visibleInstances = {};
  54. this._renderIdForInstances = new Array();
  55. this._batchCache = new _InstancesBatch();
  56. this._instancesBufferSize = 32 * 16 * 4; // let's start with a maximum of 32 instances
  57. this._sideOrientation = Mesh._DEFAULTSIDE;
  58. this._areNormalsFrozen = false; // Will be used by ribbons mainly
  59. if (source) {
  60. // Geometry
  61. if (source._geometry) {
  62. source._geometry.applyToMesh(this);
  63. }
  64. // Deep copy
  65. BABYLON.Tools.DeepCopy(source, this, ["name", "material", "skeleton", "instances"], ["_poseMatrix"]);
  66. // Pivot
  67. this.setPivotMatrix(source.getPivotMatrix());
  68. this.id = name + "." + source.id;
  69. // Material
  70. this.material = source.material;
  71. var index;
  72. if (!doNotCloneChildren) {
  73. // Children
  74. for (index = 0; index < scene.meshes.length; index++) {
  75. var mesh = scene.meshes[index];
  76. if (mesh.parent === source) {
  77. // doNotCloneChildren is always going to be False
  78. var newChild = mesh.clone(name + "." + mesh.name, this, doNotCloneChildren);
  79. }
  80. }
  81. }
  82. // Physics clone
  83. var physicsEngine = this.getScene().getPhysicsEngine();
  84. if (clonePhysicsImpostor && physicsEngine) {
  85. var impostor = physicsEngine.getImpostorForPhysicsObject(source);
  86. if (impostor) {
  87. this.physicsImpostor = impostor.clone(this);
  88. }
  89. }
  90. // Particles
  91. for (index = 0; index < scene.particleSystems.length; index++) {
  92. var system = scene.particleSystems[index];
  93. if (system.emitter === source) {
  94. system.clone(system.name, this);
  95. }
  96. }
  97. this.computeWorldMatrix(true);
  98. }
  99. // Parent
  100. if (parent !== null) {
  101. this.parent = parent;
  102. }
  103. }
  104. Object.defineProperty(Mesh, "FRONTSIDE", {
  105. /**
  106. * Mesh side orientation : usually the external or front surface
  107. */
  108. get: function () {
  109. return Mesh._FRONTSIDE;
  110. },
  111. enumerable: true,
  112. configurable: true
  113. });
  114. Object.defineProperty(Mesh, "BACKSIDE", {
  115. /**
  116. * Mesh side orientation : usually the internal or back surface
  117. */
  118. get: function () {
  119. return Mesh._BACKSIDE;
  120. },
  121. enumerable: true,
  122. configurable: true
  123. });
  124. Object.defineProperty(Mesh, "DOUBLESIDE", {
  125. /**
  126. * Mesh side orientation : both internal and external or front and back surfaces
  127. */
  128. get: function () {
  129. return Mesh._DOUBLESIDE;
  130. },
  131. enumerable: true,
  132. configurable: true
  133. });
  134. Object.defineProperty(Mesh, "DEFAULTSIDE", {
  135. /**
  136. * Mesh side orientation : by default, `FRONTSIDE`
  137. */
  138. get: function () {
  139. return Mesh._DEFAULTSIDE;
  140. },
  141. enumerable: true,
  142. configurable: true
  143. });
  144. Object.defineProperty(Mesh, "NO_CAP", {
  145. /**
  146. * Mesh cap setting : no cap
  147. */
  148. get: function () {
  149. return Mesh._NO_CAP;
  150. },
  151. enumerable: true,
  152. configurable: true
  153. });
  154. Object.defineProperty(Mesh, "CAP_START", {
  155. /**
  156. * Mesh cap setting : one cap at the beginning of the mesh
  157. */
  158. get: function () {
  159. return Mesh._CAP_START;
  160. },
  161. enumerable: true,
  162. configurable: true
  163. });
  164. Object.defineProperty(Mesh, "CAP_END", {
  165. /**
  166. * Mesh cap setting : one cap at the end of the mesh
  167. */
  168. get: function () {
  169. return Mesh._CAP_END;
  170. },
  171. enumerable: true,
  172. configurable: true
  173. });
  174. Object.defineProperty(Mesh, "CAP_ALL", {
  175. /**
  176. * Mesh cap setting : two caps, one at the beginning and one at the end of the mesh
  177. */
  178. get: function () {
  179. return Mesh._CAP_ALL;
  180. },
  181. enumerable: true,
  182. configurable: true
  183. });
  184. Object.defineProperty(Mesh.prototype, "onBeforeDraw", {
  185. set: function (callback) {
  186. if (this._onBeforeDrawObserver) {
  187. this.onBeforeDrawObservable.remove(this._onBeforeDrawObserver);
  188. }
  189. this._onBeforeDrawObserver = this.onBeforeDrawObservable.add(callback);
  190. },
  191. enumerable: true,
  192. configurable: true
  193. });
  194. // Methods
  195. /**
  196. * @param {boolean} fullDetails - support for multiple levels of logging within scene loading
  197. */
  198. Mesh.prototype.toString = function (fullDetails) {
  199. var ret = _super.prototype.toString.call(this, fullDetails);
  200. ret += ", n vertices: " + this.getTotalVertices();
  201. ret += ", parent: " + (this._waitingParentId ? this._waitingParentId : (this.parent ? this.parent.name : "NONE"));
  202. if (this.animations) {
  203. for (var i = 0; i < this.animations.length; i++) {
  204. ret += ", animation[0]: " + this.animations[i].toString(fullDetails);
  205. }
  206. }
  207. if (fullDetails) {
  208. ret += ", flat shading: " + (this._geometry ? (this.getVerticesData(BABYLON.VertexBuffer.PositionKind).length / 3 === this.getIndices().length ? "YES" : "NO") : "UNKNOWN");
  209. }
  210. return ret;
  211. };
  212. Object.defineProperty(Mesh.prototype, "hasLODLevels", {
  213. get: function () {
  214. return this._LODLevels.length > 0;
  215. },
  216. enumerable: true,
  217. configurable: true
  218. });
  219. Mesh.prototype._sortLODLevels = function () {
  220. this._LODLevels.sort(function (a, b) {
  221. if (a.distance < b.distance) {
  222. return 1;
  223. }
  224. if (a.distance > b.distance) {
  225. return -1;
  226. }
  227. return 0;
  228. });
  229. };
  230. /**
  231. * Add a mesh as LOD level triggered at the given distance.
  232. * tuto : http://doc.babylonjs.com/tutorials/How_to_use_LOD
  233. * @param {number} distance The distance from the center of the object to show this level
  234. * @param {Mesh} mesh The mesh to be added as LOD level
  235. * @return {Mesh} This mesh (for chaining)
  236. */
  237. Mesh.prototype.addLODLevel = function (distance, mesh) {
  238. if (mesh && mesh._masterMesh) {
  239. BABYLON.Tools.Warn("You cannot use a mesh as LOD level twice");
  240. return this;
  241. }
  242. var level = new BABYLON.Internals.MeshLODLevel(distance, mesh);
  243. this._LODLevels.push(level);
  244. if (mesh) {
  245. mesh._masterMesh = this;
  246. }
  247. this._sortLODLevels();
  248. return this;
  249. };
  250. /**
  251. * Returns the LOD level mesh at the passed distance or null if not found.
  252. * It is related to the method `addLODLevel(distance, mesh)`.
  253. * tuto : http://doc.babylonjs.com/tutorials/How_to_use_LOD
  254. */
  255. Mesh.prototype.getLODLevelAtDistance = function (distance) {
  256. for (var index = 0; index < this._LODLevels.length; index++) {
  257. var level = this._LODLevels[index];
  258. if (level.distance === distance) {
  259. return level.mesh;
  260. }
  261. }
  262. return null;
  263. };
  264. /**
  265. * Remove a mesh from the LOD array
  266. * tuto : http://doc.babylonjs.com/tutorials/How_to_use_LOD
  267. * @param {Mesh} mesh The mesh to be removed.
  268. * @return {Mesh} This mesh (for chaining)
  269. */
  270. Mesh.prototype.removeLODLevel = function (mesh) {
  271. for (var index = 0; index < this._LODLevels.length; index++) {
  272. if (this._LODLevels[index].mesh === mesh) {
  273. this._LODLevels.splice(index, 1);
  274. if (mesh) {
  275. mesh._masterMesh = null;
  276. }
  277. }
  278. }
  279. this._sortLODLevels();
  280. return this;
  281. };
  282. /**
  283. * Returns the registered LOD mesh distant from the parameter `camera` position if any, else returns the current mesh.
  284. * tuto : http://doc.babylonjs.com/tutorials/How_to_use_LOD
  285. */
  286. Mesh.prototype.getLOD = function (camera, boundingSphere) {
  287. if (!this._LODLevels || this._LODLevels.length === 0) {
  288. return this;
  289. }
  290. var distanceToCamera = (boundingSphere ? boundingSphere : this.getBoundingInfo().boundingSphere).centerWorld.subtract(camera.globalPosition).length();
  291. if (this._LODLevels[this._LODLevels.length - 1].distance > distanceToCamera) {
  292. if (this.onLODLevelSelection) {
  293. this.onLODLevelSelection(distanceToCamera, this, this._LODLevels[this._LODLevels.length - 1].mesh);
  294. }
  295. return this;
  296. }
  297. for (var index = 0; index < this._LODLevels.length; index++) {
  298. var level = this._LODLevels[index];
  299. if (level.distance < distanceToCamera) {
  300. if (level.mesh) {
  301. level.mesh._preActivate();
  302. level.mesh._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);
  303. }
  304. if (this.onLODLevelSelection) {
  305. this.onLODLevelSelection(distanceToCamera, this, level.mesh);
  306. }
  307. return level.mesh;
  308. }
  309. }
  310. if (this.onLODLevelSelection) {
  311. this.onLODLevelSelection(distanceToCamera, this, this);
  312. }
  313. return this;
  314. };
  315. Object.defineProperty(Mesh.prototype, "geometry", {
  316. /**
  317. * Returns the mesh internal Geometry object.
  318. */
  319. get: function () {
  320. return this._geometry;
  321. },
  322. enumerable: true,
  323. configurable: true
  324. });
  325. /**
  326. * Returns a positive integer : the total number of vertices within the mesh geometry or zero if the mesh has no geometry.
  327. */
  328. Mesh.prototype.getTotalVertices = function () {
  329. if (!this._geometry) {
  330. return 0;
  331. }
  332. return this._geometry.getTotalVertices();
  333. };
  334. /**
  335. * Returns an array of integers or floats, or a Float32Array, depending on the requested `kind` (positions, indices, normals, etc).
  336. * If `copywhenShared` is true (default false) and if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one.
  337. * Returns null if the mesh has no geometry or no vertex buffer.
  338. * Possible `kind` values :
  339. * - BABYLON.VertexBuffer.PositionKind
  340. * - BABYLON.VertexBuffer.UVKind
  341. * - BABYLON.VertexBuffer.UV2Kind
  342. * - BABYLON.VertexBuffer.UV3Kind
  343. * - BABYLON.VertexBuffer.UV4Kind
  344. * - BABYLON.VertexBuffer.UV5Kind
  345. * - BABYLON.VertexBuffer.UV6Kind
  346. * - BABYLON.VertexBuffer.ColorKind
  347. * - BABYLON.VertexBuffer.MatricesIndicesKind
  348. * - BABYLON.VertexBuffer.MatricesIndicesExtraKind
  349. * - BABYLON.VertexBuffer.MatricesWeightsKind
  350. * - BABYLON.VertexBuffer.MatricesWeightsExtraKind
  351. */
  352. Mesh.prototype.getVerticesData = function (kind, copyWhenShared) {
  353. if (!this._geometry) {
  354. return null;
  355. }
  356. return this._geometry.getVerticesData(kind, copyWhenShared);
  357. };
  358. /**
  359. * Returns the mesh VertexBuffer object from the requested `kind` : positions, indices, normals, etc.
  360. * Returns `undefined` if the mesh has no geometry.
  361. * Possible `kind` values :
  362. * - BABYLON.VertexBuffer.PositionKind
  363. * - BABYLON.VertexBuffer.UVKind
  364. * - BABYLON.VertexBuffer.UV2Kind
  365. * - BABYLON.VertexBuffer.UV3Kind
  366. * - BABYLON.VertexBuffer.UV4Kind
  367. * - BABYLON.VertexBuffer.UV5Kind
  368. * - BABYLON.VertexBuffer.UV6Kind
  369. * - BABYLON.VertexBuffer.ColorKind
  370. * - BABYLON.VertexBuffer.MatricesIndicesKind
  371. * - BABYLON.VertexBuffer.MatricesIndicesExtraKind
  372. * - BABYLON.VertexBuffer.MatricesWeightsKind
  373. * - BABYLON.VertexBuffer.MatricesWeightsExtraKind
  374. */
  375. Mesh.prototype.getVertexBuffer = function (kind) {
  376. if (!this._geometry) {
  377. return undefined;
  378. }
  379. return this._geometry.getVertexBuffer(kind);
  380. };
  381. /**
  382. * Returns a boolean depending on the existence of the Vertex Data for the requested `kind`.
  383. * Possible `kind` values :
  384. * - BABYLON.VertexBuffer.PositionKind
  385. * - BABYLON.VertexBuffer.UVKind
  386. * - BABYLON.VertexBuffer.UV2Kind
  387. * - BABYLON.VertexBuffer.UV3Kind
  388. * - BABYLON.VertexBuffer.UV4Kind
  389. * - BABYLON.VertexBuffer.UV5Kind
  390. * - BABYLON.VertexBuffer.UV6Kind
  391. * - BABYLON.VertexBuffer.ColorKind
  392. * - BABYLON.VertexBuffer.MatricesIndicesKind
  393. * - BABYLON.VertexBuffer.MatricesIndicesExtraKind
  394. * - BABYLON.VertexBuffer.MatricesWeightsKind
  395. * - BABYLON.VertexBuffer.MatricesWeightsExtraKind
  396. */
  397. Mesh.prototype.isVerticesDataPresent = function (kind) {
  398. if (!this._geometry) {
  399. if (this._delayInfo) {
  400. return this._delayInfo.indexOf(kind) !== -1;
  401. }
  402. return false;
  403. }
  404. return this._geometry.isVerticesDataPresent(kind);
  405. };
  406. /**
  407. * Returns a string : the list of existing `kinds` of Vertex Data for this mesh.
  408. * Possible `kind` values :
  409. * - BABYLON.VertexBuffer.PositionKind
  410. * - BABYLON.VertexBuffer.UVKind
  411. * - BABYLON.VertexBuffer.UV2Kind
  412. * - BABYLON.VertexBuffer.UV3Kind
  413. * - BABYLON.VertexBuffer.UV4Kind
  414. * - BABYLON.VertexBuffer.UV5Kind
  415. * - BABYLON.VertexBuffer.UV6Kind
  416. * - BABYLON.VertexBuffer.ColorKind
  417. * - BABYLON.VertexBuffer.MatricesIndicesKind
  418. * - BABYLON.VertexBuffer.MatricesIndicesExtraKind
  419. * - BABYLON.VertexBuffer.MatricesWeightsKind
  420. * - BABYLON.VertexBuffer.MatricesWeightsExtraKind
  421. */
  422. Mesh.prototype.getVerticesDataKinds = function () {
  423. if (!this._geometry) {
  424. var result = [];
  425. if (this._delayInfo) {
  426. for (var kind in this._delayInfo) {
  427. result.push(kind);
  428. }
  429. }
  430. return result;
  431. }
  432. return this._geometry.getVerticesDataKinds();
  433. };
  434. /**
  435. * Returns a positive integer : the total number of indices in this mesh geometry.
  436. * Returns zero if the mesh has no geometry.
  437. */
  438. Mesh.prototype.getTotalIndices = function () {
  439. if (!this._geometry) {
  440. return 0;
  441. }
  442. return this._geometry.getTotalIndices();
  443. };
  444. /**
  445. * Returns an array of integers or a Int32Array populated with the mesh indices.
  446. * If the parameter `copyWhenShared` is true (default false) and and if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one.
  447. * Returns an empty array if the mesh has no geometry.
  448. */
  449. Mesh.prototype.getIndices = function (copyWhenShared) {
  450. if (!this._geometry) {
  451. return [];
  452. }
  453. return this._geometry.getIndices(copyWhenShared);
  454. };
  455. Object.defineProperty(Mesh.prototype, "isBlocked", {
  456. get: function () {
  457. return this._masterMesh !== null && this._masterMesh !== undefined;
  458. },
  459. enumerable: true,
  460. configurable: true
  461. });
  462. /**
  463. * Boolean : true once the mesh is ready after all the delayed process (loading, etc) are complete.
  464. */
  465. Mesh.prototype.isReady = function () {
  466. if (this.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_LOADING) {
  467. return false;
  468. }
  469. return _super.prototype.isReady.call(this);
  470. };
  471. /**
  472. * Boolean : true if the mesh has been disposed.
  473. */
  474. Mesh.prototype.isDisposed = function () {
  475. return this._isDisposed;
  476. };
  477. Object.defineProperty(Mesh.prototype, "sideOrientation", {
  478. get: function () {
  479. return this._sideOrientation;
  480. },
  481. /**
  482. * Sets the mesh side orientation : BABYLON.Mesh.FRONTSIDE, BABYLON.Mesh.BACKSIDE, BABYLON.Mesh.DOUBLESIDE or BABYLON.Mesh.DEFAULTSIDE
  483. * tuto : http://doc.babylonjs.com/tutorials/Discover_Basic_Elements#side-orientation
  484. */
  485. set: function (sideO) {
  486. this._sideOrientation = sideO;
  487. },
  488. enumerable: true,
  489. configurable: true
  490. });
  491. Object.defineProperty(Mesh.prototype, "areNormalsFrozen", {
  492. /**
  493. * Boolean : true if the normals aren't to be recomputed on next mesh `positions` array update.
  494. * This property is pertinent only for updatable parametric shapes.
  495. */
  496. get: function () {
  497. return this._areNormalsFrozen;
  498. },
  499. enumerable: true,
  500. configurable: true
  501. });
  502. /**
  503. * This function affects parametric shapes on vertex position update only : ribbons, tubes, etc.
  504. * It has no effect at all on other shapes.
  505. * It prevents the mesh normals from being recomputed on next `positions` array update.
  506. */
  507. Mesh.prototype.freezeNormals = function () {
  508. this._areNormalsFrozen = true;
  509. };
  510. /**
  511. * This function affects parametric shapes on vertex position update only : ribbons, tubes, etc.
  512. * It has no effect at all on other shapes.
  513. * It reactivates the mesh normals computation if it was previously frozen.
  514. */
  515. Mesh.prototype.unfreezeNormals = function () {
  516. this._areNormalsFrozen = false;
  517. };
  518. Object.defineProperty(Mesh.prototype, "overridenInstanceCount", {
  519. /**
  520. * Overrides instance count. Only applicable when custom instanced InterleavedVertexBuffer are used rather than InstancedMeshs
  521. */
  522. set: function (count) {
  523. this._overridenInstanceCount = count;
  524. },
  525. enumerable: true,
  526. configurable: true
  527. });
  528. // Methods
  529. Mesh.prototype._preActivate = function () {
  530. var sceneRenderId = this.getScene().getRenderId();
  531. if (this._preActivateId === sceneRenderId) {
  532. return;
  533. }
  534. this._preActivateId = sceneRenderId;
  535. this._visibleInstances = null;
  536. };
  537. Mesh.prototype._preActivateForIntermediateRendering = function (renderId) {
  538. if (this._visibleInstances) {
  539. this._visibleInstances.intermediateDefaultRenderId = renderId;
  540. }
  541. };
  542. Mesh.prototype._registerInstanceForRenderId = function (instance, renderId) {
  543. if (!this._visibleInstances) {
  544. this._visibleInstances = {};
  545. this._visibleInstances.defaultRenderId = renderId;
  546. this._visibleInstances.selfDefaultRenderId = this._renderId;
  547. }
  548. if (!this._visibleInstances[renderId]) {
  549. this._visibleInstances[renderId] = new Array();
  550. }
  551. this._visibleInstances[renderId].push(instance);
  552. };
  553. /**
  554. * This method recomputes and sets a new BoundingInfo to the mesh unless it is locked.
  555. * This means the mesh underlying bounding box and sphere are recomputed.
  556. */
  557. Mesh.prototype.refreshBoundingInfo = function () {
  558. if (this._boundingInfo.isLocked) {
  559. return;
  560. }
  561. var data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  562. if (data) {
  563. var extend = BABYLON.Tools.ExtractMinAndMax(data, 0, this.getTotalVertices());
  564. this._boundingInfo = new BABYLON.BoundingInfo(extend.minimum, extend.maximum);
  565. }
  566. if (this.subMeshes) {
  567. for (var index = 0; index < this.subMeshes.length; index++) {
  568. this.subMeshes[index].refreshBoundingInfo();
  569. }
  570. }
  571. this._updateBoundingInfo();
  572. };
  573. Mesh.prototype._createGlobalSubMesh = function () {
  574. var totalVertices = this.getTotalVertices();
  575. if (!totalVertices || !this.getIndices()) {
  576. return null;
  577. }
  578. this.releaseSubMeshes();
  579. return new BABYLON.SubMesh(0, 0, totalVertices, 0, this.getTotalIndices(), this);
  580. };
  581. Mesh.prototype.subdivide = function (count) {
  582. if (count < 1) {
  583. return;
  584. }
  585. var totalIndices = this.getTotalIndices();
  586. var subdivisionSize = (totalIndices / count) | 0;
  587. var offset = 0;
  588. // Ensure that subdivisionSize is a multiple of 3
  589. while (subdivisionSize % 3 !== 0) {
  590. subdivisionSize++;
  591. }
  592. this.releaseSubMeshes();
  593. for (var index = 0; index < count; index++) {
  594. if (offset >= totalIndices) {
  595. break;
  596. }
  597. BABYLON.SubMesh.CreateFromIndices(0, offset, Math.min(subdivisionSize, totalIndices - offset), this);
  598. offset += subdivisionSize;
  599. }
  600. this.synchronizeInstances();
  601. };
  602. /**
  603. * Sets the vertex data of the mesh geometry for the requested `kind`.
  604. * If the mesh has no geometry, a new Geometry object is set to the mesh and then passed this vertex data.
  605. * The `data` are either a numeric array either a Float32Array.
  606. * The parameter `updatable` is passed as is to the underlying Geometry object constructor (if initianilly none) or updater.
  607. * The parameter `stride` is an optional positive integer, it is usually automatically deducted from the `kind` (3 for positions or normals, 2 for UV, etc).
  608. * Note that a new underlying VertexBuffer object is created each call.
  609. * If the `kind` is the `PositionKind`, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed.
  610. *
  611. * Possible `kind` values :
  612. * - BABYLON.VertexBuffer.PositionKind
  613. * - BABYLON.VertexBuffer.UVKind
  614. * - BABYLON.VertexBuffer.UV2Kind
  615. * - BABYLON.VertexBuffer.UV3Kind
  616. * - BABYLON.VertexBuffer.UV4Kind
  617. * - BABYLON.VertexBuffer.UV5Kind
  618. * - BABYLON.VertexBuffer.UV6Kind
  619. * - BABYLON.VertexBuffer.ColorKind
  620. * - BABYLON.VertexBuffer.MatricesIndicesKind
  621. * - BABYLON.VertexBuffer.MatricesIndicesExtraKind
  622. * - BABYLON.VertexBuffer.MatricesWeightsKind
  623. * - BABYLON.VertexBuffer.MatricesWeightsExtraKind
  624. */
  625. Mesh.prototype.setVerticesData = function (kind, data, updatable, stride) {
  626. if (!this._geometry) {
  627. var vertexData = new BABYLON.VertexData();
  628. vertexData.set(data, kind);
  629. var scene = this.getScene();
  630. new BABYLON.Geometry(BABYLON.Geometry.RandomId(), scene, vertexData, updatable, this);
  631. }
  632. else {
  633. this._geometry.setVerticesData(kind, data, updatable, stride);
  634. }
  635. };
  636. Mesh.prototype.setVerticesBuffer = function (buffer) {
  637. if (!this._geometry) {
  638. var scene = this.getScene();
  639. new BABYLON.Geometry(BABYLON.Geometry.RandomId(), scene).applyToMesh(this);
  640. }
  641. this._geometry.setVerticesBuffer(buffer);
  642. };
  643. /**
  644. * Updates the existing vertex data of the mesh geometry for the requested `kind`.
  645. * If the mesh has no geometry, it is simply returned as it is.
  646. * The `data` are either a numeric array either a Float32Array.
  647. * No new underlying VertexBuffer object is created.
  648. * If the `kind` is the `PositionKind` and if `updateExtends` is true, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed.
  649. * If the parameter `makeItUnique` is true, a new global geometry is created from this positions and is set to the mesh.
  650. *
  651. * Possible `kind` values :
  652. * - BABYLON.VertexBuffer.PositionKind
  653. * - BABYLON.VertexBuffer.UVKind
  654. * - BABYLON.VertexBuffer.UV2Kind
  655. * - BABYLON.VertexBuffer.UV3Kind
  656. * - BABYLON.VertexBuffer.UV4Kind
  657. * - BABYLON.VertexBuffer.UV5Kind
  658. * - BABYLON.VertexBuffer.UV6Kind
  659. * - BABYLON.VertexBuffer.ColorKind
  660. * - BABYLON.VertexBuffer.MatricesIndicesKind
  661. * - BABYLON.VertexBuffer.MatricesIndicesExtraKind
  662. * - BABYLON.VertexBuffer.MatricesWeightsKind
  663. * - BABYLON.VertexBuffer.MatricesWeightsExtraKind
  664. */
  665. Mesh.prototype.updateVerticesData = function (kind, data, updateExtends, makeItUnique) {
  666. if (!this._geometry) {
  667. return;
  668. }
  669. if (!makeItUnique) {
  670. this._geometry.updateVerticesData(kind, data, updateExtends);
  671. }
  672. else {
  673. this.makeGeometryUnique();
  674. this.updateVerticesData(kind, data, updateExtends, false);
  675. }
  676. };
  677. /**
  678. * Deprecated since BabylonJS v2.3
  679. */
  680. Mesh.prototype.updateVerticesDataDirectly = function (kind, data, offset, makeItUnique) {
  681. BABYLON.Tools.Warn("Mesh.updateVerticesDataDirectly deprecated since 2.3.");
  682. if (!this._geometry) {
  683. return;
  684. }
  685. if (!makeItUnique) {
  686. this._geometry.updateVerticesDataDirectly(kind, data, offset);
  687. }
  688. else {
  689. this.makeGeometryUnique();
  690. this.updateVerticesDataDirectly(kind, data, offset, false);
  691. }
  692. };
  693. /**
  694. * This method updates the vertex positions of an updatable mesh according to the `positionFunction` returned values.
  695. * tuto : http://doc.babylonjs.com/tutorials/How_to_dynamically_morph_a_mesh#other-shapes-updatemeshpositions
  696. * The parameter `positionFunction` is a simple JS function what is passed the mesh `positions` array. It doesn't need to return anything.
  697. * The parameter `computeNormals` is a boolean (default true) to enable/disable the mesh normal recomputation after the vertex position update.
  698. */
  699. Mesh.prototype.updateMeshPositions = function (positionFunction, computeNormals) {
  700. if (computeNormals === void 0) { computeNormals = true; }
  701. var positions = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  702. positionFunction(positions);
  703. this.updateVerticesData(BABYLON.VertexBuffer.PositionKind, positions, false, false);
  704. if (computeNormals) {
  705. var indices = this.getIndices();
  706. var normals = this.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  707. BABYLON.VertexData.ComputeNormals(positions, indices, normals);
  708. this.updateVerticesData(BABYLON.VertexBuffer.NormalKind, normals, false, false);
  709. }
  710. };
  711. Mesh.prototype.makeGeometryUnique = function () {
  712. if (!this._geometry) {
  713. return;
  714. }
  715. var geometry = this._geometry.copy(BABYLON.Geometry.RandomId());
  716. geometry.applyToMesh(this);
  717. };
  718. /**
  719. * Sets the mesh indices.
  720. * Expects an array populated with integers or a Int32Array.
  721. * If the mesh has no geometry, a new `Geometry` object is created and set to the mesh.
  722. * This method creates a new index buffer each call.
  723. */
  724. Mesh.prototype.setIndices = function (indices, totalVertices) {
  725. if (!this._geometry) {
  726. var vertexData = new BABYLON.VertexData();
  727. vertexData.indices = indices;
  728. var scene = this.getScene();
  729. new BABYLON.Geometry(BABYLON.Geometry.RandomId(), scene, vertexData, false, this);
  730. }
  731. else {
  732. this._geometry.setIndices(indices, totalVertices);
  733. }
  734. };
  735. /**
  736. * Invert the geometry to move from a right handed system to a left handed one.
  737. */
  738. Mesh.prototype.toLeftHanded = function () {
  739. if (!this._geometry) {
  740. return;
  741. }
  742. this._geometry.toLeftHanded();
  743. };
  744. Mesh.prototype._bind = function (subMesh, effect, fillMode) {
  745. var engine = this.getScene().getEngine();
  746. // Wireframe
  747. var indexToBind;
  748. if (this._unIndexed) {
  749. indexToBind = null;
  750. }
  751. else {
  752. switch (fillMode) {
  753. case BABYLON.Material.PointFillMode:
  754. indexToBind = null;
  755. break;
  756. case BABYLON.Material.WireFrameFillMode:
  757. indexToBind = subMesh.getLinesIndexBuffer(this.getIndices(), engine);
  758. break;
  759. default:
  760. case BABYLON.Material.TriangleFillMode:
  761. indexToBind = this._unIndexed ? null : this._geometry.getIndexBuffer();
  762. break;
  763. }
  764. }
  765. // VBOs
  766. engine.bindBuffers(this._geometry.getVertexBuffers(), indexToBind, effect);
  767. };
  768. Mesh.prototype._draw = function (subMesh, fillMode, instancesCount) {
  769. if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
  770. return;
  771. }
  772. this.onBeforeDrawObservable.notifyObservers(this);
  773. var engine = this.getScene().getEngine();
  774. // Draw order
  775. switch (fillMode) {
  776. case BABYLON.Material.PointFillMode:
  777. engine.drawPointClouds(subMesh.verticesStart, subMesh.verticesCount, instancesCount);
  778. break;
  779. case BABYLON.Material.WireFrameFillMode:
  780. if (this._unIndexed) {
  781. engine.drawUnIndexed(false, subMesh.verticesStart, subMesh.verticesCount, instancesCount);
  782. }
  783. else {
  784. engine.draw(false, 0, subMesh.linesIndexCount, instancesCount);
  785. }
  786. break;
  787. default:
  788. if (this._unIndexed) {
  789. engine.drawUnIndexed(true, subMesh.verticesStart, subMesh.verticesCount, instancesCount);
  790. }
  791. else {
  792. engine.draw(true, subMesh.indexStart, subMesh.indexCount, instancesCount);
  793. }
  794. }
  795. };
  796. /**
  797. * Registers for this mesh a javascript function called just before the rendering process.
  798. * This function is passed the current mesh and doesn't return anything.
  799. */
  800. Mesh.prototype.registerBeforeRender = function (func) {
  801. this.onBeforeRenderObservable.add(func);
  802. };
  803. /**
  804. * Disposes a previously registered javascript function called before the rendering.
  805. * This function is passed the current mesh and doesn't return anything.
  806. */
  807. Mesh.prototype.unregisterBeforeRender = function (func) {
  808. this.onBeforeRenderObservable.removeCallback(func);
  809. };
  810. /**
  811. * Registers for this mesh a javascript function called just after the rendering is complete.
  812. * This function is passed the current mesh and doesn't return anything.
  813. */
  814. Mesh.prototype.registerAfterRender = function (func) {
  815. this.onAfterRenderObservable.add(func);
  816. };
  817. /**
  818. * Disposes a previously registered javascript function called after the rendering.
  819. * This function is passed the current mesh and doesn't return anything.
  820. */
  821. Mesh.prototype.unregisterAfterRender = function (func) {
  822. this.onAfterRenderObservable.removeCallback(func);
  823. };
  824. Mesh.prototype._getInstancesRenderList = function (subMeshId) {
  825. var scene = this.getScene();
  826. this._batchCache.mustReturn = false;
  827. this._batchCache.renderSelf[subMeshId] = this.isEnabled() && this.isVisible;
  828. this._batchCache.visibleInstances[subMeshId] = null;
  829. if (this._visibleInstances) {
  830. var currentRenderId = scene.getRenderId();
  831. var defaultRenderId = (scene._isInIntermediateRendering() ? this._visibleInstances.intermediateDefaultRenderId : this._visibleInstances.defaultRenderId);
  832. this._batchCache.visibleInstances[subMeshId] = this._visibleInstances[currentRenderId];
  833. var selfRenderId = this._renderId;
  834. if (!this._batchCache.visibleInstances[subMeshId] && defaultRenderId) {
  835. this._batchCache.visibleInstances[subMeshId] = this._visibleInstances[defaultRenderId];
  836. currentRenderId = Math.max(defaultRenderId, currentRenderId);
  837. selfRenderId = Math.max(this._visibleInstances.selfDefaultRenderId, currentRenderId);
  838. }
  839. if (this._batchCache.visibleInstances[subMeshId] && this._batchCache.visibleInstances[subMeshId].length) {
  840. if (this._renderIdForInstances[subMeshId] === currentRenderId) {
  841. this._batchCache.mustReturn = true;
  842. return this._batchCache;
  843. }
  844. if (currentRenderId !== selfRenderId) {
  845. this._batchCache.renderSelf[subMeshId] = false;
  846. }
  847. }
  848. this._renderIdForInstances[subMeshId] = currentRenderId;
  849. }
  850. return this._batchCache;
  851. };
  852. Mesh.prototype._renderWithInstances = function (subMesh, fillMode, batch, effect, engine) {
  853. var visibleInstances = batch.visibleInstances[subMesh._id];
  854. var matricesCount = visibleInstances.length + 1;
  855. var bufferSize = matricesCount * 16 * 4;
  856. var currentInstancesBufferSize = this._instancesBufferSize;
  857. var instancesBuffer = this._instancesBuffer;
  858. while (this._instancesBufferSize < bufferSize) {
  859. this._instancesBufferSize *= 2;
  860. }
  861. if (!this._instancesData || currentInstancesBufferSize != this._instancesBufferSize) {
  862. this._instancesData = new Float32Array(this._instancesBufferSize / 4);
  863. }
  864. var offset = 0;
  865. var instancesCount = 0;
  866. var world = this.getWorldMatrix();
  867. if (batch.renderSelf[subMesh._id]) {
  868. world.copyToArray(this._instancesData, offset);
  869. offset += 16;
  870. instancesCount++;
  871. }
  872. if (visibleInstances) {
  873. for (var instanceIndex = 0; instanceIndex < visibleInstances.length; instanceIndex++) {
  874. var instance = visibleInstances[instanceIndex];
  875. instance.getWorldMatrix().copyToArray(this._instancesData, offset);
  876. offset += 16;
  877. instancesCount++;
  878. }
  879. }
  880. if (!instancesBuffer || currentInstancesBufferSize != this._instancesBufferSize) {
  881. if (instancesBuffer) {
  882. instancesBuffer.dispose();
  883. }
  884. instancesBuffer = new BABYLON.Buffer(engine, this._instancesData, true, 16, false, true);
  885. this._instancesBuffer = instancesBuffer;
  886. this.setVerticesBuffer(instancesBuffer.createVertexBuffer("world0", 0, 4));
  887. this.setVerticesBuffer(instancesBuffer.createVertexBuffer("world1", 4, 4));
  888. this.setVerticesBuffer(instancesBuffer.createVertexBuffer("world2", 8, 4));
  889. this.setVerticesBuffer(instancesBuffer.createVertexBuffer("world3", 12, 4));
  890. engine.bindBuffers(this.geometry.getVertexBuffers(), this.geometry.getIndexBuffer(), effect);
  891. }
  892. else {
  893. instancesBuffer.updateDirectly(this._instancesData, 0, instancesCount);
  894. }
  895. this._draw(subMesh, fillMode, instancesCount);
  896. engine.unbindInstanceAttributes();
  897. };
  898. Mesh.prototype._processRendering = function (subMesh, effect, fillMode, batch, hardwareInstancedRendering, onBeforeDraw) {
  899. var scene = this.getScene();
  900. var engine = scene.getEngine();
  901. if (hardwareInstancedRendering) {
  902. this._renderWithInstances(subMesh, fillMode, batch, effect, engine);
  903. }
  904. else {
  905. if (batch.renderSelf[subMesh._id]) {
  906. // Draw
  907. if (onBeforeDraw) {
  908. onBeforeDraw(false, this.getWorldMatrix());
  909. }
  910. this._draw(subMesh, fillMode, this._overridenInstanceCount);
  911. }
  912. if (batch.visibleInstances[subMesh._id]) {
  913. for (var instanceIndex = 0; instanceIndex < batch.visibleInstances[subMesh._id].length; instanceIndex++) {
  914. var instance = batch.visibleInstances[subMesh._id][instanceIndex];
  915. // World
  916. var world = instance.getWorldMatrix();
  917. if (onBeforeDraw) {
  918. onBeforeDraw(true, world);
  919. }
  920. // Draw
  921. this._draw(subMesh, fillMode);
  922. }
  923. }
  924. }
  925. };
  926. /**
  927. * Triggers the draw call for the mesh.
  928. * Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager.
  929. */
  930. Mesh.prototype.render = function (subMesh, enableAlphaMode) {
  931. var scene = this.getScene();
  932. // Managing instances
  933. var batch = this._getInstancesRenderList(subMesh._id);
  934. if (batch.mustReturn) {
  935. return;
  936. }
  937. // Checking geometry state
  938. if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
  939. return;
  940. }
  941. var callbackIndex;
  942. this.onBeforeRenderObservable.notifyObservers(this);
  943. var engine = scene.getEngine();
  944. var hardwareInstancedRendering = (engine.getCaps().instancedArrays !== null) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
  945. // Material
  946. var effectiveMaterial = subMesh.getMaterial();
  947. if (!effectiveMaterial || !effectiveMaterial.isReady(this, hardwareInstancedRendering)) {
  948. return;
  949. }
  950. // Outline - step 1
  951. var savedDepthWrite = engine.getDepthWrite();
  952. if (this.renderOutline) {
  953. engine.setDepthWrite(false);
  954. scene.getOutlineRenderer().render(subMesh, batch);
  955. engine.setDepthWrite(savedDepthWrite);
  956. }
  957. effectiveMaterial._preBind();
  958. var effect = effectiveMaterial.getEffect();
  959. // Bind
  960. var fillMode = scene.forcePointsCloud ? BABYLON.Material.PointFillMode : (scene.forceWireframe ? BABYLON.Material.WireFrameFillMode : effectiveMaterial.fillMode);
  961. this._bind(subMesh, effect, fillMode);
  962. var world = this.getWorldMatrix();
  963. effectiveMaterial.bind(world, this);
  964. // Alpha mode
  965. if (enableAlphaMode) {
  966. engine.setAlphaMode(effectiveMaterial.alphaMode);
  967. }
  968. // Draw
  969. this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, function (isInstance, world) {
  970. if (isInstance) {
  971. effectiveMaterial.bindOnlyWorldMatrix(world);
  972. }
  973. });
  974. // Unbind
  975. effectiveMaterial.unbind();
  976. // Outline - step 2
  977. if (this.renderOutline && savedDepthWrite) {
  978. engine.setDepthWrite(true);
  979. engine.setColorWrite(false);
  980. scene.getOutlineRenderer().render(subMesh, batch);
  981. engine.setColorWrite(true);
  982. }
  983. // Overlay
  984. if (this.renderOverlay) {
  985. var currentMode = engine.getAlphaMode();
  986. engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
  987. scene.getOutlineRenderer().render(subMesh, batch, true);
  988. engine.setAlphaMode(currentMode);
  989. }
  990. this.onAfterRenderObservable.notifyObservers(this);
  991. };
  992. /**
  993. * Returns an array populated with ParticleSystem objects whose the mesh is the emitter.
  994. */
  995. Mesh.prototype.getEmittedParticleSystems = function () {
  996. var results = new Array();
  997. for (var index = 0; index < this.getScene().particleSystems.length; index++) {
  998. var particleSystem = this.getScene().particleSystems[index];
  999. if (particleSystem.emitter === this) {
  1000. results.push(particleSystem);
  1001. }
  1002. }
  1003. return results;
  1004. };
  1005. /**
  1006. * Returns an array populated with ParticleSystem objects whose the mesh or its children are the emitter.
  1007. */
  1008. Mesh.prototype.getHierarchyEmittedParticleSystems = function () {
  1009. var results = new Array();
  1010. var descendants = this.getDescendants();
  1011. descendants.push(this);
  1012. for (var index = 0; index < this.getScene().particleSystems.length; index++) {
  1013. var particleSystem = this.getScene().particleSystems[index];
  1014. if (descendants.indexOf(particleSystem.emitter) !== -1) {
  1015. results.push(particleSystem);
  1016. }
  1017. }
  1018. return results;
  1019. };
  1020. Mesh.prototype._checkDelayState = function () {
  1021. var _this = this;
  1022. var that = this;
  1023. var scene = this.getScene();
  1024. if (this._geometry) {
  1025. this._geometry.load(scene);
  1026. }
  1027. else if (that.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_NOTLOADED) {
  1028. that.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_LOADING;
  1029. scene._addPendingData(that);
  1030. var getBinaryData = (this.delayLoadingFile.indexOf(".babylonbinarymeshdata") !== -1);
  1031. BABYLON.Tools.LoadFile(this.delayLoadingFile, function (data) {
  1032. if (data instanceof ArrayBuffer) {
  1033. _this._delayLoadingFunction(data, _this);
  1034. }
  1035. else {
  1036. _this._delayLoadingFunction(JSON.parse(data), _this);
  1037. }
  1038. _this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_LOADED;
  1039. scene._removePendingData(_this);
  1040. }, function () { }, scene.database, getBinaryData);
  1041. }
  1042. };
  1043. /**
  1044. * Boolean, true is the mesh in the frustum defined by the Plane objects from the `frustumPlanes` array parameter.
  1045. */
  1046. Mesh.prototype.isInFrustum = function (frustumPlanes) {
  1047. if (this.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_LOADING) {
  1048. return false;
  1049. }
  1050. if (!_super.prototype.isInFrustum.call(this, frustumPlanes)) {
  1051. return false;
  1052. }
  1053. this._checkDelayState();
  1054. return true;
  1055. };
  1056. /**
  1057. * Sets the mesh material by the material or multiMaterial `id` property.
  1058. * The material `id` is a string identifying the material or the multiMaterial.
  1059. * This method returns nothing.
  1060. */
  1061. Mesh.prototype.setMaterialByID = function (id) {
  1062. var materials = this.getScene().materials;
  1063. var index;
  1064. for (index = 0; index < materials.length; index++) {
  1065. if (materials[index].id === id) {
  1066. this.material = materials[index];
  1067. return;
  1068. }
  1069. }
  1070. // Multi
  1071. var multiMaterials = this.getScene().multiMaterials;
  1072. for (index = 0; index < multiMaterials.length; index++) {
  1073. if (multiMaterials[index].id === id) {
  1074. this.material = multiMaterials[index];
  1075. return;
  1076. }
  1077. }
  1078. };
  1079. /**
  1080. * Returns as a new array populated with the mesh material and/or skeleton, if any.
  1081. */
  1082. Mesh.prototype.getAnimatables = function () {
  1083. var results = [];
  1084. if (this.material) {
  1085. results.push(this.material);
  1086. }
  1087. if (this.skeleton) {
  1088. results.push(this.skeleton);
  1089. }
  1090. return results;
  1091. };
  1092. /**
  1093. * Modifies the mesh geometry according to the passed transformation matrix.
  1094. * This method returns nothing but it really modifies the mesh even if it's originally not set as updatable.
  1095. * The mesh normals are modified accordingly the same transformation.
  1096. * tuto : http://doc.babylonjs.com/tutorials/How_Rotations_and_Translations_Work#baking-transform
  1097. * Note that, under the hood, this method sets a new VertexBuffer each call.
  1098. */
  1099. Mesh.prototype.bakeTransformIntoVertices = function (transform) {
  1100. // Position
  1101. if (!this.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
  1102. return;
  1103. }
  1104. var submeshes = this.subMeshes.splice(0);
  1105. this._resetPointsArrayCache();
  1106. var data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  1107. var temp = [];
  1108. var index;
  1109. for (index = 0; index < data.length; index += 3) {
  1110. BABYLON.Vector3.TransformCoordinates(BABYLON.Vector3.FromArray(data, index), transform).toArray(temp, index);
  1111. }
  1112. this.setVerticesData(BABYLON.VertexBuffer.PositionKind, temp, this.getVertexBuffer(BABYLON.VertexBuffer.PositionKind).isUpdatable());
  1113. // Normals
  1114. if (!this.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
  1115. return;
  1116. }
  1117. data = this.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  1118. temp = [];
  1119. for (index = 0; index < data.length; index += 3) {
  1120. BABYLON.Vector3.TransformNormal(BABYLON.Vector3.FromArray(data, index), transform).normalize().toArray(temp, index);
  1121. }
  1122. this.setVerticesData(BABYLON.VertexBuffer.NormalKind, temp, this.getVertexBuffer(BABYLON.VertexBuffer.NormalKind).isUpdatable());
  1123. // flip faces?
  1124. if (transform.m[0] * transform.m[5] * transform.m[10] < 0) {
  1125. this.flipFaces();
  1126. }
  1127. // Restore submeshes
  1128. this.releaseSubMeshes();
  1129. this.subMeshes = submeshes;
  1130. };
  1131. /**
  1132. * Modifies the mesh geometry according to its own current World Matrix.
  1133. * The mesh World Matrix is then reset.
  1134. * This method returns nothing but really modifies the mesh even if it's originally not set as updatable.
  1135. * tuto : tuto : http://doc.babylonjs.com/tutorials/How_Rotations_and_Translations_Work#baking-transform
  1136. * Note that, under the hood, this method sets a new VertexBuffer each call.
  1137. */
  1138. Mesh.prototype.bakeCurrentTransformIntoVertices = function () {
  1139. this.bakeTransformIntoVertices(this.computeWorldMatrix(true));
  1140. this.scaling.copyFromFloats(1, 1, 1);
  1141. this.position.copyFromFloats(0, 0, 0);
  1142. this.rotation.copyFromFloats(0, 0, 0);
  1143. //only if quaternion is already set
  1144. if (this.rotationQuaternion) {
  1145. this.rotationQuaternion = BABYLON.Quaternion.Identity();
  1146. }
  1147. this._worldMatrix = BABYLON.Matrix.Identity();
  1148. };
  1149. // Cache
  1150. Mesh.prototype._resetPointsArrayCache = function () {
  1151. this._positions = null;
  1152. };
  1153. Mesh.prototype._generatePointsArray = function () {
  1154. if (this._positions)
  1155. return true;
  1156. this._positions = [];
  1157. var data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  1158. if (!data) {
  1159. return false;
  1160. }
  1161. for (var index = 0; index < data.length; index += 3) {
  1162. this._positions.push(BABYLON.Vector3.FromArray(data, index));
  1163. }
  1164. return true;
  1165. };
  1166. /**
  1167. * Returns a new Mesh object generated from the current mesh properties.
  1168. * This method must not get confused with createInstance().
  1169. * The parameter `name` is a string, the name given to the new mesh.
  1170. * The optional parameter `newParent` can be any `Node` object (default `null`).
  1171. * The optional parameter `doNotCloneChildren` (default `false`) allows/denies the recursive cloning of the original mesh children if any.
  1172. * The parameter `clonePhysicsImpostor` (default `true`) allows/denies the cloning in the same time of the original mesh `body` used by the physics engine, if any.
  1173. */
  1174. Mesh.prototype.clone = function (name, newParent, doNotCloneChildren, clonePhysicsImpostor) {
  1175. if (clonePhysicsImpostor === void 0) { clonePhysicsImpostor = true; }
  1176. return new Mesh(name, this.getScene(), newParent, this, doNotCloneChildren, clonePhysicsImpostor);
  1177. };
  1178. /**
  1179. * Disposes the mesh.
  1180. * This also frees the memory allocated under the hood to all the buffers used by WebGL.
  1181. */
  1182. Mesh.prototype.dispose = function (doNotRecurse) {
  1183. if (this._geometry) {
  1184. this._geometry.releaseForMesh(this, true);
  1185. }
  1186. // Instances
  1187. if (this._instancesBuffer) {
  1188. this._instancesBuffer.dispose();
  1189. this._instancesBuffer = null;
  1190. }
  1191. while (this.instances.length) {
  1192. this.instances[0].dispose();
  1193. }
  1194. _super.prototype.dispose.call(this, doNotRecurse);
  1195. };
  1196. /**
  1197. * Modifies the mesh geometry according to a displacement map.
  1198. * A displacement map is a colored image. Each pixel color value (actually a gradient computed from red, green, blue values) will give the displacement to apply to each mesh vertex.
  1199. * The mesh must be set as updatable. Its internal geometry is directly modified, no new buffer are allocated.
  1200. * This method returns nothing.
  1201. * The parameter `url` is a string, the URL from the image file is to be downloaded.
  1202. * The parameters `minHeight` and `maxHeight` are the lower and upper limits of the displacement.
  1203. * The parameter `onSuccess` is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
  1204. */
  1205. Mesh.prototype.applyDisplacementMap = function (url, minHeight, maxHeight, onSuccess) {
  1206. var _this = this;
  1207. var scene = this.getScene();
  1208. var onload = function (img) {
  1209. // Getting height map data
  1210. var canvas = document.createElement("canvas");
  1211. var context = canvas.getContext("2d");
  1212. var heightMapWidth = img.width;
  1213. var heightMapHeight = img.height;
  1214. canvas.width = heightMapWidth;
  1215. canvas.height = heightMapHeight;
  1216. context.drawImage(img, 0, 0);
  1217. // Create VertexData from map data
  1218. //Cast is due to wrong definition in lib.d.ts from ts 1.3 - https://github.com/Microsoft/TypeScript/issues/949
  1219. var buffer = context.getImageData(0, 0, heightMapWidth, heightMapHeight).data;
  1220. _this.applyDisplacementMapFromBuffer(buffer, heightMapWidth, heightMapHeight, minHeight, maxHeight);
  1221. //execute success callback, if set
  1222. if (onSuccess) {
  1223. onSuccess(_this);
  1224. }
  1225. };
  1226. BABYLON.Tools.LoadImage(url, onload, function () { }, scene.database);
  1227. };
  1228. /**
  1229. * Modifies the mesh geometry according to a displacementMap buffer.
  1230. * A displacement map is a colored image. Each pixel color value (actually a gradient computed from red, green, blue values) will give the displacement to apply to each mesh vertex.
  1231. * The mesh must be set as updatable. Its internal geometry is directly modified, no new buffer are allocated.
  1232. * This method returns nothing.
  1233. * The parameter `buffer` is a `Uint8Array` buffer containing series of `Uint8` lower than 255, the red, green, blue and alpha values of each successive pixel.
  1234. * The parameters `heightMapWidth` and `heightMapHeight` are positive integers to set the width and height of the buffer image.
  1235. * The parameters `minHeight` and `maxHeight` are the lower and upper limits of the displacement.
  1236. */
  1237. Mesh.prototype.applyDisplacementMapFromBuffer = function (buffer, heightMapWidth, heightMapHeight, minHeight, maxHeight) {
  1238. if (!this.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)
  1239. || !this.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)
  1240. || !this.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
  1241. BABYLON.Tools.Warn("Cannot call applyDisplacementMap: Given mesh is not complete. Position, Normal or UV are missing");
  1242. return;
  1243. }
  1244. var positions = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  1245. var normals = this.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  1246. var uvs = this.getVerticesData(BABYLON.VertexBuffer.UVKind);
  1247. var position = BABYLON.Vector3.Zero();
  1248. var normal = BABYLON.Vector3.Zero();
  1249. var uv = BABYLON.Vector2.Zero();
  1250. for (var index = 0; index < positions.length; index += 3) {
  1251. BABYLON.Vector3.FromArrayToRef(positions, index, position);
  1252. BABYLON.Vector3.FromArrayToRef(normals, index, normal);
  1253. BABYLON.Vector2.FromArrayToRef(uvs, (index / 3) * 2, uv);
  1254. // Compute height
  1255. var u = ((Math.abs(uv.x) * heightMapWidth) % heightMapWidth) | 0;
  1256. var v = ((Math.abs(uv.y) * heightMapHeight) % heightMapHeight) | 0;
  1257. var pos = (u + v * heightMapWidth) * 4;
  1258. var r = buffer[pos] / 255.0;
  1259. var g = buffer[pos + 1] / 255.0;
  1260. var b = buffer[pos + 2] / 255.0;
  1261. var gradient = r * 0.3 + g * 0.59 + b * 0.11;
  1262. normal.normalize();
  1263. normal.scaleInPlace(minHeight + (maxHeight - minHeight) * gradient);
  1264. position = position.add(normal);
  1265. position.toArray(positions, index);
  1266. }
  1267. BABYLON.VertexData.ComputeNormals(positions, this.getIndices(), normals);
  1268. this.updateVerticesData(BABYLON.VertexBuffer.PositionKind, positions);
  1269. this.updateVerticesData(BABYLON.VertexBuffer.NormalKind, normals);
  1270. };
  1271. /**
  1272. * Modify the mesh to get a flat shading rendering.
  1273. * This means each mesh facet will then have its own normals. Usually new vertices are added in the mesh geometry to get this result.
  1274. * This method returns nothing.
  1275. * Warning : the mesh is really modified even if not set originally as updatable and, under the hood, a new VertexBuffer is allocated.
  1276. */
  1277. Mesh.prototype.convertToFlatShadedMesh = function () {
  1278. /// <summary>Update normals and vertices to get a flat shading rendering.</summary>
  1279. /// <summary>Warning: This may imply adding vertices to the mesh in order to get exactly 3 vertices per face</summary>
  1280. var kinds = this.getVerticesDataKinds();
  1281. var vbs = [];
  1282. var data = [];
  1283. var newdata = [];
  1284. var updatableNormals = false;
  1285. var kindIndex;
  1286. var kind;
  1287. for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
  1288. kind = kinds[kindIndex];
  1289. var vertexBuffer = this.getVertexBuffer(kind);
  1290. if (kind === BABYLON.VertexBuffer.NormalKind) {
  1291. updatableNormals = vertexBuffer.isUpdatable();
  1292. kinds.splice(kindIndex, 1);
  1293. kindIndex--;
  1294. continue;
  1295. }
  1296. vbs[kind] = vertexBuffer;
  1297. data[kind] = vbs[kind].getData();
  1298. newdata[kind] = [];
  1299. }
  1300. // Save previous submeshes
  1301. var previousSubmeshes = this.subMeshes.slice(0);
  1302. var indices = this.getIndices();
  1303. var totalIndices = this.getTotalIndices();
  1304. // Generating unique vertices per face
  1305. var index;
  1306. for (index = 0; index < totalIndices; index++) {
  1307. var vertexIndex = indices[index];
  1308. for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
  1309. kind = kinds[kindIndex];
  1310. var stride = vbs[kind].getStrideSize();
  1311. for (var offset = 0; offset < stride; offset++) {
  1312. newdata[kind].push(data[kind][vertexIndex * stride + offset]);
  1313. }
  1314. }
  1315. }
  1316. // Updating faces & normal
  1317. var normals = [];
  1318. var positions = newdata[BABYLON.VertexBuffer.PositionKind];
  1319. for (index = 0; index < totalIndices; index += 3) {
  1320. indices[index] = index;
  1321. indices[index + 1] = index + 1;
  1322. indices[index + 2] = index + 2;
  1323. var p1 = BABYLON.Vector3.FromArray(positions, index * 3);
  1324. var p2 = BABYLON.Vector3.FromArray(positions, (index + 1) * 3);
  1325. var p3 = BABYLON.Vector3.FromArray(positions, (index + 2) * 3);
  1326. var p1p2 = p1.subtract(p2);
  1327. var p3p2 = p3.subtract(p2);
  1328. var normal = BABYLON.Vector3.Normalize(BABYLON.Vector3.Cross(p1p2, p3p2));
  1329. // Store same normals for every vertex
  1330. for (var localIndex = 0; localIndex < 3; localIndex++) {
  1331. normals.push(normal.x);
  1332. normals.push(normal.y);
  1333. normals.push(normal.z);
  1334. }
  1335. }
  1336. this.setIndices(indices);
  1337. this.setVerticesData(BABYLON.VertexBuffer.NormalKind, normals, updatableNormals);
  1338. // Updating vertex buffers
  1339. for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
  1340. kind = kinds[kindIndex];
  1341. this.setVerticesData(kind, newdata[kind], vbs[kind].isUpdatable());
  1342. }
  1343. // Updating submeshes
  1344. this.releaseSubMeshes();
  1345. for (var submeshIndex = 0; submeshIndex < previousSubmeshes.length; submeshIndex++) {
  1346. var previousOne = previousSubmeshes[submeshIndex];
  1347. var subMesh = new BABYLON.SubMesh(previousOne.materialIndex, previousOne.indexStart, previousOne.indexCount, previousOne.indexStart, previousOne.indexCount, this);
  1348. }
  1349. this.synchronizeInstances();
  1350. };
  1351. /**
  1352. * This method removes all the mesh indices and add new vertices (duplication) in order to unfold facets into buffers.
  1353. * In other words, more vertices, no more indices and a single bigger VBO.
  1354. * This method returns nothing.
  1355. * The mesh is really modified even if not set originally as updatable. Under the hood, a new VertexBuffer is allocated.
  1356. *
  1357. */
  1358. Mesh.prototype.convertToUnIndexedMesh = function () {
  1359. /// <summary>Remove indices by unfolding faces into buffers</summary>
  1360. /// <summary>Warning: This implies adding vertices to the mesh in order to get exactly 3 vertices per face</summary>
  1361. var kinds = this.getVerticesDataKinds();
  1362. var vbs = [];
  1363. var data = [];
  1364. var newdata = [];
  1365. var updatableNormals = false;
  1366. var kindIndex;
  1367. var kind;
  1368. for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
  1369. kind = kinds[kindIndex];
  1370. var vertexBuffer = this.getVertexBuffer(kind);
  1371. vbs[kind] = vertexBuffer;
  1372. data[kind] = vbs[kind].getData();
  1373. newdata[kind] = [];
  1374. }
  1375. // Save previous submeshes
  1376. var previousSubmeshes = this.subMeshes.slice(0);
  1377. var indices = this.getIndices();
  1378. var totalIndices = this.getTotalIndices();
  1379. // Generating unique vertices per face
  1380. var index;
  1381. for (index = 0; index < totalIndices; index++) {
  1382. var vertexIndex = indices[index];
  1383. for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
  1384. kind = kinds[kindIndex];
  1385. var stride = vbs[kind].getStrideSize();
  1386. for (var offset = 0; offset < stride; offset++) {
  1387. newdata[kind].push(data[kind][vertexIndex * stride + offset]);
  1388. }
  1389. }
  1390. }
  1391. // Updating indices
  1392. for (index = 0; index < totalIndices; index += 3) {
  1393. indices[index] = index;
  1394. indices[index + 1] = index + 1;
  1395. indices[index + 2] = index + 2;
  1396. }
  1397. this.setIndices(indices);
  1398. // Updating vertex buffers
  1399. for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
  1400. kind = kinds[kindIndex];
  1401. this.setVerticesData(kind, newdata[kind], vbs[kind].isUpdatable());
  1402. }
  1403. // Updating submeshes
  1404. this.releaseSubMeshes();
  1405. for (var submeshIndex = 0; submeshIndex < previousSubmeshes.length; submeshIndex++) {
  1406. var previousOne = previousSubmeshes[submeshIndex];
  1407. var subMesh = new BABYLON.SubMesh(previousOne.materialIndex, previousOne.indexStart, previousOne.indexCount, previousOne.indexStart, previousOne.indexCount, this);
  1408. }
  1409. this._unIndexed = true;
  1410. this.synchronizeInstances();
  1411. };
  1412. /**
  1413. * Inverses facet orientations and inverts also the normals with `flipNormals` (default `false`) if true.
  1414. * This method returns nothing.
  1415. * Warning : the mesh is really modified even if not set originally as updatable. A new VertexBuffer is created under the hood each call.
  1416. */
  1417. Mesh.prototype.flipFaces = function (flipNormals) {
  1418. if (flipNormals === void 0) { flipNormals = false; }
  1419. var vertex_data = BABYLON.VertexData.ExtractFromMesh(this);
  1420. var i;
  1421. if (flipNormals && this.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
  1422. for (i = 0; i < vertex_data.normals.length; i++) {
  1423. vertex_data.normals[i] *= -1;
  1424. }
  1425. }
  1426. var temp;
  1427. for (i = 0; i < vertex_data.indices.length; i += 3) {
  1428. // reassign indices
  1429. temp = vertex_data.indices[i + 1];
  1430. vertex_data.indices[i + 1] = vertex_data.indices[i + 2];
  1431. vertex_data.indices[i + 2] = temp;
  1432. }
  1433. vertex_data.applyToMesh(this);
  1434. };
  1435. // Instances
  1436. /**
  1437. * Creates a new InstancedMesh object from the mesh model.
  1438. * An instance shares the same properties and the same material than its model.
  1439. * Only these properties of each instance can then be set individually :
  1440. * - position
  1441. * - rotation
  1442. * - rotationQuaternion
  1443. * - setPivotMatrix
  1444. * - scaling
  1445. * tuto : http://doc.babylonjs.com/tutorials/How_to_use_Instances
  1446. * Warning : this method is not supported for Line mesh and LineSystem
  1447. */
  1448. Mesh.prototype.createInstance = function (name) {
  1449. return new BABYLON.InstancedMesh(name, this);
  1450. };
  1451. /**
  1452. * Synchronises all the mesh instance submeshes to the current mesh submeshes, if any.
  1453. * After this call, all the mesh instances have the same submeshes than the current mesh.
  1454. * This method returns nothing.
  1455. */
  1456. Mesh.prototype.synchronizeInstances = function () {
  1457. for (var instanceIndex = 0; instanceIndex < this.instances.length; instanceIndex++) {
  1458. var instance = this.instances[instanceIndex];
  1459. instance._syncSubMeshes();
  1460. }
  1461. };
  1462. /**
  1463. * Simplify the mesh according to the given array of settings.
  1464. * Function will return immediately and will simplify async. It returns nothing.
  1465. * @param settings a collection of simplification settings.
  1466. * @param parallelProcessing should all levels calculate parallel or one after the other.
  1467. * @param type the type of simplification to run.
  1468. * @param successCallback optional success callback to be called after the simplification finished processing all settings.
  1469. */
  1470. Mesh.prototype.simplify = function (settings, parallelProcessing, simplificationType, successCallback) {
  1471. if (parallelProcessing === void 0) { parallelProcessing = true; }
  1472. if (simplificationType === void 0) { simplificationType = BABYLON.SimplificationType.QUADRATIC; }
  1473. this.getScene().simplificationQueue.addTask({
  1474. settings: settings,
  1475. parallelProcessing: parallelProcessing,
  1476. mesh: this,
  1477. simplificationType: simplificationType,
  1478. successCallback: successCallback
  1479. });
  1480. };
  1481. /**
  1482. * Optimization of the mesh's indices, in case a mesh has duplicated vertices.
  1483. * The function will only reorder the indices and will not remove unused vertices to avoid problems with submeshes.
  1484. * This should be used together with the simplification to avoid disappearing triangles.
  1485. * @param successCallback an optional success callback to be called after the optimization finished.
  1486. */
  1487. Mesh.prototype.optimizeIndices = function (successCallback) {
  1488. var _this = this;
  1489. var indices = this.getIndices();
  1490. var positions = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  1491. var vectorPositions = [];
  1492. for (var pos = 0; pos < positions.length; pos = pos + 3) {
  1493. vectorPositions.push(BABYLON.Vector3.FromArray(positions, pos));
  1494. }
  1495. var dupes = [];
  1496. BABYLON.AsyncLoop.SyncAsyncForLoop(vectorPositions.length, 40, function (iteration) {
  1497. var realPos = vectorPositions.length - 1 - iteration;
  1498. var testedPosition = vectorPositions[realPos];
  1499. for (var j = 0; j < realPos; ++j) {
  1500. var againstPosition = vectorPositions[j];
  1501. if (testedPosition.equals(againstPosition)) {
  1502. dupes[realPos] = j;
  1503. break;
  1504. }
  1505. }
  1506. }, function () {
  1507. for (var i = 0; i < indices.length; ++i) {
  1508. indices[i] = dupes[indices[i]] || indices[i];
  1509. }
  1510. //indices are now reordered
  1511. var originalSubMeshes = _this.subMeshes.slice(0);
  1512. _this.setIndices(indices);
  1513. _this.subMeshes = originalSubMeshes;
  1514. if (successCallback) {
  1515. successCallback(_this);
  1516. }
  1517. });
  1518. };
  1519. // Statics
  1520. /**
  1521. * Returns a new Mesh object what is a deep copy of the passed mesh.
  1522. * The parameter `parsedMesh` is the mesh to be copied.
  1523. * The parameter `rootUrl` is a string, it's the root URL to prefix the `delayLoadingFile` property with
  1524. */
  1525. Mesh.Parse = function (parsedMesh, scene, rootUrl) {
  1526. var mesh = new Mesh(parsedMesh.name, scene);
  1527. mesh.id = parsedMesh.id;
  1528. BABYLON.Tags.AddTagsTo(mesh, parsedMesh.tags);
  1529. mesh.position = BABYLON.Vector3.FromArray(parsedMesh.position);
  1530. if (parsedMesh.rotationQuaternion) {
  1531. mesh.rotationQuaternion = BABYLON.Quaternion.FromArray(parsedMesh.rotationQuaternion);
  1532. }
  1533. else if (parsedMesh.rotation) {
  1534. mesh.rotation = BABYLON.Vector3.FromArray(parsedMesh.rotation);
  1535. }
  1536. mesh.scaling = BABYLON.Vector3.FromArray(parsedMesh.scaling);
  1537. if (parsedMesh.localMatrix) {
  1538. mesh.setPivotMatrix(BABYLON.Matrix.FromArray(parsedMesh.localMatrix));
  1539. }
  1540. else if (parsedMesh.pivotMatrix) {
  1541. mesh.setPivotMatrix(BABYLON.Matrix.FromArray(parsedMesh.pivotMatrix));
  1542. }
  1543. mesh.setEnabled(parsedMesh.isEnabled);
  1544. mesh.isVisible = parsedMesh.isVisible;
  1545. mesh.infiniteDistance = parsedMesh.infiniteDistance;
  1546. mesh.showBoundingBox = parsedMesh.showBoundingBox;
  1547. mesh.showSubMeshesBoundingBox = parsedMesh.showSubMeshesBoundingBox;
  1548. if (parsedMesh.applyFog !== undefined) {
  1549. mesh.applyFog = parsedMesh.applyFog;
  1550. }
  1551. if (parsedMesh.pickable !== undefined) {
  1552. mesh.isPickable = parsedMesh.pickable;
  1553. }
  1554. if (parsedMesh.alphaIndex !== undefined) {
  1555. mesh.alphaIndex = parsedMesh.alphaIndex;
  1556. }
  1557. mesh.receiveShadows = parsedMesh.receiveShadows;
  1558. mesh.billboardMode = parsedMesh.billboardMode;
  1559. if (parsedMesh.visibility !== undefined) {
  1560. mesh.visibility = parsedMesh.visibility;
  1561. }
  1562. mesh.checkCollisions = parsedMesh.checkCollisions;
  1563. mesh._shouldGenerateFlatShading = parsedMesh.useFlatShading;
  1564. // freezeWorldMatrix
  1565. if (parsedMesh.freezeWorldMatrix) {
  1566. mesh._waitingFreezeWorldMatrix = parsedMesh.freezeWorldMatrix;
  1567. }
  1568. // Parent
  1569. if (parsedMesh.parentId) {
  1570. mesh._waitingParentId = parsedMesh.parentId;
  1571. }
  1572. // Actions
  1573. if (parsedMesh.actions !== undefined) {
  1574. mesh._waitingActions = parsedMesh.actions;
  1575. }
  1576. // Geometry
  1577. mesh.hasVertexAlpha = parsedMesh.hasVertexAlpha;
  1578. if (parsedMesh.delayLoadingFile) {
  1579. mesh.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NOTLOADED;
  1580. mesh.delayLoadingFile = rootUrl + parsedMesh.delayLoadingFile;
  1581. mesh._boundingInfo = new BABYLON.BoundingInfo(BABYLON.Vector3.FromArray(parsedMesh.boundingBoxMinimum), BABYLON.Vector3.FromArray(parsedMesh.boundingBoxMaximum));
  1582. if (parsedMesh._binaryInfo) {
  1583. mesh._binaryInfo = parsedMesh._binaryInfo;
  1584. }
  1585. mesh._delayInfo = [];
  1586. if (parsedMesh.hasUVs) {
  1587. mesh._delayInfo.push(BABYLON.VertexBuffer.UVKind);
  1588. }
  1589. if (parsedMesh.hasUVs2) {
  1590. mesh._delayInfo.push(BABYLON.VertexBuffer.UV2Kind);
  1591. }
  1592. if (parsedMesh.hasUVs3) {
  1593. mesh._delayInfo.push(BABYLON.VertexBuffer.UV3Kind);
  1594. }
  1595. if (parsedMesh.hasUVs4) {
  1596. mesh._delayInfo.push(BABYLON.VertexBuffer.UV4Kind);
  1597. }
  1598. if (parsedMesh.hasUVs5) {
  1599. mesh._delayInfo.push(BABYLON.VertexBuffer.UV5Kind);
  1600. }
  1601. if (parsedMesh.hasUVs6) {
  1602. mesh._delayInfo.push(BABYLON.VertexBuffer.UV6Kind);
  1603. }
  1604. if (parsedMesh.hasColors) {
  1605. mesh._delayInfo.push(BABYLON.VertexBuffer.ColorKind);
  1606. }
  1607. if (parsedMesh.hasMatricesIndices) {
  1608. mesh._delayInfo.push(BABYLON.VertexBuffer.MatricesIndicesKind);
  1609. }
  1610. if (parsedMesh.hasMatricesWeights) {
  1611. mesh._delayInfo.push(BABYLON.VertexBuffer.MatricesWeightsKind);
  1612. }
  1613. mesh._delayLoadingFunction = BABYLON.Geometry.ImportGeometry;
  1614. if (BABYLON.SceneLoader.ForceFullSceneLoadingForIncremental) {
  1615. mesh._checkDelayState();
  1616. }
  1617. }
  1618. else {
  1619. BABYLON.Geometry.ImportGeometry(parsedMesh, mesh);
  1620. }
  1621. // Material
  1622. if (parsedMesh.materialId) {
  1623. mesh.setMaterialByID(parsedMesh.materialId);
  1624. }
  1625. else {
  1626. mesh.material = null;
  1627. }
  1628. // Skeleton
  1629. if (parsedMesh.skeletonId > -1) {
  1630. mesh.skeleton = scene.getLastSkeletonByID(parsedMesh.skeletonId);
  1631. if (parsedMesh.numBoneInfluencers) {
  1632. mesh.numBoneInfluencers = parsedMesh.numBoneInfluencers;
  1633. }
  1634. }
  1635. // Animations
  1636. if (parsedMesh.animations) {
  1637. for (var animationIndex = 0; animationIndex < parsedMesh.animations.length; animationIndex++) {
  1638. var parsedAnimation = parsedMesh.animations[animationIndex];
  1639. mesh.animations.push(BABYLON.Animation.Parse(parsedAnimation));
  1640. }
  1641. BABYLON.Node.ParseAnimationRanges(mesh, parsedMesh, scene);
  1642. }
  1643. if (parsedMesh.autoAnimate) {
  1644. scene.beginAnimation(mesh, parsedMesh.autoAnimateFrom, parsedMesh.autoAnimateTo, parsedMesh.autoAnimateLoop, parsedMesh.autoAnimateSpeed || 1.0);
  1645. }
  1646. // Layer Mask
  1647. if (parsedMesh.layerMask && (!isNaN(parsedMesh.layerMask))) {
  1648. mesh.layerMask = Math.abs(parseInt(parsedMesh.layerMask));
  1649. }
  1650. else {
  1651. mesh.layerMask = 0x0FFFFFFF;
  1652. }
  1653. //(Deprecated) physics
  1654. if (parsedMesh.physicsImpostor) {
  1655. mesh.physicsImpostor = new BABYLON.PhysicsImpostor(mesh, parsedMesh.physicsImpostor, {
  1656. mass: parsedMesh.physicsMass,
  1657. friction: parsedMesh.physicsFriction,
  1658. restitution: parsedMesh.physicsRestitution
  1659. }, scene);
  1660. }
  1661. // Instances
  1662. if (parsedMesh.instances) {
  1663. for (var index = 0; index < parsedMesh.instances.length; index++) {
  1664. var parsedInstance = parsedMesh.instances[index];
  1665. var instance = mesh.createInstance(parsedInstance.name);
  1666. BABYLON.Tags.AddTagsTo(instance, parsedInstance.tags);
  1667. instance.position = BABYLON.Vector3.FromArray(parsedInstance.position);
  1668. if (parsedInstance.rotationQuaternion) {
  1669. instance.rotationQuaternion = BABYLON.Quaternion.FromArray(parsedInstance.rotationQuaternion);
  1670. }
  1671. else if (parsedInstance.rotation) {
  1672. instance.rotation = BABYLON.Vector3.FromArray(parsedInstance.rotation);
  1673. }
  1674. instance.scaling = BABYLON.Vector3.FromArray(parsedInstance.scaling);
  1675. instance.checkCollisions = mesh.checkCollisions;
  1676. if (parsedMesh.animations) {
  1677. for (animationIndex = 0; animationIndex < parsedMesh.animations.length; animationIndex++) {
  1678. parsedAnimation = parsedMesh.animations[animationIndex];
  1679. instance.animations.push(BABYLON.Animation.Parse(parsedAnimation));
  1680. }
  1681. BABYLON.Node.ParseAnimationRanges(instance, parsedMesh, scene);
  1682. }
  1683. }
  1684. }
  1685. return mesh;
  1686. };
  1687. /**
  1688. * Creates a ribbon mesh.
  1689. * Please consider using the same method from the MeshBuilder class instead.
  1690. * The ribbon is a parametric shape : http://doc.babylonjs.com/tutorials/Parametric_Shapes. It has no predefined shape. Its final shape will depend on the input parameters.
  1691. *
  1692. * Please read this full tutorial to understand how to design a ribbon : http://doc.babylonjs.com/tutorials/Ribbon_Tutorial
  1693. * The parameter `pathArray` is a required array of paths, what are each an array of successive Vector3. The pathArray parameter depicts the ribbon geometry.
  1694. * The parameter `closeArray` (boolean, default false) creates a seam between the first and the last paths of the path array.
  1695. * The parameter `closePath` (boolean, default false) creates a seam between the first and the last points of each path of the path array.
  1696. * The parameter `offset` (positive integer, default : rounded half size of the pathArray length), is taken in account only if the `pathArray` is containing a single path.
  1697. * It's the offset to join together the points from the same path. Ex : offset = 10 means the point 1 is joined to the point 11.
  1698. * The optional parameter `instance` is an instance of an existing Ribbon object to be updated with the passed `pathArray` parameter : http://doc.babylonjs.com/tutorials/How_to_dynamically_morph_a_mesh#ribbon
  1699. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1700. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1701. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1702. */
  1703. Mesh.CreateRibbon = function (name, pathArray, closeArray, closePath, offset, scene, updatable, sideOrientation, instance) {
  1704. return BABYLON.MeshBuilder.CreateRibbon(name, {
  1705. pathArray: pathArray,
  1706. closeArray: closeArray,
  1707. closePath: closePath,
  1708. offset: offset,
  1709. updatable: updatable,
  1710. sideOrientation: sideOrientation,
  1711. instance: instance
  1712. }, scene);
  1713. };
  1714. /**
  1715. * Creates a plane polygonal mesh. By default, this is a disc.
  1716. * Please consider using the same method from the MeshBuilder class instead.
  1717. * The parameter `radius` sets the radius size (float) of the polygon (default 0.5).
  1718. * The parameter `tessellation` sets the number of polygon sides (positive integer, default 64). So a tessellation valued to 3 will build a triangle, to 4 a square, etc.
  1719. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1720. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1721. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1722. */
  1723. Mesh.CreateDisc = function (name, radius, tessellation, scene, updatable, sideOrientation) {
  1724. var options = {
  1725. radius: radius,
  1726. tessellation: tessellation,
  1727. sideOrientation: sideOrientation,
  1728. updatable: updatable
  1729. };
  1730. return BABYLON.MeshBuilder.CreateDisc(name, options, scene);
  1731. };
  1732. /**
  1733. * Creates a box mesh.
  1734. * Please consider using the same method from the MeshBuilder class instead.
  1735. * The parameter `size` sets the size (float) of each box side (default 1).
  1736. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1737. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1738. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1739. */
  1740. Mesh.CreateBox = function (name, size, scene, updatable, sideOrientation) {
  1741. var options = {
  1742. size: size,
  1743. sideOrientation: sideOrientation,
  1744. updatable: updatable
  1745. };
  1746. return BABYLON.MeshBuilder.CreateBox(name, options, scene);
  1747. };
  1748. /**
  1749. * Creates a sphere mesh.
  1750. * Please consider using the same method from the MeshBuilder class instead.
  1751. * The parameter `diameter` sets the diameter size (float) of the sphere (default 1).
  1752. * The parameter `segments` sets the sphere number of horizontal stripes (positive integer, default 32).
  1753. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1754. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1755. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1756. */
  1757. Mesh.CreateSphere = function (name, segments, diameter, scene, updatable, sideOrientation) {
  1758. var options = {
  1759. segments: segments,
  1760. diameterX: diameter,
  1761. diameterY: diameter,
  1762. diameterZ: diameter,
  1763. sideOrientation: sideOrientation,
  1764. updatable: updatable
  1765. };
  1766. return BABYLON.MeshBuilder.CreateSphere(name, options, scene);
  1767. };
  1768. /**
  1769. * Creates a cylinder or a cone mesh.
  1770. * Please consider using the same method from the MeshBuilder class instead.
  1771. * The parameter `height` sets the height size (float) of the cylinder/cone (float, default 2).
  1772. * The parameter `diameter` sets the diameter of the top and bottom cap at once (float, default 1).
  1773. * The parameters `diameterTop` and `diameterBottom` overwrite the parameter `diameter` and set respectively the top cap and bottom cap diameter (floats, default 1). The parameter "diameterBottom" can't be zero.
  1774. * The parameter `tessellation` sets the number of cylinder sides (positive integer, default 24). Set it to 3 to get a prism for instance.
  1775. * The parameter `subdivisions` sets the number of rings along the cylinder height (positive integer, default 1).
  1776. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1777. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1778. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1779. */
  1780. Mesh.CreateCylinder = function (name, height, diameterTop, diameterBottom, tessellation, subdivisions, scene, updatable, sideOrientation) {
  1781. if (scene === undefined || !(scene instanceof BABYLON.Scene)) {
  1782. if (scene !== undefined) {
  1783. sideOrientation = updatable || Mesh.DEFAULTSIDE;
  1784. updatable = scene;
  1785. }
  1786. scene = subdivisions;
  1787. subdivisions = 1;
  1788. }
  1789. var options = {
  1790. height: height,
  1791. diameterTop: diameterTop,
  1792. diameterBottom: diameterBottom,
  1793. tessellation: tessellation,
  1794. subdivisions: subdivisions,
  1795. sideOrientation: sideOrientation,
  1796. updatable: updatable
  1797. };
  1798. return BABYLON.MeshBuilder.CreateCylinder(name, options, scene);
  1799. };
  1800. // Torus (Code from SharpDX.org)
  1801. /**
  1802. * Creates a torus mesh.
  1803. * Please consider using the same method from the MeshBuilder class instead.
  1804. * The parameter `diameter` sets the diameter size (float) of the torus (default 1).
  1805. * The parameter `thickness` sets the diameter size of the tube of the torus (float, default 0.5).
  1806. * The parameter `tessellation` sets the number of torus sides (postive integer, default 16).
  1807. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1808. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1809. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1810. */
  1811. Mesh.CreateTorus = function (name, diameter, thickness, tessellation, scene, updatable, sideOrientation) {
  1812. var options = {
  1813. diameter: diameter,
  1814. thickness: thickness,
  1815. tessellation: tessellation,
  1816. sideOrientation: sideOrientation,
  1817. updatable: updatable
  1818. };
  1819. return BABYLON.MeshBuilder.CreateTorus(name, options, scene);
  1820. };
  1821. /**
  1822. * Creates a torus knot mesh.
  1823. * Please consider using the same method from the MeshBuilder class instead.
  1824. * The parameter `radius` sets the global radius size (float) of the torus knot (default 2).
  1825. * The parameter `radialSegments` sets the number of sides on each tube segments (positive integer, default 32).
  1826. * The parameter `tubularSegments` sets the number of tubes to decompose the knot into (positive integer, default 32).
  1827. * The parameters `p` and `q` are the number of windings on each axis (positive integers, default 2 and 3).
  1828. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1829. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1830. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1831. */
  1832. Mesh.CreateTorusKnot = function (name, radius, tube, radialSegments, tubularSegments, p, q, scene, updatable, sideOrientation) {
  1833. var options = {
  1834. radius: radius,
  1835. tube: tube,
  1836. radialSegments: radialSegments,
  1837. tubularSegments: tubularSegments,
  1838. p: p,
  1839. q: q,
  1840. sideOrientation: sideOrientation,
  1841. updatable: updatable
  1842. };
  1843. return BABYLON.MeshBuilder.CreateTorusKnot(name, options, scene);
  1844. };
  1845. /**
  1846. * Creates a line mesh.
  1847. * Please consider using the same method from the MeshBuilder class instead.
  1848. * A line mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of points as an input parameter.
  1849. * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineMesh to this static function.
  1850. * The parameter `points` is an array successive Vector3.
  1851. * The optional parameter `instance` is an instance of an existing LineMesh object to be updated with the passed `points` parameter : http://doc.babylonjs.com/tutorials/How_to_dynamically_morph_a_mesh#lines-and-dashedlines
  1852. * When updating an instance, remember that only point positions can change, not the number of points.
  1853. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1854. */
  1855. Mesh.CreateLines = function (name, points, scene, updatable, instance) {
  1856. var options = {
  1857. points: points,
  1858. updatable: updatable,
  1859. instance: instance
  1860. };
  1861. return BABYLON.MeshBuilder.CreateLines(name, options, scene);
  1862. };
  1863. /**
  1864. * Creates a dashed line mesh.
  1865. * Please consider using the same method from the MeshBuilder class instead.
  1866. * A dashed line mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of points as an input parameter.
  1867. * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineMesh to this static function.
  1868. * The parameter `points` is an array successive Vector3.
  1869. * The parameter `dashNb` is the intended total number of dashes (positive integer, default 200).
  1870. * The parameter `dashSize` is the size of the dashes relatively the dash number (positive float, default 3).
  1871. * The parameter `gapSize` is the size of the gap between two successive dashes relatively the dash number (positive float, default 1).
  1872. * The optional parameter `instance` is an instance of an existing LineMesh object to be updated with the passed `points` parameter : http://doc.babylonjs.com/tutorials/How_to_dynamically_morph_a_mesh#lines-and-dashedlines
  1873. * When updating an instance, remember that only point positions can change, not the number of points.
  1874. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1875. */
  1876. Mesh.CreateDashedLines = function (name, points, dashSize, gapSize, dashNb, scene, updatable, instance) {
  1877. var options = {
  1878. points: points,
  1879. dashSize: dashSize,
  1880. gapSize: gapSize,
  1881. dashNb: dashNb,
  1882. updatable: updatable
  1883. };
  1884. return BABYLON.MeshBuilder.CreateDashedLines(name, options, scene);
  1885. };
  1886. /**
  1887. * Creates an extruded shape mesh.
  1888. * The extrusion is a parametric shape : http://doc.babylonjs.com/tutorials/Parametric_Shapes. It has no predefined shape. Its final shape will depend on the input parameters.
  1889. * Please consider using the same method from the MeshBuilder class instead.
  1890. *
  1891. * Please read this full tutorial to understand how to design an extruded shape : http://doc.babylonjs.com/tutorials/Parametric_Shapes#extrusion
  1892. * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be
  1893. * extruded along the Z axis.
  1894. * The parameter `path` is a required array of successive Vector3. This is the axis curve the shape is extruded along.
  1895. * The parameter `rotation` (float, default 0 radians) is the angle value to rotate the shape each step (each path point), from the former step (so rotation added each step) along the curve.
  1896. * The parameter `scale` (float, default 1) is the value to scale the shape.
  1897. * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
  1898. * The optional parameter `instance` is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters : http://doc.babylonjs.com/tutorials/How_to_dynamically_morph_a_mesh#extruded-shape
  1899. * Remember you can only change the shape or path point positions, not their number when updating an extruded shape.
  1900. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1901. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1902. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1903. */
  1904. Mesh.ExtrudeShape = function (name, shape, path, scale, rotation, cap, scene, updatable, sideOrientation, instance) {
  1905. var options = {
  1906. shape: shape,
  1907. path: path,
  1908. scale: scale,
  1909. rotation: rotation,
  1910. cap: (cap === 0) ? 0 : cap || Mesh.NO_CAP,
  1911. sideOrientation: sideOrientation,
  1912. instance: instance,
  1913. updatable: updatable
  1914. };
  1915. return BABYLON.MeshBuilder.ExtrudeShape(name, options, scene);
  1916. };
  1917. /**
  1918. * Creates an custom extruded shape mesh.
  1919. * The custom extrusion is a parametric shape : http://doc.babylonjs.com/tutorials/Parametric_Shapes. It has no predefined shape. Its final shape will depend on the input parameters.
  1920. * Please consider using the same method from the MeshBuilder class instead.
  1921. *
  1922. * Please read this full tutorial to understand how to design a custom extruded shape : http://doc.babylonjs.com/tutorials/Parametric_Shapes#extrusion
  1923. * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be
  1924. * extruded along the Z axis.
  1925. * The parameter `path` is a required array of successive Vector3. This is the axis curve the shape is extruded along.
  1926. * The parameter `rotationFunction` (JS function) is a custom Javascript function called on each path point. This function is passed the position i of the point in the path
  1927. * and the distance of this point from the begining of the path :
  1928. * ```javascript
  1929. * var rotationFunction = function(i, distance) {
  1930. * // do things
  1931. * return rotationValue; }
  1932. * ```
  1933. * It must returns a float value that will be the rotation in radians applied to the shape on each path point.
  1934. * The parameter `scaleFunction` (JS function) is a custom Javascript function called on each path point. This function is passed the position i of the point in the path
  1935. * and the distance of this point from the begining of the path :
  1936. * ```javascript
  1937. * var scaleFunction = function(i, distance) {
  1938. * // do things
  1939. * return scaleValue;}
  1940. * ```
  1941. * It must returns a float value that will be the scale value applied to the shape on each path point.
  1942. * The parameter `ribbonClosePath` (boolean, default false) forces the extrusion underlying ribbon to close all the paths in its `pathArray`.
  1943. * The parameter `ribbonCloseArray` (boolean, default false) forces the extrusion underlying ribbon to close its `pathArray`.
  1944. * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
  1945. * The optional parameter `instance` is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters : http://doc.babylonjs.com/tutorials/How_to_dynamically_morph_a_mesh#extruded-shape
  1946. * Remember you can only change the shape or path point positions, not their number when updating an extruded shape.
  1947. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1948. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1949. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1950. */
  1951. Mesh.ExtrudeShapeCustom = function (name, shape, path, scaleFunction, rotationFunction, ribbonCloseArray, ribbonClosePath, cap, scene, updatable, sideOrientation, instance) {
  1952. var options = {
  1953. shape: shape,
  1954. path: path,
  1955. scaleFunction: scaleFunction,
  1956. rotationFunction: rotationFunction,
  1957. ribbonCloseArray: ribbonCloseArray,
  1958. ribbonClosePath: ribbonClosePath,
  1959. cap: (cap === 0) ? 0 : cap || Mesh.NO_CAP,
  1960. sideOrientation: sideOrientation,
  1961. instance: instance,
  1962. updatable: updatable
  1963. };
  1964. return BABYLON.MeshBuilder.ExtrudeShapeCustom(name, options, scene);
  1965. };
  1966. /**
  1967. * Creates lathe mesh.
  1968. * The lathe is a shape with a symetry axis : a 2D model shape is rotated around this axis to design the lathe.
  1969. * Please consider using the same method from the MeshBuilder class instead.
  1970. *
  1971. * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be rotated in its local space : the shape must be designed in the xOy plane and will be
  1972. * rotated around the Y axis. It's usually a 2D shape, so the Vector3 z coordinates are often set to zero.
  1973. * The parameter `radius` (positive float, default 1) is the radius value of the lathe.
  1974. * The parameter `tessellation` (positive integer, default 64) is the side number of the lathe.
  1975. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1976. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1977. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1978. */
  1979. Mesh.CreateLathe = function (name, shape, radius, tessellation, scene, updatable, sideOrientation) {
  1980. var options = {
  1981. shape: shape,
  1982. radius: radius,
  1983. tessellation: tessellation,
  1984. sideOrientation: sideOrientation,
  1985. updatable: updatable
  1986. };
  1987. return BABYLON.MeshBuilder.CreateLathe(name, options, scene);
  1988. };
  1989. /**
  1990. * Creates a plane mesh.
  1991. * Please consider using the same method from the MeshBuilder class instead.
  1992. * The parameter `size` sets the size (float) of both sides of the plane at once (default 1).
  1993. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  1994. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  1995. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  1996. */
  1997. Mesh.CreatePlane = function (name, size, scene, updatable, sideOrientation) {
  1998. var options = {
  1999. size: size,
  2000. width: size,
  2001. height: size,
  2002. sideOrientation: sideOrientation,
  2003. updatable: updatable
  2004. };
  2005. return BABYLON.MeshBuilder.CreatePlane(name, options, scene);
  2006. };
  2007. /**
  2008. * Creates a ground mesh.
  2009. * Please consider using the same method from the MeshBuilder class instead.
  2010. * The parameters `width` and `height` (floats, default 1) set the width and height sizes of the ground.
  2011. * The parameter `subdivisions` (positive integer) sets the number of subdivisions per side.
  2012. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  2013. */
  2014. Mesh.CreateGround = function (name, width, height, subdivisions, scene, updatable) {
  2015. var options = {
  2016. width: width,
  2017. height: height,
  2018. subdivisions: subdivisions,
  2019. updatable: updatable
  2020. };
  2021. return BABYLON.MeshBuilder.CreateGround(name, options, scene);
  2022. };
  2023. /**
  2024. * Creates a tiled ground mesh.
  2025. * Please consider using the same method from the MeshBuilder class instead.
  2026. * The parameters `xmin` and `xmax` (floats, default -1 and 1) set the ground minimum and maximum X coordinates.
  2027. * The parameters `zmin` and `zmax` (floats, default -1 and 1) set the ground minimum and maximum Z coordinates.
  2028. * The parameter `subdivisions` is a javascript object `{w: positive integer, h: positive integer}` (default `{w: 6, h: 6}`). `w` and `h` are the
  2029. * numbers of subdivisions on the ground width and height. Each subdivision is called a tile.
  2030. * The parameter `precision` is a javascript object `{w: positive integer, h: positive integer}` (default `{w: 2, h: 2}`). `w` and `h` are the
  2031. * numbers of subdivisions on the ground width and height of each tile.
  2032. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  2033. */
  2034. Mesh.CreateTiledGround = function (name, xmin, zmin, xmax, zmax, subdivisions, precision, scene, updatable) {
  2035. var options = {
  2036. xmin: xmin,
  2037. zmin: zmin,
  2038. xmax: xmax,
  2039. zmax: zmax,
  2040. subdivisions: subdivisions,
  2041. precision: precision,
  2042. updatable: updatable
  2043. };
  2044. return BABYLON.MeshBuilder.CreateTiledGround(name, options, scene);
  2045. };
  2046. /**
  2047. * Creates a ground mesh from a height map.
  2048. * tuto : http://doc.babylonjs.com/tutorials/14._Height_Map
  2049. * Please consider using the same method from the MeshBuilder class instead.
  2050. * The parameter `url` sets the URL of the height map image resource.
  2051. * The parameters `width` and `height` (positive floats, default 10) set the ground width and height sizes.
  2052. * The parameter `subdivisions` (positive integer, default 1) sets the number of subdivision per side.
  2053. * The parameter `minHeight` (float, default 0) is the minimum altitude on the ground.
  2054. * The parameter `maxHeight` (float, default 1) is the maximum altitude on the ground.
  2055. * The parameter `onReady` is a javascript callback function that will be called once the mesh is just built (the height map download can last some time).
  2056. * This function is passed the newly built mesh :
  2057. * ```javascript
  2058. * function(mesh) { // do things
  2059. * return; }
  2060. * ```
  2061. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  2062. */
  2063. Mesh.CreateGroundFromHeightMap = function (name, url, width, height, subdivisions, minHeight, maxHeight, scene, updatable, onReady) {
  2064. var options = {
  2065. width: width,
  2066. height: height,
  2067. subdivisions: subdivisions,
  2068. minHeight: minHeight,
  2069. maxHeight: maxHeight,
  2070. updatable: updatable,
  2071. onReady: onReady
  2072. };
  2073. return BABYLON.MeshBuilder.CreateGroundFromHeightMap(name, url, options, scene);
  2074. };
  2075. /**
  2076. * Creates a tube mesh.
  2077. * The tube is a parametric shape : http://doc.babylonjs.com/tutorials/Parametric_Shapes. It has no predefined shape. Its final shape will depend on the input parameters.
  2078. *
  2079. * Please consider using the same method from the MeshBuilder class instead.
  2080. * The parameter `path` is a required array of successive Vector3. It is the curve used as the axis of the tube.
  2081. * The parameter `radius` (positive float, default 1) sets the tube radius size.
  2082. * The parameter `tessellation` (positive float, default 64) is the number of sides on the tubular surface.
  2083. * The parameter `radiusFunction` (javascript function, default null) is a vanilla javascript function. If it is not null, it overwrittes the parameter `radius`.
  2084. * This function is called on each point of the tube path and is passed the index `i` of the i-th point and the distance of this point from the first point of the path.
  2085. * It must return a radius value (positive float) :
  2086. * ```javascript
  2087. * var radiusFunction = function(i, distance) {
  2088. * // do things
  2089. * return radius; }
  2090. * ```
  2091. * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
  2092. * The optional parameter `instance` is an instance of an existing Tube object to be updated with the passed `pathArray` parameter : http://doc.babylonjs.com/tutorials/How_to_dynamically_morph_a_mesh#tube
  2093. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  2094. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  2095. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  2096. */
  2097. Mesh.CreateTube = function (name, path, radius, tessellation, radiusFunction, cap, scene, updatable, sideOrientation, instance) {
  2098. var options = {
  2099. path: path,
  2100. radius: radius,
  2101. tessellation: tessellation,
  2102. radiusFunction: radiusFunction,
  2103. arc: 1,
  2104. cap: cap,
  2105. updatable: updatable,
  2106. sideOrientation: sideOrientation,
  2107. instance: instance
  2108. };
  2109. return BABYLON.MeshBuilder.CreateTube(name, options, scene);
  2110. };
  2111. /**
  2112. * Creates a polyhedron mesh.
  2113. *
  2114. * Please consider using the same method from the MeshBuilder class instead.
  2115. * The parameter `type` (positive integer, max 14, default 0) sets the polyhedron type to build among the 15 embbeded types. Please refer to the type sheet in the tutorial
  2116. * to choose the wanted type.
  2117. * The parameter `size` (positive float, default 1) sets the polygon size.
  2118. * You can overwrite the `size` on each dimension bu using the parameters `sizeX`, `sizeY` or `sizeZ` (positive floats, default to `size` value).
  2119. * You can build other polyhedron types than the 15 embbeded ones by setting the parameter `custom` (`polyhedronObject`, default null). If you set the parameter `custom`, this overwrittes the parameter `type`.
  2120. * A `polyhedronObject` is a formatted javascript object. You'll find a full file with pre-set polyhedra here : https://github.com/BabylonJS/Extensions/tree/master/Polyhedron
  2121. * You can set the color and the UV of each side of the polyhedron with the parameters `faceColors` (Color4, default `(1, 1, 1, 1)`) and faceUV (Vector4, default `(0, 0, 1, 1)`).
  2122. * To understand how to set `faceUV` or `faceColors`, please read this by considering the right number of faces of your polyhedron, instead of only 6 for the box : http://doc.babylonjs.com/tutorials/CreateBox_Per_Face_Textures_And_Colors
  2123. * The parameter `flat` (boolean, default true). If set to false, it gives the polyhedron a single global face, so less vertices and shared normals. In this case, `faceColors` and `faceUV` are ignored.
  2124. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  2125. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  2126. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  2127. */
  2128. Mesh.CreatePolyhedron = function (name, options, scene) {
  2129. return BABYLON.MeshBuilder.CreatePolyhedron(name, options, scene);
  2130. };
  2131. /**
  2132. * Creates a sphere based upon an icosahedron with 20 triangular faces which can be subdivided.
  2133. * Please consider using the same method from the MeshBuilder class instead.
  2134. * The parameter `radius` sets the radius size (float) of the icosphere (default 1).
  2135. * You can set some different icosphere dimensions, for instance to build an ellipsoid, by using the parameters `radiusX`, `radiusY` and `radiusZ` (all by default have the same value than `radius`).
  2136. * The parameter `subdivisions` sets the number of subdivisions (postive integer, default 4). The more subdivisions, the more faces on the icosphere whatever its size.
  2137. * The parameter `flat` (boolean, default true) gives each side its own normals. Set it to false to get a smooth continuous light reflection on the surface.
  2138. * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
  2139. * Detail here : http://doc.babylonjs.com/tutorials/02._Discover_Basic_Elements#side-orientation
  2140. * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
  2141. */
  2142. Mesh.CreateIcoSphere = function (name, options, scene) {
  2143. return BABYLON.MeshBuilder.CreateIcoSphere(name, options, scene);
  2144. };
  2145. /**
  2146. * Creates a decal mesh.
  2147. * Please consider using the same method from the MeshBuilder class instead.
  2148. * A decal is a mesh usually applied as a model onto the surface of another mesh. So don't forget the parameter `sourceMesh` depicting the decal.
  2149. * The parameter `position` (Vector3, default `(0, 0, 0)`) sets the position of the decal in World coordinates.
  2150. * The parameter `normal` (Vector3, default `Vector3.Up`) sets the normal of the mesh where the decal is applied onto in World coordinates.
  2151. * The parameter `size` (Vector3, default `(1, 1, 1)`) sets the decal scaling.
  2152. * The parameter `angle` (float in radian, default 0) sets the angle to rotate the decal.
  2153. */
  2154. Mesh.CreateDecal = function (name, sourceMesh, position, normal, size, angle) {
  2155. var options = {
  2156. position: position,
  2157. normal: normal,
  2158. size: size,
  2159. angle: angle
  2160. };
  2161. return BABYLON.MeshBuilder.CreateDecal(name, sourceMesh, options);
  2162. };
  2163. // Skeletons
  2164. /**
  2165. * @returns original positions used for CPU skinning. Useful for integrating Morphing with skeletons in same mesh.
  2166. */
  2167. Mesh.prototype.setPositionsForCPUSkinning = function () {
  2168. var source;
  2169. if (!this._sourcePositions) {
  2170. source = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  2171. this._sourcePositions = new Float32Array(source);
  2172. if (!this.getVertexBuffer(BABYLON.VertexBuffer.PositionKind).isUpdatable()) {
  2173. this.setVerticesData(BABYLON.VertexBuffer.PositionKind, source, true);
  2174. }
  2175. }
  2176. return this._sourcePositions;
  2177. };
  2178. /**
  2179. * @returns original normals used for CPU skinning. Useful for integrating Morphing with skeletons in same mesh.
  2180. */
  2181. Mesh.prototype.setNormalsForCPUSkinning = function () {
  2182. var source;
  2183. if (!this._sourceNormals) {
  2184. source = this.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  2185. this._sourceNormals = new Float32Array(source);
  2186. if (!this.getVertexBuffer(BABYLON.VertexBuffer.NormalKind).isUpdatable()) {
  2187. this.setVerticesData(BABYLON.VertexBuffer.NormalKind, source, true);
  2188. }
  2189. }
  2190. return this._sourceNormals;
  2191. };
  2192. /**
  2193. * Update the vertex buffers by applying transformation from the bones
  2194. * @param {skeleton} skeleton to apply
  2195. */
  2196. Mesh.prototype.applySkeleton = function (skeleton) {
  2197. if (!this.geometry) {
  2198. return;
  2199. }
  2200. if (this.geometry._softwareSkinningRenderId == this.getScene().getRenderId()) {
  2201. return;
  2202. }
  2203. this.geometry._softwareSkinningRenderId = this.getScene().getRenderId();
  2204. if (!this.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
  2205. return this;
  2206. }
  2207. if (!this.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
  2208. return this;
  2209. }
  2210. if (!this.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind)) {
  2211. return this;
  2212. }
  2213. if (!this.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
  2214. return this;
  2215. }
  2216. if (!this._sourcePositions) {
  2217. this.setPositionsForCPUSkinning();
  2218. }
  2219. if (!this._sourceNormals) {
  2220. this.setNormalsForCPUSkinning();
  2221. }
  2222. // positionsData checks for not being Float32Array will only pass at most once
  2223. var positionsData = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  2224. if (!(positionsData instanceof Float32Array)) {
  2225. positionsData = new Float32Array(positionsData);
  2226. }
  2227. // normalsData checks for not being Float32Array will only pass at most once
  2228. var normalsData = this.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  2229. if (!(normalsData instanceof Float32Array)) {
  2230. normalsData = new Float32Array(normalsData);
  2231. }
  2232. var matricesIndicesData = this.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind);
  2233. var matricesWeightsData = this.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind);
  2234. var needExtras = this.numBoneInfluencers > 4;
  2235. var matricesIndicesExtraData = needExtras ? this.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind) : null;
  2236. var matricesWeightsExtraData = needExtras ? this.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind) : null;
  2237. var skeletonMatrices = skeleton.getTransformMatrices(this);
  2238. var tempVector3 = BABYLON.Vector3.Zero();
  2239. var finalMatrix = new BABYLON.Matrix();
  2240. var tempMatrix = new BABYLON.Matrix();
  2241. var matWeightIdx = 0;
  2242. var inf;
  2243. for (var index = 0; index < positionsData.length; index += 3, matWeightIdx += 4) {
  2244. var weight;
  2245. for (inf = 0; inf < 4; inf++) {
  2246. weight = matricesWeightsData[matWeightIdx + inf];
  2247. if (weight > 0) {
  2248. BABYLON.Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, matricesIndicesData[matWeightIdx + inf] * 16, weight, tempMatrix);
  2249. finalMatrix.addToSelf(tempMatrix);
  2250. }
  2251. else
  2252. break;
  2253. }
  2254. if (needExtras) {
  2255. for (inf = 0; inf < 4; inf++) {
  2256. weight = matricesWeightsExtraData[matWeightIdx + inf];
  2257. if (weight > 0) {
  2258. BABYLON.Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, matricesIndicesExtraData[matWeightIdx + inf] * 16, weight, tempMatrix);
  2259. finalMatrix.addToSelf(tempMatrix);
  2260. }
  2261. else
  2262. break;
  2263. }
  2264. }
  2265. BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(this._sourcePositions[index], this._sourcePositions[index + 1], this._sourcePositions[index + 2], finalMatrix, tempVector3);
  2266. tempVector3.toArray(positionsData, index);
  2267. BABYLON.Vector3.TransformNormalFromFloatsToRef(this._sourceNormals[index], this._sourceNormals[index + 1], this._sourceNormals[index + 2], finalMatrix, tempVector3);
  2268. tempVector3.toArray(normalsData, index);
  2269. finalMatrix.reset();
  2270. }
  2271. this.updateVerticesData(BABYLON.VertexBuffer.PositionKind, positionsData);
  2272. this.updateVerticesData(BABYLON.VertexBuffer.NormalKind, normalsData);
  2273. return this;
  2274. };
  2275. // Tools
  2276. /**
  2277. * Returns an object `{min: Vector3, max: Vector3}`
  2278. * This min and max Vector3 are the minimum and maximum vectors of each mesh bounding box from the passed array, in the World system
  2279. */
  2280. Mesh.MinMax = function (meshes) {
  2281. var minVector = null;
  2282. var maxVector = null;
  2283. for (var i in meshes) {
  2284. var mesh = meshes[i];
  2285. var boundingBox = mesh.getBoundingInfo().boundingBox;
  2286. if (!minVector) {
  2287. minVector = boundingBox.minimumWorld;
  2288. maxVector = boundingBox.maximumWorld;
  2289. continue;
  2290. }
  2291. minVector.MinimizeInPlace(boundingBox.minimumWorld);
  2292. maxVector.MaximizeInPlace(boundingBox.maximumWorld);
  2293. }
  2294. return {
  2295. min: minVector,
  2296. max: maxVector
  2297. };
  2298. };
  2299. /**
  2300. * Returns a `Vector3`, the center of the `{min: Vector3, max: Vector3}` or the center of MinMax vector3 computed from a mesh array.
  2301. */
  2302. Mesh.Center = function (meshesOrMinMaxVector) {
  2303. var minMaxVector = meshesOrMinMaxVector.min !== undefined ? meshesOrMinMaxVector : Mesh.MinMax(meshesOrMinMaxVector);
  2304. return BABYLON.Vector3.Center(minMaxVector.min, minMaxVector.max);
  2305. };
  2306. /**
  2307. * Merge the array of meshes into a single mesh for performance reasons.
  2308. * @param {Array<Mesh>} meshes - The vertices source. They should all be of the same material. Entries can empty
  2309. * @param {boolean} disposeSource - When true (default), dispose of the vertices from the source meshes
  2310. * @param {boolean} allow32BitsIndices - When the sum of the vertices > 64k, this must be set to true.
  2311. * @param {Mesh} meshSubclass - When set, vertices inserted into this Mesh. Meshes can then be merged into a Mesh sub-class.
  2312. */
  2313. Mesh.MergeMeshes = function (meshes, disposeSource, allow32BitsIndices, meshSubclass) {
  2314. if (disposeSource === void 0) { disposeSource = true; }
  2315. var index;
  2316. if (!allow32BitsIndices) {
  2317. var totalVertices = 0;
  2318. // Counting vertices
  2319. for (index = 0; index < meshes.length; index++) {
  2320. if (meshes[index]) {
  2321. totalVertices += meshes[index].getTotalVertices();
  2322. if (totalVertices > 65536) {
  2323. BABYLON.Tools.Warn("Cannot merge meshes because resulting mesh will have more than 65536 vertices. Please use allow32BitsIndices = true to use 32 bits indices");
  2324. return null;
  2325. }
  2326. }
  2327. }
  2328. }
  2329. // Merge
  2330. var vertexData;
  2331. var otherVertexData;
  2332. var source;
  2333. for (index = 0; index < meshes.length; index++) {
  2334. if (meshes[index]) {
  2335. meshes[index].computeWorldMatrix(true);
  2336. otherVertexData = BABYLON.VertexData.ExtractFromMesh(meshes[index], true);
  2337. otherVertexData.transform(meshes[index].getWorldMatrix());
  2338. if (vertexData) {
  2339. vertexData.merge(otherVertexData);
  2340. }
  2341. else {
  2342. vertexData = otherVertexData;
  2343. source = meshes[index];
  2344. }
  2345. }
  2346. }
  2347. if (!meshSubclass) {
  2348. meshSubclass = new Mesh(source.name + "_merged", source.getScene());
  2349. }
  2350. vertexData.applyToMesh(meshSubclass);
  2351. // Setting properties
  2352. meshSubclass.material = source.material;
  2353. meshSubclass.checkCollisions = source.checkCollisions;
  2354. // Cleaning
  2355. if (disposeSource) {
  2356. for (index = 0; index < meshes.length; index++) {
  2357. if (meshes[index]) {
  2358. meshes[index].dispose();
  2359. }
  2360. }
  2361. }
  2362. return meshSubclass;
  2363. };
  2364. // Consts
  2365. Mesh._FRONTSIDE = 0;
  2366. Mesh._BACKSIDE = 1;
  2367. Mesh._DOUBLESIDE = 2;
  2368. Mesh._DEFAULTSIDE = 0;
  2369. Mesh._NO_CAP = 0;
  2370. Mesh._CAP_START = 1;
  2371. Mesh._CAP_END = 2;
  2372. Mesh._CAP_ALL = 3;
  2373. return Mesh;
  2374. }(BABYLON.AbstractMesh));
  2375. BABYLON.Mesh = Mesh;
  2376. })(BABYLON || (BABYLON = {}));