Question about Armature and PoseBone

Scripting in Blender with Python, and working on the API

Moderators: jesterKing, stiv

Post Reply
amoghvc
Posts: 0
Joined: Tue Feb 21, 2006 7:49 am
Contact:

Question about Armature and PoseBone

Post by amoghvc »

I had posted this in the Interface and Tools section, but now it seems t me that it is the wrong place. So reposting it here.

I was doing some digging into Blender architecture for a exporter script and had a few questions.

What is the nature of data stored in the following matrices. In particular, is there any hierarchical relation between matrices :

1. Pose.PoseBone.localMatrix

2. Pose.PoseBone.poseMatrix

3. Armature.Bone.matrix

I am trying to export a mesh with armature and the problem I am facing is this . . .

The DirectX Mesh format (.X file) specifies a bone chain (i.e. a bone and it's linked children) with FrameTransformMatrices. The child bone matrix should be an offset from the parent matrix. So the final matrix for the child is obtained from multiplying the parent matrix with the child matrix. This is what I picked up from GameDev.net :

Code: Select all

1. Combined_MatrixBone = Local_MatrixBone * Combined_MatrixParent

2. Final_MatrixBone = Skin_OffsetBone * Combined_MatrixBone
This is how the data is written in the .X file . . .

Code: Select all

Frame ParentBone {
      FrameTransformMatrix {
            Local_MatrixBone
      }

      Frame ChildBone {
            FrameTransformMatrix {
                  Local_MatrixBone
            }
      }
}
So how do I calculate the Local_Matrixbone and the Skin_Offsetbone from the matrices available in Blander ? I got till this point where I have to do the following . . .

Code: Select all

1. Local_MatrixBone =  Combined_MatrixBone * (1/Combined_MatrixParent)

2. Skin_OffsetBone =  Final_MatrixBone * (1/Combined_MatrixBone)
But then no further; because I don't understand the nature of data in the matrices I have mentioned above and also no idea how to implement it in Blender Python.

I have gone through the API documentation available at the blender site that I downloaded but it was not clear enough for me.

Hoping desperately to get some help.

Dragon
Posts: 0
Joined: Wed Feb 22, 2006 2:04 am

Re: Question about Armature and PoseBone

Post by Dragon »

amoghvc wrote:1. Pose.PoseBone.localMatrix

2. Pose.PoseBone.poseMatrix

3. Armature.Bone.matrix
my answer is now based on my trial-and-error, and what i got working with my scripts ( hence i assume it has to correct to some extend ).

first the Armature.Bone matrix is a dictionary in fact having a matrix keyed to 'ARMATURESPACE'. this matrix transforms from the object origin to the base of the given bone ( in the reference position, hence undeformed ).

the poseMatrix matrix is the same as the ARMATURESPACE matrix but affected by the current deformation ( pose ).

the localMatrix contains only the rotation part of the poseMatrix ( but about this one i'm not sure, i don't use it ).

hence interesting are the ARMATURESPACE and the poseMatrix matrices.
But then no further; because I don't understand the nature of data in the matrices I have mentioned above and also no idea how to implement it in Blender Python.
maybe it helps, here is how i implemented it in my game engine exporter.

Code: Select all

						restMat = convertMatrix( poseBone.poseMatrix )
						if bone.hasParent():
							poseParent = pose.bones[ bone.parent.name ]
							parentMat = refMat * convertMatrix( poseParent.poseMatrix )
							parentMat.invert()
							restMat = restMat * parentMat
important to know is that i use only the data types of the blender math utils as for some reason the implemented methods break on me hence i use my own ones ( own and from the net, unfortunatly missing the author references to credit them ):

Code: Select all

def convertMatrix( matrix ):
	axisX = Vector( [ -matrix[0][0], matrix[0][2], -matrix[0][1], 0 ] )
	axisY = Vector( [ -matrix[1][0], matrix[1][2], -matrix[1][1], 0 ] )
	axisZ = Vector( [ -matrix[2][0], matrix[2][2], -matrix[2][1], 0 ] )
	pos = Vector( [ -matrix[3][0], matrix[3][2], -matrix[3][1], 1 ] )
	return Matrix( axisX, axisZ, axisY, pos )
you have to adept convertMatrix to convert from the blender coordinate system into the direct-x coordinate system. keep in mind that the blender uses the opengl system which has the matrix transposed compared to directx ( hence the translation part is in [3][0..3] not [0..3][3] )

i hope this helps you out a bit.

amoghvc
Posts: 0
Joined: Tue Feb 21, 2006 7:49 am
Contact:

Post by amoghvc »

Dragon, Thanks a lot for your input. I now understand what is happening in the code that I am looking at.

Code: Select all

 
        pose = armatureObject.getPose()
        bonePoseMatrix = Matrix (pose.bones[bone.name].poseMatrix)
        if bone.hasParent():
            parentPoseMatrix = Matrix (pose.bones[bone.parent.name].poseMatrix)
        else:
            parentPoseMatrix = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
        bonePoseMatrix = bonePoseMatrix * parentPoseMatrix.invert()
        self.writeFrameTransformMatrix (bonePoseMatrix)
This is what I came up with and it fixed my problem. Very similar to what your code is doing. And also this for the offset matrix:

Code: Select all

 
offsetMatrix = Matrix (pose.bones[bone.name].poseMatrix * ADJUST_MATRIX)
self.writeMatrix (offsetMatrix.invert())
Here I use ADJUST_MATRIX to fix the orientation of my mesh / object to work with DirectX. The answer comes from the way the matrices are organized in the Armature space.

Thanks a lot, I really appreciate your help.

Ben
Posts: 9
Joined: Wed Oct 23, 2002 8:32 pm

Post by Ben »

....with the adjust matrix you fix only the orientation of the bones
but not of the meshes.This way will get the armature rotated and the
mesh not.You must apply the adjust matrix to all matrices.
There is a "writeFrame(self,matx)" in the exporter.You can apply
there(adjust matrix*matx) in order to fix all object orientations.


Ben

amoghvc
Posts: 0
Joined: Tue Feb 21, 2006 7:49 am
Contact:

Post by amoghvc »

Ben,

I have taken care of that. What I gave you is only a small snippet of my code. All my meshes are adjusted in the right way for display. Actually what you have to do is apply the ADJUST_MATRIX only to the frame transform matrix of a mesh / OffetMatrix of a skinned mesh to fix the orientation.

Moreover, the bone matrix is finally applied to the mesh (all the vertices of the mesh affected by the bone, that is) to move the mesh and the armature / skeleton to character space / world space. So just applying the ADJUST_MATRIX to the OffsetMatix will do the trick because every vertex in the mesh is finally multiplied to the OffsetMatrix which is already adjusted, thus moving the whole mesh into proper orientation. Alos all the bones are multiplied with the offset matrix as well, so the bones get adjusted as well.

Thanks,

Amogh

Ben
Posts: 9
Joined: Wed Oct 23, 2002 8:32 pm

Post by Ben »

I'll try that......anyway I dont realize which is your problem
Do you want to flip the z axis? or to swap the yz axis...??
which the orientation you need to fix?

amoghvc
Posts: 0
Joined: Tue Feb 21, 2006 7:49 am
Contact:

Post by amoghvc »

Well, in one matrix both happen.

LetterRip
Posts: 0
Joined: Thu Mar 25, 2004 7:03 am

Post by LetterRip »

perhaps post your entire script so that the guess work of what you are doing can be removed?

LetterRip

amoghvc
Posts: 0
Joined: Tue Feb 21, 2006 7:49 am
Contact:

Post by amoghvc »

I will, eventually . . . But I first want to try and figure it out my self first. Just for the satisfaction and learning part of it. But if it is way beyond me then I surely will come to the big guns for help.

It is a bit big a script (approximately 1000 lines) to be posted here. So if there is an alternate way to put up the code (which I will eventually have to) please let me know.

I will release it for everybody's use once I have ironed out the creases.

LetterRip, I appreciate your trying to help. But I am a bit of a stickler for figuring out myself first and then going for help if I fail.

LetterRip
Posts: 0
Joined: Thu Mar 25, 2004 7:03 am

Post by LetterRip »

You can put it on the wiki which is what i usually do.

If it is under the GPL and generally useful I might add it to the bundled scripts,

LetterRip

Ben
Posts: 9
Joined: Wed Oct 23, 2002 8:32 pm

Post by Ben »

It's just in the bundled scripts.He's trying to modify the
DirectX Exporter........

Ben

LetterRip
Posts: 0
Joined: Thu Mar 25, 2004 7:03 am

Post by LetterRip »

whoops - hadn't noticed that in the early part of the post :)

amoghvc
Posts: 0
Joined: Tue Feb 21, 2006 7:49 am
Contact:

Post by amoghvc »

LetterRip, thanks for wiki idea. Will do that in a day or two.

Ben - I have found a few bugs in the bundled script that prevent certain types of meshes (Meshes with Sub-surfaces and armatures) from being exported correctly. Also a host of other stuff.

P.S. I hope to not just modify but improve upon that script :) .

LetterRip
Posts: 0
Joined: Thu Mar 25, 2004 7:03 am

Post by LetterRip »

since ben is the direct x exporter author :) I'm sure he will appreciate fixes, although not be to thrilled that there were a 'host of bugs' :)

LetterRip

amoghvc
Posts: 0
Joined: Tue Feb 21, 2006 7:49 am
Contact:

Post by amoghvc »

Well, I am a loss for words here. I didn't mean to be rude. How do I put it; in a professional manner ? :oops: :shock: :? . . .

Ben has written a great script. He has done a lot of ground work; some of which I am using as the basis for my new script. But there are some conditions coded in that script that are breaking the export of very simple scenes in blender (e.x. 3 cubes arranged in space to form steps with each cube given sub-surfaces). So I have had to question all of that code and do my own work from scratch.

I will post a more detailed list of my findings. I come in peace and wish only to help. :D

P.S. Not bugs per say - but a few conditions assumed in the script that break simple exports.

Post Reply