need to disconnect bones before export, animations mess up...

I have a script for a format which has all bones relative to root (0,0,0). But they still get connected when importing to make posing possible. They get disconnected again in the exporter.

When I create an animation when the bones are connected and then have them disconnected, the animations mess up. What to do? This really sucks.
I thought Blender recalculates the bone transforms after they are unparented/disconnected and the opposite.

As a work around maybe you need to have 2 armatures. One is properly parented for posing in Blender and the other is a duplicate of all those bones with no parent relationships but with “copy transform” constraints back to the Blender rig. Then you pose the first rig but export the 2nd rig.

More info please.
From what I understand you mean having 2 armatures, 1 hidden and one’s bones set to inherit angles/positions/scales of the other’s.
Could work, though would be a bit ugly and maybe confusing for users when they’ll see a dublicate of the Armature in the Outliner.
But anyway, it seems angles will be shared as well and that’s bad as when bones get connected they usually change angle.

I probably misunderstand what you are trying to do. Does your export format really not respect the parent-child relationship or does it just not have explicit fields to set parent-child information?

If you move the upper arm in your pose armature, I’m assuming that you still want the lower arm to follow that when it exports. Is that true?

If so, then you can just use the data in the PoseBone.matrix for each frame. This encapsulates all the rotation/location/scale data from all the parent bones + the rotation/location/scale for the current bone.

If you move the upper arm in your pose armature, I’m assuming that you still want the lower arm to follow that when it exports. Is that true?
Yes, I want them disconnected, but still move as before, preferably inside Blender as well, to test that everything is fine.

I should have been clearer. The bones, when connected, also change their angle. The exporter actually has the original angles hardcoded and basically regenerates the skeleton.
This way works fine for importing/exporting our limited model format, but when it comes to animations, this problem arises.

Let me rephrase my question to show more accurately what I need to do:

I have an armature, at one point (before) export, I need to replace it with another one which has same amount of bones with same names and positions and that’s all they have in common (parenting info, angle, scale are different).

I need to do this as my format doesn’t support bone parenting (bones are relative to root). I connect and rotate the bones in my importer and do the opposite in my exporter. This allows me to rig my new meshes easily as I can pose them and stuff, and as I undo the changes in the exporter, be able to use existing animations (not made by me, not made in Blender) in my environment on that model I exported from Blender.

The problem is now I want to also be able to make animations. But if I make animations on the Armature my importer has edited, they will deform weirdly after my exporter undoes those changes, as bones will be disconnected and rerotated.

I gotta say kastoria is on the right track. A 2nd armature with identical bones, each bone has a copy transforms constraint on it targeting the same bone in the original rig, but without the parent child relationships. Create your animation, inserting keyframes for the first rig, your 2nd rig will follow along. Now on the 2nd rig, on every keyframe the first rig has, I-key -> visual LocRot keyframes for the 2nd rig. See the attached .blend file…

In it, I create a 2 bone rig on the first object layer, on the last object layer is exactly the same rig, but without parent/child relations. I animated the first rig and inserted 2 keyframes on frame 1 & 11. Then I selected the object layer with the 2nd rig and in pose mode I inserted visual LocRot keyframes for it. Try it for yourself, delete the rig on the first layer (so the copy transforms constraints have nothing to copy) and the animation on the 2nd rig still happens.

I’m also thinking since someone wrote and exporter presumably in python for blender to your format, they could also add this to the exporter as well, so you don’t have to manually create the 2nd rig/constraints/keyframes.

Randy

Afterthought - you can only insert visual LocRot, can’t insert visual Scale, so scaling of bones won’t work… dunno why blender won’t do that…

Attachments

example_rig.blend (379 KB)

Thank you for taking the time to make an example, but like I explained that won’t work. it’s very close, but still not a workaround, because the bones aren’t merely disconnected, but can have different angle.

So take your armature with the disconnected bones and take the bigger bone and move its tip in Edit Mode, now go to pose mode. The tip angle has changed. See what I mean?

Basically that could work if the constraint “didn’t affect the rest pose”, or “were relative to rest pose of the constraint’d bone”.

Thanks, but seems to suffer the same problem as the previous solution. I tried the example blend file, rotated one bone, went out of the edit mode, and the bone’s angle is still the same as it was before rotating it in edit mode. So

Basically that could work if the constraint “didn’t affect the rest pose”, or “were relative to rest pose of the constraint’d bone”.

As for the possible solution for the other question, we should talk there instead. Right now I tried porting the function to 2.4, and it didn’t solve it, made things look worse. Maybe I ported something wrongly.


def get_pose_matrix_in_other_space(armature, mat, pose_bone):
    """ Returns the transform matrix relative to pose_bone's current
        transform space.  In other words, presuming that mat is in
        armature space, slapping the returned matrix onto pose_bone
        should give it the armature-space transforms of mat.
        TODO: try to handle cases with axis-scaled parents better.
    """
    bone = armature.getData().bones[pose_bone.name]
    parentbone = armature.getData().bones[pose_bone.name].parent
    
    rest = bone.matrix['ARMATURESPACE'].copy() # pose_bone.bone.matrix_local.copy()
    rest_inv = rest.copy().invert()
    if pose_bone.parent:
        par_mat = parentbone.matrix['ARMATURESPACE'].copy()
        par_inv = parentbone.matrix['ARMATURESPACE'].inverted()
        par_rest = parentbone['BONESPACE'].copy()
    else:
        par_mat = Blender.Mathutils.Matrix()
        par_inv = Blender.Mathutils.Matrix()
        par_rest = Blender.Mathutils.Matrix()

    # Get matrix in bone's current transform space
    smat = rest_inv * (par_rest * (par_inv * mat))
    
    # Compensate for non-inherited rotation/scale
    # no flag for this in 2.4 API, removed
    
    return smat

http://i.imgur.com/y4DDU.jpg

Now I can’t even notice the individual limbs of the characters.
I think it would be best to first understand what matrices posebone.localMatrix() and posebone.poseMatrix() return, because by my tests “poseMatrix” seems to be in “armature space”.

I’m sorry, I thought according to your posts you are working with animations, when did you mention editing the armature? :spin:

Randy

I might have made a mistake by trying to simplify the problem for you guys by not telling my exact situation.

So… I need to edit my Armature by disconnecting (+unparenting) and rotating some bones, but still have the animations I’ve made for it to work.
So I need to:

  1. Not lose animation data for bones which were children of other bones, after disconnecting/uparenting them (Blender doesn’t seem to apply and transform to them personally, and doesn’t apply the transforms to them even when (after) disconnecting/unparenting them. When you do that, they just stay in “mid air”).
  2. Not ruin my animation after rotating bones in Edit Mode (make the animations not get modified by the new rest pose).

blender (as far as i know) does not re-calculate the recorded animations of armature bones for any edit-activity done afterwards.

This is opposite of - for example the automatic update of uv-unwrapping of an edited mesh (but even this could be made impossible, when adding whole mesh-parts).

I think I said in my last post that Blender doesn’t seem to do that, so yeah I know. If you thought I said the problem is because it does change the animations to work with the edited bones, then no, I meant the opposite: the animations mess up because it doesn’t.
So I still need a solution, theoretically it’s not impossible.

Maybe I should move this to the Python support if you mean Blender doesn’t have any GUI option to do the things I want.

Converting back to 2.4… begs the question.

Rather than editing your armature bones to export,

My suggestion was to make a new set of bones, one for each of your blender rig bones, each at the origin.

a format which has all bones relative to root (0,0,0).

then snap each of these to your blender rig bones, using the snapping code from previous post, or as randy suggested, constraints…

Now export using data from the new set of bones. Clean up by removing the new bone set.

Sorry if I’m missing something obvious, but how would that work? I already explained that constraints would only work for positions, but not rotations, because:

Thanks, but seems to suffer the same problem as the previous solution. I tried the example blend file, rotated one bone, went out of the edit mode, and the bone’s angle is still the same as it was before rotating it in edit mode.

Imagine I create a bone with the different angle and add the constraint to it instead of rotating the existing bone. It’s the same problem:

If I have a bone facing up in rest pose and add constraint to inherit rotation of a bone facing down in rest pose, it will face down itself, in rest pose. Changes to the rest pose as well destroy the animations.

Attached a file.

The three bones are at the origin and point for each axis, in edit mode or rest pose. Hit the snap to bones button. Each will snap to the head bone. Each will have location and rotation relative to their rest pose. If you change the rest pose, hit the button again and it will snap to the bone and reflect the change.


Isn’t this what you are trying to achieve?

Attachments

rp_test.blend (822 KB)

It seems you simply don’t get why it’s not a solution (not trying to be rude here).
So here’s a visual explanation:
http://i48.tinypic.com/281r8mg.jpg

imagine the bone head geometry attached:
http://i49.tinypic.com/352p6xs.jpg