Hi all,
This code snippet creates a collision mesh from a loaded model, suitable for the built-in collision detection and handling system:
from panda3d.core import *
from direct.showbase.ShowBase import ShowBase
base = ShowBase()
# set up a light source
p_light = PointLight("point_light")
p_light.set_color((1., 1., 1., 1.))
base.light = base.camera.attach_new_node(p_light)
base.light.set_pos(5., -100., 7.)
base.render.set_light(base.light)
# load model(s)
path_to_model = "smiley"
model_root = base.loader.load_model(path_to_model)
model_root.reparent_to(base.render)
# create a temporary copy to generate the collision meshes from
model_copy = model_root.copy_to(base.render)
model_copy.detach_node()
# create root node to attach collision nodes to
collision_root = NodePath("collision_root")
collision_root.reparent_to(model_root)
# offset the collision meshes from the model so they're easier to see
collision_root.set_x(1.)
# create a collision mesh for each of the loaded models
for model in model_copy.find_all_matches("**/+GeomNode"):
model_node = model.node()
collision_node = CollisionNode(model_node.name)
collision_mesh = collision_root.attach_new_node(collision_node)
collision_mesh.set_mat(model.get_mat())
# collision nodes are hidden by default
collision_mesh.show()
for geom in model_node.modify_geoms():
geom.decompose_in_place()
vertex_data = geom.modify_vertex_data()
vertex_data.format = GeomVertexFormat.get_v3()
view = memoryview(vertex_data.arrays[0]).cast("B").cast("f")
index_list = geom.primitives[0].get_vertex_list()
index_count = len(index_list)
for indices in (index_list[i:i+3] for i in range(0, index_count, 3)):
points = [Point3(*view[index*3:index*3+3]) for index in indices]
coll_poly = CollisionPolygon(*points)
collision_node.add_solid(coll_poly)
base.run()
Please note that this is far from efficient, especially for models with complex geometry!
It is meant to be used in cases where exact collisions take priority over performance and for testing purposes.
In other cases, a simpler collision shape approximating the model geometry is strongly recommended.
Hopefully some of you will find it useful .