Browse Source

Various fixes

David Catuhe 10 years ago
parent
commit
c37f483483

+ 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);

+ 1 - 1
Babylon/Cameras/babylon.camera.js

@@ -261,7 +261,7 @@ var BABYLON;
         };
         Camera.prototype.dispose = function () {
             // Remove from scene
-            var index = this.getScene().removeCamera(this);
+            this.getScene().removeCamera(this);
             for (var i = 0; i < this._postProcessesTakenIndices.length; ++i) {
                 this._postProcesses[this._postProcessesTakenIndices[i]].dispose(this);
             }

+ 1 - 1
Babylon/Cameras/babylon.camera.ts

@@ -333,7 +333,7 @@
 
         public dispose(): void {
             // Remove from scene
-            var index = this.getScene().removeCamera(this);
+            this.getScene().removeCamera(this);
 
             // Postprocesses
             for (var i = 0; i < this._postProcessesTakenIndices.length; ++i) {

+ 1 - 1
Babylon/Lights/babylon.light.js

@@ -61,7 +61,7 @@ var BABYLON;
                 this._shadowGenerator = null;
             }
             // Remove from scene
-            var index = this.getScene().removeLight(this);
+            this.getScene().removeLight(this);
         };
         return Light;
     })(BABYLON.Node);

+ 1 - 1
Babylon/Lights/babylon.light.ts

@@ -92,7 +92,7 @@
             }
 
             // Remove from scene
-            var index = this.getScene().removeLight(this);
+            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;
         }
 

+ 13 - 12
Babylon/Mesh/babylon.abstractMesh.js

@@ -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 == BABYLON.Space.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 == BABYLON.Space.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,10 +753,10 @@ var BABYLON;
             // SubMeshes
             this.releaseSubMeshes();
             // Remove from scene
-            var index = this.getScene().removeMesh(this);
+            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--;
                     }
@@ -763,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();
                     }
                 }

+ 75 - 73
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;
@@ -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,12 +897,12 @@
             this.releaseSubMeshes();
 
             // Remove from scene
-            var index = this.getScene().removeMesh(this);
+            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--;
                     }
@@ -909,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);
 

+ 2 - 2
Babylon/Mesh/babylon.mesh.js

@@ -882,7 +882,7 @@ var BABYLON;
          */
         Mesh.prototype.simplify = function (settings, parallelProcessing, simplificationType, successCallback) {
             if (parallelProcessing === void 0) { parallelProcessing = true; }
-            if (simplificationType === void 0) { simplificationType = BABYLON.SimplificationType.QUADRATIC; }
+            if (simplificationType === void 0) { simplificationType = 0 /* QUADRATIC */; }
             this.getScene().simplificationQueue.addTask({
                 settings: settings,
                 parallelProcessing: parallelProcessing,
@@ -897,7 +897,7 @@ var BABYLON;
          * 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.optimize = function (successCallback) {
+        Mesh.prototype.optimizeIndices = function (successCallback) {
             var _this = this;
             var indices = this.getIndices();
             var positions = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);

+ 4 - 4
Babylon/Mesh/babylon.mesh.ts

@@ -1096,16 +1096,16 @@
          * 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 optimize(successCallback?: (mesh?: Mesh) => void) {
+        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(BABYLON.Vector3.FromArray(positions, pos));
+                vectorPositions.push(Vector3.FromArray(positions, pos));
             }
             var dupes = [];
 
-            AsyncLoop.SyncAsyncForLoop(vectorPositions.length, 40, function (iteration) {
+            AsyncLoop.SyncAsyncForLoop(vectorPositions.length, 40, (iteration) => {
                 var realPos = vectorPositions.length - 1 - iteration;
                 var testedPosition = vectorPositions[realPos];
                 for (var j = 0; j < realPos; ++j) {
@@ -1406,4 +1406,4 @@
             return newMesh;
         }
     }
-} 
+} 

+ 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);
         }

+ 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();
 

+ 1 - 1
Babylon/babylon.node.js

@@ -52,7 +52,7 @@ var BABYLON;
             return true;
         };
         Node.prototype.isSynchronizedWithParent = function () {
-            return this.parent ? this.parent._currentRenderId <= this._currentRenderId : true;
+            return this.parent ? this.parent._currentRenderId <= this._currentRenderId && this.parent.isSynchronized() : true;
         };
         Node.prototype.isSynchronized = function (updateCache) {
             var check = this.hasNewParent();

+ 1 - 1
Babylon/babylon.node.ts

@@ -75,7 +75,7 @@
         }
 
         public isSynchronizedWithParent(): boolean {
-            return this.parent ? this.parent._currentRenderId <= this._currentRenderId : true;
+            return this.parent ? this.parent._currentRenderId <= this._currentRenderId && this.parent.isSynchronized() : true;
         }
 
         public isSynchronized(updateCache?: boolean): boolean {

+ 3 - 3
Babylon/babylon.scene.js

@@ -538,7 +538,7 @@ var BABYLON;
         };
         Scene.prototype.removeMesh = function (toRemove) {
             var index = this.meshes.indexOf(toRemove);
-            if (index != -1) {
+            if (index !== -1) {
                 // Remove from the scene if mesh found 
                 this.meshes.splice(index, 1);
             }
@@ -549,7 +549,7 @@ var BABYLON;
         };
         Scene.prototype.removeLight = function (toRemove) {
             var index = this.lights.indexOf(toRemove);
-            if (index != -1) {
+            if (index !== -1) {
                 // Remove from the scene if mesh found 
                 this.lights.splice(index, 1);
             }
@@ -560,7 +560,7 @@ var BABYLON;
         };
         Scene.prototype.removeCamera = function (toRemove) {
             var index = this.cameras.indexOf(toRemove);
-            if (index != -1) {
+            if (index !== -1) {
                 // Remove from the scene if mesh found 
                 this.cameras.splice(index, 1);
             }

+ 6 - 6
Babylon/babylon.scene.ts

@@ -728,9 +728,9 @@
             }
         }
 
-        public removeMesh(toRemove: AbstractMesh) : number {
+        public removeMesh(toRemove: AbstractMesh): number {
             var index = this.meshes.indexOf(toRemove);
-            if (index != -1) {
+            if (index !== -1) {
                 // Remove from the scene if mesh found 
                 this.meshes.splice(index, 1);
             }
@@ -740,9 +740,9 @@
             return index;
         }
 
-        public removeLight(toRemove: Light) : number {
+        public removeLight(toRemove: Light): number {
             var index = this.lights.indexOf(toRemove);
-            if (index != -1) {
+            if (index !== -1) {
                 // Remove from the scene if mesh found 
                 this.lights.splice(index, 1);
             }
@@ -752,9 +752,9 @@
             return index;
         }
 
-        public removeCamera(toRemove: Camera) : number {
+        public removeCamera(toRemove: Camera): number {
             var index = this.cameras.indexOf(toRemove);
-            if (index != -1) {
+            if (index !== -1) {
                 // Remove from the scene if mesh found 
                 this.cameras.splice(index, 1);
             }

+ 144 - 39
babylon.2.1-alpha.debug.js

@@ -5293,7 +5293,7 @@ var __extends = this.__extends || function (d, b) {
             return true;
         };
         Node.prototype.isSynchronizedWithParent = function () {
-            return this.parent ? this.parent._currentRenderId <= this._currentRenderId : true;
+            return this.parent ? this.parent._currentRenderId <= this._currentRenderId && this.parent.isSynchronized() : true;
         };
         Node.prototype.isSynchronized = function (updateCache) {
             var check = this.hasNewParent();
@@ -5698,7 +5698,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;
@@ -5741,8 +5741,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);
@@ -6603,7 +6602,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;
             }
@@ -6832,8 +6831,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);
             }
@@ -8418,6 +8416,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
@@ -9717,7 +9766,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 () {
@@ -9826,7 +9875,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);
             }
@@ -9842,7 +9891,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);
             }
@@ -10000,7 +10049,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);
@@ -10044,11 +10093,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);
@@ -10060,7 +10109,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 {
@@ -10104,7 +10153,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>
@@ -10387,8 +10436,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++) {
@@ -10400,14 +10450,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--;
                     }
@@ -10415,7 +10461,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();
                     }
                 }
@@ -11321,7 +11367,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; }
@@ -11334,6 +11380,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; }
@@ -15968,8 +16052,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);
@@ -18086,7 +18176,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
@@ -19100,8 +19190,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;
@@ -24652,6 +24748,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();
+                        }
                     }
                 }
             }
@@ -27877,14 +27977,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.
@@ -27900,6 +27999,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();
                     });
@@ -27941,6 +28041,7 @@ var BABYLON;
             this.error = new Array(4);
             this.deleted = false;
             this.isDirty = false;
+            this.deletePending = false;
             this.borderFactor = 0;
         }
         return DecimationTriangle;
@@ -28038,7 +28139,6 @@ var BABYLON;
                 });
             }, function () {
                 setTimeout(function () {
-                    _this._reconstructedMesh.isVisible = true;
                     successCallback(_this._reconstructedMesh);
                 }, 0);
             });
@@ -28108,7 +28208,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;
@@ -28117,10 +28226,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);
@@ -28254,7 +28359,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++;
                 }
             }
@@ -28354,7 +28459,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;

File diff suppressed because it is too large
+ 16 - 16
babylon.2.1-alpha.js