WorldViz User Forum  

Go Back   WorldViz User Forum > Vizard

Reply
 
Thread Tools Rate Thread Display Modes
  #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
  #2  
Old 07-27-2007, 07:46 PM
farshizzo farshizzo is offline
WorldViz Team Member
 
Join Date: Mar 2003
Posts: 2,849
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:
Code:
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)
Reply With Quote
  #3  
Old 07-27-2007, 07:57 PM
k_iwan k_iwan is offline
Member
 
Join Date: May 2006
Posts: 115
Red face Thank you for explanation...

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!

Kind Regards,
Iwan
Reply With Quote
Reply

Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 07:36 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Copyright 2002-2023 WorldViz LLC