Panda3D
collisionHandlerQueue.cxx
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 collisionHandlerQueue.cxx
10  * @author drose
11  * @date 2002-03-16
12  */
13 
14 #include "collisionHandlerQueue.h"
15 #include "config_collide.h"
16 #include "indent.h"
17 
18 TypeHandle CollisionHandlerQueue::_type_handle;
19 
20 // This class is used in sort_entries(), below.
21 class CollisionEntrySorter {
22 public:
23  CollisionEntrySorter(CollisionEntry *entry) {
24  _entry = entry;
25  if (entry->has_surface_point()) {
26  LVector3 vec =
27  entry->get_surface_point(entry->get_from_node_path()) -
28  entry->get_from()->get_collision_origin();
29  _dist2 = vec.length_squared();
30  }
31  else {
32  _dist2 = make_inf((PN_stdfloat)0);
33  }
34  }
35  bool operator < (const CollisionEntrySorter &other) const {
36  return _dist2 < other._dist2;
37  }
38 
39  CollisionEntry *_entry;
40  PN_stdfloat _dist2;
41 };
42 
43 /**
44  *
45  */
46 CollisionHandlerQueue::
47 CollisionHandlerQueue() {
48 }
49 
50 /**
51  * Will be called by the CollisionTraverser before a new traversal is begun.
52  * It instructs the handler to reset itself in preparation for a number of
53  * CollisionEntries to be sent.
54  */
57  _entries.clear();
58 }
59 
60 /**
61  * Called between a begin_group() .. end_group() sequence for each collision
62  * that is detected.
63  */
66  nassertv(entry != nullptr);
67  _entries.push_back(entry);
68 }
69 
70 /**
71  * Sorts all the detected collisions front-to-back by
72  * from_intersection_point() so that those intersection points closest to the
73  * collider's origin (e.g., the center of the CollisionSphere, or the point_a
74  * of a CollisionSegment) appear first.
75  */
78  // Build up a temporary vector of entries so we can sort the pointers. This
79  // uses the class defined above.
80  typedef pvector<CollisionEntrySorter> Sorter;
81  Sorter sorter;
82  sorter.reserve(_entries.size());
83 
84  Entries::const_iterator ei;
85  for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
86  sorter.push_back(CollisionEntrySorter(*ei));
87  }
88 
89  sort(sorter.begin(), sorter.end());
90  nassertv(sorter.size() == _entries.size());
91 
92  // Now that they're sorted, get them back. We do this in two steps,
93  // building up a temporary vector first, so we don't accidentally delete all
94  // the entries when the pointers go away.
95  Entries sorted_entries;
96  sorted_entries.reserve(sorter.size());
97  Sorter::const_iterator si;
98  for (si = sorter.begin(); si != sorter.end(); ++si) {
99  sorted_entries.push_back((*si)._entry);
100  }
101 
102  _entries.swap(sorted_entries);
103 }
104 
105 /**
106  * Removes all the entries from the queue.
107  */
110  _entries.clear();
111 }
112 
113 /**
114  * Returns the number of CollisionEntries detected last pass.
115  */
116 int CollisionHandlerQueue::
117 get_num_entries() const {
118  return _entries.size();
119 }
120 
121 /**
122  * Returns the nth CollisionEntry detected last pass.
123  */
125 get_entry(int n) const {
126  nassertr(n >= 0 && n < (int)_entries.size(), nullptr);
127  return _entries[n];
128 }
129 
130 /**
131  *
132  */
133 void CollisionHandlerQueue::
134 output(std::ostream &out) const {
135  out << "CollisionHandlerQueue, " << _entries.size() << " entries";
136 }
137 
138 /**
139  *
140  */
141 void CollisionHandlerQueue::
142 write(std::ostream &out, int indent_level) const {
143  indent(out, indent_level)
144  << "CollisionHandlerQueue, " << _entries.size() << " entries:\n";
145 
146  Entries::const_iterator ei;
147  for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
148  (*ei)->write(out, indent_level + 2);
149  }
150 }
bool has_surface_point() const
Returns true if the surface point has been specified, false otherwise.
get_from_node_path
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
LPoint3 get_surface_point(const NodePath &space) const
Returns the point, on the surface of the "into" object, at which a collision is detected.
void sort_entries()
Sorts all the detected collisions front-to-back by from_intersection_point() so that those intersecti...
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
virtual void add_entry(CollisionEntry *entry)
Called between a begin_group() .
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
Defines a single collision event.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_from
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void clear_entries()
Removes all the entries from the queue.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
get_entry
Returns the nth CollisionEntry detected last pass.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void begin_group()
Will be called by the CollisionTraverser before a new traversal is begun.