physics1.py
This script demonstrates how to track an object.
import viz
import vizact
import vizmat
viz.setMultiSample(4)
viz.fov(60)
viz.go()
import vizinfo
vizinfo.add('Click
on an object to track it\nRight click to stop tracking\nPress \'r\' to
reset the simulation')
#Declare some constants
NUM_BALLS = 20
BALL_ALPHA = 0.5
#We need to enable physics
viz.phys.enable()
#Add a ground with an infinite collision plane
ground = viz.addChild('ground.osgb')
ground.collidePlane()
target = 0 #The
target we are tracking
lockedTarget = 0
#Have we locked onto the target?
currentLook = viz.Vector() #Our current look vector
lastTick = viz.tick() #The last update time
#The list of rigid body objects
bodies = []
#Add a bunch of balls to the physics simulation
for x in range(NUM_BALLS):
#Add the geometric representation of the ball
ball = viz.addChild('beachball.osgb',cache=viz.CACHE_COPY)
#Make ball twice as big
ball.setScale([2,2,2])
#The balls collision will be represented by
a sphere
ball.collideSphere()
#Set the alpha value of the ball
ball.alpha(BALL_ALPHA)
#Add the ball to the physical objects list
bodies.append(ball)
#Add a box model
box = viz.addChild('crate.osgb')
#Use the boxes bounding box for collisions
box.collideBox()
#Set the alpha value of the box
box.alpha(BALL_ALPHA)
#Add the box to the list of physical objects
bodies.append(box)
#Move the head position back and up and look at the origin
viz.MainView.setPosition([0,6,-15])
viz.MainView.lookAt([0,0,0])
#This function will reset the physics simulation
def Reset():
for x,b in enumerate(bodies):
#Reset the physics of the object
(This will zero its velocities and forces)
b.reset()
#Translate the object to the
proper height
b.setPosition([vizmat.GetRandom(-0.2,0.2),x*1.5+15,vizmat.GetRandom(-0.2,0.2)])
#Reset the rotation of the object
b.setEuler([0,0,0])
Reset()
def mytimer():
global lastTick,
currentLook, lockedTarget
if target:
#Calculate elapsed time
elapsed = viz.tick() - lastTick
#Create the vector of the targets
current position
dest = viz.Vector(target.getPosition())
#Create a vector pointing from
our current looking position to the new looking position
newLook = dest - currentLook
#Calculate the distance between
the two positions
distance = newLook.length()
#If the distance is small or
we are locked on the target then look at it immediately
if distance <
0.1 or lockedTarget:
currentLook =
dest
lockedTarget =
1
else:
#We are not locked
on the target, so we increment our looking position towards the current
position of the target
newLook.setLength(elapsed * distance *
2)
currentLook +=
newLook
#Look at the newly calculated
position
viz.lookAt(currentLook.get())
#Save the current time
lastTick = viz.tick()
vizact.ontimer(0, mytimer)
def startTracking():
global target,
lockedTarget, currentLook
#Find which object the mouse is over
node = viz.pick()
#If the mouse is over an object other than
the ground, begin tracking it
if node in bodies:
#If we were previously tracking
an object, restore its alpha value
if target:
target.alpha(BALL_ALPHA)
else:
#Calculate our
current looking position based on the viewers
#head position
and look vector
headpos =
viz.MainView.getPosition()
ballpos =
node.getPosition()
distance =
vizmat.Distance(headpos,ballpos)
currentLook.set(viz.MainView.getMatrix().getForward())
currentLook.setLength(distance)
currentLook +=
headpos
#Save the new target and set
its alpha
target = node
lockedTarget = 0
target.alpha(1)
#turn off mouse navigation
viz.mouse(viz.OFF)
def stopTracking():
global target,
lockedTarget, currentLook
#Stop tracking the current target and turn
on mouse navigation
if target:
target.alpha(BALL_ALPHA)
target = 0
lockedTarget = 0
viz.mouse(viz.ON)
vizact.onmousedown(viz.MOUSEBUTTON_LEFT, startTracking)
vizact.onmousedown(viz.MOUSEBUTTON_RIGHT, stopTracking)
#'r' key resets simulation
vizact.onkeydown('r',Reset)
#Set the background color
viz.clearcolor(viz.SKYBLUE)