@babylonjs/loaders
Version:
For usage documentation please visit https://doc.babylonjs.com/features/featuresDeepDive/importers/loadingFileTypes/.
255 lines • 10.2 kB
JavaScript
import { EParameterType, ETextureWrapMode, ETextureFilterType, EComponentType } from "./glTFLoaderInterfaces.js";
import { Vector2, Vector3, Vector4, Matrix } from "@babylonjs/core/Maths/math.vector.js";
import { Color4 } from "@babylonjs/core/Maths/math.color.js";
import { Effect } from "@babylonjs/core/Materials/effect.js";
import { ShaderMaterial } from "@babylonjs/core/Materials/shaderMaterial.js";
import { Texture } from "@babylonjs/core/Materials/Textures/texture.js";
/**
* Utils functions for GLTF
* @internal
* @deprecated
*/
export class GLTFUtils {
/**
* Sets the given "parameter" matrix
* @param scene the Scene object
* @param source the source node where to pick the matrix
* @param parameter the GLTF technique parameter
* @param uniformName the name of the shader's uniform
* @param shaderMaterial the shader material
*/
static SetMatrix(scene, source, parameter, uniformName, shaderMaterial) {
let mat = null;
if (parameter.semantic === "MODEL") {
mat = source.getWorldMatrix();
}
else if (parameter.semantic === "PROJECTION") {
mat = scene.getProjectionMatrix();
}
else if (parameter.semantic === "VIEW") {
mat = scene.getViewMatrix();
}
else if (parameter.semantic === "MODELVIEWINVERSETRANSPOSE") {
mat = Matrix.Transpose(source.getWorldMatrix().multiply(scene.getViewMatrix()).invert());
}
else if (parameter.semantic === "MODELVIEW") {
mat = source.getWorldMatrix().multiply(scene.getViewMatrix());
}
else if (parameter.semantic === "MODELVIEWPROJECTION") {
mat = source.getWorldMatrix().multiply(scene.getTransformMatrix());
}
else if (parameter.semantic === "MODELINVERSE") {
mat = source.getWorldMatrix().invert();
}
else if (parameter.semantic === "VIEWINVERSE") {
mat = scene.getViewMatrix().invert();
}
else if (parameter.semantic === "PROJECTIONINVERSE") {
mat = scene.getProjectionMatrix().invert();
}
else if (parameter.semantic === "MODELVIEWINVERSE") {
mat = source.getWorldMatrix().multiply(scene.getViewMatrix()).invert();
}
else if (parameter.semantic === "MODELVIEWPROJECTIONINVERSE") {
mat = source.getWorldMatrix().multiply(scene.getTransformMatrix()).invert();
}
else if (parameter.semantic === "MODELINVERSETRANSPOSE") {
mat = Matrix.Transpose(source.getWorldMatrix().invert());
}
if (mat) {
switch (parameter.type) {
case EParameterType.FLOAT_MAT2:
shaderMaterial.setMatrix2x2(uniformName, Matrix.GetAsMatrix2x2(mat));
break;
case EParameterType.FLOAT_MAT3:
shaderMaterial.setMatrix3x3(uniformName, Matrix.GetAsMatrix3x3(mat));
break;
case EParameterType.FLOAT_MAT4:
shaderMaterial.setMatrix(uniformName, mat);
break;
default:
break;
}
}
}
/**
* Sets the given "parameter" matrix
* @param shaderMaterial the shader material
* @param uniform the name of the shader's uniform
* @param value the value of the uniform
* @param type the uniform's type (EParameterType FLOAT, VEC2, VEC3 or VEC4)
* @returns true if set, else false
*/
static SetUniform(shaderMaterial, uniform, value, type) {
switch (type) {
case EParameterType.FLOAT:
shaderMaterial.setFloat(uniform, value);
return true;
case EParameterType.FLOAT_VEC2:
shaderMaterial.setVector2(uniform, Vector2.FromArray(value));
return true;
case EParameterType.FLOAT_VEC3:
shaderMaterial.setVector3(uniform, Vector3.FromArray(value));
return true;
case EParameterType.FLOAT_VEC4:
shaderMaterial.setVector4(uniform, Vector4.FromArray(value));
return true;
default:
return false;
}
}
/**
* Returns the wrap mode of the texture
* @param mode the mode value
* @returns the wrap mode (TEXTURE_WRAP_ADDRESSMODE, MIRROR_ADDRESSMODE or CLAMP_ADDRESSMODE)
*/
static GetWrapMode(mode) {
switch (mode) {
case ETextureWrapMode.CLAMP_TO_EDGE:
return Texture.CLAMP_ADDRESSMODE;
case ETextureWrapMode.MIRRORED_REPEAT:
return Texture.MIRROR_ADDRESSMODE;
case ETextureWrapMode.REPEAT:
return Texture.WRAP_ADDRESSMODE;
default:
return Texture.WRAP_ADDRESSMODE;
}
}
/**
* Returns the byte stride giving an accessor
* @param accessor the GLTF accessor objet
* @returns the byte stride
*/
static GetByteStrideFromType(accessor) {
// Needs this function since "byteStride" isn't requiered in glTF format
const type = accessor.type;
switch (type) {
case "VEC2":
return 2;
case "VEC3":
return 3;
case "VEC4":
return 4;
case "MAT2":
return 4;
case "MAT3":
return 9;
case "MAT4":
return 16;
default:
return 1;
}
}
/**
* Returns the texture filter mode giving a mode value
* @param mode the filter mode value
* @returns the filter mode (TODO - needs to be a type?)
*/
static GetTextureFilterMode(mode) {
switch (mode) {
case ETextureFilterType.LINEAR:
case ETextureFilterType.LINEAR_MIPMAP_NEAREST:
case ETextureFilterType.LINEAR_MIPMAP_LINEAR:
return Texture.TRILINEAR_SAMPLINGMODE;
case ETextureFilterType.NEAREST:
case ETextureFilterType.NEAREST_MIPMAP_NEAREST:
return Texture.NEAREST_SAMPLINGMODE;
default:
return Texture.BILINEAR_SAMPLINGMODE;
}
}
static GetBufferFromBufferView(gltfRuntime, bufferView, byteOffset, byteLength, componentType) {
byteOffset = bufferView.byteOffset + byteOffset;
const loadedBufferView = gltfRuntime.loadedBufferViews[bufferView.buffer];
if (byteOffset + byteLength > loadedBufferView.byteLength) {
throw new Error("Buffer access is out of range");
}
const buffer = loadedBufferView.buffer;
byteOffset += loadedBufferView.byteOffset;
switch (componentType) {
case EComponentType.BYTE:
return new Int8Array(buffer, byteOffset, byteLength);
case EComponentType.UNSIGNED_BYTE:
return new Uint8Array(buffer, byteOffset, byteLength);
case EComponentType.SHORT:
return new Int16Array(buffer, byteOffset, byteLength);
case EComponentType.UNSIGNED_SHORT:
return new Uint16Array(buffer, byteOffset, byteLength);
default:
return new Float32Array(buffer, byteOffset, byteLength);
}
}
/**
* Returns a buffer from its accessor
* @param gltfRuntime the GLTF runtime
* @param accessor the GLTF accessor
* @returns an array buffer view
*/
static GetBufferFromAccessor(gltfRuntime, accessor) {
const bufferView = gltfRuntime.bufferViews[accessor.bufferView];
const byteLength = accessor.count * GLTFUtils.GetByteStrideFromType(accessor);
return GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, accessor.byteOffset, byteLength, accessor.componentType);
}
/**
* Decodes a buffer view into a string
* @param view the buffer view
* @returns a string
*/
static DecodeBufferToText(view) {
let result = "";
const length = view.byteLength;
for (let i = 0; i < length; ++i) {
result += String.fromCharCode(view[i]);
}
return result;
}
/**
* Returns the default material of gltf. Related to
* https://github.com/KhronosGroup/glTF/tree/master/specification/1.0#appendix-a-default-material
* @param scene the Babylon.js scene
* @returns the default Babylon material
*/
static GetDefaultMaterial(scene) {
if (!GLTFUtils._DefaultMaterial) {
Effect.ShadersStore["GLTFDefaultMaterialVertexShader"] = [
"precision highp float;",
"",
"uniform mat4 worldView;",
"uniform mat4 projection;",
"",
"attribute vec3 position;",
"",
"void main(void)",
"{",
" gl_Position = projection * worldView * vec4(position, 1.0);",
"}",
].join("\n");
Effect.ShadersStore["GLTFDefaultMaterialPixelShader"] = [
"precision highp float;",
"",
"uniform vec4 u_emission;",
"",
"void main(void)",
"{",
" gl_FragColor = u_emission;",
"}",
].join("\n");
const shaderPath = {
vertex: "GLTFDefaultMaterial",
fragment: "GLTFDefaultMaterial",
};
const options = {
attributes: ["position"],
uniforms: ["worldView", "projection", "u_emission"],
samplers: new Array(),
needAlphaBlending: false,
};
GLTFUtils._DefaultMaterial = new ShaderMaterial("GLTFDefaultMaterial", scene, shaderPath, options);
GLTFUtils._DefaultMaterial.setColor4("u_emission", new Color4(0.5, 0.5, 0.5, 1.0));
}
return GLTFUtils._DefaultMaterial;
}
}
// The GLTF default material
GLTFUtils._DefaultMaterial = null;
//# sourceMappingURL=glTFLoaderUtils.js.map