babylon.mesh.vertexData.js 90 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741
  1. var BABYLON;
  2. (function (BABYLON) {
  3. var VertexData = (function () {
  4. function VertexData() {
  5. }
  6. VertexData.prototype.set = function (data, kind) {
  7. switch (kind) {
  8. case BABYLON.VertexBuffer.PositionKind:
  9. this.positions = data;
  10. break;
  11. case BABYLON.VertexBuffer.NormalKind:
  12. this.normals = data;
  13. break;
  14. case BABYLON.VertexBuffer.UVKind:
  15. this.uvs = data;
  16. break;
  17. case BABYLON.VertexBuffer.UV2Kind:
  18. this.uvs2 = data;
  19. break;
  20. case BABYLON.VertexBuffer.UV3Kind:
  21. this.uvs3 = data;
  22. break;
  23. case BABYLON.VertexBuffer.UV4Kind:
  24. this.uvs4 = data;
  25. break;
  26. case BABYLON.VertexBuffer.UV5Kind:
  27. this.uvs5 = data;
  28. break;
  29. case BABYLON.VertexBuffer.UV6Kind:
  30. this.uvs6 = data;
  31. break;
  32. case BABYLON.VertexBuffer.ColorKind:
  33. this.colors = data;
  34. break;
  35. case BABYLON.VertexBuffer.MatricesIndicesKind:
  36. this.matricesIndices = data;
  37. break;
  38. case BABYLON.VertexBuffer.MatricesWeightsKind:
  39. this.matricesWeights = data;
  40. break;
  41. case BABYLON.VertexBuffer.MatricesIndicesExtraKind:
  42. this.matricesIndicesExtra = data;
  43. break;
  44. case BABYLON.VertexBuffer.MatricesWeightsExtraKind:
  45. this.matricesWeightsExtra = data;
  46. break;
  47. }
  48. };
  49. VertexData.prototype.applyToMesh = function (mesh, updatable) {
  50. this._applyTo(mesh, updatable);
  51. };
  52. VertexData.prototype.applyToGeometry = function (geometry, updatable) {
  53. this._applyTo(geometry, updatable);
  54. };
  55. VertexData.prototype.updateMesh = function (mesh, updateExtends, makeItUnique) {
  56. this._update(mesh);
  57. };
  58. VertexData.prototype.updateGeometry = function (geometry, updateExtends, makeItUnique) {
  59. this._update(geometry);
  60. };
  61. VertexData.prototype._applyTo = function (meshOrGeometry, updatable) {
  62. if (this.positions) {
  63. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.PositionKind, this.positions, updatable);
  64. }
  65. if (this.normals) {
  66. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.NormalKind, this.normals, updatable);
  67. }
  68. if (this.uvs) {
  69. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.UVKind, this.uvs, updatable);
  70. }
  71. if (this.uvs2) {
  72. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.UV2Kind, this.uvs2, updatable);
  73. }
  74. if (this.uvs3) {
  75. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.UV3Kind, this.uvs3, updatable);
  76. }
  77. if (this.uvs4) {
  78. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.UV4Kind, this.uvs4, updatable);
  79. }
  80. if (this.uvs5) {
  81. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.UV5Kind, this.uvs5, updatable);
  82. }
  83. if (this.uvs6) {
  84. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.UV6Kind, this.uvs6, updatable);
  85. }
  86. if (this.colors) {
  87. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.ColorKind, this.colors, updatable);
  88. }
  89. if (this.matricesIndices) {
  90. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind, this.matricesIndices, updatable);
  91. }
  92. if (this.matricesWeights) {
  93. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, this.matricesWeights, updatable);
  94. }
  95. if (this.matricesIndicesExtra) {
  96. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updatable);
  97. }
  98. if (this.matricesWeightsExtra) {
  99. meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updatable);
  100. }
  101. if (this.indices) {
  102. meshOrGeometry.setIndices(this.indices);
  103. }
  104. };
  105. VertexData.prototype._update = function (meshOrGeometry, updateExtends, makeItUnique) {
  106. if (this.positions) {
  107. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.PositionKind, this.positions, updateExtends, makeItUnique);
  108. }
  109. if (this.normals) {
  110. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.NormalKind, this.normals, updateExtends, makeItUnique);
  111. }
  112. if (this.uvs) {
  113. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.UVKind, this.uvs, updateExtends, makeItUnique);
  114. }
  115. if (this.uvs2) {
  116. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.UV2Kind, this.uvs2, updateExtends, makeItUnique);
  117. }
  118. if (this.uvs3) {
  119. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.UV3Kind, this.uvs3, updateExtends, makeItUnique);
  120. }
  121. if (this.uvs4) {
  122. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.UV4Kind, this.uvs4, updateExtends, makeItUnique);
  123. }
  124. if (this.uvs5) {
  125. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.UV5Kind, this.uvs5, updateExtends, makeItUnique);
  126. }
  127. if (this.uvs6) {
  128. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.UV6Kind, this.uvs6, updateExtends, makeItUnique);
  129. }
  130. if (this.colors) {
  131. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.ColorKind, this.colors, updateExtends, makeItUnique);
  132. }
  133. if (this.matricesIndices) {
  134. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind, this.matricesIndices, updateExtends, makeItUnique);
  135. }
  136. if (this.matricesWeights) {
  137. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, this.matricesWeights, updateExtends, makeItUnique);
  138. }
  139. if (this.matricesIndicesExtra) {
  140. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updateExtends, makeItUnique);
  141. }
  142. if (this.matricesWeightsExtra) {
  143. meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updateExtends, makeItUnique);
  144. }
  145. if (this.indices) {
  146. meshOrGeometry.setIndices(this.indices);
  147. }
  148. };
  149. VertexData.prototype.transform = function (matrix) {
  150. var transformed = BABYLON.Vector3.Zero();
  151. var index;
  152. if (this.positions) {
  153. var position = BABYLON.Vector3.Zero();
  154. for (index = 0; index < this.positions.length; index += 3) {
  155. BABYLON.Vector3.FromArrayToRef(this.positions, index, position);
  156. BABYLON.Vector3.TransformCoordinatesToRef(position, matrix, transformed);
  157. this.positions[index] = transformed.x;
  158. this.positions[index + 1] = transformed.y;
  159. this.positions[index + 2] = transformed.z;
  160. }
  161. }
  162. if (this.normals) {
  163. var normal = BABYLON.Vector3.Zero();
  164. for (index = 0; index < this.normals.length; index += 3) {
  165. BABYLON.Vector3.FromArrayToRef(this.normals, index, normal);
  166. BABYLON.Vector3.TransformNormalToRef(normal, matrix, transformed);
  167. this.normals[index] = transformed.x;
  168. this.normals[index + 1] = transformed.y;
  169. this.normals[index + 2] = transformed.z;
  170. }
  171. }
  172. };
  173. VertexData.prototype.merge = function (other) {
  174. var index;
  175. if (other.indices) {
  176. if (!this.indices) {
  177. this.indices = [];
  178. }
  179. var offset = this.positions ? this.positions.length / 3 : 0;
  180. for (index = 0; index < other.indices.length; index++) {
  181. this.indices.push(other.indices[index] + offset);
  182. }
  183. }
  184. if (other.positions) {
  185. if (!this.positions) {
  186. this.positions = [];
  187. }
  188. for (index = 0; index < other.positions.length; index++) {
  189. this.positions.push(other.positions[index]);
  190. }
  191. }
  192. if (other.normals) {
  193. if (!this.normals) {
  194. this.normals = [];
  195. }
  196. for (index = 0; index < other.normals.length; index++) {
  197. this.normals.push(other.normals[index]);
  198. }
  199. }
  200. if (other.uvs) {
  201. if (!this.uvs) {
  202. this.uvs = [];
  203. }
  204. for (index = 0; index < other.uvs.length; index++) {
  205. this.uvs.push(other.uvs[index]);
  206. }
  207. }
  208. if (other.uvs2) {
  209. if (!this.uvs2) {
  210. this.uvs2 = [];
  211. }
  212. for (index = 0; index < other.uvs2.length; index++) {
  213. this.uvs2.push(other.uvs2[index]);
  214. }
  215. }
  216. if (other.uvs3) {
  217. if (!this.uvs3) {
  218. this.uvs3 = [];
  219. }
  220. for (index = 0; index < other.uvs3.length; index++) {
  221. this.uvs3.push(other.uvs3[index]);
  222. }
  223. }
  224. if (other.uvs4) {
  225. if (!this.uvs4) {
  226. this.uvs4 = [];
  227. }
  228. for (index = 0; index < other.uvs4.length; index++) {
  229. this.uvs4.push(other.uvs4[index]);
  230. }
  231. }
  232. if (other.uvs5) {
  233. if (!this.uvs5) {
  234. this.uvs5 = [];
  235. }
  236. for (index = 0; index < other.uvs5.length; index++) {
  237. this.uvs5.push(other.uvs5[index]);
  238. }
  239. }
  240. if (other.uvs6) {
  241. if (!this.uvs6) {
  242. this.uvs6 = [];
  243. }
  244. for (index = 0; index < other.uvs6.length; index++) {
  245. this.uvs6.push(other.uvs6[index]);
  246. }
  247. }
  248. if (other.matricesIndices) {
  249. if (!this.matricesIndices) {
  250. this.matricesIndices = [];
  251. }
  252. for (index = 0; index < other.matricesIndices.length; index++) {
  253. this.matricesIndices.push(other.matricesIndices[index]);
  254. }
  255. }
  256. if (other.matricesWeights) {
  257. if (!this.matricesWeights) {
  258. this.matricesWeights = [];
  259. }
  260. for (index = 0; index < other.matricesWeights.length; index++) {
  261. this.matricesWeights.push(other.matricesWeights[index]);
  262. }
  263. }
  264. if (other.matricesIndicesExtra) {
  265. if (!this.matricesIndicesExtra) {
  266. this.matricesIndicesExtra = [];
  267. }
  268. for (index = 0; index < other.matricesIndicesExtra.length; index++) {
  269. this.matricesIndicesExtra.push(other.matricesIndicesExtra[index]);
  270. }
  271. }
  272. if (other.matricesWeightsExtra) {
  273. if (!this.matricesWeightsExtra) {
  274. this.matricesWeightsExtra = [];
  275. }
  276. for (index = 0; index < other.matricesWeightsExtra.length; index++) {
  277. this.matricesWeightsExtra.push(other.matricesWeightsExtra[index]);
  278. }
  279. }
  280. if (other.colors) {
  281. if (!this.colors) {
  282. this.colors = [];
  283. }
  284. for (index = 0; index < other.colors.length; index++) {
  285. this.colors.push(other.colors[index]);
  286. }
  287. }
  288. };
  289. // Statics
  290. VertexData.ExtractFromMesh = function (mesh, copyWhenShared) {
  291. return VertexData._ExtractFrom(mesh, copyWhenShared);
  292. };
  293. VertexData.ExtractFromGeometry = function (geometry, copyWhenShared) {
  294. return VertexData._ExtractFrom(geometry, copyWhenShared);
  295. };
  296. VertexData._ExtractFrom = function (meshOrGeometry, copyWhenShared) {
  297. var result = new VertexData();
  298. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
  299. result.positions = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.PositionKind, copyWhenShared);
  300. }
  301. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
  302. result.normals = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.NormalKind, copyWhenShared);
  303. }
  304. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
  305. result.uvs = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.UVKind, copyWhenShared);
  306. }
  307. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
  308. result.uvs2 = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.UV2Kind, copyWhenShared);
  309. }
  310. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.UV3Kind)) {
  311. result.uvs3 = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.UV3Kind, copyWhenShared);
  312. }
  313. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.UV4Kind)) {
  314. result.uvs4 = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.UV4Kind, copyWhenShared);
  315. }
  316. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.UV5Kind)) {
  317. result.uvs5 = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.UV5Kind, copyWhenShared);
  318. }
  319. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.UV6Kind)) {
  320. result.uvs6 = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.UV6Kind, copyWhenShared);
  321. }
  322. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
  323. result.colors = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.ColorKind, copyWhenShared);
  324. }
  325. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind)) {
  326. result.matricesIndices = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind, copyWhenShared);
  327. }
  328. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
  329. result.matricesWeights = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, copyWhenShared);
  330. }
  331. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesExtraKind)) {
  332. result.matricesIndicesExtra = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, copyWhenShared);
  333. }
  334. if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsExtraKind)) {
  335. result.matricesWeightsExtra = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind, copyWhenShared);
  336. }
  337. result.indices = meshOrGeometry.getIndices(copyWhenShared);
  338. return result;
  339. };
  340. VertexData.CreateRibbon = function (options) {
  341. var pathArray = options.pathArray;
  342. var closeArray = options.closeArray || false;
  343. var closePath = options.closePath || false;
  344. var defaultOffset = Math.floor(pathArray[0].length / 2);
  345. var offset = options.offset || defaultOffset;
  346. offset = offset > defaultOffset ? defaultOffset : Math.floor(offset); // offset max allowed : defaultOffset
  347. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  348. var positions = [];
  349. var indices = [];
  350. var normals = [];
  351. var uvs = [];
  352. var us = []; // us[path_id] = [uDist1, uDist2, uDist3 ... ] distances between points on path path_id
  353. var vs = []; // vs[i] = [vDist1, vDist2, vDist3, ... ] distances between points i of consecutives paths from pathArray
  354. var uTotalDistance = []; // uTotalDistance[p] : total distance of path p
  355. var vTotalDistance = []; // vTotalDistance[i] : total distance between points i of first and last path from pathArray
  356. var minlg; // minimal length among all paths from pathArray
  357. var lg = []; // array of path lengths : nb of vertex per path
  358. var idx = []; // array of path indexes : index of each path (first vertex) in the total vertex number
  359. var p; // path iterator
  360. var i; // point iterator
  361. var j; // point iterator
  362. // if single path in pathArray
  363. if (pathArray.length < 2) {
  364. var ar1 = [];
  365. var ar2 = [];
  366. for (i = 0; i < pathArray[0].length - offset; i++) {
  367. ar1.push(pathArray[0][i]);
  368. ar2.push(pathArray[0][i + offset]);
  369. }
  370. pathArray = [ar1, ar2];
  371. }
  372. // positions and horizontal distances (u)
  373. var idc = 0;
  374. var closePathCorr = (closePath) ? 1 : 0;
  375. var path;
  376. var l;
  377. minlg = pathArray[0].length;
  378. var vectlg;
  379. var dist;
  380. for (p = 0; p < pathArray.length; p++) {
  381. uTotalDistance[p] = 0;
  382. us[p] = [0];
  383. path = pathArray[p];
  384. l = path.length;
  385. minlg = (minlg < l) ? minlg : l;
  386. j = 0;
  387. while (j < l) {
  388. positions.push(path[j].x, path[j].y, path[j].z);
  389. if (j > 0) {
  390. vectlg = path[j].subtract(path[j - 1]).length();
  391. dist = vectlg + uTotalDistance[p];
  392. us[p].push(dist);
  393. uTotalDistance[p] = dist;
  394. }
  395. j++;
  396. }
  397. if (closePath) {
  398. j--;
  399. positions.push(path[0].x, path[0].y, path[0].z);
  400. vectlg = path[j].subtract(path[0]).length();
  401. dist = vectlg + uTotalDistance[p];
  402. us[p].push(dist);
  403. uTotalDistance[p] = dist;
  404. }
  405. lg[p] = l + closePathCorr;
  406. idx[p] = idc;
  407. idc += (l + closePathCorr);
  408. }
  409. // vertical distances (v)
  410. var path1;
  411. var path2;
  412. var vertex1;
  413. var vertex2;
  414. for (i = 0; i < minlg + closePathCorr; i++) {
  415. vTotalDistance[i] = 0;
  416. vs[i] = [0];
  417. for (p = 0; p < pathArray.length - 1; p++) {
  418. path1 = pathArray[p];
  419. path2 = pathArray[p + 1];
  420. if (i === minlg) {
  421. vertex1 = path1[0];
  422. vertex2 = path2[0];
  423. }
  424. else {
  425. vertex1 = path1[i];
  426. vertex2 = path2[i];
  427. }
  428. vectlg = vertex2.subtract(vertex1).length();
  429. dist = vectlg + vTotalDistance[i];
  430. vs[i].push(dist);
  431. vTotalDistance[i] = dist;
  432. }
  433. if (closeArray) {
  434. path1 = pathArray[p];
  435. path2 = pathArray[0];
  436. if (i === minlg) {
  437. vertex2 = path2[0];
  438. }
  439. vectlg = vertex2.subtract(vertex1).length();
  440. dist = vectlg + vTotalDistance[i];
  441. vTotalDistance[i] = dist;
  442. }
  443. }
  444. // uvs
  445. var u;
  446. var v;
  447. for (p = 0; p < pathArray.length; p++) {
  448. for (i = 0; i < minlg + closePathCorr; i++) {
  449. u = us[p][i] / uTotalDistance[p];
  450. v = vs[i][p] / vTotalDistance[i];
  451. uvs.push(u, v);
  452. }
  453. }
  454. // indices
  455. p = 0; // path index
  456. var pi = 0; // positions array index
  457. var l1 = lg[p] - 1; // path1 length
  458. var l2 = lg[p + 1] - 1; // path2 length
  459. var min = (l1 < l2) ? l1 : l2; // current path stop index
  460. var shft = idx[1] - idx[0]; // shift
  461. var path1nb = closeArray ? lg.length : lg.length - 1; // number of path1 to iterate on
  462. while (pi <= min && p < path1nb) {
  463. // draw two triangles between path1 (p1) and path2 (p2) : (p1.pi, p2.pi, p1.pi+1) and (p2.pi+1, p1.pi+1, p2.pi) clockwise
  464. indices.push(pi, pi + shft, pi + 1);
  465. indices.push(pi + shft + 1, pi + 1, pi + shft);
  466. pi += 1;
  467. if (pi === min) {
  468. p++;
  469. if (p === lg.length - 1) {
  470. shft = idx[0] - idx[p];
  471. l1 = lg[p] - 1;
  472. l2 = lg[0] - 1;
  473. }
  474. else {
  475. shft = idx[p + 1] - idx[p];
  476. l1 = lg[p] - 1;
  477. l2 = lg[p + 1] - 1;
  478. }
  479. pi = idx[p];
  480. min = (l1 < l2) ? l1 + pi : l2 + pi;
  481. }
  482. }
  483. // normals
  484. VertexData.ComputeNormals(positions, indices, normals);
  485. if (closePath) {
  486. var indexFirst = 0;
  487. var indexLast = 0;
  488. for (p = 0; p < pathArray.length; p++) {
  489. indexFirst = idx[p] * 3;
  490. if (p + 1 < pathArray.length) {
  491. indexLast = (idx[p + 1] - 1) * 3;
  492. }
  493. else {
  494. indexLast = normals.length - 3;
  495. }
  496. normals[indexFirst] = (normals[indexFirst] + normals[indexLast]) * 0.5;
  497. normals[indexFirst + 1] = (normals[indexFirst + 1] + normals[indexLast + 1]) * 0.5;
  498. normals[indexFirst + 2] = (normals[indexFirst + 2] + normals[indexLast + 2]) * 0.5;
  499. normals[indexLast] = normals[indexFirst];
  500. normals[indexLast + 1] = normals[indexFirst + 1];
  501. normals[indexLast + 2] = normals[indexFirst + 2];
  502. }
  503. }
  504. // sides
  505. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  506. // Result
  507. var vertexData = new VertexData();
  508. vertexData.indices = indices;
  509. vertexData.positions = positions;
  510. vertexData.normals = normals;
  511. vertexData.uvs = uvs;
  512. if (closePath) {
  513. vertexData._idx = idx;
  514. }
  515. return vertexData;
  516. };
  517. VertexData.CreateBox = function (options) {
  518. var normalsSource = [
  519. new BABYLON.Vector3(0, 0, 1),
  520. new BABYLON.Vector3(0, 0, -1),
  521. new BABYLON.Vector3(1, 0, 0),
  522. new BABYLON.Vector3(-1, 0, 0),
  523. new BABYLON.Vector3(0, 1, 0),
  524. new BABYLON.Vector3(0, -1, 0)
  525. ];
  526. var indices = [];
  527. var positions = [];
  528. var normals = [];
  529. var uvs = [];
  530. var width = options.width || options.size || 1;
  531. var height = options.height || options.size || 1;
  532. var depth = options.depth || options.size || 1;
  533. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  534. var faceUV = options.faceUV || new Array(6);
  535. var faceColors = options.faceColors;
  536. var colors = [];
  537. // default face colors and UV if undefined
  538. for (var f = 0; f < 6; f++) {
  539. if (faceUV[f] === undefined) {
  540. faceUV[f] = new BABYLON.Vector4(0, 0, 1, 1);
  541. }
  542. if (faceColors && faceColors[f] === undefined) {
  543. faceColors[f] = new BABYLON.Color4(1, 1, 1, 1);
  544. }
  545. }
  546. var scaleVector = new BABYLON.Vector3(width / 2, height / 2, depth / 2);
  547. // Create each face in turn.
  548. for (var index = 0; index < normalsSource.length; index++) {
  549. var normal = normalsSource[index];
  550. // Get two vectors perpendicular to the face normal and to each other.
  551. var side1 = new BABYLON.Vector3(normal.y, normal.z, normal.x);
  552. var side2 = BABYLON.Vector3.Cross(normal, side1);
  553. // Six indices (two triangles) per face.
  554. var verticesLength = positions.length / 3;
  555. indices.push(verticesLength);
  556. indices.push(verticesLength + 1);
  557. indices.push(verticesLength + 2);
  558. indices.push(verticesLength);
  559. indices.push(verticesLength + 2);
  560. indices.push(verticesLength + 3);
  561. // Four vertices per face.
  562. var vertex = normal.subtract(side1).subtract(side2).multiply(scaleVector);
  563. positions.push(vertex.x, vertex.y, vertex.z);
  564. normals.push(normal.x, normal.y, normal.z);
  565. uvs.push(faceUV[index].z, faceUV[index].w);
  566. if (faceColors) {
  567. colors.push(faceColors[index].r, faceColors[index].g, faceColors[index].b, faceColors[index].a);
  568. }
  569. vertex = normal.subtract(side1).add(side2).multiply(scaleVector);
  570. positions.push(vertex.x, vertex.y, vertex.z);
  571. normals.push(normal.x, normal.y, normal.z);
  572. uvs.push(faceUV[index].x, faceUV[index].w);
  573. if (faceColors) {
  574. colors.push(faceColors[index].r, faceColors[index].g, faceColors[index].b, faceColors[index].a);
  575. }
  576. vertex = normal.add(side1).add(side2).multiply(scaleVector);
  577. positions.push(vertex.x, vertex.y, vertex.z);
  578. normals.push(normal.x, normal.y, normal.z);
  579. uvs.push(faceUV[index].x, faceUV[index].y);
  580. if (faceColors) {
  581. colors.push(faceColors[index].r, faceColors[index].g, faceColors[index].b, faceColors[index].a);
  582. }
  583. vertex = normal.add(side1).subtract(side2).multiply(scaleVector);
  584. positions.push(vertex.x, vertex.y, vertex.z);
  585. normals.push(normal.x, normal.y, normal.z);
  586. uvs.push(faceUV[index].z, faceUV[index].y);
  587. if (faceColors) {
  588. colors.push(faceColors[index].r, faceColors[index].g, faceColors[index].b, faceColors[index].a);
  589. }
  590. }
  591. // sides
  592. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  593. // Result
  594. var vertexData = new VertexData();
  595. vertexData.indices = indices;
  596. vertexData.positions = positions;
  597. vertexData.normals = normals;
  598. vertexData.uvs = uvs;
  599. if (faceColors) {
  600. var totalColors = (sideOrientation === BABYLON.Mesh.DOUBLESIDE) ? colors.concat(colors) : colors;
  601. vertexData.colors = totalColors;
  602. }
  603. return vertexData;
  604. };
  605. VertexData.CreateSphere = function (options) {
  606. var segments = options.segments || 32;
  607. var diameterX = options.diameterX || options.diameter || 1;
  608. var diameterY = options.diameterY || options.diameter || 1;
  609. var diameterZ = options.diameterZ || options.diameter || 1;
  610. var arc = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
  611. var slice = (options.slice <= 0) ? 1.0 : options.slice || 1.0;
  612. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  613. var radius = new BABYLON.Vector3(diameterX / 2, diameterY / 2, diameterZ / 2);
  614. var totalZRotationSteps = 2 + segments;
  615. var totalYRotationSteps = 2 * totalZRotationSteps;
  616. var indices = [];
  617. var positions = [];
  618. var normals = [];
  619. var uvs = [];
  620. for (var zRotationStep = 0; zRotationStep <= totalZRotationSteps; zRotationStep++) {
  621. var normalizedZ = zRotationStep / totalZRotationSteps;
  622. var angleZ = normalizedZ * Math.PI * slice;
  623. for (var yRotationStep = 0; yRotationStep <= totalYRotationSteps; yRotationStep++) {
  624. var normalizedY = yRotationStep / totalYRotationSteps;
  625. var angleY = normalizedY * Math.PI * 2 * arc;
  626. var rotationZ = BABYLON.Matrix.RotationZ(-angleZ);
  627. var rotationY = BABYLON.Matrix.RotationY(angleY);
  628. var afterRotZ = BABYLON.Vector3.TransformCoordinates(BABYLON.Vector3.Up(), rotationZ);
  629. var complete = BABYLON.Vector3.TransformCoordinates(afterRotZ, rotationY);
  630. var vertex = complete.multiply(radius);
  631. var normal = BABYLON.Vector3.Normalize(vertex);
  632. positions.push(vertex.x, vertex.y, vertex.z);
  633. normals.push(normal.x, normal.y, normal.z);
  634. uvs.push(normalizedY, normalizedZ);
  635. }
  636. if (zRotationStep > 0) {
  637. var verticesCount = positions.length / 3;
  638. for (var firstIndex = verticesCount - 2 * (totalYRotationSteps + 1); (firstIndex + totalYRotationSteps + 2) < verticesCount; firstIndex++) {
  639. indices.push((firstIndex));
  640. indices.push((firstIndex + 1));
  641. indices.push(firstIndex + totalYRotationSteps + 1);
  642. indices.push((firstIndex + totalYRotationSteps + 1));
  643. indices.push((firstIndex + 1));
  644. indices.push((firstIndex + totalYRotationSteps + 2));
  645. }
  646. }
  647. }
  648. // Sides
  649. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  650. // Result
  651. var vertexData = new VertexData();
  652. vertexData.indices = indices;
  653. vertexData.positions = positions;
  654. vertexData.normals = normals;
  655. vertexData.uvs = uvs;
  656. return vertexData;
  657. };
  658. // Cylinder and cone
  659. VertexData.CreateCylinder = function (options) {
  660. var height = options.height || 2;
  661. var diameterTop = (options.diameterTop === 0) ? 0 : options.diameterTop || options.diameter || 1;
  662. var diameterBottom = options.diameterBottom || options.diameter || 1;
  663. var tessellation = options.tessellation || 24;
  664. var subdivisions = options.subdivisions || 1;
  665. var hasRings = options.hasRings;
  666. var enclose = options.enclose;
  667. var arc = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
  668. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  669. var faceUV = options.faceUV || new Array(3);
  670. var faceColors = options.faceColors;
  671. // default face colors and UV if undefined
  672. var quadNb = (arc !== 1 && enclose) ? 2 : 0;
  673. var ringNb = (hasRings) ? subdivisions : 1;
  674. var colorNb = 2 + (1 + quadNb) * ringNb;
  675. var f;
  676. for (f = 0; f < colorNb; f++) {
  677. if (faceColors && faceColors[f] === undefined) {
  678. faceColors[f] = new BABYLON.Color4(1, 1, 1, 1);
  679. }
  680. }
  681. for (f = 0; f < 3; f++) {
  682. if (faceUV && faceUV[f] === undefined) {
  683. faceUV[f] = new BABYLON.Vector4(0, 0, 1, 1);
  684. }
  685. }
  686. var indices = [];
  687. var positions = [];
  688. var normals = [];
  689. var uvs = [];
  690. var colors = [];
  691. var angle_step = Math.PI * 2 * arc / tessellation;
  692. var angle;
  693. var h;
  694. var radius;
  695. var tan = (diameterBottom - diameterTop) / 2 / height;
  696. var ringVertex = BABYLON.Vector3.Zero();
  697. var ringNormal = BABYLON.Vector3.Zero();
  698. var ringFirstVertex = BABYLON.Vector3.Zero();
  699. var ringFirstNormal = BABYLON.Vector3.Zero();
  700. var quadNormal = BABYLON.Vector3.Zero();
  701. var Y = BABYLON.Axis.Y;
  702. // positions, normals, uvs
  703. var i;
  704. var j;
  705. var r;
  706. var ringIdx = 1;
  707. for (i = 0; i <= subdivisions; i++) {
  708. h = i / subdivisions;
  709. radius = (h * (diameterTop - diameterBottom) + diameterBottom) / 2;
  710. ringIdx = (hasRings && i !== 0 && i !== subdivisions) ? 2 : 1;
  711. for (r = 0; r < ringIdx; r++) {
  712. for (j = 0; j <= tessellation; j++) {
  713. angle = j * angle_step;
  714. // position
  715. ringVertex.x = Math.cos(-angle) * radius;
  716. ringVertex.y = -height / 2 + h * height;
  717. ringVertex.z = Math.sin(-angle) * radius;
  718. // normal
  719. if (diameterTop === 0 && i === subdivisions) {
  720. // if no top cap, reuse former normals
  721. ringNormal.x = normals[normals.length - (tessellation + 1) * 3];
  722. ringNormal.y = normals[normals.length - (tessellation + 1) * 3 + 1];
  723. ringNormal.z = normals[normals.length - (tessellation + 1) * 3 + 2];
  724. }
  725. else {
  726. ringNormal.x = ringVertex.x;
  727. ringNormal.z = ringVertex.z;
  728. ringNormal.y = Math.sqrt(ringNormal.x * ringNormal.x + ringNormal.z * ringNormal.z) * tan;
  729. ringNormal.normalize();
  730. }
  731. // keep first values for enclose
  732. if (j === 0) {
  733. ringFirstVertex.copyFrom(ringVertex);
  734. ringFirstNormal.copyFrom(ringNormal);
  735. }
  736. positions.push(ringVertex.x, ringVertex.y, ringVertex.z);
  737. normals.push(ringNormal.x, ringNormal.y, ringNormal.z);
  738. uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x) * j / tessellation, faceUV[1].y + (faceUV[1].w - faceUV[1].y) * h);
  739. if (faceColors) {
  740. colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
  741. }
  742. }
  743. // if enclose, add four vertices and their dedicated normals
  744. if (arc !== 1 && enclose) {
  745. positions.push(ringVertex.x, ringVertex.y, ringVertex.z);
  746. positions.push(0, ringVertex.y, 0);
  747. positions.push(0, ringVertex.y, 0);
  748. positions.push(ringFirstVertex.x, ringFirstVertex.y, ringFirstVertex.z);
  749. BABYLON.Vector3.CrossToRef(Y, ringNormal, quadNormal);
  750. quadNormal.normalize();
  751. normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);
  752. BABYLON.Vector3.CrossToRef(ringFirstNormal, Y, quadNormal);
  753. quadNormal.normalize();
  754. normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);
  755. uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
  756. uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
  757. uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
  758. uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
  759. if (faceColors) {
  760. colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
  761. colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
  762. colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
  763. colors.push(faceColors[1].r, faceColors[1].g, faceColors[1].b, faceColors[1].a);
  764. }
  765. }
  766. }
  767. }
  768. // indices
  769. var e = (arc !== 1 && enclose) ? tessellation + 4 : tessellation; // correction of number of iteration if enclose
  770. var s;
  771. i = 0;
  772. for (s = 0; s < subdivisions; s++) {
  773. for (j = 0; j < tessellation; j++) {
  774. var i0 = i * (e + 1) + j;
  775. var i1 = (i + 1) * (e + 1) + j;
  776. var i2 = i * (e + 1) + (j + 1);
  777. var i3 = (i + 1) * (e + 1) + (j + 1);
  778. indices.push(i0, i1, i2);
  779. indices.push(i3, i2, i1);
  780. }
  781. if (arc !== 1 && enclose) {
  782. indices.push(i0 + 2, i1 + 2, i2 + 2);
  783. indices.push(i3 + 2, i2 + 2, i1 + 2);
  784. indices.push(i0 + 4, i1 + 4, i2 + 4);
  785. indices.push(i3 + 4, i2 + 4, i1 + 4);
  786. }
  787. i = (hasRings) ? (i + 2) : (i + 1);
  788. }
  789. // Caps
  790. var createCylinderCap = function (isTop) {
  791. var radius = isTop ? diameterTop / 2 : diameterBottom / 2;
  792. if (radius === 0) {
  793. return;
  794. }
  795. // Cap positions, normals & uvs
  796. var angle;
  797. var circleVector;
  798. var i;
  799. var u = (isTop) ? faceUV[2] : faceUV[0];
  800. var c;
  801. if (faceColors) {
  802. c = (isTop) ? faceColors[colorNb - 1] : faceColors[0];
  803. }
  804. // cap center
  805. var vbase = positions.length / 3;
  806. var offset = isTop ? height / 2 : -height / 2;
  807. var center = new BABYLON.Vector3(0, offset, 0);
  808. positions.push(center.x, center.y, center.z);
  809. normals.push(0, isTop ? 1 : -1, 0);
  810. uvs.push(u.x + (u.z - u.x) * 0.5, u.y + (u.w - u.y) * 0.5);
  811. if (faceColors) {
  812. colors.push(c.r, c.g, c.b, c.a);
  813. }
  814. var textureScale = new BABYLON.Vector2(0.5, 0.5);
  815. for (i = 0; i <= tessellation; i++) {
  816. angle = Math.PI * 2 * i * arc / tessellation;
  817. var cos = Math.cos(-angle);
  818. var sin = Math.sin(-angle);
  819. circleVector = new BABYLON.Vector3(cos * radius, offset, sin * radius);
  820. var textureCoordinate = new BABYLON.Vector2(cos * textureScale.x + 0.5, sin * textureScale.y + 0.5);
  821. positions.push(circleVector.x, circleVector.y, circleVector.z);
  822. normals.push(0, isTop ? 1 : -1, 0);
  823. uvs.push(u.x + (u.z - u.x) * textureCoordinate.x, u.y + (u.w - u.y) * textureCoordinate.y);
  824. if (faceColors) {
  825. colors.push(c.r, c.g, c.b, c.a);
  826. }
  827. }
  828. // Cap indices
  829. for (i = 0; i < tessellation; i++) {
  830. if (!isTop) {
  831. indices.push(vbase);
  832. indices.push(vbase + (i + 1));
  833. indices.push(vbase + (i + 2));
  834. }
  835. else {
  836. indices.push(vbase);
  837. indices.push(vbase + (i + 2));
  838. indices.push(vbase + (i + 1));
  839. }
  840. }
  841. };
  842. // add caps to geometry
  843. createCylinderCap(false);
  844. createCylinderCap(true);
  845. // Sides
  846. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  847. var vertexData = new VertexData();
  848. vertexData.indices = indices;
  849. vertexData.positions = positions;
  850. vertexData.normals = normals;
  851. vertexData.uvs = uvs;
  852. if (faceColors) {
  853. vertexData.colors = colors;
  854. }
  855. return vertexData;
  856. };
  857. VertexData.CreateTorus = function (options) {
  858. var indices = [];
  859. var positions = [];
  860. var normals = [];
  861. var uvs = [];
  862. var diameter = options.diameter || 1;
  863. var thickness = options.thickness || 0.5;
  864. var tessellation = options.tessellation || 16;
  865. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  866. var stride = tessellation + 1;
  867. for (var i = 0; i <= tessellation; i++) {
  868. var u = i / tessellation;
  869. var outerAngle = i * Math.PI * 2.0 / tessellation - Math.PI / 2.0;
  870. var transform = BABYLON.Matrix.Translation(diameter / 2.0, 0, 0).multiply(BABYLON.Matrix.RotationY(outerAngle));
  871. for (var j = 0; j <= tessellation; j++) {
  872. var v = 1 - j / tessellation;
  873. var innerAngle = j * Math.PI * 2.0 / tessellation + Math.PI;
  874. var dx = Math.cos(innerAngle);
  875. var dy = Math.sin(innerAngle);
  876. // Create a vertex.
  877. var normal = new BABYLON.Vector3(dx, dy, 0);
  878. var position = normal.scale(thickness / 2);
  879. var textureCoordinate = new BABYLON.Vector2(u, v);
  880. position = BABYLON.Vector3.TransformCoordinates(position, transform);
  881. normal = BABYLON.Vector3.TransformNormal(normal, transform);
  882. positions.push(position.x, position.y, position.z);
  883. normals.push(normal.x, normal.y, normal.z);
  884. uvs.push(textureCoordinate.x, textureCoordinate.y);
  885. // And create indices for two triangles.
  886. var nextI = (i + 1) % stride;
  887. var nextJ = (j + 1) % stride;
  888. indices.push(i * stride + j);
  889. indices.push(i * stride + nextJ);
  890. indices.push(nextI * stride + j);
  891. indices.push(i * stride + nextJ);
  892. indices.push(nextI * stride + nextJ);
  893. indices.push(nextI * stride + j);
  894. }
  895. }
  896. // Sides
  897. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  898. // Result
  899. var vertexData = new VertexData();
  900. vertexData.indices = indices;
  901. vertexData.positions = positions;
  902. vertexData.normals = normals;
  903. vertexData.uvs = uvs;
  904. return vertexData;
  905. };
  906. VertexData.CreateLines = function (options) {
  907. var indices = [];
  908. var positions = [];
  909. var points = options.points;
  910. for (var index = 0; index < points.length; index++) {
  911. positions.push(points[index].x, points[index].y, points[index].z);
  912. if (index > 0) {
  913. indices.push(index - 1);
  914. indices.push(index);
  915. }
  916. }
  917. // Result
  918. var vertexData = new VertexData();
  919. vertexData.indices = indices;
  920. vertexData.positions = positions;
  921. return vertexData;
  922. };
  923. VertexData.CreateDashedLines = function (options) {
  924. var dashSize = options.dashSize || 3;
  925. var gapSize = options.gapSize || 1;
  926. var dashNb = options.dashNb || 200;
  927. var points = options.points;
  928. var positions = new Array();
  929. var indices = new Array();
  930. var curvect = BABYLON.Vector3.Zero();
  931. var lg = 0;
  932. var nb = 0;
  933. var shft = 0;
  934. var dashshft = 0;
  935. var curshft = 0;
  936. var idx = 0;
  937. var i = 0;
  938. for (i = 0; i < points.length - 1; i++) {
  939. points[i + 1].subtractToRef(points[i], curvect);
  940. lg += curvect.length();
  941. }
  942. shft = lg / dashNb;
  943. dashshft = dashSize * shft / (dashSize + gapSize);
  944. for (i = 0; i < points.length - 1; i++) {
  945. points[i + 1].subtractToRef(points[i], curvect);
  946. nb = Math.floor(curvect.length() / shft);
  947. curvect.normalize();
  948. for (var j = 0; j < nb; j++) {
  949. curshft = shft * j;
  950. positions.push(points[i].x + curshft * curvect.x, points[i].y + curshft * curvect.y, points[i].z + curshft * curvect.z);
  951. positions.push(points[i].x + (curshft + dashshft) * curvect.x, points[i].y + (curshft + dashshft) * curvect.y, points[i].z + (curshft + dashshft) * curvect.z);
  952. indices.push(idx, idx + 1);
  953. idx += 2;
  954. }
  955. }
  956. // Result
  957. var vertexData = new VertexData();
  958. vertexData.positions = positions;
  959. vertexData.indices = indices;
  960. return vertexData;
  961. };
  962. VertexData.CreateGround = function (options) {
  963. var indices = [];
  964. var positions = [];
  965. var normals = [];
  966. var uvs = [];
  967. var row, col;
  968. var width = options.width || 1;
  969. var height = options.height || 1;
  970. var subdivisions = options.subdivisions || 1;
  971. for (row = 0; row <= subdivisions; row++) {
  972. for (col = 0; col <= subdivisions; col++) {
  973. var position = new BABYLON.Vector3((col * width) / subdivisions - (width / 2.0), 0, ((subdivisions - row) * height) / subdivisions - (height / 2.0));
  974. var normal = new BABYLON.Vector3(0, 1.0, 0);
  975. positions.push(position.x, position.y, position.z);
  976. normals.push(normal.x, normal.y, normal.z);
  977. uvs.push(col / subdivisions, 1.0 - row / subdivisions);
  978. }
  979. }
  980. for (row = 0; row < subdivisions; row++) {
  981. for (col = 0; col < subdivisions; col++) {
  982. indices.push(col + 1 + (row + 1) * (subdivisions + 1));
  983. indices.push(col + 1 + row * (subdivisions + 1));
  984. indices.push(col + row * (subdivisions + 1));
  985. indices.push(col + (row + 1) * (subdivisions + 1));
  986. indices.push(col + 1 + (row + 1) * (subdivisions + 1));
  987. indices.push(col + row * (subdivisions + 1));
  988. }
  989. }
  990. // Result
  991. var vertexData = new VertexData();
  992. vertexData.indices = indices;
  993. vertexData.positions = positions;
  994. vertexData.normals = normals;
  995. vertexData.uvs = uvs;
  996. return vertexData;
  997. };
  998. VertexData.CreateTiledGround = function (options) {
  999. var xmin = options.xmin;
  1000. var zmin = options.zmin;
  1001. var xmax = options.xmax;
  1002. var zmax = options.zmax;
  1003. var subdivisions = options.subdivisions || { w: 1, h: 1 };
  1004. var precision = options.precision || { w: 1, h: 1 };
  1005. var indices = [];
  1006. var positions = [];
  1007. var normals = [];
  1008. var uvs = [];
  1009. var row, col, tileRow, tileCol;
  1010. subdivisions.h = (subdivisions.w < 1) ? 1 : subdivisions.h;
  1011. subdivisions.w = (subdivisions.w < 1) ? 1 : subdivisions.w;
  1012. precision.w = (precision.w < 1) ? 1 : precision.w;
  1013. precision.h = (precision.h < 1) ? 1 : precision.h;
  1014. var tileSize = {
  1015. 'w': (xmax - xmin) / subdivisions.w,
  1016. 'h': (zmax - zmin) / subdivisions.h
  1017. };
  1018. function applyTile(xTileMin, zTileMin, xTileMax, zTileMax) {
  1019. // Indices
  1020. var base = positions.length / 3;
  1021. var rowLength = precision.w + 1;
  1022. for (row = 0; row < precision.h; row++) {
  1023. for (col = 0; col < precision.w; col++) {
  1024. var square = [
  1025. base + col + row * rowLength,
  1026. base + (col + 1) + row * rowLength,
  1027. base + (col + 1) + (row + 1) * rowLength,
  1028. base + col + (row + 1) * rowLength
  1029. ];
  1030. indices.push(square[1]);
  1031. indices.push(square[2]);
  1032. indices.push(square[3]);
  1033. indices.push(square[0]);
  1034. indices.push(square[1]);
  1035. indices.push(square[3]);
  1036. }
  1037. }
  1038. // Position, normals and uvs
  1039. var position = BABYLON.Vector3.Zero();
  1040. var normal = new BABYLON.Vector3(0, 1.0, 0);
  1041. for (row = 0; row <= precision.h; row++) {
  1042. position.z = (row * (zTileMax - zTileMin)) / precision.h + zTileMin;
  1043. for (col = 0; col <= precision.w; col++) {
  1044. position.x = (col * (xTileMax - xTileMin)) / precision.w + xTileMin;
  1045. position.y = 0;
  1046. positions.push(position.x, position.y, position.z);
  1047. normals.push(normal.x, normal.y, normal.z);
  1048. uvs.push(col / precision.w, row / precision.h);
  1049. }
  1050. }
  1051. }
  1052. for (tileRow = 0; tileRow < subdivisions.h; tileRow++) {
  1053. for (tileCol = 0; tileCol < subdivisions.w; tileCol++) {
  1054. applyTile(xmin + tileCol * tileSize.w, zmin + tileRow * tileSize.h, xmin + (tileCol + 1) * tileSize.w, zmin + (tileRow + 1) * tileSize.h);
  1055. }
  1056. }
  1057. // Result
  1058. var vertexData = new VertexData();
  1059. vertexData.indices = indices;
  1060. vertexData.positions = positions;
  1061. vertexData.normals = normals;
  1062. vertexData.uvs = uvs;
  1063. return vertexData;
  1064. };
  1065. VertexData.CreateGroundFromHeightMap = function (options) {
  1066. var indices = [];
  1067. var positions = [];
  1068. var normals = [];
  1069. var uvs = [];
  1070. var row, col;
  1071. // Vertices
  1072. for (row = 0; row <= options.subdivisions; row++) {
  1073. for (col = 0; col <= options.subdivisions; col++) {
  1074. var position = new BABYLON.Vector3((col * options.width) / options.subdivisions - (options.width / 2.0), 0, ((options.subdivisions - row) * options.height) / options.subdivisions - (options.height / 2.0));
  1075. // Compute height
  1076. var heightMapX = (((position.x + options.width / 2) / options.width) * (options.bufferWidth - 1)) | 0;
  1077. var heightMapY = ((1.0 - (position.z + options.height / 2) / options.height) * (options.bufferHeight - 1)) | 0;
  1078. var pos = (heightMapX + heightMapY * options.bufferWidth) * 4;
  1079. var r = options.buffer[pos] / 255.0;
  1080. var g = options.buffer[pos + 1] / 255.0;
  1081. var b = options.buffer[pos + 2] / 255.0;
  1082. var gradient = r * 0.3 + g * 0.59 + b * 0.11;
  1083. position.y = options.minHeight + (options.maxHeight - options.minHeight) * gradient;
  1084. // Add vertex
  1085. positions.push(position.x, position.y, position.z);
  1086. normals.push(0, 0, 0);
  1087. uvs.push(col / options.subdivisions, 1.0 - row / options.subdivisions);
  1088. }
  1089. }
  1090. // Indices
  1091. for (row = 0; row < options.subdivisions; row++) {
  1092. for (col = 0; col < options.subdivisions; col++) {
  1093. indices.push(col + 1 + (row + 1) * (options.subdivisions + 1));
  1094. indices.push(col + 1 + row * (options.subdivisions + 1));
  1095. indices.push(col + row * (options.subdivisions + 1));
  1096. indices.push(col + (row + 1) * (options.subdivisions + 1));
  1097. indices.push(col + 1 + (row + 1) * (options.subdivisions + 1));
  1098. indices.push(col + row * (options.subdivisions + 1));
  1099. }
  1100. }
  1101. // Normals
  1102. VertexData.ComputeNormals(positions, indices, normals);
  1103. // Result
  1104. var vertexData = new VertexData();
  1105. vertexData.indices = indices;
  1106. vertexData.positions = positions;
  1107. vertexData.normals = normals;
  1108. vertexData.uvs = uvs;
  1109. return vertexData;
  1110. };
  1111. VertexData.CreatePlane = function (options) {
  1112. var indices = [];
  1113. var positions = [];
  1114. var normals = [];
  1115. var uvs = [];
  1116. var width = options.width || options.size || 1;
  1117. var height = options.height || options.size || 1;
  1118. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1119. // Vertices
  1120. var halfWidth = width / 2.0;
  1121. var halfHeight = height / 2.0;
  1122. positions.push(-halfWidth, -halfHeight, 0);
  1123. normals.push(0, 0, -1.0);
  1124. uvs.push(0.0, 0.0);
  1125. positions.push(halfWidth, -halfHeight, 0);
  1126. normals.push(0, 0, -1.0);
  1127. uvs.push(1.0, 0.0);
  1128. positions.push(halfWidth, halfHeight, 0);
  1129. normals.push(0, 0, -1.0);
  1130. uvs.push(1.0, 1.0);
  1131. positions.push(-halfWidth, halfHeight, 0);
  1132. normals.push(0, 0, -1.0);
  1133. uvs.push(0.0, 1.0);
  1134. // Indices
  1135. indices.push(0);
  1136. indices.push(1);
  1137. indices.push(2);
  1138. indices.push(0);
  1139. indices.push(2);
  1140. indices.push(3);
  1141. // Sides
  1142. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  1143. // Result
  1144. var vertexData = new VertexData();
  1145. vertexData.indices = indices;
  1146. vertexData.positions = positions;
  1147. vertexData.normals = normals;
  1148. vertexData.uvs = uvs;
  1149. return vertexData;
  1150. };
  1151. VertexData.CreateDisc = function (options) {
  1152. var positions = [];
  1153. var indices = [];
  1154. var normals = [];
  1155. var uvs = [];
  1156. var radius = options.radius || 0.5;
  1157. var tessellation = options.tessellation || 64;
  1158. var arc = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
  1159. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1160. // positions and uvs
  1161. positions.push(0, 0, 0); // disc center first
  1162. uvs.push(0.5, 0.5);
  1163. var theta = Math.PI * 2 * arc;
  1164. var step = theta / tessellation;
  1165. for (var a = 0; a < theta; a += step) {
  1166. var x = Math.cos(a);
  1167. var y = Math.sin(a);
  1168. var u = (x + 1) / 2;
  1169. var v = (1 - y) / 2;
  1170. positions.push(radius * x, radius * y, 0);
  1171. uvs.push(u, v);
  1172. }
  1173. if (arc === 1) {
  1174. positions.push(positions[3], positions[4], positions[5]); // close the circle
  1175. uvs.push(uvs[2], uvs[3]);
  1176. }
  1177. //indices
  1178. var vertexNb = positions.length / 3;
  1179. for (var i = 1; i < vertexNb - 1; i++) {
  1180. indices.push(i + 1, 0, i);
  1181. }
  1182. // result
  1183. VertexData.ComputeNormals(positions, indices, normals);
  1184. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  1185. var vertexData = new VertexData();
  1186. vertexData.indices = indices;
  1187. vertexData.positions = positions;
  1188. vertexData.normals = normals;
  1189. vertexData.uvs = uvs;
  1190. return vertexData;
  1191. };
  1192. VertexData.CreateIcoSphere = function (options) {
  1193. var sideOrientation = options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1194. var radius = options.radius || 1;
  1195. var flat = (options.flat === undefined) ? true : options.flat;
  1196. var subdivisions = options.subdivisions || 4;
  1197. var radiusX = options.radiusX || radius;
  1198. var radiusY = options.radiusY || radius;
  1199. var radiusZ = options.radiusZ || radius;
  1200. var t = (1 + Math.sqrt(5)) / 2;
  1201. // 12 vertex x,y,z
  1202. var ico_vertices = [
  1203. -1, t, -0, 1, t, 0, -1, -t, 0, 1, -t, 0,
  1204. 0, -1, -t, 0, 1, -t, 0, -1, t, 0, 1, t,
  1205. t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, -1 // v8-11
  1206. ];
  1207. // index of 3 vertex makes a face of icopshere
  1208. var ico_indices = [
  1209. 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 12, 22, 23,
  1210. 1, 5, 20, 5, 11, 4, 23, 22, 13, 22, 18, 6, 7, 1, 8,
  1211. 14, 21, 4, 14, 4, 2, 16, 13, 6, 15, 6, 19, 3, 8, 9,
  1212. 4, 21, 5, 13, 17, 23, 6, 13, 22, 19, 6, 18, 9, 8, 1
  1213. ];
  1214. // vertex for uv have aliased position, not for UV
  1215. var vertices_unalias_id = [
  1216. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
  1217. // vertex alias
  1218. 0,
  1219. 2,
  1220. 3,
  1221. 3,
  1222. 3,
  1223. 4,
  1224. 7,
  1225. 8,
  1226. 9,
  1227. 9,
  1228. 10,
  1229. 11 // 23: B + 12
  1230. ];
  1231. // uv as integer step (not pixels !)
  1232. var ico_vertexuv = [
  1233. 5, 1, 3, 1, 6, 4, 0, 0,
  1234. 5, 3, 4, 2, 2, 2, 4, 0,
  1235. 2, 0, 1, 1, 6, 0, 6, 2,
  1236. // vertex alias (for same vertex on different faces)
  1237. 0, 4,
  1238. 3, 3,
  1239. 4, 4,
  1240. 3, 1,
  1241. 4, 2,
  1242. 4, 4,
  1243. 0, 2,
  1244. 1, 1,
  1245. 2, 2,
  1246. 3, 3,
  1247. 1, 3,
  1248. 2, 4 // 23: B + 12
  1249. ];
  1250. // Vertices[0, 1, ...9, A, B] : position on UV plane
  1251. // '+' indicate duplicate position to be fixed (3,9:0,2,3,4,7,8,A,B)
  1252. // First island of uv mapping
  1253. // v = 4h 3+ 2
  1254. // v = 3h 9+ 4
  1255. // v = 2h 9+ 5 B
  1256. // v = 1h 9 1 0
  1257. // v = 0h 3 8 7 A
  1258. // u = 0 1 2 3 4 5 6 *a
  1259. // Second island of uv mapping
  1260. // v = 4h 0+ B+ 4+
  1261. // v = 3h A+ 2+
  1262. // v = 2h 7+ 6 3+
  1263. // v = 1h 8+ 3+
  1264. // v = 0h
  1265. // u = 0 1 2 3 4 5 6 *a
  1266. // Face layout on texture UV mapping
  1267. // ============
  1268. // \ 4 /\ 16 / ======
  1269. // \ / \ / /\ 11 /
  1270. // \/ 7 \/ / \ /
  1271. // ======= / 10 \/
  1272. // /\ 17 /\ =======
  1273. // / \ / \ \ 15 /\
  1274. // / 8 \/ 12 \ \ / \
  1275. // ============ \/ 6 \
  1276. // \ 18 /\ ============
  1277. // \ / \ \ 5 /\ 0 /
  1278. // \/ 13 \ \ / \ /
  1279. // ======= \/ 1 \/
  1280. // =============
  1281. // /\ 19 /\ 2 /\
  1282. // / \ / \ / \
  1283. // / 14 \/ 9 \/ 3 \
  1284. // ===================
  1285. // uv step is u:1 or 0.5, v:cos(30)=sqrt(3)/2, ratio approx is 84/97
  1286. var ustep = 138 / 1024;
  1287. var vstep = 239 / 1024;
  1288. var uoffset = 60 / 1024;
  1289. var voffset = 26 / 1024;
  1290. // Second island should have margin, not to touch the first island
  1291. // avoid any borderline artefact in pixel rounding
  1292. var island_u_offset = -40 / 1024;
  1293. var island_v_offset = +20 / 1024;
  1294. // face is either island 0 or 1 :
  1295. // second island is for faces : [4, 7, 8, 12, 13, 16, 17, 18]
  1296. var island = [
  1297. 0, 0, 0, 0, 1,
  1298. 0, 0, 1, 1, 0,
  1299. 0, 0, 1, 1, 0,
  1300. 0, 1, 1, 1, 0,
  1301. ];
  1302. var indices = [];
  1303. var positions = [];
  1304. var normals = [];
  1305. var uvs = [];
  1306. var current_indice = 0;
  1307. // prepare array of 3 vector (empty) (to be worked in place, shared for each face)
  1308. var face_vertex_pos = new Array(3);
  1309. var face_vertex_uv = new Array(3);
  1310. for (var v012 = 0; v012 < 3; v012++) {
  1311. face_vertex_pos[v012] = BABYLON.Vector3.Zero();
  1312. face_vertex_uv[v012] = BABYLON.Vector2.Zero();
  1313. }
  1314. // create all with normals
  1315. for (var face = 0; face < 20; face++) {
  1316. // 3 vertex per face
  1317. for (var v012 = 0; v012 < 3; v012++) {
  1318. // look up vertex 0,1,2 to its index in 0 to 11 (or 23 including alias)
  1319. var v_id = ico_indices[3 * face + v012];
  1320. // vertex have 3D position (x,y,z)
  1321. face_vertex_pos[v012].copyFromFloats(ico_vertices[3 * vertices_unalias_id[v_id]], ico_vertices[3 * vertices_unalias_id[v_id] + 1], ico_vertices[3 * vertices_unalias_id[v_id] + 2]);
  1322. // Normalize to get normal, then scale to radius
  1323. face_vertex_pos[v012].normalize().scaleInPlace(radius);
  1324. // uv Coordinates from vertex ID
  1325. face_vertex_uv[v012].copyFromFloats(ico_vertexuv[2 * v_id] * ustep + uoffset + island[face] * island_u_offset, ico_vertexuv[2 * v_id + 1] * vstep + voffset + island[face] * island_v_offset);
  1326. }
  1327. // Subdivide the face (interpolate pos, norm, uv)
  1328. // - pos is linear interpolation, then projected to sphere (converge polyhedron to sphere)
  1329. // - norm is linear interpolation of vertex corner normal
  1330. // (to be checked if better to re-calc from face vertex, or if approximation is OK ??? )
  1331. // - uv is linear interpolation
  1332. //
  1333. // Topology is as below for sub-divide by 2
  1334. // vertex shown as v0,v1,v2
  1335. // interp index is i1 to progress in range [v0,v1[
  1336. // interp index is i2 to progress in range [v0,v2[
  1337. // face index as (i1,i2) for /\ : (i1,i2),(i1+1,i2),(i1,i2+1)
  1338. // and (i1,i2)' for \/ : (i1+1,i2),(i1+1,i2+1),(i1,i2+1)
  1339. //
  1340. //
  1341. // i2 v2
  1342. // ^ ^
  1343. // / / \
  1344. // / / \
  1345. // / / \
  1346. // / / (0,1) \
  1347. // / #---------\
  1348. // / / \ (0,0)'/ \
  1349. // / / \ / \
  1350. // / / \ / \
  1351. // / / (0,0) \ / (1,0) \
  1352. // / #---------#---------\
  1353. // v0 v1
  1354. //
  1355. // --------------------> i1
  1356. //
  1357. // interp of (i1,i2):
  1358. // along i2 : x0=lerp(v0,v2, i2/S) <---> x1=lerp(v1,v2, i2/S)
  1359. // along i1 : lerp(x0,x1, i1/(S-i2))
  1360. //
  1361. // centroid of triangle is needed to get help normal computation
  1362. // (c1,c2) are used for centroid location
  1363. var interp_vertex = function (i1, i2, c1, c2) {
  1364. // vertex is interpolated from
  1365. // - face_vertex_pos[0..2]
  1366. // - face_vertex_uv[0..2]
  1367. var pos_x0 = BABYLON.Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], i2 / subdivisions);
  1368. var pos_x1 = BABYLON.Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], i2 / subdivisions);
  1369. var pos_interp = (subdivisions === i2) ? face_vertex_pos[2] : BABYLON.Vector3.Lerp(pos_x0, pos_x1, i1 / (subdivisions - i2));
  1370. pos_interp.normalize();
  1371. pos_interp.x *= radiusX;
  1372. pos_interp.y *= radiusY;
  1373. pos_interp.z *= radiusZ;
  1374. var vertex_normal;
  1375. if (flat) {
  1376. // in flat mode, recalculate normal as face centroid normal
  1377. var centroid_x0 = BABYLON.Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], c2 / subdivisions);
  1378. var centroid_x1 = BABYLON.Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], c2 / subdivisions);
  1379. var centroid_interp = BABYLON.Vector3.Lerp(centroid_x0, centroid_x1, c1 / (subdivisions - c2));
  1380. vertex_normal = BABYLON.Vector3.Normalize(centroid_interp);
  1381. }
  1382. else {
  1383. // in smooth mode, recalculate normal from each single vertex position
  1384. vertex_normal = BABYLON.Vector3.Normalize(pos_interp);
  1385. }
  1386. var uv_x0 = BABYLON.Vector2.Lerp(face_vertex_uv[0], face_vertex_uv[2], i2 / subdivisions);
  1387. var uv_x1 = BABYLON.Vector2.Lerp(face_vertex_uv[1], face_vertex_uv[2], i2 / subdivisions);
  1388. var uv_interp = (subdivisions === i2) ? face_vertex_uv[2] : BABYLON.Vector2.Lerp(uv_x0, uv_x1, i1 / (subdivisions - i2));
  1389. positions.push(pos_interp.x, pos_interp.y, pos_interp.z);
  1390. normals.push(vertex_normal.x, vertex_normal.y, vertex_normal.z);
  1391. uvs.push(uv_interp.x, uv_interp.y);
  1392. // push each vertex has member of a face
  1393. // Same vertex can bleong to multiple face, it is pushed multiple time (duplicate vertex are present)
  1394. indices.push(current_indice);
  1395. current_indice++;
  1396. };
  1397. for (var i2 = 0; i2 < subdivisions; i2++) {
  1398. for (var i1 = 0; i1 + i2 < subdivisions; i1++) {
  1399. // face : (i1,i2) for /\ :
  1400. // interp for : (i1,i2),(i1+1,i2),(i1,i2+1)
  1401. interp_vertex(i1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);
  1402. interp_vertex(i1 + 1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);
  1403. interp_vertex(i1, i2 + 1, i1 + 1.0 / 3, i2 + 1.0 / 3);
  1404. if (i1 + i2 + 1 < subdivisions) {
  1405. // face : (i1,i2)' for \/ :
  1406. // interp for (i1+1,i2),(i1+1,i2+1),(i1,i2+1)
  1407. interp_vertex(i1 + 1, i2, i1 + 2.0 / 3, i2 + 2.0 / 3);
  1408. interp_vertex(i1 + 1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);
  1409. interp_vertex(i1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);
  1410. }
  1411. }
  1412. }
  1413. }
  1414. // Sides
  1415. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  1416. // Result
  1417. var vertexData = new VertexData();
  1418. vertexData.indices = indices;
  1419. vertexData.positions = positions;
  1420. vertexData.normals = normals;
  1421. vertexData.uvs = uvs;
  1422. return vertexData;
  1423. };
  1424. // inspired from // http://stemkoski.github.io/Three.js/Polyhedra.html
  1425. VertexData.CreatePolyhedron = function (options) {
  1426. // provided polyhedron types :
  1427. // 0 : Tetrahedron, 1 : Octahedron, 2 : Dodecahedron, 3 : Icosahedron, 4 : Rhombicuboctahedron, 5 : Triangular Prism, 6 : Pentagonal Prism, 7 : Hexagonal Prism, 8 : Square Pyramid (J1)
  1428. // 9 : Pentagonal Pyramid (J2), 10 : Triangular Dipyramid (J12), 11 : Pentagonal Dipyramid (J13), 12 : Elongated Square Dipyramid (J15), 13 : Elongated Pentagonal Dipyramid (J16), 14 : Elongated Pentagonal Cupola (J20)
  1429. var polyhedra = [];
  1430. polyhedra[0] = { vertex: [[0, 0, 1.732051], [1.632993, 0, -0.5773503], [-0.8164966, 1.414214, -0.5773503], [-0.8164966, -1.414214, -0.5773503]], face: [[0, 1, 2], [0, 2, 3], [0, 3, 1], [1, 3, 2]] };
  1431. polyhedra[1] = { vertex: [[0, 0, 1.414214], [1.414214, 0, 0], [0, 1.414214, 0], [-1.414214, 0, 0], [0, -1.414214, 0], [0, 0, -1.414214]], face: [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [3, 5, 4]] };
  1432. polyhedra[2] = {
  1433. vertex: [[0, 0, 1.070466], [0.7136442, 0, 0.7978784], [-0.3568221, 0.618034, 0.7978784], [-0.3568221, -0.618034, 0.7978784], [0.7978784, 0.618034, 0.3568221], [0.7978784, -0.618034, 0.3568221], [-0.9341724, 0.381966, 0.3568221], [0.1362939, 1, 0.3568221], [0.1362939, -1, 0.3568221], [-0.9341724, -0.381966, 0.3568221], [0.9341724, 0.381966, -0.3568221], [0.9341724, -0.381966, -0.3568221], [-0.7978784, 0.618034, -0.3568221], [-0.1362939, 1, -0.3568221], [-0.1362939, -1, -0.3568221], [-0.7978784, -0.618034, -0.3568221], [0.3568221, 0.618034, -0.7978784], [0.3568221, -0.618034, -0.7978784], [-0.7136442, 0, -0.7978784], [0, 0, -1.070466]],
  1434. face: [[0, 1, 4, 7, 2], [0, 2, 6, 9, 3], [0, 3, 8, 5, 1], [1, 5, 11, 10, 4], [2, 7, 13, 12, 6], [3, 9, 15, 14, 8], [4, 10, 16, 13, 7], [5, 8, 14, 17, 11], [6, 12, 18, 15, 9], [10, 11, 17, 19, 16], [12, 13, 16, 19, 18], [14, 15, 18, 19, 17]]
  1435. };
  1436. polyhedra[3] = {
  1437. vertex: [[0, 0, 1.175571], [1.051462, 0, 0.5257311], [0.3249197, 1, 0.5257311], [-0.8506508, 0.618034, 0.5257311], [-0.8506508, -0.618034, 0.5257311], [0.3249197, -1, 0.5257311], [0.8506508, 0.618034, -0.5257311], [0.8506508, -0.618034, -0.5257311], [-0.3249197, 1, -0.5257311], [-1.051462, 0, -0.5257311], [-0.3249197, -1, -0.5257311], [0, 0, -1.175571]],
  1438. face: [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1], [1, 5, 7], [1, 7, 6], [1, 6, 2], [2, 6, 8], [2, 8, 3], [3, 8, 9], [3, 9, 4], [4, 9, 10], [4, 10, 5], [5, 10, 7], [6, 7, 11], [6, 11, 8], [7, 10, 11], [8, 11, 9], [9, 11, 10]]
  1439. };
  1440. polyhedra[4] = {
  1441. vertex: [[0, 0, 1.070722], [0.7148135, 0, 0.7971752], [-0.104682, 0.7071068, 0.7971752], [-0.6841528, 0.2071068, 0.7971752], [-0.104682, -0.7071068, 0.7971752], [0.6101315, 0.7071068, 0.5236279], [1.04156, 0.2071068, 0.1367736], [0.6101315, -0.7071068, 0.5236279], [-0.3574067, 1, 0.1367736], [-0.7888348, -0.5, 0.5236279], [-0.9368776, 0.5, 0.1367736], [-0.3574067, -1, 0.1367736], [0.3574067, 1, -0.1367736], [0.9368776, -0.5, -0.1367736], [0.7888348, 0.5, -0.5236279], [0.3574067, -1, -0.1367736], [-0.6101315, 0.7071068, -0.5236279], [-1.04156, -0.2071068, -0.1367736], [-0.6101315, -0.7071068, -0.5236279], [0.104682, 0.7071068, -0.7971752], [0.6841528, -0.2071068, -0.7971752], [0.104682, -0.7071068, -0.7971752], [-0.7148135, 0, -0.7971752], [0, 0, -1.070722]],
  1442. face: [[0, 2, 3], [1, 6, 5], [4, 9, 11], [7, 15, 13], [8, 16, 10], [12, 14, 19], [17, 22, 18], [20, 21, 23], [0, 1, 5, 2], [0, 3, 9, 4], [0, 4, 7, 1], [1, 7, 13, 6], [2, 5, 12, 8], [2, 8, 10, 3], [3, 10, 17, 9], [4, 11, 15, 7], [5, 6, 14, 12], [6, 13, 20, 14], [8, 12, 19, 16], [9, 17, 18, 11], [10, 16, 22, 17], [11, 18, 21, 15], [13, 15, 21, 20], [14, 20, 23, 19], [16, 19, 23, 22], [18, 22, 23, 21]]
  1443. };
  1444. polyhedra[5] = { vertex: [[0, 0, 1.322876], [1.309307, 0, 0.1889822], [-0.9819805, 0.8660254, 0.1889822], [0.1636634, -1.299038, 0.1889822], [0.3273268, 0.8660254, -0.9449112], [-0.8183171, -0.4330127, -0.9449112]], face: [[0, 3, 1], [2, 4, 5], [0, 1, 4, 2], [0, 2, 5, 3], [1, 3, 5, 4]] };
  1445. polyhedra[6] = { vertex: [[0, 0, 1.159953], [1.013464, 0, 0.5642542], [-0.3501431, 0.9510565, 0.5642542], [-0.7715208, -0.6571639, 0.5642542], [0.6633206, 0.9510565, -0.03144481], [0.8682979, -0.6571639, -0.3996071], [-1.121664, 0.2938926, -0.03144481], [-0.2348831, -1.063314, -0.3996071], [0.5181548, 0.2938926, -0.9953061], [-0.5850262, -0.112257, -0.9953061]], face: [[0, 1, 4, 2], [0, 2, 6, 3], [1, 5, 8, 4], [3, 6, 9, 7], [5, 7, 9, 8], [0, 3, 7, 5, 1], [2, 4, 8, 9, 6]] };
  1446. polyhedra[7] = { vertex: [[0, 0, 1.118034], [0.8944272, 0, 0.6708204], [-0.2236068, 0.8660254, 0.6708204], [-0.7826238, -0.4330127, 0.6708204], [0.6708204, 0.8660254, 0.2236068], [1.006231, -0.4330127, -0.2236068], [-1.006231, 0.4330127, 0.2236068], [-0.6708204, -0.8660254, -0.2236068], [0.7826238, 0.4330127, -0.6708204], [0.2236068, -0.8660254, -0.6708204], [-0.8944272, 0, -0.6708204], [0, 0, -1.118034]], face: [[0, 1, 4, 2], [0, 2, 6, 3], [1, 5, 8, 4], [3, 6, 10, 7], [5, 9, 11, 8], [7, 10, 11, 9], [0, 3, 7, 9, 5, 1], [2, 4, 8, 11, 10, 6]] };
  1447. polyhedra[8] = { vertex: [[-0.729665, 0.670121, 0.319155], [-0.655235, -0.29213, -0.754096], [-0.093922, -0.607123, 0.537818], [0.702196, 0.595691, 0.485187], [0.776626, -0.36656, -0.588064]], face: [[1, 4, 2], [0, 1, 2], [3, 0, 2], [4, 3, 2], [4, 1, 0, 3]] };
  1448. polyhedra[9] = { vertex: [[-0.868849, -0.100041, 0.61257], [-0.329458, 0.976099, 0.28078], [-0.26629, -0.013796, -0.477654], [-0.13392, -1.034115, 0.229829], [0.738834, 0.707117, -0.307018], [0.859683, -0.535264, -0.338508]], face: [[3, 0, 2], [5, 3, 2], [4, 5, 2], [1, 4, 2], [0, 1, 2], [0, 3, 5, 4, 1]] };
  1449. polyhedra[10] = { vertex: [[-0.610389, 0.243975, 0.531213], [-0.187812, -0.48795, -0.664016], [-0.187812, 0.9759, -0.664016], [0.187812, -0.9759, 0.664016], [0.798201, 0.243975, 0.132803]], face: [[1, 3, 0], [3, 4, 0], [3, 1, 4], [0, 2, 1], [0, 4, 2], [2, 4, 1]] };
  1450. polyhedra[11] = { vertex: [[-1.028778, 0.392027, -0.048786], [-0.640503, -0.646161, 0.621837], [-0.125162, -0.395663, -0.540059], [0.004683, 0.888447, -0.651988], [0.125161, 0.395663, 0.540059], [0.632925, -0.791376, 0.433102], [1.031672, 0.157063, -0.354165]], face: [[3, 2, 0], [2, 1, 0], [2, 5, 1], [0, 4, 3], [0, 1, 4], [4, 1, 5], [2, 3, 6], [3, 4, 6], [5, 2, 6], [4, 5, 6]] };
  1451. polyhedra[12] = { vertex: [[-0.669867, 0.334933, -0.529576], [-0.669867, 0.334933, 0.529577], [-0.4043, 1.212901, 0], [-0.334933, -0.669867, -0.529576], [-0.334933, -0.669867, 0.529577], [0.334933, 0.669867, -0.529576], [0.334933, 0.669867, 0.529577], [0.4043, -1.212901, 0], [0.669867, -0.334933, -0.529576], [0.669867, -0.334933, 0.529577]], face: [[8, 9, 7], [6, 5, 2], [3, 8, 7], [5, 0, 2], [4, 3, 7], [0, 1, 2], [9, 4, 7], [1, 6, 2], [9, 8, 5, 6], [8, 3, 0, 5], [3, 4, 1, 0], [4, 9, 6, 1]] };
  1452. polyhedra[13] = { vertex: [[-0.931836, 0.219976, -0.264632], [-0.636706, 0.318353, 0.692816], [-0.613483, -0.735083, -0.264632], [-0.326545, 0.979634, 0], [-0.318353, -0.636706, 0.692816], [-0.159176, 0.477529, -0.856368], [0.159176, -0.477529, -0.856368], [0.318353, 0.636706, 0.692816], [0.326545, -0.979634, 0], [0.613482, 0.735082, -0.264632], [0.636706, -0.318353, 0.692816], [0.931835, -0.219977, -0.264632]], face: [[11, 10, 8], [7, 9, 3], [6, 11, 8], [9, 5, 3], [2, 6, 8], [5, 0, 3], [4, 2, 8], [0, 1, 3], [10, 4, 8], [1, 7, 3], [10, 11, 9, 7], [11, 6, 5, 9], [6, 2, 0, 5], [2, 4, 1, 0], [4, 10, 7, 1]] };
  1453. polyhedra[14] = {
  1454. vertex: [[-0.93465, 0.300459, -0.271185], [-0.838689, -0.260219, -0.516017], [-0.711319, 0.717591, 0.128359], [-0.710334, -0.156922, 0.080946], [-0.599799, 0.556003, -0.725148], [-0.503838, -0.004675, -0.969981], [-0.487004, 0.26021, 0.48049], [-0.460089, -0.750282, -0.512622], [-0.376468, 0.973135, -0.325605], [-0.331735, -0.646985, 0.084342], [-0.254001, 0.831847, 0.530001], [-0.125239, -0.494738, -0.966586], [0.029622, 0.027949, 0.730817], [0.056536, -0.982543, -0.262295], [0.08085, 1.087391, 0.076037], [0.125583, -0.532729, 0.485984], [0.262625, 0.599586, 0.780328], [0.391387, -0.726999, -0.716259], [0.513854, -0.868287, 0.139347], [0.597475, 0.85513, 0.326364], [0.641224, 0.109523, 0.783723], [0.737185, -0.451155, 0.538891], [0.848705, -0.612742, -0.314616], [0.976075, 0.365067, 0.32976], [1.072036, -0.19561, 0.084927]],
  1455. face: [[15, 18, 21], [12, 20, 16], [6, 10, 2], [3, 0, 1], [9, 7, 13], [2, 8, 4, 0], [0, 4, 5, 1], [1, 5, 11, 7], [7, 11, 17, 13], [13, 17, 22, 18], [18, 22, 24, 21], [21, 24, 23, 20], [20, 23, 19, 16], [16, 19, 14, 10], [10, 14, 8, 2], [15, 9, 13, 18], [12, 15, 21, 20], [6, 12, 16, 10], [3, 6, 2, 0], [9, 3, 1, 7], [9, 15, 12, 6, 3], [22, 17, 11, 5, 4, 8, 14, 19, 23, 24]]
  1456. };
  1457. var type = (options.type < 0 || options.type >= polyhedra.length) ? 0 : options.type || 0;
  1458. var size = options.size;
  1459. var sizeX = options.sizeX || size || 1;
  1460. var sizeY = options.sizeY || size || 1;
  1461. var sizeZ = options.sizeZ || size || 1;
  1462. var data = options.custom || polyhedra[type];
  1463. var nbfaces = data.face.length;
  1464. var faceUV = options.faceUV || new Array(nbfaces);
  1465. var faceColors = options.faceColors;
  1466. var flat = (options.flat === undefined) ? true : options.flat;
  1467. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1468. var positions = [];
  1469. var indices = [];
  1470. var normals = [];
  1471. var uvs = [];
  1472. var colors = [];
  1473. var index = 0;
  1474. var faceIdx = 0; // face cursor in the array "indexes"
  1475. var indexes = [];
  1476. var i = 0;
  1477. var f = 0;
  1478. var u, v, ang, x, y, tmp;
  1479. // default face colors and UV if undefined
  1480. if (flat) {
  1481. for (f = 0; f < nbfaces; f++) {
  1482. if (faceColors && faceColors[f] === undefined) {
  1483. faceColors[f] = new BABYLON.Color4(1, 1, 1, 1);
  1484. }
  1485. if (faceUV && faceUV[f] === undefined) {
  1486. faceUV[f] = new BABYLON.Vector4(0, 0, 1, 1);
  1487. }
  1488. }
  1489. }
  1490. if (!flat) {
  1491. for (i = 0; i < data.vertex.length; i++) {
  1492. positions.push(data.vertex[i][0] * sizeX, data.vertex[i][1] * sizeY, data.vertex[i][2] * sizeZ);
  1493. uvs.push(0, 0);
  1494. }
  1495. for (f = 0; f < nbfaces; f++) {
  1496. for (i = 0; i < data.face[f].length - 2; i++) {
  1497. indices.push(data.face[f][0], data.face[f][i + 2], data.face[f][i + 1]);
  1498. }
  1499. }
  1500. }
  1501. else {
  1502. for (f = 0; f < nbfaces; f++) {
  1503. var fl = data.face[f].length; // number of vertices of the current face
  1504. ang = 2 * Math.PI / fl;
  1505. x = 0.5 * Math.tan(ang / 2);
  1506. y = 0.5;
  1507. // positions, uvs, colors
  1508. for (i = 0; i < fl; i++) {
  1509. // positions
  1510. positions.push(data.vertex[data.face[f][i]][0] * sizeX, data.vertex[data.face[f][i]][1] * sizeY, data.vertex[data.face[f][i]][2] * sizeZ);
  1511. indexes.push(index);
  1512. index++;
  1513. // uvs
  1514. u = faceUV[f].x + (faceUV[f].z - faceUV[f].x) * (0.5 + x);
  1515. v = faceUV[f].y + (faceUV[f].w - faceUV[f].y) * (y - 0.5);
  1516. uvs.push(u, v);
  1517. tmp = x * Math.cos(ang) - y * Math.sin(ang);
  1518. y = x * Math.sin(ang) + y * Math.cos(ang);
  1519. x = tmp;
  1520. // colors
  1521. if (faceColors) {
  1522. colors.push(faceColors[f].r, faceColors[f].g, faceColors[f].b, faceColors[f].a);
  1523. }
  1524. }
  1525. // indices from indexes
  1526. for (i = 0; i < fl - 2; i++) {
  1527. indices.push(indexes[0 + faceIdx], indexes[i + 2 + faceIdx], indexes[i + 1 + faceIdx]);
  1528. }
  1529. faceIdx += fl;
  1530. }
  1531. }
  1532. VertexData.ComputeNormals(positions, indices, normals);
  1533. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  1534. var vertexData = new VertexData();
  1535. vertexData.positions = positions;
  1536. vertexData.indices = indices;
  1537. vertexData.normals = normals;
  1538. vertexData.uvs = uvs;
  1539. if (faceColors && flat) {
  1540. vertexData.colors = colors;
  1541. }
  1542. return vertexData;
  1543. };
  1544. // based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
  1545. VertexData.CreateTorusKnot = function (options) {
  1546. var indices = [];
  1547. var positions = [];
  1548. var normals = [];
  1549. var uvs = [];
  1550. var radius = options.radius || 2;
  1551. var tube = options.tube || 0.5;
  1552. var radialSegments = options.radialSegments || 32;
  1553. var tubularSegments = options.tubularSegments || 32;
  1554. var p = options.p || 2;
  1555. var q = options.q || 3;
  1556. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1557. // Helper
  1558. var getPos = function (angle) {
  1559. var cu = Math.cos(angle);
  1560. var su = Math.sin(angle);
  1561. var quOverP = q / p * angle;
  1562. var cs = Math.cos(quOverP);
  1563. var tx = radius * (2 + cs) * 0.5 * cu;
  1564. var ty = radius * (2 + cs) * su * 0.5;
  1565. var tz = radius * Math.sin(quOverP) * 0.5;
  1566. return new BABYLON.Vector3(tx, ty, tz);
  1567. };
  1568. // Vertices
  1569. var i;
  1570. var j;
  1571. for (i = 0; i <= radialSegments; i++) {
  1572. var modI = i % radialSegments;
  1573. var u = modI / radialSegments * 2 * p * Math.PI;
  1574. var p1 = getPos(u);
  1575. var p2 = getPos(u + 0.01);
  1576. var tang = p2.subtract(p1);
  1577. var n = p2.add(p1);
  1578. var bitan = BABYLON.Vector3.Cross(tang, n);
  1579. n = BABYLON.Vector3.Cross(bitan, tang);
  1580. bitan.normalize();
  1581. n.normalize();
  1582. for (j = 0; j < tubularSegments; j++) {
  1583. var modJ = j % tubularSegments;
  1584. var v = modJ / tubularSegments * 2 * Math.PI;
  1585. var cx = -tube * Math.cos(v);
  1586. var cy = tube * Math.sin(v);
  1587. positions.push(p1.x + cx * n.x + cy * bitan.x);
  1588. positions.push(p1.y + cx * n.y + cy * bitan.y);
  1589. positions.push(p1.z + cx * n.z + cy * bitan.z);
  1590. uvs.push(i / radialSegments);
  1591. uvs.push(j / tubularSegments);
  1592. }
  1593. }
  1594. for (i = 0; i < radialSegments; i++) {
  1595. for (j = 0; j < tubularSegments; j++) {
  1596. var jNext = (j + 1) % tubularSegments;
  1597. var a = i * tubularSegments + j;
  1598. var b = (i + 1) * tubularSegments + j;
  1599. var c = (i + 1) * tubularSegments + jNext;
  1600. var d = i * tubularSegments + jNext;
  1601. indices.push(d);
  1602. indices.push(b);
  1603. indices.push(a);
  1604. indices.push(d);
  1605. indices.push(c);
  1606. indices.push(b);
  1607. }
  1608. }
  1609. // Normals
  1610. VertexData.ComputeNormals(positions, indices, normals);
  1611. // Sides
  1612. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  1613. // Result
  1614. var vertexData = new VertexData();
  1615. vertexData.indices = indices;
  1616. vertexData.positions = positions;
  1617. vertexData.normals = normals;
  1618. vertexData.uvs = uvs;
  1619. return vertexData;
  1620. };
  1621. // Tools
  1622. /**
  1623. * @param {any} - positions (number[] or Float32Array)
  1624. * @param {any} - indices (number[] or Uint16Array)
  1625. * @param {any} - normals (number[] or Float32Array)
  1626. */
  1627. VertexData.ComputeNormals = function (positions, indices, normals) {
  1628. var index = 0;
  1629. var p1p2x = 0.0;
  1630. var p1p2y = 0.0;
  1631. var p1p2z = 0.0;
  1632. var p3p2x = 0.0;
  1633. var p3p2y = 0.0;
  1634. var p3p2z = 0.0;
  1635. var faceNormalx = 0.0;
  1636. var faceNormaly = 0.0;
  1637. var faceNormalz = 0.0;
  1638. var length = 0.0;
  1639. var i1 = 0;
  1640. var i2 = 0;
  1641. var i3 = 0;
  1642. for (index = 0; index < positions.length; index++) {
  1643. normals[index] = 0.0;
  1644. }
  1645. // indice triplet = 1 face
  1646. var nbFaces = indices.length / 3;
  1647. for (index = 0; index < nbFaces; index++) {
  1648. i1 = indices[index * 3]; // get the indexes of each vertex of the face
  1649. i2 = indices[index * 3 + 1];
  1650. i3 = indices[index * 3 + 2];
  1651. p1p2x = positions[i1 * 3] - positions[i2 * 3]; // compute two vectors per face
  1652. p1p2y = positions[i1 * 3 + 1] - positions[i2 * 3 + 1];
  1653. p1p2z = positions[i1 * 3 + 2] - positions[i2 * 3 + 2];
  1654. p3p2x = positions[i3 * 3] - positions[i2 * 3];
  1655. p3p2y = positions[i3 * 3 + 1] - positions[i2 * 3 + 1];
  1656. p3p2z = positions[i3 * 3 + 2] - positions[i2 * 3 + 2];
  1657. faceNormalx = p1p2y * p3p2z - p1p2z * p3p2y; // compute the face normal with cross product
  1658. faceNormaly = p1p2z * p3p2x - p1p2x * p3p2z;
  1659. faceNormalz = p1p2x * p3p2y - p1p2y * p3p2x;
  1660. length = Math.sqrt(faceNormalx * faceNormalx + faceNormaly * faceNormaly + faceNormalz * faceNormalz);
  1661. length = (length === 0) ? 1.0 : length;
  1662. faceNormalx /= length; // normalize this normal
  1663. faceNormaly /= length;
  1664. faceNormalz /= length;
  1665. normals[i1 * 3] += faceNormalx; // accumulate all the normals per face
  1666. normals[i1 * 3 + 1] += faceNormaly;
  1667. normals[i1 * 3 + 2] += faceNormalz;
  1668. normals[i2 * 3] += faceNormalx;
  1669. normals[i2 * 3 + 1] += faceNormaly;
  1670. normals[i2 * 3 + 2] += faceNormalz;
  1671. normals[i3 * 3] += faceNormalx;
  1672. normals[i3 * 3 + 1] += faceNormaly;
  1673. normals[i3 * 3 + 2] += faceNormalz;
  1674. }
  1675. // last normalization of each normal
  1676. for (index = 0; index < normals.length / 3; index++) {
  1677. faceNormalx = normals[index * 3];
  1678. faceNormaly = normals[index * 3 + 1];
  1679. faceNormalz = normals[index * 3 + 2];
  1680. length = Math.sqrt(faceNormalx * faceNormalx + faceNormaly * faceNormaly + faceNormalz * faceNormalz);
  1681. length = (length === 0) ? 1.0 : length;
  1682. faceNormalx /= length;
  1683. faceNormaly /= length;
  1684. faceNormalz /= length;
  1685. normals[index * 3] = faceNormalx;
  1686. normals[index * 3 + 1] = faceNormaly;
  1687. normals[index * 3 + 2] = faceNormalz;
  1688. }
  1689. };
  1690. VertexData._ComputeSides = function (sideOrientation, positions, indices, normals, uvs) {
  1691. var li = indices.length;
  1692. var ln = normals.length;
  1693. var i;
  1694. var n;
  1695. sideOrientation = sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1696. switch (sideOrientation) {
  1697. case BABYLON.Mesh.FRONTSIDE:
  1698. // nothing changed
  1699. break;
  1700. case BABYLON.Mesh.BACKSIDE:
  1701. var tmp;
  1702. // indices
  1703. for (i = 0; i < li; i += 3) {
  1704. tmp = indices[i];
  1705. indices[i] = indices[i + 2];
  1706. indices[i + 2] = tmp;
  1707. }
  1708. // normals
  1709. for (n = 0; n < ln; n++) {
  1710. normals[n] = -normals[n];
  1711. }
  1712. break;
  1713. case BABYLON.Mesh.DOUBLESIDE:
  1714. // positions
  1715. var lp = positions.length;
  1716. var l = lp / 3;
  1717. for (var p = 0; p < lp; p++) {
  1718. positions[lp + p] = positions[p];
  1719. }
  1720. // indices
  1721. for (i = 0; i < li; i += 3) {
  1722. indices[i + li] = indices[i + 2] + l;
  1723. indices[i + 1 + li] = indices[i + 1] + l;
  1724. indices[i + 2 + li] = indices[i] + l;
  1725. }
  1726. // normals
  1727. for (n = 0; n < ln; n++) {
  1728. normals[ln + n] = -normals[n];
  1729. }
  1730. // uvs
  1731. var lu = uvs.length;
  1732. for (var u = 0; u < lu; u++) {
  1733. uvs[u + lu] = uvs[u];
  1734. }
  1735. break;
  1736. }
  1737. };
  1738. return VertexData;
  1739. })();
  1740. BABYLON.VertexData = VertexData;
  1741. })(BABYLON || (BABYLON = {}));