Browse Source

collide: improve performance of colliding with visible geometry

rdb 5 years ago
parent
commit
94571aac93

+ 0 - 15
panda/src/collide/collisionPolygon.I

@@ -73,21 +73,6 @@ get_point(size_t n) const {
   return to_3d(_points[n]._p, to_3d_mat);
   return to_3d(_points[n]._p, to_3d_mat);
 }
 }
 
 
-/**
- * Verifies that the indicated set of points will define a valid
- * CollisionPolygon: that is, at least three non-collinear points, with no
- * points repeated.
- */
-INLINE bool CollisionPolygon::
-verify_points(const LPoint3 &a, const LPoint3 &b,
-              const LPoint3 &c) {
-  LPoint3 array[3];
-  array[0] = a;
-  array[1] = b;
-  array[2] = c;
-  return verify_points(array, array + 3);
-}
-
 /**
 /**
  * Verifies that the indicated set of points will define a valid
  * Verifies that the indicated set of points will define a valid
  * CollisionPolygon: that is, at least three non-collinear points, with no
  * CollisionPolygon: that is, at least three non-collinear points, with no

+ 17 - 0
panda/src/collide/collisionPolygon.cxx

@@ -69,6 +69,23 @@ make_copy() {
   return new CollisionPolygon(*this);
   return new CollisionPolygon(*this);
 }
 }
 
 
+/**
+ * Verifies that the indicated set of points will define a valid
+ * CollisionPolygon: that is, at least three non-collinear points, with no
+ * points repeated.
+ */
+bool CollisionPolygon::
+verify_points(const LPoint3 &a, const LPoint3 &b, const LPoint3 &c) {
+  // First, check for repeated or invalid points.
+  if (a.is_nan() || b.is_nan() || c.is_nan() || a == b || b == c || a == c) {
+    return false;
+  }
+
+  // Check that the vectors ab and ac are not colinear.
+  LVector3 normal = ::cross(b - a, c - a);
+  return normal.length_squared() != (PN_stdfloat)0.0f;
+}
+
 /**
 /**
  * Verifies that the indicated set of points will define a valid
  * Verifies that the indicated set of points will define a valid
  * CollisionPolygon: that is, at least three non-collinear points, with no
  * CollisionPolygon: that is, at least three non-collinear points, with no

+ 1 - 2
panda/src/collide/collisionPolygon.h

@@ -50,10 +50,9 @@ PUBLISHED:
   MAKE_SEQ(get_points, get_num_points, get_point);
   MAKE_SEQ(get_points, get_num_points, get_point);
 
 
 
 
-  INLINE static bool verify_points(const LPoint3 &a, const LPoint3 &b,
-                                   const LPoint3 &c);
   INLINE static bool verify_points(const LPoint3 &a, const LPoint3 &b,
   INLINE static bool verify_points(const LPoint3 &a, const LPoint3 &b,
                                    const LPoint3 &c, const LPoint3 &d);
                                    const LPoint3 &c, const LPoint3 &d);
+  static bool verify_points(const LPoint3 &a, const LPoint3 &b, const LPoint3 &c);
   static bool verify_points(const LPoint3 *begin, const LPoint3 *end);
   static bool verify_points(const LPoint3 *begin, const LPoint3 *end);
 
 
   bool is_valid() const;
   bool is_valid() const;

+ 8 - 8
panda/src/collide/collisionTraverser.cxx

@@ -1289,15 +1289,15 @@ compare_collider_to_geom(CollisionEntry &entry, const Geom *geom,
             if (CollisionPolygon::verify_points(v[0], v[1], v[2])) {
             if (CollisionPolygon::verify_points(v[0], v[1], v[2])) {
               bool within_solid_bounds = true;
               bool within_solid_bounds = true;
               if (from_node_gbv != nullptr) {
               if (from_node_gbv != nullptr) {
-                PT(BoundingSphere) sphere = new BoundingSphere;
-                sphere->around(v, v + 3);
-                within_solid_bounds = (sphere->contains(from_node_gbv) != 0);
+                BoundingSphere sphere;
+                sphere.around(v, v + 3);
+                within_solid_bounds = (sphere.contains(from_node_gbv) != 0);
 #ifdef DO_PSTATS
 #ifdef DO_PSTATS
                 CollisionGeom::_volume_pcollector.add_level(1);
                 CollisionGeom::_volume_pcollector.add_level(1);
 #endif  // DO_PSTATS
 #endif  // DO_PSTATS
               }
               }
               if (within_solid_bounds) {
               if (within_solid_bounds) {
-                PT(CollisionGeom) cgeom = new CollisionGeom(LVecBase3(v[0]), LVecBase3(v[1]), LVecBase3(v[2]));
+                PT(CollisionGeom) cgeom = new CollisionGeom(v[0], v[1], v[2]);
                 entry._into = cgeom;
                 entry._into = cgeom;
                 entry.test_intersection((*ci).second, this);
                 entry.test_intersection((*ci).second, this);
               }
               }
@@ -1319,15 +1319,15 @@ compare_collider_to_geom(CollisionEntry &entry, const Geom *geom,
             if (CollisionPolygon::verify_points(v[0], v[1], v[2])) {
             if (CollisionPolygon::verify_points(v[0], v[1], v[2])) {
               bool within_solid_bounds = true;
               bool within_solid_bounds = true;
               if (from_node_gbv != nullptr) {
               if (from_node_gbv != nullptr) {
-                PT(BoundingSphere) sphere = new BoundingSphere;
-                sphere->around(v, v + 3);
-                within_solid_bounds = (sphere->contains(from_node_gbv) != 0);
+                BoundingSphere sphere;
+                sphere.around(v, v + 3);
+                within_solid_bounds = (sphere.contains(from_node_gbv) != 0);
 #ifdef DO_PSTATS
 #ifdef DO_PSTATS
                 CollisionGeom::_volume_pcollector.add_level(1);
                 CollisionGeom::_volume_pcollector.add_level(1);
 #endif  // DO_PSTATS
 #endif  // DO_PSTATS
               }
               }
               if (within_solid_bounds) {
               if (within_solid_bounds) {
-                PT(CollisionGeom) cgeom = new CollisionGeom(LVecBase3(v[0]), LVecBase3(v[1]), LVecBase3(v[2]));
+                PT(CollisionGeom) cgeom = new CollisionGeom(v[0], v[1], v[2]);
                 entry._into = cgeom;
                 entry._into = cgeom;
                 entry.test_intersection((*ci).second, this);
                 entry.test_intersection((*ci).second, this);
               }
               }