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 our own Panda specialization on the default STL map.
Definition: pmap.h:49
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(),...
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