# Converting MD5Mesh/Anim From Z-Up to Y-Up

This topic is 4377 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have a basic MD5 loader and cant figure out how to convert the mesh to y-up coordinate system. What I think should work, but doesnt, is converting the joint positions & weight positions to y-up (seems to get the bones in the proper space). But when I compute the vertex positions the rotations are completely screwed. I am still trying to wrap my ahead around how quaternions work - do I need to convert them as well? I tried converting the x,y,z part to y-up, but that didnt work. Any ideas?

##### Share on other sites
I had the same problem. I have not been able to get the conversion done at load time. My solution is to do the conversion at animation time (i.e. convert while doing the skinning)

##### Share on other sites
Hi,

At load time swap y and z of your vertex positions.
For your quaternions swap y and z, and invert w.

So a quaternion goes like:

newQuat = Quaternion(old.x, old.z, old.y, -old.w);

For your matrices, swap the second and third columns and rows.
So row[1] becomes row[2] and row[2] becomes row[1].
After this do the same with the 2nd and 3rd column in the matrices (if there are any matrices stored at all).

Then at runtime you need no further changes and all will be in your y-up coordinate system.

What I do in my software is having some coordinate system class, in which you define what coordinate system your engine runs in.
Then at load time it converts automatically all vectors/matrices/quaternions into the coordinate system that has been setup.

Cheers,
- John

##### Share on other sites
What I did (which was back in the DOOM 3 alpha days) was that I created a quaternion 'Q.Build(vec3(1,0,0), -PI / 2)' that rotates from their coordinate system to mine (y+).

In the .md5mesh file joint transformations are stored in world space IIRC. So for each joint that is loaded, simply rotate it into our coordinate system:
  Joint.Position = Q * PositionReadFromMD5Mesh  Joint.Rotation = Q * QuaternionReadFromMD5Mesh

In the .md5anim file joints are relative to each other so we only need to rotate the root joint:
  if (Joint.ParentIndex == -1)    Joint.Position = Q * PositionReadFromMD5Anim    Joint.Rotation = Q * QuaternionReadFromMD5Anim  else    Joint.Position = PositionReadFromMD5Anim    Joint.Rotation = QuaternionReadFromMD5Anim

But now, animations will look wrong since they animate quaternion and position componenets, which have changed. I fixed this by looping through the frame data
and do something I can't remember... :)

for (int i = 0; i < pAnimation->m_AnimatedJoints.GetLength(); i++){	// root	if (pAnimation->m_AnimatedJoints.m_pJoint->m_ParentIndex == -1)	{		uint8 &n = pAnimation->m_AnimatedJoints.m_AnimatedComponents;		for (int j = 0; j < pAnimation->GetNumFrames(); j++)		{			fp32 *pFrameData = &pAnimation->m_Frames[j].m_Data[ pAnimation->m_AnimatedJoints.m_FrameDataIndex ];			if (n & 1)				pFrameData++;			if (n & 2)				*pFrameData = -*pFrameData++;			if (n & 4)				pFrameData++;			if (n & 8)				pFrameData++;			if (n & 16)				pFrameData++;			if (n & 32)				pFrameData++;		}		// Swap		int bit0 = n & 2;		int bit1 = n & 4;		n &= ~6;		n |= bit0 << 1;		n |= bit1 >> 1;	}}

Good luck!

• 10
• 17
• 9
• 14
• 41