PDA

View Full Version : picking problem...


k_iwan
07-27-2007, 07:08 PM
Hi,

I need help with picking, after I modified the picking tutorial incorporating classes, I can no longer pick the balls.

import viz
import vizmat
import vizinfo


class Ball(object):
def __init__(self, alpha):

self.BALL_ALPHA = alpha
#Add the geometric representation of the ball
self.ball = viz.add('ball.wrl')
#Make ball twice as big
self.ball.scale(2,2,2)
#The balls collision will be represented by a sphere
self.ball.collideSphere()
#Set the alpha value of the ball
self.ball.alpha(self.BALL_ALPHA)

def reset(self):
#pass
self.ball.reset()

def translate(self,x, y, z):
self.x = x
self.y = y
self.z = z
self.ball.translate([self.x, self.y, self.z])

def rotate(self, x, y, z, angle):
self.x = x
self.y = y
self.z = z
self.angle = angle
self.ball.rotate(self.x, self.y, self.z, self.angle)

def getPosition(self):
self.x, self.y, self.z = self.ball.getPosition()
return self.x, self.y, self.z

def onPick(self):
self.node = self.ball.pick()
return self.node

class World(object):
def __init__(self):

vizinfo.add('Click on an object to track it\nRight click to stop tracking\nPress \'r\' to reset the simulation')


#Add a ground with an infinite collision plane
self.ground = viz.add('tut_ground.wrl')
self.ground.collidePlane()

class Simulation(viz.EventClass):
def __init__(self):


#Initializing base class
viz.EventClass.__init__(self)

#Create a callback to our own event class function
self.callback(viz.TIMER_EVENT, self.mytimer)
self.callback(viz.MOUSEDOWN_EVENT, self.mousedown)
self.starttimer(1,0.01,viz.FOREVER)




self.NUM_BALLS = 20
self.BALL_ALPHA = 0.5
self.BALL_RADIUS = 0.5

self.world = World()


self.target = 0 #The target we are tracking
self.lockedTarget = 0 #Have we locked onto the target?
self.currentLook = viz.Vector() #Our current look vector
self.lastTick = viz.tick() #The last update time

#The list of rigid body objects
self.bodies = []

#Add a bunch of balls to the physics simulation
for x in range(self.NUM_BALLS):
self.ball = Ball(self.BALL_ALPHA)
#Add the ball to the physical objects list
self.bodies.append(self.ball)

#Add a box model
self.box = viz.add('box.wrl')
#Use the boxes bounding box for collisions
self.box.collideBox()
#Set the alpha value of the box
self.box.alpha(self.BALL_ALPHA)
#Add the box to the list of physical objects
self.bodies.append(self.box)

self.Reset()

#This function will reset the physics simulation
def Reset(self):
for x,b in enumerate(self.bodies):
#Reset the physics of the object (This will zero its velocities and forces)
b.reset()
#Translate the object to the proper height
b.translate(vizmat.GetRandom(-0.2,0.2),x*1.5+15,vizmat.GetRandom(-0.2,0.2))
#Reset the rotation of the object
b.rotate(0,1,0,0)

def mytimer(self,num):
#global lastTick, currentLook, lockedTarget
if self.target:
#Calculate elapsed time
self.elapsed = viz.tick() - self.lastTick
#Create the vector of the targets current position
self.dest = viz.Vector(self.target.getPosition())
#Create a vector pointing from our current looking position to the new looking position
self.newLook = self.dest - self.currentLook
#Calculate the distance between the two positions
self.distance = self.newLook.length()
#If the distance is small or we are locked on the target then look at it immediately
if self.distance < 0.1 or self.lockedTarget:
self.currentLook = self.dest
self.lockedTarget = 1
else:
#We are not locked on the target, so we increment our looking position towards the current position of the target
self.newLook.setLength(self.elapsed * self.distance * 2)
self.currentLook += self.newLook
#Look at the newly calculated position
viz.lookat(self.currentLook.get())
#Save the current time
self.lastTick = viz.tick()


def mousedown(self,button):
#global target, lockedTarget, currentLook
if button == viz.MOUSEBUTTON_LEFT:

#Find which object the mouse is over
#self.node = viz.pick()
self.node = viz.pick()
#If the mouse is over an object other than the ground, begin tracking it
if self.node in self.bodies:

#If we were previously tracking an object, restore its alpha value
if self.target:
self.target.alpha(self.BALL_ALPHA)
else:
#Calculate our current looking position based on the viewers
#head position and look vector
self.headpos = viz.get(viz.HEAD_POS)
self.ballpos = self.node.getPosition()
self.distance = vizmat.Distance(self.headpos,self.ballpos)
self.currentLook.set(viz.get(viz.VIEW_LOOK)[:3])
self.currentLook.setLength(self.distance)
self.currentLook += self.headpos
#Save the new target and set its alpha
self.target = self.node
self.lockedTarget = 0
self.target.alpha(1)
#turn on mouse navigation # initially was off
viz.mouse(viz.ON) # initially was off


elif button == viz.MOUSEBUTTON_RIGHT:
#Stop tracking the current target and turn on mouse navigation
if self.target:
self.target.alpha(self.BALL_ALPHA)
self.target = 0
self.lockedTarget = 0
viz.mouse(viz.ON)


# Main ################################################## ##################################

#We need to enable physics
viz.phys.enable()

#Move the head position back and up and look at the origin
viz.translate(viz.HEAD_POS,0,5,-20)
viz.lookat(0,0,0)

s=Simulation()


viz.go()

I can still pick the cube OK, does that mean that the pick object must be on the top level? cannot be an instance of a class?

farshizzo
07-27-2007, 07:46 PM
Hi,

The viz.pick() command returns a Vizard node object. However, you are populating your bodies list with your own Ball objects, which are not node objects. You can iterate through the list and check if the node is equal to the ball attribute of the Ball class. Or you can have your Ball class inherit from the Vizard node object. If you wanted to inherit from a Vizard node your Ball class would look like this:class Ball(viz.VizNode):
def __init__(self, alpha):

self.BALL_ALPHA = alpha
#Add the geometric representation of the ball
self.ball = viz.add('ball.wrl')
#Make ball twice as big
self.ball.scale(2,2,2)
#The balls collision will be represented by a sphere
self.ball.collideSphere()
#Set the alpha value of the ball
self.ball.alpha(self.BALL_ALPHA)

#Need to initialize base class
viz.VizNode.__init__(self,self.ball.id)

k_iwan
07-27-2007, 07:57 PM
Hi farshizzo,

Thank you for your explanation, I didn't know that viz.pick() actually returns a Vizard node object. It seemed like I missed this information while reading the manual.

Much Appreciated! :D

Kind Regards,
Iwan