I'm developing a Kinect Project using C# and XNA 4.0. Now facing a problem that I couldn't solve. When the player turn around himself, the avatar doesn't turn, but its arms and legs are trying to turn. This is causing a bad view, so I want to block arms and legs rotation movement. Although I tried some ways, it didn't work. For example the right arm movement:
else if (bone.EndJoint == JointType.ElbowRight || bone.EndJoint == JointType.WristRight)
{
Matrix tempMat = KinectHelper.Matrix4ToXNAMatrix(bone.HierarchicalRotation.Matrix);
if (bone.EndJoint == JointType.ElbowRight)
{
// Add a small adjustment rotation to correct for the avatar skeleton shoulder/upper arm bones.
// The dude should now be able to have arms correctly down at his sides when avateering
Matrix adjustment = Matrix.CreateRotationZ(MathHelper.ToRadians(15)); // 15 degree rotation around the local Kinect z axis for the upper arm bone.
tempMat *= adjustment;
}
// Kinect = +Y along arm, +X up, +Z forward in body coordinate system
// Avatar = +X along arm, +Y back, +Z down
Quaternion kinectRotation = KinectHelper.DecomposeMatRot(tempMat); // XYZ
Quaternion avatarRotation = new Quaternion(kinectRotation.Y, -kinectRotation.Z, -kinectRotation.X, kinectRotation.W); // transform from Kinect to avatar coordinate system
tempMat = Matrix.CreateFromQuaternion(avatarRotation);
this.ReplaceBoneMatrix(bone.EndJoint, tempMat, false, ref boneTransforms);
}
Any way to block the rotations?
I've managed to lock the hip center with:
if (bone.StartJoint == JointType.HipCenter && bone.EndJoint == JointType.HipCenter)
{
// Unless in seated mode, the hip center is special - it is the root of the NuiSkeleton and describes the skeleton orientation in the world
// (camera) coordinate system. All other bones/joint orientations in the hierarchy have hip center as one of their parents.
// However, if in seated mode, the shoulder center then holds the skeleton orientation in the world (camera) coordinate system.
bindRoot.Translation = Vector3.Zero;
Matrix invBindRoot = Matrix.Invert(bindRoot);
//Matrix hipOrientation = KinectHelper.Matrix4ToXNAMatrix(bone.HierarchicalRotation.Matrix);
// Here we create a rotation matrix for the hips from the inverse of the bind pose
// for the pelvis rotation and the inverse of the bind pose for the root node (0) in the Dude model.
// This multiplication effectively removes the initial 90 degree rotations set in the first two model nodes.
Matrix pelvis = boneTransforms[1];
pelvis.Translation = Vector3.Zero; // Ensure pure rotation as we explicitly set world translation from the Kinect camera below.
Matrix invPelvis = Matrix.Invert(pelvis);
//Matrix combined = (invBindRoot * hipOrientation) * invPelvis;
Matrix combined = invBindRoot * invPelvis;
Matrix adjustment = Matrix.CreateRotationZ(MathHelper.ToRadians(180));
combined *= adjustment;
this.ReplaceBoneMatrix(JointType.HipCenter, combined, true, ref boneTransforms);