Working with multiple characters

We will see how to duplicate the character, update their colors and move them in the scene

[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=1200, height=720)

Load the USD Asset

the default skinned character is accessible directly from internal resources

[2]:
character_a = viewer.import_usd_asset('AnimLabSimpleMale.usd')

Duplicate the asset

So we do not duplicate the GPU memory for the meshes

[3]:
character_b = character_a.duplicate()
character_c = character_a.duplicate()
[4]:
character_a.material_names()
[4]:
['/AnimLabSimpleMale/mtl/SuitMaterial',
 '/AnimLabSimpleMale/mtl/ShirtMaterial',
 '/AnimLabSimpleMale/mtl/LeatherMaterial',
 '/AnimLabSimpleMale/mtl/ShoeMaterial',
 '/AnimLabSimpleMale/mtl/SkinMaterial']

Update materials

So we can easily find the different characters

[5]:
character_b.material('/AnimLabSimpleMale/mtl/SuitMaterial').set_albedo(np.array([0.5,1.0,0.5], dtype=np.float32))
character_c.material('/AnimLabSimpleMale/mtl/SuitMaterial').set_albedo(np.array([0.5,0.5,1.0], dtype=np.float32))

Update the character transforms

We will move the different characters in the scene, so even if we render the same animation on each, they will be placed next to each others

[9]:
xform = np.eye(4, dtype=np.float32)
xform[:3, 3] = [-100, 0, 0]
character_b.set_xform(xform)

xform[:3, 3] = [100, 0, 0]
character_c.set_xform(xform)

Load the animation

we use the bvh animation with a mapper so we can render it easily

[7]:
animmap = lab.AnimMapper(character_a, root_motion=True, match_effectors=True)
anim = lab.import_bvh('push1_subject2.bvh', anim_mapper=animmap)

Render

we render the 3 characters exactly with the same animation here

[8]:
def render(frame):

    p = (anim.pos[frame,...])
    q = (anim.quats[frame,...])
    a = lab.utils.quat_to_mat(q, p)

    viewer.begin_shadow()
    viewer.draw(character_a, a)
    viewer.draw(character_b, a)
    viewer.draw(character_c, a)
    viewer.end_shadow()

    viewer.begin_display()
    viewer.draw_ground()
    viewer.draw(character_a, a)
    viewer.draw(character_b, a)
    viewer.draw(character_c, a)
    viewer.end_display()

    viewer.execute_commands()

interact(
    render,
    frame=lab.Timeline(max=anim.quats.shape[0]-1)
)
viewer
[8]: