Panda3D
collisionTraverser.h
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file collisionTraverser.h
10  * @author drose
11  * @date 2002-03-16
12  */
13 
14 #ifndef COLLISIONTRAVERSER_H
15 #define COLLISIONTRAVERSER_H
16 
17 #include "pandabase.h"
18 
19 #include "collisionHandler.h"
20 #include "collisionLevelState.h"
21 
22 #include "pointerTo.h"
23 #include "pStatCollector.h"
24 
25 #include "pset.h"
26 #include "register_type.h"
27 
28 class CollisionNode;
29 class CollisionRecorder;
30 class CollisionVisualizer;
31 class Geom;
32 class NodePath;
33 class CollisionEntry;
34 
35 /**
36  * This class manages the traversal through the scene graph to detect
37  * collisions. It holds ownership of a number of collider objects, each of
38  * which is a CollisionNode and an associated CollisionHandler.
39  *
40  * When traverse() is called, it begins at the indicated root and detects all
41  * collisions with any of its collider objects against nodes at or below the
42  * indicated root, calling the appropriate CollisionHandler for each detected
43  * collision.
44  */
45 class EXPCL_PANDA_COLLIDE CollisionTraverser : public Namable {
46 PUBLISHED:
47  explicit CollisionTraverser(const std::string &name = "ctrav");
49 
50  INLINE void set_respect_prev_transform(bool flag);
51  INLINE bool get_respect_prev_transform() const;
52  MAKE_PROPERTY(respect_preV_transform, get_respect_prev_transform,
53  set_respect_prev_transform);
54 
55  void add_collider(const NodePath &collider, CollisionHandler *handler);
56  bool remove_collider(const NodePath &collider);
57  bool has_collider(const NodePath &collider) const;
58  int get_num_colliders() const;
59  NodePath get_collider(int n) const;
60  MAKE_SEQ(get_colliders, get_num_colliders, get_collider);
61  CollisionHandler *get_handler(const NodePath &collider) const;
62  void clear_colliders();
63  MAKE_SEQ_PROPERTY(colliders, get_num_colliders, get_collider);
64 
65  void traverse(const NodePath &root);
66 
67 #ifdef DO_COLLISION_RECORDING
68  void set_recorder(CollisionRecorder *recorder);
69  INLINE bool has_recorder() const;
70  INLINE CollisionRecorder *get_recorder() const;
71  INLINE void clear_recorder();
72  MAKE_PROPERTY2(recorder, has_recorder, get_recorder,
73  set_recorder, clear_recorder);
74 
75  CollisionVisualizer *show_collisions(const NodePath &root);
76  void hide_collisions();
77 #endif // DO_COLLISION_RECORDING
78 
79  void output(std::ostream &out) const;
80  void write(std::ostream &out, int indent_level) const;
81 
82 private:
84  void prepare_colliders_single(LevelStatesSingle &level_states, const NodePath &root);
85  void r_traverse_single(CollisionLevelStateSingle &level_state, size_t pass);
86 
88  void prepare_colliders_double(LevelStatesDouble &level_states, const NodePath &root);
89  void r_traverse_double(CollisionLevelStateDouble &level_state, size_t pass);
90 
92  void prepare_colliders_quad(LevelStatesQuad &level_states, const NodePath &root);
93  void r_traverse_quad(CollisionLevelStateQuad &level_state, size_t pass);
94 
95  void compare_collider_to_node(CollisionEntry &entry,
96  const GeometricBoundingVolume *from_parent_gbv,
97  const GeometricBoundingVolume *from_node_gbv,
98  const GeometricBoundingVolume *into_node_gbv);
99  void compare_collider_to_geom_node(CollisionEntry &entry,
100  const GeometricBoundingVolume *from_parent_gbv,
101  const GeometricBoundingVolume *from_node_gbv,
102  const GeometricBoundingVolume *into_node_gbv);
103  void compare_collider_to_solid(CollisionEntry &entry,
104  const GeometricBoundingVolume *from_node_gbv,
105  const GeometricBoundingVolume *solid_gbv);
106  void compare_collider_to_geom(CollisionEntry &entry, const Geom *geom,
107  const GeometricBoundingVolume *from_node_gbv,
108  const GeometricBoundingVolume *solid_gbv);
109 
110  PStatCollector &get_pass_collector(int pass);
111 
112 private:
113  PT(CollisionHandler) _default_handler;
114 
115  class OrderedColliderDef {
116  public:
117  NodePath _node_path;
118  bool _in_graph;
119  };
120 
121  typedef pmap<NodePath, PT(CollisionHandler) > Colliders;
122  Colliders _colliders;
123  typedef pvector<OrderedColliderDef> OrderedColliders;
124  OrderedColliders _ordered_colliders;
125 
126  typedef pmap<PT(CollisionHandler), int> Handlers;
127  Handlers _handlers;
128 
129  Handlers::iterator remove_handler(Handlers::iterator hi);
130 
131  bool _respect_prev_transform;
132 #ifdef DO_COLLISION_RECORDING
133  CollisionRecorder *_recorder;
134  NodePath _collision_visualizer_np;
135 #endif // DO_COLLISION_RECORDING
136 
137  // Statistics
138  static PStatCollector _collisions_pcollector;
139 
140  static PStatCollector _cnode_volume_pcollector;
141  static PStatCollector _gnode_volume_pcollector;
142  static PStatCollector _geom_volume_pcollector;
143 
144  PStatCollector _this_pcollector;
145  typedef pvector<PStatCollector> PassCollectors;
146  PassCollectors _pass_collectors;
147  // pstats category for actual collision detection (vs. bounding heirarchy
148  // collision detection)
149  typedef pvector<PStatCollector> SolidCollideCollectors;
150  SolidCollideCollectors _solid_collide_collectors;
151 
152 public:
153  static TypeHandle get_class_type() {
154  return _type_handle;
155  }
156  static void init_type() {
157  register_type(_type_handle, "CollisionTraverser");
158  }
159 
160 private:
161  static TypeHandle _type_handle;
162 
163  friend class SortByColliderSort;
164 };
165 
166 INLINE std::ostream &operator << (std::ostream &out, const CollisionTraverser &trav) {
167  trav.output(out);
168  return out;
169 }
170 
171 #include "collisionTraverser.I"
172 
173 #endif
The abstract interface to a number of classes that decide what to do when a collision is detected...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the state information the CollisionTraverser retains for each level during traversal...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(), along with zero to four record_derivation()s.
Definition: register_type.I:22
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
void output(std::ostream &out) const
Outputs the Namable.
Definition: namable.I:61
A lightweight class that represents a single element that may be timed and/or counted via stats...
This is another abstract class, for a general class of bounding volumes that actually enclose points ...
A base class for all things which can have a name.
Definition: namable.h:26
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Defines a single collision event.
A container for geometry primitives.
Definition: geom.h:54
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node in the scene graph that can hold any number of CollisionSolids.
Definition: collisionNode.h:30
This class manages the traversal through the scene graph to detect collisions.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161