babylon.mesh.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. var __extends = 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. __.prototype = b.prototype;
  5. d.prototype = new __();
  6. };
  7. var BABYLON;
  8. (function (BABYLON) {
  9. var Mesh = (function (_super) {
  10. __extends(Mesh, _super);
  11. function Mesh(name, scene) {
  12. _super.call(this, name, scene);
  13. // Members
  14. this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NONE;
  15. this.instances = new Array();
  16. this._onBeforeRenderCallbacks = [];
  17. this._visibleInstances = {};
  18. this._renderIdForInstances = -1;
  19. }
  20. Mesh.prototype.getTotalVertices = function () {
  21. if (!this._geometry) {
  22. return 0;
  23. }
  24. return this._geometry.getTotalVertices();
  25. };
  26. Mesh.prototype.getVerticesData = function (kind) {
  27. if (!this._geometry) {
  28. return null;
  29. }
  30. return this._geometry.getVerticesData(kind);
  31. };
  32. Mesh.prototype.getVertexBuffer = function (kind) {
  33. if (!this._geometry) {
  34. return undefined;
  35. }
  36. return this._geometry.getVertexBuffer(kind);
  37. };
  38. Mesh.prototype.isVerticesDataPresent = function (kind) {
  39. if (!this._geometry) {
  40. if (this._delayInfo) {
  41. return this._delayInfo.indexOf(kind) !== -1;
  42. }
  43. return false;
  44. }
  45. return this._geometry.isVerticesDataPresent(kind);
  46. };
  47. Mesh.prototype.getVerticesDataKinds = function () {
  48. if (!this._geometry) {
  49. var result = [];
  50. if (this._delayInfo) {
  51. for (var kind in this._delayInfo) {
  52. result.push(kind);
  53. }
  54. }
  55. return result;
  56. }
  57. return this._geometry.getVerticesDataKinds();
  58. };
  59. Mesh.prototype.getTotalIndices = function () {
  60. if (!this._geometry) {
  61. return 0;
  62. }
  63. return this._geometry.getTotalIndices();
  64. };
  65. Mesh.prototype.getIndices = function () {
  66. if (!this._geometry) {
  67. return [];
  68. }
  69. return this._geometry.getIndices();
  70. };
  71. Mesh.prototype.isReady = function () {
  72. if (this.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_LOADING) {
  73. return false;
  74. }
  75. return _super.prototype.isReady.call(this);
  76. };
  77. Mesh.prototype.isDisposed = function () {
  78. return this._isDisposed;
  79. };
  80. // Methods
  81. Mesh.prototype._preActivate = function () {
  82. this._visibleInstances = null;
  83. };
  84. Mesh.prototype._registerInstanceForRenderId = function (instance, renderId) {
  85. if (!this._visibleInstances) {
  86. this._visibleInstances = {};
  87. this._visibleInstances.defaultRenderId = renderId;
  88. this._visibleInstances.selfDefaultRenderId = this._renderId;
  89. }
  90. if (!this._visibleInstances[renderId]) {
  91. this._visibleInstances[renderId] = new Array();
  92. }
  93. this._visibleInstances[renderId].push(instance);
  94. };
  95. Mesh.prototype.refreshBoundingInfo = function () {
  96. var data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  97. if (data) {
  98. var extend = BABYLON.Tools.ExtractMinAndMax(data, 0, this.getTotalVertices());
  99. this._boundingInfo = new BABYLON.BoundingInfo(extend.minimum, extend.maximum);
  100. }
  101. if (this.subMeshes) {
  102. for (var index = 0; index < this.subMeshes.length; index++) {
  103. this.subMeshes[index].refreshBoundingInfo();
  104. }
  105. }
  106. this._updateBoundingInfo();
  107. };
  108. Mesh.prototype._createGlobalSubMesh = function () {
  109. var totalVertices = this.getTotalVertices();
  110. if (!totalVertices || !this.getIndices()) {
  111. return null;
  112. }
  113. this.releaseSubMeshes();
  114. return new BABYLON.SubMesh(0, 0, totalVertices, 0, this.getTotalIndices(), this);
  115. };
  116. Mesh.prototype.subdivide = function (count) {
  117. if (count < 1) {
  118. return;
  119. }
  120. var totalIndices = this.getTotalIndices();
  121. var subdivisionSize = totalIndices / count;
  122. var offset = 0;
  123. this.releaseSubMeshes();
  124. for (var index = 0; index < count; index++) {
  125. BABYLON.SubMesh.CreateFromIndices(0, offset, Math.min(subdivisionSize, totalIndices - offset), this);
  126. offset += subdivisionSize;
  127. }
  128. this.synchronizeInstances();
  129. };
  130. Mesh.prototype.setVerticesData = function (data, kind, updatable) {
  131. if (!this._geometry) {
  132. var vertexData = new BABYLON.VertexData();
  133. vertexData.set(data, kind);
  134. var scene = this.getScene();
  135. new BABYLON.Geometry(BABYLON.Geometry.RandomId(), scene.getEngine(), vertexData, updatable, this);
  136. } else {
  137. this._geometry.setVerticesData(data, kind, updatable);
  138. }
  139. };
  140. Mesh.prototype.updateVerticesData = function (kind, data, updateExtends, makeItUnique) {
  141. if (!this._geometry) {
  142. return;
  143. }
  144. if (!makeItUnique) {
  145. this._geometry.updateVerticesData(kind, data, updateExtends);
  146. } else {
  147. this.makeGeometryUnique();
  148. this.updateVerticesData(kind, data, updateExtends, false);
  149. }
  150. };
  151. Mesh.prototype.makeGeometryUnique = function () {
  152. if (!this._geometry) {
  153. return;
  154. }
  155. var geometry = this._geometry.copy(BABYLON.Geometry.RandomId());
  156. geometry.applyToMesh(this);
  157. };
  158. Mesh.prototype.setIndices = function (indices) {
  159. if (!this._geometry) {
  160. var vertexData = new BABYLON.VertexData();
  161. vertexData.indices = indices;
  162. var scene = this.getScene();
  163. new BABYLON.Geometry(BABYLON.Geometry.RandomId(), scene.getEngine(), vertexData, false, this);
  164. } else {
  165. this._geometry.setIndices(indices);
  166. }
  167. };
  168. Mesh.prototype._bind = function (subMesh, effect, wireframe) {
  169. var engine = this.getScene().getEngine();
  170. // Wireframe
  171. var indexToBind = this._geometry.getIndexBuffer();
  172. if (wireframe) {
  173. indexToBind = subMesh.getLinesIndexBuffer(this.getIndices(), engine);
  174. }
  175. // VBOs
  176. engine.bindMultiBuffers(this._geometry.getVertexBuffers(), indexToBind, effect);
  177. };
  178. Mesh.prototype._draw = function (subMesh, useTriangles) {
  179. if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
  180. return;
  181. }
  182. var engine = this.getScene().getEngine();
  183. // Draw order
  184. engine.draw(useTriangles, useTriangles ? subMesh.indexStart : 0, useTriangles ? subMesh.indexCount : subMesh.linesIndexCount);
  185. };
  186. Mesh.prototype.bindAndDraw = function (subMesh, effect, wireframe) {
  187. this._bind(subMesh, effect, wireframe);
  188. this._draw(subMesh, !wireframe);
  189. };
  190. Mesh.prototype.registerBeforeRender = function (func) {
  191. this._onBeforeRenderCallbacks.push(func);
  192. };
  193. Mesh.prototype.unregisterBeforeRender = function (func) {
  194. var index = this._onBeforeRenderCallbacks.indexOf(func);
  195. if (index > -1) {
  196. this._onBeforeRenderCallbacks.splice(index, 1);
  197. }
  198. };
  199. Mesh.prototype.render = function (subMesh) {
  200. var renderSelf = true;
  201. var scene = this.getScene();
  202. // Managing instances
  203. if (this._visibleInstances) {
  204. var currentRenderId = scene.getRenderId();
  205. var visibleInstances = this._visibleInstances[currentRenderId];
  206. var selfRenderId = this._renderId;
  207. if (!visibleInstances && this._visibleInstances.defaultRenderId) {
  208. visibleInstances = this._visibleInstances[this._visibleInstances.defaultRenderId];
  209. currentRenderId = this._visibleInstances.defaultRenderId;
  210. selfRenderId = this._visibleInstances.selfDefaultRenderId;
  211. }
  212. if (visibleInstances && visibleInstances.length) {
  213. if (this._renderIdForInstances === currentRenderId) {
  214. return;
  215. }
  216. if (currentRenderId !== selfRenderId) {
  217. renderSelf = false;
  218. }
  219. }
  220. this._renderIdForInstances = currentRenderId;
  221. }
  222. // Checking geometry state
  223. if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
  224. return;
  225. }
  226. for (var callbackIndex = 0; callbackIndex < this._onBeforeRenderCallbacks.length; callbackIndex++) {
  227. this._onBeforeRenderCallbacks[callbackIndex]();
  228. }
  229. // Material
  230. var effectiveMaterial = subMesh.getMaterial();
  231. if (!effectiveMaterial || !effectiveMaterial.isReady(this)) {
  232. return;
  233. }
  234. var engine = scene.getEngine();
  235. var effect = effectiveMaterial.getEffect();
  236. // Bind
  237. var wireFrame = engine.forceWireframe || effectiveMaterial.wireframe;
  238. this._bind(subMesh, effect, wireFrame);
  239. effectiveMaterial._preBind();
  240. if (renderSelf) {
  241. // World
  242. var world = this.getWorldMatrix();
  243. effectiveMaterial.bind(world, this);
  244. // Draw
  245. this._draw(subMesh, !wireFrame);
  246. }
  247. if (visibleInstances) {
  248. for (var instanceIndex = 0; instanceIndex < visibleInstances.length; instanceIndex++) {
  249. var instance = visibleInstances[instanceIndex];
  250. // World
  251. world = instance.getWorldMatrix();
  252. effectiveMaterial.bind(world, this);
  253. // Draw
  254. this._draw(subMesh, !wireFrame);
  255. }
  256. }
  257. // Unbind
  258. effectiveMaterial.unbind();
  259. };
  260. Mesh.prototype.getEmittedParticleSystems = function () {
  261. var results = new Array();
  262. for (var index = 0; index < this.getScene().particleSystems.length; index++) {
  263. var particleSystem = this.getScene().particleSystems[index];
  264. if (particleSystem.emitter === this) {
  265. results.push(particleSystem);
  266. }
  267. }
  268. return results;
  269. };
  270. Mesh.prototype.getHierarchyEmittedParticleSystems = function () {
  271. var results = new Array();
  272. var descendants = this.getDescendants();
  273. descendants.push(this);
  274. for (var index = 0; index < this.getScene().particleSystems.length; index++) {
  275. var particleSystem = this.getScene().particleSystems[index];
  276. if (descendants.indexOf(particleSystem.emitter) !== -1) {
  277. results.push(particleSystem);
  278. }
  279. }
  280. return results;
  281. };
  282. Mesh.prototype.getChildren = function () {
  283. var results = [];
  284. for (var index = 0; index < this.getScene().meshes.length; index++) {
  285. var mesh = this.getScene().meshes[index];
  286. if (mesh.parent == this) {
  287. results.push(mesh);
  288. }
  289. }
  290. return results;
  291. };
  292. Mesh.prototype._checkDelayState = function () {
  293. var _this = this;
  294. var that = this;
  295. var scene = this.getScene();
  296. if (this._geometry) {
  297. this._geometry.load(scene);
  298. } else if (that.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_NOTLOADED) {
  299. that.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_LOADING;
  300. scene._addPendingData(that);
  301. BABYLON.Tools.LoadFile(this.delayLoadingFile, function (data) {
  302. _this._delayLoadingFunction(JSON.parse(data), _this);
  303. _this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_LOADED;
  304. scene._removePendingData(_this);
  305. }, function () {
  306. }, scene.database);
  307. }
  308. };
  309. Mesh.prototype.isInFrustum = function (frustumPlanes) {
  310. if (this.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_LOADING) {
  311. return false;
  312. }
  313. if (!_super.prototype.isInFrustum.call(this, frustumPlanes)) {
  314. return false;
  315. }
  316. this._checkDelayState();
  317. return true;
  318. };
  319. Mesh.prototype.setMaterialByID = function (id) {
  320. var materials = this.getScene().materials;
  321. for (var index = 0; index < materials.length; index++) {
  322. if (materials[index].id == id) {
  323. this.material = materials[index];
  324. return;
  325. }
  326. }
  327. // Multi
  328. var multiMaterials = this.getScene().multiMaterials;
  329. for (index = 0; index < multiMaterials.length; index++) {
  330. if (multiMaterials[index].id == id) {
  331. this.material = multiMaterials[index];
  332. return;
  333. }
  334. }
  335. };
  336. Mesh.prototype.getAnimatables = function () {
  337. var results = [];
  338. if (this.material) {
  339. results.push(this.material);
  340. }
  341. return results;
  342. };
  343. // Geometry
  344. Mesh.prototype.bakeTransformIntoVertices = function (transform) {
  345. // Position
  346. if (!this.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
  347. return;
  348. }
  349. this._resetPointsArrayCache();
  350. var data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  351. var temp = [];
  352. for (var index = 0; index < data.length; index += 3) {
  353. BABYLON.Vector3.TransformCoordinates(BABYLON.Vector3.FromArray(data, index), transform).toArray(temp, index);
  354. }
  355. this.setVerticesData(temp, BABYLON.VertexBuffer.PositionKind, this.getVertexBuffer(BABYLON.VertexBuffer.PositionKind).isUpdatable());
  356. // Normals
  357. if (!this.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
  358. return;
  359. }
  360. data = this.getVerticesData(BABYLON.VertexBuffer.NormalKind);
  361. for (index = 0; index < data.length; index += 3) {
  362. BABYLON.Vector3.TransformNormal(BABYLON.Vector3.FromArray(data, index), transform).toArray(temp, index);
  363. }
  364. this.setVerticesData(temp, BABYLON.VertexBuffer.NormalKind, this.getVertexBuffer(BABYLON.VertexBuffer.NormalKind).isUpdatable());
  365. };
  366. // Cache
  367. Mesh.prototype._resetPointsArrayCache = function () {
  368. this._positions = null;
  369. };
  370. Mesh.prototype._generatePointsArray = function () {
  371. if (this._positions)
  372. return true;
  373. this._positions = [];
  374. var data = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  375. if (!data) {
  376. return false;
  377. }
  378. for (var index = 0; index < data.length; index += 3) {
  379. this._positions.push(BABYLON.Vector3.FromArray(data, index));
  380. }
  381. return true;
  382. };
  383. // Clone
  384. Mesh.prototype.clone = function (name, newParent, doNotCloneChildren) {
  385. var result = new BABYLON.Mesh(name, this.getScene());
  386. // Geometry
  387. this._geometry.applyToMesh(result);
  388. // Deep copy
  389. BABYLON.Tools.DeepCopy(this, result, ["name", "material", "skeleton"], []);
  390. // Bounding info
  391. var extend = BABYLON.Tools.ExtractMinAndMax(this.getVerticesData(BABYLON.VertexBuffer.PositionKind), 0, this.getTotalVertices());
  392. result._boundingInfo = new BABYLON.BoundingInfo(extend.minimum, extend.maximum);
  393. // Material
  394. result.material = this.material;
  395. // Parent
  396. if (newParent) {
  397. result.parent = newParent;
  398. }
  399. if (!doNotCloneChildren) {
  400. for (var index = 0; index < this.getScene().meshes.length; index++) {
  401. var mesh = this.getScene().meshes[index];
  402. if (mesh.parent == this) {
  403. mesh.clone(mesh.name, result);
  404. }
  405. }
  406. }
  407. for (index = 0; index < this.getScene().particleSystems.length; index++) {
  408. var system = this.getScene().particleSystems[index];
  409. if (system.emitter == this) {
  410. system.clone(system.name, result);
  411. }
  412. }
  413. result.computeWorldMatrix(true);
  414. return result;
  415. };
  416. // Dispose
  417. Mesh.prototype.dispose = function (doNotRecurse) {
  418. if (this._geometry) {
  419. this._geometry.releaseForMesh(this);
  420. }
  421. while (this.instances.length) {
  422. this.instances[0].dispose();
  423. }
  424. _super.prototype.dispose.call(this, doNotRecurse);
  425. };
  426. // Geometric tools
  427. Mesh.prototype.convertToFlatShadedMesh = function () {
  428. /// <summary>Update normals and vertices to get a flat shading rendering.</summary>
  429. /// <summary>Warning: This may imply adding vertices to the mesh in order to get exactly 3 vertices per face</summary>
  430. var kinds = this.getVerticesDataKinds();
  431. var vbs = [];
  432. var data = [];
  433. var newdata = [];
  434. var updatableNormals = false;
  435. for (var kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
  436. var kind = kinds[kindIndex];
  437. var vertexBuffer = this.getVertexBuffer(kind);
  438. if (kind === BABYLON.VertexBuffer.NormalKind) {
  439. updatableNormals = vertexBuffer.isUpdatable();
  440. kinds.splice(kindIndex, 1);
  441. kindIndex--;
  442. continue;
  443. }
  444. vbs[kind] = vertexBuffer;
  445. data[kind] = vbs[kind].getData();
  446. newdata[kind] = [];
  447. }
  448. // Save previous submeshes
  449. var previousSubmeshes = this.subMeshes.slice(0);
  450. var indices = this.getIndices();
  451. var totalIndices = this.getTotalIndices();
  452. for (index = 0; index < totalIndices; index++) {
  453. var vertexIndex = indices[index];
  454. for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
  455. kind = kinds[kindIndex];
  456. var stride = vbs[kind].getStrideSize();
  457. for (var offset = 0; offset < stride; offset++) {
  458. newdata[kind].push(data[kind][vertexIndex * stride + offset]);
  459. }
  460. }
  461. }
  462. // Updating faces & normal
  463. var normals = [];
  464. var positions = newdata[BABYLON.VertexBuffer.PositionKind];
  465. for (var index = 0; index < totalIndices; index += 3) {
  466. indices[index] = index;
  467. indices[index + 1] = index + 1;
  468. indices[index + 2] = index + 2;
  469. var p1 = BABYLON.Vector3.FromArray(positions, index * 3);
  470. var p2 = BABYLON.Vector3.FromArray(positions, (index + 1) * 3);
  471. var p3 = BABYLON.Vector3.FromArray(positions, (index + 2) * 3);
  472. var p1p2 = p1.subtract(p2);
  473. var p3p2 = p3.subtract(p2);
  474. var normal = BABYLON.Vector3.Normalize(BABYLON.Vector3.Cross(p1p2, p3p2));
  475. for (var localIndex = 0; localIndex < 3; localIndex++) {
  476. normals.push(normal.x);
  477. normals.push(normal.y);
  478. normals.push(normal.z);
  479. }
  480. }
  481. this.setIndices(indices);
  482. this.setVerticesData(normals, BABYLON.VertexBuffer.NormalKind, updatableNormals);
  483. for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
  484. kind = kinds[kindIndex];
  485. this.setVerticesData(newdata[kind], kind, vbs[kind].isUpdatable());
  486. }
  487. // Updating submeshes
  488. this.releaseSubMeshes();
  489. for (var submeshIndex = 0; submeshIndex < previousSubmeshes.length; submeshIndex++) {
  490. var previousOne = previousSubmeshes[submeshIndex];
  491. var subMesh = new BABYLON.SubMesh(previousOne.materialIndex, previousOne.indexStart, previousOne.indexCount, previousOne.indexStart, previousOne.indexCount, this);
  492. }
  493. this.synchronizeInstances();
  494. };
  495. // Instances
  496. Mesh.prototype.createInstance = function (name) {
  497. return new BABYLON.InstancedMesh(name, this);
  498. };
  499. Mesh.prototype.synchronizeInstances = function () {
  500. for (var instanceIndex = 0; instanceIndex < this.instances.length; instanceIndex++) {
  501. var instance = this.instances[instanceIndex];
  502. instance._syncSubMeshes();
  503. }
  504. };
  505. // Statics
  506. Mesh.CreateBox = function (name, size, scene, updatable) {
  507. var box = new BABYLON.Mesh(name, scene);
  508. var vertexData = BABYLON.VertexData.CreateBox(size);
  509. vertexData.applyToMesh(box, updatable);
  510. return box;
  511. };
  512. Mesh.CreateSphere = function (name, segments, diameter, scene, updatable) {
  513. var sphere = new BABYLON.Mesh(name, scene);
  514. var vertexData = BABYLON.VertexData.CreateSphere(segments, diameter);
  515. vertexData.applyToMesh(sphere, updatable);
  516. return sphere;
  517. };
  518. // Cylinder and cone (Code inspired by SharpDX.org)
  519. Mesh.CreateCylinder = function (name, height, diameterTop, diameterBottom, tessellation, scene, updatable) {
  520. var cylinder = new BABYLON.Mesh(name, scene);
  521. var vertexData = BABYLON.VertexData.CreateCylinder(height, diameterTop, diameterBottom, tessellation);
  522. vertexData.applyToMesh(cylinder, updatable);
  523. return cylinder;
  524. };
  525. // Torus (Code from SharpDX.org)
  526. Mesh.CreateTorus = function (name, diameter, thickness, tessellation, scene, updatable) {
  527. var torus = new BABYLON.Mesh(name, scene);
  528. var vertexData = BABYLON.VertexData.CreateTorus(diameter, thickness, tessellation);
  529. vertexData.applyToMesh(torus, updatable);
  530. return torus;
  531. };
  532. Mesh.CreateTorusKnot = function (name, radius, tube, radialSegments, tubularSegments, p, q, scene, updatable) {
  533. var torusKnot = new BABYLON.Mesh(name, scene);
  534. var vertexData = BABYLON.VertexData.CreateTorusKnot(radius, tube, radialSegments, tubularSegments, p, q);
  535. vertexData.applyToMesh(torusKnot, updatable);
  536. return torusKnot;
  537. };
  538. // Plane & ground
  539. Mesh.CreatePlane = function (name, size, scene, updatable) {
  540. var plane = new BABYLON.Mesh(name, scene);
  541. var vertexData = BABYLON.VertexData.CreatePlane(size);
  542. vertexData.applyToMesh(plane, updatable);
  543. return plane;
  544. };
  545. Mesh.CreateGround = function (name, width, height, subdivisions, scene, updatable) {
  546. var ground = new BABYLON.Mesh(name, scene);
  547. var vertexData = BABYLON.VertexData.CreateGround(width, height, subdivisions);
  548. vertexData.applyToMesh(ground, updatable);
  549. return ground;
  550. };
  551. Mesh.CreateGroundFromHeightMap = function (name, url, width, height, subdivisions, minHeight, maxHeight, scene, updatable) {
  552. var ground = new BABYLON.Mesh(name, scene);
  553. var onload = function (img) {
  554. // Getting height map data
  555. var canvas = document.createElement("canvas");
  556. var context = canvas.getContext("2d");
  557. var heightMapWidth = img.width;
  558. var heightMapHeight = img.height;
  559. canvas.width = heightMapWidth;
  560. canvas.height = heightMapHeight;
  561. context.drawImage(img, 0, 0);
  562. // Create VertexData from map data
  563. var buffer = context.getImageData(0, 0, heightMapWidth, heightMapHeight).data;
  564. var vertexData = BABYLON.VertexData.CreateGroundFromHeightMap(width, height, subdivisions, minHeight, maxHeight, buffer, heightMapWidth, heightMapHeight);
  565. vertexData.applyToMesh(ground, updatable);
  566. ground._isReady = true;
  567. };
  568. BABYLON.Tools.LoadImage(url, onload, function () {
  569. }, scene.database);
  570. ground._isReady = false;
  571. return ground;
  572. };
  573. // Tools
  574. Mesh.MinMax = function (meshes) {
  575. var minVector = null;
  576. var maxVector = null;
  577. for (var i in meshes) {
  578. var mesh = meshes[i];
  579. var boundingBox = mesh.getBoundingInfo().boundingBox;
  580. if (!minVector) {
  581. minVector = boundingBox.minimumWorld;
  582. maxVector = boundingBox.maximumWorld;
  583. continue;
  584. }
  585. minVector.MinimizeInPlace(boundingBox.minimumWorld);
  586. maxVector.MaximizeInPlace(boundingBox.maximumWorld);
  587. }
  588. return {
  589. min: minVector,
  590. max: maxVector
  591. };
  592. };
  593. Mesh.Center = function (meshesOrMinMaxVector) {
  594. var minMaxVector = meshesOrMinMaxVector.min !== undefined ? meshesOrMinMaxVector : BABYLON.Mesh.MinMax(meshesOrMinMaxVector);
  595. return BABYLON.Vector3.Center(minMaxVector.min, minMaxVector.max);
  596. };
  597. return Mesh;
  598. })(BABYLON.AbstractMesh);
  599. BABYLON.Mesh = Mesh;
  600. })(BABYLON || (BABYLON = {}));
  601. //# sourceMappingURL=babylon.mesh.js.map