Bläddra i källkod

First version of glTF khr_lights extension importing.

Michael Bond 7 år sedan
förälder
incheckning
704235a393

+ 4 - 2
Tools/Gulp/config.json

@@ -1512,7 +1512,8 @@
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderUtils.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderUtils.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts"
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts",
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_lights.ts"
                 ],
                 ],
                 "doNotIncludeInBundle": true,
                 "doNotIncludeInBundle": true,
                 "output": "babylon.glTF2FileLoader.js"
                 "output": "babylon.glTF2FileLoader.js"
@@ -1531,7 +1532,8 @@
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderUtils.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderUtils.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts"
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts",
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_lights.ts"
                 ],
                 ],
                 "output": "babylon.glTFFileLoader.js"
                 "output": "babylon.glTFFileLoader.js"
             }
             }

+ 165 - 0
loaders/src/glTF/2.0/Extensions/KHR_lights.ts

@@ -0,0 +1,165 @@
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON.GLTF2.Extensions {
+    interface IGLTFLight {
+        type: "directional" | "point" | "spot" | "hemisphere";
+        color: [number, number, number];
+        intensity: number;
+        // Runtime values
+        index: number;
+        babylonLight: Light;
+    }
+
+    interface IKHRLights {
+        lights: IGLTFLight[];
+        // diffuseFactor: number[];
+        // diffuseTexture: IGLTFTextureInfo;
+        // specularFactor: number[];
+        // glossinessFactor: number;
+        // specularGlossinessTexture: IGLTFTextureInfo;
+    }
+
+    interface IGLTFLightReference {
+        light: number;
+        babylonLight: Light;
+    }
+
+    export class KHRLights extends GLTFLoaderExtension {
+        public get name(): string {
+            return "KHR_lights";
+        }
+
+        private applyCommonProperties(light: Light, lightInfo: IGLTFLight): void {
+            if (lightInfo.color) {
+                light.diffuse.copyFromFloats(lightInfo.color[0], lightInfo.color[1], lightInfo.color[2]);
+            } else {
+                light.diffuse.copyFromFloats(1, 1, 1);
+            }
+
+            if (lightInfo.intensity !== undefined) {
+                light.intensity = lightInfo.intensity;
+            } else {
+                light.intensity = 1;
+            }
+        }
+
+        protected _loadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean { 
+            return this._loadExtension<IGLTFLightReference>(context, scene, (context, extension, onComplete) => {
+                if (extension.light >= 0 && loader._gltf.extensions) {
+                    const lightInfo = loader._gltf.extensions.KHR_lights.lights[extension.light];
+                    if (lightInfo.type !== 'ambient' && lightInfo.type !== 'hemisphere') {
+                        return;
+                    }
+
+                    const direction = new Vector3(0, 1, 0);
+                    extension.babylonLight = new BABYLON.HemisphericLight("light", direction, loader._babylonScene);
+
+                    this.applyCommonProperties(extension.babylonLight, lightInfo);
+                    
+                    if (lightInfo.type == 'hemisphere') {
+                        const groundColor = lightInfo.hemisphere && lightInfo.hemisphere.groundColor ? lightInfo.hemisphere.groundColor : [1, 1, 1];
+                        (extension.babylonLight as HemisphericLight).groundColor.copyFromFloats(groundColor[0], groundColor[1], groundColor[2]);
+                    } else {
+                        const groundColor = lightInfo.color ? lightInfo.color : [1, 1, 1];
+                        (extension.babylonLight as HemisphericLight).groundColor.copyFromFloats(groundColor[0], groundColor[1], groundColor[2]);
+                    }
+                }
+                
+                onComplete();
+            });
+        }
+
+        protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean { 
+            return this._loadExtension<IGLTFLightReference>(context, node, (context, extension, onComplete) => {
+                if (extension.light >= 0 && loader._gltf.extensions) {
+                    const lightInfo = loader._gltf.extensions.KHR_lights.lights[extension.light];
+                    const name = node.name || 'Light';
+                    let position: Vector3 = Vector3.Zero();
+                    let rotation: Quaternion = Quaternion.Identity();
+                    let scaling: Vector3 = Vector3.One();
+
+                    let matrix;
+                    if (node.matrix) {
+                        matrix = Matrix.FromArray(node.matrix);
+                        matrix.decompose(scaling, rotation, position);
+                    } else {
+                        matrix = Matrix.Identity();
+                    }
+
+                    let direction = new Vector3(1, 0, 0);
+                    if (lightInfo.type == 'directional' || lightInfo.type == 'spot') {
+                        const rotationMatrix = new Matrix();
+                        rotation.toRotationMatrix(rotationMatrix);
+                        direction = Vector3.TransformCoordinates(direction, rotationMatrix);
+                    }
+
+                    let light: Light;
+                    if (lightInfo.type == 'directional') {
+                        light = new DirectionalLight(name, direction, loader._babylonScene);
+                    } else if (lightInfo.type == 'spot') {
+                        // TODO - translate glTF values for spotlight
+                        const angle = 90;
+                        const exponent = 1;
+                        light = new SpotLight(name, position, direction, angle, exponent, loader._babylonScene);
+                    } else {
+                        light = new PointLight(name, position, loader._babylonScene);
+                    }
+
+                    this.applyCommonProperties(light, lightInfo);
+                    
+                    extension.babylonLight = light;
+                    extension.babylonLight.parent = node.parent ? node.parent.babylonMesh : null;
+                    
+                    if (node.children) {
+                        for (const index of node.children) {
+                            const childNode = GLTFLoader._GetProperty(loader._gltf.nodes, index);
+                            if (!childNode) {
+                                throw new Error(context + ": Failed to find child node " + index);
+                            }
+        
+                            loader._loadNode("#/nodes/" + index, childNode);
+                        }
+                    }
+        
+                    // this.onMeshLoadedObservable.notifyObservers(node.babylonMesh);
+                }
+                onComplete();
+            });
+        }
+
+        protected _loadRoot(loader: GLTFLoader, context: string, root: IGLTF): boolean {
+            return this._loadExtension<IKHRLights>(context, root, (context, extension, onComplete) => {
+                // GLTFLoader._AssignIndices(loader._gltf.accessors);
+                // for (const light of extension.lights) {
+                //     this._loadLight(context, light);
+                // }
+                extension.lights.forEach((light: IGLTFLight, idx: number) => {
+                    light.index = idx;
+                });
+                onComplete();
+            });
+        }
+
+        // protected _loadExtension<T>(context: string, property: IGLTFProperty, action: (context: string, extension: T, onComplete: () => void) => void): boolean {
+        //     return super._loadExtension(context, property, action);
+        // }
+        
+        // protected _loadNode(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean {
+        //     return this._loadExtension<IKHRLights>(context, material, (context, extension, onComplete) => {
+        //         loader._createPbrMaterial(material);
+        //         loader._loadMaterialBaseProperties(context, material);
+        //         // this._loadSpecularGlossinessProperties(loader, context, material, extension);
+        //         assign(material.babylonMaterial, true);
+        //         onComplete();
+        //     });
+        // }
+
+        // private _loadLight(context: string, light: IGLTFLight) {
+        //     // Create appropriate Babylon.js light
+        //     light.babylonLight = undefined;//new DirectionalLight("stuff", new Vector3(0, 1, 0), null);
+        // }
+
+    }
+
+    GLTFLoader.RegisterExtension(new KHRLights());
+}

+ 5 - 0
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -198,6 +198,9 @@ module BABYLON.GLTF2 {
             GLTFLoader._AssignIndices(this._gltf.skins);
             GLTFLoader._AssignIndices(this._gltf.skins);
             GLTFLoader._AssignIndices(this._gltf.textures);
             GLTFLoader._AssignIndices(this._gltf.textures);
 
 
+            // Handle global extensions as they may add their own data types.
+            GLTFLoaderExtension.LoadRoot(this, "#/", this._gltf);
+
             if (data.bin) {
             if (data.bin) {
                 const buffers = this._gltf.buffers;
                 const buffers = this._gltf.buffers;
                 if (buffers && buffers[0] && !buffers[0].uri) {
                 if (buffers && buffers[0] && !buffers[0].uri) {
@@ -290,6 +293,8 @@ module BABYLON.GLTF2 {
         }
         }
 
 
         private _loadScene(context: string, scene: IGLTFScene, nodeNames: any): void {
         private _loadScene(context: string, scene: IGLTFScene, nodeNames: any): void {
+            GLTFLoaderExtension.LoadScene(this, context, scene)) {
+            
             this._rootNode = { babylonMesh: new Mesh("__root__", this._babylonScene) } as IGLTFNode;
             this._rootNode = { babylonMesh: new Mesh("__root__", this._babylonScene) } as IGLTFNode;
 
 
             switch (this.coordinateSystemMode) {
             switch (this.coordinateSystemMode) {

+ 12 - 0
loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts

@@ -10,6 +10,10 @@ module BABYLON.GLTF2 {
 
 
         protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean { return false; }
         protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean { return false; }
 
 
+        protected _loadRoot(loader: GLTFLoader, context: string, root: IGLTF): boolean { return false; }
+
+        protected _loadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean { return false; }
+
         protected _loadMaterial(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean { return false; }
         protected _loadMaterial(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean { return false; }
 
 
         protected _loadExtension<T>(context: string, property: IGLTFProperty, action: (context: string, extension: T, onComplete: () => void) => void): boolean {
         protected _loadExtension<T>(context: string, property: IGLTFProperty, action: (context: string, extension: T, onComplete: () => void) => void): boolean {
@@ -43,6 +47,14 @@ module BABYLON.GLTF2 {
             return this._ApplyExtensions(extension => extension._traverseNode(loader, context, node, action, parentNode));
             return this._ApplyExtensions(extension => extension._traverseNode(loader, context, node, action, parentNode));
         }
         }
 
 
+        public static LoadRoot(loader: GLTFLoader, context: string, root: IGLTF): boolean {
+            return this._ApplyExtensions(extension => extension._loadRoot(loader, context, root));
+        }
+
+        public static LoadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean {
+            return this._ApplyExtensions(extension => extension._loadScene(loader, context, scene));
+        }
+
         public static LoadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean {
         public static LoadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean {
             return this._ApplyExtensions(extension => extension._loadNode(loader, context, node));
             return this._ApplyExtensions(extension => extension._loadNode(loader, context, node));
         }
         }