Browse Source

Load CollisionBox from egg files

enn0x 12 years ago
parent
commit
a6bdde5f26

+ 5 - 0
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

+ 4 - 0
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);

+ 1 - 0
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 {

+ 86 - 0
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<EggVertex *> 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<EggVertex *>::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

+ 5 - 0
panda/src/egg2pg/eggLoader.h

@@ -166,6 +166,9 @@ private:
   bool make_sphere(EggGroup *start_group, EggGroup::CollideFlags flags,
                    LPoint3 &center, 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,