(Not) Picking Cards

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,

  1. Multiple cards are picked simultaneously–and their positions are such that they can’t all be intersected by a single ray.

  2. 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.

  3. 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?



def init(self):
		pickerNode = CollisionNode('mouseRay')
		self.pickerNP = base.camera.attachNewNode(pickerNode)
		self.mCollisionQue = CollisionHandlerQueue()
		self.pickerRay = CollisionRay()
		self.traverser = CollisionTraverser()
		self.traverser.addCollider(self.pickerNP, self.mCollisionQue)
	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())
	   # 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.
			pickedObj = self.mCollisionQue.getEntry(0).getIntoNodePath()
			pickedObj = pickedObj.findNetTag('myObjectTag')
			if not pickedObj.isEmpty():
		return task.cont

I believe that with showCollisions on, a red tri means that was tested against but discarded because the ray doesn’t pass through it. The one the ray does pass through should be blue, not red.

Are you getting the little red arrow that denotes where a collision has actually taken place?

You can also call self.pickerNP.show() to show where the ray is right now. If it is actually coming out of the camera, it should be invisible, though.

Hmm. I’m having trouble finding info on showCollisions. I’m not sure what red/blue triangles indicate (though I’m not seeing any blue ones). I’ve got some 450 cards on the screen…showCollisions “lights up” no more than a dozen of them at any given time (with red). Obviously, a lot more cards than that aren’t being collided with.

I’m not seeing a little red arrow.

I thought that the sheer number of cards might be a problem, but I took it down to 50 and I’m still getting the odd behavior.

I turned on pickerNP.show(). That was interesting. There’s a ray emanating from what I believe is 0,0,0. Its source doesn’t change as the camera rotates and it moves when the mouse moves. When it touches cards, nothing happens. And the cards whose polygons turn red in response to mouse movement are not touched by it.

So: more clues. Any thoughts?


Put these two lines in your code after you call setFronLens.
print self.pickerNP.getPos(render)
print base.camera.getPos(render)

They should be the same even if you move the camera. If they’re not, your pickerNP isn’t parented to base.camera anymore. If they are the same but don’t change when you move the camera, you have somehow managed to make a new camera and you’re looking through that.


You were right: I was mixing up base.cam and base.camera. I get much better results now…if I’m picking TextNodes with cards on them. If I try to pick a plain vanilla Card from a CardMaker, however, I get nothing…no red/blue indicator, no arrow. (The cards have TwoSided set to True, if that matters.) Any ideas on this one?



I’m not entirely sure why that would be so. You could try making a collisionPolygon that is the same size as your card and parenting it. panda3d.org/manual/index.php … ion_Solids

Or you could make your own .egg file of the correct size and set the tag on it to do it automatically.