Hello, all. I’m trying to pick cards (CardMaker.generate()). I’m using the standard Panda3D approach (CollisionNode, CollisionRay, CollisionTraverser) that I’ve found in various parts of the Web. (The code is below.) I have stacks of cards in my scene graph. I’ve invoked self.traverser.showCollisions(render) so I can see which card(s) have been picked.
The showCollisions(render) call does in fact show me that cards are being picked (the lines that define their triangles are rendered in red). However,
-
Multiple cards are picked simultaneously–and their positions are such that they can’t all be intersected by a single ray.
-
The cards that are picked seem to bear no relationship to the position of the mouse on the screen. The mouse can be on the left side of the screen and stacks of cards will be picked on the right, and vice versa.
-
It doesn’t matter where the camera is. This is particularly odd and is probably a Clue. I’ve slaved the CollisionNode to base.camera (see below) and I then make the camera rotate around a scene. Moving the mouse to a location where card #37 (say) was selected will continue to select card #37 even though the camera has moved. To put it another way: if I leave the mouse in place while the camera is moving, the picked cards do not change.
So I’m a little bemused not to mention blocked. I can’t find a record of anyone else experiencing anything like this. Any ideas?
Thanks.
UnbreakableToy
def init(self):
pickerNode = CollisionNode('mouseRay')
self.pickerNP = base.camera.attachNewNode(pickerNode)
self.mCollisionQue = CollisionHandlerQueue()
pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
self.pickerRay = CollisionRay()
pickerNode.addSolid(self.pickerRay)
self.traverser = CollisionTraverser()
self.traverser.addCollider(self.pickerNP, self.mCollisionQue)
self.traverser.showCollisions(render)
...
def mouse1(self, task):
if base.mouseWatcherNode.hasMouse() == False:
return task.cont
mpos = base.mouseWatcherNode.getMouse()
self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
self.traverser.traverse(render)
# Assume for simplicity's sake that myHandler is a CollisionHandlerQueue.
if self.mCollisionQue.getNumEntries() > 0:
print str(self.mCollisionQue.getNumEntries())
# This is so we get the closest object.
self.mCollisionQue.sortEntries()
pickedObj = self.mCollisionQue.getEntry(0).getIntoNodePath()
pickedObj = pickedObj.findNetTag('myObjectTag')
if not pickedObj.isEmpty():
handlePickedObject(pickedObj)
return task.cont