瀏覽代碼

Fix incorrect transformation of CollisionBox loaded from .egg file

rdb 11 年之前
父節點
當前提交
79d025e9a8
共有 2 個文件被更改,包括 75 次插入47 次删除
  1. 46 19
      panda/src/collide/collisionBox.cxx
  2. 29 28
      panda/src/egg2pg/eggLoader.cxx

+ 46 - 19
panda/src/collide/collisionBox.cxx

@@ -29,7 +29,7 @@
 #include "cmath.h"
 #include "mathNumbers.h"
 #include "geom.h"
-#include "geomTrifans.h"
+#include "geomTriangles.h"
 #include "geomVertexWriter.h"
 #include "config_mathutil.h"
 #include "dcast.h"
@@ -80,7 +80,7 @@ setup_box(){
 //     Function: CollisionBox::setup_points
 //       Access: Private
 //  Description: Computes the plane and 2d projection of points that
-//               make up this side          
+//               make up this side.
 ////////////////////////////////////////////////////////////////////
 void CollisionBox::
 setup_points(const LPoint3 *begin, const LPoint3 *end, int plane) {
@@ -552,7 +552,7 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
   PN_stdfloat near_t = 0.0;
   bool intersect;
   LPlane plane;
-  LPlane near_plane; 
+  LPlane near_plane;
 
   //Returns the details about the first plane of the box that the
   //segment intersects.
@@ -589,7 +589,6 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
     }
     ++j;
   }
-   
 
   if(!intersect) {
     //No intersection with ANY of the box's planes has been detected
@@ -645,22 +644,50 @@ fill_viz_geom() {
   PT(GeomVertexData) vdata = new GeomVertexData
     ("collision", GeomVertexFormat::get_v3(),
      Geom::UH_static);
-  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
-  
-  for(int i = 0; i < 6; i++) {
-    for(int j = 0; j < 4; j++)
-      vertex.add_data3(get_point(plane_def[i][j]));
 
-    PT(GeomTrifans) body = new GeomTrifans(Geom::UH_static);
-    body->add_consecutive_vertices(i*4, 4);
-    body->close_primitive();
+  vdata->unclean_set_num_rows(8);
 
-    PT(Geom) geom = new Geom(vdata);
-    geom->add_primitive(body);
+  {
+    GeomVertexWriter vertex(vdata, InternalName::get_vertex());
+    vertex.set_data3(_min[0], _min[1], _min[2]);
+    vertex.set_data3(_min[0], _max[1], _min[2]);
+    vertex.set_data3(_max[0], _max[1], _min[2]);
+    vertex.set_data3(_max[0], _min[1], _min[2]);
 
-    _viz_geom->add_geom(geom, get_solid_viz_state());
-    _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state());
+    vertex.set_data3(_min[0], _min[1], _max[2]);
+    vertex.set_data3(_min[0], _max[1], _max[2]);
+    vertex.set_data3(_max[0], _max[1], _max[2]);
+    vertex.set_data3(_max[0], _min[1], _max[2]);
   }
+
+  PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static);
+
+  // Bottom
+  tris->add_vertices(0, 1, 2);
+  tris->add_vertices(2, 3, 0);
+
+  // Top
+  tris->add_vertices(4, 7, 6);
+  tris->add_vertices(6, 5, 4);
+
+  // Sides
+  tris->add_vertices(0, 4, 1);
+  tris->add_vertices(1, 4, 5);
+
+  tris->add_vertices(1, 5, 2);
+  tris->add_vertices(2, 5, 6);
+
+  tris->add_vertices(2, 6, 3);
+  tris->add_vertices(3, 6, 7);
+
+  tris->add_vertices(3, 7, 0);
+  tris->add_vertices(0, 7, 4);
+
+  PT(Geom) geom = new Geom(vdata);
+  geom->add_primitive(tris);
+
+  _viz_geom->add_geom(geom, get_solid_viz_state());
+  _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state());
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -675,7 +702,7 @@ fill_viz_geom() {
 //               planes), or false otherwise.
 ////////////////////////////////////////////////////////////////////
 bool CollisionBox::
-apply_clip_plane(CollisionBox::Points &new_points, 
+apply_clip_plane(CollisionBox::Points &new_points,
                  const ClipPlaneAttrib *cpa,
                  const TransformState *net_transform, int plane_no) const {
   bool all_in = true;
@@ -687,9 +714,9 @@ apply_clip_plane(CollisionBox::Points &new_points,
     NodePath plane_path = cpa->get_on_plane(i);
     PlaneNode *plane_node = DCAST(PlaneNode, plane_path.node());
     if ((plane_node->get_clip_effect() & PlaneNode::CE_collision) != 0) {
-      CPT(TransformState) new_transform = 
+      CPT(TransformState) new_transform =
         net_transform->invert_compose(plane_path.get_net_transform());
-      
+
       LPlane plane = plane_node->get_plane() * new_transform->get_mat();
       if (first_plane) {
         first_plane = false;

+ 29 - 28
panda/src/egg2pg/eggLoader.cxx

@@ -2855,9 +2855,8 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
 //               This box is used by make_collision_box.
 ////////////////////////////////////////////////////////////////////
 bool EggLoader::
-make_box(EggGroup *egg_group, EggGroup::CollideFlags flags, 
-            LPoint3 &min_p, LPoint3 &max_p, LColor &color) {
-  bool success = false;
+make_box(EggGroup *egg_group, EggGroup::CollideFlags flags,
+         LPoint3 &min_p, LPoint3 &max_p, LColor &color) {
   EggGroup *geom_group = find_collision_geometry(egg_group, flags);
   if (geom_group != (EggGroup *)NULL) {
     // Collect all of the vertices.
@@ -2875,36 +2874,38 @@ make_box(EggGroup *egg_group, EggGroup::CollideFlags flags,
     }
 
     // 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);
-      LVertex pos = LCAST(PN_stdfloat, vtx->get_pos3());
+    vi = vertices.begin();
 
-      if (first) {
-        min_p.set(pos[0], pos[1], pos[2]);
-        max_p.set(pos[0], pos[1], pos[2]);
-        first = false;
-      } else {
-        min_p.set(min(min_p[0], pos[0]),
-                  min(min_p[1], pos[1]),
-                  min(min_p[2], pos[2]));
-        max_p.set(max(max_p[0], pos[0]),
-                  max(max_p[1], pos[1]),
-                  max(max_p[2], pos[2]));
-      }
-      num_vertices++;
+    if (vi == vertices.end()) {
+      // No vertices, no bounding box.
+      min_p.set(0, 0, 0);
+      max_p.set(0, 0, 0);
+      return false;
     }
 
-    if (num_vertices > 1) {
-      vi = vertices.begin();
-      EggVertex *clr_vtx = (*vi);
-      color = clr_vtx->get_color();
-      success = true;
-    }
+    EggVertex *vertex = (*vi);
+    LVertexd min_pd = vertex->get_pos3();
+    LVertexd max_pd = min_pd;
+    color = vertex->get_color();
+
+    for (++vi; vi != vertices.end(); ++vi) {
+      vertex = (*vi);
+      const LVertexd &pos = vertex->get_pos3();
+      min_pd.set(min(min_pd[0], pos[0]),
+                 min(min_pd[1], pos[1]),
+                 min(min_pd[2], pos[2]));
+      max_pd.set(max(max_pd[0], pos[0]),
+                 max(max_pd[1], pos[1]),
+                 max(max_pd[2], pos[2]));
+    }
+
+    LMatrix4d mat = egg_group->get_vertex_to_node();
+    min_p = LCAST(PN_stdfloat, min_pd * mat);
+    max_p = LCAST(PN_stdfloat, max_pd * mat);
+    return (min_pd != max_pd);
   }
-  return success;
+  return false;
 }
 
 ////////////////////////////////////////////////////////////////////