00001 // Filename: collisionHandlerFloor.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 "collisionHandlerFloor.h" 00020 #include "collisionNode.h" 00021 #include "collisionEntry.h" 00022 #include "config_collide.h" 00023 00024 #include "clockObject.h" 00025 00026 TypeHandle CollisionHandlerFloor::_type_handle; 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: CollisionHandlerFloor::Constructor 00030 // Access: Public 00031 // Description: 00032 //////////////////////////////////////////////////////////////////// 00033 CollisionHandlerFloor:: 00034 CollisionHandlerFloor() { 00035 _offset = 0.0f; 00036 _max_velocity = 0.0f; 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: CollisionHandlerFloor::Destructor 00041 // Access: Public, Virtual 00042 // Description: 00043 //////////////////////////////////////////////////////////////////// 00044 CollisionHandlerFloor:: 00045 ~CollisionHandlerFloor() { 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: CollisionHandlerFloor::handle_entries 00050 // Access: Protected, Virtual 00051 // Description: Called by the parent class after all collisions have 00052 // been detected, this manages the various collisions 00053 // and moves around the nodes as necessary. 00054 // 00055 // The return value is normally true, but it may be 00056 // false to indicate the CollisionTraverser should 00057 // disable this handler from being called in the future. 00058 //////////////////////////////////////////////////////////////////// 00059 bool CollisionHandlerFloor:: 00060 handle_entries() { 00061 bool okflag = true; 00062 00063 FromEntries::const_iterator fi; 00064 for (fi = _from_entries.begin(); fi != _from_entries.end(); ++fi) { 00065 CollisionNode *from_node = (*fi).first; 00066 nassertr(from_node != (CollisionNode *)NULL, false); 00067 const Entries &entries = (*fi).second; 00068 00069 Colliders::iterator ci; 00070 ci = _colliders.find(from_node); 00071 if (ci == _colliders.end()) { 00072 // Hmm, someone added a CollisionNode to a traverser and gave 00073 // it this CollisionHandler pointer--but they didn't tell us 00074 // about the node. 00075 collide_cat.error() 00076 << get_type() << " doesn't know about " 00077 << *from_node << ", disabling.\n"; 00078 okflag = false; 00079 00080 } else { 00081 ColliderDef &def = (*ci).second; 00082 if (!def.is_valid()) { 00083 collide_cat.error() 00084 << "Removing invalid collider " << *from_node << " from " 00085 << get_type() << "\n"; 00086 _colliders.erase(ci); 00087 00088 } else { 00089 // Get the maximum height for all collisions with this node. 00090 bool got_max = false; 00091 float max_height = 0.0f; 00092 00093 Entries::const_iterator ei; 00094 for (ei = entries.begin(); ei != entries.end(); ++ei) { 00095 CollisionEntry *entry = (*ei); 00096 nassertr(entry != (CollisionEntry *)NULL, false); 00097 nassertr(from_node == entry->get_from_node(), false); 00098 00099 if (entry->has_from_intersection_point()) { 00100 LPoint3f point = entry->get_from_intersection_point(); 00101 if (collide_cat.is_debug()) { 00102 collide_cat.debug() 00103 << "Intersection point detected at " << point << "\n"; 00104 } 00105 00106 float height = point[2]; 00107 if (!got_max || height > max_height) { 00108 got_max = true; 00109 max_height = height; 00110 } 00111 } 00112 } 00113 00114 // Now set our height accordingly. 00115 float adjust = max_height + _offset; 00116 if (!IS_THRESHOLD_ZERO(adjust, 0.001)) { 00117 if (collide_cat.is_debug()) { 00118 collide_cat.debug() 00119 << "Adjusting height by " << adjust << "\n"; 00120 } 00121 00122 if (adjust < 0.0f && _max_velocity != 0.0f) { 00123 float max_adjust = 00124 _max_velocity * ClockObject::get_global_clock()->get_dt(); 00125 adjust = max(adjust, -max_adjust); 00126 } 00127 00128 LMatrix4f mat; 00129 def.get_mat(mat); 00130 mat(3, 2) += adjust; 00131 def.set_mat(mat); 00132 } else { 00133 if (collide_cat.is_spam()) { 00134 collide_cat.spam() 00135 << "Leaving height unchanged.\n"; 00136 } 00137 } 00138 } 00139 } 00140 } 00141 00142 return okflag; 00143 }