Vizard 7 » Reference » Physics » Physics basics
7.5

Physics Basics

 

The physics engine gives node objects the ability to collide with other node objects and react to forces as if they were ridge material bodies.  The physics engine consist of two fundamental concepts, collision shapes and forces.  Collisions shapes define the occur between two independent objects when their collision areas intersect. Forces can be applied to nodes as a linear force or as a torque. In order for collisions to occur or forces to be applied a node must have a collision area defined.

Enabling and Disabling Physics

Physics is enabled globally by calling the viz.phys.enable() function. Physics can be disabled by calling viz.phys.disable(). When disabling physics all physics objects will stop moving but remember their current velocity. When physics is re-enabled, all nodes will resume their previous velocity. To turn on physics call the following:

viz.phys.enable()   # Enable physics

Colliding Objects

The collision area of a node can be defined in a number of ways with the simplest being the collidePlane, collideBox and collideSphere methods. Each of these methods takes the optional arguments friction, hardness, bounce, and density. Each method returns a VizPhysicsShape object which is used to apply forces and change properties. When calling one of these methods physics is automatically enabled on that node, which means it will immediately be affected by gravity and will be collideable.

 

The collidePlane method defines an entire plane stretching to infinity as a collision area.  Planes are often used to establish the ground. VizPhysicsShape objects created in this manner are unaffected by forces, such as gravity, collisions with other objects and manually applied forces.

 

The collideBox method defines the collision area as the objects bounding box.  

 

The collideSphere method defines the collision area as the objects bounding sphere.  Optionally a radius can be provided which skips the calculation of the radius based on the object.

ground = viz.add('tut_ground.wrl'# Add ground
ground.collidePlane()   # Make collideable plane
ball = viz.add('ball.wrl',pos=(0,1.8,6))    # Add a ball
ballPhys = ball.collideSphere(bounce=1.5)   # Define ball's physical properties

Gravity

Once a collision area is defined for an object and physics is enabled, gravity will affect the object. The default gravity vector is [0,-9.8,0] and can be changed with the viz.phys.setGravity function. To disable gravity call the following:

viz.phys.setGravity(0,0,0)

For real gravity one can disable the world gravity by the previous line, and use the addAttractor function described and demonstrated on the forces page.

Applying Forces

Forces can be applied directly to a node object with a variety of functions. In order for a force to have an effect a collision area must be defined for the node and physics must be enabled on a node.

 

Forces can be applied directly or through two special functions, addVelocity and addSpring, each of which is discussed on the forces page.

 

Applying a Force

Simply the applyForce function takes a force vector and duration to apply a force.

ball = viz.add('ball.wrl',pos=[0,.2,6]) # Add a ball
ballPhys = ball.collideSphere() # Enable physics on ball

ball.applyForce([0,0,.1],1) # Apply small force for 1 second

In the above example the force is applied in the world's 'z' coordinate. In order to always apply the force in the balls 'z' coordinate the apply force function must be called like so: ball.applyForce([0,0,.1],1,viz.ABS_LOCAL). With this the force direction will change with the ball and thus it behaves differently.

Joints

Combining two physics enabled objects in Vizard is done with the use of joints. There are 6 joints that can be made with Vizard each of which has a different behavior. The six joints are:

  1. Hinge
  2. Universal
  3. Ball
  4. Slider
  5. Wheel
  6. Fixed

Each of these are explained in more detail on the joints page. The following is a simple example of a hinge joint, with a force applied to it.

box = viz.add('box.wrl',pos=[0,1.1,6])  # Add a box
box.setScale(2,1,.1) # Make it look more door like
box.collideBox() # Enable physics on the box

joint = viz.phys.addHingeJoint(box,None,pos=[0,1.6,6]) # Hinge joint attached to world

def push():
    box.applyForce([0,0,1.2],0,viz.ABS_LOCAL) # Apply force into door
vizact.onkeydown(' ',push) # Call push function on spacebar

The above example shows a box hanging by a hinge. By pressing spacebar a force is applied perpendicular to the middle of the door causing it to swing. Note that the hinge joint does not require a second physics object to be constructed, but instead must have the None parameter passed in as the second object. Also note the setup position of the hinge; this is specified in the world's coordinates.

Motors

Motors in Vizard apply forces between two objects when connected with a joint. There are four main functions to using a motor and each function behaves differently depending on the joint. The four functions are:

  1. setMotorVelocity
  2. setMotorAngle
  3. setMotorThrottle
  4. disableMotor

The motors typically take three parameters, axis, torque and velocity. When using a motor an axis must be specified in which to apply this angle. Depending on the joint, the axis is typically 0, however for the few joints where there are two axis then the axis is either 0 or 1. The torque or maxTorque parameter is used to specify or limit the amount of force applied to a particular joint. The velocity or maxVelocity parameter is used to specify or limit, in degrees per second, the rotational speed at which a motor is applied.

 

Motors in Vizard work like electric motors by applying the maximum torque at zero velocity and zero torque at the maximum velocity. Keep this in mind if building something like a car motor as car motors do not apply maximum torque at zero velocity.

 

The following is similar to the applyForce example above, however the force is now applied with the use of a motor.

box = viz.add('box.wrl',pos=[0,1.1,6])  # Add a box
box.setScale(2,1,.1) # Make it look more door like
box.collideBox() # Enable physics on the box

joint = viz.phys.addHingeJoint(box,None,pos=[0,1.6,6]) # Create a hinge joint

on = 0 # Motor Status
def push():
    global on
    if not on:
        joint.setMotorVelocity(axis=0,velocity=1080,maxTorque=.2) # Apply torque
    else:
        joint.disableMotor(axis=0) # Disable motor
    on = (on+1)%2 # Toggle status
vizact.onkeydown(' ',push) # Call push function on spacebar

Tweaking

Physics can be modified with two commands setStepSize and setAccuracy. The step size is the time between each physics calculation and when decreased reduces the error from the calculations.

 

Changing the accuracy makes use of more accurate physics calculations also decreasing the error, but by also increasing the CPU usage.

 

If an objects movement appears jittery try changing these values around to see if it can be smoothed out.

See also

In this section:

Physics Shapes - In depth discussion of the collide methods.

Forces - More detail on applyForce and applyTorque.

Joints - In depth overview of the joint types.

Motors - In depth explanation of how each motor works with each joint.

Physics Command Table

Other sections:

Tutorial: Physics

Event Reference

Example scripts:

Basic physics

Tracking an object

Collision plane

Callbacks & complex shapes

Forces & materials