00001 // Filename: collisionHandlerQueue.cxx 00002 // Created by: drose (16Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "collisionHandlerQueue.h" 00020 #include "config_collide.h" 00021 00022 TypeHandle CollisionHandlerQueue::_type_handle; 00023 00024 // This class is used in sort_entries(), below. 00025 class CollisionEntrySorter { 00026 public: 00027 CollisionEntrySorter(CollisionEntry *entry) { 00028 _entry = entry; 00029 LVector3f vec = 00030 entry->get_from_intersection_point() - 00031 entry->get_from()->get_collision_origin(); 00032 _dist2 = vec.length_squared(); 00033 } 00034 bool operator < (const CollisionEntrySorter &other) const { 00035 return _dist2 < other._dist2; 00036 } 00037 00038 CollisionEntry *_entry; 00039 float _dist2; 00040 }; 00041 00042 //////////////////////////////////////////////////////////////////// 00043 // Function: CollisionHandlerQueue::Constructor 00044 // Access: Public 00045 // Description: 00046 //////////////////////////////////////////////////////////////////// 00047 CollisionHandlerQueue:: 00048 CollisionHandlerQueue() { 00049 } 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function: CollisionHandlerQueue::begin_group 00053 // Access: Public, Virtual 00054 // Description: Will be called by the CollisionTraverser before a new 00055 // traversal is begun. It instructs the handler to 00056 // reset itself in preparation for a number of 00057 // CollisionEntries to be sent. 00058 //////////////////////////////////////////////////////////////////// 00059 void CollisionHandlerQueue:: 00060 begin_group() { 00061 _entries.clear(); 00062 } 00063 00064 //////////////////////////////////////////////////////////////////// 00065 // Function: CollisionHandlerQueue::add_entry 00066 // Access: Public, Virtual 00067 // Description: Called between a begin_group() .. end_group() 00068 // sequence for each collision that is detected. 00069 //////////////////////////////////////////////////////////////////// 00070 void CollisionHandlerQueue:: 00071 add_entry(CollisionEntry *entry) { 00072 nassertv(entry != (CollisionEntry *)NULL); 00073 _entries.push_back(entry); 00074 } 00075 00076 //////////////////////////////////////////////////////////////////// 00077 // Function: CollisionHandlerQueue::sort_entries 00078 // Access: Public 00079 // Description: Sorts all the detected collisions front-to-back by 00080 // from_intersection_point() so that those intersection 00081 // points closest to the collider's origin (e.g., the 00082 // center of the CollisionSphere, or the point_a of a 00083 // CollisionSegment) appear first. 00084 //////////////////////////////////////////////////////////////////// 00085 void CollisionHandlerQueue:: 00086 sort_entries() { 00087 // Build up a temporary vector of entries so we can sort the 00088 // pointers. This uses the class defined above. 00089 typedef pvector<CollisionEntrySorter> Sorter; 00090 Sorter sorter; 00091 sorter.reserve(_entries.size()); 00092 00093 Entries::const_iterator ei; 00094 for (ei = _entries.begin(); ei != _entries.end(); ++ei) { 00095 sorter.push_back(CollisionEntrySorter(*ei)); 00096 } 00097 00098 sort(sorter.begin(), sorter.end()); 00099 nassertv(sorter.size() == _entries.size()); 00100 00101 // Now that they're sorted, get them back. We do this in two steps, 00102 // building up a temporary vector first, so we don't accidentally 00103 // delete all the entries when the pointers go away. 00104 Entries sorted_entries; 00105 sorted_entries.reserve(sorter.size()); 00106 Sorter::const_iterator si; 00107 for (si = sorter.begin(); si != sorter.end(); ++si) { 00108 sorted_entries.push_back((*si)._entry); 00109 } 00110 00111 _entries.swap(sorted_entries); 00112 } 00113 00114 //////////////////////////////////////////////////////////////////// 00115 // Function: CollisionHandlerQueue::clear_entries 00116 // Access: Public 00117 // Description: Removes all the entries from the queue. 00118 //////////////////////////////////////////////////////////////////// 00119 void CollisionHandlerQueue:: 00120 clear_entries() { 00121 _entries.clear(); 00122 } 00123 00124 //////////////////////////////////////////////////////////////////// 00125 // Function: CollisionHandlerQueue::get_num_entries 00126 // Access: Public 00127 // Description: Returns the number of CollisionEntries detected last 00128 // pass. 00129 //////////////////////////////////////////////////////////////////// 00130 int CollisionHandlerQueue:: 00131 get_num_entries() const { 00132 return _entries.size(); 00133 } 00134 00135 //////////////////////////////////////////////////////////////////// 00136 // Function: CollisionHandlerQueue::get_entry 00137 // Access: Public 00138 // Description: Returns the nth CollisionEntry detected last pass. 00139 //////////////////////////////////////////////////////////////////// 00140 CollisionEntry *CollisionHandlerQueue:: 00141 get_entry(int n) const { 00142 nassertr(n >= 0 && n < (int)_entries.size(), NULL); 00143 return _entries[n]; 00144 }