瀏覽代碼

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

David Catuhe 8 年之前
父節點
當前提交
3d88bfa675
共有 3 個文件被更改,包括 113 次插入9 次删除
  1. 37 0
      src/Bones/babylon.bone.ts
  2. 31 8
      src/Bones/babylon.boneIKController.ts
  3. 45 1
      src/Math/babylon.math.ts

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

@@ -689,6 +689,43 @@
             }
         }
 
+        public getRotationMatrix(space = Space.LOCAL, mesh: AbstractMesh): Matrix {
+
+            var result = Matrix.Identity();
+
+            this.getRotationMatrixToRef(space, mesh, result);
+
+            return result;
+
+        }
+
+        public getRotationMatrixToRef(space = Space.LOCAL, mesh: AbstractMesh, result: Matrix): void{
+
+            if(space == Space.LOCAL){
+
+                this.getLocalMatrix().getRotationMatrixToRef(result);
+
+            }else{
+
+                var mat = Tmp.Matrix[0];
+                var amat = this.getAbsoluteTransform();
+
+                if(mesh){
+                    amat.multiplyToRef(mesh.getWorldMatrix(), mat);
+                }else{
+                    mat.copyFrom(amat);
+                }
+
+                mat.m[0] *= this._scalingDeterminant;
+                mat.m[1] *= this._scalingDeterminant;
+                mat.m[2] *= this._scalingDeterminant;
+
+                mat.getRotationMatrixToRef(result);
+                
+            }
+
+        }
+
         public getAbsolutePositionFromLocal(position:Vector3, mesh?:AbstractMesh): Vector3{
 
             var result = Vector3.Zero();

+ 31 - 8
src/Bones/babylon.boneIKController.ts

@@ -4,14 +4,16 @@ module BABYLON {
         public targetMesh: AbstractMesh;
         public poleTargetMesh: AbstractMesh;
         public poleTargetBone: Bone;
-
         public targetPosition = Vector3.Zero();
         public poleTargetPosition = Vector3.Zero();
-        
         public poleTargetLocalOffset = Vector3.Zero();
         public poleAngle = 0;
-
         public mesh: AbstractMesh;
+        public slerpAmount = 1;
+
+        private _bone1Quat = Quaternion.Identity();
+        private _bone1Mat = Matrix.Identity();
+        private _bone2Ang = Math.PI;
 
         private _bone1: Bone;
         private _bone2: Bone;
@@ -25,13 +27,14 @@ module BABYLON {
         private _tmpVec3 = Vector3.Zero();
         private _tmpVec4 = Vector3.Zero();
         private _tmpVec5 = Vector3.Zero();
-
         private _tmpMat1 = Matrix.Identity();
         private _tmpMat2 = Matrix.Identity();
+        private _tmpQuat1 = Quaternion.Identity();
 
         private _rightHandedSystem = false;
 
         private _bendAxis = Vector3.Right();
+        private _slerping = false;
 
         get maxAngle(): number {
 
@@ -45,11 +48,11 @@ module BABYLON {
 
         }
 
-        constructor(mesh: AbstractMesh, bone: Bone, options?: { targetMesh?: AbstractMesh, poleTargetMesh?: AbstractMesh, poleTargetBone?: Bone, poleTargetLocalOffset?:Vector3, poleAngle?: number, bendAxis?: Vector3, maxAngle?:number }){
+        constructor(mesh: AbstractMesh, bone: Bone, options?: { targetMesh?: AbstractMesh, poleTargetMesh?: AbstractMesh, poleTargetBone?: Bone, poleTargetLocalOffset?:Vector3, poleAngle?: number, bendAxis?: Vector3, maxAngle?:number, slerpAmount?:number }){
 
             this._bone2 = bone;
             this._bone1 = bone.getParent();
-
+            
             this.mesh = mesh;
 
              if(bone.getAbsoluteTransform().determinant() > 0){
@@ -80,6 +83,7 @@ module BABYLON {
 
             }
 
+            this._bone1.getRotationMatrixToRef(Space.WORLD, mesh, this._bone1Mat);
             this.maxAngle = Math.PI;
             
             if(options){
@@ -120,6 +124,10 @@ module BABYLON {
                     this.maxAngle = options.maxAngle;
                 }
 
+                if(options.slerpAmount){
+                    this.slerpAmount = options.slerpAmount;
+                }
+
             }
 
         }
@@ -230,7 +238,7 @@ module BABYLON {
                 Matrix.RotationAxisToRef(this._bendAxis, angB, mat2);
                 mat2.multiplyToRef(mat1, mat1);
 
-            }else {
+            } else {
 
                 this._tmpVec1.copyFrom(this._bendAxis);
                 this._tmpVec1.x *= -1;
@@ -245,8 +253,23 @@ module BABYLON {
                 mat1.multiplyToRef(mat2, mat1);
             }
 
-            this._bone1.setRotationMatrix(mat1, Space.WORLD, this.mesh);
+            if(this.slerpAmount < 1){
+                if(!this._slerping){
+                    Quaternion.FromRotationMatrixToRef(this._bone1Mat, this._bone1Quat);
+                }
+                Quaternion.FromRotationMatrixToRef(mat1, this._tmpQuat1);
+                Quaternion.SlerpToRef(this._bone1Quat, this._tmpQuat1, this.slerpAmount, this._bone1Quat);
+                angC = this._bone2Ang * (1.0 - this.slerpAmount) + angC * this.slerpAmount;
+                this._bone1.setRotationQuaternion(this._bone1Quat, Space.WORLD, this.mesh);
+                this._slerping = true;
+            } else {
+                this._bone1.setRotationMatrix(mat1, Space.WORLD, this.mesh);
+                this._bone1Mat.copyFrom(mat1);
+                this._slerping = false;
+            }
+
             this._bone2.setAxisAngle(this._bendAxis, angC, Space.LOCAL);
+            this._bone2Ang = angC;
 
         }
 

+ 45 - 1
src/Math/babylon.math.ts

@@ -2120,6 +2120,16 @@
         }
 
         public static Slerp(left: Quaternion, right: Quaternion, amount: number): Quaternion {
+            
+            var result = Quaternion.Identity();
+
+            Quaternion.SlerpToRef(left, right, amount, result);
+
+            return result;
+
+        }
+
+        public static SlerpToRef(left: Quaternion, right: Quaternion, amount: number, result:Quaternion): void {
             var num2;
             var num3;
             var num = amount;
@@ -2142,7 +2152,11 @@
                 num2 = flag ? ((-Math.sin(num * num5)) * num6) : ((Math.sin(num * num5)) * num6);
             }
 
-            return new Quaternion((num3 * left.x) + (num2 * right.x), (num3 * left.y) + (num2 * right.y), (num3 * left.z) + (num2 * right.z), (num3 * left.w) + (num2 * right.w));
+            result.x = (num3 * left.x) + (num2 * right.x);
+            result.y = (num3 * left.y) + (num2 * right.y);
+            result.z = (num3 * left.z) + (num2 * right.z);
+            result.w = (num3 * left.w) + (num2 * right.w);
+
         }
     }
 
@@ -2448,6 +2462,36 @@
             return true;
         }
 
+        public getRotationMatrix(): Matrix{
+
+            var result = Matrix.Identity();
+
+            this.getRotationMatrixToRef(result);
+
+            return result;
+
+        }
+
+        public getRotationMatrixToRef(result:Matrix): void{
+
+            var m = this.m;
+
+            var xs = m[0] * m[1] * m[2] * m[3] < 0 ? -1 : 1;
+            var ys = m[4] * m[5] * m[6] * m[7] < 0 ? -1 : 1;
+            var zs = m[8] * m[9] * m[10] * m[11] < 0 ? -1 : 1;
+
+            var sx = xs * Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
+            var sy = ys * Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
+            var sz = zs * Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
+
+            Matrix.FromValuesToRef(
+                m[0] / sx, m[1] / sx, m[2] / sx, 0,
+                m[4] / sy, m[5] / sy, m[6] / sy, 0,
+                m[8] / sz, m[9] / sz, m[10] / sz, 0,
+                0, 0, 0, 1, result);
+
+        }
+
         // Statics
         public static FromArray(array: number[], offset?: number): Matrix {
             var result = new Matrix();