瀏覽代碼

light are now tracked by meshes

David Catuhe 8 年之前
父節點
當前提交
fb7d9d8ace

+ 0 - 1
Tools/Gulp/config.json

@@ -22,7 +22,6 @@
             "../../src/Tools/babylon.database.js",
             "../../src/Tools/babylon.tools.tga.js",
             "../../src/Tools/babylon.smartArray.js",
-            "../../src/Tools/babylon.observableArray.js",
             "../../src/Tools/babylon.stringDictionary.js",
             "../../src/Tools/babylon.tools.js",
             "../../src/States/babylon.alphaCullingState.js",

文件差異過大導致無法顯示
+ 6900 - 6903
dist/preview release/babylon.d.ts


文件差異過大導致無法顯示
+ 6900 - 6903
dist/preview release/babylon.module.d.ts


+ 83 - 18
src/Lights/babylon.light.ts

@@ -70,31 +70,46 @@
         @serialize()
         public range = Number.MAX_VALUE;
 
-        @serialize()
-        public includeOnlyWithLayerMask = 0;
-
-        private _includedOnlyMeshes = new ObservableArray<AbstractMesh>();
-        public get includedOnlyMeshes(): any {
+        private _includedOnlyMeshes: AbstractMesh[];
+        public get includedOnlyMeshes(): AbstractMesh[] {
             return this._includedOnlyMeshes;
         }
-        public set includedOnlyMeshes(value: any) {
-            this._includedOnlyMeshes = new ObservableArray<AbstractMesh>();
 
-            this._includedOnlyMeshes.push(value);
+        public set includedOnlyMeshes(value: AbstractMesh[]) {
+            this._includedOnlyMeshes = value;
+            this._hookArray(value);
         }
 
-        private _excludedMeshes = new ObservableArray<AbstractMesh>();
-        public get excludedMeshes(): any {
+        private _excludedMeshes: AbstractMesh[];
+        public get excludedMeshes(): AbstractMesh[] {
             return this._excludedMeshes;
         }
-        public set excludedMeshes(value: any) {
-            this._excludedMeshes = new ObservableArray<AbstractMesh>();
+        public set excludedMeshes(value: AbstractMesh[]) {
+            this._excludedMeshes = value;
+            this._hookArray(value);
+        }        
+
+        @serialize("excludeWithLayerMask")
+        private _excludeWithLayerMask = 0;
+        public get excludeWithLayerMask(): number {
+            return this._excludeWithLayerMask;
+        }
 
-            this._excludedMeshes.push(value);
+        public set excludeWithLayerMask(value: number) {
+            this._excludeWithLayerMask = value;
+            this._resyncMeshes();
         }        
 
-        @serialize()
-        public excludeWithLayerMask = 0;
+        @serialize("includeOnlyWithLayerMask")
+        private _includeOnlyWithLayerMask = 0;
+        public get includeOnlyWithLayerMask(): number {
+            return this._includeOnlyWithLayerMask;
+        }
+
+        public set includeOnlyWithLayerMask(value: number) {
+            this._includeOnlyWithLayerMask = value;
+            this._resyncMeshes();
+        }          
 
         @serialize()
         public lightmapMode = 0;
@@ -116,9 +131,10 @@
             super(name, scene);
             this.getScene().addLight(this);
 
-            this._excludedMeshes.onDataAdded.add((mesh) => {
-                
-            });
+            this.includedOnlyMeshes = new Array<AbstractMesh>();
+            this.excludedMeshes = new Array<AbstractMesh>();
+
+            this._resyncMeshes();
         }
         /**
          * Returns the string "Light".  
@@ -142,6 +158,19 @@
             }
             return ret;
         } 
+
+
+        /**
+         * Set the enabled state of this node.
+         * @param {boolean} value - the new enabled state
+         * @see isEnabled
+         */
+        public setEnabled(value: boolean): void {
+            super.setEnabled(value);
+
+            this._resyncMeshes();
+        }
+
         /**
          * Returns the Light associated shadow generator.  
          */
@@ -224,6 +253,12 @@
 
             // Animations
             this.getScene().stopAnimation(this);
+
+            // Remove from meshes
+            for (var mesh of this.getScene().meshes) {
+                mesh._removeLightSource(this);
+            }
+
             // Remove from scene
             this.getScene().removeLight(this);
             super.dispose();
@@ -332,5 +367,35 @@
 
             return light;
         }
+
+        private _hookArray(array: AbstractMesh[]): void {
+            var oldPush = array.push;
+            array.push = function(...items: AbstractMesh[]): number {
+                var result = oldPush.apply(array, items);
+
+                for (var item of items) {
+                    item._resyncLighSource(this);
+                }
+
+                return result;
+            }
+
+            var oldSplice = array.splice;
+            array.splice = function(index: number, deleteCount?: number): AbstractMesh[] {
+                var deleted = oldSplice.apply(array, [index, deleteCount]);
+
+                for (var item of deleted) {
+                    item._resyncLighSource(this);
+                }
+
+                return deleted;
+            }
+        }
+
+        private _resyncMeshes() {
+            for (var mesh of this.getScene().meshes) {
+                mesh._resyncLighSource(this);
+            }
+        }
     }
 }

+ 12 - 24
src/Materials/babylon.materialHelper.ts

@@ -7,22 +7,10 @@
             var needShadows = false;
             var lightmapMode = false;
 
-            for (var index = 0; index < scene.lights.length; index++) {
-                var light = scene.lights[index];
+            var count = 0;
+            for (var light of mesh._lightSources) {
+                count++;
 
-                if (!light.isEnabled()) {
-                    if (defines["LIGHT" + lightIndex] !== undefined) {
-                        defines["LIGHT" + lightIndex] = false;
-                    }
-                    continue;
-                }
-
-                if (!light.canAffectMesh(mesh)) {
-                    if (defines["LIGHT" + lightIndex] !== undefined) {
-                        defines["LIGHT" + lightIndex] = false;
-                    }
-                    continue;
-                }
                 needNormals = true;
 
                 if (defines["LIGHT" + lightIndex] === undefined) {
@@ -41,7 +29,7 @@
                     type = "DIRLIGHT" + lightIndex;
                 }
 
-                if (defines[type] === undefined) {
+                if (!needRebuild && defines[type] === undefined) {
                     needRebuild = true;
                 }
 
@@ -55,7 +43,7 @@
                 if (scene.shadowsEnabled) {
                     var shadowGenerator = <ShadowGenerator>light.getShadowGenerator();
                     if (mesh && mesh.receiveShadows && shadowGenerator) {
-                        if (defines["SHADOW" + lightIndex] === undefined) {
+                        if (!needRebuild && defines["SHADOW" + lightIndex] === undefined) {
                             needRebuild = true;
                         }
                         defines["SHADOW" + lightIndex] = true;
@@ -63,14 +51,14 @@
                         shadowEnabled = true;
 
                         if (shadowGenerator.usePoissonSampling) {
-                            if (defines["SHADOWPCF" + lightIndex] === undefined) {
+                            if (!needRebuild && defines["SHADOWPCF" + lightIndex] === undefined) {
                                 needRebuild = true;
                             }
 
                             defines["SHADOWPCF" + lightIndex] = true;
                         } 
                         else if (shadowGenerator.useExponentialShadowMap || shadowGenerator.useBlurExponentialShadowMap) {
-                            if (defines["SHADOWESM" + lightIndex] === undefined) {
+                            if (!needRebuild && defines["SHADOWESM" + lightIndex] === undefined) {
                                 needRebuild = true;
                             }
 
@@ -87,10 +75,10 @@
 
                 if (light.lightmapMode != Light.LIGHTMAP_DEFAULT ) {
                     lightmapMode = true;
-                    if (defines["LIGHTMAPEXCLUDED" + lightIndex] === undefined) {
+                    if (!needRebuild && defines["LIGHTMAPEXCLUDED" + lightIndex] === undefined) {
                         needRebuild = true;
                     }
-                    if (defines["LIGHTMAPNOSPECULAR" + lightIndex] === undefined) {
+                    if (!needRebuild && defines["LIGHTMAPNOSPECULAR" + lightIndex] === undefined) {
                         needRebuild = true;
                     }
                     defines["LIGHTMAPEXCLUDED" + lightIndex] = true;
@@ -106,20 +94,20 @@
             }
 
             // Resetting all other lights if any
-            for (var index = scene.lights.length; index < maxSimultaneousLights; index++) {
+            for (var index = count; index < maxSimultaneousLights; index++) {
                 if (defines["LIGHT" + lightIndex] !== undefined) {
                     defines["LIGHT" + lightIndex] = false;
                 }
             }
 
             let caps = scene.getEngine().getCaps();
-            if (defines["SHADOWFULLFLOAT"] === undefined) {
+            if (!needRebuild && defines["SHADOWFULLFLOAT"] === undefined) {
                 needRebuild = true;
             }
 
             defines["SHADOWFULLFLOAT"] = (needShadows && caps.textureFloat && caps.textureFloatLinearFiltering && caps.textureFloatRender);
 
-            if (defines["LIGHTMAPEXCLUDED"] === undefined) {
+            if (!needRebuild && defines["LIGHTMAPEXCLUDED"] === undefined) {
                 needRebuild = true;
             }
 

+ 10 - 0
src/Materials/babylon.standardMaterial.ts

@@ -614,6 +614,16 @@ module BABYLON {
                     }
                 }
                 this._defines._areTexturesDirty = false;
+            } else {
+                this._defines.DIFFUSE = false;
+                this._defines.AMBIENT = false;
+                this._defines.OPACITY = false;
+                this._defines.REFLECTION = false;
+                this._defines.EMISSIVE = false;
+                this._defines.LIGHTMAP = false;
+                this._defines.BUMP = false;
+                this._defines.REFRACTION = false;
+                this._defines.CAMERACOLORGRADING = false;
             }
 
             // Effect

+ 45 - 3
src/Mesh/babylon.abstractMesh.ts

@@ -224,7 +224,7 @@
 
         public _poseMatrix: Matrix;
 
-        public _lightSources = new SmartArray<Light>(8);
+        public _lightSources = new Array<Light>();
 
         // Loading properties
         public _waitingActions: any;
@@ -259,6 +259,8 @@
             super(name, scene);
 
             this.getScene().addMesh(this);
+
+            this._resyncLightSources();
         }
 
         /**
@@ -284,6 +286,48 @@
             return ret;
         }
 
+        public _resyncLightSources(): void {
+            this._lightSources.length = 0;
+
+            for (var light of this.getScene().lights) {
+                if (!light.isEnabled()) {
+                    continue;
+                }
+
+                if (light.canAffectMesh(this)) {
+                    this._lightSources.push(light);
+                }
+            }
+        }
+
+        public _resyncLighSource(light: Light): void {
+            var isIn = light.isEnabled() && light.canAffectMesh(this);
+
+            var index = this._lightSources.indexOf(light);
+
+            if (index === -1) {
+                if (!isIn) {
+                    return;
+                }
+                this._lightSources.push(light);
+                return;
+            }
+
+            if (isIn) {
+                return;
+            }
+            this._lightSources.splice(index, 1);            
+        }
+
+        public _removeLightSource(light: Light): void {
+            var index = this._lightSources.indexOf(light);
+
+            if (index === -1) {
+                return;
+            }
+            this._lightSources.slice(index, 1);       
+        }
+
         /**
          * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z. 
          * If rotation quaternion is set, this Vector3 will (almost always) be the Zero vector!
@@ -1439,8 +1483,6 @@
                 }
             });
 
-            this._lightSources.dispose();
-
             // Edges
             if (this._edgesRenderer) {
                 this._edgesRenderer.dispose();

+ 0 - 64
src/Tools/babylon.observableArray.ts

@@ -1,64 +0,0 @@
-module BABYLON {
-    export class ObservableArray<T> {
-        public data: Array<T>;
-        public length: number = 0;
-
-        public onDataAdded = new Observable<T>();
-        public onDataRemoved = new Observable<T>();
-
-        constructor() {
-            this.data = new Array<T>();
-        }
-
-        public splice(start: number, deleteCount?: number): T[] {
-            var removed = this.data.splice(start, deleteCount);
-
-            if (this.onDataRemoved.hasObservers) {
-                for (var item of removed) {
-                    this.onDataRemoved.notifyObservers(item);
-                }
-            }
-
-            return removed;
-        }
-
-        public push(...items: T[]): void {
-            this.data.push(...items);
-
-            if (this.onDataAdded.hasObservers) {
-                for (var item of items) {
-                    this.onDataAdded.notifyObservers(item);
-                }
-            }
-        }
-
-        public forEach(func: (content: T) => void): void {
-            for (var index = 0; index < this.length; index++) {
-                func(this.data[index]);
-            }
-        }
-
-        public sort(compareFn): void {
-            this.data.sort(compareFn);
-        }
-
-        public reset(): void {
-            this.length = 0;
-        }
-
-        public dispose(): void {
-            this.reset();
-            this.data.length = 0;
-        }
-
-        public indexOf(value): number {
-            var position = this.data.indexOf(value);
-
-            if (position >= this.length) {
-                return -1;
-            }
-
-            return position;
-        }
-    }
-} 

+ 5 - 1
src/Tools/babylon.smartArray.ts

@@ -80,7 +80,7 @@
             }
         }
 
-        public indexOf(value): number {
+        public indexOf(value: T): number {
             var position = this.data.indexOf(value);
 
             if (position >= this.length) {
@@ -90,6 +90,10 @@
             return position;
         }
 
+        public contains(value: T): boolean {
+            return this.data.indexOf(value) !== -1;
+        }
+
         // Statics
         private static _GlobalId = 0;
     }