Panda3D
|
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 ¶ms) { 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 }