Open topic with navigation
Tracking an object
\examples\physics\physics1.py
This script demonstrates how to track an object.
"""
Click on an object to track it
Right click to stop tracking
Press 'r' to reset the simulation
"""
import viz
import vizact
import vizmat
viz.setMultiSample(4)
viz.fov(60)
viz.go()
import vizinfo
vizinfo.InfoPanel()
#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.SLATE)