Vizard 7 » Tutorials & Examples » Physics engine » Tutorial: Physics
7.6

Tutorial: Physics

Vizard allows the addition of physics to your worlds through its integration of the OPAL physics library.  The physics system supports collision detection along with material properties, such as friction, density, hardness and bounce.  The system also provides methods for applying forces to physics objects and setting their velocities.  

This content is discussed in more detail in the reference section.

Basic physics concepts

This tutorial steps through code found in basicPhysics.py.  To open the script look in the \tutorials\physics directory.

 

The basicPhysics.py script demonstrates the initialization of the physics system and collision shape objects using a seesaw and two ducks.

 

Besides the normal Vizard startup code at the top of the script, you will see the following lines:

#Turn on the physics engine
viz.phys.enable()

This command loads the OPAL library and begins applying a gravitational force to physics shape objects (if any existed).

 

The script now begins loading models and creating physics shape objects for them.

#Add ground
ground = viz.addChild('ground.osgb')
ground.collidePlane() #Make ground collide with objects as if it were an infinite plane

The <node3d.>collidePlane() function creates a physics shape that is an infinite, horizontal plane at the origin.  Physics shape objects collide with other physics shape objects, so this one will act as an impenetrable ground.  

 

The following code creates the seesaw lever that the ducks land on.

#Create seesaw board
seesaw = viz.addChild('box.wrl')
seesaw.setScale([10,0.3,1])
seesaw.collideBox() #Make object collide as if a bounding box surrounded the object

The <node3d>.collideBox() function creates a box physics shape object surrounding the model.  This box physics shape will be this node's representation in the physics system, so it will collide with other physics shapes as a box would.  The box created around the model is known as a bounding box, which is as closely fitting as possible while still completely enclosing the model.  Because the seesaw is completely rectangular, <node3d>.collideBox() creates a perfectly fitting physics shape.  We scale the model before <node3d>.collideBox() is called so that the resulting collision shape matches the size of the geometry.  

 

The script now adds a cone shaped object to the world.  

#Create balance point of seesaw
fulcrum = viz.addChild('tut_cone.wrl')
fulcrum.setScale([0.5,0.5,0.5])
fulcrum.setPosition([0,.01,1])
fulcrum.collideMesh() #Make object collide if its actual geometry intersects another object
fulcrum.disable(viz.DYNAMICS) #Disables dynamic physics forces from acting on the object

The <node3d>.collideMesh() function creates a physics shape object that uses the node's geometry to compute collisions.  The <node3d>.disable(viz.DYNAMICS) command causes the fulcrum to be unaffected by collisions with other physics shapes or the force of gravity.  Currently, the OPAL library does not support dynamic forces on collideMesh() objects, so you should disable dynamics for theses objects.  

 

Next, the script creates the ducks that will fall on both sides of the seesaw.

#Create weight on right side of seesaw
load = viz.addChild('duck.wrl')
load.collideBox()

#Create weight on left side of seesaw
counterWeight = viz.addAvatar('duck.cfg')
counterWeight.collideBox(density=5) #The high density parameter makes the object heavier

The bounding box shapes created by <node3d>.collideBox() fully encloses the ducks' geometry, but because of their box shape, also contain empty space.  Notice the density parameter suppled to the second <node3d>.collideBox() function.  This makes the physics shape have much more mass.

 

In order to see everything the viewpoint is moved to a good location.

#Move the viewpoint so that it can see the show
viz.MainView.setPosition([0,2,-15])

Next, we add a reset function that places the ducks in their starting positions and removes any forces that are acting on them. This function is called automatically once in the script to start the simulation. A vizact.onkeydown callback is also added so the user can reset the simulation anytime the spacebar is pressed.

#Puts the moving objects in their original state
def reset():    
    seesaw.reset() #Zeros out all forces
    seesaw.setPosition([0,3,5])
    seesaw.setEuler([0,0,0]) #Puts object upright

    load.reset()
    load.setPosition([4,5,5])
    load.setEuler([0,0,0])

    counterWeight.reset()
    counterWeight.setPosition([-4, 11, 5])
    counterWeight.setEuler([90,0,0])

#Reset simulation
reset()

vizact.onkeydown(' ', reset)

Basic physics concepts

Forces and material properties

Callbacks and complex shapes