Panda3D
 All Classes Functions Variables Enumerations
collisionEntry.cxx
00001 // Filename: collisionEntry.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 "collisionEntry.h"
00016 #include "dcast.h"
00017 #include "indent.h"
00018 
00019 TypeHandle CollisionEntry::_type_handle;
00020 
00021 ////////////////////////////////////////////////////////////////////
00022 //     Function: CollisionEntry::Copy Constructor
00023 //       Access: Public
00024 //  Description:
00025 ////////////////////////////////////////////////////////////////////
00026 CollisionEntry::
00027 CollisionEntry(const CollisionEntry &copy) :
00028   _from(copy._from),
00029   _into(copy._into),
00030   _from_node(copy._from_node),
00031   _into_node(copy._into_node),
00032   _from_node_path(copy._from_node_path),
00033   _into_node_path(copy._into_node_path),
00034   _into_clip_planes(copy._into_clip_planes),
00035   _t(copy._t),
00036   _flags(copy._flags),
00037   _surface_point(copy._surface_point),
00038   _surface_normal(copy._surface_normal),
00039   _interior_point(copy._interior_point),
00040   _contact_pos(copy._contact_pos),
00041   _contact_normal(copy._contact_normal)
00042 {
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: CollisionEntry::Copy Assignment Operator
00047 //       Access: Public
00048 //  Description:
00049 ////////////////////////////////////////////////////////////////////
00050 void CollisionEntry::
00051 operator = (const CollisionEntry &copy) {
00052   _from = copy._from;
00053   _into = copy._into;
00054   _from_node = copy._from_node;
00055   _into_node = copy._into_node;
00056   _from_node_path = copy._from_node_path;
00057   _into_node_path = copy._into_node_path;
00058   _into_clip_planes = copy._into_clip_planes;
00059   _t = copy._t;
00060   _flags = copy._flags;
00061   _surface_point = copy._surface_point;
00062   _surface_normal = copy._surface_normal;
00063   _interior_point = copy._interior_point;
00064   _contact_pos = copy._contact_pos;
00065   _contact_normal = copy._contact_normal;
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////
00069 //     Function: CollisionEntry::get_surface_point
00070 //       Access: Published
00071 //  Description: Returns the point, on the surface of the "into"
00072 //               object, at which a collision is detected.  This can
00073 //               be thought of as the first point of intersection.
00074 //               However the contact point is the actual first point of
00075 //               intersection.
00076 //
00077 //               The point will be converted into whichever coordinate
00078 //               space the caller specifies.
00079 ////////////////////////////////////////////////////////////////////
00080 LPoint3 CollisionEntry::
00081 get_surface_point(const NodePath &space) const {
00082   nassertr(has_surface_point(), LPoint3::zero());
00083   CPT(TransformState) transform = _into_node_path.get_transform(space);
00084   return _surface_point * transform->get_mat();
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////
00088 //     Function: CollisionEntry::get_surface_normal
00089 //       Access: Published
00090 //  Description: Returns the surface normal of the "into" object at
00091 //               the point at which a collision is detected.
00092 //
00093 //               The normal will be converted into whichever coordinate
00094 //               space the caller specifies.
00095 ////////////////////////////////////////////////////////////////////
00096 LVector3 CollisionEntry::
00097 get_surface_normal(const NodePath &space) const {
00098   nassertr(has_surface_normal(), LVector3::zero());
00099   CPT(TransformState) transform = _into_node_path.get_transform(space);
00100   return _surface_normal * transform->get_mat();
00101 }
00102 
00103 ////////////////////////////////////////////////////////////////////
00104 //     Function: CollisionEntry::get_interior_point
00105 //       Access: Published
00106 //  Description: Returns the point, within the interior of the "into"
00107 //               object, which represents the depth to which the
00108 //               "from" object has penetrated.  This can also be
00109 //               described as the intersection point on the surface of
00110 //               the "from" object (which is inside the "into"
00111 //               object).  It can be thought of as the deepest point
00112 //               of intersection.
00113 //
00114 //               The point will be converted into whichever coordinate
00115 //               space the caller specifies.
00116 ////////////////////////////////////////////////////////////////////
00117 LPoint3 CollisionEntry::
00118 get_interior_point(const NodePath &space) const {
00119   if (!has_interior_point()) {
00120     return get_surface_point(space);
00121   }
00122   CPT(TransformState) transform = _into_node_path.get_transform(space);
00123   return _interior_point * transform->get_mat();
00124 }
00125 
00126 ////////////////////////////////////////////////////////////////////
00127 //     Function: CollisionEntry::get_all
00128 //       Access: Published
00129 //  Description: Simultaneously transforms the surface point, surface
00130 //               normal, and interior point of the collision into the
00131 //               indicated coordinate space.
00132 //
00133 //               Returns true if all three properties are available,
00134 //               or false if any one of them is not.
00135 ////////////////////////////////////////////////////////////////////
00136 bool CollisionEntry::
00137 get_all(const NodePath &space, LPoint3 &surface_point,
00138         LVector3 &surface_normal, LPoint3 &interior_point) const {
00139   CPT(TransformState) transform = _into_node_path.get_transform(space);
00140   const LMatrix4 &mat = transform->get_mat();
00141   bool all_ok = true;
00142 
00143   if (!has_surface_point()) {
00144     surface_point = LPoint3::zero();
00145     all_ok = false;
00146   } else {
00147     surface_point = _surface_point * mat;
00148   }
00149 
00150   if (!has_surface_normal()) {
00151     surface_normal = LVector3::zero();
00152     all_ok = false;
00153   } else {
00154     surface_normal = _surface_normal * mat;
00155   }
00156 
00157   if (!has_interior_point()) {
00158     interior_point = surface_point;
00159     all_ok = false;
00160   } else {
00161     interior_point = _interior_point * mat;
00162   }
00163 
00164   return all_ok;
00165 }
00166 
00167 ////////////////////////////////////////////////////////////////////
00168 //     Function: CollisionEntry::get_contact_pos
00169 //       Access: Published
00170 //  Description: Returns the position of the "from" object at the instant
00171 //               that a collision is first detected.
00172 //
00173 //               The position will be converted into whichever coordinate
00174 //               space the caller specifies.
00175 ////////////////////////////////////////////////////////////////////
00176 LPoint3 CollisionEntry::
00177 get_contact_pos(const NodePath &space) const {
00178   nassertr(has_contact_pos(), LPoint3::zero());
00179   CPT(TransformState) transform = _into_node_path.get_transform(space);
00180   return _contact_pos * transform->get_mat();
00181 }
00182 
00183 ////////////////////////////////////////////////////////////////////
00184 //     Function: CollisionEntry::get_contact_normal
00185 //       Access: Published
00186 //  Description: Returns the surface normal of the "into" object at
00187 //               the contact position.
00188 //
00189 //               The normal will be converted into whichever coordinate
00190 //               space the caller specifies.
00191 ////////////////////////////////////////////////////////////////////
00192 LVector3 CollisionEntry::
00193 get_contact_normal(const NodePath &space) const {
00194   nassertr(has_contact_normal(), LVector3::zero());
00195   CPT(TransformState) transform = _into_node_path.get_transform(space);
00196   return _contact_normal * transform->get_mat();
00197 }
00198 
00199 ////////////////////////////////////////////////////////////////////
00200 //     Function: CollisionEntry::get_all_contact_info
00201 //       Access: Published
00202 //  Description: Simultaneously transforms the contact position and
00203 //               contact normal of the collision into the
00204 //               indicated coordinate space.
00205 //
00206 //               Returns true if all three properties are available,
00207 //               or false if any one of them is not.
00208 ////////////////////////////////////////////////////////////////////
00209 bool CollisionEntry::
00210 get_all_contact_info(const NodePath &space, LPoint3 &contact_pos,
00211                      LVector3 &contact_normal) const {
00212   CPT(TransformState) transform = _into_node_path.get_transform(space);
00213   const LMatrix4 &mat = transform->get_mat();
00214   bool all_ok = true;
00215 
00216   if (!has_contact_pos()) {
00217     contact_pos = LPoint3::zero();
00218     all_ok = false;
00219   } else {
00220     contact_pos = _contact_pos * mat;
00221   }
00222 
00223   if (!has_contact_normal()) {
00224     contact_normal = LVector3::zero();
00225     all_ok = false;
00226   } else {
00227     contact_normal = _contact_normal * mat;
00228   }
00229 
00230   return all_ok;
00231 }
00232 
00233 ////////////////////////////////////////////////////////////////////
00234 //     Function: CollisionEntry::output
00235 //       Access: Published
00236 //  Description: 
00237 ////////////////////////////////////////////////////////////////////
00238 void CollisionEntry::
00239 output(ostream &out) const {
00240   out << _from_node_path;
00241   if (!_into_node_path.is_empty()) {
00242     out << " into " << _into_node_path;
00243   }
00244   if (has_surface_point()) {
00245     out << " at " << get_surface_point(NodePath());
00246   }
00247 }
00248 
00249 ////////////////////////////////////////////////////////////////////
00250 //     Function: CollisionEntry::write
00251 //       Access: Published
00252 //  Description: 
00253 ////////////////////////////////////////////////////////////////////
00254 void CollisionEntry::
00255 write(ostream &out, int indent_level) const {
00256   indent(out, indent_level)
00257     << "CollisionEntry:\n";
00258   if (!_from_node_path.is_empty()) {
00259     indent(out, indent_level + 2)
00260       << "from " << _from_node_path << "\n";
00261   }
00262   if (!_into_node_path.is_empty()) {
00263     indent(out, indent_level + 2)
00264       << "into " << _into_node_path;
00265 
00266     out << " [";
00267     _into_node_path.node()->list_tags(out, ", ");
00268     out << "]";
00269 
00270     const ClipPlaneAttrib *cpa = get_into_clip_planes();
00271     if (cpa != (ClipPlaneAttrib *)NULL) {
00272       out << " (clipped)";
00273     }
00274     out << "\n";
00275   }
00276   if (has_surface_point()) {
00277     indent(out, indent_level + 2)
00278       << "at " << get_surface_point(NodePath()) << "\n";
00279   }
00280   if (has_surface_normal()) {
00281     indent(out, indent_level + 2)
00282       << "normal " << get_surface_normal(NodePath()) << "\n";
00283   }
00284   if (has_interior_point()) {
00285     indent(out, indent_level + 2)
00286       << "interior " << get_interior_point(NodePath()) 
00287       << " (depth " 
00288       << (get_interior_point(NodePath()) - get_surface_point(NodePath())).length() 
00289       << ")\n";
00290   }
00291   indent(out, indent_level + 2)
00292     << "respect_prev_transform = " << get_respect_prev_transform() << "\n";
00293 }
00294 
00295 ////////////////////////////////////////////////////////////////////
00296 //     Function: CollisionEntry::check_clip_planes
00297 //       Access: Private
00298 //  Description: Checks whether the into_node_path has a
00299 //               ClipPlaneAttrib defined.
00300 ////////////////////////////////////////////////////////////////////
00301 void CollisionEntry::
00302 check_clip_planes() {
00303   _into_clip_planes = DCAST(ClipPlaneAttrib, _into_node_path.get_net_state()->get_attrib(ClipPlaneAttrib::get_class_slot()));
00304   _flags |= F_checked_clip_planes;
00305 }
 All Classes Functions Variables Enumerations