Avatar Collisions

This article descibes how to detect collisions on individual body parts of an avatar. Included is some sample code and a short video of this in action.

To detect these collisions we define collide boxes that are sized to the avatar's bones and then linked to them. Define as few or as many collide boxes as bones that will be involved in collisions. By leaving dynamics enabled, the avatar can move an object that it collides with or you can disable dynamics if you just need to determine, for example, if an avatar has touched something. The following video and example code shows an avatar fighting a box. When the avatar's right hand hand touches the box, it will change color.

In the example code below a box is created that matches the size of the avatar's hand. A collide box is generated from that and then linked to the hand bone. To have other body parts collide repeat this process for other bones. When initially setting up your collide boxes, in order to match the bone's size and create the correct offset when linking it to the bone, visualize the collide area by rendering the box.

import viz
viz.go()

#Enable physics
viz.phys.enable()

#Create ground plane
ground = viz.add('tut_ground.wrl')
ground.collidePlane()

#Create static box in front of avatar
box = viz.add('box.wrl',scale=[2,2,2],pos=(0,1,1.7),color = viz.BLUE)
box.collideBox()
box.disable(viz.DYNAMICS)

#Create avatar that doesn't like big boxes
avatar = viz.add('vcc_female.cfg')
avatar.state(6)

#Create a collision box and link it to right hand of avatar
rHandBox = viz.add('box.wrl',scale=[0.1,0.1,0.1])
rHandBox.collideBox()
rHandBox.disable(viz.DYNAMICS)
rHandBox.enable(viz.COLLIDE_NOTIFY)
rHandLink = viz.link( avatar.getBone('Bip01 R Hand') , rHandBox )
#tweak the position of the box to cover the hand
rHandLink.preTrans([0.05,-0.05,0])

#Comment this line out if you want to see the collision box around the hand
rHandBox.disable(viz.RENDERING)

#Change color of the box to red when the avatar hits it
#and then back to blue after a short time
def onCollideBegin(e):
    if e.obj1 == rHandBox:
        if e.obj2 == box:
            box.color(viz.RED)
            vizact.ontimer2(.1,0,box.color,viz.BLUE)
viz.callback(viz.COLLIDE_BEGIN_EVENT,onCollideBegin)

#Setup camera navigation
import vizcam
vizcam.PivotNavigate(center=[0,1,0],distance=5)