diff --git a/panda/src/doc/eggSyntax.txt b/panda/src/doc/eggSyntax.txt index a1aafdfeed..7cbf1b228f 100644 --- a/panda/src/doc/eggSyntax.txt +++ b/panda/src/doc/eggSyntax.txt @@ -1499,6 +1499,11 @@ GROUPING ENTRIES The geometry represents a sphere. The vertices in the group are averaged together to determine the sphere's center and radius. + Box + + The geometry represents a box. The smalles axis-alligned box + that will fit around the vertices is used. + InvSphere The geometry represents an inverse sphere. This is the same as diff --git a/panda/src/egg/eggGroup.cxx b/panda/src/egg/eggGroup.cxx index 0234733aed..e0a5f8c736 100644 --- a/panda/src/egg/eggGroup.cxx +++ b/panda/src/egg/eggGroup.cxx @@ -999,6 +999,8 @@ string_cs_type(const string &strval) { return CST_polyset; } else if (cmp_nocase_uh(strval, "sphere") == 0) { return CST_sphere; + } else if (cmp_nocase_uh(strval, "box") == 0) { + return CST_box; } else if (cmp_nocase_uh(strval, "inv-sphere") == 0 || cmp_nocase_uh(strval, "invsphere") == 0) { return CST_inv_sphere; @@ -1494,6 +1496,8 @@ ostream &operator << (ostream &out, EggGroup::CollisionSolidType t) { return out << "Tube"; case EggGroup::CST_floor_mesh: return out << "FloorMesh"; + case EggGroup::CST_box: + return out << "Box"; } nassertr(false, out); diff --git a/panda/src/egg/eggGroup.h b/panda/src/egg/eggGroup.h index c71345e3cf..b3fbb68378 100644 --- a/panda/src/egg/eggGroup.h +++ b/panda/src/egg/eggGroup.h @@ -72,6 +72,7 @@ PUBLISHED: CST_sphere = 0x00040000, CST_tube = 0x00050000, CST_inv_sphere = 0x00060000, + CST_box = 0x00070000, CST_floor_mesh = 0x00080000, }; enum CollideFlags { diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index 2384610ed2..974172f297 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -79,6 +79,7 @@ #include "collisionPlane.h" #include "collisionPolygon.h" #include "collisionFloorMesh.h" +#include "collisionBox.h" #include "parametricCurve.h" #include "nurbsCurve.h" #include "nurbsCurveInterface.h" @@ -2842,6 +2843,67 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags, return success; } +//////////////////////////////////////////////////////////////////// +// Function: EggLoader::make_box +// Access: Private +// Description: Creates a single generic Box corresponding +// to the polygons associated with this group. +// This box is used by make_collision_box. +//////////////////////////////////////////////////////////////////// +bool EggLoader:: +make_box(EggGroup *egg_group, EggGroup::CollideFlags flags, + LPoint3 &_min, LPoint3 &_max, LColor &color) { + bool success=false; + EggGroup *geom_group = find_collision_geometry(egg_group, flags); + if (geom_group != (EggGroup *)NULL) { + // Collect all of the vertices. + pset vertices; + + EggGroup::const_iterator ci; + for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) { + if ((*ci)->is_of_type(EggPrimitive::get_class_type())) { + EggPrimitive *prim = DCAST(EggPrimitive, *ci); + EggPrimitive::const_iterator pi; + for (pi = prim->begin(); pi != prim->end(); ++pi) { + vertices.insert(*pi); + } + } + } + + // Now find the _min/_max points + int num_vertices = 0; + bool first = true; + pset::const_iterator vi; + for (vi = vertices.begin(); vi != vertices.end(); ++vi) { + EggVertex *vtx = (*vi); + LVertexd pos = vtx->get_pos3(); + + if (first) { + _min.set(pos[0], pos[1], pos[2]); + _max.set(pos[0], pos[1], pos[2]); + first = false; + } + else { + _min.set(min(_min[0], pos[0]), + min(_min[1], pos[1]), + min(_min[2], pos[2])); + _max.set(max(_max[0], pos[0]), + max(_max[1], pos[1]), + max(_max[2], pos[2])); + } + num_vertices++; + } + + if (num_vertices > 1) { + vi = vertices.begin(); + EggVertex *clr_vtx = (*vi); + color = clr_vtx->get_color(); + success = true; + } + } + return success; +} + //////////////////////////////////////////////////////////////////// // Function: EggLoader::make_collision_solids // Access: Private @@ -2877,6 +2939,10 @@ make_collision_solids(EggGroup *start_group, EggGroup *egg_group, make_collision_sphere(egg_group, cnode, start_group->get_collide_flags()); break; + case EggGroup::CST_box: + make_collision_box(egg_group, cnode, start_group->get_collide_flags()); + break; + case EggGroup::CST_inv_sphere: make_collision_inv_sphere(egg_group, cnode, start_group->get_collide_flags()); break; @@ -3031,6 +3097,26 @@ make_collision_sphere(EggGroup *egg_group, CollisionNode *cnode, } } +//////////////////////////////////////////////////////////////////// +// Function: EggLoader::make_collision_box +// Access: Private +// Description: Creates a single CollisionBox corresponding +// to the polygons associated with this group. +//////////////////////////////////////////////////////////////////// +void EggLoader:: +make_collision_box(EggGroup *egg_group, CollisionNode *cnode, + EggGroup::CollideFlags flags) { + LPoint3 min; + LPoint3 max; + LColor dummycolor; + if (make_box(egg_group, flags, min, max, dummycolor)) { + CollisionBox *csbox = + new CollisionBox(min, max); + apply_collision_flags(csbox, flags); + cnode->add_solid(csbox); + } +} + //////////////////////////////////////////////////////////////////// // Function: EggLoader::make_collision_inv_sphere // Access: Private diff --git a/panda/src/egg2pg/eggLoader.h b/panda/src/egg2pg/eggLoader.h index b4c91a2e89..df895d13b3 100644 --- a/panda/src/egg2pg/eggLoader.h +++ b/panda/src/egg2pg/eggLoader.h @@ -166,6 +166,9 @@ private: bool make_sphere(EggGroup *start_group, EggGroup::CollideFlags flags, LPoint3 ¢er, PN_stdfloat &radius, LColor &color); + bool make_box(EggGroup *start_group, EggGroup::CollideFlags flags, + LPoint3 &min, LPoint3 &max, LColor &color); + void make_collision_solids(EggGroup *start_group, EggGroup *egg_group, CollisionNode *cnode); void make_collision_plane(EggGroup *egg_group, CollisionNode *cnode, @@ -176,6 +179,8 @@ private: EggGroup::CollideFlags flags); void make_collision_sphere(EggGroup *egg_group, CollisionNode *cnode, EggGroup::CollideFlags flags); + void make_collision_box(EggGroup *egg_group, CollisionNode *cnode, + EggGroup::CollideFlags flags); void make_collision_inv_sphere(EggGroup *egg_group, CollisionNode *cnode, EggGroup::CollideFlags flags); void make_collision_tube(EggGroup *egg_group, CollisionNode *cnode,