Explorar el Código

fixed issue with starting ik slerp in the middle of an animation and added Matrix.getRotationMatrix and Bone.getRotationMatrix

Adam Bowman hace 8 años
padre
commit
0d013b5cd2
Se han modificado 3 ficheros con 73 adiciones y 3 borrados
  1. 37 0
      src/Bones/babylon.bone.ts
  2. 6 3
      src/Bones/babylon.boneIKController.ts
  3. 30 0
      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{
         public getAbsolutePositionFromLocal(position:Vector3, mesh?:AbstractMesh): Vector3{
 
 
             var result = Vector3.Zero();
             var result = Vector3.Zero();

+ 6 - 3
src/Bones/babylon.boneIKController.ts

@@ -11,7 +11,8 @@ module BABYLON {
         public mesh: AbstractMesh;
         public mesh: AbstractMesh;
         public slerpAmount = 1;
         public slerpAmount = 1;
 
 
-        private _bone1Quat: Quaternion = Quaternion.Identity();
+        private _bone1Quat = Quaternion.Identity();
+        private _bone1Mat = Matrix.Identity();
         private _bone2Ang = Math.PI;
         private _bone2Ang = Math.PI;
 
 
         private _bone1: Bone;
         private _bone1: Bone;
@@ -51,7 +52,7 @@ module BABYLON {
 
 
             this._bone2 = bone;
             this._bone2 = bone;
             this._bone1 = bone.getParent();
             this._bone1 = bone.getParent();
-
+            
             this.mesh = mesh;
             this.mesh = mesh;
 
 
              if(bone.getAbsoluteTransform().determinant() > 0){
              if(bone.getAbsoluteTransform().determinant() > 0){
@@ -82,6 +83,7 @@ module BABYLON {
 
 
             }
             }
 
 
+            this._bone1.getRotationMatrixToRef(Space.WORLD, mesh, this._bone1Mat);
             this.maxAngle = Math.PI;
             this.maxAngle = Math.PI;
             
             
             if(options){
             if(options){
@@ -253,7 +255,7 @@ module BABYLON {
 
 
             if(this.slerpAmount < 1){
             if(this.slerpAmount < 1){
                 if(!this._slerping){
                 if(!this._slerping){
-                    this._bone1.getRotationQuaternionToRef(Space.WORLD, this.mesh, this._bone1Quat);
+                    Quaternion.FromRotationMatrixToRef(this._bone1Mat, this._bone1Quat);
                 }
                 }
                 Quaternion.FromRotationMatrixToRef(mat1, this._tmpQuat1);
                 Quaternion.FromRotationMatrixToRef(mat1, this._tmpQuat1);
                 Quaternion.SlerpToRef(this._bone1Quat, this._tmpQuat1, this.slerpAmount, this._bone1Quat);
                 Quaternion.SlerpToRef(this._bone1Quat, this._tmpQuat1, this.slerpAmount, this._bone1Quat);
@@ -262,6 +264,7 @@ module BABYLON {
                 this._slerping = true;
                 this._slerping = true;
             } else {
             } else {
                 this._bone1.setRotationMatrix(mat1, Space.WORLD, this.mesh);
                 this._bone1.setRotationMatrix(mat1, Space.WORLD, this.mesh);
+                this._bone1Mat.copyFrom(mat1);
                 this._slerping = false;
                 this._slerping = false;
             }
             }
 
 

+ 30 - 0
src/Math/babylon.math.ts

@@ -2462,6 +2462,36 @@
             return true;
             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
         // Statics
         public static FromArray(array: number[], offset?: number): Matrix {
         public static FromArray(array: number[], offset?: number): Matrix {
             var result = new Matrix();
             var result = new Matrix();