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()