Переглянути джерело

use PStats to count number of collision tests

David Rose 20 роки тому
батько
коміт
e3b0ae1bc3

+ 3 - 0
panda/src/collide/Sources.pp

@@ -11,6 +11,7 @@
 
   #define SOURCES \
     collisionEntry.I collisionEntry.h \
+    collisionGeom.I collisionGeom.h \
     collisionHandler.h  \
     collisionHandlerEvent.I collisionHandlerEvent.h  \
     collisionHandlerFloor.I collisionHandlerFloor.h  \
@@ -36,6 +37,7 @@
     
  #define INCLUDED_SOURCES \
     collisionEntry.cxx \
+    collisionGeom.cxx \
     collisionHandler.cxx \
     collisionHandlerEvent.cxx  \
     collisionHandlerFloor.cxx \
@@ -61,6 +63,7 @@
 
   #define INSTALL_HEADERS \
     collisionEntry.I collisionEntry.h \
+    collisionGeom.I collisionGeom.h \
     collisionHandler.h \
     collisionHandlerEvent.I collisionHandlerEvent.h \
     collisionHandlerFloor.I collisionHandlerFloor.h \

+ 1 - 0
panda/src/collide/collide_composite1.cxx

@@ -1,5 +1,6 @@
 #include "config_collide.cxx"
 #include "collisionEntry.cxx"
+#include "collisionGeom.cxx"
 #include "collisionHandler.cxx"
 #include "collisionHandlerEvent.cxx"
 #include "collisionHandlerFloor.cxx"

+ 3 - 0
panda/src/collide/collisionEntry.I

@@ -338,6 +338,9 @@ test_intersection(CollisionHandler *record,
     }
   }
 #endif  // DO_COLLISION_RECORDING
+#ifdef DO_PSTATS
+  ((CollisionSolid *)get_into())->get_test_pcollector().add_level(1);
+#endif  // DO_PSTATS
   if (result != (CollisionEntry *)NULL) {
     record->add_entry(result);
   }

+ 41 - 0
panda/src/collide/collisionGeom.I

@@ -0,0 +1,41 @@
+// Filename: collisionGeom.I
+// Created by:  drose (01Mar06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionGeom::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE CollisionGeom::
+CollisionGeom(const LVecBase3f &a, const LVecBase3f &b,
+              const LVecBase3f &c) :
+  CollisionPolygon(a, b, c)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionGeom::Copy Constructor
+//       Access: Private
+//  Description:
+////////////////////////////////////////////////////////////////////
+CollisionGeom::
+CollisionGeom(const CollisionGeom &copy) :
+  CollisionPolygon(copy)
+{
+}

+ 67 - 0
panda/src/collide/collisionGeom.cxx

@@ -0,0 +1,67 @@
+// Filename: collisionGeom.cxx
+// Created by:  drose (01Mar06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "collisionGeom.h"
+
+PStatCollector CollisionGeom::_volume_pcollector("Collision Volumes:CollisionGeom");
+PStatCollector CollisionGeom::_test_pcollector("Collision Tests:CollisionGeom");
+TypeHandle CollisionGeom::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionGeom::make_copy
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+CollisionSolid *CollisionGeom::
+make_copy() {
+  return new CollisionGeom(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionGeom::get_volume_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of bounding volume tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionGeom::
+get_volume_pcollector() {
+  return _volume_pcollector;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionGeom::get_test_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of intersection tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionGeom::
+get_test_pcollector() {
+  return _test_pcollector;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionGeom::output
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+void CollisionGeom::
+output(ostream &out) const {
+  out << "cgeom";
+}

+ 79 - 0
panda/src/collide/collisionGeom.h

@@ -0,0 +1,79 @@
+// Filename: collisionGeom.h
+// Created by:  drose (01Mar06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef COLLISIONGEOM_H
+#define COLLISIONGEOM_H
+
+#include "pandabase.h"
+
+#include "collisionPolygon.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : CollisionGeom
+// Description : A special CollisionPolygon created just for the
+//               purpose of detecting collision against geometry.
+//               This kind of object does not have any persistance in
+//               the scene graph; it is created on-the-fly.
+//
+//               You should not attempt to create one of these
+//               directly; it is created only by the
+//               CollisionTraverser, as needed.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA CollisionGeom : public CollisionPolygon {
+private:
+  INLINE CollisionGeom(const LVecBase3f &a, const LVecBase3f &b,
+                       const LVecBase3f &c);
+  INLINE CollisionGeom(const CollisionGeom &copy);
+
+public:
+  virtual CollisionSolid *make_copy();
+
+  virtual PStatCollector get_volume_pcollector();
+  virtual PStatCollector get_test_pcollector();
+
+  virtual void output(ostream &out) const;
+
+private:
+  static PStatCollector _volume_pcollector;
+  static PStatCollector _test_pcollector;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    CollisionPolygon::init_type();
+    register_type(_type_handle, "CollisionGeom",
+                  CollisionPolygon::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+
+  friend class CollisionTraverser;
+};
+
+#include "collisionGeom.I"
+
+#endif
+
+

+ 26 - 0
panda/src/collide/collisionInvSphere.cxx

@@ -34,6 +34,8 @@
 #include "geomTristrips.h"
 #include "geomVertexWriter.h"
 
+PStatCollector CollisionInvSphere::_volume_pcollector("Collision Volumes:CollisionInvSphere");
+PStatCollector CollisionInvSphere::_test_pcollector("Collision Tests:CollisionInvSphere");
 TypeHandle CollisionInvSphere::_type_handle;
 
 ////////////////////////////////////////////////////////////////////
@@ -57,6 +59,30 @@ test_intersection(const CollisionEntry &) const {
   return NULL;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionInvSphere::get_volume_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of bounding volume tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionInvSphere::
+get_volume_pcollector() {
+  return _volume_pcollector;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionInvSphere::get_test_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of intersection tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionInvSphere::
+get_test_pcollector() {
+  return _test_pcollector;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionInvSphere::output
 //       Access: Public, Virtual

+ 7 - 0
panda/src/collide/collisionInvSphere.h

@@ -47,6 +47,9 @@ public:
   virtual PT(CollisionEntry)
   test_intersection(const CollisionEntry &entry) const;
 
+  virtual PStatCollector get_volume_pcollector();
+  virtual PStatCollector get_test_pcollector();
+
   virtual void output(ostream &out) const;
 
 protected:
@@ -63,6 +66,10 @@ protected:
 
   virtual void fill_viz_geom();
 
+private:
+  static PStatCollector _volume_pcollector;
+  static PStatCollector _test_pcollector;
+
 public:
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &me);

+ 3 - 0
panda/src/collide/collisionLevelState.cxx

@@ -20,6 +20,8 @@
 #include "collisionSolid.h"
 #include "dcast.h"
 
+PStatCollector CollisionLevelState::_node_volume_pcollector("Collision Volumes:PandaNode");
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionLevelState::clear
 //       Access: Public
@@ -141,6 +143,7 @@ any_in_bounds() {
             get_local_bound(c);
           if (col_gbv != (GeometricBoundingVolume *)NULL) {
             is_in = (node_gbv->contains(col_gbv) != 0);
+            _node_volume_pcollector.add_level(1);
 
 #ifndef NDEBUG
             if (collide_cat.is_spam()) {

+ 3 - 0
panda/src/collide/collisionLevelState.h

@@ -28,6 +28,7 @@
 #include "workingNodePath.h"
 #include "pointerTo.h"
 #include "plist.h"
+#include "pStatCollector.h"
 
 class CollisionSolid;
 class CollisionNode;
@@ -100,6 +101,8 @@ private:
   typedef PTA(CPT(GeometricBoundingVolume)) BoundingVolumes;
   BoundingVolumes _local_bounds;
   BoundingVolumes _parent_bounds;
+
+  static PStatCollector _node_volume_pcollector;
 };
 
 #include "collisionLevelState.I"

+ 26 - 0
panda/src/collide/collisionPlane.cxx

@@ -38,6 +38,8 @@
 #include "geomLinestrips.h"
 #include "geomVertexWriter.h"
 
+PStatCollector CollisionPlane::_volume_pcollector("Collision Volumes:CollisionPlane");
+PStatCollector CollisionPlane::_test_pcollector("Collision Tests:CollisionPlane");
 TypeHandle CollisionPlane::_type_handle;
 
 ////////////////////////////////////////////////////////////////////
@@ -77,6 +79,30 @@ get_collision_origin() const {
   return LPoint3f::origin();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionPlane::get_volume_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of bounding volume tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionPlane::
+get_volume_pcollector() {
+  return _volume_pcollector;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionPlane::get_test_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of intersection tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionPlane::
+get_test_pcollector() {
+  return _test_pcollector;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionPlane::output
 //       Access: Public, Virtual

+ 6 - 0
panda/src/collide/collisionPlane.h

@@ -44,6 +44,9 @@ public:
   virtual void xform(const LMatrix4f &mat);
   virtual LPoint3f get_collision_origin() const;
 
+  virtual PStatCollector get_volume_pcollector();
+  virtual PStatCollector get_test_pcollector();
+
   virtual void output(ostream &out) const;
 
 PUBLISHED:
@@ -71,6 +74,9 @@ protected:
 private:
   Planef _plane;
 
+  static PStatCollector _volume_pcollector;
+  static PStatCollector _test_pcollector;
+
 public:
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter* manager, Datagram &me);

+ 26 - 2
panda/src/collide/collisionPolygon.cxx

@@ -44,10 +44,10 @@
 
 #include <algorithm>
 
+PStatCollector CollisionPolygon::_volume_pcollector("Collision Volumes:CollisionPolygon");
+PStatCollector CollisionPolygon::_test_pcollector("Collision Tests:CollisionPolygon");
 TypeHandle CollisionPolygon::_type_handle;
 
-
-
 ////////////////////////////////////////////////////////////////////
 //     Function: is_right
 //  Description: Returns true if the 2-d v1 is to the right of v2.
@@ -322,6 +322,30 @@ get_viz(const CullTraverser *trav, const CullTraverserData &data,
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionPolygon::get_volume_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of bounding volume tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionPolygon::
+get_volume_pcollector() {
+  return _volume_pcollector;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionPolygon::get_test_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of intersection tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionPolygon::
+get_test_pcollector() {
+  return _test_pcollector;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionPolygon::output
 //       Access: Public, Virtual

+ 6 - 0
panda/src/collide/collisionPolygon.h

@@ -65,6 +65,9 @@ public:
                                 const CullTraverserData &data,
                                 bool bounds_only) const;
 
+  virtual PStatCollector get_volume_pcollector();
+  virtual PStatCollector get_test_pcollector();
+
   virtual void output(ostream &out) const;
   virtual void write(ostream &out, int indent_level = 0) const;
 
@@ -118,6 +121,9 @@ private:
   Points _points;
   LMatrix4f _to_2d_mat;
 
+  static PStatCollector _volume_pcollector;
+  static PStatCollector _test_pcollector;
+
 public:
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter* manager, Datagram &me);

+ 26 - 0
panda/src/collide/collisionSolid.cxx

@@ -34,6 +34,8 @@
 #include "transparencyAttrib.h"
 #include "geomNode.h"
 
+PStatCollector CollisionSolid::_volume_pcollector("Collision Volumes:CollisionSolid");
+PStatCollector CollisionSolid::_test_pcollector("Collision Tests:CollisionSolid");
 TypeHandle CollisionSolid::_type_handle;
 
 ////////////////////////////////////////////////////////////////////
@@ -145,6 +147,30 @@ get_viz(const CullTraverser *, const CullTraverserData &, bool bounds_only) cons
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionSolid::get_volume_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of bounding volume tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionSolid::
+get_volume_pcollector() {
+  return _volume_pcollector;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionSolid::get_test_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of intersection tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionSolid::
+get_test_pcollector() {
+  return _test_pcollector;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionSolid::output
 //       Access: Public, Virtual

+ 7 - 0
panda/src/collide/collisionSolid.h

@@ -29,6 +29,7 @@
 #include "geomNode.h"
 #include "pmutex.h"
 #include "mutexHolder.h"
+#include "pStatCollector.h"
 
 class CollisionHandler;
 class CollisionEntry;
@@ -83,6 +84,9 @@ public:
                                 const CullTraverserData &data,
                                 bool bounds_only) const;
 
+  virtual PStatCollector get_volume_pcollector();
+  virtual PStatCollector get_test_pcollector();
+
 PUBLISHED:
   virtual void output(ostream &out) const;
   virtual void write(ostream &out, int indent_level = 0) const;
@@ -134,6 +138,9 @@ private:
 
   Mutex _lock;
 
+  static PStatCollector _volume_pcollector;
+  static PStatCollector _test_pcollector;
+
 public:
   virtual void write_datagram(BamWriter* manager, Datagram &me);
 

+ 26 - 0
panda/src/collide/collisionSphere.cxx

@@ -36,6 +36,8 @@
 #include "geomTristrips.h"
 #include "geomVertexWriter.h"
 
+PStatCollector CollisionSphere::_volume_pcollector("Collision Volumes:CollisionSphere");
+PStatCollector CollisionSphere::_test_pcollector("Collision Tests:CollisionSphere");
 TypeHandle CollisionSphere::_type_handle;
 
 ////////////////////////////////////////////////////////////////////
@@ -88,6 +90,30 @@ get_collision_origin() const {
   return get_center();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionSphere::get_volume_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of bounding volume tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionSphere::
+get_volume_pcollector() {
+  return _volume_pcollector;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionSphere::get_test_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of intersection tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionSphere::
+get_test_pcollector() {
+  return _test_pcollector;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionSphere::output
 //       Access: Public, Virtual

+ 6 - 0
panda/src/collide/collisionSphere.h

@@ -45,6 +45,9 @@ public:
   virtual void xform(const LMatrix4f &mat);
   virtual LPoint3f get_collision_origin() const;
 
+  virtual PStatCollector get_volume_pcollector();
+  virtual PStatCollector get_test_pcollector();
+
   virtual void output(ostream &out) const;
 
 PUBLISHED:
@@ -78,6 +81,9 @@ private:
   LPoint3f _center;
   float _radius;
 
+  static PStatCollector _volume_pcollector;
+  static PStatCollector _test_pcollector;
+
 public:
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &me);

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

@@ -20,6 +20,7 @@
 #include "collisionNode.h"
 #include "collisionEntry.h"
 #include "collisionPolygon.h"
+#include "collisionGeom.h"
 #include "collisionRecorder.h"
 #include "collisionVisualizer.h"
 #include "config_collide.h"
@@ -38,6 +39,10 @@
 PStatCollector CollisionTraverser::_collisions_pcollector("App:Collisions");
 PStatCollector CollisionTraverser::_reset_prev_pcollector("App:Collisions:Reset");
 
+PStatCollector CollisionTraverser::_cnode_volume_pcollector("Collision Volumes:CollisionNode");
+PStatCollector CollisionTraverser::_gnode_volume_pcollector("Collision Volumes:GeomNode");
+PStatCollector CollisionTraverser::_geom_volume_pcollector("Collision Volumes:Geom");
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::Constructor
 //       Access: Published
@@ -642,6 +647,7 @@ compare_collider_to_node(CollisionEntry &entry,
   if (from_parent_gbv != (GeometricBoundingVolume *)NULL &&
       into_node_gbv != (GeometricBoundingVolume *)NULL) {
     within_node_bounds = (into_node_gbv->contains(from_parent_gbv) != 0);
+    _cnode_volume_pcollector.add_level(1);
   }
 
   if (within_node_bounds) {
@@ -683,6 +689,7 @@ compare_collider_to_geom_node(CollisionEntry &entry,
   if (from_parent_gbv != (GeometricBoundingVolume *)NULL &&
       into_node_gbv != (GeometricBoundingVolume *)NULL) {
     within_node_bounds = (into_node_gbv->contains(from_parent_gbv) != 0);
+    _gnode_volume_pcollector.add_level(1);
   }
 
   if (within_node_bounds) {
@@ -724,6 +731,9 @@ compare_collider_to_solid(CollisionEntry &entry,
   if (from_node_gbv != (GeometricBoundingVolume *)NULL &&
       solid_gbv != (GeometricBoundingVolume *)NULL) {
     within_solid_bounds = (solid_gbv->contains(from_node_gbv) != 0);
+#ifdef DO_PSTATS
+    ((CollisionSolid *)entry.get_into())->get_volume_pcollector().add_level(1);
+#endif  // DO_PSTATS
   }
   if (within_solid_bounds) {
     Colliders::const_iterator ci;
@@ -746,6 +756,7 @@ compare_collider_to_geom(CollisionEntry &entry, const Geom *geom,
   if (from_node_gbv != (GeometricBoundingVolume *)NULL &&
       geom_gbv != (GeometricBoundingVolume *)NULL) {
     within_geom_bounds = (geom_gbv->contains(from_node_gbv) != 0);
+    _geom_volume_pcollector.add_level(1);
   }
   if (within_geom_bounds) {
     Colliders::const_iterator ci;
@@ -765,18 +776,32 @@ compare_collider_to_geom(CollisionEntry &entry, const Geom *geom,
         nassertv((num_vertices % 3) == 0);
         
         for (int vi = 0; vi < num_vertices; vi += 3) {
+          Vertexf v[3];
+
           vertex.set_row(tris->get_vertex(vi));
-          Vertexf v0 = vertex.get_data3f();
+          v[0] = vertex.get_data3f();
           vertex.set_row(tris->get_vertex(vi + 1));
-          Vertexf v1 = vertex.get_data3f();
+          v[1] = vertex.get_data3f();
           vertex.set_row(tris->get_vertex(vi + 2));
-          Vertexf v2 = vertex.get_data3f();
+          v[2] = vertex.get_data3f();
           
-          // Generate a temporary CollisionPolygon on the fly for
-          // each triangle in the Geom.
-          if (CollisionPolygon::verify_points(v0, v1, v2)) {
-            entry._into = new CollisionPolygon(v0, v1, v2);
-            entry.test_intersection((*ci).second, this);
+          // Generate a temporary CollisionGeom on the fly for each
+          // triangle in the Geom.
+          if (CollisionPolygon::verify_points(v[0], v[1], v[2])) {
+            bool within_solid_bounds = true;
+            if (from_node_gbv != (GeometricBoundingVolume *)NULL) {
+              PT(BoundingSphere) sphere = new BoundingSphere;
+              sphere->around(v, v + 3);
+              within_solid_bounds = (sphere->contains(from_node_gbv) != 0);
+#ifdef DO_PSTATS
+              CollisionGeom::_volume_pcollector.add_level(1);
+#endif  // DO_PSTATS
+            }
+            if (within_solid_bounds) {
+              PT(CollisionGeom) cgeom = new CollisionGeom(v[0], v[1], v[2]);
+              entry._into = cgeom;
+              entry.test_intersection((*ci).second, this);
+            }
           }
         }
       }

+ 5 - 0
panda/src/collide/collisionTraverser.h

@@ -135,6 +135,11 @@ private:
   // Statistics
   static PStatCollector _collisions_pcollector;
   static PStatCollector _reset_prev_pcollector;
+
+  static PStatCollector _cnode_volume_pcollector;
+  static PStatCollector _gnode_volume_pcollector;
+  static PStatCollector _geom_volume_pcollector;
+
   PStatCollector _this_pcollector;
   typedef pvector<PStatCollector> PassCollectors;
   PassCollectors _pass_collectors;

+ 26 - 1
panda/src/collide/collisionTube.cxx

@@ -38,9 +38,10 @@
 #include "geomTristrips.h"
 #include "geomVertexWriter.h"
 
+PStatCollector CollisionTube::_volume_pcollector("Collision Volumes:CollisionTube");
+PStatCollector CollisionTube::_test_pcollector("Collision Tests:CollisionTube");
 TypeHandle CollisionTube::_type_handle;
 
-
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTube::make_copy
 //       Access: Public, Virtual
@@ -83,6 +84,30 @@ get_collision_origin() const {
   return get_point_a();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionTube::get_volume_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of bounding volume tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionTube::
+get_volume_pcollector() {
+  return _volume_pcollector;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionTube::get_test_pcollector
+//       Access: Public, Virtual
+//  Description: Returns a PStatCollector that is used to count the
+//               number of intersection tests made against a solid
+//               of this type in a given frame.
+////////////////////////////////////////////////////////////////////
+PStatCollector CollisionTube::
+get_test_pcollector() {
+  return _test_pcollector;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTube::output
 //       Access: Public, Virtual

+ 6 - 0
panda/src/collide/collisionTube.h

@@ -49,6 +49,9 @@ public:
   virtual void xform(const LMatrix4f &mat);
   virtual LPoint3f get_collision_origin() const;
 
+  virtual PStatCollector get_volume_pcollector();
+  virtual PStatCollector get_test_pcollector();
+
   virtual void output(ostream &out) const;
 
 PUBLISHED:
@@ -104,6 +107,9 @@ private:
   LMatrix4f _inv_mat;
   float _length;
 
+  static PStatCollector _volume_pcollector;
+  static PStatCollector _test_pcollector;
+
 public:
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &dg);

+ 44 - 0
panda/src/display/graphicsEngine.cxx

@@ -64,6 +64,27 @@ PStatCollector GraphicsEngine::_render_states_unused_pcollector("RenderStates:Un
 PStatCollector GraphicsEngine::_cyclers_pcollector("PipelineCyclers");
 PStatCollector GraphicsEngine::_dirty_cyclers_pcollector("Dirty PipelineCyclers");
 
+// These are counted independently by the collision system; we
+// redefine them here so we can reset them at each frame.
+PStatCollector GraphicsEngine::_cnode_volume_pcollector("Collision Volumes:CollisionNode");
+PStatCollector GraphicsEngine::_gnode_volume_pcollector("Collision Volumes:GeomNode");
+PStatCollector GraphicsEngine::_geom_volume_pcollector("Collision Volumes:Geom");
+PStatCollector GraphicsEngine::_node_volume_pcollector("Collision Volumes:PandaNode");
+PStatCollector GraphicsEngine::_volume_pcollector("Collision Volumes:CollisionSolid");
+PStatCollector GraphicsEngine::_test_pcollector("Collision Tests:CollisionSolid");
+PStatCollector GraphicsEngine::_volume_polygon_pcollector("Collision Volumes:CollisionPolygon");
+PStatCollector GraphicsEngine::_test_polygon_pcollector("Collision Tests:CollisionPolygon");
+PStatCollector GraphicsEngine::_volume_plane_pcollector("Collision Volumes:CollisionPlane");
+PStatCollector GraphicsEngine::_test_plane_pcollector("Collision Tests:CollisionPlane");
+PStatCollector GraphicsEngine::_volume_sphere_pcollector("Collision Volumes:CollisionSphere");
+PStatCollector GraphicsEngine::_test_sphere_pcollector("Collision Tests:CollisionSphere");
+PStatCollector GraphicsEngine::_volume_tube_pcollector("Collision Volumes:CollisionTube");
+PStatCollector GraphicsEngine::_test_tube_pcollector("Collision Tests:CollisionTube");
+PStatCollector GraphicsEngine::_volume_inv_sphere_pcollector("Collision Volumes:CollisionInvSphere");
+PStatCollector GraphicsEngine::_test_inv_sphere_pcollector("Collision Tests:CollisionInvSphere");
+PStatCollector GraphicsEngine::_volume_geom_pcollector("Collision Volumes:CollisionGeom");
+PStatCollector GraphicsEngine::_test_geom_pcollector("Collision Tests:CollisionGeom");
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsEngine::Constructor
 //       Access: Published
@@ -568,6 +589,8 @@ render_frame() {
   if (global_clock->check_errors()) {
     throw_event("clock_error");
   }
+
+#ifdef DO_PSTATS
   PStatClient::main_tick();
 
   // Reset our pcollectors that track data across the frame.
@@ -586,6 +609,27 @@ render_frame() {
     _render_states_unused_pcollector.set_level(RenderState::get_num_unused_states());
   }
 
+  _cnode_volume_pcollector.clear_level();
+  _gnode_volume_pcollector.clear_level();
+  _geom_volume_pcollector.clear_level();
+  _node_volume_pcollector.clear_level();
+  _volume_pcollector.clear_level();
+  _test_pcollector.clear_level();
+  _volume_polygon_pcollector.clear_level();
+  _test_polygon_pcollector.clear_level();
+  _volume_plane_pcollector.clear_level();
+  _test_plane_pcollector.clear_level();
+  _volume_sphere_pcollector.clear_level();
+  _test_sphere_pcollector.clear_level();
+  _volume_tube_pcollector.clear_level();
+  _test_tube_pcollector.clear_level();
+  _volume_inv_sphere_pcollector.clear_level();
+  _test_inv_sphere_pcollector.clear_level();
+  _volume_geom_pcollector.clear_level();
+  _test_geom_pcollector.clear_level();
+
+#endif  // DO_PSTATS
+
   // Now signal all of our threads to begin their next frame.
   Threads::const_iterator ti;
   for (ti = _threads.begin(); ti != _threads.end(); ++ti) {

+ 19 - 0
panda/src/display/graphicsEngine.h

@@ -269,6 +269,25 @@ private:
   static PStatCollector _cyclers_pcollector;
   static PStatCollector _dirty_cyclers_pcollector;
 
+  static PStatCollector _cnode_volume_pcollector;
+  static PStatCollector _gnode_volume_pcollector;
+  static PStatCollector _geom_volume_pcollector;
+  static PStatCollector _node_volume_pcollector;
+  static PStatCollector _volume_pcollector;
+  static PStatCollector _test_pcollector;
+  static PStatCollector _volume_polygon_pcollector;
+  static PStatCollector _test_polygon_pcollector;
+  static PStatCollector _volume_plane_pcollector;
+  static PStatCollector _test_plane_pcollector;
+  static PStatCollector _volume_sphere_pcollector;
+  static PStatCollector _test_sphere_pcollector;
+  static PStatCollector _volume_tube_pcollector;
+  static PStatCollector _test_tube_pcollector;
+  static PStatCollector _volume_inv_sphere_pcollector;
+  static PStatCollector _test_inv_sphere_pcollector;
+  static PStatCollector _volume_geom_pcollector;
+  static PStatCollector _test_geom_pcollector;
+
   friend class WindowRenderer;
   friend class GraphicsOutput;
 };

+ 2 - 0
panda/src/pstatclient/pStatProperties.cxx

@@ -214,6 +214,8 @@ static LevelCollectorProperties level_properties[] = {
   { 1, "RenderStates:Unused",              { 0.2, 0.2, 0.2 } },
   { 1, "PipelineCyclers",                  { 0.5, 0.5, 1.0 },  "", 50000 },
   { 1, "Dirty PipelineCyclers",            { 0.2, 0.2, 0.2 },  "", 5000 },
+  { 1, "Collision Volumes",                { 1.0, 0.8, 0.5 },  "", 500 },
+  { 1, "Collision Tests",                  { 0.5, 0.8, 1.0 },  "", 100 },
   { 0, NULL }
 };