Im trying to track the position of the mouse in 3D space using a CollisionRay. I’ve created a basic terrain generated via code, and I want where on the 3D terrain my curser is pointed at, but when I try it crashes and I get the following error:
Assertion failed: tris->is_of_type(GeomTriangles::get_class_type()) at line 1275 of panda/src/collide/collisionTraverser.cxx
This happens as I call:
self.traverser.transverse(render)
Where
self.traverser
is the traverser I create at game start.
base.cTrav = CollisionTraverser()
So I’m wondering exactly what that error mean. Have I forgotten to add something to the dynamic terrain, or is something else going on?
Here is the traverse code:
class MouseController:
def __init__(self, traverser):
self.traverser = traverser
self.handler = CollisionHandlerQueue()
self.pickerNode = CollisionNode("mouseRay")
self.pickerNP = base.camera.attachNewNode(self.pickerNode)
self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
self.pickerRay = CollisionRay()
self.pickerNode.addSolid(self.pickerRay)
self.traverser.addCollider(self.pickerNP, self.handler)
self.object_counter = 0
self.registered_objects = []
def register_object(self, obj):
print(type(obj))
obj.setPythonTag("MouseCollisionObject", str(self.object_counter))
self.object_counter += 1
self.registered_objects.append(obj)
def getCameraCollision(self, tracked_object):
if tracked_object not in self.registered_objects:
return TypeError("Object not tracked")
mpos = base.mouseWatcherNode.getMouse()
self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
self.traverser.showCollisions(render)
self.traverser.traverse(render)
# Assume for simplicity's sake that myHandler is a CollisionHandlerQueue.
if self.handler.getNumEntries() > 0:
# This is so we get the closest object.
for obj in self.self.handler.getEntries():
print("Iterator\n")
picked_object = obj.getIntoNodePath()
print("find Tag\n")
picked_object = obj.findNetTag("MouseCollisionObject")
print("Before if \n")
if not picked_object.isEmpty and picked_object == tracked_object:
return obj.getSurfacePoint(render), obj.getSurfaceNormal(render)
else:
return None, None
And the mesh to node object creation code i use for the terrain:
def construct_pandas_object(self):
vertex_format = GeomVertexFormat.get_v3n3c4t2()
vertex_data = GeomVertexData("surface", vertex_format, Geom.UH_static)
pos_writer = GeomVertexWriter(vertex_data, "vertex")
normal_writer = GeomVertexWriter(vertex_data, "normal")
col_writer = GeomVertexWriter(vertex_data, "color")
uv_writer = GeomVertexWriter(vertex_data, "texcoord")
tris_prim = GeomTriangles(Geom.UH_static)
tris_prim.reserve_num_vertices(len(self.faces))
print(f"vertices {len(self.vertices)}")
print(f"normals {len(self.normals)}")
print(f"faces {len(self.faces)}")
geometry = Geom(vertex_data)
for i, face in enumerate(self.faces):
tris_prim.add_vertices(*face)
if i < len(self.vertices):
pos_writer.add_data3(tuple(self.vertices[i]))
col_writer.add_data4((1.0, 1.0, 1.0, 1.0))
uv_writer.add_data2((0, 0))
normal_writer.add_data3(tuple(self.normals[i]))
geometry.add_primitive(tris_prim)
node = GeomNode("surface")
node.add_geom(geometry)
return NodePath(node)