glTFLoaderUtils.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. import { EParameterType, ETextureWrapMode, ETextureFilterType, EComponentType } from "./glTFLoaderInterfaces.js";
  2. import { Vector2, Vector3, Vector4, Matrix } from "@babylonjs/core/Maths/math.vector.js";
  3. import { Color4 } from "@babylonjs/core/Maths/math.color.js";
  4. import { Effect } from "@babylonjs/core/Materials/effect.js";
  5. import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial.js";
  6. import { Texture } from "@babylonjs/core/Materials/Textures/texture.js";
  7. /**
  8. * Utils functions for GLTF
  9. * @internal
  10. * @deprecated
  11. */
  12. export class GLTFUtils {
  13. /**
  14. * Sets the given "parameter" matrix
  15. * @param scene the Scene object
  16. * @param source the source node where to pick the matrix
  17. * @param parameter the GLTF technique parameter
  18. * @param uniformName the name of the shader's uniform
  19. * @param shaderMaterial the shader material
  20. */
  21. static SetMatrix(scene, source, parameter, uniformName, shaderMaterial) {
  22. let mat = null;
  23. if (parameter.semantic === "MODEL") {
  24. mat = source.getWorldMatrix();
  25. }
  26. else if (parameter.semantic === "PROJECTION") {
  27. mat = scene.getProjectionMatrix();
  28. }
  29. else if (parameter.semantic === "VIEW") {
  30. mat = scene.getViewMatrix();
  31. }
  32. else if (parameter.semantic === "MODELVIEWINVERSETRANSPOSE") {
  33. mat = Matrix.Transpose(source.getWorldMatrix().multiply(scene.getViewMatrix()).invert());
  34. }
  35. else if (parameter.semantic === "MODELVIEW") {
  36. mat = source.getWorldMatrix().multiply(scene.getViewMatrix());
  37. }
  38. else if (parameter.semantic === "MODELVIEWPROJECTION") {
  39. mat = source.getWorldMatrix().multiply(scene.getTransformMatrix());
  40. }
  41. else if (parameter.semantic === "MODELINVERSE") {
  42. mat = source.getWorldMatrix().invert();
  43. }
  44. else if (parameter.semantic === "VIEWINVERSE") {
  45. mat = scene.getViewMatrix().invert();
  46. }
  47. else if (parameter.semantic === "PROJECTIONINVERSE") {
  48. mat = scene.getProjectionMatrix().invert();
  49. }
  50. else if (parameter.semantic === "MODELVIEWINVERSE") {
  51. mat = source.getWorldMatrix().multiply(scene.getViewMatrix()).invert();
  52. }
  53. else if (parameter.semantic === "MODELVIEWPROJECTIONINVERSE") {
  54. mat = source.getWorldMatrix().multiply(scene.getTransformMatrix()).invert();
  55. }
  56. else if (parameter.semantic === "MODELINVERSETRANSPOSE") {
  57. mat = Matrix.Transpose(source.getWorldMatrix().invert());
  58. }
  59. if (mat) {
  60. switch (parameter.type) {
  61. case EParameterType.FLOAT_MAT2:
  62. shaderMaterial.setMatrix2x2(uniformName, Matrix.GetAsMatrix2x2(mat));
  63. break;
  64. case EParameterType.FLOAT_MAT3:
  65. shaderMaterial.setMatrix3x3(uniformName, Matrix.GetAsMatrix3x3(mat));
  66. break;
  67. case EParameterType.FLOAT_MAT4:
  68. shaderMaterial.setMatrix(uniformName, mat);
  69. break;
  70. default:
  71. break;
  72. }
  73. }
  74. }
  75. /**
  76. * Sets the given "parameter" matrix
  77. * @param shaderMaterial the shader material
  78. * @param uniform the name of the shader's uniform
  79. * @param value the value of the uniform
  80. * @param type the uniform's type (EParameterType FLOAT, VEC2, VEC3 or VEC4)
  81. * @returns true if set, else false
  82. */
  83. static SetUniform(shaderMaterial, uniform, value, type) {
  84. switch (type) {
  85. case EParameterType.FLOAT:
  86. shaderMaterial.setFloat(uniform, value);
  87. return true;
  88. case EParameterType.FLOAT_VEC2:
  89. shaderMaterial.setVector2(uniform, Vector2.FromArray(value));
  90. return true;
  91. case EParameterType.FLOAT_VEC3:
  92. shaderMaterial.setVector3(uniform, Vector3.FromArray(value));
  93. return true;
  94. case EParameterType.FLOAT_VEC4:
  95. shaderMaterial.setVector4(uniform, Vector4.FromArray(value));
  96. return true;
  97. default:
  98. return false;
  99. }
  100. }
  101. /**
  102. * Returns the wrap mode of the texture
  103. * @param mode the mode value
  104. * @returns the wrap mode (TEXTURE_WRAP_ADDRESSMODE, MIRROR_ADDRESSMODE or CLAMP_ADDRESSMODE)
  105. */
  106. static GetWrapMode(mode) {
  107. switch (mode) {
  108. case ETextureWrapMode.CLAMP_TO_EDGE:
  109. return Texture.CLAMP_ADDRESSMODE;
  110. case ETextureWrapMode.MIRRORED_REPEAT:
  111. return Texture.MIRROR_ADDRESSMODE;
  112. case ETextureWrapMode.REPEAT:
  113. return Texture.WRAP_ADDRESSMODE;
  114. default:
  115. return Texture.WRAP_ADDRESSMODE;
  116. }
  117. }
  118. /**
  119. * Returns the byte stride giving an accessor
  120. * @param accessor the GLTF accessor objet
  121. * @returns the byte stride
  122. */
  123. static GetByteStrideFromType(accessor) {
  124. // Needs this function since "byteStride" isn't requiered in glTF format
  125. const type = accessor.type;
  126. switch (type) {
  127. case "VEC2":
  128. return 2;
  129. case "VEC3":
  130. return 3;
  131. case "VEC4":
  132. return 4;
  133. case "MAT2":
  134. return 4;
  135. case "MAT3":
  136. return 9;
  137. case "MAT4":
  138. return 16;
  139. default:
  140. return 1;
  141. }
  142. }
  143. /**
  144. * Returns the texture filter mode giving a mode value
  145. * @param mode the filter mode value
  146. * @returns the filter mode (TODO - needs to be a type?)
  147. */
  148. static GetTextureFilterMode(mode) {
  149. switch (mode) {
  150. case ETextureFilterType.LINEAR:
  151. case ETextureFilterType.LINEAR_MIPMAP_NEAREST:
  152. case ETextureFilterType.LINEAR_MIPMAP_LINEAR:
  153. return Texture.TRILINEAR_SAMPLINGMODE;
  154. case ETextureFilterType.NEAREST:
  155. case ETextureFilterType.NEAREST_MIPMAP_NEAREST:
  156. return Texture.NEAREST_SAMPLINGMODE;
  157. default:
  158. return Texture.BILINEAR_SAMPLINGMODE;
  159. }
  160. }
  161. static GetBufferFromBufferView(gltfRuntime, bufferView, byteOffset, byteLength, componentType) {
  162. byteOffset = bufferView.byteOffset + byteOffset;
  163. const loadedBufferView = gltfRuntime.loadedBufferViews[bufferView.buffer];
  164. if (byteOffset + byteLength > loadedBufferView.byteLength) {
  165. throw new Error("Buffer access is out of range");
  166. }
  167. const buffer = loadedBufferView.buffer;
  168. byteOffset += loadedBufferView.byteOffset;
  169. switch (componentType) {
  170. case EComponentType.BYTE:
  171. return new Int8Array(buffer, byteOffset, byteLength);
  172. case EComponentType.UNSIGNED_BYTE:
  173. return new Uint8Array(buffer, byteOffset, byteLength);
  174. case EComponentType.SHORT:
  175. return new Int16Array(buffer, byteOffset, byteLength);
  176. case EComponentType.UNSIGNED_SHORT:
  177. return new Uint16Array(buffer, byteOffset, byteLength);
  178. default:
  179. return new Float32Array(buffer, byteOffset, byteLength);
  180. }
  181. }
  182. /**
  183. * Returns a buffer from its accessor
  184. * @param gltfRuntime the GLTF runtime
  185. * @param accessor the GLTF accessor
  186. * @returns an array buffer view
  187. */
  188. static GetBufferFromAccessor(gltfRuntime, accessor) {
  189. const bufferView = gltfRuntime.bufferViews[accessor.bufferView];
  190. const byteLength = accessor.count * GLTFUtils.GetByteStrideFromType(accessor);
  191. return GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, accessor.byteOffset, byteLength, accessor.componentType);
  192. }
  193. /**
  194. * Decodes a buffer view into a string
  195. * @param view the buffer view
  196. * @returns a string
  197. */
  198. static DecodeBufferToText(view) {
  199. let result = "";
  200. const length = view.byteLength;
  201. for (let i = 0; i < length; ++i) {
  202. result += String.fromCharCode(view[i]);
  203. }
  204. return result;
  205. }
  206. /**
  207. * Returns the default material of gltf. Related to
  208. * https://github.com/KhronosGroup/glTF/tree/master/specification/1.0#appendix-a-default-material
  209. * @param scene the Babylon.js scene
  210. * @returns the default Babylon material
  211. */
  212. static GetDefaultMaterial(scene) {
  213. if (!GLTFUtils._DefaultMaterial) {
  214. Effect.ShadersStore["GLTFDefaultMaterialVertexShader"] = [
  215. "precision highp float;",
  216. "",
  217. "uniform mat4 worldView;",
  218. "uniform mat4 projection;",
  219. "",
  220. "attribute vec3 position;",
  221. "",
  222. "void main(void)",
  223. "{",
  224. " gl_Position = projection * worldView * vec4(position, 1.0);",
  225. "}",
  226. ].join("\n");
  227. Effect.ShadersStore["GLTFDefaultMaterialPixelShader"] = [
  228. "precision highp float;",
  229. "",
  230. "uniform vec4 u_emission;",
  231. "",
  232. "void main(void)",
  233. "{",
  234. " gl_FragColor = u_emission;",
  235. "}",
  236. ].join("\n");
  237. const shaderPath = {
  238. vertex: "GLTFDefaultMaterial",
  239. fragment: "GLTFDefaultMaterial",
  240. };
  241. const options = {
  242. attributes: ["position"],
  243. uniforms: ["worldView", "projection", "u_emission"],
  244. samplers: new Array(),
  245. needAlphaBlending: false,
  246. };
  247. GLTFUtils._DefaultMaterial = new ShaderMaterial("GLTFDefaultMaterial", scene, shaderPath, options);
  248. GLTFUtils._DefaultMaterial.setColor4("u_emission", new Color4(0.5, 0.5, 0.5, 1.0));
  249. }
  250. return GLTFUtils._DefaultMaterial;
  251. }
  252. }
  253. // The GLTF default material
  254. GLTFUtils._DefaultMaterial = null;
  255. //# sourceMappingURL=glTFLoaderUtils.js.map