Panda3D
|
00001 // Filename: collisionTraverser.h 00002 // Created by: drose (16Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef COLLISIONTRAVERSER_H 00016 #define COLLISIONTRAVERSER_H 00017 00018 #include "pandabase.h" 00019 00020 #include "collisionHandler.h" 00021 #include "collisionLevelState.h" 00022 00023 #include "pointerTo.h" 00024 #include "pStatCollector.h" 00025 00026 #include "pset.h" 00027 #include "register_type.h" 00028 00029 class CollisionNode; 00030 class CollisionRecorder; 00031 class CollisionVisualizer; 00032 class Geom; 00033 class NodePath; 00034 class CollisionEntry; 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Class : CollisionTraverser 00038 // Description : This class manages the traversal through the scene 00039 // graph to detect collisions. It holds ownership of a 00040 // number of collider objects, each of which is a 00041 // CollisionNode and an associated CollisionHandler. 00042 // 00043 // When traverse() is called, it begins at the indicated 00044 // root and detects all collisions with any of its 00045 // collider objects against nodes at or below the 00046 // indicated root, calling the appropriate 00047 // CollisionHandler for each detected collision. 00048 //////////////////////////////////////////////////////////////////// 00049 class EXPCL_PANDA_COLLIDE CollisionTraverser : public Namable { 00050 PUBLISHED: 00051 CollisionTraverser(const string &name = "ctrav"); 00052 ~CollisionTraverser(); 00053 00054 INLINE void set_respect_prev_transform(bool flag); 00055 INLINE bool get_respect_prev_transform() const; 00056 00057 void add_collider(const NodePath &collider, CollisionHandler *handler); 00058 bool remove_collider(const NodePath &collider); 00059 bool has_collider(const NodePath &collider) const; 00060 int get_num_colliders() const; 00061 NodePath get_collider(int n) const; 00062 MAKE_SEQ(get_colliders, get_num_colliders, get_collider); 00063 CollisionHandler *get_handler(const NodePath &collider) const; 00064 void clear_colliders(); 00065 00066 void traverse(const NodePath &root); 00067 00068 #ifdef DO_COLLISION_RECORDING 00069 void set_recorder(CollisionRecorder *recorder); 00070 INLINE bool has_recorder() const; 00071 INLINE CollisionRecorder *get_recorder() const; 00072 INLINE void clear_recorder(); 00073 00074 CollisionVisualizer *show_collisions(const NodePath &root); 00075 void hide_collisions(); 00076 #endif // DO_COLLISION_RECORDING 00077 00078 void output(ostream &out) const; 00079 void write(ostream &out, int indent_level) const; 00080 00081 private: 00082 typedef pvector<CollisionLevelStateSingle> LevelStatesSingle; 00083 void prepare_colliders_single(LevelStatesSingle &level_states, const NodePath &root); 00084 void r_traverse_single(CollisionLevelStateSingle &level_state, size_t pass); 00085 00086 typedef pvector<CollisionLevelStateDouble> LevelStatesDouble; 00087 void prepare_colliders_double(LevelStatesDouble &level_states, const NodePath &root); 00088 void r_traverse_double(CollisionLevelStateDouble &level_state, size_t pass); 00089 00090 typedef pvector<CollisionLevelStateQuad> LevelStatesQuad; 00091 void prepare_colliders_quad(LevelStatesQuad &level_states, const NodePath &root); 00092 void r_traverse_quad(CollisionLevelStateQuad &level_state, size_t pass); 00093 00094 void compare_collider_to_node(CollisionEntry &entry, 00095 const GeometricBoundingVolume *from_parent_gbv, 00096 const GeometricBoundingVolume *from_node_gbv, 00097 const GeometricBoundingVolume *into_node_gbv); 00098 void compare_collider_to_geom_node(CollisionEntry &entry, 00099 const GeometricBoundingVolume *from_parent_gbv, 00100 const GeometricBoundingVolume *from_node_gbv, 00101 const GeometricBoundingVolume *into_node_gbv); 00102 void compare_collider_to_solid(CollisionEntry &entry, 00103 const GeometricBoundingVolume *from_node_gbv, 00104 const GeometricBoundingVolume *solid_gbv); 00105 void compare_collider_to_geom(CollisionEntry &entry, const Geom *geom, 00106 const GeometricBoundingVolume *from_node_gbv, 00107 const GeometricBoundingVolume *solid_gbv); 00108 00109 PStatCollector &get_pass_collector(int pass); 00110 00111 private: 00112 PT(CollisionHandler) _default_handler; 00113 TypeHandle _graph_type; 00114 00115 class OrderedColliderDef { 00116 public: 00117 NodePath _node_path; 00118 bool _in_graph; 00119 }; 00120 00121 typedef pmap<NodePath, PT(CollisionHandler) > Colliders; 00122 Colliders _colliders; 00123 typedef pvector<OrderedColliderDef> OrderedColliders; 00124 OrderedColliders _ordered_colliders; 00125 00126 typedef pmap<PT(CollisionHandler), int> Handlers; 00127 Handlers _handlers; 00128 00129 Handlers::iterator remove_handler(Handlers::iterator hi); 00130 00131 bool _respect_prev_transform; 00132 #ifdef DO_COLLISION_RECORDING 00133 CollisionRecorder *_recorder; 00134 NodePath _collision_visualizer_np; 00135 #endif // DO_COLLISION_RECORDING 00136 00137 // Statistics 00138 static PStatCollector _collisions_pcollector; 00139 00140 static PStatCollector _cnode_volume_pcollector; 00141 static PStatCollector _gnode_volume_pcollector; 00142 static PStatCollector _geom_volume_pcollector; 00143 00144 PStatCollector _this_pcollector; 00145 typedef pvector<PStatCollector> PassCollectors; 00146 PassCollectors _pass_collectors; 00147 // pstats category for actual collision detection (vs. bounding heirarchy collision detection) 00148 typedef pvector<PStatCollector> SolidCollideCollectors; 00149 SolidCollideCollectors _solid_collide_collectors; 00150 00151 public: 00152 static TypeHandle get_class_type() { 00153 return _type_handle; 00154 } 00155 static void init_type() { 00156 register_type(_type_handle, "CollisionTraverser"); 00157 } 00158 00159 private: 00160 static TypeHandle _type_handle; 00161 00162 friend class SortByColliderSort; 00163 }; 00164 00165 INLINE ostream &operator << (ostream &out, const CollisionTraverser &trav) { 00166 trav.output(out); 00167 return out; 00168 } 00169 00170 #include "collisionTraverser.I" 00171 00172 #endif 00173