Browse Source

Merge pull request #1530 from abow/master

additions to BoneIKController, BoneLookController, and Bone
David Catuhe 8 years ago
parent
commit
8083e983f1

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

@@ -689,5 +689,32 @@
             }
         }
 
+        public getAbsolutePositionFromLocal(position:Vector3, mesh?:AbstractMesh): Vector3{
+
+            var result = Vector3.Zero();
+
+            this.getAbsolutePositionFromLocalToRef(position, mesh, result);
+
+            return result;
+
+        }
+
+        public getAbsolutePositionFromLocalToRef(position:Vector3, mesh:AbstractMesh, result:Vector3): void{
+
+            this._skeleton.computeAbsoluteTransforms();
+
+            var tmat = Tmp.Matrix[0];
+            
+            if (mesh) {
+                tmat.copyFrom(this.getAbsoluteTransform());
+                tmat.multiplyToRef(mesh.getWorldMatrix(), tmat);
+            }else{
+                tmat = this.getAbsoluteTransform();
+            }
+
+            Vector3.TransformCoordinatesToRef(position, tmat, result);
+
+        }
+
     }
 } 

+ 87 - 37
src/Bones/babylon.boneIKController.ts

@@ -1,9 +1,16 @@
 module BABYLON {
     export class BoneIKController {
 
-        public target: AbstractMesh;
-        public poleTarget: AbstractMesh;
+        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;
 
         private _bone1: Bone;
@@ -24,6 +31,8 @@ module BABYLON {
 
         private _rightHandedSystem = false;
 
+        private _bendAxis = Vector3.Right();
+
         get maxAngle(): number {
 
             return this._maxAngle;
@@ -36,21 +45,18 @@ module BABYLON {
 
         }
 
-        constructor(mesh: AbstractMesh, bone: Bone, target: AbstractMesh, poleTarget: AbstractMesh, poleAngle: number = 0){
-
-            target.computeWorldMatrix(true);
-            poleTarget.computeWorldMatrix(true);
+        constructor(mesh: AbstractMesh, bone: Bone, options?: { targetMesh?: AbstractMesh, poleTargetMesh?: AbstractMesh, poleTargetBone?: Bone, poleTargetLocalOffset?:Vector3, poleAngle?: number, bendAxis?: Vector3, maxAngle?:number }){
 
             this._bone2 = bone;
             this._bone1 = bone.getParent();
 
-            this.target = target;
-            this.poleTarget = poleTarget;
-            this.poleAngle = poleAngle;
             this.mesh = mesh;
 
-            if(bone.getAbsoluteTransform().determinant() > 0){
+             if(bone.getAbsoluteTransform().determinant() > 0){
                 this._rightHandedSystem = true;
+                this._bendAxis.x = 0;
+                this._bendAxis.y = 0;
+                this._bendAxis.z = 1;
             }
 
             if (this._bone1.length) {
@@ -58,8 +64,8 @@ module BABYLON {
                 var boneScale1 = this._bone1.getScale();
                 var boneScale2 = this._bone2.getScale();
                 
-                this._bone1Length = this._bone1.length * boneScale1.y;
-                this._bone2Length = this._bone2.length * boneScale2.y;
+                this._bone1Length = this._bone1.length * boneScale1.y * this.mesh.scaling.y;
+                this._bone2Length = this._bone2.length * boneScale2.y * this.mesh.scaling.y;
 
             } else if (this._bone1.children[0]) {
             
@@ -75,6 +81,46 @@ module BABYLON {
             }
 
             this.maxAngle = Math.PI;
+            
+            if(options){
+
+                if(options.targetMesh){
+                    this.targetMesh = options.targetMesh;
+                    this.targetMesh.computeWorldMatrix(true);
+                }
+
+                if(options.poleTargetMesh){
+
+                    this.poleTargetMesh = options.poleTargetMesh;
+                    this.poleTargetMesh.computeWorldMatrix(true);
+
+                }else if(options.poleTargetBone){
+
+                    this.poleTargetBone = options.poleTargetBone;
+
+                }else if(this._bone1.getParent()){
+
+                    this.poleTargetBone = this._bone1.getParent();
+
+                }
+
+                if(options.poleTargetLocalOffset){
+                    this.poleTargetLocalOffset.copyFrom(options.poleTargetLocalOffset);
+                }
+
+                if(options.poleAngle){
+                    this.poleAngle = options.poleAngle;
+                }
+
+                if(options.bendAxis){
+                    this._bendAxis.copyFrom(options.bendAxis);
+                }
+
+                if(options.maxAngle){
+                    this.maxAngle = options.maxAngle;
+                }
+
+            }
 
         }
 
@@ -100,17 +146,28 @@ module BABYLON {
         public update (): void {
 	
             var bone1 = this._bone1;
-            var target = this.target.getAbsolutePosition();
-            var poleTarget = this.poleTarget.getAbsolutePosition();
+            var target = this.targetPosition;
+            var poleTarget = this.poleTargetPosition;
+
+            var mat1 = this._tmpMat1;
+            var mat2 = this._tmpMat2;
+
+            if(this.targetMesh){
+                target.copyFrom(this.targetMesh.getAbsolutePosition());
+            }
+
+            if(this.poleTargetBone){
+                this.poleTargetBone.getAbsolutePositionFromLocalToRef(this.poleTargetLocalOffset, this.mesh, poleTarget);
+            }else if(this.poleTargetMesh){
+                Vector3.TransformCoordinatesToRef(this.poleTargetLocalOffset, this.poleTargetMesh.getWorldMatrix(), poleTarget);
+            }
 
             var bonePos = this._tmpVec1;
             var zaxis = this._tmpVec2;
             var xaxis = this._tmpVec3;
             var yaxis = this._tmpVec4;
             var upAxis = this._tmpVec5;
-            var mat1 = this._tmpMat1;
-            var mat2 = this._tmpMat2;
-
+            
             bone1.getAbsolutePositionToRef(this.mesh, bonePos);
 
             poleTarget.subtractToRef(bonePos, upAxis);
@@ -165,38 +222,31 @@ module BABYLON {
 
             var angC = -angA - angB;
 
-            
-            var bendAxis = this._tmpVec1;
-            bendAxis.x = 0;
-            bendAxis.y = 0;
-            bendAxis.z = 0;
-
             if (this._rightHandedSystem) {
 
-                bendAxis.z = 1;
+                Matrix.RotationYawPitchRollToRef(0, 0, Math.PI * .5, mat2);
+                mat2.multiplyToRef(mat1, mat1);
 
-                Matrix.RotationYawPitchRollToRef(0, 0, angB + Math.PI*.5, mat2);
+                Matrix.RotationAxisToRef(this._bendAxis, angB, mat2);
                 mat2.multiplyToRef(mat1, mat1);
-                
-                Matrix.RotationAxisToRef(yaxis, this.poleAngle + Math.PI, mat2);
-                mat1.multiplyToRef(mat2, mat1);
 
-            } else {
+            }else {
 
-                bendAxis.x = 1;
+                this._tmpVec1.copyFrom(this._bendAxis);
+                this._tmpVec1.x *= -1;
 
-                Matrix.RotationYawPitchRollToRef(0, angB, 0, mat2);
+                Matrix.RotationAxisToRef(this._tmpVec1, -angB, mat2);
                 mat2.multiplyToRef(mat1, mat1);
+                
+            }
 
-                if (this.poleAngle) {
-                    Matrix.RotationAxisToRef(yaxis, this.poleAngle, mat2);
-                    mat1.multiplyToRef(mat2, mat1);
-                }
-
+            if (this.poleAngle) {
+                Matrix.RotationAxisToRef(yaxis, this.poleAngle, mat2);
+                mat1.multiplyToRef(mat2, mat1);
             }
 
             this._bone1.setRotationMatrix(mat1, Space.WORLD, this.mesh);
-            this._bone2.setAxisAngle(bendAxis, angC, Space.LOCAL);
+            this._bone2.setAxisAngle(this._bendAxis, angC, Space.LOCAL);
 
         }
 

+ 16 - 4
src/Bones/babylon.boneLookController.ts

@@ -18,15 +18,27 @@ module BABYLON {
         private _tmpMat1 = Matrix.Identity();
         private _tmpMat2 = Matrix.Identity();
 
-        constructor(mesh: AbstractMesh, bone: Bone, target: Vector3, adjustYaw: number = 0, adjustPitch: number = 0, adjustRoll: number = 0){
+        constructor(mesh: AbstractMesh, bone: Bone, target: Vector3, options?: {adjustYaw?: number, adjustPitch?: number, adjustRoll?: number} ){
 
             this.mesh = mesh;
             this.bone = bone;
             this.target = target;
 
-            this.adjustYaw = adjustYaw;
-            this.adjustPitch = adjustPitch;
-            this.adjustRoll = adjustRoll;
+            if(options){
+
+                if(options.adjustYaw){
+                    this.adjustYaw = options.adjustYaw;
+                }
+
+                if(options.adjustPitch){
+                    this.adjustPitch = options.adjustPitch;
+                }
+
+                if(options.adjustRoll){
+                    this.adjustRoll = options.adjustRoll;
+                }
+
+            }
 
         }