Browse Source

Merge pull request #1477 from abow/master

added Bone.rotate and Bone.scale
David Catuhe 8 years ago
parent
commit
26ed1adc87
3 changed files with 176 additions and 3 deletions
  1. 2 0
      dist/preview release/what's new.md
  2. 168 0
      src/Bones/babylon.bone.ts
  3. 6 3
      src/Math/babylon.math.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.rotate ([abow](https://github.com/abow))
+- Added Bone.scale ([abow](https://github.com/abow))
 - Added Node.getDirection ([abow](https://github.com/abow))
 - New ```Tools.CreateScreenshot``` function will capture all canvas data. Previous implementation is now called `CreateScreenshotUsingRenderTarget` ([deltakosh](https://github.com/deltakosh)) 
 - Cube textures are now cached by texture cache ([deltakosh](https://github.com/deltakosh)) 

+ 168 - 0
src/Bones/babylon.bone.ts

@@ -13,6 +13,9 @@
         private _invertedAbsoluteTransform = new Matrix();
         private _parent: Bone;
 
+        private _scaleMatrix: Matrix;
+        private _scaleVector: Vector3;
+
         constructor(public name: string, skeleton: Skeleton, parentBone: Bone, matrix: Matrix, restPose?: Matrix) {
             super(name, skeleton.getScene());
             this._skeleton = skeleton;
@@ -161,5 +164,170 @@
             this.animations[0].createRange(rangeName, from + frameOffset, to + frameOffset);
             return true;
         }
+
+        public scale (x: number, y: number, z: number, scaleChildren = false) {
+	
+            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);
+                                                
+            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 {
+                this.getAbsoluteTransform().copyFrom(locMat);
+            }
+            
+            var len = this.children.length;
+            
+            for (var i = 0; i < len; i++){
+                
+                var parentAbsMat = this.children[i]._parent.getAbsoluteTransform();
+                
+                this.children[i].getLocalMatrix().multiplyToRef(parentAbsMat, this.children[i].getAbsoluteTransform());
+            
+            }
+            
+            if (this.children[0] && !scaleChildren) {
+
+                scaleMat.invert();
+
+                var cm = this.children[0].getLocalMatrix();
+
+                cm.multiplyToRef(scaleMat, cm);
+                
+                var lm = this.children[0].getLocalMatrix();
+                    
+                lm.m[12] *= this._scaleVector.x;
+                lm.m[13] *= this._scaleVector.y;
+                lm.m[14] *= this._scaleVector.z;
+
+            }
+            
+            this.markAsDirty();
+
+        }
+
+        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];
+            
+            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];
+            
+            if (parent) {
+                
+                if (space == BABYLON.Space.WORLD) {
+                    
+                    if (mesh) {
+                        parentScale.copyFrom(mesh.getWorldMatrix());
+                        parent.getAbsoluteTransform().multiplyToRef(parentScale, parentScale);
+                    } else {
+                        parentScale.copyFrom(parent.getAbsoluteTransform());
+                    }
+                    
+                } else {
+                    
+                    parentScale = parent._scaleMatrix;
+                    
+                }
+
+                parentScaleInv.copyFrom(parentScale);
+                parentScaleInv.invert();
+                
+                lmat.multiplyToRef(parentScale, lmat);
+                lmat.multiplyToRef(rmat, lmat);
+                lmat.multiplyToRef(parentScaleInv, lmat);
+                
+            } 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 {
+                    
+                    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 {
+                this.getAbsoluteTransform().copyFrom(lmat);
+            }
+            
+            var len = this.children.length;
+            
+            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();
+            
+        }
+
+        public getScale(): Vector3 {
+            
+            return this._scaleVector.clone();
+            
+        }
+
+        public getScaleToRef(result:Vector3): void {
+	
+            result.copyFrom(this._scaleVector);
+            
+        }
+
     }
 } 

+ 6 - 3
src/Math/babylon.math.ts

@@ -1074,9 +1074,12 @@
         }
 
         public static TransformNormalToRef(vector: Vector3, transformation: Matrix, result: Vector3): void {
-            result.x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]) + (vector.z * transformation.m[8]);
-            result.y = (vector.x * transformation.m[1]) + (vector.y * transformation.m[5]) + (vector.z * transformation.m[9]);
-            result.z = (vector.x * transformation.m[2]) + (vector.y * transformation.m[6]) + (vector.z * transformation.m[10]);
+            var x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]) + (vector.z * transformation.m[8]);
+            var y = (vector.x * transformation.m[1]) + (vector.y * transformation.m[5]) + (vector.z * transformation.m[9]);
+            var z = (vector.x * transformation.m[2]) + (vector.y * transformation.m[6]) + (vector.z * transformation.m[10]);
+            result.x = x;
+            result.y = y;
+            result.z = z;
         }
 
         public static TransformNormalFromFloatsToRef(x: number, y: number, z: number, transformation: Matrix, result: Vector3): void {