Blender rig exporter/animation importer

Are you guys using pre-made animations in mocap or making your own mocap animations?

If you’re using mocap, what product? If not, where’d you find the animations?

https://www.mixamo.com/

Hit “Animations” at the top

1 Like

someone download all of these and upload on mega, pls

2 Likes

This is the internet, it would be weird if someone hasn’t already done that (not necessarily someone from Roblox)

4 Likes

One thing that I hope you guys add (or is already there) is the ability to work with multiple ROBLOX rigs at once. I want to be able to animate things like 2 guys fighting, or something like that. Any way to work with those multiple rigs?

1 Like

You could import + generate one rig, rename the __Rig and __RigMeta objects to something else (postfix a 2 or so), then import another rig. The plugin always looks for those objects by name when importing/generating/exporting, but you can animate both rigs simultaneously in Blender just fine with different names. Just rename it back when exporting.

I just tried this whole process tonight, following the YouTube Tutorial linked above, and it’s so close to working. But somehow, I’m losing the critical location data from the animation when trying to apply the Mixamo-generated .fbx file in Blender to the rig. The Mixamo file has all the location and rotation information, as you can see in the clip below. The stick figure on the left is the Mixamo .fbx rig file imported with File->Import->FBX. But if I try to apply it to my character (R15 block mode imported via Import Model and Rebuild rig) with “Import FBX” from the RBX add-on, or if I name the correctly-imported rig to __Rig2 and use “Map keyframes by bone name”, I get the same results: all location information is lost and the Roblox character animates with their HumanoidRootPart and LowerTorso fixed in space. Where am I going wrong?

https://i.gyazo.com/8dc0f8467d8b132e24c5fee12635bc48.mp4

3 Likes

You have to map the HumanoidRootPart to the Mixamo Root joint (in Mixamo).
In Roblox, HRP is static in animations (the root), which the built-in mapping function also enforces.


(the neon green is the HRP)

3 Likes

Ah yes, I forgot to mention a key detail. As best I can tell, Mixamo no longer has this feature. “My Assets” is gone from the site, and the fbx auto-rigger is full auto, no manual adjustments. In fact, I was only able to get it to accept and animate the armature alone; any attempt I made to include mesh data in my FBX caused the autorigger to hang.

4 Likes

I haven’t used the “new” Mixamo (i.e. deleted 90% of the site) yet myself, but it sounds sort of painful if they have removed the ability to adjust their automatic mapping…
It’s probably fixable by multiplying LowerTorso.matrix_basis with HumanoidRootPart.matrix_basis, then setting HumanoidRootPart.matrix_basis to the identity matrix for each keyframe. I might check it and “fix” the import code of the addon this weekend.

2 Likes

Cool. While manually connecting up the Mixamo-generated rig to the rigged character can get things working in Blender, it also results in an exported animation that the Blender Animations copy-paste plugin thing can’t parse. :-/ I’ll be fiddling with it a bit more tonight. I don’t know enough about what goes on on the mixamo side to know if there is a way to massage the Blender fbx into something their new auto-rigging can deal with correctly. Thanks for your feedback!

3 Likes

This is apparently caused by Mixamo applying an animation onto the entire armature instead of the root bone/lower torso bone. That root bone issue is a case I’ve apparently already handled, but not when the entire armature is being animated.

For now you can just use File → Import → FBX, then open the Dope sheet for the loaded armature from Mixamo. Copy all the scale + rotation tracks (with all their keyframes) for the X/Y/Z Location and X/Y/Z Euler Rotation tracks. Paste them in the associated tracks for LowerTorso, like shown here:

Make sure to set the LowerTorso rotation tracks to Euler XYZ mode, not quaternions, for some reason the armature itself uses Eulers instead of quaternions…
The dope sheet blender API is still a bit magic, not sure when I get to automating this.

4 Likes

Thanks for this, I was having the same problem but didn’t have the time to troubleshoot it myself :+1:

1 Like

That’s cool that there is a way to fix it right in Blender. I got the Mixamo animations working yesterday also, and discovered the same thing regarding the rig. I added an else clause in your copy_anim_state_bone function to apply the source.matrix_world onto the HRP so that this propagates to all bones, then set it back to Matrix.Identity(4) after all the bone updates. That’s not the only issue I found with Mixamo either; some of the animations are weirdly offset in world space, even when you check off “in place”. So I ended up adding support for adjusting the animation offset, so I can correct that when copying the animation onto the __Rig. Also, a flip 180 option :slight_smile:

Thanks for your help, and for making these sweet tools!

https://i.gyazo.com/42dfc2f7b7dbf7f7d73a2648c8d3bd92.mp4

7 Likes

Thanks for sharing how you fixed it, I’ll adjust the addon soon™ too. Feels like that armature offset is also caused by the “new” Mixamo, given how previously I never had that issue…

That flipping is still a small quirk in my addon though, it always makes the armature origin is the identity matrix while it should probably be the HRP matrix instead. Roblox their rig generation plugin creates rigs with the HRP rotated 180 degrees around (0, 1, 0), so it causes those issues with Mixamo if you wouldn’t rotate that rig around first (to ensure the HRP rotation matrix is also the identity one)…

2 Likes

If anyone could make a video on how to animate multiple ROBLOX rigs at the same time, and individually export their animation code as separate, that’d be awesome! Thanks!

3 Likes

I looked for the github repository for this, but can’t find it, only links to the RAW source. Is it online somewhere, forkable?

My changes were just a few lines, to the two functions below. I added comments starting with AYB where I made additions. I used this with the Roblox Rig Generator’s Woman Rig most recently. I also left in a line commented out, which has additional translation and rotation corrections that I needed for the first rig I exported, since I messed up my prep work somehow, either from Roblox to Blender, or when I exported the FBX from Blender (there are too many settings permutations, especially for scaling!)

I was never able to get new Mixamo to properly accept a Roblox character FBX with mesh, but it will take just the armature, and I can see the dancing blue stick figure enough to know it works. I used the modified script with your plugin’s Map keyframes by bone name option with the Mixamo rig selected, not the Import FBX option. I’m unsure if the latter works. I imported the Mixamo-generated animation FBX with Blender’s built-in Import->FBX.

def copy_anim_state_bone(target, source, bone):
    # get transform mat of the bone in the source ao
    bpy.context.scene.objects.active = source
    t_mat = source.pose.bones[bone.name].matrix
    #AYB - Root rig world position/orientation we ultimately need transferred to the Lower Torso
    w_mat = source.matrix_world
    bpy.context.scene.objects.active = target
        
    # root bone transform is ignored, this is carried to child bones (keeps HRP static)
    if bone.parent:
        # apply transform w.r.t. the current parent bone transform
        r_mat = bone.bone.matrix_local
        p_mat = bone.parent.matrix
        p_r_mat = bone.parent.bone.matrix_local
        bone.matrix_basis = (p_r_mat.inverted() * r_mat).inverted() * (p_mat.inverted() * t_mat)
    else:
        #AYB - Setting the matrix_basis for humanoid root part to the source rig translation and orientation
        #so that this world orientation propagates down the armature to all bones, then afterwards I
        #will set it back to the identity in copy_anim_state below
        r_mat = bone.bone.matrix_local
        #AYB - This commented out line was to fix translation and rotation issues I had with my first attempt to export a rig from Roblox
        #bone.matrix_basis = Matrix.Translation(Vector((0,2.32211,0))) * ((r_mat.inverted() * (w_mat.inverted() * t_mat)) * Matrix.Rotation(math.radians(180),4,'Y'))
        bone.matrix_basis = (r_mat.inverted() * (w_mat.inverted() * t_mat))
        
    # update properties (hacky :p)
    bpy.ops.anim.keyframe_insert()
    bpy.context.scene.frame_set(bpy.context.scene .frame_current)

    # now apply on children (which use the parents transform)
    for ch in bone.children:
        copy_anim_state_bone(target, source, ch)
    
def copy_anim_state(target, source):
    # to pose mode
    bpy.context.scene.objects.active = source
    bpy.ops.object.mode_set(mode='POSE')

    bpy.context.scene.objects.active = target
    bpy.ops.object.mode_set(mode='POSE')

    for i in range(bpy.context.scene.frame_start, bpy.context.scene.frame_end+1):
        bpy.context.scene.frame_set(i)
        copy_anim_state_bone(target, source, root)
        #AYB - Setting HRP back to identity CFrame orientation
        root.matrix_basis = Matrix.Identity(4)
        bpy.ops.anim.keyframe_insert()
7 Likes

I haven’t set up version control for this.

That’s normal, I basically attach mesh objects to bones once they’re being imported to emulate the blocky Roblox rig rather than constructing a skinned rig (which is what the rest of the world uses and what Mixamo expects).

Thanks for your changes anyway. I’m considering a slightly alternation now: first move all armature object animations to HRP bone (in world space like you did) on the imported rig and clearing all the entire animation tracks on the armature object. Then the imported armature object can simply be translated and rotated to correct for messed up positioning/rotation (this isn’t really possible until the animation track is removed from the armature object, as you’d be editing a single keyframe otherwise).

3 Likes

I have updated the Blender addon now to mostly handle the new Mixamo stuff properly, see link in first post.

There is now also a way to manually adjust rigs + apply the armature object transform. If you simply use the “Import FBX” button, this will also be applied automatically (which should resolve the problem of the HRP <-> LowerTorso joints not properly moving automatically).

If you want to manually adjust an armature, see this video:

https://streamable.com/rmevx

(Transform the entire armature in object mode, then use “Apply armature transform” to apply your transformation to the root bone so the actual animation gets offset once you use “Map keyframes by bone names”.)

In general with the new Mixamo I’d recommend making sure the Position is (0, 2.35, 0) and orientation (0, 0, 0) (for R15 rig, default hip height) before exporting from Roblox. This avoids you having to manually adjust the imported Mixamo animation.

Thanks to @AllYourBlox for some debugging!

5 Likes

Okay, so I tried re-naming the _RigMeta and _Rig names in Blender, and once I did that (I just put a 2 after the names) I try to import the other rig but it still disappears and is replaced with the newly imported rig. If I could get some help, that’d be great. Thanks!

2 Likes