Panda3D

collisionHandlerPhysical.cxx

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 }
 All Classes Functions Variables Enumerations