Load a character
Load a skinned mesh using fbx.
For this you need to compile a compatible version of fbx for python.
[1]:
import numpy as np
from ipywidgets import widgets, interact, interactive
import ipyanimlab as lab
viewer = lab.Viewer(shadow_quality=lab.ShadowQuality.HIGH, move_speed=5, width=800, height=600)
[2]:
character = viewer.import_fbx_asset('AnimLabSimpleMale.fbx')
Rename the bones
As the fbx model has a namespace, we will remove it so we can load animation on this character
[3]:
for i in range(len(character.bone_names())):
character.bone_names()[i] = character.bone_names()[i].split(':')[-1]
character.bone_names()
[3]:
['Root',
'Hips',
'Spine',
'Spine1',
'Spine2',
'Neck',
'Head',
'LeftShoulder',
'LeftArm',
'LeftForeArm',
'LeftHand',
'RightShoulder',
'RightArm',
'RightForeArm',
'RightHand',
'LeftUpLeg',
'LeftLeg',
'LeftFoot',
'LeftToe',
'RightUpLeg',
'RightLeg',
'RightFoot',
'RightToe']
[8]:
viewer.begin_shadow()
# draw the character with bindpose
viewer.draw(character)
viewer.end_shadow()
viewer.begin_display()
# draw the default ground
viewer.draw_ground()
# draw the character with bindpose
viewer.draw(character)
viewer.end_display()
# disable DEPTH_TEST so we can draw on top of the scene
viewer.disable(depth_test=True)
# draw XYZ axis for each bone of the character
viewer.draw_axis(character.world_skeleton_xforms(), 5)
# draw black lines between each joints
viewer.draw_lines(character.world_skeleton_lines())
viewer.execute_commands()
viewer
[8]:
Load an animation
[5]:
animmap = lab.AnimMapper(character, root_motion=True, match_effectors=True)
anim = lab.import_bvh('push1_subject2.bvh', anim_mapper=animmap)
[6]:
def render(frame):
p = (anim.pos[frame,...])
q = (anim.quats[frame,...])
a = lab.utils.quat_to_mat(q, p)
viewer.set_shadow_poi(p[0])
viewer.begin_shadow()
# render giving the computed pose this frame, and the bones names from the animation
viewer.draw(character, a, anim.bones)
viewer.end_shadow()
viewer.begin_display()
viewer.draw_ground()
# render giving the computed pose this frame, and the bones names from the animation
viewer.draw(character, a, anim.bones)
viewer.end_display()
viewer.disable(depth_test=True)
# render giving the computed pose this frame, and the bones names from the animation
viewer.draw_axis(character.world_skeleton_xforms(a, anim.bones), 5)
# render giving the computed pose this frame, and the bones names from the animation
viewer.draw_lines(character.world_skeleton_lines(a, anim.bones))
viewer.execute_commands()
interact(
render,
frame=lab.Timeline(max=anim.quats.shape[0]-1)
)
viewer
[6]: