Browse Source

Add versioned glTF loader support

Gary Hsu 8 năm trước cách đây
mục cha
commit
aec514120a

+ 22 - 6
Tools/Gulp/config.json

@@ -506,14 +506,30 @@
             },
             {
                 "files": [
-                    "../../loaders/src/glTF/babylon.glTFFileLoaderInterfaces.ts",
-                    "../../loaders/src/glTF/babylon.glTFFileLoader.ts",
-                    "../../loaders/src/glTF/babylon.glTFFileLoaderUtils.ts",
-                    "../../loaders/src/glTF/babylon.glTFFileLoaderExtension.ts",
-                    "../../loaders/src/glTF/babylon.glTFMaterialsCommonExtension.ts",
-                    "../../loaders/src/glTF/babylon.glTFMaterialsPbrSpecularGlossinessExtension.ts"
+                    "../../loaders/src/glTF/babylon.glTFFileLoader.ts"
                 ],
                 "output": "babylon.glTFFileLoader.js"
+            },
+            {
+                "files": [
+                    "../../loaders/src/glTF/1.0/babylon.glTFLoaderInterfaces.ts",
+                    "../../loaders/src/glTF/1.0/babylon.glTFLoader.ts",
+                    "../../loaders/src/glTF/1.0/babylon.glTFLoaderUtils.ts",
+                    "../../loaders/src/glTF/1.0/babylon.glTFLoaderExtension.ts",
+                    "../../loaders/src/glTF/1.0/babylon.glTFBinaryExtension.ts",
+                    "../../loaders/src/glTF/1.0/babylon.glTFMaterialsCommonExtension.ts"
+                ],
+                "output": "babylon.glTF1Loader.js"
+            },
+            {
+                "files": [
+                    "../../loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts",
+                    "../../loaders/src/glTF/2.0/babylon.glTFLoader.ts",
+                    "../../loaders/src/glTF/2.0/babylon.glTFLoaderUtils.ts",
+                    "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
+                    "../../loaders/src/glTF/2.0/babylon.glTFMaterialsPbrSpecularGlossinessExtension.ts"
+                ],
+                "output": "babylon.glTF2Loader.js"
             }
         ],
         "build": {

+ 114 - 0
loaders/src/glTF/1.0/babylon.glTFBinaryExtension.ts

@@ -0,0 +1,114 @@
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON.GLTF1 {
+    const BinaryExtensionBufferName = "binary_glTF";
+
+    enum EContentFormat {
+        JSON = 0
+    };
+
+    interface IGLTFBinaryExtensionShader {
+        bufferView: string;
+    };
+
+    interface IGLTFBinaryExtensionImage {
+        bufferView: string;
+        mimeType: string;
+        height: number;
+        width: number;
+    };
+
+    export class GLTFBinaryExtension extends GLTFLoaderExtension {
+        private _bin : ArrayBufferView;
+
+        public constructor() {
+            super("KHR_binary_glTF");
+        }
+
+        public loadRuntimeAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (gltfRuntime: IGLTFRuntime) => void, onError: () => void): boolean {
+            var extensionsUsed = (<any>data.json).extensionsUsed;
+            if (!extensionsUsed || extensionsUsed.indexOf(this.name) === -1) {
+                return false;
+            }
+
+            this._bin = data.bin;
+            onSuccess(GLTFLoaderBase.CreateRuntime(data.json, scene, rootUrl));
+            return true;
+        }
+
+        public loadBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: () => void): boolean {
+            if (gltfRuntime.extensionsUsed.indexOf(this.name) === -1) {
+                return false;
+            }
+
+            if (id !== BinaryExtensionBufferName) {
+                return false;
+            }
+
+            onSuccess(this._bin);
+            return true;
+        }
+
+        public loadTextureBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: () => void): boolean {
+            var texture: IGLTFTexture = gltfRuntime.textures[id];
+            var source: IGLTFImage = gltfRuntime.images[texture.source];
+            if (!source.extensions || !(this.name in source.extensions)) {
+                return false;
+            }
+
+            var sourceExt: IGLTFBinaryExtensionImage = source.extensions[this.name];
+            var bufferView: IGLTFBufferView = gltfRuntime.bufferViews[sourceExt.bufferView];
+            var buffer = GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, 0, bufferView.byteLength, EComponentType.UNSIGNED_BYTE);
+            onSuccess(buffer);
+            return true;
+        }
+
+        public loadShaderStringAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (shaderString: string) => void, onError: () => void): boolean {
+            var shader: IGLTFShader = gltfRuntime.shaders[id];
+            if (!shader.extensions || !(this.name in shader.extensions)) {
+                return false;
+            }
+
+            var binaryExtensionShader: IGLTFBinaryExtensionShader = shader.extensions[this.name];
+            var bufferView: IGLTFBufferView = gltfRuntime.bufferViews[binaryExtensionShader.bufferView];
+            var shaderBytes = GLTFUtils.GetBufferFromBufferView(gltfRuntime, bufferView, 0, bufferView.byteLength, EComponentType.UNSIGNED_BYTE);
+
+            setTimeout(() => {
+                var shaderString = GLTFUtils.DecodeBufferToText(shaderBytes);
+                onSuccess(shaderString);
+            });
+
+            return true;
+        }
+    }
+
+    class BinaryReader {
+        private _arrayBuffer: ArrayBuffer;
+        private _dataView: DataView;
+        private _byteOffset: number;
+
+        constructor(arrayBuffer: ArrayBuffer) {
+            this._arrayBuffer = arrayBuffer;
+            this._dataView = new DataView(arrayBuffer);
+            this._byteOffset = 0;
+        }
+
+        public getUint32(): number {
+            var value = this._dataView.getUint32(this._byteOffset, true);
+            this._byteOffset += 4;
+            return value;
+        }
+
+        public getUint8Array(length?: number): Uint8Array {
+            if (!length) {
+                length = this._arrayBuffer.byteLength - this._byteOffset;
+            }
+
+            var value = new Uint8Array(this._arrayBuffer, this._byteOffset, length);
+            this._byteOffset += length;
+            return value;
+        }
+    }
+
+    GLTFLoader.RegisterExtension(new GLTFBinaryExtension());
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1735 - 0
loaders/src/glTF/1.0/babylon.glTFLoader.ts


+ 152 - 0
loaders/src/glTF/1.0/babylon.glTFLoaderExtension.ts

@@ -0,0 +1,152 @@
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON.GLTF1 {
+    export abstract class GLTFLoaderExtension {
+        private _name: string;
+
+        public constructor(name: string) {
+            this._name = name;
+        }
+
+        public get name(): string {
+            return this._name;
+        }
+
+        /**
+        * Defines an override for loading the runtime
+        * Return true to stop further extensions from loading the runtime
+        */
+        public loadRuntimeAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (gltfRuntime: IGLTFRuntime) => void, onError: () => void): boolean {
+            return false;
+        }
+
+        /**
+         * Defines an onverride for creating gltf runtime
+         * Return true to stop further extensions from creating the runtime
+         */
+        public loadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError: () => void): boolean {
+            return false;
+        }
+
+        /**
+        * Defines an override for loading buffers
+        * Return true to stop further extensions from loading this buffer
+        */
+        public loadBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: () => void, onProgress?: () => void): boolean {
+            return false;
+        }
+
+        /**
+        * Defines an override for loading texture buffers
+        * Return true to stop further extensions from loading this texture data
+        */
+        public loadTextureBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: () => void): boolean {
+            return false;
+        }
+
+        /**
+        * Defines an override for creating textures
+        * Return true to stop further extensions from loading this texture
+        */
+        public createTextureAsync(gltfRuntime: IGLTFRuntime, id: string, buffer: ArrayBufferView, onSuccess: (texture: Texture) => void, onError: () => void): boolean {
+            return false;
+        }
+
+        /**
+        * Defines an override for loading shader strings
+        * Return true to stop further extensions from loading this shader data
+        */
+        public loadShaderStringAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (shaderString: string) => void, onError: () => void): boolean {
+            return false;
+        }
+
+        /**
+        * Defines an override for loading materials
+        * Return true to stop further extensions from loading this material
+        */
+        public loadMaterialAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (material: Material) => void, onError: () => void): boolean {
+            return false;
+        }
+
+        // ---------
+        // Utilities
+        // ---------
+
+        public static LoadRuntimeAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (gltfRuntime: IGLTFRuntime) => void, onError: () => void): void {
+            GLTFLoaderExtension.ApplyExtensions(loaderExtension => {
+                return loaderExtension.loadRuntimeAsync(scene, data, rootUrl, onSuccess, onError);
+            }, () => {
+                setTimeout(() => {
+                    onSuccess(GLTFLoaderBase.CreateRuntime(data.json, scene, rootUrl));
+                });
+            });
+        }
+
+        public static LoadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError: () => void): void {
+            GLTFLoaderExtension.ApplyExtensions(loaderExtension => {
+                return loaderExtension.loadRuntimeExtensionsAsync(gltfRuntime, onSuccess, onError);
+            }, () => {
+                setTimeout(() => {
+                    onSuccess();
+                });
+            });
+        }
+
+        public static LoadBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (bufferView: ArrayBufferView) => void, onError: () => void, onProgress?: () => void): void {
+            GLTFLoaderExtension.ApplyExtensions(loaderExtension => {
+                return loaderExtension.loadBufferAsync(gltfRuntime, id, onSuccess, onError, onProgress);
+            }, () => {
+                GLTFLoaderBase.LoadBufferAsync(gltfRuntime, id, onSuccess, onError, onProgress);
+            });
+        }
+
+        public static LoadTextureAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (texture: Texture) => void, onError: () => void): void {
+            GLTFLoaderExtension.LoadTextureBufferAsync(gltfRuntime, id,
+                buffer => GLTFLoaderExtension.CreateTextureAsync(gltfRuntime, id, buffer, onSuccess, onError),
+                onError);
+        }
+
+        public static LoadShaderStringAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (shaderData: string) => void, onError: () => void): void {
+            GLTFLoaderExtension.ApplyExtensions(loaderExtension => {
+                return loaderExtension.loadShaderStringAsync(gltfRuntime, id, onSuccess, onError);
+            }, () => {
+                GLTFLoaderBase.LoadShaderStringAsync(gltfRuntime, id, onSuccess, onError);
+            });
+        }
+
+        public static LoadMaterialAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (material: Material) => void, onError: () => void): void {
+            GLTFLoaderExtension.ApplyExtensions(loaderExtension => {
+                return loaderExtension.loadMaterialAsync(gltfRuntime, id, onSuccess, onError);
+            }, () => {
+                GLTFLoaderBase.LoadMaterialAsync(gltfRuntime, id, onSuccess, onError);
+            });
+        }
+
+        private static LoadTextureBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (buffer: ArrayBufferView) => void, onError: () => void): void {
+            GLTFLoaderExtension.ApplyExtensions(loaderExtension => {
+                return loaderExtension.loadTextureBufferAsync(gltfRuntime, id, onSuccess, onError);
+            }, () => {
+                GLTFLoaderBase.LoadTextureBufferAsync(gltfRuntime, id, onSuccess, onError);
+            });
+        }
+
+        private static CreateTextureAsync(gltfRuntime: IGLTFRuntime, id: string, buffer: ArrayBufferView, onSuccess: (texture: Texture) => void, onError: () => void): void {
+            GLTFLoaderExtension.ApplyExtensions(loaderExtension => {
+                return loaderExtension.createTextureAsync(gltfRuntime, id, buffer, onSuccess, onError);
+            }, () => {
+                GLTFLoaderBase.CreateTextureAsync(gltfRuntime, id, buffer, onSuccess, onError);
+            });
+        }
+
+        private static ApplyExtensions(func: (loaderExtension: GLTFLoaderExtension) => boolean, defaultFunc: () => void): void {
+            for (var extensionName in GLTFLoader.Extensions) {
+                var loaderExtension = GLTFLoader.Extensions[extensionName];
+                if (func(loaderExtension)) {
+                    return;
+                }
+            }
+
+            defaultFunc();
+        }
+    }
+}

+ 386 - 0
loaders/src/glTF/1.0/babylon.glTFLoaderInterfaces.ts

@@ -0,0 +1,386 @@
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON.GLTF1 {
+    /**
+    * Enums
+    */
+    export enum EComponentType {
+        BYTE = 5120,
+        UNSIGNED_BYTE = 5121,
+        SHORT = 5122,
+        UNSIGNED_SHORT = 5123,
+        FLOAT = 5126
+    }
+
+    export enum EShaderType {
+        FRAGMENT = 35632,
+        VERTEX = 35633
+    }
+
+    export enum EParameterType {
+        BYTE = 5120,
+        UNSIGNED_BYTE = 5121,
+        SHORT = 5122,
+        UNSIGNED_SHORT = 5123,
+        INT = 5124,
+        UNSIGNED_INT = 5125,
+        FLOAT = 5126,
+        FLOAT_VEC2 = 35664,
+        FLOAT_VEC3 = 35665,
+        FLOAT_VEC4 = 35666,
+        INT_VEC2 = 35667,
+        INT_VEC3 = 35668,
+        INT_VEC4 = 35669,
+        BOOL = 35670,
+        BOOL_VEC2 = 35671,
+        BOOL_VEC3 = 35672,
+        BOOL_VEC4 = 35673,
+        FLOAT_MAT2 = 35674,
+        FLOAT_MAT3 = 35675,
+        FLOAT_MAT4 = 35676,
+        SAMPLER_2D = 35678
+    }
+
+    export enum ETextureWrapMode {
+        CLAMP_TO_EDGE = 33071,
+        MIRRORED_REPEAT = 33648,
+        REPEAT = 10497
+    }
+
+    export enum ETextureFilterType {
+        NEAREST = 9728,
+        LINEAR = 9728,
+        NEAREST_MIPMAP_NEAREST = 9984,
+        LINEAR_MIPMAP_NEAREST = 9985,
+        NEAREST_MIPMAP_LINEAR = 9986,
+        LINEAR_MIPMAP_LINEAR = 9987
+    }
+
+    export enum ETextureFormat {
+        ALPHA = 6406,
+        RGB = 6407,
+        RGBA = 6408,
+        LUMINANCE = 6409,
+        LUMINANCE_ALPHA = 6410
+    }
+
+    export enum ECullingType {
+        FRONT = 1028,
+        BACK = 1029,
+        FRONT_AND_BACK = 1032
+    }
+
+    export enum EBlendingFunction {
+        ZERO = 0,
+        ONE = 1,
+        SRC_COLOR = 768,
+        ONE_MINUS_SRC_COLOR = 769,
+        DST_COLOR = 774,
+        ONE_MINUS_DST_COLOR = 775,
+        SRC_ALPHA = 770,
+        ONE_MINUS_SRC_ALPHA = 771,
+        DST_ALPHA = 772,
+        ONE_MINUS_DST_ALPHA = 773,
+        CONSTANT_COLOR = 32769,
+        ONE_MINUS_CONSTANT_COLOR = 32770,
+        CONSTANT_ALPHA = 32771,
+        ONE_MINUS_CONSTANT_ALPHA = 32772,
+        SRC_ALPHA_SATURATE = 776
+    }
+
+    /**
+    * Interfaces
+    */
+    export interface IGLTFProperty {
+        extensions?: Object;
+        extras?: Object;
+    }
+
+    export interface IGLTFChildRootProperty extends IGLTFProperty {
+        name?: string;
+    }
+
+    export interface IGLTFAccessor extends IGLTFChildRootProperty {
+        bufferView: string;
+        byteOffset: number;
+        byteStride: number;
+        count: number;
+        type: string;
+        componentType: EComponentType;
+
+        max?: number[],
+        min?: number[],
+        name?: string;
+    }
+
+    export interface IGLTFBufferView extends IGLTFChildRootProperty {
+        buffer: string;
+        byteOffset: number;
+        byteLength: number;
+
+        target?: number;
+    }
+
+    export interface IGLTFBuffer extends IGLTFChildRootProperty {
+        uri: string;
+
+        byteLength?: number;
+        type?: string;
+    }
+
+    export interface IGLTFShader extends IGLTFChildRootProperty {
+        uri: string;
+        type: EShaderType;
+    }
+
+    export interface IGLTFProgram extends IGLTFChildRootProperty {
+        attributes: string[];
+        fragmentShader: string;
+        vertexShader: string;
+    }
+
+    export interface IGLTFTechniqueParameter {
+        type: number;
+
+        count?: number;
+        semantic?: string;
+        node?: string;
+        value?: number|boolean|string|Array<any>;
+        source?: string;
+
+        babylonValue?: any;
+    }
+
+    export interface IGLTFTechniqueCommonProfile {
+        lightingModel: string;
+        texcoordBindings: Object;
+
+        parameters?: Array<any>;
+    }
+
+    export interface IGLTFTechniqueStatesFunctions {
+        blendColor?: number[];
+        blendEquationSeparate?: number[];
+        blendFuncSeparate?: number[];
+        colorMask: boolean[];
+        cullFace: number[];
+    }
+
+    export interface IGLTFTechniqueStates {
+        enable: number[];
+        functions: IGLTFTechniqueStatesFunctions;
+    }
+
+    export interface IGLTFTechnique extends IGLTFChildRootProperty {
+        parameters: Object;
+        program: string;
+
+        attributes: Object;
+        uniforms: Object;
+        states: IGLTFTechniqueStates;
+    }
+
+    export interface IGLTFMaterial extends IGLTFChildRootProperty {
+        technique?: string;
+        values: string[];
+    }
+
+    export interface IGLTFMeshPrimitive extends IGLTFProperty {
+        attributes: Object;
+        indices: string;
+        material: string;
+
+        mode?: number;
+    }
+
+    export interface IGLTFMesh extends IGLTFChildRootProperty {
+        primitives: IGLTFMeshPrimitive[];
+    }
+
+    export interface IGLTFImage extends IGLTFChildRootProperty {
+        uri: string;
+    }
+
+    export interface IGLTFSampler extends IGLTFChildRootProperty {
+        magFilter?: number;
+        minFilter?: number;
+        wrapS?: number;
+        wrapT?: number;
+    }
+
+    export interface IGLTFTexture extends IGLTFChildRootProperty {
+        sampler: string;
+        source: string;
+
+        format?: ETextureFormat;
+        internalFormat?: ETextureFormat;
+        target?: number;
+        type?: number;
+        
+        // Babylon.js values (optimize)
+        babylonTexture?: Texture;
+    }
+
+    export interface IGLTFAmbienLight {
+        color?: number[];
+    }
+
+    export interface IGLTFDirectionalLight {
+        color?: number[];
+    }
+
+    export interface IGLTFPointLight {
+        color?: number[];
+        constantAttenuation?: number;
+        linearAttenuation?: number;
+        quadraticAttenuation?: number;
+    }
+
+    export interface IGLTFSpotLight {
+        color?: number[];
+        constantAttenuation?: number;
+        fallOfAngle?: number;
+        fallOffExponent?: number;
+        linearAttenuation?: number;
+        quadraticAttenuation?: number;
+    }
+
+    export interface IGLTFLight extends IGLTFChildRootProperty {
+        type: string;
+    }
+
+    export interface IGLTFCameraOrthographic {
+        xmag: number;
+        ymag: number;
+        zfar: number;
+        znear: number;
+    }
+
+    export interface IGLTFCameraPerspective {
+        aspectRatio: number;
+        yfov: number;
+        zfar: number;
+        znear: number;
+    }
+
+    export interface IGLTFCamera extends IGLTFChildRootProperty {
+        type: string;
+    }
+
+    export interface IGLTFAnimationChannelTarget {
+        id: string;
+        path: string;
+    }
+
+    export interface IGLTFAnimationChannel {
+        sampler: string;
+        target: IGLTFAnimationChannelTarget;
+    }
+
+    export interface IGLTFAnimationSampler {
+        input: string;
+        output: string;
+
+        interpolation?: string;
+    }
+
+    export interface IGLTFAnimation extends IGLTFChildRootProperty {
+        channels?: IGLTFAnimationChannel[];
+        parameters?: Object;
+        samplers?: Object;
+    }
+
+    export interface IGLTFNodeInstanceSkin {
+        skeletons: string[];
+        skin: string;
+        meshes: string[];
+    }
+
+    export interface IGLTFSkins extends IGLTFChildRootProperty {
+        bindShapeMatrix: number[];
+        inverseBindMatrices: string;
+        jointNames: string[];
+
+        babylonSkeleton?: Skeleton;
+    }
+
+    export interface IGLTFNode extends IGLTFChildRootProperty {
+        camera?: string;
+        children: string[];
+        skin?: string;
+        jointName?: string;
+        light?: string;
+        matrix: number[];
+        mesh?: string;
+        meshes?: string[];
+        rotation?: number[];
+        scale?: number[];
+        translation?: number[];
+
+        // Babylon.js values (optimize)
+        babylonNode?: Node;
+    }
+
+    export interface IGLTFScene extends IGLTFChildRootProperty {
+        nodes: string[];
+    }
+
+    /**
+    * Runtime
+    */
+    export interface IGLTFRuntime {
+        extensions: Object;
+        accessors: Object;
+        buffers: Object;
+        bufferViews: Object;
+        meshes: Object;
+        lights: Object;
+        cameras: Object;
+        nodes: Object;
+        images: Object;
+        textures: Object;
+        shaders: Object;
+        programs: Object;
+        samplers: Object;
+        techniques: Object;
+        materials: Object;
+        animations: Object;
+        skins: Object;
+
+        currentScene?: Object;
+        scenes: Object; // v1.1
+
+        extensionsUsed: string[];
+        extensionsRequired?: string[]; // v1.1
+
+        buffersCount: number;
+        shaderscount: number;
+
+        scene: Scene;
+        rootUrl: string;
+
+        loadedBufferCount: number;
+        loadedBufferViews: { [name: string]: ArrayBufferView };
+
+        loadedShaderCount: number;
+
+        importOnlyMeshes: boolean;
+        importMeshesNames?: string[];
+
+        dummyNodes: Node[];
+    }
+
+    /**
+    * Bones
+    */
+    export interface INodeToRoot {
+        bone: Bone;
+        node: IGLTFNode;
+        id: string;
+    }
+
+    export interface IJointNode {
+        node: IGLTFNode;
+        id: string;
+    }
+}

+ 255 - 0
loaders/src/glTF/1.0/babylon.glTFLoaderUtils.ts

@@ -0,0 +1,255 @@
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON.GLTF1 {
+    /**
+    * Utils functions for GLTF
+    */
+    export class GLTFUtils {
+        /**
+         * Sets the given "parameter" matrix
+         * @param scene: the {BABYLON.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
+         */
+        public static SetMatrix(scene: Scene, source: Node, parameter: IGLTFTechniqueParameter, uniformName: string, shaderMaterial: ShaderMaterial | Effect): void {
+            var mat: Matrix = 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());
+            }
+            else {
+                debugger;
+            }
+
+            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)
+         */
+        public static SetUniform(shaderMaterial: ShaderMaterial | Effect, uniform: string, value: any, type: number): boolean {
+            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;
+            }
+        }
+
+        /**
+        * If the uri is a base64 string
+        * @param uri: the uri to test
+        */
+        public static IsBase64(uri: string): boolean {
+            return uri.length < 5 ? false : uri.substr(0, 5) === "data:";
+        }
+
+        /**
+        * Decode the base64 uri
+        * @param uri: the uri to decode
+        */
+        public static DecodeBase64(uri: string): ArrayBuffer {
+            var decodedString = atob(uri.split(",")[1]);
+            var bufferLength = decodedString.length;
+            var bufferView = new Uint8Array(new ArrayBuffer(bufferLength));
+
+            for (var i = 0; i < bufferLength; i++) {
+                bufferView[i] = decodedString.charCodeAt(i);
+            }
+
+            return bufferView.buffer;
+        }
+
+        /**
+        * Returns the wrap mode of the texture
+        * @param mode: the mode value
+        */
+        public static GetWrapMode(mode: number): number {
+            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
+         */
+        public static GetByteStrideFromType(accessor: IGLTFAccessor): number {
+            // Needs this function since "byteStride" isn't requiered in glTF format
+            var 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
+         */
+        public static GetTextureFilterMode(mode: number): ETextureFilterType {
+            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;
+            }
+        }
+
+        public static GetBufferFromBufferView(gltfRuntime: IGLTFRuntime, bufferView: IGLTFBufferView, byteOffset: number, byteLength: number, componentType: EComponentType): ArrayBufferView {
+            var byteOffset = bufferView.byteOffset + byteOffset;
+
+            var loadedBufferView = gltfRuntime.loadedBufferViews[bufferView.buffer];
+            if (byteOffset + byteLength > loadedBufferView.byteLength) {
+                throw new Error("Buffer access is out of range");
+            }
+
+            var 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
+         */
+        public static GetBufferFromAccessor(gltfRuntime: IGLTFRuntime, accessor: IGLTFAccessor): any {
+            var bufferView: IGLTFBufferView = gltfRuntime.bufferViews[accessor.bufferView];
+            var 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
+         */
+        public static DecodeBufferToText(view: ArrayBufferView): string {
+            var result = "";
+            var length = view.byteLength;
+
+            for (var 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
+         */
+        public static GetDefaultMaterial(scene: Scene): ShaderMaterial {
+            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");
+
+                var shaderPath = {
+                    vertex: "GLTFDefaultMaterial",
+                    fragment: "GLTFDefaultMaterial"
+                };
+
+                var options = {
+                    attributes: ["position"],
+                    uniforms: ["worldView", "projection", "u_emission"],
+                    samplers: [],
+                    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
+        private static _DefaultMaterial: ShaderMaterial = null;
+    }
+}

+ 26 - 28
loaders/src/glTF/babylon.glTFMaterialsCommonExtension.ts

@@ -1,6 +1,6 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
-module BABYLON {
+module BABYLON.GLTF1 {
     interface IGLTFMaterialsCommonExtensionValues {
         ambient?: number[] | string;
         diffuse?: number[] | string;
@@ -55,17 +55,17 @@ module BABYLON {
         quadraticAttenuation: number;
     }
 
-    export class GLTFMaterialsCommonExtension extends GLTFFileLoaderExtension {
+    export class GLTFMaterialsCommonExtension extends GLTFLoaderExtension {
 
         constructor() {
             super("KHR_materials_common");
         }
 
-        protected postCreateRuntime(runtime: IGLTFRuntime): void {
-            if (!runtime.gltf.extensions) return;
+        public loadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError: () => void): boolean {
+            if (!gltfRuntime.extensions) return false;
 
-            var extension = runtime.gltf.extensions[this.name];
-            if (!extension) return;
+            var extension = gltfRuntime.extensions[this.name];
+            if (!extension) return false;
 
             // Create lights
             var lights: IGLTFRuntimeCommonExtension = extension.lights;
@@ -75,17 +75,17 @@ module BABYLON {
 
                     switch (light.type) {
                         case "ambient":
-                            var ambientLight = new HemisphericLight(light.name, new Vector3(0, 1, 0), runtime.babylonScene);
+                            var ambientLight = new HemisphericLight(light.name, new Vector3(0, 1, 0), gltfRuntime.scene);
                             var ambient = light.ambient;
                             ambientLight.diffuse = Color3.FromArray(ambient.color || [1, 1, 1]);
                             break;
                         case "point":
-                            var pointLight = new PointLight(light.name, new Vector3(10, 10, 10), runtime.babylonScene);
+                            var pointLight = new PointLight(light.name, new Vector3(10, 10, 10), gltfRuntime.scene);
                             var point = light.point;
                             pointLight.diffuse = Color3.FromArray(point.color || [1, 1, 1]);
                             break;
                         case "directional":
-                            var dirLight = new DirectionalLight(light.name, new Vector3(0, -1, 0), runtime.babylonScene);
+                            var dirLight = new DirectionalLight(light.name, new Vector3(0, -1, 0), gltfRuntime.scene);
                             var directional = light.directional;
                             dirLight.diffuse = Color3.FromArray(directional.color || [1, 1, 1]);
                             break;
@@ -94,23 +94,25 @@ module BABYLON {
                             var spotLight = new SpotLight(light.name, new Vector3(0, 10, 0), new Vector3(0, -1, 0),
                                                           light.spot.fallOffAngle || Math.PI,
                                                           light.spot.fallOffExponent || 0.0,
-                                                          runtime.babylonScene);
+                                                          gltfRuntime.scene);
                             spotLight.diffuse = Color3.FromArray(spot.color || [1, 1, 1]);
                             break;
-                        default: Tools.Warn("GLTF Materials Common extension: light type \"" + light.type + "\” not supported"); break;
+                        default: Tools.Warn("GLTF Material Common extension: light type \"" + light.type + "\” not supported"); break;
                     }
                 }
             }
+
+            return false;
         }
 
-        protected loadMaterial(runtime: IGLTFRuntime, index: number): boolean {
-            var material = runtime.gltf.materials[index];
+        public loadMaterialAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (material: Material) => void, onError: () => void): boolean {
+            var material: IGLTFMaterial = gltfRuntime.materials[id];
             if (!material || !material.extensions) return false;
 
             var extension: IGLTFMaterialsCommonExtension = material.extensions[this.name];
             if (!extension) return false;
 
-            var standardMaterial = new StandardMaterial(material.name || "mat" + index, runtime.babylonScene);
+            var standardMaterial = new StandardMaterial(id, gltfRuntime.scene);
             standardMaterial.sideOrientation = Material.CounterClockWiseSideOrientation;
 
             if (extension.technique === "CONSTANT") {
@@ -120,11 +122,10 @@ module BABYLON {
             standardMaterial.backFaceCulling = extension.doubleSided === undefined ? false : !extension.doubleSided;
             standardMaterial.alpha = extension.values.transparency === undefined ? 1.0 : extension.values.transparency;
             standardMaterial.specularPower = extension.values.shininess === undefined ? 0.0 : extension.values.shininess;
-
-            /*
+            
             // Ambient
             if (typeof extension.values.ambient === "string") {
-                this._loadTexture(runtime, extension.values.ambient, standardMaterial, "ambientTexture", onError);
+                this._loadTexture(gltfRuntime, extension.values.ambient, standardMaterial, "ambientTexture", onError);
             }
             else {
                 standardMaterial.ambientColor = Color3.FromArray(extension.values.ambient || [0, 0, 0]);
@@ -132,7 +133,7 @@ module BABYLON {
 
             // Diffuse
             if (typeof extension.values.diffuse === "string") {
-                this._loadTexture(runtime, extension.values.diffuse, standardMaterial, "diffuseTexture", onError);
+                this._loadTexture(gltfRuntime, extension.values.diffuse, standardMaterial, "diffuseTexture", onError);
             }
             else {
                 standardMaterial.diffuseColor = Color3.FromArray(extension.values.diffuse || [0, 0, 0]);
@@ -140,7 +141,7 @@ module BABYLON {
 
             // Emission
             if (typeof extension.values.emission === "string") {
-                this._loadTexture(runtime, extension.values.emission, standardMaterial, "emissiveTexture", onError);
+                this._loadTexture(gltfRuntime, extension.values.emission, standardMaterial, "emissiveTexture", onError);
             }
             else {
                 standardMaterial.emissiveColor = Color3.FromArray(extension.values.emission || [0, 0, 0]);
@@ -148,26 +149,23 @@ module BABYLON {
 
             // Specular
             if (typeof extension.values.specular === "string") {
-                this._loadTexture(runtime, extension.values.specular, standardMaterial, "specularTexture", onError);
+                this._loadTexture(gltfRuntime, extension.values.specular, standardMaterial, "specularTexture", onError);
             }
             else {
                 standardMaterial.specularColor = Color3.FromArray(extension.values.specular || [0, 0, 0]);
             }
-            */
 
             return true;
         }
 
-        /*
-        private _loadTexture(runtime: IGLTFRuntime, id: string, material: StandardMaterial, propertyPath: string, onError: () => void): void {
+        private _loadTexture(gltfRuntime: IGLTFRuntime, id: string, material: StandardMaterial, propertyPath: string, onError: () => void): void {
             // Create buffer from texture url
-            GLTFFileLoaderBase.LoadTextureBufferAsync(runtime, id, (buffer) => {
+            GLTFLoaderBase.LoadTextureBufferAsync(gltfRuntime, id, (buffer) => {
                 // Create texture from buffer
-                GLTFFileLoaderBase.CreateTextureAsync(runtime, id, buffer, (texture) => material[propertyPath] = texture, onError);
+                GLTFLoaderBase.CreateTextureAsync(gltfRuntime, id, buffer, (texture) => material[propertyPath] = texture, onError);
             }, onError);
         }
-        */
     }
 
-    GLTFFileLoader.RegisterExtension(new GLTFMaterialsCommonExtension());
+    GLTFLoader.RegisterExtension(new GLTFMaterialsCommonExtension());
 }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1214 - 0
loaders/src/glTF/2.0/babylon.glTFLoader.ts


+ 10 - 10
loaders/src/glTF/babylon.glTFFileLoaderExtension.ts

@@ -1,7 +1,7 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
-module BABYLON {
-    export abstract class GLTFFileLoaderExtension {
+module BABYLON.GLTF2 {
+    export abstract class GLTFLoaderExtension {
         private _name: string;
 
         public constructor(name: string) {
@@ -22,24 +22,24 @@ module BABYLON {
         // ---------
 
         public static PostCreateRuntime(runtime: IGLTFRuntime): void {
-            for (var extensionName in GLTFFileLoader.Extensions) {
-                var extension = GLTFFileLoader.Extensions[extensionName];
+            for (var extensionName in GLTFLoader.Extensions) {
+                var extension = GLTFLoader.Extensions[extensionName];
                 extension.postCreateRuntime(runtime);
             }
         }
 
         public static LoadMaterial(runtime: IGLTFRuntime, index: number): void {
-            for (var extensionName in GLTFFileLoader.Extensions) {
-                var extension = GLTFFileLoader.Extensions[extensionName];
+            for (var extensionName in GLTFLoader.Extensions) {
+                var extension = GLTFLoader.Extensions[extensionName];
                 if (extension.loadMaterial(runtime, index)) {
                     return;
                 }
             }
 
-            var material = GLTFFileLoader.LoadMaterial(runtime, index);
+            var material = GLTFLoader.LoadMaterial(runtime, index);
             if (material) {
-                GLTFFileLoader.LoadMetallicRoughnessMaterialProperties(runtime, material);
-                GLTFFileLoader.LoadCommonMaterialProperties(runtime, material);
+                GLTFLoader.LoadMetallicRoughnessMaterialProperties(runtime, material);
+                GLTFLoader.LoadCommonMaterialProperties(runtime, material);
             }
         }
     }

+ 2 - 2
loaders/src/glTF/babylon.glTFFileLoaderInterfaces.ts

@@ -1,6 +1,6 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
-module BABYLON {
+module BABYLON.GLTF2 {
     /**
     * Enums
     */

+ 2 - 2
loaders/src/glTF/babylon.glTFFileLoaderUtils.ts

@@ -1,6 +1,6 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
-module BABYLON {
+module BABYLON.GLTF2 {
     /**
     * Utils functions for GLTF
     */

+ 9 - 9
loaders/src/glTF/babylon.glTFMaterialsPbrSpecularGlossinessExtension.ts

@@ -1,6 +1,6 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
-module BABYLON {
+module BABYLON.GLTF2 {
     interface IGLTFMaterialsPbrSpecularGlossiness {
         diffuseFactor: number[];
         diffuseTexture: IGLTFTextureInfo;
@@ -9,13 +9,13 @@ module BABYLON {
         specularGlossinessTexture: IGLTFTextureInfo;
     }
 
-    export class GLTFMaterialsPbrSpecularGlossinessExtension extends GLTFFileLoaderExtension {
+    export class GLTFMaterialsPbrSpecularGlossinessExtension extends GLTFLoaderExtension {
         constructor() {
             super("KHR_materials_pbrSpecularGlossiness");
         }
 
         protected loadMaterial(runtime: IGLTFRuntime, index: number): boolean {
-            var material = GLTFFileLoader.LoadMaterial(runtime, index);
+            var material = GLTFLoader.LoadMaterial(runtime, index);
             if (!material || !material.extensions) return false;
 
             var properties: IGLTFMaterialsPbrSpecularGlossiness = material.extensions[this.name];
@@ -26,10 +26,10 @@ module BABYLON {
             material.babylonMaterial.microSurface = properties.glossinessFactor === undefined ? 1 : properties.glossinessFactor;
 
             if (properties.diffuseTexture) {
-                GLTFFileLoader.LoadTextureAsync(runtime, properties.diffuseTexture,
+                GLTFLoader.LoadTextureAsync(runtime, properties.diffuseTexture,
                     texture => {
                         material.babylonMaterial.albedoTexture = texture;
-                        GLTFFileLoader.LoadAlphaProperties(runtime, material);
+                        GLTFLoader.LoadAlphaProperties(runtime, material);
                     },
                     () => {
                         Tools.Warn("Failed to load diffuse texture");
@@ -37,7 +37,7 @@ module BABYLON {
             }
 
             if (properties.specularGlossinessTexture) {
-                GLTFFileLoader.LoadTextureAsync(runtime, properties.specularGlossinessTexture,
+                GLTFLoader.LoadTextureAsync(runtime, properties.specularGlossinessTexture,
                     texture => {
                         material.babylonMaterial.reflectivityTexture = texture;
                         material.babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
@@ -47,10 +47,10 @@ module BABYLON {
                     });
             }
 
-            GLTFFileLoader.LoadCommonMaterialProperties(runtime, material);
+            GLTFLoader.LoadCommonMaterialProperties(runtime, material);
             return true;
         }
     }
 
-    GLTFFileLoader.RegisterExtension(new GLTFMaterialsPbrSpecularGlossinessExtension());
+    GLTFLoader.RegisterExtension(new GLTFMaterialsPbrSpecularGlossinessExtension());
 }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 157 - 1184
loaders/src/glTF/babylon.glTFFileLoader.ts