How to Compute a Armature's Rest-Position

Scripting in Blender with Python, and working on the API

Moderators: jesterKing, stiv

Post Reply
Matt3D
Posts: 0
Joined: Thu Apr 21, 2005 11:14 pm

How to Compute a Armature's Rest-Position

Post by Matt3D » Thu Apr 21, 2005 11:37 pm

Hi,

Can anybody please tell me how it is possible to compute the Rest-Position of an Armature? This is the the position & rotation that the Armature was in when it was first Parented to the Mesh.

Ideally, I'd like to have a routine similar to getRestMatrix() available in the Bone class that instead returns the matrix of the Armature.

Thanks in advance,
--Matthew

reimpell
Posts: 0
Joined: Wed Oct 01, 2003 5:09 pm

Re: How to Compute a Armature's Rest-Position

Post by reimpell » Fri Apr 22, 2005 11:57 am

Matt3D wrote:Can anybody please tell me how it is possible to compute the Rest-Position of an Armature? This is the the position & rotation that the Armature was in when it was first Parented to the Mesh.
I do this using the worldspace object matrices of the mesh (M) and armature (A). In the "left-multiplication" convention, the initial armature transformation relative to the mesh object's coordinate system is then A*M^(-1) as, of course, A*M^(-1)*M = A. See the Ogre3D export script for a working example.

Matt3D
Posts: 0
Joined: Thu Apr 21, 2005 11:14 pm

Computing Armature & Bone Rest Matrices

Post by Matt3D » Sat Apr 23, 2005 2:18 am

> I do this using the worldspace object matrices of the mesh (M) and
> armature (A). In the "left-multiplication" convention, the initial armature
> transformation relative to the mesh object's coordinate system is then
> A*M^(-1)

Great! I implemented this and sure enough, the correct Armature rotation is now computed correctly. Thanks for your help reimpell.

I also would like to be able tp compute a Bone's location is the local coordinate system of the Mesh.
If I substitute a Bone's global position Matrix for the Mesh Matrixin the equation above, will thatresult equal a Bones position and in the Mesh coordinate system?

One last question. Since the Bone rotation variable named "quat" equals the Rotation applied to the Bones rest-position (I think) can I multiply the "quat" rotation (converted to a matrix) by the "rest-matrix" to compute the Bones current local rotation?

Thanks for your help. :P
Best Regards,
--Matt

reimpell
Posts: 0
Joined: Wed Oct 01, 2003 5:09 pm

Re: Computing Armature & Bone Rest Matrices

Post by reimpell » Sat Apr 23, 2005 7:16 pm

Matt3D wrote:I also would like to be able tp compute a Bone's location is the local coordinate system of the Mesh.
If B is the rest matrix of the current bone and P is the transformation due to its parent bones, then the position of the current bone in the mesh's coordinate system is (0,0,0)*B*P*A*M^(-1).
Matt3D wrote:One last question. Since the Bone rotation variable named "quat" equals the Rotation applied to the Bones rest-position (I think) can I multiply the "quat" rotation (converted to a matrix) by the "rest-matrix" to compute the Bones current local rotation?
Bone.getRestMatrix('bonespace').toQuat() is the current rotation for child bones, while (Bone.getRestMatrix('bonespace')*A*M^(-1)).toQuat() is the current rotation for root bones in respect of the mesh's coordinate system.

Matt3D
Posts: 0
Joined: Thu Apr 21, 2005 11:14 pm

Bones Orientation relative to a Mesh

Post by Matt3D » Sat Apr 23, 2005 10:33 pm

> If B is the rest matrix of the current bone and P is the transformation
> due to its parent bones, then the position of the current bone in the
> mesh's coordinate system is (0,0,0)*B*P*A*M^(-1).

Thank you very much for the information, but I'm still a bit confused. How do you compute (0, 0, 0) * (Matrix) as you described ?

And can you please clarify what "P = the transformation
due to its parent bones" is equivalent to?

Thanks in advance,
--Matthew

reimpell
Posts: 0
Joined: Wed Oct 01, 2003 5:09 pm

Re: Bones Orientation relative to a Mesh

Post by reimpell » Sun Apr 24, 2005 1:28 am

Matt3D wrote:Thank you very much for the information, but I'm still a bit confused. How do you compute (0, 0, 0) * (Matrix) as you described ?

And can you please clarify what "P = the transformation
due to its parent bones" is equivalent to?
Of course, it's the vector (0,0,0,1), as we are in homogeneous coordinates. P ist just the parents rest matrices multiplied together (i.e. (parent transformation)*(parent's parent transformation)*...).

Matt3D
Posts: 0
Joined: Thu Apr 21, 2005 11:14 pm

Pose Bone Rotations

Post by Matt3D » Sun Apr 24, 2005 9:28 pm

> Bone.getRestMatrix('bonespace').toQuat() is the current
> rotation for child bones, while
> (Bone.getRestMatrix('bonespace')*A*M^(-1)).toQuat() is the
> current rotation for root bones in respect of the mesh's
> coordinate system.

The current rotation I'm trying to compute is the rotation of the currently posed armature bones.
These equations above don't appear to apply the posed bone rotation.

Can't I just multiply bone.quat.toMatrix() to the equation above like this to compute the Posed bone matrix:

if (Bone.getParent() != None):
boneRestMatrix = Bone.getRestMatrix('bonespace')
else:
armatureMatrix = sarmatureObject.getMatrix()

inverseMeshMatrix = meshObject.getMatrix()
inverseMeshMatrix.invert()
inverseMeshMatrix.resize4x4()

boneRestMatrix = Bone.getRestMatrix('bonespace') * armatureMatrix * inverseMeshMatrix)

posedBoneMatrix = bone.quat.toMatrix() * boneRestMatrix

> If B is the rest matrix of the current bone and P is the
> transformation due to its parent bones, then the position of
> the current bone in the mesh's coordinate system is
> (0,0,0)*B*P*A*M^(-1).

Your help is greatly appreciated! FYI I implemented the equations you posted to compute the bone location
in the Mesh's local coordinate system. It now works correctly. Thanks again reimpell. I assumed that
in the above equation you meant:
A = the Armature matrix in global space
*M^(-1) = inverse mesh matrix in global space
B = bone rest matrix in local bone space
P = combine parent bones rest matrix in local bone space

Is that correct?

Best Regards,
--Matthew

reimpell
Posts: 0
Joined: Wed Oct 01, 2003 5:09 pm

Re: Pose Bone Rotations

Post by reimpell » Mon Apr 25, 2005 3:31 am

Matt3D wrote:> Bone.getRestMatrix('bonespace').toQuat() is the current
> rotation for child bones, while
> (Bone.getRestMatrix('bonespace')*A*M^(-1)).toQuat() is the
> current rotation for root bones in respect of the mesh's
> coordinate system.

The current rotation I'm trying to compute is the rotation of the currently posed armature bones.
These equations above don't appear to apply the posed bone rotation.
Blender's ordering of transformations is dR*dS*dT in the bone's coordinate system, where dR is the current rotation, dS is the current scale and dT is the current translation. E.g. for root bones, the overall rotation in respect of the mesh's coordinate system is (dR*dS*dT*Bone.getRestMatrix('bonespace')*A*M^(-1)).toQuat().

dandeloreon1984
Posts: 0
Joined: Wed Jan 21, 2004 11:12 pm
Contact:

Post by dandeloreon1984 » Mon Apr 25, 2005 5:54 am

i actually saw something about this before... a known bugs with the bones... here is the list i've noted:
  1. IK based bones don't show head position.
  2. all bones don't return quats -- always [1,0,0,0] or somethin close.
  3. position always returns 0,0,0
  4. and various other things.
the best place to see what i'm talkin about is this bug report.

reimpell
Posts: 0
Joined: Wed Oct 01, 2003 5:09 pm

Post by reimpell » Mon Apr 25, 2005 9:22 pm

dandeloreon1984 wrote:i actually saw something about this before... a known bugs with the bones...
Fortunately, you can still export animations. See the Ogre3D export script for possible workarounds, resp. a fully functional animation export.

z3r0_d
Posts: 289
Joined: Wed Oct 16, 2002 2:38 am
Contact:

Post by z3r0_d » Tue Apr 26, 2005 1:56 am

The documentation seems very incomplete, but here is what I've gathered

reimpell: if you could point out any problems with what I say... that'd be great

so a bone object has the following properties:

Code: Select all

name
parent # list containing single parent bone or None
children # all children not just immediate ones
boneclass # SKINNABLE and such
ik # ik button in edit buttons and 0 if no parent
weight # people use this?
head # position of head
tail # position of tail

# properties modified by pose:
quat # local rotation when posed
size # size [list on each axis] relative from initial
loc # location of posed bone [head]
roll # useless?
I don't understand roll

loc returns [0.0,0.0,0.0] when IK is set [head of current bone can't be moved relative to tail of parent, they are attached]

constraints modify rotation and location ... uhh, after these things are calculated from the animation? so we can't export an animation using ik constraints properly because the rotations/locations are simply not made accessable

rotations are relative to the parent bone

locations are relative to the parent's tail

is the tranformation for a child bone rotate [around head] then translate [along axes specified by rotation of parent]?

so, scaling along one axis of one bone warps that one bone

to children bones it does what? in the interface it seems to do odd things [consistent to objects in blender] where the scaling is applied after the rotation of the child bones, so a rotation of some amount of child bones results in possibly less apparent of rotation [because you are squashing the results]... I don't know this is weird. I don't know exactly how to deal with it [and I'm fairly certain the ogre export did not, but I haven't checked. bones in ogre when scaled dont' modify their children, so how would you specify the irregular axis of scaling on child bones? [if that is how things work] ... I assume you don't deal with scaling, but I haven't tested it]

umm, at the least whomever did the api for armatures in blender should be asked to allow access to baking of the animations.

reimpell
Posts: 0
Joined: Wed Oct 01, 2003 5:09 pm

Post by reimpell » Tue Apr 26, 2005 12:31 pm

z3r0_d wrote:weight # people use this?
Yes.
z3r0_d wrote:I don't understand roll
Head and tail define the position of the bone's y-axis. Roll is the additional rotation around this axis in respect of the parent's coordinate system.
z3r0_d wrote:loc returns [0.0,0.0,0.0] when IK is set [head of current bone can't be moved relative to tail of parent, they are attached]
Also, this is the correct behaviour, so it's not a bug as claimed above.
z3r0_d wrote:in the interface it seems to do odd things [consistent to objects in blender] where the scaling is applied after the rotation of the child bones, so a rotation of some amount of child bones results in possibly less apparent of rotation [because you are squashing the results]... I don't know this is weird.
As nonuniform scaling does not commute with rotations, there is no way around it. Again, this is the correct behaviour.

dandeloreon1984
Posts: 0
Joined: Wed Jan 21, 2004 11:12 pm
Contact:

Post by dandeloreon1984 » Thu Apr 28, 2005 5:17 am

i'm not sure about that to begin with... but i do know that for us tryin to start scripts to begin with it's very hard to get quats for the bones based on various things... maybe a few new handles would help fix this, like getikquat or even some other things like that... it's just fairly odd... and also, ik doesn't work with multiple ik connections to one root bone. i know this is yet another sign of how blender's whole python api that is available is needin updates.

Post Reply