Load a character
Load a skinned mesh using USD and animate it
[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)
Load the USD Asset
the default skinned character is accessible directly from internal resources
[2]:
character = viewer.import_usd_asset('AnimLabSimpleMale.usd')
[3]:
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']
Render the character in tpose
by calling the draw command without any matrices, we will render it with the default bindpose
[4]:
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
[4]:
Render and update some bones
[5]:
xforms = np.eye(4, dtype=np.float32)[np.newaxis, ...].repeat(2, axis=0)
xforms[0, :3, 3] = [10, -10, 20]
xforms[1, :3, 3] = [10, -10, -20]
viewer.begin_shadow()
# passing a few matrices to the draw command, with the names of the bones for which we have given the matrices
viewer.draw(character, xforms, ['LeftArm', 'RightArm'])
viewer.end_shadow()
viewer.begin_display()
viewer.draw_ground()
# passing a few matrices to the draw command, with the names of the bones for which we have given the matrices
viewer.draw(character, xforms, ['LeftArm', 'RightArm'])
viewer.end_display()
viewer.disable(depth_test=True)
# passing a few matrices to the draw command, with the names of the bones for which we have given the matrices
viewer.draw_axis(character.world_skeleton_xforms(xforms, ['LeftArm', 'RightArm']), 5)
# passing a few matrices to the draw command, with the names of the bones for which we have given the matrices
viewer.draw_lines(character.world_skeleton_lines(xforms, ['LeftArm', 'RightArm']))
viewer.execute_commands()
viewer
[5]:
Load an animation.
We will load an animation saved as usd stage.
[8]:
anim = lab.import_usd_animation('example_animation.usd')
[10]:
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
[10]: