I have procedurally generated hexagon mesh, where every hexagon is GeomNode which contains one 2 geoms (one hexagon lines other hexagon surface). The hexagon surface is a geom created with 6 triangle primitives. The chunks of hexagons are grouped into NodePath.
I would like to pick individual hex based on mouse position. For this i have set up CollisionRay with CollisionTraverser. However, when i try to see detected collisions with myTraverser.showCollisions(base.render) it seems that it tests against every single primitive. (The small triangles.) This seems like very inefficient method.
-
How can i specify the into objects for collisions?
-
Based on documentation, i was under impression, that i have to specify collisions solids before being able to check for collisions. But it seems my ray is checking against all visible geometry, even if i haven’t specified any collision solids, nor set up CollisionNodes. I would be glad if someone could explain why it behaves this way.
-
The efficiency: I understand that the most efficient way to select objects is to set up collision plane and determine the intersection and calculate corresponding hex. However, in the future the mesh wont be flat, some hexes will be elevated, therefore this is not viable. I could set up several planes at different heights, but would this really be more efficient? The mesh will have large number of hexes, so is it really so inefficient to test for collisions with every hex?
example code of collision picker:
def pickHex():
mpos = base.mouseWatcherNode.getMouse()
pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
myTraverser.traverse(base.render)
# Assume for simplicity's sake that myHandler is a CollisionHandlerQueue.
if handler_queue.getNumEntries() > 0:
# This is so we get the closest object
handler_queue.sortEntries()
pickedObj = handler_queue.getEntry(0).getIntoNodePath()
print(pickedObj)
CollisionTraverser()
handler_queue = CollisionHandlerQueue()
myTraverser = CollisionTraverser('myTraverser')
pickerNode = CollisionNode('mouseRay')
pickerNP = base.camera.attachNewNode(pickerNode)
pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
pickerRay = CollisionRay()
pickerNode.addSolid(pickerRay)
myTraverser.addCollider(pickerNP, handler_queue)
myTraverser.showCollisions(base.render)
def printMouse(task):
if base.mouseWatcherNode.hasMouse():
pickHex()
return Task.cont