bone matrices - bind pose <-> current frame

Scripting in Blender with Python, and working on the API

Moderators: jesterKing, stiv

ascotan
Posts: 0
Joined: Thu May 29, 2003 10:32 pm
Location: Maryland, U.S.

Post by ascotan »

The poseMatrix property takes constraints into account i believe. The localMatrix property is only a (delta) transformation matrix from rest.

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

Post by LetterRip »

ascotan,

is that in the documentation? If not could you add it?

Thanks,

LetterRip

kakapo
Posts: 0
Joined: Sat Sep 04, 2004 2:32 pm

Post by kakapo »

and what's wrong with my example?

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

Post by Ben »

-The poseMatrix has some strange behaviours.In the documentation
is written it's not settable.Anyway in an example like this:

Code: Select all

pose_mat = pose_bone.poseMatrix
pose_mat.invert()
-the bone is transformed in the 3d view.This happens more frequently
if no 3d view is on the screen.

Ben

ascotan
Posts: 0
Joined: Thu May 29, 2003 10:32 pm
Location: Maryland, U.S.

Post by ascotan »

your not supposed to write to the pose matrix because the posematrix is calculated.

It is calculated from the localMatrix (which is a (delta) tranformation from rest pose), the armature_space bone matrix and any currently applied constraints.

I'll def have to check into any weird behaviors of pose matrix.

The way to set animation using the pose module is by setting the change in loc/rot/size into localMatrix or into loc/rot/size. You would then key this into an action to save it.

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

Post by LetterRip »

ascotan,

I think Ben means that because the documentation states that the matrix is not setable, one might think it would be 'unwritable', however things like inverting a matrix that that the matrix has been assigned to inverts the matrix.

This might be worth documenting a bit better ie that the user should do

pose_mat = Matrix(pose_bone.poseMatrix)
pose_mat.invert()

to avoid inverting the matrix. (This behavior is consistent with other matrix usage in Blender but the not setable makes it a bit counter intuitive).

LetterRip

kakapo
Posts: 0
Joined: Sat Sep 04, 2004 2:32 pm

Post by kakapo »

i still don't know if querying the posematrix of different animation frames like in my example is supposed to work? :) or if i would have to do in some other way...

khughes
Posts: 0
Joined: Sat Jan 08, 2005 9:30 pm
Location: Northern California

Post by khughes »

Maybe there needs to be a read-only setting for some wrapped objects? I can see why you might wanted a copy of the wrapped matrix, assuming that as the pose changes you could get the updated matrix. A copy of the matrix obviously wouldn't do this.

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

Post by Ben »

Yes, its right but a copy of the matrix has other problems,it gives
always the same values of the poseMatrix, so we loose the animation.Here is a little example which shows the problem:
http://xoomer.virgilio.it/glabro1/Pose_bug.blend

1 - Open the blend and run the script Text1 with the multiple window screen
(as it is).Note the matrix values in the console,change for every frame.
This way everything is OK.

2 - Now try to make the Text window fullscreen and run the script again.
Check the console, the matrix values are the same for all the frames.

3 -If instead of the 3d view window(in multiple window screen) put another
one(not important which) the matrix is always the same for evry frame
of animation.
So, if no 3d view is active on the screen the matrix doesnt update.
In the same way appears the problem with the direct poseMatrix.The deformations inverting the matrix, occurs in the case 2 and 3, not in the first case.
This is important for an exporter,bacause if a user open the export
menu and the 3d view window is covered by the fileselector no animation
will be exported(or not corect data if the direct poseMatrix is used
Ben

jsgreenawalt
Posts: 0
Joined: Sun Jan 08, 2006 6:27 am

Post by jsgreenawalt »

I ran up against the same problem that Ben was having. I was convinced that the poseMatrix returned was incorrect until I got the idea to try it with a 3d view visible. It is a valid usability concern, especially for exporters with a
GUI. I have yet to find a way to control which pane the script GUI will open in through the API (when launched from File->Export->someexporter). So it's always a possibility that the exporter will cover the 3d view and the user will think animation export is broken.

an-toni
Posts: 0
Joined: Wed Mar 17, 2004 5:20 pm

Post by an-toni »

thank you a lot for this crucial info. dealing with the different application contexts, which have different data in memory, is indeed a major challence in apifying this tricky beast.

~Toni

kakapo
Posts: 0
Joined: Sat Sep 04, 2004 2:32 pm

Post by kakapo »

i managed to get different posematrices now for each animation frame. i did a stupid mistake with passing around references instead of copies of the matrix. :P



i would need these two matrices for my exporter:

- a bone's world space bind pose matrix
- a bone's world space animation frame matrix

i think i know how to calculate everything else i need from these two...

Code: Select all

armature = Armature.Get("Armature")
pose = Object.Get("Armature").getPose()

bone = armature.bones["leg1.R"]
posebone = pose.bones["leg1.R"]

armaturematrix = Matrix(Object.Get("Armature").matrixWorld)

ws_bindposematrix = Matrix(bone.matrix["ARMATURESPACE"]) * armaturematrix
ws_animationframematrix = Matrix(posebone.poseMatrix) * armaturematrix
is this correct? i am a bit confused about what the posematrix really is...

ascotan
Posts: 0
Joined: Thu May 29, 2003 10:32 pm
Location: Maryland, U.S.

Post by ascotan »

Guys sorry I haven't been too responsive here. Lately I've been swamped with RL work and haven't had a breather yet.

TY so much for taking interest in this module and the comments/bugs that have been posted. This really does help (me at least).
however things like inverting a matrix that that the matrix has been assigned to inverts the matrix.
<EEK> This was not intended and I'm sure this has to do with Py_WRAP.
pose_mat = Matrix(pose_bone.poseMatrix)
pose_mat.invert()
We've been running into this all over the place - and it's a bit of a hidden gotya! that script writers have seen.

Here's the deal on this FYI:
A while back we had trouble because the vector information returned from objects when written to did not update the transformation on the object.
I don't remember the exact problem now, but when you did:
"Mesh.vert[4].loc = 1,2,3" or something this would write a NEW vector object being returned by 'loc' and the transformation would NOT occur. Many ppl complained about this.
As a resolution stephen added a method called vector_proxy which would allow you to write directly to the data rather than to a new python object. I took that method and made it into something that affects ALL the math classes. When data returned needs wrapping and direct access we use PY_WRAP and when the data needs a new python object we use PY_NEW.
An unforseen consequence is having to write the above code when you DON'T want to directly modify data.

objet.matrix.invert() <eek> ppl where wondering y they had to re-invert the matrix at somepoint.

I think maybe for the refactoring we need to get rid of this strange and potentially harmful behavior. I think I'll repeat this on the ML.

So, if no 3d view is active on the screen the matrix doesnt update.
Blender updates some calculations on objects through it's windowing event queue - apparently this is one of them. So if no redraw is called for then no object update i guess :(. We have to figure out a way around this.

I think this is also a problem for object.matrix and one point. I think the solution might be to call something like where_is_pose in the method to force the calculations to update.
I have yet to find a way to control which pane the script GUI will open in through the API
Well the GUI will always come up in the scripts window. I _believe_ the scripts window is programmed to appear in the same window area as the text area from which the script was executed.
i did a stupid mistake
It's not a stupid mistake. I think this is a design issue that prob needs addressing (as posted above). The stupid mistake was probably me returning wrapped data for the posematrix :p
i am a bit confused about what the posematrix really is...
OK ok if you want to know the technical Ton definition it's in the code:
This is the bone transformation trick; they're hierarchical so each bone(b)
is in the coord system of bone(b-1):

arm_mat(b)= arm_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b)

-> yoffs is just the y axis translation in parent's coord system
-> d_root is the translation of the bone root, also in parent's coord system

pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b)

we then - in init deform - store the deform in chan_mat, such that:

pose_mat(b)= arm_mat(b) * chan_mat(b)
bone_mat is the bonespace bone matrix and chan_mat is the delta transformation from rest.

jsgreenawalt
Posts: 0
Joined: Sun Jan 08, 2006 6:27 am

Post by jsgreenawalt »

Yes, the script GUI will always come up in the scripts window if you launch it from there but if you launch through "File->Export->someexporter" It often turns the 3d view into a script window (if no script window is currently on screen). I guess I could remove the "Group: 'Export'" from the header to prevent users from launching the script through the File->Export menu, but it still dosen't solve the problem if the user switches their 3d view to a script window and runs it from there. My current plan is to check if any 3d views are visible, if not, pop up a warning and halt the export.

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

Post by amoghvc »

jsgreenawalt, how did you do that ? How do you check if the 3D window is open or not ? I have the same problem as you guys are facing. That is the final piece in the puzzle for this exporter.

Post Reply