Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • jtesch/smplx_blender_addon
1 result
Show changes
Commits on Source (2)
......@@ -87,9 +87,12 @@ This add-on allows you to add [SMPL-X](https://smpl-x.is.tue.mpg.de) skinned mes
+ Added Alembic export button
+ 20220315:
+ Speed up animation import time
+ 20220328:
+ 20220326:
+ Added Unreal FBX export. Shape keys bake options can now be found in export dialog settings.
+ Fix unwanted duplicated animation sequence in FBX export
+ 20220613:
+ Add option to import animation onto grounded rest pose armature
+ Disable animation keyframe simplification for FBX export so that FBX animations match Alembic animations
## Contact
+ smplx-blender@tue.mpg.de
......@@ -19,7 +19,7 @@
bl_info = {
"name": "SMPL-X for Blender",
"author": "Joachim Tesch, Max Planck Institute for Intelligent Systems",
"version": (2022, 3, 26),
"version": (2022, 6, 13),
"blender": (2, 80, 0),
"location": "Viewport > Right panel",
"description": "SMPL-X for Blender",
......@@ -445,8 +445,8 @@ class SMPLXSnapGroundPlane(bpy.types.Operator):
obj = bpy.context.object
if obj.type == 'ARMATURE':
armature = obj
obj = bpy.context.object.children[0]
armature = obj
obj = bpy.context.object.children[0]
else:
armature = obj.parent
......@@ -893,7 +893,7 @@ class SMPLXLoadPose(bpy.types.Operator, ImportHelper):
class SMPLXAddAnimation(bpy.types.Operator, ImportHelper):
bl_idname = "object.smplx_add_animation"
bl_label = "Add Animation"
bl_description = ("Load AMASS (SMPL-X) animation and create animated SMPL-X body")
bl_description = ("Load AMASS/SMPL-X animation and create animated SMPL-X body")
bl_options = {'REGISTER', 'UNDO'}
filter_glob: StringProperty(
......@@ -909,6 +909,14 @@ class SMPLXAddAnimation(bpy.types.Operator, ImportHelper):
),
)
rest_position: EnumProperty(
name="Rest position",
items=(
("SMPL-X", "SMPL-X", "Use default SMPL-X rest position (feet below the floor)"),
("GROUNDED", "Grounded", "Use feet-on-floor rest position"),
),
)
keyframe_corrective_pose_weights: BoolProperty(
name="Use keyframed corrective pose weights",
description="Keyframe the weights of the corrective pose shapes for each frame. This increases animation load time and slows down editor real-time playback.",
......@@ -981,6 +989,26 @@ class SMPLXAddAnimation(bpy.types.Operator, ImportHelper):
bpy.ops.object.smplx_update_joint_locations('EXEC_DEFAULT')
height_offset = 0
if self.rest_position == "GROUNDED":
bpy.ops.object.smplx_snap_ground_plane('EXEC_DEFAULT')
height_offset = armature.location[2]
# Apply location offsets to armature and skinned mesh
bpy.context.view_layer.objects.active = armature
armature.select_set(True)
obj.select_set(True)
bpy.ops.object.transform_apply(location = True, rotation=False, scale=False) # apply to selected objects
armature.select_set(False)
# Fix root bone location
bpy.ops.object.mode_set(mode='EDIT')
bone = armature.data.edit_bones["root"]
bone.head = (0.0, 0.0, 0.0)
bone.tail = (0.0, 0.0, 0.1)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.context.view_layer.objects.active = obj
# Keyframe poses
step_size = int(mocap_framerate / target_framerate)
......@@ -1007,6 +1035,10 @@ class SMPLXAddAnimation(bpy.types.Operator, ImportHelper):
for index, bone_name in enumerate(SMPLX_JOINT_NAMES):
if bone_name == "pelvis":
# Keyframe pelvis location
if self.rest_position == "GROUNDED":
current_trans[1] = current_trans[1] - height_offset # SMPL-X local joint coordinates are Y-Up
armature.pose.bones[bone_name].location = Vector((current_trans[0], current_trans[1], current_trans[2]))
armature.pose.bones[bone_name].keyframe_insert('location', frame=current_frame)
......@@ -1210,7 +1242,8 @@ class SMPLXExportFBX(bpy.types.Operator, ExportHelper):
# Default FBX export settings export all animations. Since we duplicated the armature we have a copy of the animation and the original animation.
# We avoid export of both by only exporting the active animation for the armature (bake_anim_use_nla_strips=False, bake_anim_use_all_actions=False).
bpy.ops.export_scene.fbx(filepath=self.filepath, use_selection=True, apply_scale_options="FBX_SCALE_ALL", add_leaf_bones=False, bake_anim_use_nla_strips=False, bake_anim_use_all_actions=False)
# Disable keyframe simplification to ensure that exported FBX animation properly matches up with exported Alembic cache.
bpy.ops.export_scene.fbx(filepath=self.filepath, use_selection=True, apply_scale_options="FBX_SCALE_ALL", add_leaf_bones=False, bake_anim_use_nla_strips=False, bake_anim_use_all_actions=False, bake_anim_simplify_factor=0)
print("Exported: " + self.filepath)
......