Reputation: 1022
From a tracking system I have access to a neck 4x4 transform matrix in relation to the camera (NeckWRTCameraMatrix).
I need to animate in three.js the neck bone that has as parent other bone but in a way that the rotation of the neck is in relation to the camera.
var m = new THREE.Matrix4();
m.fromArray(NeckWRTCameraMatrix);
var quaternion = new THREE.Quaternion();
quaternion.setFromRotationMatrix(m);
head.boneByName("Joint_Neck").quaternion.copy(quaternion);
However this rotates the bone in 180 degrees. How do I apply the rotation wrt camera as the rotations are in relation to the parent?
Thank you
EDIT: So probably what I need is get the rotation of the neck wrt camera in relation to the world.. some operation between the camera rotation transform and the matrix I got ?
Upvotes: 0
Views: 3021
Reputation: 1022
After researching I got there this way, might help someone with quaternion problems:
Extracted quaternion from the first frame rotation matrix and conjugated it to get the inverse direction rotation. This will work as the initial pose quaternion
initial_quaternion = new THREE.Quaternion();
initial_quaternion.setFromRotationMatrix(m);
initial_quaternion.conjugate();
For each frame extracted the quaternion and multiplied for the first quaternion, so I got the composed rotation of both quaternions (being the first inverted, that conjugation will give the difference from the initial rotation instead of the sum). As I wanted the rotation of neck bone in relation to head bone, this works great.
var quaternion = new THREE.Quaternion();
quaternion.setFromRotationMatrix(m);
quaternion.multiply(initial_quaternion);
After having that, as the head and neck movement have a composed rotation of 50% of the total movement, I wanted to give a 50% weight to the rotation. To that, interpolated a neutral pose quaternion by the resulted quaternion in 2 with t = 0.5
var basicQuaternion = new THREE.Quaternion();
quaternion.slerp(basicQuaternion,0.5);
Applied that quaternion to both neck and head bones (axis in the mesh are different from the ones as input) .
head.boneByName("Joint_Head").quaternion.set(
quaternion.y,
quaternion.z,
quaternion.x,
quaternion.w
);
head.boneByName("Joint_Neck").quaternion.set(
quaternion.y,
quaternion.z,
quaternion.x,
quaternion.w
);
Upvotes: 1