babylon.glTFFileLoaderUtils.ts 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. module BABYLON {
  2. /**
  3. * Utils functions for GLTF
  4. */
  5. export class GLTFUtils {
  6. /**
  7. * Sets the given "parameter" matrix
  8. * @param scene: the {BABYLON.Scene} object
  9. * @param source: the source node where to pick the matrix
  10. * @param parameter: the GLTF technique parameter
  11. * @param uniformName: the name of the shader's uniform
  12. * @param shaderMaterial: the shader material
  13. */
  14. public static SetMatrix(scene: Scene, source: Node, parameter: IGLTFTechniqueParameter, uniformName: string, shaderMaterial: ShaderMaterial | Effect): void {
  15. var mat: Matrix = null;
  16. if (parameter.semantic === "MODEL") {
  17. mat = source.getWorldMatrix();
  18. }
  19. else if (parameter.semantic === "PROJECTION") {
  20. mat = scene.getProjectionMatrix();
  21. }
  22. else if (parameter.semantic === "VIEW") {
  23. mat = scene.getViewMatrix();
  24. }
  25. else if (parameter.semantic === "MODELVIEWINVERSETRANSPOSE") {
  26. mat = Matrix.Transpose(source.getWorldMatrix().multiply(scene.getViewMatrix()).invert());
  27. }
  28. else if (parameter.semantic === "MODELVIEW") {
  29. mat = source.getWorldMatrix().multiply(scene.getViewMatrix());
  30. }
  31. else if (parameter.semantic === "MODELVIEWPROJECTION") {
  32. mat = source.getWorldMatrix().multiply(scene.getTransformMatrix());
  33. }
  34. else if (parameter.semantic === "MODELINVERSE") {
  35. mat = source.getWorldMatrix().invert();
  36. }
  37. else if (parameter.semantic === "VIEWINVERSE") {
  38. mat = scene.getViewMatrix().invert();
  39. }
  40. else if (parameter.semantic === "PROJECTIONINVERSE") {
  41. mat = scene.getProjectionMatrix().invert();
  42. }
  43. else if (parameter.semantic === "MODELVIEWINVERSE") {
  44. mat = source.getWorldMatrix().multiply(scene.getViewMatrix()).invert();
  45. }
  46. else if (parameter.semantic === "MODELVIEWPROJECTIONINVERSE") {
  47. mat = source.getWorldMatrix().multiply(scene.getTransformMatrix()).invert();
  48. }
  49. else if (parameter.semantic === "MODELINVERSETRANSPOSE") {
  50. mat = Matrix.Transpose(source.getWorldMatrix().invert());
  51. }
  52. else {
  53. debugger;
  54. }
  55. switch (parameter.type) {
  56. case EParameterType.FLOAT_MAT2: shaderMaterial.setMatrix2x2(uniformName, Matrix.GetAsMatrix2x2(mat)); break;
  57. case EParameterType.FLOAT_MAT3: shaderMaterial.setMatrix3x3(uniformName, Matrix.GetAsMatrix3x3(mat)); break;
  58. case EParameterType.FLOAT_MAT4: shaderMaterial.setMatrix(uniformName, mat); break;
  59. default: break;
  60. }
  61. }
  62. /**
  63. * Sets the given "parameter" matrix
  64. * @param shaderMaterial: the shader material
  65. * @param uniform: the name of the shader's uniform
  66. * @param value: the value of the uniform
  67. * @param type: the uniform's type (EParameterType FLOAT, VEC2, VEC3 or VEC4)
  68. */
  69. public static SetUniform(shaderMaterial: ShaderMaterial | Effect, uniform: string, value: any, type: number): boolean {
  70. switch (type) {
  71. case EParameterType.FLOAT: shaderMaterial.setFloat(uniform, value); return true;
  72. case EParameterType.FLOAT_VEC2: shaderMaterial.setVector2(uniform, Vector2.FromArray(value)); return true;
  73. case EParameterType.FLOAT_VEC3: shaderMaterial.setVector3(uniform, Vector3.FromArray(value)); return true;
  74. case EParameterType.FLOAT_VEC4: shaderMaterial.setVector4(uniform, Vector4.FromArray(value)); return true;
  75. default: return false;
  76. }
  77. }
  78. /**
  79. * If the uri is a base64 string
  80. * @param uri: the uri to test
  81. */
  82. public static IsBase64(uri: string): boolean {
  83. return uri.length < 5 ? false : uri.substr(0, 5) === "data:";
  84. }
  85. /**
  86. * Decode the base64 uri
  87. * @param uri: the uri to decode
  88. */
  89. public static DecodeBase64(uri: string): ArrayBuffer {
  90. var decodedString = atob(uri.split(",")[1]);
  91. var bufferLength = decodedString.length;
  92. var bufferView = new Uint8Array(new ArrayBuffer(bufferLength));
  93. for (var i = 0; i < bufferLength; i++) {
  94. bufferView[i] = decodedString.charCodeAt(i);
  95. }
  96. return bufferView.buffer;
  97. }
  98. /**
  99. * Returns the wrap mode of the texture
  100. * @param mode: the mode value
  101. */
  102. public static GetWrapMode(mode: number): number {
  103. switch (mode) {
  104. case ETextureWrapMode.CLAMP_TO_EDGE: return Texture.CLAMP_ADDRESSMODE;
  105. case ETextureWrapMode.MIRRORED_REPEAT: return Texture.MIRROR_ADDRESSMODE;
  106. case ETextureWrapMode.REPEAT: return Texture.WRAP_ADDRESSMODE;
  107. default: return Texture.WRAP_ADDRESSMODE;
  108. }
  109. }
  110. /**
  111. * Returns the byte stride giving an accessor
  112. * @param accessor: the GLTF accessor objet
  113. */
  114. public static GetByteStrideFromType(accessor: IGLTFAccessor): number {
  115. // Needs this function since "byteStride" isn't requiered in glTF format
  116. var type = accessor.type;
  117. switch (type) {
  118. case "VEC2": return 2;
  119. case "VEC3": return 3;
  120. case "VEC4": return 4;
  121. case "MAT2": return 4;
  122. case "MAT3": return 9;
  123. case "MAT4": return 16;
  124. default: return 1;
  125. }
  126. }
  127. /**
  128. * Returns the texture filter mode giving a mode value
  129. * @param mode: the filter mode value
  130. */
  131. public static GetTextureFilterMode(mode: number): ETextureFilterType {
  132. switch (mode) {
  133. case ETextureFilterType.LINEAR:
  134. case ETextureFilterType.LINEAR_MIPMAP_NEAREST:
  135. case ETextureFilterType.LINEAR_MIPMAP_LINEAR: return Texture.TRILINEAR_SAMPLINGMODE;
  136. case ETextureFilterType.NEAREST:
  137. case ETextureFilterType.NEAREST_MIPMAP_NEAREST: return Texture.NEAREST_SAMPLINGMODE;
  138. default: return Texture.BILINEAR_SAMPLINGMODE;
  139. }
  140. }
  141. public static GetBufferFromBufferView(gltfRuntime: IGLTFRuntime, bufferView: IGLTFBufferView, byteOffset: number, byteLength: number, componentType: EComponentType): ArrayBufferView {
  142. var byteOffset = bufferView.byteOffset + byteOffset;
  143. var loadedBufferView = gltfRuntime.loadedBufferViews[bufferView.buffer];
  144. if (byteOffset + byteLength > loadedBufferView.byteLength) {
  145. throw new Error("Buffer access is out of range");
  146. }
  147. var buffer = loadedBufferView.buffer;
  148. byteOffset += loadedBufferView.byteOffset;
  149. switch (componentType) {
  150. case EComponentType.BYTE: return new Int8Array(buffer, byteOffset, byteLength);
  151. case EComponentType.UNSIGNED_BYTE: return new Uint8Array(buffer, byteOffset, byteLength);
  152. case EComponentType.SHORT: return new Int16Array(buffer, byteOffset, byteLength);
  153. case EComponentType.UNSIGNED_SHORT: return new Uint16Array(buffer, byteOffset, byteLength);
  154. default: return new Float32Array(buffer, byteOffset, byteLength);
  155. }
  156. }
  157. /**
  158. * Returns a buffer from its accessor
  159. * @param gltfRuntime: the GLTF runtime
  160. * @param accessor: the GLTF accessor
  161. */
  162. public static GetBufferFromAccessor(gltfRuntime: IGLTFRuntime, accessor: IGLTFAccessor): any {
  163. var bufferView: IGLTFBufferView = gltfRuntime.bufferViews[accessor.bufferView];
  164. var byteLength = accessor.count * GLTFUtils.GetByteStrideFromType(accessor);
  165. return GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, accessor.byteOffset, byteLength, accessor.componentType);
  166. }
  167. /**
  168. * Decodes a buffer view into a string
  169. * @param view: the buffer view
  170. */
  171. public static DecodeBufferToText(view: ArrayBufferView): string {
  172. var result = "";
  173. var length = view.byteLength;
  174. for (var i = 0; i < length; ++i) {
  175. result += String.fromCharCode(view[i]);
  176. }
  177. return result;
  178. }
  179. }
  180. }