View Single Post
  #1  
Old 07-27-2007, 07:08 PM
k_iwan k_iwan is offline
Member
 
Join Date: May 2006
Posts: 115
Unhappy picking problem...

Hi,

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

Code:
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?
Reply With Quote