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

panda/src/collide/collisionSolid.cxx

Go to the documentation of this file.
00001 // Filename: collisionSolid.cxx
00002 // Created by:  drose (24Apr00)
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 "collisionSolid.h"
00021 #include "config_collide.h"
00022 #include "collisionSphere.h"
00023 #include "collisionRay.h"
00024 #include "collisionSegment.h"
00025 
00026 #include "datagram.h"
00027 #include "datagramIterator.h"
00028 #include "bamReader.h"
00029 #include "bamWriter.h"
00030 #include "indent.h"
00031 #include "cullFaceAttrib.h"
00032 #include "colorAttrib.h"
00033 #include "renderModeAttrib.h"
00034 #include "transparencyAttrib.h"
00035 #include "geomNode.h"
00036 
00037 TypeHandle CollisionSolid::_type_handle;
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: CollisionSolid::Constructor
00041 //       Access: Public
00042 //  Description:
00043 ////////////////////////////////////////////////////////////////////
00044 CollisionSolid::
00045 CollisionSolid() {
00046   _viz_geom_stale = true;
00047   _tangible = true;
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: CollisionSolid::Copy Constructor
00052 //       Access: Public
00053 //  Description:
00054 ////////////////////////////////////////////////////////////////////
00055 CollisionSolid::
00056 CollisionSolid(const CollisionSolid &copy) :
00057   _tangible(copy._tangible)
00058 {
00059   // Actually, there's not a whole lot here we want to copy.
00060   _viz_geom_stale = true;
00061 }
00062 
00063 ////////////////////////////////////////////////////////////////////
00064 //     Function: CollisionSolid::Destructor
00065 //       Access: Public, Virtual
00066 //  Description:
00067 ////////////////////////////////////////////////////////////////////
00068 CollisionSolid::
00069 ~CollisionSolid() {
00070 }
00071 
00072 ////////////////////////////////////////////////////////////////////
00073 //     Function: CollisionSolid::test_intersection
00074 //       Access: Public, Virtual
00075 //  Description: Tests for a collision between this object (which is
00076 //               also the "from" object in the entry) and the "into"
00077 //               object.  If a collision is detected, returns a new
00078 //               CollisionEntry object that records the collision;
00079 //               otherwise, returns NULL.
00080 ////////////////////////////////////////////////////////////////////
00081 PT(CollisionEntry) CollisionSolid::
00082 test_intersection(const CollisionEntry &) const {
00083   report_undefined_from_intersection(get_type());
00084   return NULL;
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////
00088 //     Function: CollisionSolid::get_viz
00089 //       Access: Public
00090 //  Description: Returns a GeomNode that may be rendered to visualize
00091 //               the CollisionSolid.  This is used during the cull
00092 //               traversal to render the CollisionNodes that have been
00093 //               made visible.
00094 ////////////////////////////////////////////////////////////////////
00095 GeomNode *CollisionSolid::
00096 get_viz() const {
00097   if (_viz_geom_stale) {
00098     if (_viz_geom == (GeomNode *)NULL) {
00099       ((CollisionSolid *)this)->_viz_geom = new GeomNode("viz");
00100     } else {
00101       _viz_geom->remove_all_geoms();
00102     }
00103     ((CollisionSolid *)this)->fill_viz_geom();
00104     ((CollisionSolid *)this)->_viz_geom_stale = false;
00105   }
00106   return _viz_geom;
00107 }
00108 
00109 ////////////////////////////////////////////////////////////////////
00110 //     Function: CollisionSolid::output
00111 //       Access: Public, Virtual
00112 //  Description:
00113 ////////////////////////////////////////////////////////////////////
00114 void CollisionSolid::
00115 output(ostream &out) const {
00116   out << get_type();
00117 }
00118 
00119 ////////////////////////////////////////////////////////////////////
00120 //     Function: CollisionSolid::write
00121 //       Access: Public, Virtual
00122 //  Description:
00123 ////////////////////////////////////////////////////////////////////
00124 void CollisionSolid::
00125 write(ostream &out, int indent_level) const {
00126   indent(out, indent_level) << (*this) << "\n";
00127 }
00128 
00129 ////////////////////////////////////////////////////////////////////
00130 //     Function: CollisionSolid::test_intersection_from_sphere
00131 //       Access: Protected, Virtual
00132 //  Description: This is part of the double-dispatch implementation of
00133 //               test_intersection().  It is called when the "from"
00134 //               object is a sphere.
00135 ////////////////////////////////////////////////////////////////////
00136 PT(CollisionEntry) CollisionSolid::
00137 test_intersection_from_sphere(const CollisionEntry &) const {
00138   report_undefined_intersection_test(CollisionSphere::get_class_type(),
00139                                      get_type());
00140   return NULL;
00141 }
00142 
00143 ////////////////////////////////////////////////////////////////////
00144 //     Function: CollisionSolid::test_intersection_from_ray
00145 //       Access: Protected, Virtual
00146 //  Description: This is part of the double-dispatch implementation of
00147 //               test_intersection().  It is called when the "from"
00148 //               object is a ray.
00149 ////////////////////////////////////////////////////////////////////
00150 PT(CollisionEntry) CollisionSolid::
00151 test_intersection_from_ray(const CollisionEntry &) const {
00152   report_undefined_intersection_test(CollisionRay::get_class_type(),
00153                                      get_type());
00154   return NULL;
00155 }
00156 
00157 ////////////////////////////////////////////////////////////////////
00158 //     Function: CollisionSolid::test_intersection_from_segment
00159 //       Access: Protected, Virtual
00160 //  Description: This is part of the double-dispatch implementation of
00161 //               test_intersection().  It is called when the "from"
00162 //               object is a segment.
00163 ////////////////////////////////////////////////////////////////////
00164 PT(CollisionEntry) CollisionSolid::
00165 test_intersection_from_segment(const CollisionEntry &) const {
00166   report_undefined_intersection_test(CollisionSegment::get_class_type(),
00167                                      get_type());
00168   return NULL;
00169 }
00170 
00171 #ifndef NDEBUG
00172 class CollisionSolidUndefinedPair {
00173 public:
00174   CollisionSolidUndefinedPair(TypeHandle a, TypeHandle b) :
00175     _a(a), _b(b)
00176   {}
00177   bool operator < (const CollisionSolidUndefinedPair &other) const {
00178     if (_a != other._a) {
00179       return _a < other._a;
00180     }
00181     return _b < other._b;
00182   }
00183 
00184   TypeHandle _a;
00185   TypeHandle _b;
00186 };
00187 #endif  // NDEBUG
00188 
00189 ////////////////////////////////////////////////////////////////////
00190 //     Function: CollisionSolid::report_undefined_intersection_test
00191 //       Access: Protected, Static
00192 //  Description: Outputs a message the first time an intersection test
00193 //               is attempted that isn't defined, and explains a bit
00194 //               about what it means.
00195 ////////////////////////////////////////////////////////////////////
00196 void CollisionSolid::
00197 report_undefined_intersection_test(TypeHandle from_type, TypeHandle into_type) {
00198 #ifndef NDEBUG
00199   typedef pset<CollisionSolidUndefinedPair> Reported;
00200   static Reported reported;
00201 
00202   if (reported.insert(CollisionSolidUndefinedPair(from_type, into_type)).second) {
00203     collide_cat.error()
00204       << "Invalid attempt to detect collision from " << from_type << " into "
00205       << into_type << "!\n\n"
00206 
00207       "This means that a " << from_type << " object attempted to test for an\n"
00208       "intersection into a " << into_type << " object.  This intersection\n"
00209       "test has not yet been defined; it is possible the " << into_type << "\n"
00210       "object is not intended to be collidable.  Consider calling\n"
00211       "set_into_collide_mask(0) on the " << into_type << " object, or\n"
00212       "set_from_collide_mask(0) on the " << from_type << " object.\n\n";
00213   }
00214 #endif  // NDEBUG
00215 }
00216 
00217 ////////////////////////////////////////////////////////////////////
00218 //     Function: CollisionSolid::report_undefined_from_intersection
00219 //       Access: Protected, Static
00220 //  Description: Outputs a message the first time an intersection test
00221 //               is attempted that isn't defined, and explains a bit
00222 //               about what it means.
00223 ////////////////////////////////////////////////////////////////////
00224 void CollisionSolid::
00225 report_undefined_from_intersection(TypeHandle from_type) {
00226 #ifndef NDEBUG
00227   typedef pset<TypeHandle> Reported;
00228   static Reported reported;
00229 
00230   if (reported.insert(from_type).second) {
00231     collide_cat.error()
00232       << "Invalid attempt to detect collision from " << from_type << "!\n\n"
00233       
00234       "This means that a " << from_type << " object was added to a\n"
00235       "CollisionTraverser as if it were a colliding object.  However,\n"
00236       "no implementation for this kind of object has yet been defined\n"
00237       "to collide with other objects.\n\n";
00238   }
00239 #endif  // NDEBUG
00240 }
00241 
00242 ////////////////////////////////////////////////////////////////////
00243 //     Function: CollisionSolid::write_datagram
00244 //       Access: Public
00245 //  Description: Function to write the important information in
00246 //               the particular object to a Datagram
00247 ////////////////////////////////////////////////////////////////////
00248 void CollisionSolid::
00249 write_datagram(BamWriter *, Datagram &me)
00250 {
00251   me.add_uint8(_tangible);
00252 }
00253 
00254 ////////////////////////////////////////////////////////////////////
00255 //     Function: CollisionSolid::fillin
00256 //       Access: Protected
00257 //  Description: Function that reads out of the datagram (or asks
00258 //               manager to read) all of the data that is needed to
00259 //               re-create this object and stores it in the appropiate
00260 //               place
00261 ////////////////////////////////////////////////////////////////////
00262 void CollisionSolid::
00263 fillin(DatagramIterator& scan, BamReader*)
00264 {
00265   _tangible = (scan.get_uint8() != 0);
00266 }
00267 
00268 
00269 ////////////////////////////////////////////////////////////////////
00270 //     Function: CollisionSolid::fill_viz_geom
00271 //       Access: Protected, Virtual
00272 //  Description: Fills the _viz_geom GeomNode up with Geoms suitable
00273 //               for rendering this solid.
00274 ////////////////////////////////////////////////////////////////////
00275 void CollisionSolid::
00276 fill_viz_geom() {
00277 }
00278 
00279 ////////////////////////////////////////////////////////////////////
00280 //     Function: CollisionSolid::get_solid_viz_state
00281 //       Access: Protected
00282 //  Description: Returns a RenderState for rendering collision
00283 //               visualizations in solid.  This automatically returns
00284 //               the appropriate state according to the setting of
00285 //               _tangible.
00286 ////////////////////////////////////////////////////////////////////
00287 CPT(RenderState) CollisionSolid::
00288 get_solid_viz_state() {
00289   // Once someone asks for this pointer, we hold its reference count
00290   // and never free it.
00291   static CPT(RenderState) base_state = (const RenderState *)NULL;
00292   if (base_state == (const RenderState *)NULL) {
00293     base_state = RenderState::make
00294       (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
00295        RenderModeAttrib::make(RenderModeAttrib::M_filled),
00296        TransparencyAttrib::make(TransparencyAttrib::M_alpha));
00297   }
00298 
00299   if (_tangible) {
00300     static CPT(RenderState) tangible_state = (const RenderState *)NULL;
00301     if (tangible_state == (const RenderState *)NULL) {
00302       tangible_state = base_state->add_attrib
00303         (ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 0.5f)));
00304     }
00305     return tangible_state;
00306 
00307   } else {
00308     static CPT(RenderState) intangible_state = (const RenderState *)NULL;
00309     if (intangible_state == (const RenderState *)NULL) {
00310       intangible_state = base_state->add_attrib
00311         (ColorAttrib::make_flat(Colorf(1.0f, 0.3f, 0.5f, 0.5f)));
00312     }
00313     return intangible_state;
00314   }
00315 }
00316 
00317 
00318 ////////////////////////////////////////////////////////////////////
00319 //     Function: CollisionSolid::get_wireframe_viz_state
00320 //       Access: Protected
00321 //  Description: Returns a RenderState for rendering collision
00322 //               visualizations in wireframe.  This automatically returns
00323 //               the appropriate state according to the setting of
00324 //               _tangible.
00325 ////////////////////////////////////////////////////////////////////
00326 CPT(RenderState) CollisionSolid::
00327 get_wireframe_viz_state() {
00328   // Once someone asks for this pointer, we hold its reference count
00329   // and never free it.
00330   static CPT(RenderState) base_state = (const RenderState *)NULL;
00331   if (base_state == (const RenderState *)NULL) {
00332     base_state = RenderState::make
00333       (CullFaceAttrib::make(CullFaceAttrib::M_cull_none),
00334        RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
00335        TransparencyAttrib::make(TransparencyAttrib::M_none));
00336   }
00337 
00338   if (_tangible) {
00339     static CPT(RenderState) tangible_state = (const RenderState *)NULL;
00340     if (tangible_state == (const RenderState *)NULL) {
00341       tangible_state = base_state->add_attrib
00342         (ColorAttrib::make_flat(Colorf(0.0f, 0.0f, 1.0f, 1.0f)));
00343     }
00344     return tangible_state;
00345 
00346   } else {
00347     static CPT(RenderState) intangible_state = (const RenderState *)NULL;
00348     if (intangible_state == (const RenderState *)NULL) {
00349       intangible_state = base_state->add_attrib
00350         (ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 0.0f, 1.0f)));
00351     }
00352     return intangible_state;
00353   }
00354 }
00355 
00356 
00357 ////////////////////////////////////////////////////////////////////
00358 //     Function: CollisionSolid::get_other_viz_state
00359 //       Access: Protected
00360 //  Description: Returns a RenderState for rendering collision
00361 //               visualizations for things that are neither solid nor
00362 //               exactly wireframe, like rays and segments.
00363 ////////////////////////////////////////////////////////////////////
00364 CPT(RenderState) CollisionSolid::
00365 get_other_viz_state() {
00366   // Once someone asks for this pointer, we hold its reference count
00367   // and never free it.
00368   static CPT(RenderState) base_state = (const RenderState *)NULL;
00369   if (base_state == (const RenderState *)NULL) {
00370     base_state = RenderState::make
00371       (CullFaceAttrib::make(CullFaceAttrib::M_cull_clockwise),
00372        RenderModeAttrib::make(RenderModeAttrib::M_filled),
00373        TransparencyAttrib::make(TransparencyAttrib::M_alpha));
00374   }
00375 
00376   // We don't bother to make a distinction here between tangible and
00377   // intangible.
00378   return base_state;
00379 }
00380 

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