David Catuhe преди 7 години
родител
ревизия
f980e5fd54

+ 5 - 2
src/Lights/babylon.hemisphericLight.ts

@@ -93,9 +93,12 @@
         }
 
         /**
-         * @hidden internal use only.
+         * Computes the world matrix of the node
+         * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
+         * @param useWasUpdatedFlag defines a reserved property
+         * @returns the world matrix
          */
-        public _getWorldMatrix(): Matrix {
+        public computeWorldMatrix(force?: boolean, useWasUpdatedFlag?: boolean): Matrix {
             if (!this._worldMatrix) {
                 this._worldMatrix = Matrix.Identity();
             }

+ 3 - 8
src/Lights/babylon.light.ts

@@ -354,11 +354,6 @@ module BABYLON {
         public abstract transferToEffect(effect: Effect, lightIndex: string): Light;
 
         /**
-         * @hidden internal use only.
-         */
-        public abstract _getWorldMatrix(): Matrix;
-
-        /**
          * Returns the string "Light".
          * @returns the class name
          */
@@ -438,16 +433,16 @@ module BABYLON {
 
             return true;
         }
-
+ 
         /**
-         * Computes and Returns the light World matrix.
+         * Computes and returns the light World matrix
          * @returns the world matrix 
          */
         public getWorldMatrix(): Matrix {
             this._currentRenderId = this.getScene().getRenderId();
             this._childRenderId = this._currentRenderId;
 
-            var worldMatrix = this._getWorldMatrix();
+            var worldMatrix = this.computeWorldMatrix();
 
             if (this.parent && this.parent.getWorldMatrix) {
                 if (!this._parentedWorldMatrix) {

+ 29 - 3
src/Lights/babylon.shadowLight.ts

@@ -301,11 +301,37 @@
             this._needProjectionMatrixCompute = true;
         }
 
+        /** @hidden */
+        public _initCache() {
+            super._initCache();
+
+            this._cache.position = Vector3.Zero();
+        }
+
+        /** @hidden */
+        public _isSynchronized(): boolean {
+            if (!this._cache.position.equals(this.position))
+                return false;
+
+            return true;
+        }        
+
         /**
-         * Get the world matrix of the sahdow lights.
-         * @hidden Internal Use Only
+         * Computes the world matrix of the node
+         * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
+         * @param useWasUpdatedFlag defines a reserved property
+         * @returns the world matrix
          */
-        public _getWorldMatrix(): Matrix {
+        public computeWorldMatrix(force?: boolean, useWasUpdatedFlag?: boolean): Matrix {
+            if (!force && this.isSynchronized(useWasUpdatedFlag)) {
+                this._currentRenderId = this.getScene().getRenderId();
+                return this._worldMatrix;
+            }
+
+            this._updateCache();
+            this._cache.position.copyFrom(this.position);
+            this._worldMatrixWasUpdated = true;
+
             if (!this._worldMatrix) {
                 this._worldMatrix = Matrix.Identity();
             }

+ 1 - 1
src/Mesh/babylon.subMesh.ts

@@ -67,7 +67,7 @@
         }
 
         public get IsGlobal(): boolean {
-            return (this.verticesStart === 0 && this.verticesCount == this._mesh.getTotalVertices());
+            return (this.verticesStart === 0 && this.verticesCount === this._mesh.getTotalVertices());
         }
 
         /**

+ 36 - 28
src/Mesh/babylon.transformNode.ts

@@ -14,13 +14,16 @@ module BABYLON {
         private _rightInverted = new Vector3(-1, 0, 0);
 
         // Properties
-        @serializeAsVector3()
+        @serializeAsVector3("position")
+        private _position = Vector3.Zero();
+
+        @serializeAsVector3("rotation")
         private _rotation = Vector3.Zero();
 
-        @serializeAsQuaternion()
+        @serializeAsQuaternion("rotationQuaternion")
         private _rotationQuaternion: Nullable<Quaternion>;
 
-        @serializeAsVector3()
+        @serializeAsVector3("scaling")
         protected _scaling = Vector3.One();
         protected _isDirty = false;
         private _transformToBoneReferal: Nullable<TransformNode>;
@@ -53,9 +56,6 @@ module BABYLON {
         @serialize()
         public ignoreNonUniformScaling = false;
 
-        @serializeAsVector3()
-        public position = Vector3.Zero();
-
         // Cache      
         /** @hidden */
         public _poseMatrix: Matrix;
@@ -93,9 +93,20 @@ module BABYLON {
         }
 
         /**
-          * Rotation property : a Vector3 depicting the rotation value in radians around each local axis X, Y, Z. 
-          * If rotation quaternion is set, this Vector3 will (almost always) be the Zero vector!
-          * Default : (0.0, 0.0, 0.0)
+          * Gets or set the node position (default is (0.0, 0.0, 0.0))
+          */
+         public get position(): Vector3 {
+            return this._position;
+        }
+
+        public set position(newPosition: Vector3) {
+            this._position = newPosition;
+            this._isDirty = true;
+        }        
+
+        /**
+          * Gets or sets the rotation property : a Vector3 defining the rotation value in radians around each local axis X, Y, Z  (default is (0.0, 0.0, 0.0)).
+          * If rotation quaternion is set, this Vector3 will be ignored and copy from the quaternion
           */
         public get rotation(): Vector3 {
             return this._rotation;
@@ -103,28 +114,24 @@ module BABYLON {
 
         public set rotation(newRotation: Vector3) {
             this._rotation = newRotation;
+            this._isDirty = true;
         }
 
         /**
-         * Scaling property : a Vector3 depicting the mesh scaling along each local axis X, Y, Z.  
-         * Default : (1.0, 1.0, 1.0)
+         * Gets or sets the scaling property : a Vector3 defining the node scaling along each local axis X, Y, Z (default is (0.0, 0.0, 0.0)).
          */
         public get scaling(): Vector3 {
             return this._scaling;
         }
 
-        /**
-         * Scaling property : a Vector3 depicting the mesh scaling along each local axis X, Y, Z.  
-         * Default : (1.0, 1.0, 1.0)
-        */
         public set scaling(newScaling: Vector3) {
             this._scaling = newScaling;
+            this._isDirty = true;
         }
 
         /**
-         * Rotation Quaternion property : this a Quaternion object depicting the mesh rotation by using a unit quaternion. 
-         * It's null by default.  
-         * If set, only the rotationQuaternion is then used to compute the mesh rotation and its property `.rotation\ is then ignored and set to (0.0, 0.0, 0.0)
+         * Gets or sets the rotation Quaternion property : this a Quaternion object defining the node rotation by using a unit quaternion (null by default).
+         * If set, only the rotationQuaternion is then used to compute the node rotation (ie. node.rotation will be ignored)
          */
         public get rotationQuaternion(): Nullable<Quaternion> {
             return this._rotationQuaternion;
@@ -226,7 +233,7 @@ module BABYLON {
                 return false;
             }
 
-            if (!this._cache.position.equals(this.position))
+            if (!this._cache.position.equals(this._position))
                 return false;
 
             if (this._rotationQuaternion) {
@@ -234,10 +241,10 @@ module BABYLON {
                     return false;
             }
 
-            if (!this._cache.rotation.equals(this.rotation))
+            if (!this._cache.rotation.equals(this._rotation))
                 return false;
 
-            if (!this._cache.scaling.equals(this.scaling))
+            if (!this._cache.scaling.equals(this._scaling))
                 return false;
 
             return true;
@@ -753,22 +760,22 @@ module BABYLON {
         }
 
         /**
-         * Computes the mesh World matrix and returns it.  
-         * If the mesh world matrix is frozen, this computation does nothing more than returning the last frozen values.  
-         * If the parameter `force` is let to `false` (default), the current cached World matrix is returned. 
-         * If the parameter `force`is set to `true`, the actual computation is done.  
-         * Returns the mesh World Matrix.
+         * Computes the world matrix of the node
+         * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
+         * @param useWasUpdatedFlag defines a reserved property
+         * @returns the world matrix
          */
-        public computeWorldMatrix(force?: boolean): Matrix {
+        public computeWorldMatrix(force?: boolean, useWasUpdatedFlag?: boolean): Matrix {
             if (this._isWorldMatrixFrozen) {
                 return this._worldMatrix;
             }
 
-            if (!force && this.isSynchronized(true)) {
+            if (!force && this.isSynchronized(useWasUpdatedFlag)) {
                 this._currentRenderId = this.getScene().getRenderId();
                 return this._worldMatrix;
             }
 
+            this._updateCache();
             this._cache.position.copyFrom(this.position);
             this._cache.scaling.copyFrom(this.scaling);
             this._cache.pivotMatrixUpdated = false;
@@ -776,6 +783,7 @@ module BABYLON {
             this._currentRenderId = this.getScene().getRenderId();
             this._childRenderId = this.getScene().getRenderId();
             this._isDirty = false;
+            this._worldMatrixWasUpdated = true;
 
             // Scaling
             Matrix.ScalingToRef(this.scaling.x * this.scalingDeterminant, this.scaling.y * this.scalingDeterminant, this.scaling.z * this.scalingDeterminant, Tmp.Matrix[1]);

+ 23 - 14
src/babylon.node.ts

@@ -104,6 +104,10 @@
         private _parentNode: Nullable<Node>;
         private _children: Node[];
 
+        /** @hidden */
+        public _worldMatrixWasUpdated = false;
+        private _identityMatrix: Matrix;
+
         /**
          * Gets a boolean indicating if the node has been disposed
          * @returns true if the node was disposed
@@ -356,37 +360,38 @@
 
         /** @hidden */
         public isSynchronizedWithParent(): boolean {
-            if (!this.parent) {
+            if (!this._parentNode) {
                 return true;
             }
 
-            if (this._parentRenderId !== this.parent._childRenderId) {
+            if (this._parentRenderId !== this._parentNode._childRenderId) {
                 return false;
             }
 
-            return this.parent.isSynchronized();
+            return this._parentNode.isSynchronized();
         }
 
         /** @hidden */
-        public isSynchronized(updateCache?: boolean): boolean {
+        public isSynchronized(useWasUpdatedFlag?: boolean): boolean {
             var check = this.hasNewParent();
 
-            check = check || !this.isSynchronizedWithParent();
+            if (!useWasUpdatedFlag) {
+                check = check || !this.isSynchronizedWithParent();
+            } else if (this._parentNode) {
+                check = this._parentNode._worldMatrixWasUpdated; 
+            }
 
             check = check || !this._isSynchronized();
 
-            if (updateCache)
-                this.updateCache(true);
-
             return !check;
         }
 
         /** @hidden */
         public hasNewParent(): boolean {
-            if (this._cache.parent === this.parent)
+            if (this._cache.parent === this._parentNode)
                 return false;
 
-            this._cache.parent = this.parent;
+            this._cache.parent = this._parentNode;
 
             return true;
         }
@@ -415,8 +420,8 @@
                 return false;
             }
 
-            if (this.parent !== undefined && this.parent !== null) {
-                return this.parent.isEnabled(checkAncestors);
+            if (this._parentNode !== undefined && this._parentNode !== null) {
+                return this._parentNode.isEnabled(checkAncestors);
             }
 
             return true;
@@ -637,10 +642,14 @@
         /**
          * Computes the world matrix of the node
          * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
+         * @param useWasUpdatedFlag defines a reserved property
          * @returns the world matrix
          */
-        public computeWorldMatrix(force?: boolean): Matrix {
-            return Matrix.Identity();
+        public computeWorldMatrix(force?: boolean, useWasUpdatedFlag?: boolean): Matrix {
+            if (!this._identityMatrix) {
+                this._identityMatrix = Matrix.Identity();
+            }
+            return this._identityMatrix;
         }
 
         /**

+ 25 - 2
src/babylon.scene.ts

@@ -4060,6 +4060,28 @@
             return this;
         }
 
+        private _computeAllWorldMatricesforBranch(node: Node) {
+            node.computeWorldMatrix(false, true);
+            const children = node.getChildren();
+
+            if (children) {
+                for (var child of children) {
+                    this._computeAllWorldMatricesforBranch(child);
+                }
+            }
+            
+            node._worldMatrixWasUpdated = false;
+        }
+
+        /**
+         * This function will traverse the scene graph and makes sure that all worldMatrix are up to date
+         */
+        public computeAllWorldMatrices() {
+            for (var node of this.rootNodes) {
+                this._computeAllWorldMatricesforBranch(node);
+            }
+        }
+
         private _evaluateActiveMeshes(): void {
             if (this._activeMeshesFrozen && this._activeMeshes.length) {
                 return;
@@ -4082,6 +4104,9 @@
                 step.action();
             }
 
+            // World matrices
+            this.computeAllWorldMatrices();
+
             // Determine mesh candidates
             const meshes = this.getActiveMeshCandidates();
             
@@ -4099,8 +4124,6 @@
                     continue;
                 }
 
-                mesh.computeWorldMatrix();
-
                 // Intersections
                 if (mesh.actionManager && mesh.actionManager.hasSpecificTriggers2(ActionManager.OnIntersectionEnterTrigger, ActionManager.OnIntersectionExitTrigger)) {
                     this._meshesForIntersections.pushNoDuplicate(mesh);