glTFUtilities.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import { IBufferView, AccessorType, AccessorComponentType, IAccessor } from "babylonjs-gltf2interface";
  2. import { FloatArray, Nullable } from "babylonjs/types";
  3. import { Vector3, Vector4, Quaternion, Matrix } from "babylonjs/Maths/math.vector";
  4. /**
  5. * @hidden
  6. */
  7. export class _GLTFUtilities {
  8. /**
  9. * Creates a buffer view based on the supplied arguments
  10. * @param bufferIndex index value of the specified buffer
  11. * @param byteOffset byte offset value
  12. * @param byteLength byte length of the bufferView
  13. * @param byteStride byte distance between conequential elements
  14. * @param name name of the buffer view
  15. * @returns bufferView for glTF
  16. */
  17. public static _CreateBufferView(bufferIndex: number, byteOffset: number, byteLength: number, byteStride?: number, name?: string): IBufferView {
  18. let bufferview: IBufferView = { buffer: bufferIndex, byteLength: byteLength };
  19. if (byteOffset) {
  20. bufferview.byteOffset = byteOffset;
  21. }
  22. if (name) {
  23. bufferview.name = name;
  24. }
  25. if (byteStride) {
  26. bufferview.byteStride = byteStride;
  27. }
  28. return bufferview;
  29. }
  30. /**
  31. * Creates an accessor based on the supplied arguments
  32. * @param bufferviewIndex The index of the bufferview referenced by this accessor
  33. * @param name The name of the accessor
  34. * @param type The type of the accessor
  35. * @param componentType The datatype of components in the attribute
  36. * @param count The number of attributes referenced by this accessor
  37. * @param byteOffset The offset relative to the start of the bufferView in bytes
  38. * @param min Minimum value of each component in this attribute
  39. * @param max Maximum value of each component in this attribute
  40. * @returns accessor for glTF
  41. */
  42. public static _CreateAccessor(bufferviewIndex: number, name: string, type: AccessorType, componentType: AccessorComponentType, count: number, byteOffset: Nullable<number>, min: Nullable<number[]>, max: Nullable<number[]>): IAccessor {
  43. let accessor: IAccessor = { name: name, bufferView: bufferviewIndex, componentType: componentType, count: count, type: type };
  44. if (min != null) {
  45. accessor.min = min;
  46. }
  47. if (max != null) {
  48. accessor.max = max;
  49. }
  50. if (byteOffset != null) {
  51. accessor.byteOffset = byteOffset;
  52. }
  53. return accessor;
  54. }
  55. /**
  56. * Calculates the minimum and maximum values of an array of position floats
  57. * @param positions Positions array of a mesh
  58. * @param vertexStart Starting vertex offset to calculate min and max values
  59. * @param vertexCount Number of vertices to check for min and max values
  60. * @returns min number array and max number array
  61. */
  62. public static _CalculateMinMaxPositions(positions: FloatArray, vertexStart: number, vertexCount: number, convertToRightHandedSystem: boolean): { min: number[], max: number[] } {
  63. const min = [Infinity, Infinity, Infinity];
  64. const max = [-Infinity, -Infinity, -Infinity];
  65. const positionStrideSize = 3;
  66. let indexOffset: number;
  67. let position: Vector3;
  68. let vector: number[];
  69. if (vertexCount) {
  70. for (let i = vertexStart, length = vertexStart + vertexCount; i < length; ++i) {
  71. indexOffset = positionStrideSize * i;
  72. position = Vector3.FromArray(positions, indexOffset);
  73. if (convertToRightHandedSystem) {
  74. _GLTFUtilities._GetRightHandedPositionVector3FromRef(position);
  75. }
  76. vector = position.asArray();
  77. for (let j = 0; j < positionStrideSize; ++j) {
  78. let num = vector[j];
  79. if (num < min[j]) {
  80. min[j] = num;
  81. }
  82. if (num > max[j]) {
  83. max[j] = num;
  84. }
  85. ++indexOffset;
  86. }
  87. }
  88. }
  89. return { min, max };
  90. }
  91. /**
  92. * Converts a new right-handed Vector3
  93. * @param vector vector3 array
  94. * @returns right-handed Vector3
  95. */
  96. public static _GetRightHandedPositionVector3(vector: Vector3): Vector3 {
  97. return new Vector3(vector.x, vector.y, -vector.z);
  98. }
  99. /**
  100. * Converts a Vector3 to right-handed
  101. * @param vector Vector3 to convert to right-handed
  102. */
  103. public static _GetRightHandedPositionVector3FromRef(vector: Vector3) {
  104. vector.z *= -1;
  105. }
  106. /**
  107. * Converts a three element number array to right-handed
  108. * @param vector number array to convert to right-handed
  109. */
  110. public static _GetRightHandedPositionArray3FromRef(vector: number[]) {
  111. vector[2] *= -1;
  112. }
  113. /**
  114. * Converts a new right-handed Vector3
  115. * @param vector vector3 array
  116. * @returns right-handed Vector3
  117. */
  118. public static _GetRightHandedNormalVector3(vector: Vector3): Vector3 {
  119. return new Vector3(vector.x, vector.y, -vector.z);
  120. }
  121. /**
  122. * Converts a Vector3 to right-handed
  123. * @param vector Vector3 to convert to right-handed
  124. */
  125. public static _GetRightHandedNormalVector3FromRef(vector: Vector3) {
  126. vector.z *= -1;
  127. }
  128. /**
  129. * Converts a three element number array to right-handed
  130. * @param vector number array to convert to right-handed
  131. */
  132. public static _GetRightHandedNormalArray3FromRef(vector: number[]) {
  133. vector[2] *= -1;
  134. }
  135. /**
  136. * Converts a Vector4 to right-handed
  137. * @param vector Vector4 to convert to right-handed
  138. */
  139. public static _GetRightHandedVector4FromRef(vector: Vector4) {
  140. vector.z *= -1;
  141. vector.w *= -1;
  142. }
  143. /**
  144. * Converts a Vector4 to right-handed
  145. * @param vector Vector4 to convert to right-handed
  146. */
  147. public static _GetRightHandedArray4FromRef(vector: number[]) {
  148. vector[2] *= -1;
  149. vector[3] *= -1;
  150. }
  151. /**
  152. * Converts a Quaternion to right-handed
  153. * @param quaternion Source quaternion to convert to right-handed
  154. */
  155. public static _GetRightHandedQuaternionFromRef(quaternion: Quaternion) {
  156. quaternion.x *= -1;
  157. quaternion.y *= -1;
  158. }
  159. /**
  160. * Converts a Quaternion to right-handed
  161. * @param quaternion Source quaternion to convert to right-handed
  162. */
  163. public static _GetRightHandedQuaternionArrayFromRef(quaternion: number[]) {
  164. quaternion[0] *= -1;
  165. quaternion[1] *= -1;
  166. }
  167. public static _NormalizeTangentFromRef(tangent: Vector4) {
  168. const length = Math.sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z);
  169. if (length > 0) {
  170. tangent.x /= length;
  171. tangent.y /= length;
  172. tangent.z /= length;
  173. }
  174. }
  175. public static _GetRightHandedMatrixFromRef(matrix: Matrix) {
  176. const m = matrix.m;
  177. Matrix.FromValuesToRef(
  178. m[0], m[1], -m[2], m[3],
  179. m[4], m[5], -m[6], m[7],
  180. -m[8], m[9], m[10], m[11],
  181. m[12], m[13], m[14], m[15],
  182. matrix
  183. );
  184. }
  185. }