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]: