Panda3D
|
00001 // Filename: collisionHandlerPhysical.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 "collisionHandlerPhysical.h" 00016 #include "config_collide.h" 00017 00018 #include "transformState.h" 00019 00020 TypeHandle CollisionHandlerPhysical::_type_handle; 00021 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Function: CollisionHandlerPhysical::Constructor 00025 // Access: Public 00026 // Description: 00027 //////////////////////////////////////////////////////////////////// 00028 CollisionHandlerPhysical:: 00029 CollisionHandlerPhysical() { 00030 _has_contact = false; 00031 } 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Function: CollisionHandlerPhysical::Destructor 00035 // Access: Public, Virtual 00036 // Description: 00037 //////////////////////////////////////////////////////////////////// 00038 CollisionHandlerPhysical:: 00039 ~CollisionHandlerPhysical() { 00040 } 00041 00042 //////////////////////////////////////////////////////////////////// 00043 // Function: CollisionHandlerPhysical::begin_group 00044 // Access: Public, Virtual 00045 // Description: Will be called by the CollisionTraverser before a new 00046 // traversal is begun. It instructs the handler to 00047 // reset itself in preparation for a number of 00048 // CollisionEntries to be sent. 00049 //////////////////////////////////////////////////////////////////// 00050 void CollisionHandlerPhysical:: 00051 begin_group() { 00052 CollisionHandlerEvent::begin_group(); 00053 _from_entries.clear(); 00054 _has_contact = false; 00055 } 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: CollisionHandlerPhysical::add_entry 00059 // Access: Public, Virtual 00060 // Description: Called between a begin_group() .. end_group() 00061 // sequence for each collision that is detected. 00062 //////////////////////////////////////////////////////////////////// 00063 void CollisionHandlerPhysical:: 00064 add_entry(CollisionEntry *entry) { 00065 nassertv(entry != (CollisionEntry *)NULL); 00066 CollisionHandlerEvent::add_entry(entry); 00067 00068 if (entry->get_from()->is_tangible() && 00069 (!entry->has_into() || entry->get_into()->is_tangible())) { 00070 00071 if (has_center()) { 00072 // If a center is specified, we have to make sure the surface is 00073 // more-or-less facing it. 00074 if (!entry->has_surface_point() || !entry->has_surface_normal()) { 00075 return; 00076 } 00077 00078 LPoint3 point = entry->get_surface_point(_center); 00079 LVector3 normal = entry->get_surface_normal(_center); 00080 if (point.dot(normal) > 0) { 00081 return; 00082 } 00083 } 00084 00085 _from_entries[entry->get_from_node_path()].push_back(entry); 00086 _has_contact = true; 00087 } 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: CollisionHandlerPhysical::end_group 00092 // Access: Public, Virtual 00093 // Description: Called by the CollisionTraverser at the completion of 00094 // all collision detections for this traversal. It 00095 // should do whatever finalization is required for the 00096 // handler. 00097 //////////////////////////////////////////////////////////////////// 00098 bool CollisionHandlerPhysical:: 00099 end_group() { 00100 bool result = handle_entries(); 00101 CollisionHandlerEvent::end_group(); 00102 00103 return result; 00104 } 00105 00106 //////////////////////////////////////////////////////////////////// 00107 // Function: CollisionHandlerPhysical::add_collider 00108 // Access: Published 00109 // Description: Adds a new collider to the list with a NodePath 00110 // that will be updated with the collider's new 00111 // position, or updates the existing collider with a new 00112 // NodePath object. 00113 //////////////////////////////////////////////////////////////////// 00114 void CollisionHandlerPhysical:: 00115 add_collider(const NodePath &collider, const NodePath &target) { 00116 nassertv(!collider.is_empty() && collider.node()->is_collision_node()); 00117 nassertv(validate_target(target)); 00118 _colliders[collider].set_target(target); 00119 } 00120 00121 //////////////////////////////////////////////////////////////////// 00122 // Function: CollisionHandlerPhysical::add_collider 00123 // Access: Published 00124 // Description: Adds a new collider to the list with a NodePath 00125 // that will be updated with the collider's new 00126 // position, or updates the existing collider with a new 00127 // NodePath object. 00128 // 00129 // The indicated DriveInterface will also be updated 00130 // with the target's new transform each frame. This 00131 // method should be used when the target is directly 00132 // controlled by a DriveInterface. 00133 //////////////////////////////////////////////////////////////////// 00134 void CollisionHandlerPhysical:: 00135 add_collider(const NodePath &collider, const NodePath &target, 00136 DriveInterface *drive_interface) { 00137 nassertv(!collider.is_empty() && collider.node()->is_collision_node()); 00138 nassertv(validate_target(target)); 00139 _colliders[collider].set_target(target, drive_interface); 00140 } 00141 00142 //////////////////////////////////////////////////////////////////// 00143 // Function: CollisionHandlerPhysical::remove_collider 00144 // Access: Published 00145 // Description: Removes the collider from the list of colliders that 00146 // this handler knows about. 00147 //////////////////////////////////////////////////////////////////// 00148 bool CollisionHandlerPhysical:: 00149 remove_collider(const NodePath &collider) { 00150 Colliders::iterator ci = _colliders.find(collider); 00151 if (ci == _colliders.end()) { 00152 return false; 00153 } 00154 _colliders.erase(ci); 00155 return true; 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: CollisionHandlerPhysical::has_collider 00160 // Access: Published 00161 // Description: Returns true if the handler knows about the indicated 00162 // collider, false otherwise. 00163 //////////////////////////////////////////////////////////////////// 00164 bool CollisionHandlerPhysical:: 00165 has_collider(const NodePath &target) const { 00166 Colliders::const_iterator ci = _colliders.find(target); 00167 return (ci != _colliders.end()); 00168 } 00169 00170 //////////////////////////////////////////////////////////////////// 00171 // Function: CollisionHandlerPhysical::clear_colliders 00172 // Access: Published 00173 // Description: Completely empties the list of colliders this handler 00174 // knows about. 00175 //////////////////////////////////////////////////////////////////// 00176 void CollisionHandlerPhysical:: 00177 clear_colliders() { 00178 _colliders.clear(); 00179 } 00180 00181 //////////////////////////////////////////////////////////////////// 00182 // Function: CollisionHandlerPhysical::validate_target 00183 // Access: Protected, Virtual 00184 // Description: Called internally to validate the target passed to 00185 // add_collider(). Returns true if acceptable, false 00186 // otherwise. 00187 //////////////////////////////////////////////////////////////////// 00188 bool CollisionHandlerPhysical:: 00189 validate_target(const NodePath &target) { 00190 nassertr_always(!target.is_empty(), false); 00191 return true; 00192 }