babylon.mesh.vertexData.js 90 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747
  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. var c = 1;
  708. for (i = 0; i <= subdivisions; i++) {
  709. h = i / subdivisions;
  710. radius = (h * (diameterTop - diameterBottom) + diameterBottom) / 2;
  711. ringIdx = (hasRings && i !== 0 && i !== subdivisions) ? 2 : 1;
  712. for (r = 0; r < ringIdx; r++) {
  713. if (hasRings) {
  714. c += r;
  715. }
  716. if (enclose) {
  717. c += 2 * r;
  718. }
  719. for (j = 0; j <= tessellation; j++) {
  720. angle = j * angle_step;
  721. // position
  722. ringVertex.x = Math.cos(-angle) * radius;
  723. ringVertex.y = -height / 2 + h * height;
  724. ringVertex.z = Math.sin(-angle) * radius;
  725. // normal
  726. if (diameterTop === 0 && i === subdivisions) {
  727. // if no top cap, reuse former normals
  728. ringNormal.x = normals[normals.length - (tessellation + 1) * 3];
  729. ringNormal.y = normals[normals.length - (tessellation + 1) * 3 + 1];
  730. ringNormal.z = normals[normals.length - (tessellation + 1) * 3 + 2];
  731. }
  732. else {
  733. ringNormal.x = ringVertex.x;
  734. ringNormal.z = ringVertex.z;
  735. ringNormal.y = Math.sqrt(ringNormal.x * ringNormal.x + ringNormal.z * ringNormal.z) * tan;
  736. ringNormal.normalize();
  737. }
  738. // keep first ring vertex values for enclose
  739. if (j === 0) {
  740. ringFirstVertex.copyFrom(ringVertex);
  741. ringFirstNormal.copyFrom(ringNormal);
  742. }
  743. positions.push(ringVertex.x, ringVertex.y, ringVertex.z);
  744. normals.push(ringNormal.x, ringNormal.y, ringNormal.z);
  745. uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x) * j / tessellation, faceUV[1].y + (faceUV[1].w - faceUV[1].y) * h);
  746. if (faceColors) {
  747. colors.push(faceColors[c].r, faceColors[c].g, faceColors[c].b, faceColors[c].a);
  748. }
  749. }
  750. // if enclose, add four vertices and their dedicated normals
  751. if (arc !== 1 && enclose) {
  752. positions.push(ringVertex.x, ringVertex.y, ringVertex.z);
  753. positions.push(0, ringVertex.y, 0);
  754. positions.push(0, ringVertex.y, 0);
  755. positions.push(ringFirstVertex.x, ringFirstVertex.y, ringFirstVertex.z);
  756. BABYLON.Vector3.CrossToRef(Y, ringNormal, quadNormal);
  757. quadNormal.normalize();
  758. normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);
  759. BABYLON.Vector3.CrossToRef(ringFirstNormal, Y, quadNormal);
  760. quadNormal.normalize();
  761. normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);
  762. uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
  763. uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
  764. uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
  765. uvs.push(faceUV[1].x + (faceUV[1].z - faceUV[1].x), faceUV[1].y + (faceUV[1].w - faceUV[1].y));
  766. colors.push(faceColors[c + 1].r, faceColors[c + 1].g, faceColors[c + 1].b, faceColors[c + 1].a);
  767. colors.push(faceColors[c + 1].r, faceColors[c + 1].g, faceColors[c + 1].b, faceColors[c + 1].a);
  768. colors.push(faceColors[c + 2].r, faceColors[c + 2].g, faceColors[c + 2].b, faceColors[c + 2].a);
  769. colors.push(faceColors[c + 2].r, faceColors[c + 2].g, faceColors[c + 2].b, faceColors[c + 2].a);
  770. }
  771. }
  772. }
  773. // indices
  774. var e = (arc !== 1 && enclose) ? tessellation + 4 : tessellation; // correction of number of iteration if enclose
  775. var s;
  776. i = 0;
  777. for (s = 0; s < subdivisions; s++) {
  778. for (j = 0; j < tessellation; j++) {
  779. var i0 = i * (e + 1) + j;
  780. var i1 = (i + 1) * (e + 1) + j;
  781. var i2 = i * (e + 1) + (j + 1);
  782. var i3 = (i + 1) * (e + 1) + (j + 1);
  783. indices.push(i0, i1, i2);
  784. indices.push(i3, i2, i1);
  785. }
  786. if (arc !== 1 && enclose) {
  787. indices.push(i0 + 2, i1 + 2, i2 + 2);
  788. indices.push(i3 + 2, i2 + 2, i1 + 2);
  789. indices.push(i0 + 4, i1 + 4, i2 + 4);
  790. indices.push(i3 + 4, i2 + 4, i1 + 4);
  791. }
  792. i = (hasRings) ? (i + 2) : (i + 1);
  793. }
  794. // Caps
  795. var createCylinderCap = function (isTop) {
  796. var radius = isTop ? diameterTop / 2 : diameterBottom / 2;
  797. if (radius === 0) {
  798. return;
  799. }
  800. // Cap positions, normals & uvs
  801. var angle;
  802. var circleVector;
  803. var i;
  804. var u = (isTop) ? faceUV[2] : faceUV[0];
  805. var c;
  806. if (faceColors) {
  807. c = (isTop) ? faceColors[colorNb - 1] : faceColors[0];
  808. }
  809. // cap center
  810. var vbase = positions.length / 3;
  811. var offset = isTop ? height / 2 : -height / 2;
  812. var center = new BABYLON.Vector3(0, offset, 0);
  813. positions.push(center.x, center.y, center.z);
  814. normals.push(0, isTop ? 1 : -1, 0);
  815. uvs.push(u.x + (u.z - u.x) * 0.5, u.y + (u.w - u.y) * 0.5);
  816. if (faceColors) {
  817. colors.push(c.r, c.g, c.b, c.a);
  818. }
  819. var textureScale = new BABYLON.Vector2(0.5, 0.5);
  820. for (i = 0; i <= tessellation; i++) {
  821. angle = Math.PI * 2 * i * arc / tessellation;
  822. var cos = Math.cos(-angle);
  823. var sin = Math.sin(-angle);
  824. circleVector = new BABYLON.Vector3(cos * radius, offset, sin * radius);
  825. var textureCoordinate = new BABYLON.Vector2(cos * textureScale.x + 0.5, sin * textureScale.y + 0.5);
  826. positions.push(circleVector.x, circleVector.y, circleVector.z);
  827. normals.push(0, isTop ? 1 : -1, 0);
  828. uvs.push(u.x + (u.z - u.x) * textureCoordinate.x, u.y + (u.w - u.y) * textureCoordinate.y);
  829. if (faceColors) {
  830. colors.push(c.r, c.g, c.b, c.a);
  831. }
  832. }
  833. // Cap indices
  834. for (i = 0; i < tessellation; i++) {
  835. if (!isTop) {
  836. indices.push(vbase);
  837. indices.push(vbase + (i + 1));
  838. indices.push(vbase + (i + 2));
  839. }
  840. else {
  841. indices.push(vbase);
  842. indices.push(vbase + (i + 2));
  843. indices.push(vbase + (i + 1));
  844. }
  845. }
  846. };
  847. // add caps to geometry
  848. createCylinderCap(false);
  849. createCylinderCap(true);
  850. // Sides
  851. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  852. var vertexData = new VertexData();
  853. vertexData.indices = indices;
  854. vertexData.positions = positions;
  855. vertexData.normals = normals;
  856. vertexData.uvs = uvs;
  857. if (faceColors) {
  858. vertexData.colors = colors;
  859. }
  860. return vertexData;
  861. };
  862. VertexData.CreateTorus = function (options) {
  863. var indices = [];
  864. var positions = [];
  865. var normals = [];
  866. var uvs = [];
  867. var diameter = options.diameter || 1;
  868. var thickness = options.thickness || 0.5;
  869. var tessellation = options.tessellation || 16;
  870. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  871. var stride = tessellation + 1;
  872. for (var i = 0; i <= tessellation; i++) {
  873. var u = i / tessellation;
  874. var outerAngle = i * Math.PI * 2.0 / tessellation - Math.PI / 2.0;
  875. var transform = BABYLON.Matrix.Translation(diameter / 2.0, 0, 0).multiply(BABYLON.Matrix.RotationY(outerAngle));
  876. for (var j = 0; j <= tessellation; j++) {
  877. var v = 1 - j / tessellation;
  878. var innerAngle = j * Math.PI * 2.0 / tessellation + Math.PI;
  879. var dx = Math.cos(innerAngle);
  880. var dy = Math.sin(innerAngle);
  881. // Create a vertex.
  882. var normal = new BABYLON.Vector3(dx, dy, 0);
  883. var position = normal.scale(thickness / 2);
  884. var textureCoordinate = new BABYLON.Vector2(u, v);
  885. position = BABYLON.Vector3.TransformCoordinates(position, transform);
  886. normal = BABYLON.Vector3.TransformNormal(normal, transform);
  887. positions.push(position.x, position.y, position.z);
  888. normals.push(normal.x, normal.y, normal.z);
  889. uvs.push(textureCoordinate.x, textureCoordinate.y);
  890. // And create indices for two triangles.
  891. var nextI = (i + 1) % stride;
  892. var nextJ = (j + 1) % stride;
  893. indices.push(i * stride + j);
  894. indices.push(i * stride + nextJ);
  895. indices.push(nextI * stride + j);
  896. indices.push(i * stride + nextJ);
  897. indices.push(nextI * stride + nextJ);
  898. indices.push(nextI * stride + j);
  899. }
  900. }
  901. // Sides
  902. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  903. // Result
  904. var vertexData = new VertexData();
  905. vertexData.indices = indices;
  906. vertexData.positions = positions;
  907. vertexData.normals = normals;
  908. vertexData.uvs = uvs;
  909. return vertexData;
  910. };
  911. VertexData.CreateLines = function (options) {
  912. var indices = [];
  913. var positions = [];
  914. var points = options.points;
  915. for (var index = 0; index < points.length; index++) {
  916. positions.push(points[index].x, points[index].y, points[index].z);
  917. if (index > 0) {
  918. indices.push(index - 1);
  919. indices.push(index);
  920. }
  921. }
  922. // Result
  923. var vertexData = new VertexData();
  924. vertexData.indices = indices;
  925. vertexData.positions = positions;
  926. return vertexData;
  927. };
  928. VertexData.CreateDashedLines = function (options) {
  929. var dashSize = options.dashSize || 3;
  930. var gapSize = options.gapSize || 1;
  931. var dashNb = options.dashNb || 200;
  932. var points = options.points;
  933. var positions = new Array();
  934. var indices = new Array();
  935. var curvect = BABYLON.Vector3.Zero();
  936. var lg = 0;
  937. var nb = 0;
  938. var shft = 0;
  939. var dashshft = 0;
  940. var curshft = 0;
  941. var idx = 0;
  942. var i = 0;
  943. for (i = 0; i < points.length - 1; i++) {
  944. points[i + 1].subtractToRef(points[i], curvect);
  945. lg += curvect.length();
  946. }
  947. shft = lg / dashNb;
  948. dashshft = dashSize * shft / (dashSize + gapSize);
  949. for (i = 0; i < points.length - 1; i++) {
  950. points[i + 1].subtractToRef(points[i], curvect);
  951. nb = Math.floor(curvect.length() / shft);
  952. curvect.normalize();
  953. for (var j = 0; j < nb; j++) {
  954. curshft = shft * j;
  955. positions.push(points[i].x + curshft * curvect.x, points[i].y + curshft * curvect.y, points[i].z + curshft * curvect.z);
  956. positions.push(points[i].x + (curshft + dashshft) * curvect.x, points[i].y + (curshft + dashshft) * curvect.y, points[i].z + (curshft + dashshft) * curvect.z);
  957. indices.push(idx, idx + 1);
  958. idx += 2;
  959. }
  960. }
  961. // Result
  962. var vertexData = new VertexData();
  963. vertexData.positions = positions;
  964. vertexData.indices = indices;
  965. return vertexData;
  966. };
  967. VertexData.CreateGround = function (options) {
  968. var indices = [];
  969. var positions = [];
  970. var normals = [];
  971. var uvs = [];
  972. var row, col;
  973. var width = options.width || 1;
  974. var height = options.height || 1;
  975. var subdivisions = options.subdivisions || 1;
  976. for (row = 0; row <= subdivisions; row++) {
  977. for (col = 0; col <= subdivisions; col++) {
  978. var position = new BABYLON.Vector3((col * width) / subdivisions - (width / 2.0), 0, ((subdivisions - row) * height) / subdivisions - (height / 2.0));
  979. var normal = new BABYLON.Vector3(0, 1.0, 0);
  980. positions.push(position.x, position.y, position.z);
  981. normals.push(normal.x, normal.y, normal.z);
  982. uvs.push(col / subdivisions, 1.0 - row / subdivisions);
  983. }
  984. }
  985. for (row = 0; row < subdivisions; row++) {
  986. for (col = 0; col < subdivisions; col++) {
  987. indices.push(col + 1 + (row + 1) * (subdivisions + 1));
  988. indices.push(col + 1 + row * (subdivisions + 1));
  989. indices.push(col + row * (subdivisions + 1));
  990. indices.push(col + (row + 1) * (subdivisions + 1));
  991. indices.push(col + 1 + (row + 1) * (subdivisions + 1));
  992. indices.push(col + row * (subdivisions + 1));
  993. }
  994. }
  995. // Result
  996. var vertexData = new VertexData();
  997. vertexData.indices = indices;
  998. vertexData.positions = positions;
  999. vertexData.normals = normals;
  1000. vertexData.uvs = uvs;
  1001. return vertexData;
  1002. };
  1003. VertexData.CreateTiledGround = function (options) {
  1004. var xmin = options.xmin;
  1005. var zmin = options.zmin;
  1006. var xmax = options.xmax;
  1007. var zmax = options.zmax;
  1008. var subdivisions = options.subdivisions || { w: 1, h: 1 };
  1009. var precision = options.precision || { w: 1, h: 1 };
  1010. var indices = [];
  1011. var positions = [];
  1012. var normals = [];
  1013. var uvs = [];
  1014. var row, col, tileRow, tileCol;
  1015. subdivisions.h = (subdivisions.w < 1) ? 1 : subdivisions.h;
  1016. subdivisions.w = (subdivisions.w < 1) ? 1 : subdivisions.w;
  1017. precision.w = (precision.w < 1) ? 1 : precision.w;
  1018. precision.h = (precision.h < 1) ? 1 : precision.h;
  1019. var tileSize = {
  1020. 'w': (xmax - xmin) / subdivisions.w,
  1021. 'h': (zmax - zmin) / subdivisions.h
  1022. };
  1023. function applyTile(xTileMin, zTileMin, xTileMax, zTileMax) {
  1024. // Indices
  1025. var base = positions.length / 3;
  1026. var rowLength = precision.w + 1;
  1027. for (row = 0; row < precision.h; row++) {
  1028. for (col = 0; col < precision.w; col++) {
  1029. var square = [
  1030. base + col + row * rowLength,
  1031. base + (col + 1) + row * rowLength,
  1032. base + (col + 1) + (row + 1) * rowLength,
  1033. base + col + (row + 1) * rowLength
  1034. ];
  1035. indices.push(square[1]);
  1036. indices.push(square[2]);
  1037. indices.push(square[3]);
  1038. indices.push(square[0]);
  1039. indices.push(square[1]);
  1040. indices.push(square[3]);
  1041. }
  1042. }
  1043. // Position, normals and uvs
  1044. var position = BABYLON.Vector3.Zero();
  1045. var normal = new BABYLON.Vector3(0, 1.0, 0);
  1046. for (row = 0; row <= precision.h; row++) {
  1047. position.z = (row * (zTileMax - zTileMin)) / precision.h + zTileMin;
  1048. for (col = 0; col <= precision.w; col++) {
  1049. position.x = (col * (xTileMax - xTileMin)) / precision.w + xTileMin;
  1050. position.y = 0;
  1051. positions.push(position.x, position.y, position.z);
  1052. normals.push(normal.x, normal.y, normal.z);
  1053. uvs.push(col / precision.w, row / precision.h);
  1054. }
  1055. }
  1056. }
  1057. for (tileRow = 0; tileRow < subdivisions.h; tileRow++) {
  1058. for (tileCol = 0; tileCol < subdivisions.w; tileCol++) {
  1059. applyTile(xmin + tileCol * tileSize.w, zmin + tileRow * tileSize.h, xmin + (tileCol + 1) * tileSize.w, zmin + (tileRow + 1) * tileSize.h);
  1060. }
  1061. }
  1062. // Result
  1063. var vertexData = new VertexData();
  1064. vertexData.indices = indices;
  1065. vertexData.positions = positions;
  1066. vertexData.normals = normals;
  1067. vertexData.uvs = uvs;
  1068. return vertexData;
  1069. };
  1070. VertexData.CreateGroundFromHeightMap = function (options) {
  1071. var indices = [];
  1072. var positions = [];
  1073. var normals = [];
  1074. var uvs = [];
  1075. var row, col;
  1076. // Vertices
  1077. for (row = 0; row <= options.subdivisions; row++) {
  1078. for (col = 0; col <= options.subdivisions; col++) {
  1079. 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));
  1080. // Compute height
  1081. var heightMapX = (((position.x + options.width / 2) / options.width) * (options.bufferWidth - 1)) | 0;
  1082. var heightMapY = ((1.0 - (position.z + options.height / 2) / options.height) * (options.bufferHeight - 1)) | 0;
  1083. var pos = (heightMapX + heightMapY * options.bufferWidth) * 4;
  1084. var r = options.buffer[pos] / 255.0;
  1085. var g = options.buffer[pos + 1] / 255.0;
  1086. var b = options.buffer[pos + 2] / 255.0;
  1087. var gradient = r * 0.3 + g * 0.59 + b * 0.11;
  1088. position.y = options.minHeight + (options.maxHeight - options.minHeight) * gradient;
  1089. // Add vertex
  1090. positions.push(position.x, position.y, position.z);
  1091. normals.push(0, 0, 0);
  1092. uvs.push(col / options.subdivisions, 1.0 - row / options.subdivisions);
  1093. }
  1094. }
  1095. // Indices
  1096. for (row = 0; row < options.subdivisions; row++) {
  1097. for (col = 0; col < options.subdivisions; col++) {
  1098. indices.push(col + 1 + (row + 1) * (options.subdivisions + 1));
  1099. indices.push(col + 1 + row * (options.subdivisions + 1));
  1100. indices.push(col + row * (options.subdivisions + 1));
  1101. indices.push(col + (row + 1) * (options.subdivisions + 1));
  1102. indices.push(col + 1 + (row + 1) * (options.subdivisions + 1));
  1103. indices.push(col + row * (options.subdivisions + 1));
  1104. }
  1105. }
  1106. // Normals
  1107. VertexData.ComputeNormals(positions, indices, normals);
  1108. // Result
  1109. var vertexData = new VertexData();
  1110. vertexData.indices = indices;
  1111. vertexData.positions = positions;
  1112. vertexData.normals = normals;
  1113. vertexData.uvs = uvs;
  1114. return vertexData;
  1115. };
  1116. VertexData.CreatePlane = function (options) {
  1117. var indices = [];
  1118. var positions = [];
  1119. var normals = [];
  1120. var uvs = [];
  1121. var width = options.width || options.size || 1;
  1122. var height = options.height || options.size || 1;
  1123. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1124. // Vertices
  1125. var halfWidth = width / 2.0;
  1126. var halfHeight = height / 2.0;
  1127. positions.push(-halfWidth, -halfHeight, 0);
  1128. normals.push(0, 0, -1.0);
  1129. uvs.push(0.0, 0.0);
  1130. positions.push(halfWidth, -halfHeight, 0);
  1131. normals.push(0, 0, -1.0);
  1132. uvs.push(1.0, 0.0);
  1133. positions.push(halfWidth, halfHeight, 0);
  1134. normals.push(0, 0, -1.0);
  1135. uvs.push(1.0, 1.0);
  1136. positions.push(-halfWidth, halfHeight, 0);
  1137. normals.push(0, 0, -1.0);
  1138. uvs.push(0.0, 1.0);
  1139. // Indices
  1140. indices.push(0);
  1141. indices.push(1);
  1142. indices.push(2);
  1143. indices.push(0);
  1144. indices.push(2);
  1145. indices.push(3);
  1146. // Sides
  1147. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  1148. // Result
  1149. var vertexData = new VertexData();
  1150. vertexData.indices = indices;
  1151. vertexData.positions = positions;
  1152. vertexData.normals = normals;
  1153. vertexData.uvs = uvs;
  1154. return vertexData;
  1155. };
  1156. VertexData.CreateDisc = function (options) {
  1157. var positions = [];
  1158. var indices = [];
  1159. var normals = [];
  1160. var uvs = [];
  1161. var radius = options.radius || 0.5;
  1162. var tessellation = options.tessellation || 64;
  1163. var arc = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
  1164. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1165. // positions and uvs
  1166. positions.push(0, 0, 0); // disc center first
  1167. uvs.push(0.5, 0.5);
  1168. var theta = Math.PI * 2 * arc;
  1169. var step = theta / tessellation;
  1170. for (var a = 0; a < theta; a += step) {
  1171. var x = Math.cos(a);
  1172. var y = Math.sin(a);
  1173. var u = (x + 1) / 2;
  1174. var v = (1 - y) / 2;
  1175. positions.push(radius * x, radius * y, 0);
  1176. uvs.push(u, v);
  1177. }
  1178. if (arc === 1) {
  1179. positions.push(positions[3], positions[4], positions[5]); // close the circle
  1180. uvs.push(uvs[2], uvs[3]);
  1181. }
  1182. //indices
  1183. var vertexNb = positions.length / 3;
  1184. for (var i = 1; i < vertexNb - 1; i++) {
  1185. indices.push(i + 1, 0, i);
  1186. }
  1187. // result
  1188. VertexData.ComputeNormals(positions, indices, normals);
  1189. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  1190. var vertexData = new VertexData();
  1191. vertexData.indices = indices;
  1192. vertexData.positions = positions;
  1193. vertexData.normals = normals;
  1194. vertexData.uvs = uvs;
  1195. return vertexData;
  1196. };
  1197. VertexData.CreateIcoSphere = function (options) {
  1198. var sideOrientation = options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1199. var radius = options.radius || 1;
  1200. var flat = (options.flat === undefined) ? true : options.flat;
  1201. var subdivisions = options.subdivisions || 4;
  1202. var radiusX = options.radiusX || radius;
  1203. var radiusY = options.radiusY || radius;
  1204. var radiusZ = options.radiusZ || radius;
  1205. var t = (1 + Math.sqrt(5)) / 2;
  1206. // 12 vertex x,y,z
  1207. var ico_vertices = [
  1208. -1, t, -0, 1, t, 0, -1, -t, 0, 1, -t, 0,
  1209. 0, -1, -t, 0, 1, -t, 0, -1, t, 0, 1, t,
  1210. t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, -1 // v8-11
  1211. ];
  1212. // index of 3 vertex makes a face of icopshere
  1213. var ico_indices = [
  1214. 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 12, 22, 23,
  1215. 1, 5, 20, 5, 11, 4, 23, 22, 13, 22, 18, 6, 7, 1, 8,
  1216. 14, 21, 4, 14, 4, 2, 16, 13, 6, 15, 6, 19, 3, 8, 9,
  1217. 4, 21, 5, 13, 17, 23, 6, 13, 22, 19, 6, 18, 9, 8, 1
  1218. ];
  1219. // vertex for uv have aliased position, not for UV
  1220. var vertices_unalias_id = [
  1221. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
  1222. // vertex alias
  1223. 0,
  1224. 2,
  1225. 3,
  1226. 3,
  1227. 3,
  1228. 4,
  1229. 7,
  1230. 8,
  1231. 9,
  1232. 9,
  1233. 10,
  1234. 11 // 23: B + 12
  1235. ];
  1236. // uv as integer step (not pixels !)
  1237. var ico_vertexuv = [
  1238. 5, 1, 3, 1, 6, 4, 0, 0,
  1239. 5, 3, 4, 2, 2, 2, 4, 0,
  1240. 2, 0, 1, 1, 6, 0, 6, 2,
  1241. // vertex alias (for same vertex on different faces)
  1242. 0, 4,
  1243. 3, 3,
  1244. 4, 4,
  1245. 3, 1,
  1246. 4, 2,
  1247. 4, 4,
  1248. 0, 2,
  1249. 1, 1,
  1250. 2, 2,
  1251. 3, 3,
  1252. 1, 3,
  1253. 2, 4 // 23: B + 12
  1254. ];
  1255. // Vertices[0, 1, ...9, A, B] : position on UV plane
  1256. // '+' indicate duplicate position to be fixed (3,9:0,2,3,4,7,8,A,B)
  1257. // First island of uv mapping
  1258. // v = 4h 3+ 2
  1259. // v = 3h 9+ 4
  1260. // v = 2h 9+ 5 B
  1261. // v = 1h 9 1 0
  1262. // v = 0h 3 8 7 A
  1263. // u = 0 1 2 3 4 5 6 *a
  1264. // Second island of uv mapping
  1265. // v = 4h 0+ B+ 4+
  1266. // v = 3h A+ 2+
  1267. // v = 2h 7+ 6 3+
  1268. // v = 1h 8+ 3+
  1269. // v = 0h
  1270. // u = 0 1 2 3 4 5 6 *a
  1271. // Face layout on texture UV mapping
  1272. // ============
  1273. // \ 4 /\ 16 / ======
  1274. // \ / \ / /\ 11 /
  1275. // \/ 7 \/ / \ /
  1276. // ======= / 10 \/
  1277. // /\ 17 /\ =======
  1278. // / \ / \ \ 15 /\
  1279. // / 8 \/ 12 \ \ / \
  1280. // ============ \/ 6 \
  1281. // \ 18 /\ ============
  1282. // \ / \ \ 5 /\ 0 /
  1283. // \/ 13 \ \ / \ /
  1284. // ======= \/ 1 \/
  1285. // =============
  1286. // /\ 19 /\ 2 /\
  1287. // / \ / \ / \
  1288. // / 14 \/ 9 \/ 3 \
  1289. // ===================
  1290. // uv step is u:1 or 0.5, v:cos(30)=sqrt(3)/2, ratio approx is 84/97
  1291. var ustep = 138 / 1024;
  1292. var vstep = 239 / 1024;
  1293. var uoffset = 60 / 1024;
  1294. var voffset = 26 / 1024;
  1295. // Second island should have margin, not to touch the first island
  1296. // avoid any borderline artefact in pixel rounding
  1297. var island_u_offset = -40 / 1024;
  1298. var island_v_offset = +20 / 1024;
  1299. // face is either island 0 or 1 :
  1300. // second island is for faces : [4, 7, 8, 12, 13, 16, 17, 18]
  1301. var island = [
  1302. 0, 0, 0, 0, 1,
  1303. 0, 0, 1, 1, 0,
  1304. 0, 0, 1, 1, 0,
  1305. 0, 1, 1, 1, 0 // 15 - 19
  1306. ];
  1307. var indices = [];
  1308. var positions = [];
  1309. var normals = [];
  1310. var uvs = [];
  1311. var current_indice = 0;
  1312. // prepare array of 3 vector (empty) (to be worked in place, shared for each face)
  1313. var face_vertex_pos = new Array(3);
  1314. var face_vertex_uv = new Array(3);
  1315. var v012;
  1316. for (v012 = 0; v012 < 3; v012++) {
  1317. face_vertex_pos[v012] = BABYLON.Vector3.Zero();
  1318. face_vertex_uv[v012] = BABYLON.Vector2.Zero();
  1319. }
  1320. // create all with normals
  1321. for (var face = 0; face < 20; face++) {
  1322. // 3 vertex per face
  1323. for (v012 = 0; v012 < 3; v012++) {
  1324. // look up vertex 0,1,2 to its index in 0 to 11 (or 23 including alias)
  1325. var v_id = ico_indices[3 * face + v012];
  1326. // vertex have 3D position (x,y,z)
  1327. 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]);
  1328. // Normalize to get normal, then scale to radius
  1329. face_vertex_pos[v012].normalize().scaleInPlace(radius);
  1330. // uv Coordinates from vertex ID
  1331. 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);
  1332. }
  1333. // Subdivide the face (interpolate pos, norm, uv)
  1334. // - pos is linear interpolation, then projected to sphere (converge polyhedron to sphere)
  1335. // - norm is linear interpolation of vertex corner normal
  1336. // (to be checked if better to re-calc from face vertex, or if approximation is OK ??? )
  1337. // - uv is linear interpolation
  1338. //
  1339. // Topology is as below for sub-divide by 2
  1340. // vertex shown as v0,v1,v2
  1341. // interp index is i1 to progress in range [v0,v1[
  1342. // interp index is i2 to progress in range [v0,v2[
  1343. // face index as (i1,i2) for /\ : (i1,i2),(i1+1,i2),(i1,i2+1)
  1344. // and (i1,i2)' for \/ : (i1+1,i2),(i1+1,i2+1),(i1,i2+1)
  1345. //
  1346. //
  1347. // i2 v2
  1348. // ^ ^
  1349. // / / \
  1350. // / / \
  1351. // / / \
  1352. // / / (0,1) \
  1353. // / #---------\
  1354. // / / \ (0,0)'/ \
  1355. // / / \ / \
  1356. // / / \ / \
  1357. // / / (0,0) \ / (1,0) \
  1358. // / #---------#---------\
  1359. // v0 v1
  1360. //
  1361. // --------------------> i1
  1362. //
  1363. // interp of (i1,i2):
  1364. // along i2 : x0=lerp(v0,v2, i2/S) <---> x1=lerp(v1,v2, i2/S)
  1365. // along i1 : lerp(x0,x1, i1/(S-i2))
  1366. //
  1367. // centroid of triangle is needed to get help normal computation
  1368. // (c1,c2) are used for centroid location
  1369. var interp_vertex = function (i1, i2, c1, c2) {
  1370. // vertex is interpolated from
  1371. // - face_vertex_pos[0..2]
  1372. // - face_vertex_uv[0..2]
  1373. var pos_x0 = BABYLON.Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], i2 / subdivisions);
  1374. var pos_x1 = BABYLON.Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], i2 / subdivisions);
  1375. var pos_interp = (subdivisions === i2) ? face_vertex_pos[2] : BABYLON.Vector3.Lerp(pos_x0, pos_x1, i1 / (subdivisions - i2));
  1376. pos_interp.normalize();
  1377. pos_interp.x *= radiusX;
  1378. pos_interp.y *= radiusY;
  1379. pos_interp.z *= radiusZ;
  1380. var vertex_normal;
  1381. if (flat) {
  1382. // in flat mode, recalculate normal as face centroid normal
  1383. var centroid_x0 = BABYLON.Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], c2 / subdivisions);
  1384. var centroid_x1 = BABYLON.Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], c2 / subdivisions);
  1385. var centroid_interp = BABYLON.Vector3.Lerp(centroid_x0, centroid_x1, c1 / (subdivisions - c2));
  1386. vertex_normal = BABYLON.Vector3.Normalize(centroid_interp);
  1387. }
  1388. else {
  1389. // in smooth mode, recalculate normal from each single vertex position
  1390. vertex_normal = BABYLON.Vector3.Normalize(pos_interp);
  1391. }
  1392. var uv_x0 = BABYLON.Vector2.Lerp(face_vertex_uv[0], face_vertex_uv[2], i2 / subdivisions);
  1393. var uv_x1 = BABYLON.Vector2.Lerp(face_vertex_uv[1], face_vertex_uv[2], i2 / subdivisions);
  1394. var uv_interp = (subdivisions === i2) ? face_vertex_uv[2] : BABYLON.Vector2.Lerp(uv_x0, uv_x1, i1 / (subdivisions - i2));
  1395. positions.push(pos_interp.x, pos_interp.y, pos_interp.z);
  1396. normals.push(vertex_normal.x, vertex_normal.y, vertex_normal.z);
  1397. uvs.push(uv_interp.x, uv_interp.y);
  1398. // push each vertex has member of a face
  1399. // Same vertex can bleong to multiple face, it is pushed multiple time (duplicate vertex are present)
  1400. indices.push(current_indice);
  1401. current_indice++;
  1402. };
  1403. for (var i2 = 0; i2 < subdivisions; i2++) {
  1404. for (var i1 = 0; i1 + i2 < subdivisions; i1++) {
  1405. // face : (i1,i2) for /\ :
  1406. // interp for : (i1,i2),(i1+1,i2),(i1,i2+1)
  1407. interp_vertex(i1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);
  1408. interp_vertex(i1 + 1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);
  1409. interp_vertex(i1, i2 + 1, i1 + 1.0 / 3, i2 + 1.0 / 3);
  1410. if (i1 + i2 + 1 < subdivisions) {
  1411. // face : (i1,i2)' for \/ :
  1412. // interp for (i1+1,i2),(i1+1,i2+1),(i1,i2+1)
  1413. interp_vertex(i1 + 1, i2, i1 + 2.0 / 3, i2 + 2.0 / 3);
  1414. interp_vertex(i1 + 1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);
  1415. interp_vertex(i1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);
  1416. }
  1417. }
  1418. }
  1419. }
  1420. // Sides
  1421. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  1422. // Result
  1423. var vertexData = new VertexData();
  1424. vertexData.indices = indices;
  1425. vertexData.positions = positions;
  1426. vertexData.normals = normals;
  1427. vertexData.uvs = uvs;
  1428. return vertexData;
  1429. };
  1430. // inspired from // http://stemkoski.github.io/Three.js/Polyhedra.html
  1431. VertexData.CreatePolyhedron = function (options) {
  1432. // provided polyhedron types :
  1433. // 0 : Tetrahedron, 1 : Octahedron, 2 : Dodecahedron, 3 : Icosahedron, 4 : Rhombicuboctahedron, 5 : Triangular Prism, 6 : Pentagonal Prism, 7 : Hexagonal Prism, 8 : Square Pyramid (J1)
  1434. // 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)
  1435. var polyhedra = [];
  1436. 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]] };
  1437. 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]] };
  1438. polyhedra[2] = {
  1439. 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]],
  1440. 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]]
  1441. };
  1442. polyhedra[3] = {
  1443. 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]],
  1444. 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]]
  1445. };
  1446. polyhedra[4] = {
  1447. 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]],
  1448. 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]]
  1449. };
  1450. 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]] };
  1451. 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]] };
  1452. 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]] };
  1453. 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]] };
  1454. 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]] };
  1455. 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]] };
  1456. 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]] };
  1457. 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]] };
  1458. 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]] };
  1459. polyhedra[14] = {
  1460. 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]],
  1461. 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]]
  1462. };
  1463. var type = (options.type < 0 || options.type >= polyhedra.length) ? 0 : options.type || 0;
  1464. var size = options.size;
  1465. var sizeX = options.sizeX || size || 1;
  1466. var sizeY = options.sizeY || size || 1;
  1467. var sizeZ = options.sizeZ || size || 1;
  1468. var data = options.custom || polyhedra[type];
  1469. var nbfaces = data.face.length;
  1470. var faceUV = options.faceUV || new Array(nbfaces);
  1471. var faceColors = options.faceColors;
  1472. var flat = (options.flat === undefined) ? true : options.flat;
  1473. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1474. var positions = [];
  1475. var indices = [];
  1476. var normals = [];
  1477. var uvs = [];
  1478. var colors = [];
  1479. var index = 0;
  1480. var faceIdx = 0; // face cursor in the array "indexes"
  1481. var indexes = [];
  1482. var i = 0;
  1483. var f = 0;
  1484. var u, v, ang, x, y, tmp;
  1485. // default face colors and UV if undefined
  1486. if (flat) {
  1487. for (f = 0; f < nbfaces; f++) {
  1488. if (faceColors && faceColors[f] === undefined) {
  1489. faceColors[f] = new BABYLON.Color4(1, 1, 1, 1);
  1490. }
  1491. if (faceUV && faceUV[f] === undefined) {
  1492. faceUV[f] = new BABYLON.Vector4(0, 0, 1, 1);
  1493. }
  1494. }
  1495. }
  1496. if (!flat) {
  1497. for (i = 0; i < data.vertex.length; i++) {
  1498. positions.push(data.vertex[i][0] * sizeX, data.vertex[i][1] * sizeY, data.vertex[i][2] * sizeZ);
  1499. uvs.push(0, 0);
  1500. }
  1501. for (f = 0; f < nbfaces; f++) {
  1502. for (i = 0; i < data.face[f].length - 2; i++) {
  1503. indices.push(data.face[f][0], data.face[f][i + 2], data.face[f][i + 1]);
  1504. }
  1505. }
  1506. }
  1507. else {
  1508. for (f = 0; f < nbfaces; f++) {
  1509. var fl = data.face[f].length; // number of vertices of the current face
  1510. ang = 2 * Math.PI / fl;
  1511. x = 0.5 * Math.tan(ang / 2);
  1512. y = 0.5;
  1513. // positions, uvs, colors
  1514. for (i = 0; i < fl; i++) {
  1515. // positions
  1516. 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);
  1517. indexes.push(index);
  1518. index++;
  1519. // uvs
  1520. u = faceUV[f].x + (faceUV[f].z - faceUV[f].x) * (0.5 + x);
  1521. v = faceUV[f].y + (faceUV[f].w - faceUV[f].y) * (y - 0.5);
  1522. uvs.push(u, v);
  1523. tmp = x * Math.cos(ang) - y * Math.sin(ang);
  1524. y = x * Math.sin(ang) + y * Math.cos(ang);
  1525. x = tmp;
  1526. // colors
  1527. if (faceColors) {
  1528. colors.push(faceColors[f].r, faceColors[f].g, faceColors[f].b, faceColors[f].a);
  1529. }
  1530. }
  1531. // indices from indexes
  1532. for (i = 0; i < fl - 2; i++) {
  1533. indices.push(indexes[0 + faceIdx], indexes[i + 2 + faceIdx], indexes[i + 1 + faceIdx]);
  1534. }
  1535. faceIdx += fl;
  1536. }
  1537. }
  1538. VertexData.ComputeNormals(positions, indices, normals);
  1539. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  1540. var vertexData = new VertexData();
  1541. vertexData.positions = positions;
  1542. vertexData.indices = indices;
  1543. vertexData.normals = normals;
  1544. vertexData.uvs = uvs;
  1545. if (faceColors && flat) {
  1546. vertexData.colors = colors;
  1547. }
  1548. return vertexData;
  1549. };
  1550. // based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
  1551. VertexData.CreateTorusKnot = function (options) {
  1552. var indices = [];
  1553. var positions = [];
  1554. var normals = [];
  1555. var uvs = [];
  1556. var radius = options.radius || 2;
  1557. var tube = options.tube || 0.5;
  1558. var radialSegments = options.radialSegments || 32;
  1559. var tubularSegments = options.tubularSegments || 32;
  1560. var p = options.p || 2;
  1561. var q = options.q || 3;
  1562. var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1563. // Helper
  1564. var getPos = function (angle) {
  1565. var cu = Math.cos(angle);
  1566. var su = Math.sin(angle);
  1567. var quOverP = q / p * angle;
  1568. var cs = Math.cos(quOverP);
  1569. var tx = radius * (2 + cs) * 0.5 * cu;
  1570. var ty = radius * (2 + cs) * su * 0.5;
  1571. var tz = radius * Math.sin(quOverP) * 0.5;
  1572. return new BABYLON.Vector3(tx, ty, tz);
  1573. };
  1574. // Vertices
  1575. var i;
  1576. var j;
  1577. for (i = 0; i <= radialSegments; i++) {
  1578. var modI = i % radialSegments;
  1579. var u = modI / radialSegments * 2 * p * Math.PI;
  1580. var p1 = getPos(u);
  1581. var p2 = getPos(u + 0.01);
  1582. var tang = p2.subtract(p1);
  1583. var n = p2.add(p1);
  1584. var bitan = BABYLON.Vector3.Cross(tang, n);
  1585. n = BABYLON.Vector3.Cross(bitan, tang);
  1586. bitan.normalize();
  1587. n.normalize();
  1588. for (j = 0; j < tubularSegments; j++) {
  1589. var modJ = j % tubularSegments;
  1590. var v = modJ / tubularSegments * 2 * Math.PI;
  1591. var cx = -tube * Math.cos(v);
  1592. var cy = tube * Math.sin(v);
  1593. positions.push(p1.x + cx * n.x + cy * bitan.x);
  1594. positions.push(p1.y + cx * n.y + cy * bitan.y);
  1595. positions.push(p1.z + cx * n.z + cy * bitan.z);
  1596. uvs.push(i / radialSegments);
  1597. uvs.push(j / tubularSegments);
  1598. }
  1599. }
  1600. for (i = 0; i < radialSegments; i++) {
  1601. for (j = 0; j < tubularSegments; j++) {
  1602. var jNext = (j + 1) % tubularSegments;
  1603. var a = i * tubularSegments + j;
  1604. var b = (i + 1) * tubularSegments + j;
  1605. var c = (i + 1) * tubularSegments + jNext;
  1606. var d = i * tubularSegments + jNext;
  1607. indices.push(d);
  1608. indices.push(b);
  1609. indices.push(a);
  1610. indices.push(d);
  1611. indices.push(c);
  1612. indices.push(b);
  1613. }
  1614. }
  1615. // Normals
  1616. VertexData.ComputeNormals(positions, indices, normals);
  1617. // Sides
  1618. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  1619. // Result
  1620. var vertexData = new VertexData();
  1621. vertexData.indices = indices;
  1622. vertexData.positions = positions;
  1623. vertexData.normals = normals;
  1624. vertexData.uvs = uvs;
  1625. return vertexData;
  1626. };
  1627. // Tools
  1628. /**
  1629. * @param {any} - positions (number[] or Float32Array)
  1630. * @param {any} - indices (number[] or Uint16Array)
  1631. * @param {any} - normals (number[] or Float32Array)
  1632. */
  1633. VertexData.ComputeNormals = function (positions, indices, normals) {
  1634. var index = 0;
  1635. var p1p2x = 0.0;
  1636. var p1p2y = 0.0;
  1637. var p1p2z = 0.0;
  1638. var p3p2x = 0.0;
  1639. var p3p2y = 0.0;
  1640. var p3p2z = 0.0;
  1641. var faceNormalx = 0.0;
  1642. var faceNormaly = 0.0;
  1643. var faceNormalz = 0.0;
  1644. var length = 0.0;
  1645. var i1 = 0;
  1646. var i2 = 0;
  1647. var i3 = 0;
  1648. for (index = 0; index < positions.length; index++) {
  1649. normals[index] = 0.0;
  1650. }
  1651. // indice triplet = 1 face
  1652. var nbFaces = indices.length / 3;
  1653. for (index = 0; index < nbFaces; index++) {
  1654. i1 = indices[index * 3]; // get the indexes of each vertex of the face
  1655. i2 = indices[index * 3 + 1];
  1656. i3 = indices[index * 3 + 2];
  1657. p1p2x = positions[i1 * 3] - positions[i2 * 3]; // compute two vectors per face
  1658. p1p2y = positions[i1 * 3 + 1] - positions[i2 * 3 + 1];
  1659. p1p2z = positions[i1 * 3 + 2] - positions[i2 * 3 + 2];
  1660. p3p2x = positions[i3 * 3] - positions[i2 * 3];
  1661. p3p2y = positions[i3 * 3 + 1] - positions[i2 * 3 + 1];
  1662. p3p2z = positions[i3 * 3 + 2] - positions[i2 * 3 + 2];
  1663. faceNormalx = p1p2y * p3p2z - p1p2z * p3p2y; // compute the face normal with cross product
  1664. faceNormaly = p1p2z * p3p2x - p1p2x * p3p2z;
  1665. faceNormalz = p1p2x * p3p2y - p1p2y * p3p2x;
  1666. length = Math.sqrt(faceNormalx * faceNormalx + faceNormaly * faceNormaly + faceNormalz * faceNormalz);
  1667. length = (length === 0) ? 1.0 : length;
  1668. faceNormalx /= length; // normalize this normal
  1669. faceNormaly /= length;
  1670. faceNormalz /= length;
  1671. normals[i1 * 3] += faceNormalx; // accumulate all the normals per face
  1672. normals[i1 * 3 + 1] += faceNormaly;
  1673. normals[i1 * 3 + 2] += faceNormalz;
  1674. normals[i2 * 3] += faceNormalx;
  1675. normals[i2 * 3 + 1] += faceNormaly;
  1676. normals[i2 * 3 + 2] += faceNormalz;
  1677. normals[i3 * 3] += faceNormalx;
  1678. normals[i3 * 3 + 1] += faceNormaly;
  1679. normals[i3 * 3 + 2] += faceNormalz;
  1680. }
  1681. // last normalization of each normal
  1682. for (index = 0; index < normals.length / 3; index++) {
  1683. faceNormalx = normals[index * 3];
  1684. faceNormaly = normals[index * 3 + 1];
  1685. faceNormalz = normals[index * 3 + 2];
  1686. length = Math.sqrt(faceNormalx * faceNormalx + faceNormaly * faceNormaly + faceNormalz * faceNormalz);
  1687. length = (length === 0) ? 1.0 : length;
  1688. faceNormalx /= length;
  1689. faceNormaly /= length;
  1690. faceNormalz /= length;
  1691. normals[index * 3] = faceNormalx;
  1692. normals[index * 3 + 1] = faceNormaly;
  1693. normals[index * 3 + 2] = faceNormalz;
  1694. }
  1695. };
  1696. VertexData._ComputeSides = function (sideOrientation, positions, indices, normals, uvs) {
  1697. var li = indices.length;
  1698. var ln = normals.length;
  1699. var i;
  1700. var n;
  1701. sideOrientation = sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
  1702. switch (sideOrientation) {
  1703. case BABYLON.Mesh.FRONTSIDE:
  1704. // nothing changed
  1705. break;
  1706. case BABYLON.Mesh.BACKSIDE:
  1707. var tmp;
  1708. // indices
  1709. for (i = 0; i < li; i += 3) {
  1710. tmp = indices[i];
  1711. indices[i] = indices[i + 2];
  1712. indices[i + 2] = tmp;
  1713. }
  1714. // normals
  1715. for (n = 0; n < ln; n++) {
  1716. normals[n] = -normals[n];
  1717. }
  1718. break;
  1719. case BABYLON.Mesh.DOUBLESIDE:
  1720. // positions
  1721. var lp = positions.length;
  1722. var l = lp / 3;
  1723. for (var p = 0; p < lp; p++) {
  1724. positions[lp + p] = positions[p];
  1725. }
  1726. // indices
  1727. for (i = 0; i < li; i += 3) {
  1728. indices[i + li] = indices[i + 2] + l;
  1729. indices[i + 1 + li] = indices[i + 1] + l;
  1730. indices[i + 2 + li] = indices[i] + l;
  1731. }
  1732. // normals
  1733. for (n = 0; n < ln; n++) {
  1734. normals[ln + n] = -normals[n];
  1735. }
  1736. // uvs
  1737. var lu = uvs.length;
  1738. for (var u = 0; u < lu; u++) {
  1739. uvs[u + lu] = uvs[u];
  1740. }
  1741. break;
  1742. }
  1743. };
  1744. return VertexData;
  1745. })();
  1746. BABYLON.VertexData = VertexData;
  1747. })(BABYLON || (BABYLON = {}));