Ver código fonte

Merge pull request #1766 from julien-moreau/master

GLTF materials common extension, getting support of lights
David Catuhe 8 anos atrás
pai
commit
6cc07d0cf7

+ 2 - 1
Tools/Gulp/config.json

@@ -437,7 +437,8 @@
         "../../loaders/src/glTF/babylon.glTFFileLoader.ts",
         "../../loaders/src/glTF/babylon.glTFFileLoaderUtils.ts",
         "../../loaders/src/glTF/babylon.glTFFileLoaderExtension.ts",
-        "../../loaders/src/glTF/babylon.glTFBinaryExtension.ts"
+        "../../loaders/src/glTF/babylon.glTFBinaryExtension.ts",
+        "../../loaders/src/glTF/babylon.glTFMaterialCommonExtension.ts"
       ],
       "output": "babylon.glTFFileLoader.js"
     }],

+ 24 - 16
loaders/src/glTF/babylon.glTFFileLoader.ts

@@ -1175,6 +1175,7 @@ module BABYLON {
     export class GLTFFileLoaderBase {
         public static CreateRuntime(parsedData: any, scene: Scene, rootUrl: string): IGLTFRuntime {
             var gltfRuntime: IGLTFRuntime = {
+                extensions: {},
                 accessors: {},
                 buffers: {},
                 bufferViews: {},
@@ -1212,6 +1213,10 @@ module BABYLON {
             }
 
             // Parse
+            if (parsedData.extensions) {
+                parseObject(parsedData.extensions, "extensions", gltfRuntime);
+            }
+
             if (parsedData.extensionsUsed) {
                 parseObject(parsedData.extensionsUsed, "extensionsUsed", gltfRuntime);
             }
@@ -1628,24 +1633,27 @@ module BABYLON {
             scene.useRightHandedSystem = true;
 
             GLTFFileLoaderExtension.LoadRuntimeAsync(scene, data, rootUrl, gltfRuntime => {
-                // Create nodes
-                this._createNodes(gltfRuntime);
-
-                // Load buffers, shaders, materials, etc.
-                this._loadBuffersAsync(gltfRuntime, () => {
-                    this._loadShadersAsync(gltfRuntime, () => {
-                        importMaterials(gltfRuntime);
-                        postLoad(gltfRuntime);
-
-                        if (!GLTFFileLoader.IncrementalLoading) {
-                            onSuccess();
-                        }
+                // Load runtime extensios
+                GLTFFileLoaderExtension.LoadRuntimeExtensionsAsync(gltfRuntime, () => {
+                    // Create nodes
+                    this._createNodes(gltfRuntime);
+
+                    // Load buffers, shaders, materials, etc.
+                    this._loadBuffersAsync(gltfRuntime, () => {
+                        this._loadShadersAsync(gltfRuntime, () => {
+                            importMaterials(gltfRuntime);
+                            postLoad(gltfRuntime);
+
+                            if (!GLTFFileLoader.IncrementalLoading) {
+                                onSuccess();
+                            }
+                        });
                     });
-                });
 
-                if (GLTFFileLoader.IncrementalLoading) {
-                    onSuccess();
-                }
+                    if (GLTFFileLoader.IncrementalLoading) {
+                        onSuccess();
+                    }
+                }, onError);
             }, onError);
 
             return true;

+ 18 - 0
loaders/src/glTF/babylon.glTFFileLoaderExtension.ts

@@ -21,6 +21,14 @@ module BABYLON {
         }
 
         /**
+         * 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
         */
@@ -74,6 +82,16 @@ module BABYLON {
             });
         }
 
+        public static LoadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError: () => void): void {
+            GLTFFileLoaderExtension.ApplyExtensions(loaderExtension => {
+                return loaderExtension.loadRuntimeExtensionsAsync(gltfRuntime, onSuccess, onError);
+            }, () => {
+                setTimeout(() => {
+                    onSuccess();
+                });
+            });
+        }
+
         public static LoadBufferAsync(gltfRuntime: IGLTFRuntime, id: string, onSuccess: (bufferView: ArrayBufferView) => void, onError: () => void): void {
             GLTFFileLoaderExtension.ApplyExtensions(loaderExtension => {
                 return loaderExtension.loadBufferAsync(gltfRuntime, id, onSuccess, onError);

+ 1 - 0
loaders/src/glTF/babylon.glTFFileLoaderInterfaces.ts

@@ -329,6 +329,7 @@ module BABYLON {
     * Runtime
     */
     export interface IGLTFRuntime {
+        extensions: Object;
         accessors: Object;
         buffers: Object;
         bufferViews: Object;

+ 140 - 0
loaders/src/glTF/babylon.glTFMaterialCommonExtension.ts

@@ -0,0 +1,140 @@
+/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON {
+    interface IGLTFMaterialCommonExtensionValues {
+        ambient?: number[] | string;
+        diffuse?: number[] | string;
+        emission?: number[] | string;
+        specular?: number[] | string;
+        shininess?: number;
+        transparency?: number;
+    };
+
+    interface IGLTFMaterialCommonExtension {
+        technique: string;
+        transparent?: number;
+        doubleSided?: boolean;
+        values: IGLTFMaterialCommonExtensionValues;
+    };
+
+    interface IGLTFRuntimeCommonExtension {
+        lights: Object;
+    }
+
+    interface IGLTFLightCommonExtension {
+        name: string;
+        type: string;
+
+        ambient?: IGLTFAmbientLightCommonExtension;
+        point?: IGLTFPointLightCommonExtension;
+    };
+
+    interface IGLTFPointLightCommonExtension {
+        color: number[];
+        constantAttenuation: number;
+        linearAttenuation: number;
+        quadraticAttenuation: number;
+    }
+
+    interface IGLTFAmbientLightCommonExtension {
+        color: number[];
+    }
+
+    export class GLTFMaterialCommonExtension extends GLTFFileLoaderExtension {
+
+        constructor() {
+            super("KHR_materials_common");
+        }
+
+        public loadRuntimeExtensionsAsync(gltfRuntime: IGLTFRuntime, onSuccess: () => void, onError: () => void): boolean {
+            if (!gltfRuntime.extensions) return false;
+
+            var extension = gltfRuntime.extensions[this.name];
+            if (!extension) return false;
+
+            // Create lights
+            var lights: IGLTFRuntimeCommonExtension = extension.lights;
+            if (lights) {
+                for (var thing in lights) {
+                    var light: IGLTFLightCommonExtension = lights[thing];
+
+                    switch (light.type) {
+                        case "ambient":
+                            var ambientLight = new HemisphericLight(light.name, new Vector3(0, 1, 0), gltfRuntime.scene);
+                            var ambient = light.ambient;
+                            ambientLight.diffuse = Color3.FromArray(ambient.color);
+                            break;
+                        case "point":
+                            var pointLight = new PointLight(light.name, Vector3.Zero(), gltfRuntime.scene);
+                            var point = light.point;
+                            pointLight.diffuse = Color3.FromArray(point.color);
+                            pointLight.position = new Vector3(10, 10, 10);
+                            break;
+                        default: Tools.Warn("GLTF Material Common extension: light type \"" + light.type + "\” not supported"); return false;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        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: IGLTFMaterialCommonExtension = material.extensions[this.name];
+            if (!extension) return false;
+
+            var standardMaterial = new StandardMaterial(id, gltfRuntime.scene);
+            standardMaterial.sideOrientation = Material.CounterClockWiseSideOrientation;
+
+            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(gltfRuntime, extension.values.ambient, standardMaterial, "ambientTexture", onError);
+            }
+            else {
+                standardMaterial.ambientColor = Color3.FromArray(extension.values.ambient || [0, 0, 0]);
+            }
+
+            // Diffuse
+            if (typeof extension.values.diffuse === "string") {
+                this._loadTexture(gltfRuntime, extension.values.diffuse, standardMaterial, "diffuseTexture", onError);
+            }
+            else {
+                standardMaterial.diffuseColor = Color3.FromArray(extension.values.diffuse || [0, 0, 0]);
+            }
+
+            // Emission
+            if (typeof extension.values.emission === "string") {
+                this._loadTexture(gltfRuntime, extension.values.emission, standardMaterial, "emissiveTexture", onError);
+            }
+            else {
+                standardMaterial.emissiveColor = Color3.FromArray(extension.values.emission || [0, 0, 0]);
+            }
+
+            // Specular
+            if (typeof extension.values.specular === "string") {
+                this._loadTexture(gltfRuntime, extension.values.specular, standardMaterial, "specularTexture", onError);
+            }
+            else {
+                standardMaterial.specularColor = Color3.FromArray(extension.values.specular || [0, 0, 0]);
+            }
+
+            return true;
+        }
+
+        private _loadTexture(gltfRuntime: IGLTFRuntime, id: string, material: StandardMaterial, propertyPath: string, onError: () => void): void {
+            // Create buffer from texture url
+            GLTFFileLoaderBase.LoadTextureBufferAsync(gltfRuntime, id, (buffer) => {
+                // Create texture from buffer
+                GLTFFileLoaderBase.CreateTextureAsync(gltfRuntime, id, buffer, (texture) => material[propertyPath] = texture, onError);
+            }, onError);
+        }
+    }
+
+    GLTFFileLoader.RegisterExtension(new GLTFMaterialCommonExtension());
+}