bone matrices - bind pose <-> current frame
Moderators: jesterKing, stiv
-The poseMatrix has some strange behaviours.In the documentation
is written it's not settable.Anyway in an example like this:
-the bone is transformed in the 3d view.This happens more frequently
if no 3d view is on the screen.
Ben
is written it's not settable.Anyway in an example like this:
Code: Select all
pose_mat = pose_bone.poseMatrix
pose_mat.invert()
if no 3d view is on the screen.
Ben
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.
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.
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
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
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
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
-
- Posts: 0
- Joined: Sun Jan 08, 2006 6:27 am
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.
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.
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. 
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...
is this correct? i am a bit confused about what the posematrix really is...

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

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.
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 have yet to find a way to control which pane the script GUI will open in through the API
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 :pi did a stupid mistake
OK ok if you want to know the technical Ton definition it's in the code:i am a bit confused about what the posematrix really is...
bone_mat is the bonespace bone matrix and chan_mat is the delta transformation from rest.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)
-
- Posts: 0
- Joined: Sun Jan 08, 2006 6:27 am
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.