Vizard 7 » Tutorials & Examples » Physics engine » Tutorial: Callbacks & complex shapes
7.6

Tutorial: Callbacks and Complex Shapes

This tutorial shows how to be notified when objects are colliding, as well as the creation of collision shape objects that more closely match their geometry. Vizard informs you of collisions with its event system, and allows you to set up a callback function handling VizPhysicsShape collision. You can make more accurate collision shapes for complex geometry by creating VizPhysicsShapes for child nodes instead of the global node.  

 

This tutorial steps through code found in callbacksAndComplexShapes.py.  For the complete example script look in the \tutorials\physics directory.

 

The code bellow creates VizPhysicsShapes at a smaller granularity than a single call to <node3d>.collideBox().

#Create a bumper prototype to copy for all other bumpers
bumper = viz.addChild( 'table.wrl' )
bumper.setScale( BUMPER_WIDTH, BUMPER_DEPTH, BUMPER_WIDTH )
#Create a collideBox for each child node rather than one encompassing the entire model
bumper.collideBox( node='Leg1', bounce = 1, friction = .00000001 )
bumper.collideBox( node='Leg2', bounce = 1, friction = .00000001 )
bumper.collideBox( node='Leg3', bounce = 1, friction = .00000001 )
bumper.collideBox( node='Leg4', bounce = 1, friction = .00000001 )
bumper.collideBox( node='Top', bounce = 1, friction = .00000001 )

By supplying the node parameter in the bumper.collideBox() call, the resulting VizPhysicsShape object will only encompass the specified child node.  Creating VizPhysicsShapes for all of the child nodes in the table.wrl model avoids creating a collision box that surrounds the entire table.wrl model and allows balls to pass between the legs of the table.  

 

For your program to be aware of physics collisions, you must do two things: call <node3d>.enable( viz.COLLIDE_NOTIFY ) on any nodes that you want to generate a collision events and setup a collision event callback function.

bumperCopy.enable( viz.COLLIDE_NOTIFY ) #We want to be notified of things colliding with the bumper

In our for loop that creates the bumpers, we tell Vizard to fire collision related events whenever objects are colliding with our bumpers.  

#Called when two objects collide in the physics simulator
def onCollide(e):
    #Did ball collide with a bumper?
    if e.obj2 in balls:
        #Change color of bumper
        e.obj1.color( random.choice( [viz.RED,viz.GREEN,viz.SKYBLUE,viz.YELLOW,viz.ORANGE,viz.PURPLE] ) )
        #Play sound at a volume appropriate for ball speed
        speed = vizmat.Vector( e.obj2.getVelocity() ).length()
        if speed > .7:
            viz.playSound( 'crashNew.wav' )
        elif speed > .4:
            viz.playSound( 'crashQuiet.wav' )
        elif speed > .1:
            viz.playSound( 'crashVeryQuiet.wav' )

viz.callback( viz.COLLIDE_BEGIN_EVENT, onCollide )

The above code is our collision event handling function followed by the callback registering function.  The event function has two attributes we are interested in: obj1, the node that generated the event, in our case the bumpers that have enabled viz.COLLIDE_NOTIFY; and obj2, the node that collided with obj1, in this script obj2 will be the bouncing balls.  The call to viz.callback( viz.COLLIDE_BEGIN_EVENT, onCollide ) tells Vizard to call the onCollide function when the nodes first collide.  If you wanted to call a function when two nodes stop touching you would register a function to handle viz.COLLIDE_END_EVENT.  For instance, a viz.COLLIDE_END_EVENT would fire when something was pushed off a table.

Basic physics concepts

Forces and material properties

Callbacks and complex shapes