Panda3D

collisionDSSolid.cxx

00001 // Filename: collisionDSSolid.cxx
00002 // Created by:  Dave Schuyler (05Apr06)
00003 // Based on collision tube by:  drose
00004 //
00005 ////////////////////////////////////////////////////////////////////
00006 //
00007 // PANDA 3D SOFTWARE
00008 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00009 //
00010 // All use of this software is subject to the terms of the revised BSD
00011 // license.  You should have received a copy of this license along
00012 // with this source code in a file named "LICENSE."
00013 //
00014 ////////////////////////////////////////////////////////////////////
00015 
00016 #include "collisionDSSolid.h"
00017 #include "collisionSphere.h"
00018 #include "collisionLine.h"
00019 #include "collisionRay.h"
00020 #include "collisionSegment.h"
00021 #include "collisionHandler.h"
00022 #include "collisionEntry.h"
00023 #include "boundingSphere.h"
00024 #include "config_collide.h"
00025 #include "look_at.h"
00026 #include "geom.h"
00027 #include "geomNode.h"
00028 #include "geometricBoundingVolume.h"
00029 #include "datagram.h"
00030 #include "datagramIterator.h"
00031 #include "bamReader.h"
00032 #include "bamWriter.h"
00033 #include "cmath.h"
00034 #include "transformState.h"
00035 #include "geom.h"
00036 #include "geomTristrips.h"
00037 #include "geomTrifans.h"
00038 #include "geomLinestrips.h"
00039 #include "geomVertexWriter.h"
00040 
00041 PStatCollector CollisionDSSolid::_volume_pcollector(
00042     "Collision Volumes:CollisionDSSolid");
00043 PStatCollector CollisionDSSolid::_test_pcollector(
00044     "Collision Tests:CollisionDSSolid");
00045 TypeHandle CollisionDSSolid::_type_handle;
00046 
00047 ////////////////////////////////////////////////////////////////////
00048 //     Function: CollisionDSSolid::make_copy
00049 //       Access: Public, Virtual
00050 //  Description:
00051 ////////////////////////////////////////////////////////////////////
00052 CollisionSolid *CollisionDSSolid::
00053 make_copy() {
00054   return new CollisionDSSolid(*this);
00055 }
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //     Function: CollisionDSSolid::test_intersection
00059 //       Access: Public, Virtual
00060 //  Description:
00061 ////////////////////////////////////////////////////////////////////
00062 PT(CollisionEntry) CollisionDSSolid::
00063 test_intersection(const CollisionEntry &entry) const {
00064   return entry.get_into()->test_intersection_from_ds_solid(entry);
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: CollisionDSSolid::xform
00069 //       Access: Public, Virtual
00070 //  Description: Transforms the solid by the indicated matrix.
00071 ////////////////////////////////////////////////////////////////////
00072 void CollisionDSSolid::
00073 xform(const LMatrix4f &mat) {
00074   _center_a = _center_a * mat;
00075   _center_b = _center_b * mat;
00076   _plane_a = _plane_a * mat;
00077   _plane_b = _plane_b * mat;
00078 
00079   // This is a little cheesy and fails miserably in the presence of a
00080   // non-uniform scale.
00081   LVector3f radius_v = LVector3f(_radius_a, 0.0f, 0.0f) * mat;
00082   _radius_a = length(radius_v);
00083 
00084   recalc_internals();
00085   CollisionSolid::xform(mat);
00086 }
00087 
00088 ////////////////////////////////////////////////////////////////////
00089 //     Function: CollisionDSSolid::get_collision_origin
00090 //       Access: Public, Virtual
00091 //  Description: Returns the point in space deemed to be the "origin"
00092 //               of the solid for collision purposes.  The closest
00093 //               intersection point to this origin point is considered
00094 //               to be the most significant.
00095 ////////////////////////////////////////////////////////////////////
00096 LPoint3f CollisionDSSolid::
00097 get_collision_origin() const {
00098   #if 1  
00099   LVector3f vec = _center_b - _center_a;
00100   float distance = vec.length();
00101   if (vec.normalize()) {
00102     // "Let" a few variables
00103     float dist_squared = distance * distance;
00104     float dist_doubled = 2.0f * distance;
00105     float radius_a_squared = _radius_a * _radius_a;
00106     float radius_b_squared = _radius_b * _radius_b;
00107     float n = dist_squared - radius_a_squared + radius_b_squared;
00108     
00109     // Get the lens center point on the intersection plane between
00110     // sphere A and sphere B
00111     LVector3f lens_center = _center_a + vec * (n / dist_doubled);
00112     return lens_center;
00113   } else {
00114     // Since both spheres are in the same place, just return
00115     // either of the centers
00116     return _center_a;
00117   }
00118   #else
00119   LVector3f vec = _center_b - _center_a;
00120   return _center_a + (vec * 0.5);
00121   #endif
00122 }
00123 
00124 ////////////////////////////////////////////////////////////////////
00125 //     Function: CollisionDSSolid::get_volume_pcollector
00126 //       Access: Public, Virtual
00127 //  Description: Returns a PStatCollector that is used to count the
00128 //               number of bounding volume tests made against a solid
00129 //               of this type in a given frame.
00130 ////////////////////////////////////////////////////////////////////
00131 PStatCollector &CollisionDSSolid::
00132 get_volume_pcollector() {
00133   return _volume_pcollector;
00134 }
00135 
00136 ////////////////////////////////////////////////////////////////////
00137 //     Function: CollisionDSSolid::get_test_pcollector
00138 //       Access: Public, Virtual
00139 //  Description: Returns a PStatCollector that is used to count the
00140 //               number of intersection tests made against a solid
00141 //               of this type in a given frame.
00142 ////////////////////////////////////////////////////////////////////
00143 PStatCollector &CollisionDSSolid::
00144 get_test_pcollector() {
00145   return _test_pcollector;
00146 }
00147 
00148 ////////////////////////////////////////////////////////////////////
00149 //     Function: CollisionDSSolid::output
00150 //       Access: Public, Virtual
00151 //  Description:
00152 ////////////////////////////////////////////////////////////////////
00153 void CollisionDSSolid::
00154 output(ostream &out) const {
00155   out << "DSSolid, a (" 
00156       << _center_a << "), ra "
00157       << _radius_a << ", b (" 
00158       << _center_b << "), rb "
00159       << _radius_b << ", pa (" 
00160       << _plane_a << "), pb "
00161       << _plane_b << ")";
00162 }
00163 
00164 ////////////////////////////////////////////////////////////////////
00165 //     Function: CollisionDSSolid::compute_internal_bounds
00166 //       Access: Protected, Virtual
00167 //  Description:
00168 ////////////////////////////////////////////////////////////////////
00169 PT(BoundingVolume) CollisionDSSolid::
00170 compute_internal_bounds() const {
00171   PT(BoundingVolume) bound = CollisionSolid::compute_internal_bounds();
00172 
00173   if (bound->is_of_type(GeometricBoundingVolume::get_class_type())) {
00174     GeometricBoundingVolume *gbound;
00175     DCAST_INTO_R(gbound, bound, bound);
00176 
00177     LVector3f vec = _center_b - _center_a;
00178     float distance = vec.length();
00179     if (vec.normalize()) {
00180       // There is some distance between the centers, so the intersection
00181       // between them is some kind of lens.
00182       
00183       // "Let" a few variables
00184       float dist_squared = distance * distance;
00185       float dist_doubled = 2.0f * distance;
00186       float radius_a_squared = _radius_a * _radius_a;
00187       float radius_b_squared = _radius_b * _radius_b;
00188       float n = dist_squared - radius_a_squared + radius_b_squared;
00189       float m = 4.0f * dist_squared * radius_a_squared - (n * n);
00190 
00191       cerr<<"distance:"<<distance<<", _radius_a:"<<_radius_a
00192           <<", _radius_b"<<_radius_b<<", n:"<<n<<"\n";
00193       cerr<<"(1.0f / dist_doubled):"<<(1.0f / dist_doubled)
00194           <<", m:"<<m<<"\n";
00195       assert(m > 0.0f);
00196       
00197       // Get the lens center point on the intersection plane between
00198       // sphere A and sphere B
00199       LPoint3f lens_center = _center_a + vec * (n / dist_doubled);
00200       _lens_radius = (1.0f / dist_doubled) * sqrt(m);
00201       cerr<<"lens_center:"<<lens_center<<", lens_radius:"<<_lens_radius<<"\n";
00202       
00203       //TODO: account for cutting planes (which could make the sphere
00204       // smaller, which is an optimization).
00205       
00206       BoundingSphere sphere(lens_center, _lens_radius);
00207       gbound->extend_by(&sphere);
00208     } else {
00209       // Both endpoints are coincident; therefore, the bounding volume
00210       // is a sphere.
00211       //TODO: account for cutting planes (which could make the sphere
00212       // smaller, which is an optimization).
00213       BoundingSphere sphere(_center_a, _radius_a);
00214       gbound->extend_by(&sphere);
00215     }
00216   }
00217 
00218   return bound;
00219 }
00220 
00221 ////////////////////////////////////////////////////////////////////
00222 //     Function: CollisionDSSolid::test_intersection_from_sphere
00223 //       Access: Public, Virtual
00224 //  Description:
00225 ////////////////////////////////////////////////////////////////////
00226 PT(CollisionEntry) CollisionDSSolid::
00227 test_intersection_from_sphere(const CollisionEntry &entry) const {
00228   const CollisionSphere *sphere;
00229   DCAST_INTO_R(sphere, entry.get_from(), 0);
00230   cerr<<"CollisionDSSolid::test_intersection_from_ds_solid\n";
00231 
00232   CPT(TransformState) wrt_space = entry.get_wrt_space();
00233 
00234   const LMatrix4f &wrt_mat = wrt_space->get_mat();
00235 
00236   LPoint3f from_a = sphere->get_center() * wrt_mat;
00237   LPoint3f from_b = from_a;
00238 
00239   LVector3f from_direction = from_b - from_a;
00240 
00241   LPoint3f from_center = sphere->get_center() * wrt_mat;
00242   LVector3f from_radius_v =
00243     LVector3f(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
00244   float from_radius = length(from_radius_v);
00245 
00246   LPoint3f sa_into_center = get_center_a();
00247   float sa_into_radius = get_radius_a();
00248   LVector3f sa_vec = from_center - sa_into_center;
00249   float sa_distance_squared = dot(sa_vec, sa_vec);
00250   float sa_and_from_radii_squared = (
00251       sa_into_radius + from_radius) * (sa_into_radius + from_radius);
00252   if (sa_distance_squared > sa_and_from_radii_squared) {
00253     // No intersection.
00254     return NULL;
00255   }
00256 
00257   LPoint3f sb_into_center = get_center_b();
00258   float sb_into_radius = get_radius_b();
00259   LVector3f sb_vec = from_center - sb_into_center;
00260   float sb_distance_squared = dot(sb_vec, sb_vec);
00261   float sb_and_from_radii_squared = (
00262       sb_into_radius + from_radius) * (sb_into_radius + from_radius);
00263   if (sb_distance_squared > sb_and_from_radii_squared) {
00264     // No intersection.
00265     return NULL;
00266   }
00267 
00268   float pa_distance = dist_to_plane_a(from_center);
00269   if (pa_distance > from_radius) {
00270     // No intersection.
00271     return NULL;
00272   }
00273 
00274   float pb_distance = dist_to_plane_b(from_center);
00275   if (pb_distance > from_radius) {
00276     // No intersection.
00277     return NULL;
00278   }
00279 
00280   if (collide_cat.is_debug()) {
00281     collide_cat.debug()
00282       << "intersection detected from " << entry.get_from_node_path()
00283       << " into " << entry.get_into_node_path() << "\n";
00284   }
00285 
00286   LVector3f surface_normal;
00287   LPoint3f surface_point;
00288   float spheres = sqrtf(sa_distance_squared) - sqrtf(sb_distance_squared);
00289   float planes = pa_distance - pb_distance;
00290   if (spheres > planes) {
00291     if (spheres > 0) {
00292       // sphere_a is the furthest
00293       cerr<<"sphere_a is the furthest"<<"\n";
00294       float vec_length = sa_vec.length();
00295       if (IS_NEARLY_ZERO(vec_length)) {
00296         // The centers are coincident, use an arbitrary normal.
00297         surface_normal.set(1.0, 0.0, 0.0);
00298       } else {
00299         surface_normal = sa_vec / vec_length;
00300       }
00301       surface_point = sa_into_center + surface_normal * sa_into_radius;
00302     } else {
00303       // sphere_b is the furthest
00304       cerr<<"sphere_b is the furthest"<<"\n";
00305       float vec_length = sb_vec.length();
00306       if (IS_NEARLY_ZERO(vec_length)) {
00307         // The centers are coincident, use an arbitrary normal.
00308         surface_normal.set(1.0, 0.0, 0.0);
00309       } else {
00310         surface_normal = sb_vec / vec_length;
00311       }
00312       surface_point = sb_into_center + surface_normal * sb_into_radius;
00313     }
00314   } else {
00315     if (planes > 0) {
00316       // plane_a is the furthest
00317       cerr<<"plane_a is the furthest"<<"\n";
00318       surface_normal = _plane_a.get_normal();
00319       surface_point = from_center - surface_normal * pa_distance;
00320     } else {
00321       // plane_b is the furthest
00322       cerr<<"plane_b is the furthest"<<"\n";
00323       surface_normal = _plane_b.get_normal();
00324       surface_point = from_center - surface_normal * pb_distance;
00325     }
00326   }
00327 
00328   PT(CollisionEntry) new_entry = new CollisionEntry(entry);
00329   new_entry->set_surface_normal(surface_normal);
00330   new_entry->set_surface_point(surface_point);
00331   new_entry->set_interior_point(from_center - surface_normal * from_radius);
00332   return new_entry;
00333 }
00334 
00335 ////////////////////////////////////////////////////////////////////
00336 //     Function: CollisionDSSolid::fill_viz_geom
00337 //       Access: Protected, Virtual
00338 //  Description: Fills the _viz_geom GeomNode up with Geoms suitable
00339 //               for rendering this solid.
00340 ////////////////////////////////////////////////////////////////////
00341 void CollisionDSSolid::
00342 fill_viz_geom() {
00343   if (collide_cat.is_debug()) {
00344     collide_cat.debug()
00345       << "Recomputing viz for " << *this << "\n";
00346   }
00347 
00348   // Generate the vertices such that we draw a shape with one sphere
00349   // at (0, 0, 0), and another at (0, length, 0).  Then we'll rotate
00350   // and translate it into place with the appropriate look_at matrix.
00351   LVector3f direction = _center_b - _center_a;
00352   float half_length = direction.length() * 0.5f;
00353   
00354   // "Let" a few variables
00355   float distance = direction.length();
00356   float dist_squared = distance * distance;
00357   float dist_doubled = 2.0f * distance;
00358   float radius_a_squared = _radius_a * _radius_a;
00359   float radius_b_squared = _radius_b * _radius_b;
00360   float triangle_height = (
00361       dist_squared - radius_a_squared + radius_b_squared) / dist_doubled;
00362   
00363   // Get (half) the angle from _center_a to the lens edge on the
00364   // intersection plane between sphere A and sphere B
00365   float half_arc_angle_a = acos(triangle_height / _radius_a);
00366   float half_arc_angle_b = acos(triangle_height / _radius_b);
00367 
00368   PT(GeomVertexData) vdata = new GeomVertexData(
00369     "collision", GeomVertexFormat::get_v3(), Geom::UH_static);
00370   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00371   
00372   PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
00373   // Generate the first endcap.
00374   static const int num_slices = 8;
00375   static const int num_rings = 4;
00376   int ri, si;
00377   for (ri = 0; ri < num_rings; ++ri) {
00378     for (si = 0; si <= num_slices; ++si) {
00379       vertex.add_data3f(calc_sphere2_vertex(
00380           ri, si, num_rings, num_slices, -half_length, half_arc_angle_a));
00381       vertex.add_data3f(calc_sphere2_vertex(
00382           ri + 1, si, num_rings, num_slices, -half_length, half_arc_angle_a));
00383     }
00384     strip->add_next_vertices((num_slices + 1) * 2);
00385     strip->close_primitive();
00386   }
00387   
00388   // Add plane A
00389   calc_plane(_plane_a);
00390   
00391   // Add plane B
00392   calc_plane(_plane_b);
00393   
00394   // And the second endcap.
00395   for (ri = num_rings - 1; ri >= 0; --ri) {
00396     for (si = 0; si <= num_slices; ++si) {
00397       vertex.add_data3f(calc_sphere1_vertex(
00398           ri + 1, si, num_rings, num_slices, half_length, half_arc_angle_b));
00399       vertex.add_data3f(calc_sphere1_vertex(
00400           ri, si, num_rings, num_slices, half_length, half_arc_angle_b));
00401     }
00402     strip->add_next_vertices((num_slices + 1) * 2);
00403     strip->close_primitive();
00404   }
00405   
00406   PT(Geom) geom = new Geom(vdata);
00407   geom->add_primitive(strip);
00408   
00409   #if 0
00410   // Now transform the vertices to their actual location.
00411   LMatrix4f mat;
00412   look_at(mat, direction, LVector3f(0.0f, 0.0f, 1.0f), CS_zup_right);
00413   mat.set_row(3, _ceneter_a);
00414   geom->transform_vertices(mat);
00415   #endif
00416   
00417   _viz_geom->add_geom(geom, get_solid_viz_state());
00418   _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state());
00419 }
00420 
00421 ////////////////////////////////////////////////////////////////////
00422 //     Function: CollisionDSSolid::calc_plane
00423 //       Access: Private
00424 //  Description: Calculates a plane, for use in generating the
00425 //               viz geometry.
00426 ////////////////////////////////////////////////////////////////////
00427 void CollisionDSSolid::
00428 calc_plane(const Planef &plane) {
00429   LPoint3f cp;
00430   LVector3f p1, p2, p3, p4;
00431 
00432   LVector3f normal = plane.get_normal();
00433   float D = plane[3];
00434 
00435   if (fabs(normal[0]) > fabs(normal[1]) &&
00436       fabs(normal[0]) > fabs(normal[2])) {
00437     // X has the largest coefficient.
00438     cp.set(-D / normal[0], 0.0f, 0.0f);
00439     p1 = LPoint3f(-(normal[1] + normal[2] + D)/normal[0], 1.0f, 1.0f) - cp;
00440 
00441   } else if (fabs(normal[1]) > fabs(normal[2])) {
00442     // Y has the largest coefficient.
00443     cp.set(0.0f, -D / normal[1], 0.0f);
00444     p1 = LPoint3f(1.0f, -(normal[0] + normal[2] + D)/normal[1], 1.0f) - cp;
00445 
00446   } else {
00447     // Z has the largest coefficient.
00448     cp.set(0.0f, 0.0f, -D / normal[2]);
00449     p1 = LPoint3f(1.0f, 1.0f, -(normal[0] + normal[1] + D)/normal[2]) - cp;
00450   }
00451 
00452   p1.normalize();
00453   p2 = cross(normal, p1);
00454   p3 = cross(normal, p2);
00455   p4 = cross(normal, p3);
00456 
00457   static const double plane_scale = 100.0;
00458 
00459   PT(GeomVertexData) vdata = new GeomVertexData
00460     ("collision", GeomVertexFormat::get_v3(),
00461      Geom::UH_static);
00462   GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00463   
00464   vertex.add_data3f(cp + p1 * plane_scale);
00465   vertex.add_data3f(cp + p2 * plane_scale);
00466   vertex.add_data3f(cp + p3 * plane_scale);
00467   vertex.add_data3f(cp + p4 * plane_scale);
00468   
00469   PT(GeomTrifans) body = new GeomTrifans(Geom::UH_static);
00470   body->add_consecutive_vertices(0, 4);
00471   body->close_primitive();
00472   
00473   PT(GeomLinestrips) border = new GeomLinestrips(Geom::UH_static);
00474   border->add_consecutive_vertices(0, 4);
00475   border->add_vertex(0);
00476   border->close_primitive();
00477   
00478   PT(Geom) geom1 = new Geom(vdata);
00479   geom1->add_primitive(body);
00480   
00481   PT(Geom) geom2 = new Geom(vdata);
00482   geom2->add_primitive(border);
00483   
00484   _viz_geom->add_geom(geom1, get_solid_viz_state());
00485   _viz_geom->add_geom(geom2, get_wireframe_viz_state());
00486   
00487   _bounds_viz_geom->add_geom(geom1, get_solid_bounds_viz_state());
00488   _bounds_viz_geom->add_geom(geom2, get_wireframe_bounds_viz_state());
00489 }
00490 
00491 ////////////////////////////////////////////////////////////////////
00492 //     Function: CollisionDSSolid::calc_sphere1_vertex
00493 //       Access: Private
00494 //  Description: Calculates a particular vertex on the surface of the
00495 //               first endcap hemisphere, for use in generating the
00496 //               viz geometry.
00497 ////////////////////////////////////////////////////////////////////
00498 Vertexf CollisionDSSolid::
00499 calc_sphere1_vertex(int ri, int si, int num_rings, int num_slices,
00500                     float length, float angle) {
00501   float r = (float)ri / (float)num_rings;
00502   float s = (float)si / (float)num_slices;
00503 
00504   // Find the point on the rim, based on the slice.
00505   float theta = s * 2.0f * MathNumbers::pi_f;
00506   float y_rim = ccos(theta);
00507   float z_rim = csin(theta);
00508 
00509   // Now pull that point in towards the pole, based on the ring.
00510   float phi = r * angle;
00511   float to_pole = csin(phi);
00512 
00513   float x = length -_radius_a * ccos(phi);
00514   float y = _radius_a * y_rim * to_pole;
00515   float z = _radius_a * z_rim * to_pole;
00516 
00517   return Vertexf(x, y, z);
00518 }
00519 
00520 ////////////////////////////////////////////////////////////////////
00521 //     Function: CollisionDSSolid::calc_sphere2_vertex
00522 //       Access: Private
00523 //  Description: Calculates a particular vertex on the surface of the
00524 //               second endcap hemisphere, for use in generating the
00525 //               viz geometry.
00526 ////////////////////////////////////////////////////////////////////
00527 Vertexf CollisionDSSolid::
00528 calc_sphere2_vertex(int ri, int si, int num_rings, int num_slices,
00529                     float length, float angle) {
00530   float r = (float)ri / (float)num_rings;
00531   float s = (float)si / (float)num_slices;
00532 
00533   // Find the point on the rim, based on the slice.
00534   float theta = s * 2.0f * MathNumbers::pi_f;
00535   float y_rim = ccos(theta);
00536   float z_rim = csin(theta);
00537 
00538   // Now pull that point in towards the pole, based on the ring.
00539   float phi = r * angle;
00540   float to_pole = csin(phi);
00541 
00542   float x = length + _radius_b * ccos(phi);
00543   float y = _radius_b * y_rim * to_pole;
00544   float z = _radius_b * z_rim * to_pole;
00545 
00546   return Vertexf(x, y, z);
00547 }
00548 
00549 ////////////////////////////////////////////////////////////////////
00550 //     Function: CollisionDSSolid::recalc_internals
00551 //       Access: Private
00552 //  Description: Should be called internally to recompute the matrix
00553 //               and length when the properties of the tube have
00554 //               changed.
00555 ////////////////////////////////////////////////////////////////////
00556 void CollisionDSSolid::
00557 recalc_internals() {
00558   mark_viz_stale();
00559   mark_internal_bounds_stale();
00560 }
00561 
00562 ////////////////////////////////////////////////////////////////////
00563 //     Function: CollisionDSSolid::register_with_read_factory
00564 //       Access: Public, Static
00565 //  Description: Tells the BamReader how to create objects of type
00566 //               CollisionDSSolid.
00567 ////////////////////////////////////////////////////////////////////
00568 void CollisionDSSolid::
00569 register_with_read_factory() {
00570   BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00571 }
00572 
00573 ////////////////////////////////////////////////////////////////////
00574 //     Function: CollisionDSSolid::write_datagram
00575 //       Access: Public, Virtual
00576 //  Description: Writes the contents of this object to the datagram
00577 //               for shipping out to a Bam file.
00578 ////////////////////////////////////////////////////////////////////
00579 void CollisionDSSolid::
00580 write_datagram(BamWriter *manager, Datagram &dg) {
00581   CollisionSolid::write_datagram(manager, dg);
00582   _center_a.write_datagram(dg);
00583   dg.add_float32(_radius_a);
00584   _center_b.write_datagram(dg);
00585   dg.add_float32(_radius_b);
00586   _plane_a.write_datagram(dg);
00587   _plane_b.write_datagram(dg);
00588 }
00589 
00590 ////////////////////////////////////////////////////////////////////
00591 //     Function: CollisionDSSolid::make_from_bam
00592 //       Access: Protected, Static
00593 //  Description: This function is called by the BamReader's factory
00594 //               when a new object of type CollisionDSSolid is encountered
00595 //               in the Bam file.  It should create the CollisionDSSolid
00596 //               and extract its information from the file.
00597 ////////////////////////////////////////////////////////////////////
00598 TypedWritable *CollisionDSSolid::
00599 make_from_bam(const FactoryParams &params) {
00600   CollisionDSSolid *node = new CollisionDSSolid();
00601   DatagramIterator scan;
00602   BamReader *manager;
00603 
00604   parse_params(params, scan, manager);
00605   node->fillin(scan, manager);
00606 
00607   return node;
00608 }
00609 
00610 ////////////////////////////////////////////////////////////////////
00611 //     Function: CollisionDSSolid::fillin
00612 //       Access: Protected
00613 //  Description: This internal function is called by make_from_bam to
00614 //               read in all of the relevant data from the BamFile for
00615 //               the new CollisionDSSolid.
00616 ////////////////////////////////////////////////////////////////////
00617 void CollisionDSSolid::
00618 fillin(DatagramIterator &scan, BamReader *manager) {
00619   CollisionSolid::fillin(scan, manager);
00620   _center_a.read_datagram(scan);
00621   _radius_a = scan.get_float32();
00622   _center_b.read_datagram(scan);
00623   _radius_b = scan.get_float32();
00624   _plane_a.read_datagram(scan);
00625   _plane_b.read_datagram(scan);
00626   recalc_internals();
00627 }
 All Classes Functions Variables Enumerations