Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/collide/collisionPlane.cxx

Go to the documentation of this file.
00001 // Filename: collisionPlane.cxx
00002 // Created by:  drose (25Apr00)
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 
00020 #include "collisionPlane.h"
00021 #include "collisionHandler.h"
00022 #include "collisionEntry.h"
00023 #include "collisionSphere.h"
00024 #include "collisionRay.h"
00025 #include "config_collide.h"
00026 
00027 #include "pointerToArray.h"
00028 #include "geomNode.h"
00029 #include "geom.h"
00030 #include "datagram.h"
00031 #include "datagramIterator.h"
00032 #include "bamReader.h"
00033 #include "bamWriter.h"
00034 #include "omniBoundingVolume.h"
00035 #include "geomQuad.h"
00036 
00037 TypeHandle CollisionPlane::_type_handle;
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: CollisionPlane::make_copy
00041 //       Access: Public, Virtual
00042 //  Description:
00043 ////////////////////////////////////////////////////////////////////
00044 CollisionSolid *CollisionPlane::
00045 make_copy() {
00046   return new CollisionPlane(*this);
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: CollisionPlane::xform
00051 //       Access: Public, Virtual
00052 //  Description: Transforms the solid by the indicated matrix.
00053 ////////////////////////////////////////////////////////////////////
00054 void CollisionPlane::
00055 xform(const LMatrix4f &mat) {
00056   _plane = _plane * mat;
00057   mark_viz_stale();
00058   mark_bound_stale();
00059 }
00060 
00061 ////////////////////////////////////////////////////////////////////
00062 //     Function: CollisionPlane::get_collision_origin
00063 //       Access: Public, Virtual
00064 //  Description: Returns the point in space deemed to be the "origin"
00065 //               of the solid for collision purposes.  The closest
00066 //               intersection point to this origin point is considered
00067 //               to be the most significant.
00068 ////////////////////////////////////////////////////////////////////
00069 LPoint3f CollisionPlane::
00070 get_collision_origin() const {
00071   // No real sensible origin exists for a plane.  We return 0, 0, 0,
00072   // without even bothering to ensure that that point exists on the
00073   // plane.
00074   return LPoint3f::origin();
00075 }
00076 
00077 ////////////////////////////////////////////////////////////////////
00078 //     Function: CollisionPlane::output
00079 //       Access: Public, Virtual
00080 //  Description:
00081 ////////////////////////////////////////////////////////////////////
00082 void CollisionPlane::
00083 output(ostream &out) const {
00084   out << "cplane, (" << _plane << ")";
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////
00088 //     Function: CollisionPlane::recompute_bound
00089 //       Access: Protected, Virtual
00090 //  Description:
00091 ////////////////////////////////////////////////////////////////////
00092 BoundingVolume *CollisionPlane::
00093 recompute_bound() {
00094   // Planes always have an infinite bounding volume.
00095   BoundedObject::recompute_bound();
00096   // Less than ideal: we throw away whatever we just allocated in
00097   // BoundedObject.
00098   return set_bound_ptr(new OmniBoundingVolume);
00099 }
00100 
00101 ////////////////////////////////////////////////////////////////////
00102 //     Function: CollisionPlane::test_intersection_from_sphere
00103 //       Access: Public, Virtual
00104 //  Description:
00105 ////////////////////////////////////////////////////////////////////
00106 PT(CollisionEntry) CollisionPlane::
00107 test_intersection_from_sphere(const CollisionEntry &entry) const {
00108   const CollisionSphere *sphere;
00109   DCAST_INTO_R(sphere, entry.get_from(), 0);
00110 
00111   LPoint3f from_center = sphere->get_center() * entry.get_wrt_space();
00112   LVector3f from_radius_v =
00113     LVector3f(sphere->get_radius(), 0.0f, 0.0f) * entry.get_wrt_space();
00114   float from_radius = length(from_radius_v);
00115 
00116   float dist = dist_to_plane(from_center);
00117   if (dist > from_radius) {
00118     // No intersection.
00119     return NULL;
00120   }
00121 
00122   if (collide_cat.is_debug()) {
00123     collide_cat.debug()
00124       << "intersection detected from " << *entry.get_from_node() << " into "
00125       << entry.get_into_node_path() << "\n";
00126   }
00127   PT(CollisionEntry) new_entry = new CollisionEntry(entry);
00128 
00129   LVector3f from_normal = get_normal() * entry.get_inv_wrt_space();
00130   float from_depth = from_radius - dist;
00131 
00132   new_entry->set_into_surface_normal(get_normal());
00133   new_entry->set_from_surface_normal(from_normal);
00134   new_entry->set_from_depth(from_depth);
00135   new_entry->set_into_intersection_point(from_center - get_normal() * dist);
00136 
00137   return new_entry;
00138 }
00139 
00140 ////////////////////////////////////////////////////////////////////
00141 //     Function: CollisionPlane::test_intersection_from_ray
00142 //       Access: Public, Virtual
00143 //  Description:
00144 ////////////////////////////////////////////////////////////////////
00145 PT(CollisionEntry) CollisionPlane::
00146 test_intersection_from_ray(const CollisionEntry &entry) const {
00147   const CollisionRay *ray;
00148   DCAST_INTO_R(ray, entry.get_from(), 0);
00149 
00150   LPoint3f from_origin = ray->get_origin() * entry.get_wrt_space();
00151   LVector3f from_direction = ray->get_direction() * entry.get_wrt_space();
00152 
00153   float t;
00154   if (!_plane.intersects_line(t, from_origin, from_direction)) {
00155     // No intersection.
00156     return NULL;
00157   }
00158 
00159   if (t < 0.0f) {
00160     // The intersection point is before the start of the ray.
00161     return NULL;
00162   }
00163 
00164   if (collide_cat.is_debug()) {
00165     collide_cat.debug()
00166       << "intersection detected from " << *entry.get_from_node() << " into "
00167       << entry.get_into_node_path() << "\n";
00168   }
00169   PT(CollisionEntry) new_entry = new CollisionEntry(entry);
00170 
00171   LPoint3f into_intersection_point = from_origin + t * from_direction;
00172   new_entry->set_into_surface_normal(get_normal());
00173   new_entry->set_into_intersection_point(into_intersection_point);
00174 
00175   return new_entry;
00176 }
00177 
00178 ////////////////////////////////////////////////////////////////////
00179 //     Function: CollisionPlane::fill_viz_geom
00180 //       Access: Protected, Virtual
00181 //  Description: Fills the _viz_geom GeomNode up with Geoms suitable
00182 //               for rendering this solid.
00183 ////////////////////////////////////////////////////////////////////
00184 void CollisionPlane::
00185 fill_viz_geom() {
00186   if (collide_cat.is_debug()) {
00187     collide_cat.debug()
00188       << "Recomputing viz for " << *this << "\n";
00189   }
00190 
00191   // Since we can't represent an infinite plane, we'll have to be
00192   // satisfied with drawing a big polygon.  Choose four points on the
00193   // plane to be the corners of the polygon.
00194 
00195   // We must choose four points fairly reasonably spread apart on
00196   // the plane.  We'll start with a center point and one corner
00197   // point, and then use cross products to find the remaining three
00198   // corners of a square.
00199 
00200   // The center point will be on the axis with the largest
00201   // coefficent.  The first corner will be diagonal in the other two
00202   // dimensions.
00203 
00204   LPoint3f cp;
00205   LVector3f p1, p2, p3, p4;
00206 
00207   LVector3f normal = get_normal();
00208   float D = _plane._d;
00209 
00210   if (fabs(normal[0]) > fabs(normal[1]) &&
00211       fabs(normal[0]) > fabs(normal[2])) {
00212     // X has the largest coefficient.
00213     cp.set(-D / normal[0], 0.0f, 0.0f);
00214     p1 = LPoint3f(-(normal[1] + normal[2] + D)/normal[0], 1.0f, 1.0f) - cp;
00215 
00216   } else if (fabs(normal[1]) > fabs(normal[2])) {
00217     // Y has the largest coefficient.
00218     cp.set(0.0f, -D / normal[1], 0.0f);
00219     p1 = LPoint3f(1.0f, -(normal[0] + normal[2] + D)/normal[1], 1.0f) - cp;
00220 
00221   } else {
00222     // Z has the largest coefficient.
00223     cp.set(0.0f, 0.0f, -D / normal[2]);
00224     p1 = LPoint3f(1.0f, 1.0f, -(normal[0] + normal[1] + D)/normal[2]) - cp;
00225   }
00226 
00227   p1.normalize();
00228   p2 = cross(normal, p1);
00229   p3 = cross(normal, p2);
00230   p4 = cross(normal, p3);
00231 
00232   static const double plane_scale = 10.0;
00233 
00234   PTA_Vertexf verts;
00235   verts.push_back(cp + p1 * plane_scale);
00236   verts.push_back(cp + p2 * plane_scale);
00237   verts.push_back(cp + p3 * plane_scale);
00238   verts.push_back(cp + p4 * plane_scale);
00239 
00240   GeomQuad *quad = new GeomQuad;
00241   quad->set_coords(verts);
00242   quad->set_num_prims(1);
00243 
00244   _viz_geom->add_geom(quad, get_solid_viz_state());
00245   _viz_geom->add_geom(quad, get_wireframe_viz_state());
00246 }
00247 
00248 ////////////////////////////////////////////////////////////////////
00249 //     Function: CollisionPlane::write_datagram
00250 //       Access: Public
00251 //  Description: Function to write the important information in
00252 //               the particular object to a Datagram
00253 ////////////////////////////////////////////////////////////////////
00254 void CollisionPlane::
00255 write_datagram(BamWriter *manager, Datagram &me)
00256 {
00257   CollisionSolid::write_datagram(manager, me);
00258   _plane.write_datagram(me);
00259 }
00260 
00261 ////////////////////////////////////////////////////////////////////
00262 //     Function: CollisionPlane::fillin
00263 //       Access: Protected
00264 //  Description: Function that reads out of the datagram (or asks
00265 //               manager to read) all of the data that is needed to
00266 //               re-create this object and stores it in the appropiate
00267 //               place
00268 ////////////////////////////////////////////////////////////////////
00269 void CollisionPlane::
00270 fillin(DatagramIterator& scan, BamReader* manager)
00271 {
00272   CollisionSolid::fillin(scan, manager);
00273   _plane.read_datagram(scan);
00274 }
00275 
00276 ////////////////////////////////////////////////////////////////////
00277 //     Function: CollisionPlane::make_CollisionPlane
00278 //       Access: Protected
00279 //  Description: Factory method to generate a CollisionPlane object
00280 ////////////////////////////////////////////////////////////////////
00281 TypedWritable* CollisionPlane::
00282 make_CollisionPlane(const FactoryParams &params)
00283 {
00284   CollisionPlane *me = new CollisionPlane;
00285   DatagramIterator scan;
00286   BamReader *manager;
00287 
00288   parse_params(params, scan, manager);
00289   me->fillin(scan, manager);
00290   return me;
00291 }
00292 
00293 ////////////////////////////////////////////////////////////////////
00294 //     Function: CollisionPlane::register_with_factory
00295 //       Access: Public, Static
00296 //  Description: Factory method to generate a CollisionPlane object
00297 ////////////////////////////////////////////////////////////////////
00298 void CollisionPlane::
00299 register_with_read_factory(void)
00300 {
00301   BamReader::get_factory()->register_factory(get_class_type(), make_CollisionPlane);
00302 }

Generated on Fri May 2 00:35:38 2003 for Panda by doxygen1.3