Преглед на файлове

Merge pull request #1478 from abow/master

fixed bug with Bone.rotate, Bone.Scale (initialized private vars) -ad…
David Catuhe преди 8 години
родител
ревизия
a604f4bae0
променени са 3 файла, в които са добавени 162 реда и са изтрити 72 реда
  1. 2 0
      dist/preview release/what's new.md
  2. 146 72
      src/Bones/babylon.bone.ts
  3. 14 0
      src/Bones/babylon.skeleton.ts

+ 2 - 0
dist/preview release/what's new.md

@@ -8,6 +8,8 @@
 - Canvas2D moved to a separate folder in main repo. Now you need to also include babylon.cavans2d.js to get Canvas@D feature ([deltakosh](https://github.com/deltakosh))
 
 ### Updates
+- Added Bone.getAbsolutePosition and Bone.getAbsolutePositionToRef ([abow](https://github.com/abow))
+- Added Bone.setYawPitchRoll ([abow](https://github.com/abow))
 - Added Bone.rotate ([abow](https://github.com/abow))
 - Added Bone.scale ([abow](https://github.com/abow))
 - Added Node.getDirection ([abow](https://github.com/abow))

+ 146 - 72
src/Bones/babylon.bone.ts

@@ -13,9 +13,9 @@
         private _invertedAbsoluteTransform = new Matrix();
         private _parent: Bone;
 
-        private _scaleMatrix: Matrix;
-        private _scaleVector: Vector3;
-
+        private _scaleMatrix: Matrix = BABYLON.Matrix.Identity();
+        private _scaleVector: Vector3 = new BABYLON.Vector3(1, 1, 1);
+        
         constructor(public name: string, skeleton: Skeleton, parentBone: Bone, matrix: Matrix, restPose?: Matrix) {
             super(name, skeleton.getScene());
             this._skeleton = skeleton;
@@ -165,154 +165,182 @@
             return true;
         }
 
-        public scale (x: number, y: number, z: number, scaleChildren = false) {
+        public scale (x: number, y: number, z: number, scaleChildren = false): void {
 	
             var locMat = this.getLocalMatrix();
-            
             var origLocMat = BABYLON.Tmp.Matrix[0];
             origLocMat.copyFrom(locMat);
-            
+
             var origLocMatInv = BABYLON.Tmp.Matrix[1];
             origLocMatInv.copyFrom(origLocMat);
             origLocMatInv.invert();
-            
+
             var scaleMat = BABYLON.Tmp.Matrix[2];
-            BABYLON.Matrix.FromValuesToRef(x, 0, 0, 0,
-                                            0, y, 0, 0,
-                                            0, 0, z, 0,
-                                            0, 0, 0, 1, scaleMat);
-                                                
+            BABYLON.Matrix.FromValuesToRef(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1, scaleMat);
             this._scaleMatrix.multiplyToRef(scaleMat, this._scaleMatrix);
-            
             this._scaleVector.x *= x;
             this._scaleVector.y *= y;
             this._scaleVector.z *= z;
-                    
+
             locMat.multiplyToRef(origLocMatInv, locMat);
             locMat.multiplyToRef(scaleMat, locMat);
             locMat.multiplyToRef(origLocMat, locMat);
-            
+
             var parent = this.getParent();
-            
+
             if (parent) {
                 locMat.multiplyToRef(parent.getAbsoluteTransform(), this.getAbsoluteTransform());
-            } else {
+            }else {
                 this.getAbsoluteTransform().copyFrom(locMat);
             }
-            
+
             var len = this.children.length;
-            
-            for (var i = 0; i < len; i++){
-                
+
+            for (var i = 0; i < len; i++) {
                 var parentAbsMat = this.children[i]._parent.getAbsoluteTransform();
-                
                 this.children[i].getLocalMatrix().multiplyToRef(parentAbsMat, this.children[i].getAbsoluteTransform());
+            }
+
+            scaleMat.invert();
             
+            if (this.children[0]) {
+                var child = this.children[0];
+                var cm = child.getLocalMatrix();
+                cm.multiplyToRef(scaleMat, cm);
+                var lm = child.getLocalMatrix();
+                lm.m[12] *= x;
+                lm.m[13] *= y;
+                lm.m[14] *= z;
             }
             
-            if (this.children[0] && !scaleChildren) {
+            if (scaleChildren) {
+                for (var i = 0; i < len; i++) {
+                    this.children[i].scale(x, y, z, scaleChildren);
+                    
+                }
+            }          
 
-                scaleMat.invert();
+            this.markAsDirty();
 
-                var cm = this.children[0].getLocalMatrix();
+        }
 
-                cm.multiplyToRef(scaleMat, cm);
+        public setYawPitchRoll (yaw: number, pitch: number, roll: number, space = BABYLON.Space.LOCAL, mesh: BABYLON.AbstractMesh = null): void {
+	
+            var rotMat = BABYLON.Tmp.Matrix[0];
+            BABYLON.Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, rotMat);
+            var rotMatInv = BABYLON.Tmp.Matrix[1];
+            
+            if (space == BABYLON.Space.WORLD) {
                 
-                var lm = this.children[0].getLocalMatrix();
+                rotMatInv.copyFrom(this.getAbsoluteTransform());
+                
+                if (mesh) {
+                    rotMatInv.multiplyToRef(mesh.getWorldMatrix(), rotMatInv);
+                }
+                
+                rotMatInv.invert();
+                
+                var scaleMatrix = BABYLON.Tmp.Matrix[2];
+                scaleMatrix.copyFrom(this._scaleMatrix);
+                scaleMatrix.m[0] *= -1;
                     
-                lm.m[12] *= this._scaleVector.x;
-                lm.m[13] *= this._scaleVector.y;
-                lm.m[14] *= this._scaleVector.z;
-
+                rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
+                rotMatInv.multiplyToRef(rotMat, rotMat);
+            
+            }else {
+                
+                rotMatInv.copyFrom(this.getLocalMatrix());
+                rotMatInv.invert();
+                
+                var scaleMatrix = BABYLON.Tmp.Matrix[2];
+                
+                scaleMatrix.copyFrom(this._scaleMatrix);
+                
+                if (this._parent) {
+                    var pscaleMatrix = BABYLON.Tmp.Matrix[3];
+                    pscaleMatrix.copyFrom(this._parent._scaleMatrix);
+                    pscaleMatrix.invert();
+                    pscaleMatrix.multiplyToRef(rotMatInv, rotMatInv);
+                }
+                
+                rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
+                rotMatInv.multiplyToRef(rotMat, rotMat);
+                
             }
             
-            this.markAsDirty();
-
+            this._rotateWithMatrix(rotMat, space, mesh);
+            
         }
 
-        public rotate (axis: BABYLON.Vector3, amount: number, space = BABYLON.Space.LOCAL, mesh: BABYLON.AbstractMesh = null) {
-
-            var lmat = this.getLocalMatrix();
-            
-            var lx = lmat.m[12];
-            var ly = lmat.m[13];
-            var lz = lmat.m[14];
+        public rotate (axis: BABYLON.Vector3, amount: number, space = BABYLON.Space.LOCAL, mesh: BABYLON.AbstractMesh = null): void {
             
             var rmat = BABYLON.Tmp.Matrix[0];
             rmat.m[12] = 0;
             rmat.m[13] = 0;
             rmat.m[14] = 0;
             
-            var parent = this.getParent();
-
             BABYLON.Matrix.RotationAxisToRef(axis, amount, rmat);
-
-            var parentScale = BABYLON.Tmp.Matrix[1];
-            var parentScaleInv = BABYLON.Tmp.Matrix[2];
             
+            this._rotateWithMatrix(rmat, space, mesh);
+            
+        }
+
+        private _rotateWithMatrix (rmat:BABYLON.Matrix, space = BABYLON.Space.LOCAL, mesh: BABYLON.AbstractMesh = null): void {
+
+            var lmat = this.getLocalMatrix();
+            var lx = lmat.m[12];
+            var ly = lmat.m[13];
+            var lz = lmat.m[14];
+            var parent = this.getParent();
+            var parentScale = BABYLON.Tmp.Matrix[3];
+            var parentScaleInv = BABYLON.Tmp.Matrix[4];
+
             if (parent) {
-                
                 if (space == BABYLON.Space.WORLD) {
-                    
                     if (mesh) {
                         parentScale.copyFrom(mesh.getWorldMatrix());
                         parent.getAbsoluteTransform().multiplyToRef(parentScale, parentScale);
-                    } else {
+                    }else {
                         parentScale.copyFrom(parent.getAbsoluteTransform());
                     }
-                    
-                } else {
-                    
+                }else {
                     parentScale = parent._scaleMatrix;
-                    
                 }
-
                 parentScaleInv.copyFrom(parentScale);
                 parentScaleInv.invert();
-                
                 lmat.multiplyToRef(parentScale, lmat);
                 lmat.multiplyToRef(rmat, lmat);
                 lmat.multiplyToRef(parentScaleInv, lmat);
-                
-            } else {
-                
+            }else {
                 if (space == BABYLON.Space.WORLD && mesh) {
-
                     parentScale.copyFrom(mesh.getWorldMatrix());
-
                     parentScaleInv.copyFrom(parentScale);
                     parentScaleInv.invert();
-                    
                     lmat.multiplyToRef(parentScale, lmat);
                     lmat.multiplyToRef(rmat, lmat);
                     lmat.multiplyToRef(parentScaleInv, lmat);
-                    
-                } else {
-                    
+                }else {
                     lmat.multiplyToRef(rmat, lmat);
-
                 }
-
             }
-            
+
             lmat.m[12] = lx;
             lmat.m[13] = ly;
             lmat.m[14] = lz;
-            
+
             if (parent) {
                 var parentAbsMat = this._parent.getAbsoluteTransform();
                 lmat.multiplyToRef(parentAbsMat, this.getAbsoluteTransform());
-            } else {
+            }else {
                 this.getAbsoluteTransform().copyFrom(lmat);
             }
-            
+
             var len = this.children.length;
-            
-            for (var i = 0; i < len; i++){
+            for (var i = 0; i < len; i++) {
                 var parentAbsMat = this.children[i]._parent.getAbsoluteTransform();
                 this.children[i].getLocalMatrix().multiplyToRef(parentAbsMat, this.children[i].getAbsoluteTransform());
             }
-            
+
             this.markAsDirty();
             
         }
@@ -329,5 +357,51 @@
             
         }
 
+        public getAbsolutePosition (mesh: BABYLON.AbstractMesh = null): BABYLON.Vector3 {
+
+            var pos = BABYLON.Vector3.Zero();
+
+            this.getAbsolutePositionToRef(mesh, pos);
+
+            return pos;
+
+        }
+
+        public getAbsolutePositionToRef (mesh: BABYLON.AbstractMesh = null, result: BABYLON.Vector3): void {
+
+            this._skeleton.computeAbsoluteTransforms();
+            
+            var tmat = BABYLON.Tmp.Matrix[0];
+
+            if (mesh) {
+                tmat.copyFrom(this.getAbsoluteTransform());
+                tmat.multiplyToRef(mesh.getWorldMatrix(), tmat);
+            }else{
+                tmat = this.getAbsoluteTransform();
+            }
+
+            result.x = tmat.m[12];
+            result.y = tmat.m[13];
+            result.z = tmat.m[14];
+
+        }
+
+        public computeAbsoluteTransforms (): void {
+
+            if (this._parent) {
+                this._matrix.multiplyToRef(this._parent._absoluteTransform, this._absoluteTransform);
+            } else {
+                this._absoluteTransform.copyFrom(this._matrix);
+            }
+
+            var children = this.children;
+            var len = children.length;
+
+            for (var i = 0; i < len; i++) {
+                children[i].computeAbsoluteTransforms();
+            }
+
+        }
+
     }
 } 

+ 14 - 0
src/Bones/babylon.skeleton.ts

@@ -13,6 +13,8 @@
 
         private _ranges: { [name: string]: AnimationRange; } = {};
 
+        private _lastAbsoluteTransformsUpdateId = -1;
+
         constructor(public name: string, public id: string, scene: Scene) {
             this.bones = [];
 
@@ -402,5 +404,17 @@
             }
             return skeleton;
         }
+
+        public computeAbsoluteTransforms (forceUpdate = false): void {
+
+            var renderId = this._scene.getRenderId();
+            
+            if (this._lastAbsoluteTransformsUpdateId != renderId || forceUpdate ) {
+                this.bones[0].computeAbsoluteTransforms();
+                this._lastAbsoluteTransformsUpdateId = renderId;
+            }
+            
+        }
+
     }
 }