Skip to main content
GameDev.net gamedev.net
🔒 Locked

Please help ( MS3D Animations)

Started by AztecGames Apr 13, 2004 at 11:02 PM 5 replies 1k views
Original Post
AztecGames
AztecGames
Can someone please help me with ms3d ascii bone animations? I have been stuck for quite a few days now. I have gone through the ms3d viewer code many many times and also the realsoon now tutorial here at gamedev with no luck. Using what I read in the two code references, I believe I am setting up the final/relative/absolute matrices correctly, but when I render the animations using this I get wild goofy movements of the vertexes to be animated. I tried my own medthod simply calculating the final matrix for each bone and then multiplying it with the parent''s final matrix, not using any of the relative or absolute matrices and this gives a close but still wrong display of the animation. I am about to rip out my hair on this one, please help!!! I can post some code if needed. Aztec
Aztec
AztecGames
AztecGames
Mabey I can better state my question.
What I am wondering is, is there somthing different that must be done to get this correctly working in directX than in opengl?

I noticed that using an inverse matrix caused the vertices to rotate the opposite way, is there somthing else I may be missing?

Aztec
Aztec
nlo
nlo
u know about DX is Left-hand coord but OGL is Right-hand coord ?

btw, try not using D3DX math library, they may give u wrong result, i''ve experience this problem b4, so at last i use MsViewer''s quaternion & matrix rotation code... werid problem.
AztecGames
AztecGames
Yeah, I know about the left and right handed coords.

I will try not using the dx maths.

Through some more close observation of the animations in action, it appears that the main problem lies in the rotation of a given joint causing the mesh to stretch out.
It will move the correct way at the correct time, it just stretches.

btw, I am using right now D3DXVec3TransFormCoord with the final matrix, what should I use instead?


Aztec
Aztec
nlo
nlo
sorry for not so specific, actually i''m not using D3DX math for "SetupBones" & "AdvanceFrame" functions, i still use D3DX math while drawing the model (as your "D3DXVec3TransFormCoord with the final matrix" part).
RenderTarget
RenderTarget
There''s nothing wrong with the D3DX math library. Use it definitely, as it''s highly optimized.

I like pie.
[sub]My spoon is too big.[/sub]
AztecGames
AztecGames
Sorry for being away so long, somthing came up and I was unable to be around my computer.

Well anyway, I did get a little further before I had to leave.
I had tried using the functions from the ms3d viewer code and came to limited results. I could replicate them the same using d3dx math functions so I went that route.

As far as using matrices for transforms, this is I think where I am getting a little confused.

Here is what I am doing now.

First I load up the model, reversing the positions for the bones and the bone keyframes.

After the info is all loaded I make a call to this sub:

Private Sub Setup_Bones(ByRef p_Mesh As MS3DASCII_FILE)
Dim i As Integer, c As Integer

With p_Mesh
ReDim tPos(.NumJoints - 1)
For i = 0 To .NumJoints - 1
''---Find Parent bone---
Dim nParentBone As Integer
For c = 0 To .NumJoints - 1
If .JointOBJ(c).cName = .JointOBJ(i).cParent Then nParentBone = c: Exit For
If c = .NumJoints - 1 Then nParentBone = -1
Next c
''----------------------
D3DXMatrixIdentity .JointOBJ(i).m_Absolute
D3DXMatrixIdentity .JointOBJ(i).m_Relative
D3DXMatrixIdentity .JointOBJ(i).m_Final
If Not nParentBone = -1 Then ''## Not the parent bone ##
Dim tMat As D3DMATRIX
Dim vPos As D3DVECTOR

''-Make tMat an identity matrix
D3DXMatrixIdentity tMat

''-Translate tMat by the parent bone''s position
D3DXMatrixIdentity matTemp
D3DXMatrixTranslation matTemp, .JointOBJ(nParentBone).PosX, .JointOBJ(nParentBone).PosY, .JointOBJ(nParentBone).PosZ
D3DXMatrixMultiply tMat, matTemp, tMat

''-Rotate tMat by the parent bone''s rotation
D3DXMatrixIdentity matTemp
D3DXMatrixRotationYawPitchRoll matTemp, .JointOBJ(nParentBone).RotY, .JointOBJ(nParentBone).RotX, .JointOBJ(nParentBone).RotZ
D3DXMatrixMultiply tMat, matTemp, tMat

''.JointOBJ(i).m_Relative = tMat ''-Temp

''-Add parent bone''s rotation to current bone''s rotation
.JointOBJ(i).RotX = .JointOBJ(i).RotX + .JointOBJ(nParentBone).RotX
.JointOBJ(i).RotY = .JointOBJ(i).RotY + .JointOBJ(nParentBone).RotY
.JointOBJ(i).RotZ = .JointOBJ(i).RotZ + .JointOBJ(nParentBone).RotZ

''-Set vPos to the current bone''s corrected position
vPos = p_Helper.Vector3D(.JointOBJ(i).PosX, .JointOBJ(i).PosY, .JointOBJ(i).PosZ)

''-Transform vPos by the matrix tMat
D3DXVec3TransformCoord vPos, vPos, tMat

''-Make the current bone''s position the transformed vPos values
.JointOBJ(i).PosX = vPos.x
.JointOBJ(i).PosY = vPos.y
.JointOBJ(i).PosZ = vPos.z
Else ''## The parent bone ##
''-Make tMat an identity matrix
D3DXMatrixIdentity tMat

''-Translate tMat by the current bone''s position
D3DXMatrixIdentity matTemp
D3DXMatrixTranslation matTemp, .JointOBJ(i).PosX, .JointOBJ(i).PosY, .JointOBJ(i).PosZ
D3DXMatrixMultiply tMat, matTemp, tMat

''-Rotate tMat by the current bone''s rotation
D3DXMatrixIdentity matTemp
D3DXMatrixRotationYawPitchRoll matTemp, .JointOBJ(i).RotY, .JointOBJ(i).RotX, .JointOBJ(i).RotZ
D3DXMatrixMultiply tMat, matTemp, tMat

''.JointOBJ(i).m_Relative = tMat ''Temp
End If
Next i
End With
End Sub


After that, in a call to animate_mesh I then get the current position and rotation of each bone linearly for now, and apply transformations as such:

''###############
''--Multiply by parent
''If Not .AnimOBJ(i).cParent = "" Then
'' For c = 0 To .NumJoints - 1
'' If .AnimOBJ(c).cName = .AnimOBJ(i).cParent Then Exit For
'' Next c
'' D3DXMatrixIdentity .AnimOBJ(i).m_Final
'' D3DXMatrixMultiply .AnimOBJ(i).m_Final, .AnimOBJ(i).m_Final, .AnimOBJ(c).m_Final
''Else
'' D3DXMatrixIdentity .AnimOBJ(i).m_Final
''End If
D3DXMatrixIdentity .AnimOBJ(i).m_Final
''--Initial transform
D3DXMatrixIdentity matTemp
D3DXMatrixTranslation matTemp, .AnimOBJ(i).PosX, .AnimOBJ(i).PosY, .AnimOBJ(i).PosZ
D3DXMatrixMultiply .AnimOBJ(i).m_Final, .AnimOBJ(i).m_Final, matTemp
D3DXMatrixIdentity matTemp
D3DXMatrixRotationYawPitchRoll matTemp, .AnimOBJ(i).RotY, .AnimOBJ(i).RotX, .AnimOBJ(i).RotZ
D3DXMatrixMultiply .AnimOBJ(i).m_Final, .AnimOBJ(i).m_Final, matTemp

''--Transform keyframes
D3DXMatrixIdentity matTemp
D3DXMatrixTranslation matTemp, PosVec.x, PosVec.y, PosVec.z
D3DXMatrixMultiply .AnimOBJ(i).m_Final, .AnimOBJ(i).m_Final, matTemp
D3DXMatrixIdentity matTemp
D3DXMatrixRotationYawPitchRoll matTemp, RotVec.y, RotVec.x, RotVec.z
D3DXMatrixMultiply .AnimOBJ(i).m_Final, .AnimOBJ(i).m_Final, matTemp

''--Inverse
D3DXMatrixIdentity matTemp
D3DXMatrixTranslation matTemp, -.AnimOBJ(i).PosX, -.AnimOBJ(i).PosY, -.AnimOBJ(i).PosZ
D3DXMatrixMultiply .AnimOBJ(i).m_Final, .AnimOBJ(i).m_Final, matTemp

tPos(i) = p_Helper.Vector3D(-.AnimOBJ(i).PosX + .Pos.x, -.AnimOBJ(i).PosY + .Pos.y, -.AnimOBJ(i).PosZ + .Pos.z)
D3DXVec3TransformCoord tPos(i), tPos(i), .AnimOBJ(i).m_Final
tPos(i) = p_Helper.Vector3D_Project(tPos(i))
''###############
Next i

''--Update vertexes
Dim transVEC As D3DVECTOR
.GeomUpdate = True
For c = 0 To .lNumVerts - 1
If Not .BoneIndex(c) = -1 Then
transVEC = p_Helper.Vector3D(TransVert(c).x, TransVert(c).y, TransVert(c).z)
D3DXVec3TransformCoord transVEC, transVEC, .AnimOBJ(.BoneIndex(c)).m_Final
TransVert(c).x = transVEC.x
TransVert(c).y = transVEC.y
TransVert(c).z = transVEC.z
End If
Next c
''----------------------------------------------


I should note that I stored a copy of the origional models vertex positions untransformed and set them to this state at the start of the animate function.

This code will work correctly if all bones extend from one parent and are not parents themselves. I just seem to not be able to transform correctly in order(down the line).
I can see some places where I am going wrong, just not how to make them right.


Aztec
Aztec

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.