mesh.vertexData.ts 72 KB

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