Jelajahi Sumber

Merge branch 'master' of git://github.com/BabylonJS/Babylon.js

Vousk-prod 10 tahun lalu
induk
melakukan
5879827767

+ 8 - 2
Babylon/Animations/babylon.animation.js

@@ -106,8 +106,14 @@ var BABYLON;
                 return highLimitValue.clone ? highLimitValue.clone() : highLimitValue;
             }
             this.currentFrame = currentFrame;
-            for (var key = 0; key < this._keys.length; key++) {
-                // for each frame, we need the key just before the frame superior
+            // Try to get a hash to find the right key
+            var startKey = Math.max(0, Math.min(this._keys.length - 1, Math.floor(this._keys.length * (currentFrame - this._keys[0].frame) / (this._keys[this._keys.length - 1].frame - this._keys[0].frame)) - 1));
+            if (this._keys[startKey].frame >= currentFrame) {
+                while (startKey - 1 >= 0 && this._keys[startKey].frame >= currentFrame) {
+                    startKey--;
+                }
+            }
+            for (var key = startKey; key < this._keys.length; key++) {
                 if (this._keys[key + 1].frame >= currentFrame) {
                     var startValue = this._getKeyValue(this._keys[key].value);
                     var endValue = this._getKeyValue(this._keys[key + 1].value);

+ 10 - 2
Babylon/Animations/babylon.animation.ts

@@ -137,8 +137,16 @@
 
             this.currentFrame = currentFrame;
 
-            for (var key = 0; key < this._keys.length; key++) {
-                // for each frame, we need the key just before the frame superior
+            // Try to get a hash to find the right key
+            var startKey = Math.max(0, Math.min(this._keys.length - 1, Math.floor(this._keys.length * (currentFrame - this._keys[0].frame) / (this._keys[this._keys.length - 1].frame - this._keys[0].frame)) - 1));
+
+            if (this._keys[startKey].frame >= currentFrame) {
+                while (startKey - 1 >= 0 && this._keys[startKey].frame >= currentFrame) {
+                    startKey--;
+                }
+            }
+
+            for (var key = startKey; key < this._keys.length ; key++) {
                 if (this._keys[key + 1].frame >= currentFrame) {
 
                     var startValue = this._getKeyValue(this._keys[key].value);

+ 2 - 3
Babylon/Cameras/babylon.camera.js

@@ -32,7 +32,7 @@ var BABYLON;
             this._postProcesses = new Array();
             this._postProcessesTakenIndices = [];
             this._activeMeshes = new BABYLON.SmartArray(256);
-            scene.cameras.push(this);
+            scene.addCamera(this);
             if (!scene.activeCamera) {
                 scene.activeCamera = this;
             }
@@ -261,8 +261,7 @@ var BABYLON;
         };
         Camera.prototype.dispose = function () {
             // Remove from scene
-            var index = this.getScene().cameras.indexOf(this);
-            this.getScene().cameras.splice(index, 1);
+            this.getScene().removeCamera(this);
             for (var i = 0; i < this._postProcessesTakenIndices.length; ++i) {
                 this._postProcesses[this._postProcessesTakenIndices[i]].dispose(this);
             }

+ 2 - 3
Babylon/Cameras/babylon.camera.ts

@@ -51,7 +51,7 @@
         constructor(name: string, public position: Vector3, scene: Scene) {
             super(name, scene);
 
-            scene.cameras.push(this);
+            scene.addCamera(this);
 
             if (!scene.activeCamera) {
                 scene.activeCamera = this;
@@ -333,8 +333,7 @@
 
         public dispose(): void {
             // Remove from scene
-            var index = this.getScene().cameras.indexOf(this);
-            this.getScene().cameras.splice(index, 1);
+            this.getScene().removeCamera(this);
 
             // Postprocesses
             for (var i = 0; i < this._postProcessesTakenIndices.length; ++i) {

+ 2 - 3
Babylon/Lights/babylon.light.js

@@ -18,7 +18,7 @@ var BABYLON;
             this.excludedMeshes = new Array();
             this._excludedMeshesIds = new Array();
             this._includedOnlyMeshesIds = new Array();
-            scene.lights.push(this);
+            scene.addLight(this);
         }
         Light.prototype.getShadowGenerator = function () {
             return this._shadowGenerator;
@@ -61,8 +61,7 @@ var BABYLON;
                 this._shadowGenerator = null;
             }
             // Remove from scene
-            var index = this.getScene().lights.indexOf(this);
-            this.getScene().lights.splice(index, 1);
+            this.getScene().removeLight(this);
         };
         return Light;
     })(BABYLON.Node);

+ 2 - 3
Babylon/Lights/babylon.light.ts

@@ -33,7 +33,7 @@
         constructor(name: string, scene: Scene) {
             super(name, scene);
 
-            scene.lights.push(this);
+            scene.addLight(this);
         }
 
         public getShadowGenerator(): ShadowGenerator {
@@ -92,8 +92,7 @@
             }
 
             // Remove from scene
-            var index = this.getScene().lights.indexOf(this);
-            this.getScene().lights.splice(index, 1);
+            this.getScene().removeLight(this);
         }
     }
 } 

+ 7 - 1
Babylon/Loading/Plugins/babylon.babylonFileLoader.js

@@ -220,8 +220,14 @@ var BABYLON;
             }
             else if (parsedShadowGenerator.useBlurVarianceShadowMap) {
                 shadowGenerator.useBlurVarianceShadowMap = true;
+                if (parsedShadowGenerator.blurScale) {
+                    shadowGenerator.blurScale = parsedShadowGenerator.blurScale;
+                }
+                if (parsedShadowGenerator.blurBoxOffset) {
+                    shadowGenerator.blurBoxOffset = parsedShadowGenerator.blurBoxOffset;
+                }
             }
-            if (parsedShadowGenerator.bias) {
+            if (parsedShadowGenerator.bias !== undefined) {
                 shadowGenerator.bias = parsedShadowGenerator.bias;
             }
             return shadowGenerator;

+ 9 - 1
Babylon/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -273,9 +273,17 @@
             shadowGenerator.useVarianceShadowMap = true;
         } else if (parsedShadowGenerator.useBlurVarianceShadowMap) {
             shadowGenerator.useBlurVarianceShadowMap = true;
+
+            if (parsedShadowGenerator.blurScale) {
+                shadowGenerator.blurScale = parsedShadowGenerator.blurScale;
+            }
+
+            if (parsedShadowGenerator.blurBoxOffset) {
+                shadowGenerator.blurBoxOffset = parsedShadowGenerator.blurBoxOffset;
+            }
         }
 
-        if (parsedShadowGenerator.bias) {
+        if (parsedShadowGenerator.bias !== undefined) {
             shadowGenerator.bias = parsedShadowGenerator.bias;
         }
 

+ 14 - 17
Babylon/Mesh/babylon.abstractMesh.js

@@ -69,7 +69,7 @@ var BABYLON;
             this._renderId = 0;
             this._intersectionsInProgress = new Array();
             this._onAfterWorldMatrixUpdate = new Array();
-            scene.meshes.push(this);
+            scene.addMesh(this);
         }
         Object.defineProperty(AbstractMesh, "BILLBOARDMODE_NONE", {
             get: function () {
@@ -178,7 +178,7 @@ var BABYLON;
                 this.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
                 this.rotation = BABYLON.Vector3.Zero();
             }
-            if (!space || space == 0 /* LOCAL */) {
+            if (!space || space === 0 /* LOCAL */) {
                 var rotationQuaternion = BABYLON.Quaternion.RotationAxis(axis, amount);
                 this.rotationQuaternion = this.rotationQuaternion.multiply(rotationQuaternion);
             }
@@ -194,7 +194,7 @@ var BABYLON;
         };
         AbstractMesh.prototype.translate = function (axis, distance, space) {
             var displacementVector = axis.scale(distance);
-            if (!space || space == 0 /* LOCAL */) {
+            if (!space || space === 0 /* LOCAL */) {
                 var tempV3 = this.getPositionExpressedInLocalSpace().add(displacementVector);
                 this.setPositionWithLocalVector(tempV3);
             }
@@ -352,7 +352,7 @@ var BABYLON;
             }
         };
         AbstractMesh.prototype.computeWorldMatrix = function (force) {
-            if (!force && (this._currentRenderId == this.getScene().getRenderId() || this.isSynchronized(true))) {
+            if (!force && (this._currentRenderId === this.getScene().getRenderId() || this.isSynchronized(true))) {
                 return this._worldMatrix;
             }
             this._cache.position.copyFrom(this.position);
@@ -396,11 +396,11 @@ var BABYLON;
                     zero = this.getScene().activeCamera.position;
                 }
                 else {
-                    if (this.billboardMode & BABYLON.AbstractMesh.BILLBOARDMODE_X)
+                    if (this.billboardMode & AbstractMesh.BILLBOARDMODE_X)
                         zero.x = localPosition.x + BABYLON.Engine.Epsilon;
-                    if (this.billboardMode & BABYLON.AbstractMesh.BILLBOARDMODE_Y)
+                    if (this.billboardMode & AbstractMesh.BILLBOARDMODE_Y)
                         zero.y = localPosition.y + 0.001;
-                    if (this.billboardMode & BABYLON.AbstractMesh.BILLBOARDMODE_Z)
+                    if (this.billboardMode & AbstractMesh.BILLBOARDMODE_Z)
                         zero.z = localPosition.z + 0.001;
                 }
                 BABYLON.Matrix.LookAtLHToRef(localPosition, zero, BABYLON.Vector3.Up(), this._localBillboard);
@@ -412,7 +412,7 @@ var BABYLON;
             // Local world
             this._localPivotScalingRotation.multiplyToRef(this._localTranslation, this._localWorld);
             // Parent
-            if (this.parent && this.parent.getWorldMatrix && this.billboardMode === BABYLON.AbstractMesh.BILLBOARDMODE_NONE) {
+            if (this.parent && this.parent.getWorldMatrix && this.billboardMode === AbstractMesh.BILLBOARDMODE_NONE) {
                 this._localWorld.multiplyToRef(this.parent.getWorldMatrix(), this._worldMatrix);
             }
             else {
@@ -456,7 +456,7 @@ var BABYLON;
         };
         AbstractMesh.prototype.lookAt = function (targetPoint, yawCor, pitchCor, rollCor) {
             /// <summary>Orients a mesh towards a target point. Mesh must be drawn facing user.</summary>
-            /// <param name="targetPoint" type="BABYLON.Vector3">The position (must be in same space as current mesh) to look at</param>
+            /// <param name="targetPoint" type="Vector3">The position (must be in same space as current mesh) to look at</param>
             /// <param name="yawCor" type="Number">optional yaw (y-axis) correction in radians</param>
             /// <param name="pitchCor" type="Number">optional pitch (x-axis) correction in radians</param>
             /// <param name="rollCor" type="Number">optional roll (z-axis) correction in radians</param>
@@ -739,8 +739,9 @@ var BABYLON;
             }
         };
         AbstractMesh.prototype.dispose = function (doNotRecurse) {
+            var index;
             // Physics
-            if (this.getPhysicsImpostor() != BABYLON.PhysicsEngine.NoImpostor) {
+            if (this.getPhysicsImpostor() !== BABYLON.PhysicsEngine.NoImpostor) {
                 this.setPhysicsState(BABYLON.PhysicsEngine.NoImpostor);
             }
             for (index = 0; index < this._intersectionsInProgress.length; index++) {
@@ -752,14 +753,10 @@ var BABYLON;
             // SubMeshes
             this.releaseSubMeshes();
             // Remove from scene
-            var index = this.getScene().meshes.indexOf(this);
-            if (index != -1) {
-                // Remove from the scene if mesh found 
-                this.getScene().meshes.splice(index, 1);
-            }
+            this.getScene().removeMesh(this);
             if (!doNotRecurse) {
                 for (index = 0; index < this.getScene().particleSystems.length; index++) {
-                    if (this.getScene().particleSystems[index].emitter == this) {
+                    if (this.getScene().particleSystems[index].emitter === this) {
                         this.getScene().particleSystems[index].dispose();
                         index--;
                     }
@@ -767,7 +764,7 @@ var BABYLON;
                 // Children
                 var objects = this.getScene().meshes.slice(0);
                 for (index = 0; index < objects.length; index++) {
-                    if (objects[index].parent == this) {
+                    if (objects[index].parent === this) {
                         objects[index].dispose();
                     }
                 }

+ 76 - 78
Babylon/Mesh/babylon.abstractMesh.ts

@@ -50,10 +50,10 @@
         public receiveShadows = false;
         public actionManager: ActionManager;
         public renderOutline = false;
-        public outlineColor = BABYLON.Color3.Red();
+        public outlineColor = Color3.Red();
         public outlineWidth = 0.02;
         public renderOverlay = false;
-        public overlayColor = BABYLON.Color3.Red();
+        public overlayColor = Color3.Red();
         public overlayAlpha = 0.5;
         public hasVertexAlpha = false;
         public useVertexColors = true;
@@ -72,32 +72,32 @@
         public _physicRestitution: number;
 
         // Collisions
-        public ellipsoid = new BABYLON.Vector3(0.5, 1, 0.5);
-        public ellipsoidOffset = new BABYLON.Vector3(0, 0, 0);
+        public ellipsoid = new Vector3(0.5, 1, 0.5);
+        public ellipsoidOffset = new Vector3(0, 0, 0);
         private _collider = new Collider();
-        private _oldPositionForCollisions = new BABYLON.Vector3(0, 0, 0);
-        private _diffPositionForCollisions = new BABYLON.Vector3(0, 0, 0);
-        private _newPositionForCollisions = new BABYLON.Vector3(0, 0, 0);
+        private _oldPositionForCollisions = new Vector3(0, 0, 0);
+        private _diffPositionForCollisions = new Vector3(0, 0, 0);
+        private _newPositionForCollisions = new Vector3(0, 0, 0);
 
         // Cache
-        private _localScaling = BABYLON.Matrix.Zero();
-        private _localRotation = BABYLON.Matrix.Zero();
-        private _localTranslation = BABYLON.Matrix.Zero();
-        private _localBillboard = BABYLON.Matrix.Zero();
-        private _localPivotScaling = BABYLON.Matrix.Zero();
-        private _localPivotScalingRotation = BABYLON.Matrix.Zero();
-        private _localWorld = BABYLON.Matrix.Zero();
-        public _worldMatrix = BABYLON.Matrix.Zero();
-        private _rotateYByPI = BABYLON.Matrix.RotationY(Math.PI);
-        private _absolutePosition = BABYLON.Vector3.Zero();
-        private _collisionsTransformMatrix = BABYLON.Matrix.Zero();
-        private _collisionsScalingMatrix = BABYLON.Matrix.Zero();
+        private _localScaling = Matrix.Zero();
+        private _localRotation = Matrix.Zero();
+        private _localTranslation = Matrix.Zero();
+        private _localBillboard = Matrix.Zero();
+        private _localPivotScaling = Matrix.Zero();
+        private _localPivotScalingRotation = Matrix.Zero();
+        private _localWorld = Matrix.Zero();
+        public _worldMatrix = Matrix.Zero();
+        private _rotateYByPI = Matrix.RotationY(Math.PI);
+        private _absolutePosition = Vector3.Zero();
+        private _collisionsTransformMatrix = Matrix.Zero();
+        private _collisionsScalingMatrix = Matrix.Zero();
         public _positions: Vector3[];
         private _isDirty = false;
         public _masterMesh: AbstractMesh;
 
         public _boundingInfo: BoundingInfo;
-        private _pivotMatrix = BABYLON.Matrix.Identity();
+        private _pivotMatrix = Matrix.Identity();
         public _isDisposed = false;
         public _renderId = 0;
 
@@ -105,7 +105,7 @@
         public _submeshesOctree: Octree<SubMesh>;
         public _intersectionsInProgress = new Array<AbstractMesh>();
 
-        private _onAfterWorldMatrixUpdate = new Array<(mesh: BABYLON.AbstractMesh) => void>();
+        private _onAfterWorldMatrixUpdate = new Array<(mesh: AbstractMesh) => void>();
 
         // Loading properties
         public _waitingActions: any;
@@ -113,7 +113,7 @@
         constructor(name: string, scene: Scene) {
             super(name, scene);
 
-            scene.meshes.push(this);
+            scene.addMesh(this);
         }
 
         // Methods
@@ -184,12 +184,12 @@
 
         public rotate(axis: Vector3, amount: number, space: Space): void {
             if (!this.rotationQuaternion) {
-                this.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
-                this.rotation = BABYLON.Vector3.Zero();
+                this.rotationQuaternion = Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
+                this.rotation = Vector3.Zero();
             }
 
-            if (!space || space == BABYLON.Space.LOCAL) {
-                var rotationQuaternion = BABYLON.Quaternion.RotationAxis(axis, amount);
+            if (!space || space === Space.LOCAL) {
+                var rotationQuaternion = Quaternion.RotationAxis(axis, amount);
                 this.rotationQuaternion = this.rotationQuaternion.multiply(rotationQuaternion);
             }
             else {
@@ -197,9 +197,9 @@
                     var invertParentWorldMatrix = this.parent.getWorldMatrix().clone();
                     invertParentWorldMatrix.invert();
 
-                    axis = BABYLON.Vector3.TransformNormal(axis, invertParentWorldMatrix);
+                    axis = Vector3.TransformNormal(axis, invertParentWorldMatrix);
                 }
-                rotationQuaternion = BABYLON.Quaternion.RotationAxis(axis, amount);
+                rotationQuaternion = Quaternion.RotationAxis(axis, amount);
                 this.rotationQuaternion = rotationQuaternion.multiply(this.rotationQuaternion);
             }
         }
@@ -207,7 +207,7 @@
         public translate(axis: Vector3, distance: number, space: Space): void {
             var displacementVector = axis.scale(distance);
 
-            if (!space || space == BABYLON.Space.LOCAL) {
+            if (!space || space === Space.LOCAL) {
                 var tempV3 = this.getPositionExpressedInLocalSpace().add(displacementVector);
                 this.setPositionWithLocalVector(tempV3);
             }
@@ -248,9 +248,9 @@
                 var invertParentWorldMatrix = this.parent.getWorldMatrix().clone();
                 invertParentWorldMatrix.invert();
 
-                var worldPosition = new BABYLON.Vector3(absolutePositionX, absolutePositionY, absolutePositionZ);
+                var worldPosition = new Vector3(absolutePositionX, absolutePositionY, absolutePositionZ);
 
-                this.position = BABYLON.Vector3.TransformCoordinates(worldPosition, invertParentWorldMatrix);
+                this.position = Vector3.TransformCoordinates(worldPosition, invertParentWorldMatrix);
             } else {
                 this.position.x = absolutePositionX;
                 this.position.y = absolutePositionY;
@@ -278,14 +278,14 @@
          * @param {number} amountUp
          * @param {number} amountForward
          */
-        public calcMovePOV(amountRight : number, amountUp : number, amountForward : number) : BABYLON.Vector3 {
-            var rotMatrix = new BABYLON.Matrix();
-            var rotQuaternion = (this.rotationQuaternion) ? this.rotationQuaternion : BABYLON.Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
+        public calcMovePOV(amountRight : number, amountUp : number, amountForward : number) : Vector3 {
+            var rotMatrix = new Matrix();
+            var rotQuaternion = (this.rotationQuaternion) ? this.rotationQuaternion : Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
             rotQuaternion.toRotationMatrix(rotMatrix);
             
-            var translationDelta = BABYLON.Vector3.Zero();
+            var translationDelta = Vector3.Zero();
             var defForwardMult = this.definedFacingForward ? -1 : 1;
-            BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(amountRight * defForwardMult, amountUp, amountForward * defForwardMult, rotMatrix, translationDelta);
+            Vector3.TransformCoordinatesFromFloatsToRef(amountRight * defForwardMult, amountUp, amountForward * defForwardMult, rotMatrix, translationDelta);
             return translationDelta;
         }
         // ================================== Point of View Rotation =================================
@@ -307,9 +307,9 @@
          * @param {number} twirlClockwise
          * @param {number} tiltRight
          */
-        public calcRotatePOV(flipBack : number, twirlClockwise : number, tiltRight : number) : BABYLON.Vector3 {
+        public calcRotatePOV(flipBack : number, twirlClockwise : number, tiltRight : number) : Vector3 {
             var defForwardMult = this.definedFacingForward ? 1 : -1;
-            return new BABYLON.Vector3(flipBack * defForwardMult, twirlClockwise, tiltRight * defForwardMult);
+            return new Vector3(flipBack * defForwardMult, twirlClockwise, tiltRight * defForwardMult);
         }
         
         public setPivotMatrix(matrix: Matrix): void {
@@ -358,10 +358,10 @@
             super._initCache();
 
             this._cache.localMatrixUpdated = false;
-            this._cache.position = BABYLON.Vector3.Zero();
-            this._cache.scaling = BABYLON.Vector3.Zero();
-            this._cache.rotation = BABYLON.Vector3.Zero();
-            this._cache.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 0);
+            this._cache.position = Vector3.Zero();
+            this._cache.scaling = Vector3.Zero();
+            this._cache.rotation = Vector3.Zero();
+            this._cache.rotationQuaternion = new Quaternion(0, 0, 0, 0);
         }
 
         public markAsDirty(property: string): void {
@@ -373,7 +373,7 @@
         }
 
         public _updateBoundingInfo(): void {
-            this._boundingInfo = this._boundingInfo || new BABYLON.BoundingInfo(this.absolutePosition, this.absolutePosition);
+            this._boundingInfo = this._boundingInfo || new BoundingInfo(this.absolutePosition, this.absolutePosition);
 
             this._boundingInfo._update(this.worldMatrixFromCache);
 
@@ -393,7 +393,7 @@
         }
 
         public computeWorldMatrix(force?: boolean): Matrix {
-            if (!force && (this._currentRenderId == this.getScene().getRenderId() || this.isSynchronized(true))) {
+            if (!force && (this._currentRenderId === this.getScene().getRenderId() || this.isSynchronized(true))) {
                 return this._worldMatrix;
             }
 
@@ -404,14 +404,14 @@
             this._isDirty = false;
 
             // Scaling
-            BABYLON.Matrix.ScalingToRef(this.scaling.x, this.scaling.y, this.scaling.z, this._localScaling);
+            Matrix.ScalingToRef(this.scaling.x, this.scaling.y, this.scaling.z, this._localScaling);
 
             // Rotation
             if (this.rotationQuaternion) {
                 this.rotationQuaternion.toRotationMatrix(this._localRotation);
                 this._cache.rotationQuaternion.copyFrom(this.rotationQuaternion);
             } else {
-                BABYLON.Matrix.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this._localRotation);
+                Matrix.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this._localRotation);
                 this._cache.rotation.copyFrom(this.rotation);
             }
 
@@ -420,12 +420,12 @@
                 var camera = this.getScene().activeCamera;
                 var cameraWorldMatrix = camera.getWorldMatrix();
 
-                var cameraGlobalPosition = new BABYLON.Vector3(cameraWorldMatrix.m[12], cameraWorldMatrix.m[13], cameraWorldMatrix.m[14]);
+                var cameraGlobalPosition = new Vector3(cameraWorldMatrix.m[12], cameraWorldMatrix.m[13], cameraWorldMatrix.m[14]);
 
-                BABYLON.Matrix.TranslationToRef(this.position.x + cameraGlobalPosition.x, this.position.y + cameraGlobalPosition.y,
+                Matrix.TranslationToRef(this.position.x + cameraGlobalPosition.x, this.position.y + cameraGlobalPosition.y,
                     this.position.z + cameraGlobalPosition.z, this._localTranslation);
             } else {
-                BABYLON.Matrix.TranslationToRef(this.position.x, this.position.y, this.position.z, this._localTranslation);
+                Matrix.TranslationToRef(this.position.x, this.position.y, this.position.z, this._localTranslation);
             }
 
             // Composing transformations
@@ -439,21 +439,21 @@
 
                 if (this.parent && (<any>this.parent).position) {
                     localPosition.addInPlace((<any>this.parent).position);
-                    BABYLON.Matrix.TranslationToRef(localPosition.x, localPosition.y, localPosition.z, this._localTranslation);
+                    Matrix.TranslationToRef(localPosition.x, localPosition.y, localPosition.z, this._localTranslation);
                 }
 
                 if ((this.billboardMode & AbstractMesh.BILLBOARDMODE_ALL) === AbstractMesh.BILLBOARDMODE_ALL) {
                     zero = this.getScene().activeCamera.position;
                 } else {
-                    if (this.billboardMode & BABYLON.AbstractMesh.BILLBOARDMODE_X)
-                        zero.x = localPosition.x + BABYLON.Engine.Epsilon;
-                    if (this.billboardMode & BABYLON.AbstractMesh.BILLBOARDMODE_Y)
+                    if (this.billboardMode & AbstractMesh.BILLBOARDMODE_X)
+                        zero.x = localPosition.x + Engine.Epsilon;
+                    if (this.billboardMode & AbstractMesh.BILLBOARDMODE_Y)
                         zero.y = localPosition.y + 0.001;
-                    if (this.billboardMode & BABYLON.AbstractMesh.BILLBOARDMODE_Z)
+                    if (this.billboardMode & AbstractMesh.BILLBOARDMODE_Z)
                         zero.z = localPosition.z + 0.001;
                 }
 
-                BABYLON.Matrix.LookAtLHToRef(localPosition, zero, BABYLON.Vector3.Up(), this._localBillboard);
+                Matrix.LookAtLHToRef(localPosition, zero, Vector3.Up(), this._localBillboard);
                 this._localBillboard.m[12] = this._localBillboard.m[13] = this._localBillboard.m[14] = 0;
 
                 this._localBillboard.invert();
@@ -466,7 +466,7 @@
             this._localPivotScalingRotation.multiplyToRef(this._localTranslation, this._localWorld);
 
             // Parent
-            if (this.parent && this.parent.getWorldMatrix && this.billboardMode === BABYLON.AbstractMesh.BILLBOARDMODE_NONE) {
+            if (this.parent && this.parent.getWorldMatrix && this.billboardMode === AbstractMesh.BILLBOARDMODE_NONE) {
                 this._localWorld.multiplyToRef(this.parent.getWorldMatrix(), this._worldMatrix);
             } else {
                 this._worldMatrix.copyFrom(this._localWorld);
@@ -490,11 +490,11 @@
         * If you'd like to be callbacked after the mesh position, rotation or scaling has been updated
         * @param func: callback function to add
         */
-        public registerAfterWorldMatrixUpdate(func: (mesh: BABYLON.AbstractMesh) => void): void {
+        public registerAfterWorldMatrixUpdate(func: (mesh: AbstractMesh) => void): void {
             this._onAfterWorldMatrixUpdate.push(func);
         }
 
-        public unregisterAfterWorldMatrixUpdate(func: (mesh: BABYLON.AbstractMesh) => void): void {
+        public unregisterAfterWorldMatrixUpdate(func: (mesh: AbstractMesh) => void): void {
             var index = this._onAfterWorldMatrixUpdate.indexOf(func);
 
             if (index > -1) {
@@ -505,7 +505,7 @@
         public setPositionWithLocalVector(vector3: Vector3): void {
             this.computeWorldMatrix();
 
-            this.position = BABYLON.Vector3.TransformNormal(vector3, this._localWorld);
+            this.position = Vector3.TransformNormal(vector3, this._localWorld);
         }
 
         public getPositionExpressedInLocalSpace(): Vector3 {
@@ -513,18 +513,18 @@
             var invLocalWorldMatrix = this._localWorld.clone();
             invLocalWorldMatrix.invert();
 
-            return BABYLON.Vector3.TransformNormal(this.position, invLocalWorldMatrix);
+            return Vector3.TransformNormal(this.position, invLocalWorldMatrix);
         }
 
         public locallyTranslate(vector3: Vector3): void {
             this.computeWorldMatrix();
 
-            this.position = BABYLON.Vector3.TransformCoordinates(vector3, this._localWorld);
+            this.position = Vector3.TransformCoordinates(vector3, this._localWorld);
         }
 
         public lookAt(targetPoint: Vector3, yawCor: number, pitchCor: number, rollCor: number): void {
             /// <summary>Orients a mesh towards a target point. Mesh must be drawn facing user.</summary>
-            /// <param name="targetPoint" type="BABYLON.Vector3">The position (must be in same space as current mesh) to look at</param>
+            /// <param name="targetPoint" type="Vector3">The position (must be in same space as current mesh) to look at</param>
             /// <param name="yawCor" type="Number">optional yaw (y-axis) correction in radians</param>
             /// <param name="pitchCor" type="Number">optional pitch (x-axis) correction in radians</param>
             /// <param name="rollCor" type="Number">optional roll (z-axis) correction in radians</param>
@@ -538,7 +538,7 @@
             var yaw = -Math.atan2(dv.z, dv.x) - Math.PI / 2;
             var len = Math.sqrt(dv.x * dv.x + dv.z * dv.z);
             var pitch = Math.atan2(dv.y, len);
-            this.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(yaw + yawCor, pitch + pitchCor, rollCor);
+            this.rotationQuaternion = Quaternion.RotationYawPitchRoll(yaw + yawCor, pitch + pitchCor, rollCor);
         }
 
         public isInFrustum(frustumPlanes: Plane[]): boolean {
@@ -556,7 +556,7 @@
 
             var transformMatrix = camera.getViewMatrix().multiply(camera.getProjectionMatrix());
 
-            if (!this._boundingInfo.isCompletelyInFrustum(BABYLON.Frustum.GetPlanes(transformMatrix))) {
+            if (!this._boundingInfo.isCompletelyInFrustum(Frustum.GetPlanes(transformMatrix))) {
                 return false;
             }
 
@@ -595,7 +595,7 @@
                 impostor = impostor.impostor;
             }
 
-            if (impostor === BABYLON.PhysicsEngine.NoImpostor) {
+            if (impostor === PhysicsEngine.NoImpostor) {
                 physicsEngine._unregisterMesh(this);
                 return;
             }
@@ -619,7 +619,7 @@
 
         public getPhysicsImpostor(): number {
             if (!this._physicImpostor) {
-                return BABYLON.PhysicsEngine.NoImpostor;
+                return PhysicsEngine.NoImpostor;
             }
 
             return this._physicImpostor;
@@ -713,7 +713,7 @@
         */
         public createOrUpdateSubmeshesOctree(maxCapacity = 64, maxDepth = 2): Octree<SubMesh> {
             if (!this._submeshesOctree) {
-                this._submeshesOctree = new BABYLON.Octree<SubMesh>(Octree.CreationFuncForSubMeshes, maxCapacity, maxDepth);
+                this._submeshesOctree = new Octree<SubMesh>(Octree.CreationFuncForSubMeshes, maxCapacity, maxDepth);
             }
 
             this.computeWorldMatrix(true);
@@ -736,7 +736,7 @@
                 var start = subMesh.verticesStart;
                 var end = (subMesh.verticesStart + subMesh.verticesCount);
                 for (var i = start; i < end; i++) {
-                    subMesh._lastColliderWorldVertices.push(BABYLON.Vector3.TransformCoordinates(this._positions[i], transformMatrix));
+                    subMesh._lastColliderWorldVertices.push(Vector3.TransformCoordinates(this._positions[i], transformMatrix));
                 }
             }
             // Collide
@@ -776,7 +776,7 @@
                 return;
 
             // Transformation matrix
-            BABYLON.Matrix.ScalingToRef(1.0 / collider.radius.x, 1.0 / collider.radius.y, 1.0 / collider.radius.z, this._collisionsScalingMatrix);
+            Matrix.ScalingToRef(1.0 / collider.radius.x, 1.0 / collider.radius.y, 1.0 / collider.radius.z, this._collisionsScalingMatrix);
             this.worldMatrixFromCache.multiplyToRef(this._collisionsScalingMatrix, this._collisionsTransformMatrix);
 
             this._processCollisionsForSubMeshes(collider, this._collisionsTransformMatrix);
@@ -788,7 +788,7 @@
         }
 
         public intersects(ray: Ray, fastCheck?: boolean): PickingInfo {
-            var pickingInfo = new BABYLON.PickingInfo();
+            var pickingInfo = new PickingInfo();
 
             if (!this.subMeshes || !this._boundingInfo || !ray.intersectsSphere(this._boundingInfo.boundingSphere) || !ray.intersectsBox(this._boundingInfo.boundingBox)) {
                 return pickingInfo;
@@ -876,8 +876,10 @@
         }
 
         public dispose(doNotRecurse?: boolean): void {
+            var index: number;
+
             // Physics
-            if (this.getPhysicsImpostor() != PhysicsEngine.NoImpostor) {
+            if (this.getPhysicsImpostor() !== PhysicsEngine.NoImpostor) {
                 this.setPhysicsState(PhysicsEngine.NoImpostor);
             }
 
@@ -895,16 +897,12 @@
             this.releaseSubMeshes();
 
             // Remove from scene
-            var index = this.getScene().meshes.indexOf(this);
-            if (index != -1) {
-                // Remove from the scene if mesh found 
-                this.getScene().meshes.splice(index, 1);
-            }
+            this.getScene().removeMesh(this);
 
             if (!doNotRecurse) {
                 // Particles
                 for (index = 0; index < this.getScene().particleSystems.length; index++) {
-                    if (this.getScene().particleSystems[index].emitter == this) {
+                    if (this.getScene().particleSystems[index].emitter === this) {
                         this.getScene().particleSystems[index].dispose();
                         index--;
                     }
@@ -913,7 +911,7 @@
                 // Children
                 var objects = this.getScene().meshes.slice(0);
                 for (index = 0; index < objects.length; index++) {
-                    if (objects[index].parent == this) {
+                    if (objects[index].parent === this) {
                         objects[index].dispose();
                     }
                 }

+ 4 - 0
Babylon/Mesh/babylon.geometry.js

@@ -89,6 +89,10 @@ var BABYLON;
                     mesh._resetPointsArrayCache();
                     if (updateExtends) {
                         mesh._boundingInfo = new BABYLON.BoundingInfo(extend.minimum, extend.maximum);
+                        for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
+                            var subMesh = mesh.subMeshes[subIndex];
+                            subMesh.refreshBoundingInfo();
+                        }
                     }
                 }
             }

+ 6 - 0
Babylon/Mesh/babylon.geometry.ts

@@ -122,6 +122,12 @@
                     mesh._resetPointsArrayCache();
                     if (updateExtends) {
                         mesh._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
+
+                        for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
+                            var subMesh = mesh.subMeshes[subIndex];
+
+                            subMesh.refreshBoundingInfo();
+                        }
                     }
                 }
             }

+ 2 - 2
Babylon/Mesh/babylon.groundMesh.ts

@@ -19,11 +19,11 @@
         }
 
         public getHeightAtCoordinates(x: number, z: number): number {
-            var ray = new BABYLON.Ray(new BABYLON.Vector3(x, this.getBoundingInfo().boundingBox.maximumWorld.y + 1, z), new BABYLON.Vector3(0, -1, 0));
+            var ray = new Ray(new Vector3(x, this.getBoundingInfo().boundingBox.maximumWorld.y + 1, z), new BABYLON.Vector3(0, -1, 0));
 
             this.getWorldMatrix().invertToRef(this._worldInverse);
 
-            ray = BABYLON.Ray.Transform(ray, this._worldInverse);
+            ray = Ray.Transform(ray, this._worldInverse);
 
             var pickInfo = this.intersects(ray);
 

+ 39 - 1
Babylon/Mesh/babylon.mesh.js

@@ -878,7 +878,7 @@ var BABYLON;
          * @param settings a collection of simplification settings.
          * @param parallelProcessing should all levels calculate parallel or one after the other.
          * @param type the type of simplification to run.
-         * successCallback optional success callback to be called after the simplification finished processing all settings.
+         * @param successCallback optional success callback to be called after the simplification finished processing all settings.
          */
         Mesh.prototype.simplify = function (settings, parallelProcessing, simplificationType, successCallback) {
             if (parallelProcessing === void 0) { parallelProcessing = true; }
@@ -891,6 +891,44 @@ var BABYLON;
                 successCallback: successCallback
             });
         };
+        /**
+         * Optimization of the mesh's indices, in case a mesh has duplicated vertices.
+         * The function will only reorder the indices and will not remove unused vertices to avoid problems with submeshes.
+         * This should be used together with the simplification to avoid disappearing triangles.
+         * @param successCallback an optional success callback to be called after the optimization finished.
+         */
+        Mesh.prototype.optimizeIndices = function (successCallback) {
+            var _this = this;
+            var indices = this.getIndices();
+            var positions = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
+            var vectorPositions = [];
+            for (var pos = 0; pos < positions.length; pos = pos + 3) {
+                vectorPositions.push(BABYLON.Vector3.FromArray(positions, pos));
+            }
+            var dupes = [];
+            BABYLON.AsyncLoop.SyncAsyncForLoop(vectorPositions.length, 40, function (iteration) {
+                var realPos = vectorPositions.length - 1 - iteration;
+                var testedPosition = vectorPositions[realPos];
+                for (var j = 0; j < realPos; ++j) {
+                    var againstPosition = vectorPositions[j];
+                    if (testedPosition.equals(againstPosition)) {
+                        dupes[realPos] = j;
+                        break;
+                    }
+                }
+            }, function () {
+                for (var i = 0; i < indices.length; ++i) {
+                    indices[i] = dupes[indices[i]] || indices[i];
+                }
+                //indices are now reordered
+                var originalSubMeshes = _this.subMeshes.slice(0);
+                _this.setIndices(indices);
+                _this.subMeshes = originalSubMeshes;
+                if (successCallback) {
+                    successCallback(_this);
+                }
+            });
+        };
         // Statics
         Mesh.CreateRibbon = function (name, pathArray, closeArray, closePath, offset, scene, updatable, sideOrientation) {
             if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }

+ 42 - 2
Babylon/Mesh/babylon.mesh.ts

@@ -1078,7 +1078,7 @@
          * @param settings a collection of simplification settings.
          * @param parallelProcessing should all levels calculate parallel or one after the other.
          * @param type the type of simplification to run.
-         * successCallback optional success callback to be called after the simplification finished processing all settings.
+         * @param successCallback optional success callback to be called after the simplification finished processing all settings.
          */
         public simplify(settings: Array<ISimplificationSettings>, parallelProcessing: boolean = true, simplificationType: SimplificationType = SimplificationType.QUADRATIC, successCallback?: (mesh?: Mesh, submeshIndex?: number) => void) {
             this.getScene().simplificationQueue.addTask({
@@ -1090,6 +1090,46 @@
             });
         }
 
+        /**
+         * Optimization of the mesh's indices, in case a mesh has duplicated vertices.
+         * The function will only reorder the indices and will not remove unused vertices to avoid problems with submeshes.
+         * This should be used together with the simplification to avoid disappearing triangles.
+         * @param successCallback an optional success callback to be called after the optimization finished.
+         */
+        public optimizeIndices(successCallback?: (mesh?: Mesh) => void) {
+            var indices = this.getIndices();
+            var positions = this.getVerticesData(VertexBuffer.PositionKind);
+            var vectorPositions = [];
+            for (var pos = 0; pos < positions.length; pos = pos + 3) {
+                vectorPositions.push(Vector3.FromArray(positions, pos));
+            }
+            var dupes = [];
+
+            AsyncLoop.SyncAsyncForLoop(vectorPositions.length, 40, (iteration) => {
+                var realPos = vectorPositions.length - 1 - iteration;
+                var testedPosition = vectorPositions[realPos];
+                for (var j = 0; j < realPos; ++j) {
+                    var againstPosition = vectorPositions[j];
+                    if (testedPosition.equals(againstPosition)) {
+                        dupes[realPos] = j;
+                        break;
+                    }
+                }
+            },  () => {
+                for (var i = 0; i < indices.length; ++i) {
+                    indices[i] = dupes[indices[i]] || indices[i];
+                }
+
+                //indices are now reordered
+                var originalSubMeshes = this.subMeshes.slice(0);
+                this.setIndices(indices);
+                this.subMeshes = originalSubMeshes;
+                if (successCallback) {
+                    successCallback(this);
+                }
+            });
+        }
+
         // Statics
         public static CreateRibbon(name: string, pathArray: Vector3[][], closeArray: boolean, closePath: boolean, offset: number, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
             var ribbon = new Mesh(name, scene);
@@ -1366,4 +1406,4 @@
             return newMesh;
         }
     }
-} 
+} 

+ 15 - 10
Babylon/Mesh/babylon.meshSimplification.js

@@ -28,14 +28,13 @@ var BABYLON;
         };
         SimplificationQueue.prototype.runSimplification = function (task) {
             var _this = this;
-            function setLODLevel(distance, mesh) {
-            }
             if (task.parallelProcessing) {
                 //parallel simplifier
                 task.settings.forEach(function (setting) {
                     var simplifier = _this.getSimplifier(task);
                     simplifier.simplify(setting, function (newMesh) {
                         task.mesh.addLODLevel(setting.distance, newMesh);
+                        newMesh.isVisible = true;
                         //check if it is the last
                         if (setting.quality === task.settings[task.settings.length - 1].quality && task.successCallback) {
                             //all done, run the success callback.
@@ -51,6 +50,7 @@ var BABYLON;
                 var runDecimation = function (setting, callback) {
                     simplifier.simplify(setting, function (newMesh) {
                         task.mesh.addLODLevel(setting.distance, newMesh);
+                        newMesh.isVisible = true;
                         //run the next quality level
                         callback();
                     });
@@ -92,6 +92,7 @@ var BABYLON;
             this.error = new Array(4);
             this.deleted = false;
             this.isDirty = false;
+            this.deletePending = false;
             this.borderFactor = 0;
         }
         return DecimationTriangle;
@@ -189,7 +190,6 @@ var BABYLON;
                 });
             }, function () {
                 setTimeout(function () {
-                    _this._reconstructedMesh.isVisible = true;
                     successCallback(_this._reconstructedMesh);
                 }, 0);
             });
@@ -259,7 +259,16 @@ var BABYLON;
                                     continue;
                                 if (_this.isFlipped(v1, i0, p, deleted1, t.borderFactor, delTr))
                                     continue;
-                                if (delTr.length == 2 || delTr[0] === delTr[1]) {
+                                if (deleted0.indexOf(true) < 0 || deleted1.indexOf(true) < 0)
+                                    continue;
+                                var uniqueArray = [];
+                                delTr.forEach(function (deletedT) {
+                                    if (uniqueArray.indexOf(deletedT) === -1) {
+                                        deletedT.deletePending = true;
+                                        uniqueArray.push(deletedT);
+                                    }
+                                });
+                                if (uniqueArray.length % 2 != 0) {
                                     continue;
                                 }
                                 v0.normal = n;
@@ -268,10 +277,6 @@ var BABYLON;
                                 else if (v0.color)
                                     v0.color = color;
                                 v0.q = v1.q.add(v0.q);
-                                if (deleted0.indexOf(true) < 0 || deleted1.indexOf(true) < 0)
-                                    continue;
-                                if (p.equals(v0.position))
-                                    continue;
                                 v0.position = p;
                                 var tStart = _this.references.length;
                                 deletedTriangles = _this.updateTriangles(v0.id, v0, deleted0, deletedTriangles);
@@ -405,7 +410,7 @@ var BABYLON;
                     this.vertices[dst].normal = this.vertices[i].normal;
                     this.vertices[dst].uv = this.vertices[i].uv;
                     this.vertices[dst].color = this.vertices[i].color;
-                    newVerticesOrder.push(i);
+                    newVerticesOrder.push(dst);
                     dst++;
                 }
             }
@@ -505,7 +510,7 @@ var BABYLON;
                 var t = this.triangles[ref.triangleId];
                 if (t.deleted)
                     continue;
-                if (deletedArray[i]) {
+                if (deletedArray[i] && t.deletePending) {
                     t.deleted = true;
                     newDeleted++;
                     continue;

+ 18 - 12
Babylon/Mesh/babylon.meshSimplification.ts

@@ -61,17 +61,13 @@
         }
 
         public runSimplification(task: ISimplificationTask) {
-
-            function setLODLevel(distance: number, mesh: Mesh) {
-
-            }
-
             if (task.parallelProcessing) {
                 //parallel simplifier
                 task.settings.forEach((setting) => {
                     var simplifier = this.getSimplifier(task);
                     simplifier.simplify(setting,(newMesh) => {
                         task.mesh.addLODLevel(setting.distance, newMesh);
+                        newMesh.isVisible = true;
                         //check if it is the last
                         if (setting.quality === task.settings[task.settings.length - 1].quality && task.successCallback) {
                             //all done, run the success callback.
@@ -87,6 +83,7 @@
                 var runDecimation = (setting: ISimplificationSettings, callback: () => void) => {
                     simplifier.simplify(setting,(newMesh) => {
                         task.mesh.addLODLevel(setting.distance, newMesh);
+                        newMesh.isVisible = true;
                         //run the next quality level
                         callback();
                     });
@@ -129,11 +126,13 @@
         public deleted: boolean;
         public isDirty: boolean;
         public borderFactor: number;
+        public deletePending: boolean;
 
         constructor(public vertices: Array<number>) {
             this.error = new Array<number>(4);
             this.deleted = false;
             this.isDirty = false;
+            this.deletePending = false;
             this.borderFactor = 0;
         }
     }
@@ -252,7 +251,6 @@
                 });
             },() => {
                     setTimeout(() => {
-                        this._reconstructedMesh.isVisible = true;
                         successCallback(this._reconstructedMesh);
                     }, 0);
                 });
@@ -332,7 +330,18 @@
                                 if (this.isFlipped(v0, i1, p, deleted0, t.borderFactor, delTr)) continue;
                                 if (this.isFlipped(v1, i0, p, deleted1, t.borderFactor, delTr)) continue;
 
-                                if (delTr.length == 2 || delTr[0] === delTr[1]) {
+                                if (deleted0.indexOf(true) < 0 || deleted1.indexOf(true) < 0)
+                                    continue;
+
+                                var uniqueArray = [];
+                                delTr.forEach(function (deletedT) {
+                                    if (uniqueArray.indexOf(deletedT) === -1) {
+                                        deletedT.deletePending = true;
+                                        uniqueArray.push(deletedT);
+                                    }
+                                });
+
+                                if (uniqueArray.length % 2 != 0) {
                                     continue;
                                 }
 
@@ -343,9 +352,6 @@
                                     v0.color = color;
                                 v0.q = v1.q.add(v0.q);
 
-                                if (deleted0.indexOf(true) < 0 || deleted1.indexOf(true) < 0) continue;
-
-                                if (p.equals(v0.position)) continue;
                                 v0.position = p;
 
                                 var tStart = this.references.length;
@@ -488,7 +494,7 @@
                     this.vertices[dst].normal = this.vertices[i].normal;
                     this.vertices[dst].uv = this.vertices[i].uv;
                     this.vertices[dst].color = this.vertices[i].color;
-                    newVerticesOrder.push(i);
+                    newVerticesOrder.push(dst);
                     dst++;
                 }
             }
@@ -601,7 +607,7 @@
                 var ref = this.references[vertex.triangleStart + i];
                 var t = this.triangles[ref.triangleId];
                 if (t.deleted) continue;
-                if (deletedArray[i]) {
+                if (deletedArray[i] && t.deletePending) {
                     t.deleted = true;
                     newDeleted++;
                     continue;

+ 2 - 2
Babylon/Mesh/babylon.subMesh.ts

@@ -67,9 +67,9 @@
             var extend;
 
             if (this.indexStart === 0 && this.indexCount === indices.length) {
-                extend = BABYLON.Tools.ExtractMinAndMax(data, this.verticesStart, this.verticesCount);
+                extend = Tools.ExtractMinAndMax(data, this.verticesStart, this.verticesCount);
             } else {
-                extend = BABYLON.Tools.ExtractMinAndMaxIndexed(data, indices, this.indexStart, this.indexCount);
+                extend = Tools.ExtractMinAndMaxIndexed(data, indices, this.indexStart, this.indexCount);
             }
             this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
         }

+ 3 - 3
Babylon/Shaders/default.fragment.fx

@@ -262,9 +262,9 @@ float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, flo
 }
 
 // Thanks to http://devmaster.net/
-float ChebychevInequality(vec2 moments, float t)
+float ChebychevInequality(vec2 moments, float t, float bias)
 {
-	if (t <= moments.x)
+	if (t - bias <= moments.x)
 	{
 		return 0.0;
 	}
@@ -291,7 +291,7 @@ float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, flo
 	vec4 texel = texture2D(shadowSampler, uv);
 
 	vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-	return 1.0 - ChebychevInequality(moments, depth.z - bias);
+	return 1.0 - ChebychevInequality(moments, depth.z, bias);
 }
 #endif
 

+ 1 - 1
Babylon/Tools/babylon.sceneSerializer.js

@@ -58,7 +58,7 @@ var BABYLON;
     var serializeCamera = function (camera) {
         var serializationObject = {};
         serializationObject.name = camera.name;
-        serializationObject.tags = BABYLON.Tags.GetTags(camera) || [];
+        serializationObject.tags = BABYLON.Tags.GetTags(camera);
         serializationObject.id = camera.id;
         serializationObject.position = camera.position.asArray();
         // Parent

+ 1 - 1
Babylon/Tools/babylon.sceneSerializer.ts

@@ -66,7 +66,7 @@
     var serializeCamera = (camera: Camera): any => {
         var serializationObject: any = {};
         serializationObject.name = camera.name;
-        serializationObject.tags = Tags.GetTags(camera) || [];
+        serializationObject.tags = Tags.GetTags(camera);
         serializationObject.id = camera.id;
         serializationObject.position = camera.position.asArray();
 

+ 9 - 1
Babylon/babylon.node.js

@@ -16,6 +16,7 @@ var BABYLON;
             this._isEnabled = true;
             this._isReady = true;
             this._currentRenderId = -1;
+            this._parentRenderId = -1;
             this.name = name;
             this.id = name;
             this._scene = scene;
@@ -52,7 +53,14 @@ var BABYLON;
             return true;
         };
         Node.prototype.isSynchronizedWithParent = function () {
-            return this.parent ? this.parent._currentRenderId <= this._currentRenderId : true;
+            if (!this.parent) {
+                return true;
+            }
+            if (this._parentRenderId !== this.parent._currentRenderId) {
+                return false;
+            }
+            this._parentRenderId = this.parent._currentRenderId;
+            return this.parent._currentRenderId <= this._currentRenderId && this.parent.isSynchronized();
         };
         Node.prototype.isSynchronized = function (updateCache) {
             var check = this.hasNewParent();

+ 12 - 1
Babylon/babylon.node.ts

@@ -17,6 +17,7 @@
         private _isEnabled = true;
         private _isReady = true;
         public _currentRenderId = -1;
+        private _parentRenderId = -1;
 
         public _waitingParentId: string;
 
@@ -75,7 +76,17 @@
         }
 
         public isSynchronizedWithParent(): boolean {
-            return this.parent ? this.parent._currentRenderId <= this._currentRenderId : true;
+            if (!this.parent) {
+                return true;
+            }
+
+            if (this._parentRenderId !== this.parent._currentRenderId) {
+                return false;
+            }
+
+            this._parentRenderId = this.parent._currentRenderId;
+
+            return this.parent._currentRenderId <= this._currentRenderId && this.parent.isSynchronized();
         }
 
         public isSynchronized(updateCache?: boolean): boolean {

+ 51 - 0
Babylon/babylon.scene.js

@@ -530,6 +530,57 @@ var BABYLON;
             this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
         };
         // Methods
+        Scene.prototype.addMesh = function (newMesh) {
+            var position = this.meshes.push(newMesh);
+            if (this.onNewMeshAdded) {
+                this.onNewMeshAdded(newMesh, position, this);
+            }
+        };
+        Scene.prototype.removeMesh = function (toRemove) {
+            var index = this.meshes.indexOf(toRemove);
+            if (index !== -1) {
+                // Remove from the scene if mesh found 
+                this.meshes.splice(index, 1);
+            }
+            if (this.onMeshRemoved) {
+                this.onMeshRemoved(toRemove);
+            }
+            return index;
+        };
+        Scene.prototype.removeLight = function (toRemove) {
+            var index = this.lights.indexOf(toRemove);
+            if (index !== -1) {
+                // Remove from the scene if mesh found 
+                this.lights.splice(index, 1);
+            }
+            if (this.onLightRemoved) {
+                this.onLightRemoved(toRemove);
+            }
+            return index;
+        };
+        Scene.prototype.removeCamera = function (toRemove) {
+            var index = this.cameras.indexOf(toRemove);
+            if (index !== -1) {
+                // Remove from the scene if mesh found 
+                this.cameras.splice(index, 1);
+            }
+            if (this.onCameraRemoved) {
+                this.onCameraRemoved(toRemove);
+            }
+            return index;
+        };
+        Scene.prototype.addLight = function (newLight) {
+            var position = this.lights.push(newLight);
+            if (this.onNewLightAdded) {
+                this.onNewLightAdded(newLight, position, this);
+            }
+        };
+        Scene.prototype.addCamera = function (newCamera) {
+            var position = this.cameras.push(newCamera);
+            if (this.onNewCameraAdded) {
+                this.onNewCameraAdded(newCamera, position, this);
+            }
+        };
         /**
          * sets the active camera of the scene using its ID
          * @param {string} id - the camera's ID

+ 63 - 0
Babylon/babylon.scene.ts

@@ -102,6 +102,8 @@
         * @type {BABYLON.Light[]}
         */
         public lights = new Array<Light>();
+        public onNewLightAdded: (newLight?: Light, positionInArray?: number, scene?: Scene) => void;
+        public onLightRemoved: (removedLight?: Light) => void;
 
         // Cameras
         /**
@@ -110,6 +112,8 @@
         * @type {BABYLON.Camera[]}
         */
         public cameras = new Array<Camera>();
+        public onNewCameraAdded: (newCamera?: Camera, positionInArray?: number, scene?: Scene) => void;
+        public onCameraRemoved: (removedCamera?: Camera) => void;
         public activeCameras = new Array<Camera>();
         public activeCamera: Camera;
 
@@ -120,6 +124,8 @@
         * @type {BABYLON.AbstractMesh[]}
         */
         public meshes = new Array<AbstractMesh>();
+        public onNewMeshAdded: (newMesh?: AbstractMesh, positionInArray?: number, scene?: Scene) => void;
+        public onMeshRemoved: (removedMesh?: AbstractMesh) => void;
 
         // Geometries
         private _geometries = new Array<Geometry>();
@@ -715,6 +721,63 @@
 
         // Methods
 
+        public addMesh(newMesh: AbstractMesh) {
+            var position = this.meshes.push(newMesh);
+            if (this.onNewMeshAdded) {
+                this.onNewMeshAdded(newMesh, position, this);
+            }
+        }
+
+        public removeMesh(toRemove: AbstractMesh): number {
+            var index = this.meshes.indexOf(toRemove);
+            if (index !== -1) {
+                // Remove from the scene if mesh found 
+                this.meshes.splice(index, 1);
+            }
+            if (this.onMeshRemoved) {
+                this.onMeshRemoved(toRemove);
+            }
+            return index;
+        }
+
+        public removeLight(toRemove: Light): number {
+            var index = this.lights.indexOf(toRemove);
+            if (index !== -1) {
+                // Remove from the scene if mesh found 
+                this.lights.splice(index, 1);
+            }
+            if (this.onLightRemoved) {
+                this.onLightRemoved(toRemove);
+            }
+            return index;
+        }
+
+        public removeCamera(toRemove: Camera): number {
+            var index = this.cameras.indexOf(toRemove);
+            if (index !== -1) {
+                // Remove from the scene if mesh found 
+                this.cameras.splice(index, 1);
+            }
+            if (this.onCameraRemoved) {
+                this.onCameraRemoved(toRemove);
+            }
+            return index;
+        }
+
+        public addLight(newLight: Light) {
+            var position = this.lights.push(newLight);
+            if (this.onNewLightAdded) {
+                this.onNewLightAdded(newLight, position, this);
+            }
+        }
+
+        public addCamera(newCamera: Camera) {
+            var position = this.cameras.push(newCamera);
+            if (this.onNewCameraAdded) {
+                this.onNewCameraAdded(newCamera, position, this);
+            }
+        }
+
         /**
          * sets the active camera of the scene using its ID
          * @param {string} id - the camera's ID

File diff ditekan karena terlalu besar
+ 153 - 40
babylon.2.1-alpha.debug.js


File diff ditekan karena terlalu besar
+ 17 - 16
babylon.2.1-alpha.js