mesh.vertexData.ts 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440
  1. import { Nullable, FloatArray, IndicesArray } from "../types";
  2. import { Matrix, Vector3, Vector2, Vector4 } from "../Maths/math.vector";
  3. import { VertexBuffer } from "../Meshes/buffer";
  4. import { _DevTools } from '../Misc/devTools';
  5. import { Color4, Color3 } from '../Maths/math.color';
  6. declare type Geometry = import("../Meshes/geometry").Geometry;
  7. declare type Mesh = import("../Meshes/mesh").Mesh;
  8. /**
  9. * Define an interface for all classes that will get and set the data on vertices
  10. */
  11. export interface IGetSetVerticesData {
  12. /**
  13. * Gets a boolean indicating if specific vertex data is present
  14. * @param kind defines the vertex data kind to use
  15. * @returns true is data kind is present
  16. */
  17. isVerticesDataPresent(kind: string): boolean;
  18. /**
  19. * Gets a specific vertex data attached to this geometry. Float data is constructed if the vertex buffer data cannot be returned directly.
  20. * @param kind defines the data kind (Position, normal, etc...)
  21. * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes
  22. * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
  23. * @returns a float array containing vertex data
  24. */
  25. getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray>;
  26. /**
  27. * Returns an array of integers or a typed array (Int32Array, Uint32Array, Uint16Array) populated with the mesh indices.
  28. * @param copyWhenShared If true (default false) and and if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one.
  29. * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
  30. * @returns the indices array or an empty array if the mesh has no geometry
  31. */
  32. getIndices(copyWhenShared?: boolean, forceCopy?: boolean): Nullable<IndicesArray>;
  33. /**
  34. * Set specific vertex data
  35. * @param kind defines the data kind (Position, normal, etc...)
  36. * @param data defines the vertex data to use
  37. * @param updatable defines if the vertex must be flagged as updatable (false as default)
  38. * @param stride defines the stride to use (0 by default). This value is deduced from the kind value if not specified
  39. */
  40. setVerticesData(kind: string, data: FloatArray, updatable: boolean): void;
  41. /**
  42. * Update a specific associated vertex buffer
  43. * @param kind defines which buffer to write to (positions, indices, normals, etc). Possible `kind` values :
  44. * - VertexBuffer.PositionKind
  45. * - VertexBuffer.UVKind
  46. * - VertexBuffer.UV2Kind
  47. * - VertexBuffer.UV3Kind
  48. * - VertexBuffer.UV4Kind
  49. * - VertexBuffer.UV5Kind
  50. * - VertexBuffer.UV6Kind
  51. * - VertexBuffer.ColorKind
  52. * - VertexBuffer.MatricesIndicesKind
  53. * - VertexBuffer.MatricesIndicesExtraKind
  54. * - VertexBuffer.MatricesWeightsKind
  55. * - VertexBuffer.MatricesWeightsExtraKind
  56. * @param data defines the data source
  57. * @param updateExtends defines if extends info of the mesh must be updated (can be null). This is mostly useful for "position" kind
  58. * @param makeItUnique defines if the geometry associated with the mesh must be cloned to make the change only for this mesh (and not all meshes associated with the same geometry)
  59. */
  60. updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean, makeItUnique?: boolean): void;
  61. /**
  62. * Creates a new index buffer
  63. * @param indices defines the indices to store in the index buffer
  64. * @param totalVertices defines the total number of vertices (could be null)
  65. * @param updatable defines if the index buffer must be flagged as updatable (false by default)
  66. */
  67. setIndices(indices: IndicesArray, totalVertices: Nullable<number>, updatable?: boolean): void;
  68. }
  69. /**
  70. * This class contains the various kinds of data on every vertex of a mesh used in determining its shape and appearance
  71. */
  72. export class VertexData {
  73. /**
  74. * Mesh side orientation : usually the external or front surface
  75. */
  76. public static readonly FRONTSIDE = 0;
  77. /**
  78. * Mesh side orientation : usually the internal or back surface
  79. */
  80. public static readonly BACKSIDE = 1;
  81. /**
  82. * Mesh side orientation : both internal and external or front and back surfaces
  83. */
  84. public static readonly DOUBLESIDE = 2;
  85. /**
  86. * Mesh side orientation : by default, `FRONTSIDE`
  87. */
  88. public static readonly DEFAULTSIDE = 0;
  89. /**
  90. * An array of the x, y, z position of each vertex [...., x, y, z, .....]
  91. */
  92. public positions: Nullable<FloatArray>;
  93. /**
  94. * An array of the x, y, z normal vector of each vertex [...., x, y, z, .....]
  95. */
  96. public normals: Nullable<FloatArray>;
  97. /**
  98. * An array of the x, y, z tangent vector of each vertex [...., x, y, z, .....]
  99. */
  100. public tangents: Nullable<FloatArray>;
  101. /**
  102. * An array of u,v which maps a texture image onto each vertex [...., u, v, .....]
  103. */
  104. public uvs: Nullable<FloatArray>;
  105. /**
  106. * A second array of u,v which maps a texture image onto each vertex [...., u, v, .....]
  107. */
  108. public uvs2: Nullable<FloatArray>;
  109. /**
  110. * A third array of u,v which maps a texture image onto each vertex [...., u, v, .....]
  111. */
  112. public uvs3: Nullable<FloatArray>;
  113. /**
  114. * A fourth array of u,v which maps a texture image onto each vertex [...., u, v, .....]
  115. */
  116. public uvs4: Nullable<FloatArray>;
  117. /**
  118. * A fifth array of u,v which maps a texture image onto each vertex [...., u, v, .....]
  119. */
  120. public uvs5: Nullable<FloatArray>;
  121. /**
  122. * A sixth array of u,v which maps a texture image onto each vertex [...., u, v, .....]
  123. */
  124. public uvs6: Nullable<FloatArray>;
  125. /**
  126. * An array of the r, g, b, a, color of each vertex [...., r, g, b, a, .....]
  127. */
  128. public colors: Nullable<FloatArray>;
  129. /**
  130. * An array containing the list of indices to the array of matrices produced by bones, each vertex have up to 4 indices (8 if the matricesIndicesExtra is set).
  131. */
  132. public matricesIndices: Nullable<FloatArray>;
  133. /**
  134. * An array containing the list of weights defining the weight of each indexed matrix in the final computation
  135. */
  136. public matricesWeights: Nullable<FloatArray>;
  137. /**
  138. * An array extending the number of possible indices
  139. */
  140. public matricesIndicesExtra: Nullable<FloatArray>;
  141. /**
  142. * An array extending the number of possible weights when the number of indices is extended
  143. */
  144. public matricesWeightsExtra: Nullable<FloatArray>;
  145. /**
  146. * An array of i, j, k the three vertex indices required for each triangular facet [...., i, j, k .....]
  147. */
  148. public indices: Nullable<IndicesArray>;
  149. /**
  150. * Uses the passed data array to set the set the values for the specified kind of data
  151. * @param data a linear array of floating numbers
  152. * @param kind the type of data that is being set, eg positions, colors etc
  153. */
  154. public set(data: FloatArray, kind: string) {
  155. switch (kind) {
  156. case VertexBuffer.PositionKind:
  157. this.positions = data;
  158. break;
  159. case VertexBuffer.NormalKind:
  160. this.normals = data;
  161. break;
  162. case VertexBuffer.TangentKind:
  163. this.tangents = data;
  164. break;
  165. case VertexBuffer.UVKind:
  166. this.uvs = data;
  167. break;
  168. case VertexBuffer.UV2Kind:
  169. this.uvs2 = data;
  170. break;
  171. case VertexBuffer.UV3Kind:
  172. this.uvs3 = data;
  173. break;
  174. case VertexBuffer.UV4Kind:
  175. this.uvs4 = data;
  176. break;
  177. case VertexBuffer.UV5Kind:
  178. this.uvs5 = data;
  179. break;
  180. case VertexBuffer.UV6Kind:
  181. this.uvs6 = data;
  182. break;
  183. case VertexBuffer.ColorKind:
  184. this.colors = data;
  185. break;
  186. case VertexBuffer.MatricesIndicesKind:
  187. this.matricesIndices = data;
  188. break;
  189. case VertexBuffer.MatricesWeightsKind:
  190. this.matricesWeights = data;
  191. break;
  192. case VertexBuffer.MatricesIndicesExtraKind:
  193. this.matricesIndicesExtra = data;
  194. break;
  195. case VertexBuffer.MatricesWeightsExtraKind:
  196. this.matricesWeightsExtra = data;
  197. break;
  198. }
  199. }
  200. /**
  201. * Associates the vertexData to the passed Mesh.
  202. * Sets it as updatable or not (default `false`)
  203. * @param mesh the mesh the vertexData is applied to
  204. * @param updatable when used and having the value true allows new data to update the vertexData
  205. * @returns the VertexData
  206. */
  207. public applyToMesh(mesh: Mesh, updatable?: boolean): VertexData {
  208. this._applyTo(mesh, updatable);
  209. return this;
  210. }
  211. /**
  212. * Associates the vertexData to the passed Geometry.
  213. * Sets it as updatable or not (default `false`)
  214. * @param geometry the geometry the vertexData is applied to
  215. * @param updatable when used and having the value true allows new data to update the vertexData
  216. * @returns VertexData
  217. */
  218. public applyToGeometry(geometry: Geometry, updatable?: boolean): VertexData {
  219. this._applyTo(geometry, updatable);
  220. return this;
  221. }
  222. /**
  223. * Updates the associated mesh
  224. * @param mesh the mesh to be updated
  225. * @param updateExtends when true the mesh BoundingInfo will be renewed when and if position kind is updated, optional with default false
  226. * @param makeItUnique when true, and when and if position kind is updated, a new global geometry will be created from these positions and set to the mesh, optional with default false
  227. * @returns VertexData
  228. */
  229. public updateMesh(mesh: Mesh): VertexData {
  230. this._update(mesh);
  231. return this;
  232. }
  233. /**
  234. * Updates the associated geometry
  235. * @param geometry the geometry to be updated
  236. * @param updateExtends when true BoundingInfo will be renewed when and if position kind is updated, optional with default false
  237. * @param makeItUnique when true, and when and if position kind is updated, a new global geometry will be created from these positions and set to the mesh, optional with default false
  238. * @returns VertexData.
  239. */
  240. public updateGeometry(geometry: Geometry): VertexData {
  241. this._update(geometry);
  242. return this;
  243. }
  244. private _applyTo(meshOrGeometry: IGetSetVerticesData, updatable: boolean = false): VertexData {
  245. if (this.positions) {
  246. meshOrGeometry.setVerticesData(VertexBuffer.PositionKind, this.positions, updatable);
  247. }
  248. if (this.normals) {
  249. meshOrGeometry.setVerticesData(VertexBuffer.NormalKind, this.normals, updatable);
  250. }
  251. if (this.tangents) {
  252. meshOrGeometry.setVerticesData(VertexBuffer.TangentKind, this.tangents, updatable);
  253. }
  254. if (this.uvs) {
  255. meshOrGeometry.setVerticesData(VertexBuffer.UVKind, this.uvs, updatable);
  256. }
  257. if (this.uvs2) {
  258. meshOrGeometry.setVerticesData(VertexBuffer.UV2Kind, this.uvs2, updatable);
  259. }
  260. if (this.uvs3) {
  261. meshOrGeometry.setVerticesData(VertexBuffer.UV3Kind, this.uvs3, updatable);
  262. }
  263. if (this.uvs4) {
  264. meshOrGeometry.setVerticesData(VertexBuffer.UV4Kind, this.uvs4, updatable);
  265. }
  266. if (this.uvs5) {
  267. meshOrGeometry.setVerticesData(VertexBuffer.UV5Kind, this.uvs5, updatable);
  268. }
  269. if (this.uvs6) {
  270. meshOrGeometry.setVerticesData(VertexBuffer.UV6Kind, this.uvs6, updatable);
  271. }
  272. if (this.colors) {
  273. meshOrGeometry.setVerticesData(VertexBuffer.ColorKind, this.colors, updatable);
  274. }
  275. if (this.matricesIndices) {
  276. meshOrGeometry.setVerticesData(VertexBuffer.MatricesIndicesKind, this.matricesIndices, updatable);
  277. }
  278. if (this.matricesWeights) {
  279. meshOrGeometry.setVerticesData(VertexBuffer.MatricesWeightsKind, this.matricesWeights, updatable);
  280. }
  281. if (this.matricesIndicesExtra) {
  282. meshOrGeometry.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updatable);
  283. }
  284. if (this.matricesWeightsExtra) {
  285. meshOrGeometry.setVerticesData(VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updatable);
  286. }
  287. if (this.indices) {
  288. meshOrGeometry.setIndices(this.indices, null, updatable);
  289. } else {
  290. meshOrGeometry.setIndices([], null);
  291. }
  292. return this;
  293. }
  294. private _update(meshOrGeometry: IGetSetVerticesData, updateExtends?: boolean, makeItUnique?: boolean): VertexData {
  295. if (this.positions) {
  296. meshOrGeometry.updateVerticesData(VertexBuffer.PositionKind, this.positions, updateExtends, makeItUnique);
  297. }
  298. if (this.normals) {
  299. meshOrGeometry.updateVerticesData(VertexBuffer.NormalKind, this.normals, updateExtends, makeItUnique);
  300. }
  301. if (this.tangents) {
  302. meshOrGeometry.updateVerticesData(VertexBuffer.TangentKind, this.tangents, updateExtends, makeItUnique);
  303. }
  304. if (this.uvs) {
  305. meshOrGeometry.updateVerticesData(VertexBuffer.UVKind, this.uvs, updateExtends, makeItUnique);
  306. }
  307. if (this.uvs2) {
  308. meshOrGeometry.updateVerticesData(VertexBuffer.UV2Kind, this.uvs2, updateExtends, makeItUnique);
  309. }
  310. if (this.uvs3) {
  311. meshOrGeometry.updateVerticesData(VertexBuffer.UV3Kind, this.uvs3, updateExtends, makeItUnique);
  312. }
  313. if (this.uvs4) {
  314. meshOrGeometry.updateVerticesData(VertexBuffer.UV4Kind, this.uvs4, updateExtends, makeItUnique);
  315. }
  316. if (this.uvs5) {
  317. meshOrGeometry.updateVerticesData(VertexBuffer.UV5Kind, this.uvs5, updateExtends, makeItUnique);
  318. }
  319. if (this.uvs6) {
  320. meshOrGeometry.updateVerticesData(VertexBuffer.UV6Kind, this.uvs6, updateExtends, makeItUnique);
  321. }
  322. if (this.colors) {
  323. meshOrGeometry.updateVerticesData(VertexBuffer.ColorKind, this.colors, updateExtends, makeItUnique);
  324. }
  325. if (this.matricesIndices) {
  326. meshOrGeometry.updateVerticesData(VertexBuffer.MatricesIndicesKind, this.matricesIndices, updateExtends, makeItUnique);
  327. }
  328. if (this.matricesWeights) {
  329. meshOrGeometry.updateVerticesData(VertexBuffer.MatricesWeightsKind, this.matricesWeights, updateExtends, makeItUnique);
  330. }
  331. if (this.matricesIndicesExtra) {
  332. meshOrGeometry.updateVerticesData(VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updateExtends, makeItUnique);
  333. }
  334. if (this.matricesWeightsExtra) {
  335. meshOrGeometry.updateVerticesData(VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updateExtends, makeItUnique);
  336. }
  337. if (this.indices) {
  338. meshOrGeometry.setIndices(this.indices, null);
  339. }
  340. return this;
  341. }
  342. /**
  343. * Transforms each position and each normal of the vertexData according to the passed Matrix
  344. * @param matrix the transforming matrix
  345. * @returns the VertexData
  346. */
  347. public transform(matrix: Matrix): VertexData {
  348. var flip = matrix.m[0] * matrix.m[5] * matrix.m[10] < 0;
  349. var transformed = Vector3.Zero();
  350. var index: number;
  351. if (this.positions) {
  352. var position = Vector3.Zero();
  353. for (index = 0; index < this.positions.length; index += 3) {
  354. Vector3.FromArrayToRef(this.positions, index, position);
  355. Vector3.TransformCoordinatesToRef(position, matrix, transformed);
  356. this.positions[index] = transformed.x;
  357. this.positions[index + 1] = transformed.y;
  358. this.positions[index + 2] = transformed.z;
  359. }
  360. }
  361. if (this.normals) {
  362. var normal = Vector3.Zero();
  363. for (index = 0; index < this.normals.length; index += 3) {
  364. Vector3.FromArrayToRef(this.normals, index, normal);
  365. Vector3.TransformNormalToRef(normal, matrix, transformed);
  366. this.normals[index] = transformed.x;
  367. this.normals[index + 1] = transformed.y;
  368. this.normals[index + 2] = transformed.z;
  369. }
  370. }
  371. if (this.tangents) {
  372. var tangent = Vector4.Zero();
  373. var tangentTransformed = Vector4.Zero();
  374. for (index = 0; index < this.tangents.length; index += 4) {
  375. Vector4.FromArrayToRef(this.tangents, index, tangent);
  376. Vector4.TransformNormalToRef(tangent, matrix, tangentTransformed);
  377. this.tangents[index] = tangentTransformed.x;
  378. this.tangents[index + 1] = tangentTransformed.y;
  379. this.tangents[index + 2] = tangentTransformed.z;
  380. this.tangents[index + 3] = tangentTransformed.w;
  381. }
  382. }
  383. if (flip && this.indices) {
  384. for (index = 0; index < this.indices!.length; index += 3) {
  385. let tmp = this.indices[index + 1];
  386. this.indices[index + 1] = this.indices[index + 2];
  387. this.indices[index + 2] = tmp;
  388. }
  389. }
  390. return this;
  391. }
  392. /**
  393. * Merges the passed VertexData into the current one
  394. * @param other the VertexData to be merged into the current one
  395. * @param use32BitsIndices defines a boolean indicating if indices must be store in a 32 bits array
  396. * @returns the modified VertexData
  397. */
  398. public merge(other: VertexData, use32BitsIndices = false): VertexData {
  399. this._validate();
  400. other._validate();
  401. if (!this.normals !== !other.normals ||
  402. !this.tangents !== !other.tangents ||
  403. !this.uvs !== !other.uvs ||
  404. !this.uvs2 !== !other.uvs2 ||
  405. !this.uvs3 !== !other.uvs3 ||
  406. !this.uvs4 !== !other.uvs4 ||
  407. !this.uvs5 !== !other.uvs5 ||
  408. !this.uvs6 !== !other.uvs6 ||
  409. !this.colors !== !other.colors ||
  410. !this.matricesIndices !== !other.matricesIndices ||
  411. !this.matricesWeights !== !other.matricesWeights ||
  412. !this.matricesIndicesExtra !== !other.matricesIndicesExtra ||
  413. !this.matricesWeightsExtra !== !other.matricesWeightsExtra) {
  414. throw new Error("Cannot merge vertex data that do not have the same set of attributes");
  415. }
  416. if (other.indices) {
  417. if (!this.indices) {
  418. this.indices = [];
  419. }
  420. var offset = this.positions ? this.positions.length / 3 : 0;
  421. var isSrcTypedArray = (<any>this.indices).BYTES_PER_ELEMENT !== undefined;
  422. if (isSrcTypedArray) {
  423. var len = this.indices.length + other.indices.length;
  424. var temp = use32BitsIndices || this.indices instanceof Uint32Array ? new Uint32Array(len) : new Uint16Array(len);
  425. temp.set(this.indices);
  426. let decal = this.indices.length;
  427. for (var index = 0; index < other.indices.length; index++) {
  428. temp[decal + index] = other.indices[index] + offset;
  429. }
  430. this.indices = temp;
  431. } else {
  432. for (var index = 0; index < other.indices.length; index++) {
  433. (<number[]>this.indices).push(other.indices[index] + offset);
  434. }
  435. }
  436. }
  437. this.positions = this._mergeElement(this.positions, other.positions);
  438. this.normals = this._mergeElement(this.normals, other.normals);
  439. this.tangents = this._mergeElement(this.tangents, other.tangents);
  440. this.uvs = this._mergeElement(this.uvs, other.uvs);
  441. this.uvs2 = this._mergeElement(this.uvs2, other.uvs2);
  442. this.uvs3 = this._mergeElement(this.uvs3, other.uvs3);
  443. this.uvs4 = this._mergeElement(this.uvs4, other.uvs4);
  444. this.uvs5 = this._mergeElement(this.uvs5, other.uvs5);
  445. this.uvs6 = this._mergeElement(this.uvs6, other.uvs6);
  446. this.colors = this._mergeElement(this.colors, other.colors);
  447. this.matricesIndices = this._mergeElement(this.matricesIndices, other.matricesIndices);
  448. this.matricesWeights = this._mergeElement(this.matricesWeights, other.matricesWeights);
  449. this.matricesIndicesExtra = this._mergeElement(this.matricesIndicesExtra, other.matricesIndicesExtra);
  450. this.matricesWeightsExtra = this._mergeElement(this.matricesWeightsExtra, other.matricesWeightsExtra);
  451. return this;
  452. }
  453. private _mergeElement(source: Nullable<FloatArray>, other: Nullable<FloatArray>): Nullable<FloatArray> {
  454. if (!source) {
  455. return other;
  456. }
  457. if (!other) {
  458. return source;
  459. }
  460. var len = other.length + source.length;
  461. var isSrcTypedArray = source instanceof Float32Array;
  462. var isOthTypedArray = other instanceof Float32Array;
  463. // use non-loop method when the source is Float32Array
  464. if (isSrcTypedArray) {
  465. var ret32 = new Float32Array(len);
  466. ret32.set(source);
  467. ret32.set(other, source.length);
  468. return ret32;
  469. // source is number[], when other is also use concat
  470. } else if (!isOthTypedArray) {
  471. return (<number[]>source).concat(<number[]>other);
  472. // source is a number[], but other is a Float32Array, loop required
  473. } else {
  474. var ret = (<number[]>source).slice(0); // copy source to a separate array
  475. for (var i = 0, len = other.length; i < len; i++) {
  476. ret.push(other[i]);
  477. }
  478. return ret;
  479. }
  480. }
  481. private _validate(): void {
  482. if (!this.positions) {
  483. throw new Error("Positions are required");
  484. }
  485. const getElementCount = (kind: string, values: FloatArray) => {
  486. const stride = VertexBuffer.DeduceStride(kind);
  487. if ((values.length % stride) !== 0) {
  488. throw new Error("The " + kind + "s array count must be a multiple of " + stride);
  489. }
  490. return values.length / stride;
  491. };
  492. const positionsElementCount = getElementCount(VertexBuffer.PositionKind, this.positions);
  493. const validateElementCount = (kind: string, values: FloatArray) => {
  494. const elementCount = getElementCount(kind, values);
  495. if (elementCount !== positionsElementCount) {
  496. throw new Error("The " + kind + "s element count (" + elementCount + ") does not match the positions count (" + positionsElementCount + ")");
  497. }
  498. };
  499. if (this.normals) { validateElementCount(VertexBuffer.NormalKind, this.normals); }
  500. if (this.tangents) { validateElementCount(VertexBuffer.TangentKind, this.tangents); }
  501. if (this.uvs) { validateElementCount(VertexBuffer.UVKind, this.uvs); }
  502. if (this.uvs2) { validateElementCount(VertexBuffer.UV2Kind, this.uvs2); }
  503. if (this.uvs3) { validateElementCount(VertexBuffer.UV3Kind, this.uvs3); }
  504. if (this.uvs4) { validateElementCount(VertexBuffer.UV4Kind, this.uvs4); }
  505. if (this.uvs5) { validateElementCount(VertexBuffer.UV5Kind, this.uvs5); }
  506. if (this.uvs6) { validateElementCount(VertexBuffer.UV6Kind, this.uvs6); }
  507. if (this.colors) { validateElementCount(VertexBuffer.ColorKind, this.colors); }
  508. if (this.matricesIndices) { validateElementCount(VertexBuffer.MatricesIndicesKind, this.matricesIndices); }
  509. if (this.matricesWeights) { validateElementCount(VertexBuffer.MatricesWeightsKind, this.matricesWeights); }
  510. if (this.matricesIndicesExtra) { validateElementCount(VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra); }
  511. if (this.matricesWeightsExtra) { validateElementCount(VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra); }
  512. }
  513. /**
  514. * Serializes the VertexData
  515. * @returns a serialized object
  516. */
  517. public serialize(): any {
  518. var serializationObject = this.serialize();
  519. if (this.positions) {
  520. serializationObject.positions = this.positions;
  521. }
  522. if (this.normals) {
  523. serializationObject.normals = this.normals;
  524. }
  525. if (this.tangents) {
  526. serializationObject.tangents = this.tangents;
  527. }
  528. if (this.uvs) {
  529. serializationObject.uvs = this.uvs;
  530. }
  531. if (this.uvs2) {
  532. serializationObject.uvs2 = this.uvs2;
  533. }
  534. if (this.uvs3) {
  535. serializationObject.uvs3 = this.uvs3;
  536. }
  537. if (this.uvs4) {
  538. serializationObject.uvs4 = this.uvs4;
  539. }
  540. if (this.uvs5) {
  541. serializationObject.uvs5 = this.uvs5;
  542. }
  543. if (this.uvs6) {
  544. serializationObject.uvs6 = this.uvs6;
  545. }
  546. if (this.colors) {
  547. serializationObject.colors = this.colors;
  548. }
  549. if (this.matricesIndices) {
  550. serializationObject.matricesIndices = this.matricesIndices;
  551. serializationObject.matricesIndices._isExpanded = true;
  552. }
  553. if (this.matricesWeights) {
  554. serializationObject.matricesWeights = this.matricesWeights;
  555. }
  556. if (this.matricesIndicesExtra) {
  557. serializationObject.matricesIndicesExtra = this.matricesIndicesExtra;
  558. serializationObject.matricesIndicesExtra._isExpanded = true;
  559. }
  560. if (this.matricesWeightsExtra) {
  561. serializationObject.matricesWeightsExtra = this.matricesWeightsExtra;
  562. }
  563. serializationObject.indices = this.indices;
  564. return serializationObject;
  565. }
  566. // Statics
  567. /**
  568. * Extracts the vertexData from a mesh
  569. * @param mesh the mesh from which to extract the VertexData
  570. * @param copyWhenShared defines if the VertexData must be cloned when shared between multiple meshes, optional, default false
  571. * @param forceCopy indicating that the VertexData must be cloned, optional, default false
  572. * @returns the object VertexData associated to the passed mesh
  573. */
  574. public static ExtractFromMesh(mesh: Mesh, copyWhenShared?: boolean, forceCopy?: boolean): VertexData {
  575. return VertexData._ExtractFrom(mesh, copyWhenShared, forceCopy);
  576. }
  577. /**
  578. * Extracts the vertexData from the geometry
  579. * @param geometry the geometry from which to extract the VertexData
  580. * @param copyWhenShared defines if the VertexData must be cloned when the geometrty is shared between multiple meshes, optional, default false
  581. * @param forceCopy indicating that the VertexData must be cloned, optional, default false
  582. * @returns the object VertexData associated to the passed mesh
  583. */
  584. public static ExtractFromGeometry(geometry: Geometry, copyWhenShared?: boolean, forceCopy?: boolean): VertexData {
  585. return VertexData._ExtractFrom(geometry, copyWhenShared, forceCopy);
  586. }
  587. private static _ExtractFrom(meshOrGeometry: IGetSetVerticesData, copyWhenShared?: boolean, forceCopy?: boolean): VertexData {
  588. var result = new VertexData();
  589. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.PositionKind)) {
  590. result.positions = meshOrGeometry.getVerticesData(VertexBuffer.PositionKind, copyWhenShared, forceCopy);
  591. }
  592. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.NormalKind)) {
  593. result.normals = meshOrGeometry.getVerticesData(VertexBuffer.NormalKind, copyWhenShared, forceCopy);
  594. }
  595. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.TangentKind)) {
  596. result.tangents = meshOrGeometry.getVerticesData(VertexBuffer.TangentKind, copyWhenShared, forceCopy);
  597. }
  598. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UVKind)) {
  599. result.uvs = meshOrGeometry.getVerticesData(VertexBuffer.UVKind, copyWhenShared, forceCopy);
  600. }
  601. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
  602. result.uvs2 = meshOrGeometry.getVerticesData(VertexBuffer.UV2Kind, copyWhenShared, forceCopy);
  603. }
  604. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UV3Kind)) {
  605. result.uvs3 = meshOrGeometry.getVerticesData(VertexBuffer.UV3Kind, copyWhenShared, forceCopy);
  606. }
  607. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UV4Kind)) {
  608. result.uvs4 = meshOrGeometry.getVerticesData(VertexBuffer.UV4Kind, copyWhenShared, forceCopy);
  609. }
  610. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UV5Kind)) {
  611. result.uvs5 = meshOrGeometry.getVerticesData(VertexBuffer.UV5Kind, copyWhenShared, forceCopy);
  612. }
  613. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.UV6Kind)) {
  614. result.uvs6 = meshOrGeometry.getVerticesData(VertexBuffer.UV6Kind, copyWhenShared, forceCopy);
  615. }
  616. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.ColorKind)) {
  617. result.colors = meshOrGeometry.getVerticesData(VertexBuffer.ColorKind, copyWhenShared, forceCopy);
  618. }
  619. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesIndicesKind)) {
  620. result.matricesIndices = meshOrGeometry.getVerticesData(VertexBuffer.MatricesIndicesKind, copyWhenShared, forceCopy);
  621. }
  622. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesWeightsKind)) {
  623. result.matricesWeights = meshOrGeometry.getVerticesData(VertexBuffer.MatricesWeightsKind, copyWhenShared, forceCopy);
  624. }
  625. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesIndicesExtraKind)) {
  626. result.matricesIndicesExtra = meshOrGeometry.getVerticesData(VertexBuffer.MatricesIndicesExtraKind, copyWhenShared, forceCopy);
  627. }
  628. if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesWeightsExtraKind)) {
  629. result.matricesWeightsExtra = meshOrGeometry.getVerticesData(VertexBuffer.MatricesWeightsExtraKind, copyWhenShared, forceCopy);
  630. }
  631. result.indices = meshOrGeometry.getIndices(copyWhenShared, forceCopy);
  632. return result;
  633. }
  634. /**
  635. * Creates the VertexData for a Ribbon
  636. * @param options an object used to set the following optional parameters for the ribbon, required but can be empty
  637. * * pathArray array of paths, each of which an array of successive Vector3
  638. * * closeArray creates a seam between the first and the last paths of the pathArray, optional, default false
  639. * * closePath creates a seam between the first and the last points of each path of the path array, optional, default false
  640. * * offset a positive integer, only used when pathArray contains a single path (offset = 10 means the point 1 is joined to the point 11), default rounded half size of the pathArray length
  641. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  642. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  643. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  644. * * invertUV swaps in the U and V coordinates when applying a texture, optional, default false
  645. * * uvs a linear array, of length 2 * number of vertices, of custom UV values, optional
  646. * * colors a linear array, of length 4 * number of vertices, of custom color values, optional
  647. * @returns the VertexData of the ribbon
  648. */
  649. public static CreateRibbon(options: { pathArray: Vector3[][], closeArray?: boolean, closePath?: boolean, offset?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, invertUV?: boolean, uvs?: Vector2[], colors?: Color4[] }): VertexData {
  650. throw _DevTools.WarnImport("ribbonBuilder");
  651. }
  652. /**
  653. * Creates the VertexData for a box
  654. * @param options an object used to set the following optional parameters for the box, required but can be empty
  655. * * size sets the width, height and depth of the box to the value of size, optional default 1
  656. * * width sets the width (x direction) of the box, overwrites the width set by size, optional, default size
  657. * * height sets the height (y direction) of the box, overwrites the height set by size, optional, default size
  658. * * depth sets the depth (z direction) of the box, overwrites the depth set by size, optional, default size
  659. * * faceUV an array of 6 Vector4 elements used to set different images to each box side
  660. * * faceColors an array of 6 Color3 elements used to set different colors to each box side
  661. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  662. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  663. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  664. * @returns the VertexData of the box
  665. */
  666. public static CreateBox(options: { size?: number, width?: number, height?: number, depth?: number, faceUV?: Vector4[], faceColors?: Color4[], sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
  667. throw _DevTools.WarnImport("boxBuilder");
  668. }
  669. /**
  670. * Creates the VertexData for a tiled box
  671. * @param options an object used to set the following optional parameters for the box, required but can be empty
  672. * * faceTiles sets the pattern, tile size and number of tiles for a face
  673. * * faceUV an array of 6 Vector4 elements used to set different images to each box side
  674. * * faceColors an array of 6 Color3 elements used to set different colors to each box side
  675. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  676. * @returns the VertexData of the box
  677. */
  678. public static CreateTiledBox(options: { pattern?: number, width?: number, height?: number, depth?: number, tileSize?: number, tileWidth?: number, tileHeight?: number, alignHorizontal?: number, alignVertical?: number, faceUV?: Vector4[], faceColors?: Color4[], sideOrientation?: number }): VertexData {
  679. throw _DevTools.WarnImport("tiledBoxBuilder");
  680. }
  681. /**
  682. * Creates the VertexData for a tiled plane
  683. * @param options an object used to set the following optional parameters for the box, required but can be empty
  684. * * pattern a limited pattern arrangement depending on the number
  685. * * tileSize sets the width, height and depth of the tile to the value of size, optional default 1
  686. * * tileWidth sets the width (x direction) of the tile, overwrites the width set by size, optional, default size
  687. * * tileHeight sets the height (y direction) of the tile, overwrites the height set by size, optional, default size
  688. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  689. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  690. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  691. * @returns the VertexData of the tiled plane
  692. */
  693. public static CreateTiledPlane(options: { pattern?: number, tileSize?: number, tileWidth?: number, tileHeight?: number, size?: number, width?: number, height?: number, alignHorizontal?: number, alignVertical?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
  694. throw _DevTools.WarnImport("tiledPlaneBuilder");
  695. }
  696. /**
  697. * Creates the VertexData for an ellipsoid, defaults to a sphere
  698. * @param options an object used to set the following optional parameters for the box, required but can be empty
  699. * * segments sets the number of horizontal strips optional, default 32
  700. * * diameter sets the axes dimensions, diameterX, diameterY and diameterZ to the value of diameter, optional default 1
  701. * * diameterX sets the diameterX (x direction) of the ellipsoid, overwrites the diameterX set by diameter, optional, default diameter
  702. * * diameterY sets the diameterY (y direction) of the ellipsoid, overwrites the diameterY set by diameter, optional, default diameter
  703. * * diameterZ sets the diameterZ (z direction) of the ellipsoid, overwrites the diameterZ set by diameter, optional, default diameter
  704. * * arc a number from 0 to 1, to create an unclosed ellipsoid based on the fraction of the circumference (latitude) given by the arc value, optional, default 1
  705. * * slice a number from 0 to 1, to create an unclosed ellipsoid based on the fraction of the height (latitude) given by the arc value, optional, default 1
  706. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  707. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  708. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  709. * @returns the VertexData of the ellipsoid
  710. */
  711. public static CreateSphere(options: { segments?: number, diameter?: number, diameterX?: number, diameterY?: number, diameterZ?: number, arc?: number, slice?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
  712. throw _DevTools.WarnImport("sphereBuilder");
  713. }
  714. /**
  715. * Creates the VertexData for a cylinder, cone or prism
  716. * @param options an object used to set the following optional parameters for the box, required but can be empty
  717. * * height sets the height (y direction) of the cylinder, optional, default 2
  718. * * diameterTop sets the diameter of the top of the cone, overwrites diameter, optional, default diameter
  719. * * diameterBottom sets the diameter of the bottom of the cone, overwrites diameter, optional, default diameter
  720. * * diameter sets the diameter of the top and bottom of the cone, optional default 1
  721. * * tessellation the number of prism sides, 3 for a triangular prism, optional, default 24
  722. * * subdivisions` the number of rings along the cylinder height, optional, default 1
  723. * * arc a number from 0 to 1, to create an unclosed cylinder based on the fraction of the circumference given by the arc value, optional, default 1
  724. * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively
  725. * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively
  726. * * hasRings when true makes each subdivision independantly treated as a face for faceUV and faceColors, optional, default false
  727. * * enclose when true closes an open cylinder by adding extra flat faces between the height axis and vertical edges, think cut cake
  728. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  729. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  730. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  731. * @returns the VertexData of the cylinder, cone or prism
  732. */
  733. public static CreateCylinder(options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], hasRings?: boolean, enclose?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
  734. throw _DevTools.WarnImport("cylinderBuilder");
  735. }
  736. /**
  737. * Creates the VertexData for a torus
  738. * @param options an object used to set the following optional parameters for the box, required but can be empty
  739. * * diameter the diameter of the torus, optional default 1
  740. * * thickness the diameter of the tube forming the torus, optional default 0.5
  741. * * tessellation the number of prism sides, 3 for a triangular prism, optional, default 24
  742. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  743. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  744. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  745. * @returns the VertexData of the torus
  746. */
  747. public static CreateTorus(options: { diameter?: number, thickness?: number, tessellation?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
  748. throw _DevTools.WarnImport("torusBuilder");
  749. }
  750. /**
  751. * Creates the VertexData of the LineSystem
  752. * @param options an object used to set the following optional parameters for the LineSystem, required but can be empty
  753. * - lines an array of lines, each line being an array of successive Vector3
  754. * - colors an array of line colors, each of the line colors being an array of successive Color4, one per line point
  755. * @returns the VertexData of the LineSystem
  756. */
  757. public static CreateLineSystem(options: { lines: Vector3[][], colors?: Nullable<Color4[][]> }): VertexData {
  758. throw _DevTools.WarnImport("linesBuilder");
  759. }
  760. /**
  761. * Create the VertexData for a DashedLines
  762. * @param options an object used to set the following optional parameters for the DashedLines, required but can be empty
  763. * - points an array successive Vector3
  764. * - dashSize the size of the dashes relative to the dash number, optional, default 3
  765. * - gapSize the size of the gap between two successive dashes relative to the dash number, optional, default 1
  766. * - dashNb the intended total number of dashes, optional, default 200
  767. * @returns the VertexData for the DashedLines
  768. */
  769. public static CreateDashedLines(options: { points: Vector3[], dashSize?: number, gapSize?: number, dashNb?: number }): VertexData {
  770. throw _DevTools.WarnImport("linesBuilder");
  771. }
  772. /**
  773. * Creates the VertexData for a Ground
  774. * @param options an object used to set the following optional parameters for the Ground, required but can be empty
  775. * - width the width (x direction) of the ground, optional, default 1
  776. * - height the height (z direction) of the ground, optional, default 1
  777. * - subdivisions the number of subdivisions per side, optional, default 1
  778. * @returns the VertexData of the Ground
  779. */
  780. public static CreateGround(options: { width?: number, height?: number, subdivisions?: number, subdivisionsX?: number, subdivisionsY?: number }): VertexData {
  781. throw _DevTools.WarnImport("groundBuilder");
  782. }
  783. /**
  784. * Creates the VertexData for a TiledGround by subdividing the ground into tiles
  785. * @param options an object used to set the following optional parameters for the Ground, required but can be empty
  786. * * xmin the ground minimum X coordinate, optional, default -1
  787. * * zmin the ground minimum Z coordinate, optional, default -1
  788. * * xmax the ground maximum X coordinate, optional, default 1
  789. * * zmax the ground maximum Z coordinate, optional, default 1
  790. * * subdivisions a javascript object {w: positive integer, h: positive integer}, `w` and `h` are the numbers of subdivisions on the ground width and height creating 'tiles', default {w: 6, h: 6}
  791. * * precision a javascript object {w: positive integer, h: positive integer}, `w` and `h` are the numbers of subdivisions on the tile width and height, default {w: 2, h: 2}
  792. * @returns the VertexData of the TiledGround
  793. */
  794. public static CreateTiledGround(options: { xmin: number, zmin: number, xmax: number, zmax: number, subdivisions?: { w: number; h: number; }, precision?: { w: number; h: number; } }): VertexData {
  795. throw _DevTools.WarnImport("groundBuilder");
  796. }
  797. /**
  798. * Creates the VertexData of the Ground designed from a heightmap
  799. * @param options an object used to set the following parameters for the Ground, required and provided by MeshBuilder.CreateGroundFromHeightMap
  800. * * width the width (x direction) of the ground
  801. * * height the height (z direction) of the ground
  802. * * subdivisions the number of subdivisions per side
  803. * * minHeight the minimum altitude on the ground, optional, default 0
  804. * * maxHeight the maximum altitude on the ground, optional default 1
  805. * * colorFilter the filter to apply to the image pixel colors to compute the height, optional Color3, default (0.3, 0.59, 0.11)
  806. * * buffer the array holding the image color data
  807. * * bufferWidth the width of image
  808. * * bufferHeight the height of image
  809. * * alphaFilter Remove any data where the alpha channel is below this value, defaults 0 (all data visible)
  810. * @returns the VertexData of the Ground designed from a heightmap
  811. */
  812. public static CreateGroundFromHeightMap(options: { width: number, height: number, subdivisions: number, minHeight: number, maxHeight: number, colorFilter: Color3, buffer: Uint8Array, bufferWidth: number, bufferHeight: number, alphaFilter: number }): VertexData {
  813. throw _DevTools.WarnImport("groundBuilder");
  814. }
  815. /**
  816. * Creates the VertexData for a Plane
  817. * @param options an object used to set the following optional parameters for the plane, required but can be empty
  818. * * size sets the width and height of the plane to the value of size, optional default 1
  819. * * width sets the width (x direction) of the plane, overwrites the width set by size, optional, default size
  820. * * height sets the height (y direction) of the plane, overwrites the height set by size, optional, default size
  821. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  822. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  823. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  824. * @returns the VertexData of the box
  825. */
  826. public static CreatePlane(options: { size?: number, width?: number, height?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
  827. throw _DevTools.WarnImport("planeBuilder");
  828. }
  829. /**
  830. * Creates the VertexData of the Disc or regular Polygon
  831. * @param options an object used to set the following optional parameters for the disc, required but can be empty
  832. * * radius the radius of the disc, optional default 0.5
  833. * * tessellation the number of polygon sides, optional, default 64
  834. * * arc a number from 0 to 1, to create an unclosed polygon based on the fraction of the circumference given by the arc value, optional, default 1
  835. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  836. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  837. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  838. * @returns the VertexData of the box
  839. */
  840. public static CreateDisc(options: { radius?: number, tessellation?: number, arc?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
  841. throw _DevTools.WarnImport("discBuilder");
  842. }
  843. /**
  844. * Creates the VertexData for an irregular Polygon in the XoZ plane using a mesh built by polygonTriangulation.build()
  845. * All parameters are provided by MeshBuilder.CreatePolygon as needed
  846. * @param polygon a mesh built from polygonTriangulation.build()
  847. * @param sideOrientation takes the values Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  848. * @param fUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively
  849. * @param fColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively
  850. * @param frontUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  851. * @param backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  852. * @param wrap a boolean, default false, when true and fUVs used texture is wrapped around all sides, when false texture is applied side
  853. * @returns the VertexData of the Polygon
  854. */
  855. public static CreatePolygon(polygon: Mesh, sideOrientation: number, fUV?: Vector4[], fColors?: Color4[], frontUVs?: Vector4, backUVs?: Vector4, wrap?: boolean): VertexData {
  856. throw _DevTools.WarnImport("polygonBuilder");
  857. }
  858. /**
  859. * Creates the VertexData of the IcoSphere
  860. * @param options an object used to set the following optional parameters for the IcoSphere, required but can be empty
  861. * * radius the radius of the IcoSphere, optional default 1
  862. * * radiusX allows stretching in the x direction, optional, default radius
  863. * * radiusY allows stretching in the y direction, optional, default radius
  864. * * radiusZ allows stretching in the z direction, optional, default radius
  865. * * flat when true creates a flat shaded mesh, optional, default true
  866. * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4
  867. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  868. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  869. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  870. * @returns the VertexData of the IcoSphere
  871. */
  872. public static CreateIcoSphere(options: { radius?: number, radiusX?: number, radiusY?: number, radiusZ?: number, flat?: boolean, subdivisions?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
  873. throw _DevTools.WarnImport("icoSphereBuilder");
  874. }
  875. // inspired from // http://stemkoski.github.io/Three.js/Polyhedra.html
  876. /**
  877. * Creates the VertexData for a Polyhedron
  878. * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty
  879. * * type provided types are:
  880. * * 0 : Tetrahedron, 1 : Octahedron, 2 : Dodecahedron, 3 : Icosahedron, 4 : Rhombicuboctahedron, 5 : Triangular Prism, 6 : Pentagonal Prism, 7 : Hexagonal Prism, 8 : Square Pyramid (J1)
  881. * * 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)
  882. * * size the size of the IcoSphere, optional default 1
  883. * * sizeX allows stretching in the x direction, optional, default size
  884. * * sizeY allows stretching in the y direction, optional, default size
  885. * * sizeZ allows stretching in the z direction, optional, default size
  886. * * custom a number that overwrites the type to create from an extended set of polyhedron from https://www.babylonjs-playground.com/#21QRSK#15 with minimised editor
  887. * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively
  888. * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively
  889. * * flat when true creates a flat shaded mesh, optional, default true
  890. * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4
  891. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  892. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  893. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  894. * @returns the VertexData of the Polyhedron
  895. */
  896. public static CreatePolyhedron(options: { type?: number, size?: number, sizeX?: number, sizeY?: number, sizeZ?: number, custom?: any, faceUV?: Vector4[], faceColors?: Color4[], flat?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
  897. throw _DevTools.WarnImport("polyhedronBuilder");
  898. }
  899. // based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
  900. /**
  901. * Creates the VertexData for a TorusKnot
  902. * @param options an object used to set the following optional parameters for the TorusKnot, required but can be empty
  903. * * radius the radius of the torus knot, optional, default 2
  904. * * tube the thickness of the tube, optional, default 0.5
  905. * * radialSegments the number of sides on each tube segments, optional, default 32
  906. * * tubularSegments the number of tubes to decompose the knot into, optional, default 32
  907. * * p the number of windings around the z axis, optional, default 2
  908. * * q the number of windings around the x axis, optional, default 3
  909. * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
  910. * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
  911. * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
  912. * @returns the VertexData of the Torus Knot
  913. */
  914. public static CreateTorusKnot(options: { radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, p?: number, q?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
  915. throw _DevTools.WarnImport("torusKnotBuilder");
  916. }
  917. // Tools
  918. /**
  919. * Compute normals for given positions and indices
  920. * @param positions an array of vertex positions, [...., x, y, z, ......]
  921. * @param indices an array of indices in groups of three for each triangular facet, [...., i, j, k, ......]
  922. * @param normals an array of vertex normals, [...., x, y, z, ......]
  923. * @param options an object used to set the following optional parameters for the TorusKnot, optional
  924. * * facetNormals : optional array of facet normals (vector3)
  925. * * facetPositions : optional array of facet positions (vector3)
  926. * * facetPartitioning : optional partitioning array. facetPositions is required for facetPartitioning computation
  927. * * ratio : optional partitioning ratio / bounding box, required for facetPartitioning computation
  928. * * bInfo : optional bounding info, required for facetPartitioning computation
  929. * * bbSize : optional bounding box size data, required for facetPartitioning computation
  930. * * subDiv : optional partitioning data about subdivsions on each axis (int), required for facetPartitioning computation
  931. * * useRightHandedSystem: optional boolean to for right handed system computation
  932. * * depthSort : optional boolean to enable the facet depth sort computation
  933. * * distanceTo : optional Vector3 to compute the facet depth from this location
  934. * * depthSortedFacets : optional array of depthSortedFacets to store the facet distances from the reference location
  935. */
  936. public static ComputeNormals(positions: any, indices: any, normals: any,
  937. options?: {
  938. facetNormals?: any, facetPositions?: any, facetPartitioning?: any, ratio?: number, bInfo?: any, bbSize?: Vector3, subDiv?: any,
  939. useRightHandedSystem?: boolean, depthSort?: boolean, distanceTo?: Vector3, depthSortedFacets?: any
  940. }): void {
  941. // temporary scalar variables
  942. var index = 0; // facet index
  943. var p1p2x = 0.0; // p1p2 vector x coordinate
  944. var p1p2y = 0.0; // p1p2 vector y coordinate
  945. var p1p2z = 0.0; // p1p2 vector z coordinate
  946. var p3p2x = 0.0; // p3p2 vector x coordinate
  947. var p3p2y = 0.0; // p3p2 vector y coordinate
  948. var p3p2z = 0.0; // p3p2 vector z coordinate
  949. var faceNormalx = 0.0; // facet normal x coordinate
  950. var faceNormaly = 0.0; // facet normal y coordinate
  951. var faceNormalz = 0.0; // facet normal z coordinate
  952. var length = 0.0; // facet normal length before normalization
  953. var v1x = 0; // vector1 x index in the positions array
  954. var v1y = 0; // vector1 y index in the positions array
  955. var v1z = 0; // vector1 z index in the positions array
  956. var v2x = 0; // vector2 x index in the positions array
  957. var v2y = 0; // vector2 y index in the positions array
  958. var v2z = 0; // vector2 z index in the positions array
  959. var v3x = 0; // vector3 x index in the positions array
  960. var v3y = 0; // vector3 y index in the positions array
  961. var v3z = 0; // vector3 z index in the positions array
  962. var computeFacetNormals = false;
  963. var computeFacetPositions = false;
  964. var computeFacetPartitioning = false;
  965. var computeDepthSort = false;
  966. var faceNormalSign = 1;
  967. let ratio = 0;
  968. var distanceTo: Nullable<Vector3> = null;
  969. if (options) {
  970. computeFacetNormals = (options.facetNormals) ? true : false;
  971. computeFacetPositions = (options.facetPositions) ? true : false;
  972. computeFacetPartitioning = (options.facetPartitioning) ? true : false;
  973. faceNormalSign = (options.useRightHandedSystem === true) ? -1 : 1;
  974. ratio = options.ratio || 0;
  975. computeDepthSort = (options.depthSort) ? true : false;
  976. distanceTo = <Vector3>(options.distanceTo);
  977. if (computeDepthSort) {
  978. if (distanceTo === undefined) {
  979. distanceTo = Vector3.Zero();
  980. }
  981. var depthSortedFacets = options.depthSortedFacets;
  982. }
  983. }
  984. // facetPartitioning reinit if needed
  985. let xSubRatio = 0;
  986. let ySubRatio = 0;
  987. let zSubRatio = 0;
  988. let subSq = 0;
  989. if (computeFacetPartitioning && options && options.bbSize) {
  990. var ox = 0; // X partitioning index for facet position
  991. var oy = 0; // Y partinioning index for facet position
  992. var oz = 0; // Z partinioning index for facet position
  993. var b1x = 0; // X partitioning index for facet v1 vertex
  994. var b1y = 0; // Y partitioning index for facet v1 vertex
  995. var b1z = 0; // z partitioning index for facet v1 vertex
  996. var b2x = 0; // X partitioning index for facet v2 vertex
  997. var b2y = 0; // Y partitioning index for facet v2 vertex
  998. var b2z = 0; // Z partitioning index for facet v2 vertex
  999. var b3x = 0; // X partitioning index for facet v3 vertex
  1000. var b3y = 0; // Y partitioning index for facet v3 vertex
  1001. var b3z = 0; // Z partitioning index for facet v3 vertex
  1002. var block_idx_o = 0; // facet barycenter block index
  1003. var block_idx_v1 = 0; // v1 vertex block index
  1004. var block_idx_v2 = 0; // v2 vertex block index
  1005. var block_idx_v3 = 0; // v3 vertex block index
  1006. var bbSizeMax = (options.bbSize.x > options.bbSize.y) ? options.bbSize.x : options.bbSize.y;
  1007. bbSizeMax = (bbSizeMax > options.bbSize.z) ? bbSizeMax : options.bbSize.z;
  1008. xSubRatio = options.subDiv.X * ratio / options.bbSize.x;
  1009. ySubRatio = options.subDiv.Y * ratio / options.bbSize.y;
  1010. zSubRatio = options.subDiv.Z * ratio / options.bbSize.z;
  1011. subSq = options.subDiv.max * options.subDiv.max;
  1012. options.facetPartitioning.length = 0;
  1013. }
  1014. // reset the normals
  1015. for (index = 0; index < positions.length; index++) {
  1016. normals[index] = 0.0;
  1017. }
  1018. // Loop : 1 indice triplet = 1 facet
  1019. var nbFaces = (indices.length / 3) | 0;
  1020. for (index = 0; index < nbFaces; index++) {
  1021. // get the indexes of the coordinates of each vertex of the facet
  1022. v1x = indices[index * 3] * 3;
  1023. v1y = v1x + 1;
  1024. v1z = v1x + 2;
  1025. v2x = indices[index * 3 + 1] * 3;
  1026. v2y = v2x + 1;
  1027. v2z = v2x + 2;
  1028. v3x = indices[index * 3 + 2] * 3;
  1029. v3y = v3x + 1;
  1030. v3z = v3x + 2;
  1031. p1p2x = positions[v1x] - positions[v2x]; // compute two vectors per facet : p1p2 and p3p2
  1032. p1p2y = positions[v1y] - positions[v2y];
  1033. p1p2z = positions[v1z] - positions[v2z];
  1034. p3p2x = positions[v3x] - positions[v2x];
  1035. p3p2y = positions[v3y] - positions[v2y];
  1036. p3p2z = positions[v3z] - positions[v2z];
  1037. // compute the face normal with the cross product
  1038. faceNormalx = faceNormalSign * (p1p2y * p3p2z - p1p2z * p3p2y);
  1039. faceNormaly = faceNormalSign * (p1p2z * p3p2x - p1p2x * p3p2z);
  1040. faceNormalz = faceNormalSign * (p1p2x * p3p2y - p1p2y * p3p2x);
  1041. // normalize this normal and store it in the array facetData
  1042. length = Math.sqrt(faceNormalx * faceNormalx + faceNormaly * faceNormaly + faceNormalz * faceNormalz);
  1043. length = (length === 0) ? 1.0 : length;
  1044. faceNormalx /= length;
  1045. faceNormaly /= length;
  1046. faceNormalz /= length;
  1047. if (computeFacetNormals && options) {
  1048. options.facetNormals[index].x = faceNormalx;
  1049. options.facetNormals[index].y = faceNormaly;
  1050. options.facetNormals[index].z = faceNormalz;
  1051. }
  1052. if (computeFacetPositions && options) {
  1053. // compute and the facet barycenter coordinates in the array facetPositions
  1054. options.facetPositions[index].x = (positions[v1x] + positions[v2x] + positions[v3x]) / 3.0;
  1055. options.facetPositions[index].y = (positions[v1y] + positions[v2y] + positions[v3y]) / 3.0;
  1056. options.facetPositions[index].z = (positions[v1z] + positions[v2z] + positions[v3z]) / 3.0;
  1057. }
  1058. if (computeFacetPartitioning && options) {
  1059. // store the facet indexes in arrays in the main facetPartitioning array :
  1060. // compute each facet vertex (+ facet barycenter) index in the partiniong array
  1061. ox = Math.floor((options.facetPositions[index].x - options.bInfo.minimum.x * ratio) * xSubRatio);
  1062. oy = Math.floor((options.facetPositions[index].y - options.bInfo.minimum.y * ratio) * ySubRatio);
  1063. oz = Math.floor((options.facetPositions[index].z - options.bInfo.minimum.z * ratio) * zSubRatio);
  1064. b1x = Math.floor((positions[v1x] - options.bInfo.minimum.x * ratio) * xSubRatio);
  1065. b1y = Math.floor((positions[v1y] - options.bInfo.minimum.y * ratio) * ySubRatio);
  1066. b1z = Math.floor((positions[v1z] - options.bInfo.minimum.z * ratio) * zSubRatio);
  1067. b2x = Math.floor((positions[v2x] - options.bInfo.minimum.x * ratio) * xSubRatio);
  1068. b2y = Math.floor((positions[v2y] - options.bInfo.minimum.y * ratio) * ySubRatio);
  1069. b2z = Math.floor((positions[v2z] - options.bInfo.minimum.z * ratio) * zSubRatio);
  1070. b3x = Math.floor((positions[v3x] - options.bInfo.minimum.x * ratio) * xSubRatio);
  1071. b3y = Math.floor((positions[v3y] - options.bInfo.minimum.y * ratio) * ySubRatio);
  1072. b3z = Math.floor((positions[v3z] - options.bInfo.minimum.z * ratio) * zSubRatio);
  1073. block_idx_v1 = b1x + options.subDiv.max * b1y + subSq * b1z;
  1074. block_idx_v2 = b2x + options.subDiv.max * b2y + subSq * b2z;
  1075. block_idx_v3 = b3x + options.subDiv.max * b3y + subSq * b3z;
  1076. block_idx_o = ox + options.subDiv.max * oy + subSq * oz;
  1077. options.facetPartitioning[block_idx_o] = options.facetPartitioning[block_idx_o] ? options.facetPartitioning[block_idx_o] : new Array();
  1078. options.facetPartitioning[block_idx_v1] = options.facetPartitioning[block_idx_v1] ? options.facetPartitioning[block_idx_v1] : new Array();
  1079. options.facetPartitioning[block_idx_v2] = options.facetPartitioning[block_idx_v2] ? options.facetPartitioning[block_idx_v2] : new Array();
  1080. options.facetPartitioning[block_idx_v3] = options.facetPartitioning[block_idx_v3] ? options.facetPartitioning[block_idx_v3] : new Array();
  1081. // push each facet index in each block containing the vertex
  1082. options.facetPartitioning[block_idx_v1].push(index);
  1083. if (block_idx_v2 != block_idx_v1) {
  1084. options.facetPartitioning[block_idx_v2].push(index);
  1085. }
  1086. if (!(block_idx_v3 == block_idx_v2 || block_idx_v3 == block_idx_v1)) {
  1087. options.facetPartitioning[block_idx_v3].push(index);
  1088. }
  1089. if (!(block_idx_o == block_idx_v1 || block_idx_o == block_idx_v2 || block_idx_o == block_idx_v3)) {
  1090. options.facetPartitioning[block_idx_o].push(index);
  1091. }
  1092. }
  1093. if (computeDepthSort && options && options.facetPositions) {
  1094. var dsf = depthSortedFacets[index];
  1095. dsf.ind = index * 3;
  1096. dsf.sqDistance = Vector3.DistanceSquared(options.facetPositions[index], distanceTo!);
  1097. }
  1098. // compute the normals anyway
  1099. normals[v1x] += faceNormalx; // accumulate all the normals per face
  1100. normals[v1y] += faceNormaly;
  1101. normals[v1z] += faceNormalz;
  1102. normals[v2x] += faceNormalx;
  1103. normals[v2y] += faceNormaly;
  1104. normals[v2z] += faceNormalz;
  1105. normals[v3x] += faceNormalx;
  1106. normals[v3y] += faceNormaly;
  1107. normals[v3z] += faceNormalz;
  1108. }
  1109. // last normalization of each normal
  1110. for (index = 0; index < normals.length / 3; index++) {
  1111. faceNormalx = normals[index * 3];
  1112. faceNormaly = normals[index * 3 + 1];
  1113. faceNormalz = normals[index * 3 + 2];
  1114. length = Math.sqrt(faceNormalx * faceNormalx + faceNormaly * faceNormaly + faceNormalz * faceNormalz);
  1115. length = (length === 0) ? 1.0 : length;
  1116. faceNormalx /= length;
  1117. faceNormaly /= length;
  1118. faceNormalz /= length;
  1119. normals[index * 3] = faceNormalx;
  1120. normals[index * 3 + 1] = faceNormaly;
  1121. normals[index * 3 + 2] = faceNormalz;
  1122. }
  1123. }
  1124. /** @hidden */
  1125. public static _ComputeSides(sideOrientation: number, positions: FloatArray, indices: FloatArray, normals: FloatArray, uvs: FloatArray, frontUVs?: Vector4, backUVs?: Vector4) {
  1126. var li: number = indices.length;
  1127. var ln: number = normals.length;
  1128. var i: number;
  1129. var n: number;
  1130. sideOrientation = sideOrientation || VertexData.DEFAULTSIDE;
  1131. switch (sideOrientation) {
  1132. case VertexData.FRONTSIDE:
  1133. // nothing changed
  1134. break;
  1135. case VertexData.BACKSIDE:
  1136. var tmp: number;
  1137. // indices
  1138. for (i = 0; i < li; i += 3) {
  1139. tmp = indices[i];
  1140. indices[i] = indices[i + 2];
  1141. indices[i + 2] = tmp;
  1142. }
  1143. // normals
  1144. for (n = 0; n < ln; n++) {
  1145. normals[n] = -normals[n];
  1146. }
  1147. break;
  1148. case VertexData.DOUBLESIDE:
  1149. // positions
  1150. var lp: number = positions.length;
  1151. var l: number = lp / 3;
  1152. for (var p = 0; p < lp; p++) {
  1153. positions[lp + p] = positions[p];
  1154. }
  1155. // indices
  1156. for (i = 0; i < li; i += 3) {
  1157. indices[i + li] = indices[i + 2] + l;
  1158. indices[i + 1 + li] = indices[i + 1] + l;
  1159. indices[i + 2 + li] = indices[i] + l;
  1160. }
  1161. // normals
  1162. for (n = 0; n < ln; n++) {
  1163. normals[ln + n] = -normals[n];
  1164. }
  1165. // uvs
  1166. var lu: number = uvs.length;
  1167. var u: number = 0;
  1168. for (u = 0; u < lu; u++) {
  1169. uvs[u + lu] = uvs[u];
  1170. }
  1171. frontUVs = frontUVs ? frontUVs : new Vector4(0.0, 0.0, 1.0, 1.0);
  1172. backUVs = backUVs ? backUVs : new Vector4(0.0, 0.0, 1.0, 1.0);
  1173. u = 0;
  1174. for (i = 0; i < lu / 2; i++) {
  1175. uvs[u] = frontUVs.x + (frontUVs.z - frontUVs.x) * uvs[u];
  1176. uvs[u + 1] = frontUVs.y + (frontUVs.w - frontUVs.y) * uvs[u + 1];
  1177. uvs[u + lu] = backUVs.x + (backUVs.z - backUVs.x) * uvs[u + lu];
  1178. uvs[u + lu + 1] = backUVs.y + (backUVs.w - backUVs.y) * uvs[u + lu + 1];
  1179. u += 2;
  1180. }
  1181. break;
  1182. }
  1183. }
  1184. /**
  1185. * Applies VertexData created from the imported parameters to the geometry
  1186. * @param parsedVertexData the parsed data from an imported file
  1187. * @param geometry the geometry to apply the VertexData to
  1188. */
  1189. public static ImportVertexData(parsedVertexData: any, geometry: Geometry) {
  1190. var vertexData = new VertexData();
  1191. // positions
  1192. var positions = parsedVertexData.positions;
  1193. if (positions) {
  1194. vertexData.set(positions, VertexBuffer.PositionKind);
  1195. }
  1196. // normals
  1197. var normals = parsedVertexData.normals;
  1198. if (normals) {
  1199. vertexData.set(normals, VertexBuffer.NormalKind);
  1200. }
  1201. // tangents
  1202. var tangents = parsedVertexData.tangents;
  1203. if (tangents) {
  1204. vertexData.set(tangents, VertexBuffer.TangentKind);
  1205. }
  1206. // uvs
  1207. var uvs = parsedVertexData.uvs;
  1208. if (uvs) {
  1209. vertexData.set(uvs, VertexBuffer.UVKind);
  1210. }
  1211. // uv2s
  1212. var uv2s = parsedVertexData.uv2s;
  1213. if (uv2s) {
  1214. vertexData.set(uv2s, VertexBuffer.UV2Kind);
  1215. }
  1216. // uv3s
  1217. var uv3s = parsedVertexData.uv3s;
  1218. if (uv3s) {
  1219. vertexData.set(uv3s, VertexBuffer.UV3Kind);
  1220. }
  1221. // uv4s
  1222. var uv4s = parsedVertexData.uv4s;
  1223. if (uv4s) {
  1224. vertexData.set(uv4s, VertexBuffer.UV4Kind);
  1225. }
  1226. // uv5s
  1227. var uv5s = parsedVertexData.uv5s;
  1228. if (uv5s) {
  1229. vertexData.set(uv5s, VertexBuffer.UV5Kind);
  1230. }
  1231. // uv6s
  1232. var uv6s = parsedVertexData.uv6s;
  1233. if (uv6s) {
  1234. vertexData.set(uv6s, VertexBuffer.UV6Kind);
  1235. }
  1236. // colors
  1237. var colors = parsedVertexData.colors;
  1238. if (colors) {
  1239. vertexData.set(Color4.CheckColors4(colors, positions.length / 3), VertexBuffer.ColorKind);
  1240. }
  1241. // matricesIndices
  1242. var matricesIndices = parsedVertexData.matricesIndices;
  1243. if (matricesIndices) {
  1244. vertexData.set(matricesIndices, VertexBuffer.MatricesIndicesKind);
  1245. }
  1246. // matricesWeights
  1247. var matricesWeights = parsedVertexData.matricesWeights;
  1248. if (matricesWeights) {
  1249. vertexData.set(matricesWeights, VertexBuffer.MatricesWeightsKind);
  1250. }
  1251. // indices
  1252. var indices = parsedVertexData.indices;
  1253. if (indices) {
  1254. vertexData.indices = indices;
  1255. }
  1256. geometry.setAllVerticesData(vertexData, parsedVertexData.updatable);
  1257. }
  1258. }