Please help ( MS3D Animations)

Started by
5 comments, last by AztecGames 19 years, 11 months ago
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
Advertisement
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
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.
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
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).
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]
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 WithEnd 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

This topic is closed to new replies.

Advertisement