00001 // Filename: collisionHandlerPhysical.cxx00002 // Created by: drose (16Mar02)00003 //00004 ////////////////////////////////////////////////////////////////////00005 //00006 // PANDA 3D SOFTWARE00007 // Copyright (c) Carnegie Mellon University. All rights reserved.00008 //00009 // All use of this software is subject to the terms of the revised BSD00010 // license. You should have received a copy of this license along00011 // 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::Constructor00025 // Access: Public00026 // Description:00027 ////////////////////////////////////////////////////////////////////00028 CollisionHandlerPhysical::
00029 CollisionHandlerPhysical() {
00030 _has_contact = false;
00031 }
00032
00033 ////////////////////////////////////////////////////////////////////00034 // Function: CollisionHandlerPhysical::Destructor00035 // Access: Public, Virtual00036 // Description:00037 ////////////////////////////////////////////////////////////////////00038 CollisionHandlerPhysical::
00039 ~CollisionHandlerPhysical() {
00040 }
00041
00042 ////////////////////////////////////////////////////////////////////00043 // Function: CollisionHandlerPhysical::begin_group00044 // Access: Public, Virtual00045 // Description: Will be called by the CollisionTraverser before a new00046 // traversal is begun. It instructs the handler to00047 // reset itself in preparation for a number of00048 // CollisionEntries to be sent.00049 ////////////////////////////////////////////////////////////////////00050 voidCollisionHandlerPhysical::00051begin_group() {
00052 CollisionHandlerEvent::begin_group();
00053 _from_entries.clear();
00054 _has_contact = false;
00055 }
00056
00057 ////////////////////////////////////////////////////////////////////00058 // Function: CollisionHandlerPhysical::add_entry00059 // Access: Public, Virtual00060 // Description: Called between a begin_group() .. end_group()00061 // sequence for each collision that is detected.00062 ////////////////////////////////////////////////////////////////////00063 voidCollisionHandlerPhysical::00064add_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 is00073 // 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_group00092 // Access: Public, Virtual00093 // Description: Called by the CollisionTraverser at the completion of00094 // all collision detections for this traversal. It00095 // should do whatever finalization is required for the00096 // handler.00097 ////////////////////////////////////////////////////////////////////00098 boolCollisionHandlerPhysical::00099end_group() {
00100 bool result = handle_entries();
00101 CollisionHandlerEvent::end_group();
00102
00103 return result;
00104 }
00105
00106 ////////////////////////////////////////////////////////////////////00107 // Function: CollisionHandlerPhysical::add_collider00108 // Access: Published00109 // Description: Adds a new collider to the list with a NodePath00110 // that will be updated with the collider's new00111 // position, or updates the existing collider with a new00112 // NodePath object.00113 ////////////////////////////////////////////////////////////////////00114 voidCollisionHandlerPhysical::00115add_collider(constNodePath &collider, constNodePath &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_collider00123 // Access: Published00124 // Description: Adds a new collider to the list with a NodePath00125 // that will be updated with the collider's new00126 // position, or updates the existing collider with a new00127 // NodePath object.00128 //00129 // The indicated DriveInterface will also be updated00130 // with the target's new transform each frame. This00131 // method should be used when the target is directly00132 // controlled by a DriveInterface.00133 ////////////////////////////////////////////////////////////////////00134 voidCollisionHandlerPhysical::00135add_collider(constNodePath &collider, constNodePath &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_collider00144 // Access: Published00145 // Description: Removes the collider from the list of colliders that00146 // this handler knows about.00147 ////////////////////////////////////////////////////////////////////00148 boolCollisionHandlerPhysical::00149remove_collider(constNodePath &collider) {
00150 Colliders::iterator ci = _colliders.find(collider);
00151 if (ci == _colliders.end()) {
00152 returnfalse;
00153 }
00154 _colliders.erase(ci);
00155 returntrue;
00156 }
00157
00158 ////////////////////////////////////////////////////////////////////00159 // Function: CollisionHandlerPhysical::has_collider00160 // Access: Published00161 // Description: Returns true if the handler knows about the indicated00162 // collider, false otherwise.00163 ////////////////////////////////////////////////////////////////////00164 boolCollisionHandlerPhysical::00165has_collider(constNodePath &target) const {
00166 Colliders::const_iterator ci = _colliders.find(target);
00167 return (ci != _colliders.end());
00168 }
00169
00170 ////////////////////////////////////////////////////////////////////00171 // Function: CollisionHandlerPhysical::clear_colliders00172 // Access: Published00173 // Description: Completely empties the list of colliders this handler00174 // knows about.00175 ////////////////////////////////////////////////////////////////////00176 voidCollisionHandlerPhysical::00177clear_colliders() {
00178 _colliders.clear();
00179 }
00180
00181 ////////////////////////////////////////////////////////////////////00182 // Function: CollisionHandlerPhysical::validate_target00183 // Access: Protected, Virtual00184 // Description: Called internally to validate the target passed to00185 // add_collider(). Returns true if acceptable, false00186 // otherwise.00187 ////////////////////////////////////////////////////////////////////00188 boolCollisionHandlerPhysical::00189validate_target(constNodePath &target) {
00190 nassertr_always(!target.is_empty(), false);
00191 returntrue;
00192 }