Panda3D Manual: Example for Clicking on 3D Objects
<<prev | top | next>> |
This is a small example program for clicking on 3D objects. A panda, a teapot, and a cube will be on screen. When you click on the screen the console will tell you the nodePath of what you have clicked on. Its basically a watered down version the tutorial included with Panda 3D 1.0.4. However, all the functionality for picking 3D objects is encapsulated into the Picker class which you may feel free to use in your own code.
import direct.directbase.DirectStart #for the events from direct.showbase import DirectObject #for collision stuff from pandac.PandaModules import * class Picker(DirectObject.DirectObject): def __init__(self): #setup collision stuff self.picker= CollisionTraverser() self.queue=CollisionHandlerQueue() self.pickerNode=CollisionNode('mouseRay') self.pickerNP=camera.attachNewNode(self.pickerNode) self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) self.pickerRay=CollisionRay() self.pickerNode.addSolid(self.pickerRay) self.picker.addCollider(self.pickerNode, self.queue) #this holds the object that has been picked self.pickedObj=None self.accept('mouse1', self.printMe) #this function is meant to flag an object as being somthing we can pick def makePickable(self,newObj): newObj.setTag('pickable','true') #this function finds the closest object to the camera that has been hit by our ray def getObjectHit(self, mpos): #mpos is the position of the mouse on the screen self.pickedObj=None #be sure to reset this self.pickerRay.setFromLens(base.camNode, mpos.getX(),mpos.getY()) self.picker.traverse(render) if self.queue.getNumEntries() > 0: self.queue.sortEntries() self.pickedObj=self.queue.getEntry(0).getIntoNodePath() parent=self.pickedObj.getParent() self.pickedObj=None while parent != render: if parent.getTag('pickable')=='true': self.pickedObj=parent return parent else: parent=parent.getParent() return None def getPickedObj(self): return self.pickedObj def printMe(self): self.getObjectHit( base.mouseWatcherNode.getMouse()) print self.pickedObj mousePicker=Picker() #load thest models panda=loader.loadModel('panda') teapot=loader.loadModel('teapot') box=loader.loadModel('box') #put them in the world panda.reparentTo(render) panda.setPos(camera, 0, 100,0) teapot.reparentTo(render) teapot.setPos(panda, -30, 0, 0) box.reparentTo(render) box.setPos(panda, 30,0,0) mousePicker.makePickable(panda) mousePicker.makePickable(teapot) mousePicker.makePickable(box) run()
If you are running this example on Panda 1.1, replace line 24 with
self.picker.addCollider(self.pickerNP, self.queue)
Note: If you switch to another window, the mouse picker may not work when you are back to the panda window. If that happens, just select the perform some window action.If it still doesn't work still, replace printMe method with this:
      def printMe(self):
      	if base.mouseWatcherNode.hasMouse():
           	self.getObjectHit( base.mouseWatcherNode.getMouse())
           	print self.pickedObj
<<prev | top | next>> |