How to collide with 3d models attached to aspect2d?

I tried modifying the code for “Clicking on 3d objects” from the manual ( Clicking on 3D Objects — Panda3D Manual ) to work with 3d models attached to aspect2d. I think this should work, not sure why not:

from panda3d.core import *
from direct.showbase.ShowBase import ShowBase

base = ShowBase()

traverser = CollisionTraverser("Mouse Traverser")
base.cTrav = traverser

collision_queue = CollisionHandlerQueue()

model = loader.loadModel("smiley")
model.reparentTo(aspect2d)

collision_sphere = CollisionSphere(0, 0, 0, 1.1)
collision_np = model.attachNewNode(CollisionNode("collision_sphere"))
collision_np.node().addSolid(collision_sphere)
collision_np.node().setIntoCollideMask(BitMask32(1))
collision_np.show()

picker = aspect2d.attachNewNode(CollisionNode('mouse_ray'))
picker.node().setFromCollideMask(BitMask32(1))
picker_ray = CollisionRay()
picker.node().addSolid(picker_ray)

traverser.addCollider(picker, collision_queue)

def collisionTask(task):
	
	if base.mouseWatcherNode.hasMouse():
		mpos = base.mouseWatcherNode.getMouse()
		
		picker.setPos(mpos.x, 10, mpos.y)
		
		# run the collision detection
		traverser.traverse(aspect2d)
		
		if collision_queue.getNumEntries() > 0: # if any collision detected
			collision_queue.sortEntries() # By default, the Collision Entries appear in the queue in no particular order. You can arrange them in order from nearest to furthest by calling queue.sortEntries() after the traversal.
			picked_collision_node = collision_queue.getEntry(0).getIntoNodePath()
			print(picked_collision_node)
		else:
			print("No collision")
	
	return task.cont

collision_task = base.taskMgr.add(collisionTask, "collisionTask")

base.run()

Several things are going wrong:

  1. You are assigning the traverser to base.cTrav, this will make ShowBase periodically call base.cTrav.traverse(render) on it. You don’t need this line, remove it.
  2. You are giving the picker render2d (-1…1) coordinates from the mouse watcher, even though it is parented to aspect2d. You should parent the picker to render2d. aspect2d is in the same scene graph as render2d, so this should not cause problems.
  3. You haven’t assigned a direction to the ray. Make it point down the Y axis:
picker_ray = CollisionRay((0, 0, 0), (0, 1, 0))

You may find these debug aids helpful, in addition:

traverser.showCollisions(aspect2d)

Also, these configuration settings:

notify-level info
notify-level-collide debug

I guess the confusion came from trying to view the ray while the view was orthographic, and also the issue with positions being in render2d.
Collision nodes with one attached to render2d while another attached to aspect2d colliding with each other, is it due to aspect2d being child of render2d?

Yes.