Panda3D

collisionHandlerQueue.cxx

00001 // Filename: collisionHandlerQueue.cxx
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 #include "collisionHandlerQueue.h"
00016 #include "config_collide.h"
00017 #include "indent.h"
00018 
00019 TypeHandle CollisionHandlerQueue::_type_handle;
00020 
00021 // This class is used in sort_entries(), below.
00022 class CollisionEntrySorter {
00023 public:
00024   CollisionEntrySorter(CollisionEntry *entry) {
00025     _entry = entry;
00026     LVector3 vec =
00027       entry->get_surface_point(entry->get_from_node_path()) -
00028       entry->get_from()->get_collision_origin();
00029     _dist2 = vec.length_squared();
00030   }
00031   bool operator < (const CollisionEntrySorter &other) const {
00032     return _dist2 < other._dist2;
00033   }
00034 
00035   CollisionEntry *_entry;
00036   PN_stdfloat _dist2;
00037 };
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: CollisionHandlerQueue::Constructor
00041 //       Access: Published
00042 //  Description:
00043 ////////////////////////////////////////////////////////////////////
00044 CollisionHandlerQueue::
00045 CollisionHandlerQueue() {
00046 }
00047 
00048 ////////////////////////////////////////////////////////////////////
00049 //     Function: CollisionHandlerQueue::begin_group
00050 //       Access: Published, Virtual
00051 //  Description: Will be called by the CollisionTraverser before a new
00052 //               traversal is begun.  It instructs the handler to
00053 //               reset itself in preparation for a number of
00054 //               CollisionEntries to be sent.
00055 ////////////////////////////////////////////////////////////////////
00056 void CollisionHandlerQueue::
00057 begin_group() {
00058   _entries.clear();
00059 }
00060 
00061 ////////////////////////////////////////////////////////////////////
00062 //     Function: CollisionHandlerQueue::add_entry
00063 //       Access: Published, Virtual
00064 //  Description: Called between a begin_group() .. end_group()
00065 //               sequence for each collision that is detected.
00066 ////////////////////////////////////////////////////////////////////
00067 void CollisionHandlerQueue::
00068 add_entry(CollisionEntry *entry) {
00069   nassertv(entry != (CollisionEntry *)NULL);
00070   _entries.push_back(entry);
00071 }
00072 
00073 ////////////////////////////////////////////////////////////////////
00074 //     Function: CollisionHandlerQueue::sort_entries
00075 //       Access: Published
00076 //  Description: Sorts all the detected collisions front-to-back by
00077 //               from_intersection_point() so that those intersection
00078 //               points closest to the collider's origin (e.g., the
00079 //               center of the CollisionSphere, or the point_a of a
00080 //               CollisionSegment) appear first.
00081 ////////////////////////////////////////////////////////////////////
00082 void CollisionHandlerQueue::
00083 sort_entries() {
00084   // Build up a temporary vector of entries so we can sort the
00085   // pointers.  This uses the class defined above.
00086   typedef pvector<CollisionEntrySorter> Sorter;
00087   Sorter sorter;
00088   sorter.reserve(_entries.size());
00089 
00090   Entries::const_iterator ei;
00091   for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
00092     sorter.push_back(CollisionEntrySorter(*ei));
00093   }
00094 
00095   sort(sorter.begin(), sorter.end());
00096   nassertv(sorter.size() == _entries.size());
00097 
00098   // Now that they're sorted, get them back.  We do this in two steps,
00099   // building up a temporary vector first, so we don't accidentally
00100   // delete all the entries when the pointers go away.
00101   Entries sorted_entries;
00102   sorted_entries.reserve(sorter.size());
00103   Sorter::const_iterator si;
00104   for (si = sorter.begin(); si != sorter.end(); ++si) {
00105     sorted_entries.push_back((*si)._entry);
00106   }
00107 
00108   _entries.swap(sorted_entries);
00109 }
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //     Function: CollisionHandlerQueue::clear_entries
00113 //       Access: Published
00114 //  Description: Removes all the entries from the queue.
00115 ////////////////////////////////////////////////////////////////////
00116 void CollisionHandlerQueue::
00117 clear_entries() {
00118   _entries.clear();
00119 }
00120 
00121 ////////////////////////////////////////////////////////////////////
00122 //     Function: CollisionHandlerQueue::get_num_entries
00123 //       Access: Published
00124 //  Description: Returns the number of CollisionEntries detected last
00125 //               pass.
00126 ////////////////////////////////////////////////////////////////////
00127 int CollisionHandlerQueue::
00128 get_num_entries() const {
00129   return _entries.size();
00130 }
00131 
00132 ////////////////////////////////////////////////////////////////////
00133 //     Function: CollisionHandlerQueue::get_entry
00134 //       Access: Published
00135 //  Description: Returns the nth CollisionEntry detected last pass.
00136 ////////////////////////////////////////////////////////////////////
00137 CollisionEntry *CollisionHandlerQueue::
00138 get_entry(int n) const {
00139   nassertr(n >= 0 && n < (int)_entries.size(), NULL);
00140   return _entries[n];
00141 }
00142 
00143 ////////////////////////////////////////////////////////////////////
00144 //     Function: CollisionHandlerQueue::output
00145 //       Access: Published
00146 //  Description: 
00147 ////////////////////////////////////////////////////////////////////
00148 void CollisionHandlerQueue::
00149 output(ostream &out) const {
00150   out << "CollisionHandlerQueue, " << _entries.size() << " entries";
00151 }
00152 
00153 ////////////////////////////////////////////////////////////////////
00154 //     Function: CollisionHandlerQueue::write
00155 //       Access: Published
00156 //  Description: 
00157 ////////////////////////////////////////////////////////////////////
00158 void CollisionHandlerQueue::
00159 write(ostream &out, int indent_level) const {
00160   indent(out, indent_level)
00161     << "CollisionHandlerQueue, " << _entries.size() << " entries:\n";
00162 
00163   Entries::const_iterator ei;
00164   for (ei = _entries.begin(); ei != _entries.end(); ++ei) {
00165     (*ei)->write(out, indent_level + 2);
00166   }
00167 }
 All Classes Functions Variables Enumerations