Sign in to follow this  
ajoling

[Cal3D] Matching bone rotation

Recommended Posts

Hi everyone, I've been trying for a few days to attach an object to the Cal3D bones. (More specific, the right hand). I thought things were going well. The translation was easy. But the rotation. Why could it be that hard. I've spent an enormous amount of time on it, and still it does not work. My code can be found here as well (below), it might be useful to other people. Cal3D documentation is very sparse, and alsost no information can be found on the net. Now, I hope someone can give advice how to fix the rotation. Cal3D has been used in so many commercial games, but there is no single piece of examples available made by other people. Strange. Can anyone please shed some light on how to fix the rotation issue? Many many thanks in advance!
int boneId = mesh->m_calModel->getSkeleton()->getCoreSkeleton()->getCoreBoneId("Bip01 R Hand");
	if (boneId > -1)
	{
		D3DXMATRIX matRot, matWorld ,matObjectTrans;
		D3DXMATRIX matBoneRotationMatrix, matBoneTranslation;
		D3DXMATRIX matCorrect;

		D3DXMatrixIdentity(&matWorld);
		D3DXMatrixIdentity(&matObjectTrans);
		D3DXMatrixIdentity(&matBoneTranslation);
		

		//Bip01 L Hand
		CalBone* bone = mesh->m_calModel->getSkeleton()->getBone(boneId);
		CalVector translationBoneSpace = bone->getTranslationAbsolute();

		//Translate the object to the bone position
		D3DXMatrixTranslation(&matBoneTranslation, translationBoneSpace.x,translationBoneSpace.y,translationBoneSpace.z);
		
		//Translate matrix to object position:
		D3DXMatrixTranslation(&matObjectTrans, vPos.x,vPos.y,vPos.z);

		//Apply rotation correction:
		D3DXMatrixRotationYawPitchRoll(&matCorrect, 0.0f,  D3DXToRadian(90.0f), 0.0f);
		D3DXMATRIX mat2;
		D3DXMatrixRotationYawPitchRoll(&mat2, 0.0f,  0.0f, D3DXToRadian(90.0f));

		matWorld = matBoneRotationMatrix * matCorrect * mat2 *  matBoneTranslation * matObjectTrans; //  * matModelRotation * matObjectTrans;

Next to above code, I have tried iterating through all the parents too, with both relative and absolute coordinates. No luck. I have tried the TransFormMatrix(), no luck. Hence I'm messing around with correction matrices, playing with every single x,yz, z,y,x, y,x,z coordinate version, and I have tried every single angle of my 3D mesh. I amm totally clueless. I'm out of suggestions. :-(

Share this post


Link to post
Share on other sites
I don't know much about cal3d, and I didn't study your code too hard, but general advice when you're having rotation trouble includes the following:

1. Make sure you're translating and rotating in the right order. It may be exactly opposite of what you think it is.
2. Make sure you're rotating about the right axes in the right order.

Share this post


Link to post
Share on other sites
Hi!

Thanks for your reply. Unfortunately, I think I have tried every single combination possible. I guess I could try to seperate the Quaternion values somehow and multiply these in all kinds of diferent orders. I'm beyond clueless, and thinking of ditching the problem for a few weeks. Unfortunately, this is something which is quite a requirement in my game.

Share this post


Link to post
Share on other sites
I don't know Cal3D, but if you want to attach an object to another object in a hierarchy you have to use forward kinematics.
This is very easy. What you need to know is the following information:

1.) The world/absolute matrix of the Bip01 R Hand node.
2.) The local/relative matrix of the attachment (say a gun).

Now to calculate the world/absolute matrix of the attachment, which you use for rendering, you do:


Matrix finalGunMatrix = bip01RHandMatrix * localAttachmentMatrix;


It is also possible that you have to multiply in the opposite order.

To calculate the local space transform from a translation and rotation for the gun, you do something like:


Matrix localAttachmentMatrix = RotationMatrix(rotation) * TranslationMatrix(translation);


You can also just build a rotation matrix and set the translation row or column directly after you built the rotation matrix.

Hope this helps.

Cheers,
- John

Share this post


Link to post
Share on other sites
We use Cal3d for Ancient Galaxy, and we had some fun with this as well.

Don't have my code handy right now, but I believe the trick is to get the absolute rotation, which goes from the root node directly to the local bone space. Then you first apply your dude's main rotation, then this absolute rotation to get into local bone space. Then you can place the object in local space, then get the inverse of the combined matrix to get back to world space.

We used quaternions for the rotations, so I can't comment on doing it with Euler angles.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this