From bd6ef2b0ea2832ff1095f9e41b3137452f0619f4 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 23 Dec 2018 19:44:53 +0100 Subject: [PATCH] Rename CollisionTube to CollisionCapsule (bam 6.44) Adds ability to register "obsolete" names for certain types under older .bam versions, so that we are still able to write out old .bam files. Fixes #347 --- makepanda/makepanda.vcproj | 6 +- panda/src/bullet/bulletBodyNode.cxx | 12 +- panda/src/bullet/bulletCapsuleShape.cxx | 10 +- panda/src/bullet/bulletCapsuleShape.h | 4 +- panda/src/collide/collisionBox.cxx | 20 +-- panda/src/collide/collisionBox.h | 2 +- .../{collisionTube.I => collisionCapsule.I} | 38 ++--- ...collisionTube.cxx => collisionCapsule.cxx} | 148 +++++++++--------- .../{collisionTube.h => collisionCapsule.h} | 42 +++-- .../collide/collisionHandlerFluidPusher.cxx | 2 +- panda/src/collide/collisionPlane.cxx | 22 +-- panda/src/collide/collisionPlane.h | 2 +- panda/src/collide/collisionSolid.cxx | 8 +- panda/src/collide/collisionSolid.h | 4 +- panda/src/collide/collisionSphere.cxx | 20 +-- panda/src/collide/collisionSphere.h | 2 +- panda/src/collide/collisionTraverser.cxx | 4 +- panda/src/collide/config_collide.cxx | 10 +- panda/src/collide/p3collide_composite1.cxx | 3 +- panda/src/collide/p3collide_composite2.cxx | 3 +- panda/src/display/graphicsEngine.cxx | 8 +- panda/src/display/graphicsEngine.h | 4 +- panda/src/doc/collisionFlags.txt | 2 +- panda/src/egg/eggGroup.cxx | 3 +- panda/src/egg2pg/eggLoader.cxx | 20 +-- panda/src/egg2pg/eggLoader.h | 4 +- panda/src/egg2pg/eggSaver.cxx | 30 ++-- panda/src/putil/bam.h | 3 +- panda/src/putil/bamWriter.cxx | 67 +++++++- panda/src/putil/bamWriter.h | 4 + pandatool/src/eggprogs/eggMakeTube.cxx | 2 +- pandatool/src/eggprogs/eggMakeTube.h | 2 +- tests/collide/test_collision_tube.py | 63 ++++++++ 33 files changed, 360 insertions(+), 214 deletions(-) rename panda/src/collide/{collisionTube.I => collisionCapsule.I} (70%) rename panda/src/collide/{collisionTube.cxx => collisionCapsule.cxx} (89%) rename panda/src/collide/{collisionTube.h => collisionCapsule.h} (81%) create mode 100644 tests/collide/test_collision_tube.py diff --git a/makepanda/makepanda.vcproj b/makepanda/makepanda.vcproj index ad7f219650..03324fb60e 100644 --- a/makepanda/makepanda.vcproj +++ b/makepanda/makepanda.vcproj @@ -1043,7 +1043,7 @@ - + @@ -1054,7 +1054,7 @@ - + @@ -1089,7 +1089,7 @@ - + diff --git a/panda/src/bullet/bulletBodyNode.cxx b/panda/src/bullet/bulletBodyNode.cxx index 81a056adc2..cb9d7ed9c0 100644 --- a/panda/src/bullet/bulletBodyNode.cxx +++ b/panda/src/bullet/bulletBodyNode.cxx @@ -28,7 +28,7 @@ #include "collisionPlane.h" #include "collisionSphere.h" #include "collisionPolygon.h" -#include "collisionTube.h" +#include "collisionCapsule.h" TypeHandle BulletBodyNode::_type_handle; @@ -813,12 +813,12 @@ add_shapes_from_collision_solids(CollisionNode *cnode) { do_add_shape(BulletBoxShape::make_from_solid(box), ts); } - // CollisionTube - else if (CollisionTube::get_class_type() == type) { - CPT(CollisionTube) tube = DCAST(CollisionTube, solid); - CPT(TransformState) ts = TransformState::make_pos((tube->get_point_b() + tube->get_point_a()) / 2.0); + // CollisionCapsule + else if (CollisionCapsule::get_class_type() == type) { + CPT(CollisionCapsule) capsule = DCAST(CollisionCapsule, solid); + CPT(TransformState) ts = TransformState::make_pos((capsule->get_point_b() + capsule->get_point_a()) / 2.0); - do_add_shape(BulletCapsuleShape::make_from_solid(tube), ts); + do_add_shape(BulletCapsuleShape::make_from_solid(capsule), ts); } // CollisionPlane diff --git a/panda/src/bullet/bulletCapsuleShape.cxx b/panda/src/bullet/bulletCapsuleShape.cxx index 0bdb1284dc..cde5e64050 100644 --- a/panda/src/bullet/bulletCapsuleShape.cxx +++ b/panda/src/bullet/bulletCapsuleShape.cxx @@ -87,16 +87,16 @@ ptr() const { /** * Constructs a new BulletCapsuleShape using the information from a - * CollisionTube from the builtin collision system. + * CollisionCapsule from the builtin collision system. */ BulletCapsuleShape *BulletCapsuleShape:: -make_from_solid(const CollisionTube *solid) { - +make_from_solid(const CollisionCapsule *solid) { + PN_stdfloat radius = solid->get_radius(); - // Get tube's cylinder height: length from point A to point B + // Get capsule's cylinder height: length from point A to point B PN_stdfloat height = (solid->get_point_b() - solid->get_point_a()).length(); - // CollisionTubes are always Z-Up. + // CollisionCapsules are always Z-Up. return new BulletCapsuleShape(radius, height, Z_up); } diff --git a/panda/src/bullet/bulletCapsuleShape.h b/panda/src/bullet/bulletCapsuleShape.h index f8eecfe3d7..e78b06bc08 100644 --- a/panda/src/bullet/bulletCapsuleShape.h +++ b/panda/src/bullet/bulletCapsuleShape.h @@ -20,7 +20,7 @@ #include "bullet_utils.h" #include "bulletShape.h" -#include "collisionTube.h" +#include "collisionCapsule.h" /** * @@ -35,7 +35,7 @@ PUBLISHED: BulletCapsuleShape(const BulletCapsuleShape ©); INLINE ~BulletCapsuleShape(); - static BulletCapsuleShape *make_from_solid(const CollisionTube *solid); + static BulletCapsuleShape *make_from_solid(const CollisionCapsule *solid); INLINE PN_stdfloat get_radius() const; INLINE PN_stdfloat get_half_height() const; diff --git a/panda/src/collide/collisionBox.cxx b/panda/src/collide/collisionBox.cxx index a8af257456..8528e7bc27 100644 --- a/panda/src/collide/collisionBox.cxx +++ b/panda/src/collide/collisionBox.cxx @@ -16,7 +16,7 @@ #include "collisionRay.h" #include "collisionSphere.h" #include "collisionSegment.h" -#include "collisionTube.h" +#include "collisionCapsule.h" #include "collisionHandler.h" #include "collisionEntry.h" #include "config_collide.h" @@ -547,19 +547,19 @@ test_intersection_from_segment(const CollisionEntry &entry) const { } /** - * Double dispatch point for tube as a FROM object + * Double dispatch point for capsule as a FROM object */ PT(CollisionEntry) CollisionBox:: -test_intersection_from_tube(const CollisionEntry &entry) const { - const CollisionTube *tube; - DCAST_INTO_R(tube, entry.get_from(), nullptr); +test_intersection_from_capsule(const CollisionEntry &entry) const { + const CollisionCapsule *capsule; + DCAST_INTO_R(capsule, entry.get_from(), nullptr); const LMatrix4 &wrt_mat = entry.get_wrt_mat(); - LPoint3 from_a = tube->get_point_a() * wrt_mat; - LPoint3 from_b = tube->get_point_b() * wrt_mat; + LPoint3 from_a = capsule->get_point_a() * wrt_mat; + LPoint3 from_b = capsule->get_point_b() * wrt_mat; LVector3 from_direction = from_b - from_a; - PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, tube->get_radius())).length_squared(); + PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, capsule->get_radius())).length_squared(); PN_stdfloat radius = csqrt(radius_sq); LPoint3 box_min = get_min(); @@ -620,7 +620,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const { LVector3 delta(0); delta[edges[i].axis] = dimensions[edges[i].axis]; double u1, u2; - CollisionTube::calc_closest_segment_points(u1, u2, from_a, from_direction, vertex, delta); + CollisionCapsule::calc_closest_segment_points(u1, u2, from_a, from_direction, vertex, delta); PN_stdfloat dist_sq = ((from_a + from_direction * u1) - (vertex + delta * u2)).length_squared(); if (dist_sq < best_dist_sq) { best_dist_sq = dist_sq; @@ -682,7 +682,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const { new_entry->set_interior_point(point - interior_vec * radius); new_entry->set_surface_point(surface_point); - if (has_effective_normal() && tube->get_respect_effective_normal()) { + if (has_effective_normal() && capsule->get_respect_effective_normal()) { new_entry->set_surface_normal(get_effective_normal()); } else { new_entry->set_surface_normal(normal); diff --git a/panda/src/collide/collisionBox.h b/panda/src/collide/collisionBox.h index cf9e8bc15b..db9d2c2aa9 100644 --- a/panda/src/collide/collisionBox.h +++ b/panda/src/collide/collisionBox.h @@ -82,7 +82,7 @@ protected: virtual PT(CollisionEntry) test_intersection_from_segment(const CollisionEntry &entry) const; virtual PT(CollisionEntry) - test_intersection_from_tube(const CollisionEntry &entry) const; + test_intersection_from_capsule(const CollisionEntry &entry) const; virtual PT(CollisionEntry) test_intersection_from_box(const CollisionEntry &entry) const; diff --git a/panda/src/collide/collisionTube.I b/panda/src/collide/collisionCapsule.I similarity index 70% rename from panda/src/collide/collisionTube.I rename to panda/src/collide/collisionCapsule.I index 53e0f4cff6..78b8c3559b 100644 --- a/panda/src/collide/collisionTube.I +++ b/panda/src/collide/collisionCapsule.I @@ -6,7 +6,7 @@ * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * - * @file collisionTube.I + * @file collisionCapsule.I * @author drose * @date 2003-09-25 */ @@ -14,8 +14,8 @@ /** * */ -INLINE CollisionTube:: -CollisionTube(const LPoint3 &a, const LPoint3 &b, PN_stdfloat radius) : +INLINE CollisionCapsule:: +CollisionCapsule(const LPoint3 &a, const LPoint3 &b, PN_stdfloat radius) : _a(a), _b(b), _radius(radius) { recalc_internals(); @@ -25,8 +25,8 @@ CollisionTube(const LPoint3 &a, const LPoint3 &b, PN_stdfloat radius) : /** * */ -INLINE CollisionTube:: -CollisionTube(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az, +INLINE CollisionCapsule:: +CollisionCapsule(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az, PN_stdfloat bx, PN_stdfloat by, PN_stdfloat bz, PN_stdfloat radius) : _a(ax, ay, az), _b(bx, by, bz), _radius(radius) @@ -36,17 +36,17 @@ CollisionTube(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az, } /** - * Creates an invalid tube. Only used when reading from a bam file. + * Creates an invalid capsule. Only used when reading from a bam file. */ -INLINE CollisionTube:: -CollisionTube() { +INLINE CollisionCapsule:: +CollisionCapsule() { } /** * */ -INLINE CollisionTube:: -CollisionTube(const CollisionTube ©) : +INLINE CollisionCapsule:: +CollisionCapsule(const CollisionCapsule ©) : CollisionSolid(copy), _a(copy._a), _b(copy._b), @@ -58,7 +58,7 @@ CollisionTube(const CollisionTube ©) : /** * Flushes the PStatCollectors used during traversal. */ -INLINE void CollisionTube:: +INLINE void CollisionCapsule:: flush_level() { _volume_pcollector.flush_level(); _test_pcollector.flush_level(); @@ -67,7 +67,7 @@ flush_level() { /** * */ -INLINE void CollisionTube:: +INLINE void CollisionCapsule:: set_point_a(const LPoint3 &a) { _a = a; recalc_internals(); @@ -76,7 +76,7 @@ set_point_a(const LPoint3 &a) { /** * */ -INLINE void CollisionTube:: +INLINE void CollisionCapsule:: set_point_a(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) { set_point_a(LPoint3(x, y, z)); } @@ -84,7 +84,7 @@ set_point_a(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) { /** * */ -INLINE const LPoint3 &CollisionTube:: +INLINE const LPoint3 &CollisionCapsule:: get_point_a() const { return _a; } @@ -92,7 +92,7 @@ get_point_a() const { /** * */ -INLINE void CollisionTube:: +INLINE void CollisionCapsule:: set_point_b(const LPoint3 &b) { _b = b; recalc_internals(); @@ -101,7 +101,7 @@ set_point_b(const LPoint3 &b) { /** * */ -INLINE void CollisionTube:: +INLINE void CollisionCapsule:: set_point_b(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) { set_point_b(LPoint3(x, y, z)); } @@ -109,7 +109,7 @@ set_point_b(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) { /** * */ -INLINE const LPoint3 &CollisionTube:: +INLINE const LPoint3 &CollisionCapsule:: get_point_b() const { return _b; } @@ -117,7 +117,7 @@ get_point_b() const { /** * */ -INLINE void CollisionTube:: +INLINE void CollisionCapsule:: set_radius(PN_stdfloat radius) { nassertv(radius >= 0.0f); _radius = radius; @@ -131,7 +131,7 @@ set_radius(PN_stdfloat radius) { /** * */ -INLINE PN_stdfloat CollisionTube:: +INLINE PN_stdfloat CollisionCapsule:: get_radius() const { return _radius; } diff --git a/panda/src/collide/collisionTube.cxx b/panda/src/collide/collisionCapsule.cxx similarity index 89% rename from panda/src/collide/collisionTube.cxx rename to panda/src/collide/collisionCapsule.cxx index 90f82a3630..91ab319735 100644 --- a/panda/src/collide/collisionTube.cxx +++ b/panda/src/collide/collisionCapsule.cxx @@ -6,12 +6,12 @@ * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * - * @file collisionTube.cxx + * @file collisionCapsule.cxx * @author drose * @date 2003-09-25 */ -#include "collisionTube.h" +#include "collisionCapsule.h" #include "collisionSphere.h" #include "collisionLine.h" #include "collisionRay.h" @@ -35,30 +35,30 @@ #include "geomVertexWriter.h" #include "boundingSphere.h" -PStatCollector CollisionTube::_volume_pcollector("Collision Volumes:CollisionTube"); -PStatCollector CollisionTube::_test_pcollector("Collision Tests:CollisionTube"); -TypeHandle CollisionTube::_type_handle; +PStatCollector CollisionCapsule::_volume_pcollector("Collision Volumes:CollisionCapsule"); +PStatCollector CollisionCapsule::_test_pcollector("Collision Tests:CollisionCapsule"); +TypeHandle CollisionCapsule::_type_handle; /** * */ -CollisionSolid *CollisionTube:: +CollisionSolid *CollisionCapsule:: make_copy() { - return new CollisionTube(*this); + return new CollisionCapsule(*this); } /** * */ -PT(CollisionEntry) CollisionTube:: +PT(CollisionEntry) CollisionCapsule:: test_intersection(const CollisionEntry &entry) const { - return entry.get_into()->test_intersection_from_tube(entry); + return entry.get_into()->test_intersection_from_capsule(entry); } /** * Transforms the solid by the indicated matrix. */ -void CollisionTube:: +void CollisionCapsule:: xform(const LMatrix4 &mat) { _a = _a * mat; _b = _b * mat; @@ -77,7 +77,7 @@ xform(const LMatrix4 &mat) { * collision purposes. The closest intersection point to this origin point is * considered to be the most significant. */ -LPoint3 CollisionTube:: +LPoint3 CollisionCapsule:: get_collision_origin() const { return get_point_a(); } @@ -86,7 +86,7 @@ get_collision_origin() const { * Returns a PStatCollector that is used to count the number of bounding * volume tests made against a solid of this type in a given frame. */ -PStatCollector &CollisionTube:: +PStatCollector &CollisionCapsule:: get_volume_pcollector() { return _volume_pcollector; } @@ -95,7 +95,7 @@ get_volume_pcollector() { * Returns a PStatCollector that is used to count the number of intersection * tests made against a solid of this type in a given frame. */ -PStatCollector &CollisionTube:: +PStatCollector &CollisionCapsule:: get_test_pcollector() { return _test_pcollector; } @@ -103,15 +103,15 @@ get_test_pcollector() { /** * */ -void CollisionTube:: +void CollisionCapsule:: output(std::ostream &out) const { - out << "tube, a (" << _a << "), b (" << _b << "), r " << _radius; + out << "capsule, a (" << _a << "), b (" << _b << "), r " << _radius; } /** * */ -PT(BoundingVolume) CollisionTube:: +PT(BoundingVolume) CollisionCapsule:: compute_internal_bounds() const { PT(BoundingVolume) bound = CollisionSolid::compute_internal_bounds(); @@ -143,7 +143,7 @@ compute_internal_bounds() const { /** * */ -PT(CollisionEntry) CollisionTube:: +PT(CollisionEntry) CollisionCapsule:: test_intersection_from_sphere(const CollisionEntry &entry) const { const CollisionSphere *sphere; DCAST_INTO_R(sphere, entry.get_from(), nullptr); @@ -160,7 +160,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const { PN_stdfloat actual_t = 0.0f; if (wrt_prev_space != wrt_space) { - // If the sphere is moving relative to the tube, it becomes a tube itself. + // If the sphere is moving relative to the capsule, it becomes a capsule itself. from_a = sphere->get_center() * wrt_prev_space->get_mat(); } @@ -195,11 +195,11 @@ test_intersection_from_sphere(const CollisionEntry &entry) const { LPoint3 into_intersection_point; if (t2 > 1.0) { - // Point b is within the tube. The first intersection point is point b + // Point b is within the capsule. The first intersection point is point b // itself. into_intersection_point = from_b; } else { - // Point b is outside the tube, and point a is either inside the tube or + // Point b is outside the capsule, and point a is either inside the capsule or // beyond it. The first intersection point is at t2. into_intersection_point = from_a + t2 * from_direction; } @@ -221,7 +221,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const { /** * */ -PT(CollisionEntry) CollisionTube:: +PT(CollisionEntry) CollisionCapsule:: test_intersection_from_line(const CollisionEntry &entry) const { const CollisionLine *line; DCAST_INTO_R(line, entry.get_from(), nullptr); @@ -269,7 +269,7 @@ test_intersection_from_line(const CollisionEntry &entry) const { /** * */ -PT(CollisionEntry) CollisionTube:: +PT(CollisionEntry) CollisionCapsule:: test_intersection_from_ray(const CollisionEntry &entry) const { const CollisionRay *ray; DCAST_INTO_R(ray, entry.get_from(), nullptr); @@ -299,11 +299,11 @@ test_intersection_from_ray(const CollisionEntry &entry) const { LPoint3 into_intersection_point; if (t1 < 0.0) { - // Point a is within the tube. The first intersection point is point a + // Point a is within the capsule. The first intersection point is point a // itself. into_intersection_point = from_origin; } else { - // Point a is outside the tube. The first intersection point is at t1. + // Point a is outside the capsule. The first intersection point is at t1. into_intersection_point = from_origin + t1 * from_direction; } set_intersection_point(new_entry, into_intersection_point, 0.0); @@ -330,7 +330,7 @@ test_intersection_from_ray(const CollisionEntry &entry) const { /** * */ -PT(CollisionEntry) CollisionTube:: +PT(CollisionEntry) CollisionCapsule:: test_intersection_from_segment(const CollisionEntry &entry) const { const CollisionSegment *segment; DCAST_INTO_R(segment, entry.get_from(), nullptr); @@ -362,11 +362,11 @@ test_intersection_from_segment(const CollisionEntry &entry) const { LPoint3 into_intersection_point; if (t1 < 0.0) { - // Point a is within the tube. The first intersection point is point a + // Point a is within the capsule. The first intersection point is point a // itself. into_intersection_point = from_a; } else { - // Point a is outside the tube, and point b is either inside the tube or + // Point a is outside the capsule, and point b is either inside the capsule or // beyond it. The first intersection point is at t1. into_intersection_point = from_a + t1 * from_direction; } @@ -394,22 +394,22 @@ test_intersection_from_segment(const CollisionEntry &entry) const { /** * */ -PT(CollisionEntry) CollisionTube:: -test_intersection_from_tube(const CollisionEntry &entry) const { - const CollisionTube *tube; - DCAST_INTO_R(tube, entry.get_from(), nullptr); +PT(CollisionEntry) CollisionCapsule:: +test_intersection_from_capsule(const CollisionEntry &entry) const { + const CollisionCapsule *capsule; + DCAST_INTO_R(capsule, entry.get_from(), nullptr); LPoint3 into_a = _a; LVector3 into_direction = _b - into_a; const LMatrix4 &wrt_mat = entry.get_wrt_mat(); - LPoint3 from_a = tube->get_point_a() * wrt_mat; - LPoint3 from_b = tube->get_point_b() * wrt_mat; + LPoint3 from_a = capsule->get_point_a() * wrt_mat; + LPoint3 from_b = capsule->get_point_b() * wrt_mat; LVector3 from_direction = from_b - from_a; LVector3 from_radius_v = - LVector3(tube->get_radius(), 0.0f, 0.0f) * wrt_mat; + LVector3(capsule->get_radius(), 0.0f, 0.0f) * wrt_mat; PN_stdfloat from_radius = length(from_radius_v); // Determine the points on each segment with the smallest distance between. @@ -420,7 +420,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const { LPoint3 into_closest = into_a + into_direction * into_t; LPoint3 from_closest = from_a + from_direction * from_t; - // If the distance is greater than the sum of tube radii, the test fails. + // If the distance is greater than the sum of capsule radii, the test fails. LVector3 closest_vec = from_closest - into_closest; PN_stdfloat distance = closest_vec.length(); if (distance > _radius + from_radius) { @@ -442,7 +442,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const { new_entry->set_surface_point(into_closest + surface_normal * _radius); new_entry->set_interior_point(from_closest - surface_normal * from_radius); - if (has_effective_normal() && tube->get_respect_effective_normal()) { + if (has_effective_normal() && capsule->get_respect_effective_normal()) { new_entry->set_surface_normal(get_effective_normal()); } else if (distance != 0) { new_entry->set_surface_normal(surface_normal); @@ -458,7 +458,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const { /** * */ -PT(CollisionEntry) CollisionTube:: +PT(CollisionEntry) CollisionCapsule:: test_intersection_from_parabola(const CollisionEntry &entry) const { const CollisionParabola *parabola; DCAST_INTO_R(parabola, entry.get_from(), nullptr); @@ -510,14 +510,14 @@ test_intersection_from_parabola(const CollisionEntry &entry) const { * Fills the _viz_geom GeomNode up with Geoms suitable for rendering this * solid. */ -void CollisionTube:: +void CollisionCapsule:: fill_viz_geom() { if (collide_cat.is_debug()) { collide_cat.debug() << "Recomputing viz for " << *this << "\n"; } - // Generate the vertices such that we draw a tube with one endpoint at (0, + // Generate the vertices such that we draw a capsule with one endpoint at (0, // 0, 0), and another at (0, length, 0). Then we'll rotate and translate it // into place with the appropriate look_at matrix. LVector3 direction = (_b - _a); @@ -576,9 +576,9 @@ fill_viz_geom() { /** * Should be called internally to recompute the matrix and length when the - * properties of the tube have changed. + * properties of the capsule have changed. */ -void CollisionTube:: +void CollisionCapsule:: recalc_internals() { LVector3 direction = (_b - _a); _length = direction.length(); @@ -595,7 +595,7 @@ recalc_internals() { * Calculates a particular vertex on the surface of the first endcap * hemisphere, for use in generating the viz geometry. */ -LVertex CollisionTube:: +LVertex CollisionCapsule:: calc_sphere1_vertex(int ri, int si, int num_rings, int num_slices) { PN_stdfloat r = (PN_stdfloat)ri / (PN_stdfloat)num_rings; PN_stdfloat s = (PN_stdfloat)si / (PN_stdfloat)num_slices; @@ -620,7 +620,7 @@ calc_sphere1_vertex(int ri, int si, int num_rings, int num_slices) { * Calculates a particular vertex on the surface of the second endcap * hemisphere, for use in generating the viz geometry. */ -LVertex CollisionTube:: +LVertex CollisionCapsule:: calc_sphere2_vertex(int ri, int si, int num_rings, int num_slices, PN_stdfloat length) { PN_stdfloat r = (PN_stdfloat)ri / (PN_stdfloat)num_rings; @@ -646,7 +646,7 @@ calc_sphere2_vertex(int ri, int si, int num_rings, int num_slices, * Given line segments s1 and s2 defined by two points each, computes the * point on each segment with the closest distance between them. */ -void CollisionTube:: +void CollisionCapsule:: calc_closest_segment_points(double &t1, double &t2, const LPoint3 &from1, const LVector3 &delta1, const LPoint3 &from2, const LVector3 &delta2) { @@ -717,18 +717,18 @@ calc_closest_segment_points(double &t1, double &t2, } /** - * Determine the point(s) of intersection of a parametric line with the tube. + * Determine the point(s) of intersection of a parametric line with the capsule. * The line is infinite in both directions, and passes through "from" and - * from+delta. If the line does not intersect the tube, the function returns - * false, and t1 and t2 are undefined. If it does intersect the tube, it + * from+delta. If the line does not intersect the capsule, the function returns + * false, and t1 and t2 are undefined. If it does intersect the capsule, it * returns true, and t1 and t2 are set to the points along the equation * from+t*delta that correspond to the two points of intersection. */ -bool CollisionTube:: +bool CollisionCapsule:: intersects_line(double &t1, double &t2, const LPoint3 &from0, const LVector3 &delta0, PN_stdfloat inflate_radius) const { - // Convert the line into our canonical coordinate space: the tube is aligned + // Convert the line into our canonical coordinate space: the capsule is aligned // with the y axis. LPoint3 from = from0 * _inv_mat; LVector3 delta = delta0 * _inv_mat; @@ -776,7 +776,7 @@ intersects_line(double &t1, double &t2, } } - // The point is within the tube! + // The point is within the capsule! t1 = t2 = 0.0; return true; } @@ -819,15 +819,15 @@ intersects_line(double &t1, double &t2, PN_stdfloat t2_y = from[1] + t2 * delta[1]; if (t1_y < -radius && t2_y < -radius) { - // Both points are way off the bottom of the tube; no intersection. + // Both points are way off the bottom of the capsule; no intersection. return false; } else if (t1_y > _length + radius && t2_y > _length + radius) { - // Both points are way off the top of the tube; no intersection. + // Both points are way off the top of the capsule; no intersection. return false; } if (t1_y < 0.0f) { - // The starting point is off the bottom of the tube. Test the line + // The starting point is off the bottom of the capsule. Test the line // against the first endcap. double t1a, t2a; if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) { @@ -838,7 +838,7 @@ intersects_line(double &t1, double &t2, t1 = t1a; } else if (t1_y > _length) { - // The starting point is off the top of the tube. Test the line against + // The starting point is off the top of the capsule. Test the line against // the second endcap. double t1b, t2b; if (!sphere_intersects_line(t1b, t2b, _length, from, delta, radius)) { @@ -850,7 +850,7 @@ intersects_line(double &t1, double &t2, } if (t2_y < 0.0f) { - // The ending point is off the bottom of the tube. Test the line against + // The ending point is off the bottom of the capsule. Test the line against // the first endcap. double t1a, t2a; if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) { @@ -861,7 +861,7 @@ intersects_line(double &t1, double &t2, t2 = t2a; } else if (t2_y > _length) { - // The ending point is off the top of the tube. Test the line against the + // The ending point is off the top of the capsule. Test the line against the // second endcap. double t1b, t2b; if (!sphere_intersects_line(t1b, t2b, _length, from, delta, radius)) { @@ -880,7 +880,7 @@ intersects_line(double &t1, double &t2, * whether it intersects one or the other endcaps. The y parameter specifies * the center of the sphere (and hence the particular endcap). */ -bool CollisionTube:: +bool CollisionCapsule:: sphere_intersects_line(double &t1, double &t2, PN_stdfloat center_y, const LPoint3 &from, const LVector3 &delta, PN_stdfloat radius) { @@ -917,14 +917,14 @@ sphere_intersects_line(double &t1, double &t2, PN_stdfloat center_y, } /** - * Determine a point of intersection of a parametric parabola with the tube. + * Determine a point of intersection of a parametric parabola with the capsule. * * We only consider the segment of the parabola between t1 and t2, which has * already been computed as corresponding to points p1 and p2. If there is an * intersection, t is set to the parametric point of intersection, and true is * returned; otherwise, false is returned. */ -bool CollisionTube:: +bool CollisionCapsule:: intersects_parabola(double &t, const LParabola ¶bola, double t1, double t2, const LPoint3 &p1, const LPoint3 &p2) const { @@ -965,11 +965,11 @@ intersects_parabola(double &t, const LParabola ¶bola, } /** - * Calculates a point that is exactly on the surface of the tube and its + * Calculates a point that is exactly on the surface of the capsule and its * corresponding normal, given a point that is supposedly on the surface of - * the tube. + * the capsule. */ -void CollisionTube:: +void CollisionCapsule:: calculate_surface_point_and_normal(const LPoint3 &surface_point, double extra_radius, LPoint3 &result_point, @@ -1015,7 +1015,7 @@ calculate_surface_point_and_normal(const LPoint3 &surface_point, * point in the CollisionEntry, and also compute the relevant normal based on * that point. */ -void CollisionTube:: +void CollisionCapsule:: set_intersection_point(CollisionEntry *new_entry, const LPoint3 &into_intersection_point, double extra_radius) const { @@ -1033,16 +1033,16 @@ set_intersection_point(CollisionEntry *new_entry, new_entry->set_surface_normal(normal); new_entry->set_surface_point(point); - // Also adjust the original point into the tube by the amount of - // extra_radius, which should put it on the surface of the tube if our + // Also adjust the original point into the capsule by the amount of + // extra_radius, which should put it on the surface of the capsule if our // collision was tangential. new_entry->set_interior_point(into_intersection_point - normal * extra_radius); } /** - * Tells the BamReader how to create objects of type CollisionTube. + * Tells the BamReader how to create objects of type CollisionCapsule. */ -void CollisionTube:: +void CollisionCapsule:: register_with_read_factory() { BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); } @@ -1051,7 +1051,7 @@ register_with_read_factory() { * Writes the contents of this object to the datagram for shipping out to a * Bam file. */ -void CollisionTube:: +void CollisionCapsule:: write_datagram(BamWriter *manager, Datagram &dg) { CollisionSolid::write_datagram(manager, dg); _a.write_datagram(dg); @@ -1061,12 +1061,12 @@ write_datagram(BamWriter *manager, Datagram &dg) { /** * This function is called by the BamReader's factory when a new object of - * type CollisionTube is encountered in the Bam file. It should create the - * CollisionTube and extract its information from the file. + * type CollisionCapsule is encountered in the Bam file. It should create the + * CollisionCapsule and extract its information from the file. */ -TypedWritable *CollisionTube:: +TypedWritable *CollisionCapsule:: make_from_bam(const FactoryParams ¶ms) { - CollisionTube *node = new CollisionTube(); + CollisionCapsule *node = new CollisionCapsule(); DatagramIterator scan; BamReader *manager; @@ -1078,9 +1078,9 @@ make_from_bam(const FactoryParams ¶ms) { /** * This internal function is called by make_from_bam to read in all of the - * relevant data from the BamFile for the new CollisionTube. + * relevant data from the BamFile for the new CollisionCapsule. */ -void CollisionTube:: +void CollisionCapsule:: fillin(DatagramIterator &scan, BamReader *manager) { CollisionSolid::fillin(scan, manager); _a.read_datagram(scan); diff --git a/panda/src/collide/collisionTube.h b/panda/src/collide/collisionCapsule.h similarity index 81% rename from panda/src/collide/collisionTube.h rename to panda/src/collide/collisionCapsule.h index 3d91ce2506..af5cbcc92d 100644 --- a/panda/src/collide/collisionTube.h +++ b/panda/src/collide/collisionCapsule.h @@ -6,38 +6,39 @@ * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * - * @file collisionTube.h + * @file collisionCapsule.h * @author drose * @date 2003-09-25 */ -#ifndef COLLISIONTUBE_H -#define COLLISIONTUBE_H +#ifndef COLLISIONCAPSULE_H +#define COLLISIONCAPSULE_H #include "pandabase.h" #include "collisionSolid.h" #include "parabola.h" /** - * This implements a solid roughly in cylindrical shape. It's not called a - * CollisionCylinder because it's not a true cylinder; specifically, it has - * rounded ends instead of flat ends. It looks more like a Contac pill. + * This implements a solid consisting of a cylinder with hemispherical endcaps, + * also known as a capsule or a spherocylinder. + * + * This shape was previously erroneously called CollisionTube. */ -class EXPCL_PANDA_COLLIDE CollisionTube : public CollisionSolid { +class EXPCL_PANDA_COLLIDE CollisionCapsule : public CollisionSolid { PUBLISHED: - INLINE explicit CollisionTube(const LPoint3 &a, const LPoint3 &db, - PN_stdfloat radius); - INLINE explicit CollisionTube(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az, - PN_stdfloat bx, PN_stdfloat by, PN_stdfloat bz, - PN_stdfloat radius); + INLINE explicit CollisionCapsule(const LPoint3 &a, const LPoint3 &db, + PN_stdfloat radius); + INLINE explicit CollisionCapsule(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az, + PN_stdfloat bx, PN_stdfloat by, PN_stdfloat bz, + PN_stdfloat radius); virtual LPoint3 get_collision_origin() const; private: - INLINE CollisionTube(); + INLINE CollisionCapsule(); public: - INLINE CollisionTube(const CollisionTube ©); + INLINE CollisionCapsule(const CollisionCapsule ©); virtual CollisionSolid *make_copy(); virtual PT(CollisionEntry) @@ -82,7 +83,7 @@ protected: virtual PT(CollisionEntry) test_intersection_from_segment(const CollisionEntry &entry) const; virtual PT(CollisionEntry) - test_intersection_from_tube(const CollisionEntry &entry) const; + test_intersection_from_capsule(const CollisionEntry &entry) const; virtual PT(CollisionEntry) test_intersection_from_parabola(const CollisionEntry &entry) const; @@ -141,7 +142,7 @@ public: } static void init_type() { CollisionSolid::init_type(); - register_type(_type_handle, "CollisionTube", + register_type(_type_handle, "CollisionCapsule", CollisionSolid::get_class_type()); } virtual TypeHandle get_type() const { @@ -155,6 +156,13 @@ private: friend class CollisionBox; }; -#include "collisionTube.I" +BEGIN_PUBLISH +/** + * Alias for backward compatibility. + */ +typedef CollisionCapsule CollisionTube; +END_PUBLISH + +#include "collisionCapsule.I" #endif diff --git a/panda/src/collide/collisionHandlerFluidPusher.cxx b/panda/src/collide/collisionHandlerFluidPusher.cxx index df15e8bacc..622f5da00d 100644 --- a/panda/src/collide/collisionHandlerFluidPusher.cxx +++ b/panda/src/collide/collisionHandlerFluidPusher.cxx @@ -72,7 +72,7 @@ handle_entries() { PosB = collider's current position M = movement vector (PosB - PosA) BV = bounding sphere that includes collider at PosA and PosB - CS = 'collision set', all 'collidables' within BV (collision polys, tubes, etc) + CS = 'collision set', all 'collidables' within BV (collision polys, capsules, etc) VARIABLES N = movement vector since most recent collision (or start of frame) diff --git a/panda/src/collide/collisionPlane.cxx b/panda/src/collide/collisionPlane.cxx index 8a325ea082..2e174d4aa8 100644 --- a/panda/src/collide/collisionPlane.cxx +++ b/panda/src/collide/collisionPlane.cxx @@ -18,7 +18,7 @@ #include "collisionLine.h" #include "collisionRay.h" #include "collisionSegment.h" -#include "collisionTube.h" +#include "collisionCapsule.h" #include "collisionParabola.h" #include "config_collide.h" #include "pointerToArray.h" @@ -298,16 +298,16 @@ test_intersection_from_segment(const CollisionEntry &entry) const { * */ PT(CollisionEntry) CollisionPlane:: -test_intersection_from_tube(const CollisionEntry &entry) const { - const CollisionTube *tube; - DCAST_INTO_R(tube, entry.get_from(), nullptr); +test_intersection_from_capsule(const CollisionEntry &entry) const { + const CollisionCapsule *capsule; + DCAST_INTO_R(capsule, entry.get_from(), nullptr); const LMatrix4 &wrt_mat = entry.get_wrt_mat(); - LPoint3 from_a = tube->get_point_a() * wrt_mat; - LPoint3 from_b = tube->get_point_b() * wrt_mat; + LPoint3 from_a = capsule->get_point_a() * wrt_mat; + LPoint3 from_b = capsule->get_point_b() * wrt_mat; LVector3 from_radius_v = - LVector3(tube->get_radius(), 0.0f, 0.0f) * wrt_mat; + LVector3(capsule->get_radius(), 0.0f, 0.0f) * wrt_mat; PN_stdfloat from_radius = length(from_radius_v); PN_stdfloat dist_a = _plane.dist_to_plane(from_a); @@ -325,7 +325,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const { } PT(CollisionEntry) new_entry = new CollisionEntry(entry); - LVector3 normal = (has_effective_normal() && tube->get_respect_effective_normal()) ? get_effective_normal() : get_normal(); + LVector3 normal = (has_effective_normal() && capsule->get_respect_effective_normal()) ? get_effective_normal() : get_normal(); new_entry->set_surface_normal(normal); PN_stdfloat t; @@ -339,17 +339,17 @@ test_intersection_from_tube(const CollisionEntry &entry) const { new_entry->set_surface_point(from_a - get_normal() * dist_a); } else { - // Within the tube! Yay, that means we have a surface point. + // Within the capsule! Yay, that means we have a surface point. new_entry->set_surface_point(from_a + t * from_direction); } } else { // If it's completely parallel, pretend it's colliding in the center of - // the tube. + // the capsule. new_entry->set_surface_point(from_a + 0.5f * from_direction - get_normal() * dist_a); } if (IS_NEARLY_EQUAL(dist_a, dist_b)) { - // Let's be fair and choose the center of the tube. + // Let's be fair and choose the center of the capsule. new_entry->set_interior_point(from_a + 0.5f * from_direction - get_normal() * from_radius); } else if (dist_a < dist_b) { diff --git a/panda/src/collide/collisionPlane.h b/panda/src/collide/collisionPlane.h index bc7602ba8b..719e33f489 100644 --- a/panda/src/collide/collisionPlane.h +++ b/panda/src/collide/collisionPlane.h @@ -72,7 +72,7 @@ protected: virtual PT(CollisionEntry) test_intersection_from_segment(const CollisionEntry &entry) const; virtual PT(CollisionEntry) - test_intersection_from_tube(const CollisionEntry &entry) const; + test_intersection_from_capsule(const CollisionEntry &entry) const; virtual PT(CollisionEntry) test_intersection_from_parabola(const CollisionEntry &entry) const; virtual PT(CollisionEntry) diff --git a/panda/src/collide/collisionSolid.cxx b/panda/src/collide/collisionSolid.cxx index b862ec7c73..b68673be15 100644 --- a/panda/src/collide/collisionSolid.cxx +++ b/panda/src/collide/collisionSolid.cxx @@ -17,7 +17,7 @@ #include "collisionLine.h" #include "collisionRay.h" #include "collisionSegment.h" -#include "collisionTube.h" +#include "collisionCapsule.h" #include "collisionParabola.h" #include "collisionBox.h" #include "collisionEntry.h" @@ -240,11 +240,11 @@ test_intersection_from_segment(const CollisionEntry &) const { /** * This is part of the double-dispatch implementation of test_intersection(). - * It is called when the "from" object is a tube. + * It is called when the "from" object is a capsule. */ PT(CollisionEntry) CollisionSolid:: -test_intersection_from_tube(const CollisionEntry &) const { - report_undefined_intersection_test(CollisionTube::get_class_type(), +test_intersection_from_capsule(const CollisionEntry &) const { + report_undefined_intersection_test(CollisionCapsule::get_class_type(), get_type()); return nullptr; } diff --git a/panda/src/collide/collisionSolid.h b/panda/src/collide/collisionSolid.h index 6b2914e954..4721d70381 100644 --- a/panda/src/collide/collisionSolid.h +++ b/panda/src/collide/collisionSolid.h @@ -108,7 +108,7 @@ protected: virtual PT(CollisionEntry) test_intersection_from_segment(const CollisionEntry &entry) const; virtual PT(CollisionEntry) - test_intersection_from_tube(const CollisionEntry &entry) const; + test_intersection_from_capsule(const CollisionEntry &entry) const; virtual PT(CollisionEntry) test_intersection_from_parabola(const CollisionEntry &entry) const; virtual PT(CollisionEntry) @@ -177,7 +177,7 @@ private: friend class CollisionLine; friend class CollisionRay; friend class CollisionSegment; - friend class CollisionTube; + friend class CollisionCapsule; friend class CollisionParabola; friend class CollisionHandlerFluidPusher; friend class CollisionBox; diff --git a/panda/src/collide/collisionSphere.cxx b/panda/src/collide/collisionSphere.cxx index a07b1fbcbc..aacc43fcb2 100644 --- a/panda/src/collide/collisionSphere.cxx +++ b/panda/src/collide/collisionSphere.cxx @@ -17,7 +17,7 @@ #include "collisionHandler.h" #include "collisionEntry.h" #include "collisionSegment.h" -#include "collisionTube.h" +#include "collisionCapsule.h" #include "collisionParabola.h" #include "collisionBox.h" #include "config_collide.h" @@ -444,18 +444,18 @@ test_intersection_from_segment(const CollisionEntry &entry) const { * */ PT(CollisionEntry) CollisionSphere:: -test_intersection_from_tube(const CollisionEntry &entry) const { - const CollisionTube *tube; - DCAST_INTO_R(tube, entry.get_from(), nullptr); +test_intersection_from_capsule(const CollisionEntry &entry) const { + const CollisionCapsule *capsule; + DCAST_INTO_R(capsule, entry.get_from(), nullptr); const LMatrix4 &wrt_mat = entry.get_wrt_mat(); - LPoint3 from_a = tube->get_point_a() * wrt_mat; - LPoint3 from_b = tube->get_point_b() * wrt_mat; + LPoint3 from_a = capsule->get_point_a() * wrt_mat; + LPoint3 from_b = capsule->get_point_b() * wrt_mat; LVector3 from_direction = from_b - from_a; LVector3 from_radius_v = - LVector3(tube->get_radius(), 0.0f, 0.0f) * wrt_mat; + LVector3(capsule->get_radius(), 0.0f, 0.0f) * wrt_mat; PN_stdfloat from_radius = length(from_radius_v); double t1, t2; @@ -465,8 +465,8 @@ test_intersection_from_tube(const CollisionEntry &entry) const { } if (t2 < 0.0 || t1 > 1.0) { - // Both intersection points are before the start of the tube or after - // the end of the tube. + // Both intersection points are before the start of the capsule or after + // the end of the capsule. return nullptr; } @@ -487,7 +487,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const { new_entry->set_surface_point(get_center() + normal * get_radius()); new_entry->set_interior_point(inner_point - normal * from_radius); - if (has_effective_normal() && tube->get_respect_effective_normal()) { + if (has_effective_normal() && capsule->get_respect_effective_normal()) { new_entry->set_surface_normal(get_effective_normal()); } else { new_entry->set_surface_normal(normal); diff --git a/panda/src/collide/collisionSphere.h b/panda/src/collide/collisionSphere.h index 8337644b42..39b21d59f1 100644 --- a/panda/src/collide/collisionSphere.h +++ b/panda/src/collide/collisionSphere.h @@ -72,7 +72,7 @@ protected: virtual PT(CollisionEntry) test_intersection_from_segment(const CollisionEntry &entry) const; virtual PT(CollisionEntry) - test_intersection_from_tube(const CollisionEntry &entry) const; + test_intersection_from_capsule(const CollisionEntry &entry) const; virtual PT(CollisionEntry) test_intersection_from_parabola(const CollisionEntry &entry) const; virtual PT(CollisionEntry) diff --git a/panda/src/collide/collisionTraverser.cxx b/panda/src/collide/collisionTraverser.cxx index 35f7966a3f..794e7552da 100644 --- a/panda/src/collide/collisionTraverser.cxx +++ b/panda/src/collide/collisionTraverser.cxx @@ -20,7 +20,7 @@ #include "collisionVisualizer.h" #include "collisionSphere.h" #include "collisionBox.h" -#include "collisionTube.h" +#include "collisionCapsule.h" #include "collisionPolygon.h" #include "collisionPlane.h" #include "config_collide.h" @@ -345,7 +345,7 @@ traverse(const NodePath &root) { _geom_volume_pcollector.flush_level(); CollisionSphere::flush_level(); - CollisionTube::flush_level(); + CollisionCapsule::flush_level(); CollisionPolygon::flush_level(); CollisionPlane::flush_level(); CollisionBox::flush_level(); diff --git a/panda/src/collide/config_collide.cxx b/panda/src/collide/config_collide.cxx index 38c821ed05..b9ca4e368a 100644 --- a/panda/src/collide/config_collide.cxx +++ b/panda/src/collide/config_collide.cxx @@ -13,6 +13,7 @@ #include "config_collide.h" #include "collisionBox.h" +#include "collisionCapsule.h" #include "collisionEntry.h" #include "collisionHandler.h" #include "collisionHandlerEvent.h" @@ -38,7 +39,6 @@ #include "collisionSolid.h" #include "collisionSphere.h" #include "collisionTraverser.h" -#include "collisionTube.h" #include "collisionVisualizer.h" #include "dconfig.h" @@ -126,6 +126,7 @@ init_libcollide() { initialized = true; CollisionBox::init_type(); + CollisionCapsule::init_type(); CollisionEntry::init_type(); CollisionHandler::init_type(); CollisionHandlerEvent::init_type(); @@ -150,14 +151,18 @@ init_libcollide() { CollisionSolid::init_type(); CollisionSphere::init_type(); CollisionTraverser::init_type(); - CollisionTube::init_type(); #ifdef DO_COLLISION_RECORDING CollisionRecorder::init_type(); CollisionVisualizer::init_type(); #endif + // Record the old name for CollisionCapsule for backwards compatibility. + BamWriter::record_obsolete_type_name(CollisionCapsule::get_class_type(), + "CollisionTube", 6, 44); + CollisionBox::register_with_read_factory(); + CollisionCapsule::register_with_read_factory(); CollisionInvSphere::register_with_read_factory(); CollisionLine::register_with_read_factory(); CollisionNode::register_with_read_factory(); @@ -168,5 +173,4 @@ init_libcollide() { CollisionRay::register_with_read_factory(); CollisionSegment::register_with_read_factory(); CollisionSphere::register_with_read_factory(); - CollisionTube::register_with_read_factory(); } diff --git a/panda/src/collide/p3collide_composite1.cxx b/panda/src/collide/p3collide_composite1.cxx index d66b71b18c..af8ecc07d8 100644 --- a/panda/src/collide/p3collide_composite1.cxx +++ b/panda/src/collide/p3collide_composite1.cxx @@ -1,5 +1,6 @@ #include "config_collide.cxx" #include "collisionBox.cxx" +#include "collisionCapsule.cxx" #include "collisionEntry.cxx" #include "collisionGeom.cxx" #include "collisionHandler.cxx" @@ -12,5 +13,3 @@ #include "collisionHandlerFluidPusher.cxx" #include "collisionHandlerQueue.cxx" #include "collisionInvSphere.cxx" -#include "collisionLevelStateBase.cxx" -#include "collisionLevelState.cxx" diff --git a/panda/src/collide/p3collide_composite2.cxx b/panda/src/collide/p3collide_composite2.cxx index 50a6acdddc..4b74e9dd9e 100644 --- a/panda/src/collide/p3collide_composite2.cxx +++ b/panda/src/collide/p3collide_composite2.cxx @@ -1,3 +1,5 @@ +#include "collisionLevelStateBase.cxx" +#include "collisionLevelState.cxx" #include "collisionLine.cxx" #include "collisionNode.cxx" #include "collisionParabola.cxx" @@ -10,5 +12,4 @@ #include "collisionSolid.cxx" #include "collisionSphere.cxx" #include "collisionTraverser.cxx" -#include "collisionTube.cxx" #include "collisionVisualizer.cxx" diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index c06c2b207f..ae1052ba1d 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -110,8 +110,8 @@ PStatCollector GraphicsEngine::_volume_sphere_pcollector("Collision Volumes:Coll PStatCollector GraphicsEngine::_test_sphere_pcollector("Collision Tests:CollisionSphere"); PStatCollector GraphicsEngine::_volume_box_pcollector("Collision Volumes:CollisionBox"); PStatCollector GraphicsEngine::_test_box_pcollector("Collision Tests:CollisionBox"); -PStatCollector GraphicsEngine::_volume_tube_pcollector("Collision Volumes:CollisionTube"); -PStatCollector GraphicsEngine::_test_tube_pcollector("Collision Tests:CollisionTube"); +PStatCollector GraphicsEngine::_volume_capsule_pcollector("Collision Volumes:CollisionCapsule"); +PStatCollector GraphicsEngine::_test_capsule_pcollector("Collision Tests:CollisionCapsule"); PStatCollector GraphicsEngine::_volume_inv_sphere_pcollector("Collision Volumes:CollisionInvSphere"); PStatCollector GraphicsEngine::_test_inv_sphere_pcollector("Collision Tests:CollisionInvSphere"); PStatCollector GraphicsEngine::_volume_geom_pcollector("Collision Volumes:CollisionGeom"); @@ -875,8 +875,8 @@ render_frame() { _test_sphere_pcollector.clear_level(); _volume_box_pcollector.clear_level(); _test_box_pcollector.clear_level(); - _volume_tube_pcollector.clear_level(); - _test_tube_pcollector.clear_level(); + _volume_capsule_pcollector.clear_level(); + _test_capsule_pcollector.clear_level(); _volume_inv_sphere_pcollector.clear_level(); _test_inv_sphere_pcollector.clear_level(); _volume_geom_pcollector.clear_level(); diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index 3371f20b39..e3e7df66c8 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -401,8 +401,8 @@ private: static PStatCollector _test_sphere_pcollector; static PStatCollector _volume_box_pcollector; static PStatCollector _test_box_pcollector; - static PStatCollector _volume_tube_pcollector; - static PStatCollector _test_tube_pcollector; + static PStatCollector _volume_capsule_pcollector; + static PStatCollector _test_capsule_pcollector; static PStatCollector _volume_inv_sphere_pcollector; static PStatCollector _test_inv_sphere_pcollector; static PStatCollector _volume_geom_pcollector; diff --git a/panda/src/doc/collisionFlags.txt b/panda/src/doc/collisionFlags.txt index 4989ef8e33..04a890f42b 100644 --- a/panda/src/doc/collisionFlags.txt +++ b/panda/src/doc/collisionFlags.txt @@ -6,7 +6,7 @@ camera-collide: for things that the camera should avoid trigger: for things (usually not barriers or floors) that should trigger an event when avatars intersect with them sphere: for things that should have a collision sphere around them -tube: for things that should have a collision tube (cylinder) around them +tube: for things that should have a collision capsule around them NOTES diff --git a/panda/src/egg/eggGroup.cxx b/panda/src/egg/eggGroup.cxx index 6bc6f152f0..fe36f2b123 100644 --- a/panda/src/egg/eggGroup.cxx +++ b/panda/src/egg/eggGroup.cxx @@ -897,7 +897,8 @@ string_cs_type(const string &strval) { } else if (cmp_nocase_uh(strval, "inv-sphere") == 0 || cmp_nocase_uh(strval, "invsphere") == 0) { return CST_inv_sphere; - } else if (cmp_nocase_uh(strval, "tube") == 0) { + } else if (cmp_nocase_uh(strval, "tube") == 0 || + cmp_nocase_uh(strval, "capsule") == 0) { return CST_tube; } else if (cmp_nocase_uh(strval, "floor-mesh") == 0 || cmp_nocase_uh(strval, "floormesh") == 0) { diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index 9d885e0234..6aeb84f54f 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -74,7 +74,7 @@ #include "collisionNode.h" #include "collisionSphere.h" #include "collisionInvSphere.h" -#include "collisionTube.h" +#include "collisionCapsule.h" #include "collisionPlane.h" #include "collisionPolygon.h" #include "collisionFloorMesh.h" @@ -2865,7 +2865,7 @@ make_collision_solids(EggGroup *start_group, EggGroup *egg_group, break; case EggGroup::CST_tube: - make_collision_tube(egg_group, cnode, start_group->get_collide_flags()); + make_collision_capsule(egg_group, cnode, start_group->get_collide_flags()); break; case EggGroup::CST_floor_mesh: @@ -3045,12 +3045,12 @@ make_collision_inv_sphere(EggGroup *egg_group, CollisionNode *cnode, } /** - * Creates a single CollisionTube corresponding to the polygons associated + * Creates a single CollisionCapsule corresponding to the polygons associated * with this group. */ void EggLoader:: -make_collision_tube(EggGroup *egg_group, CollisionNode *cnode, - EggGroup::CollideFlags flags) { +make_collision_capsule(EggGroup *egg_group, CollisionNode *cnode, + EggGroup::CollideFlags flags) { EggGroup *geom_group = find_collision_geometry(egg_group, flags); if (geom_group != nullptr) { // Collect all of the vertices. @@ -3175,7 +3175,7 @@ make_collision_tube(EggGroup *egg_group, CollisionNode *cnode, // Transform all of the points so that the major axis is along the Y // axis, and the origin is the center. This is very similar to the - // CollisionTube's idea of its canonical orientation (although not + // CollisionCapsule's idea of its canonical orientation (although not // exactly the same, since it is centered on the origin instead of // having point_a on the origin). It makes it easier to determine the // length and radius of the cylinder. @@ -3230,11 +3230,11 @@ make_collision_tube(EggGroup *egg_group, CollisionNode *cnode, LPoint3d point_a = center - half; LPoint3d point_b = center + half; - CollisionTube *cstube = - new CollisionTube(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b), + CollisionCapsule *cscapsule = + new CollisionCapsule(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b), radius); - apply_collision_flags(cstube, flags); - cnode->add_solid(cstube); + apply_collision_flags(cscapsule, flags); + cnode->add_solid(cscapsule); } } } diff --git a/panda/src/egg2pg/eggLoader.h b/panda/src/egg2pg/eggLoader.h index eb81317bd8..0f974f41c2 100644 --- a/panda/src/egg2pg/eggLoader.h +++ b/panda/src/egg2pg/eggLoader.h @@ -180,8 +180,8 @@ private: EggGroup::CollideFlags flags); void make_collision_inv_sphere(EggGroup *egg_group, CollisionNode *cnode, EggGroup::CollideFlags flags); - void make_collision_tube(EggGroup *egg_group, CollisionNode *cnode, - EggGroup::CollideFlags flags); + void make_collision_capsule(EggGroup *egg_group, CollisionNode *cnode, + EggGroup::CollideFlags flags); void make_collision_floor_mesh(EggGroup *egg_group, CollisionNode *cnode, EggGroup::CollideFlags flags); void apply_collision_flags(CollisionSolid *solid, diff --git a/panda/src/egg2pg/eggSaver.cxx b/panda/src/egg2pg/eggSaver.cxx index fb6bb3a59b..9aba56cc01 100644 --- a/panda/src/egg2pg/eggSaver.cxx +++ b/panda/src/egg2pg/eggSaver.cxx @@ -39,7 +39,7 @@ #include "collisionSphere.h" #include "collisionBox.h" #include "collisionInvSphere.h" -#include "collisionTube.h" +#include "collisionCapsule.h" #include "textureStage.h" #include "geomNode.h" #include "geom.h" @@ -620,13 +620,13 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path, egg_poly->add_vertex(cvpool->create_unique_vertex(ev0)); egg_poly->add_vertex(cvpool->create_unique_vertex(ev1)); - } else if (child->is_of_type(CollisionTube::get_class_type())) { - CPT(CollisionTube) tube = DCAST(CollisionTube, child); - LPoint3 point_a = tube->get_point_a(); - LPoint3 point_b = tube->get_point_b(); + } else if (child->is_of_type(CollisionCapsule::get_class_type())) { + CPT(CollisionCapsule) capsule = DCAST(CollisionCapsule, child); + LPoint3 point_a = capsule->get_point_a(); + LPoint3 point_b = capsule->get_point_b(); LPoint3 centroid = (point_a + point_b) * 0.5f; - // Also get an arbitrary vector perpendicular to the tube. + // Also get an arbitrary vector perpendicular to the capsule. LVector3 axis = point_b - point_a; LVector3 sideways; if (std::fabs(axis[2]) > std::fabs(axis[1])) { @@ -635,18 +635,18 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path, sideways = axis.cross(LVector3(0, 0, 1)); } sideways.normalize(); - sideways *= tube->get_radius(); - LVector3 extend = axis.normalized() * tube->get_radius(); + sideways *= capsule->get_radius(); + LVector3 extend = axis.normalized() * capsule->get_radius(); - EggGroup *egg_tube; + EggGroup *egg_capsule; if (num_solids == 1) { - egg_tube = egg_group; + egg_capsule = egg_group; } else { - egg_tube = new EggGroup; - egg_group->add_child(egg_tube); + egg_capsule = new EggGroup; + egg_group->add_child(egg_capsule); } - egg_tube->set_cs_type(EggGroup::CST_tube); - egg_tube->set_collide_flags(flags); + egg_capsule->set_cs_type(EggGroup::CST_tube); + egg_capsule->set_collide_flags(flags); // Add two points for the endcaps, and then two points around the // centroid to indicate the radius. @@ -657,7 +657,7 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path, ev3.set_pos(LCAST(double, (centroid - sideways) * net_mat)); EggPolygon *egg_poly = new EggPolygon; - egg_tube->add_child(egg_poly); + egg_capsule->add_child(egg_poly); egg_poly->add_vertex(cvpool->create_unique_vertex(ev0)); egg_poly->add_vertex(cvpool->create_unique_vertex(ev1)); diff --git a/panda/src/putil/bam.h b/panda/src/putil/bam.h index 96f41cbf98..e21dadbc14 100644 --- a/panda/src/putil/bam.h +++ b/panda/src/putil/bam.h @@ -32,7 +32,7 @@ static const unsigned short _bam_major_ver = 6; // Bumped to major version 6 on 2006-02-11 to factor out PandaNode::CData. static const unsigned short _bam_first_minor_ver = 14; -static const unsigned short _bam_minor_ver = 43; +static const unsigned short _bam_minor_ver = 44; // Bumped to minor version 14 on 2007-12-19 to change default ColorAttrib. // Bumped to minor version 15 on 2008-04-09 to add TextureAttrib::_implicit_sort. // Bumped to minor version 16 on 2008-05-13 to add Texture::_quality_level. @@ -63,5 +63,6 @@ static const unsigned short _bam_minor_ver = 43; // Bumped to minor version 41 on 2016-03-02 to change LensNode, Lens, and Camera. // Bumped to minor version 42 on 2016-04-08 to expand ColorBlendAttrib. // Bumped to minor version 43 on 2018-12-06 to expand BillboardEffect and CompassEffect. +// Bumped to minor version 44 on 2018-12-23 to rename CollisionTube to CollisionCapsule. #endif diff --git a/panda/src/putil/bamWriter.cxx b/panda/src/putil/bamWriter.cxx index d8aa3e0b30..3de731d27d 100644 --- a/panda/src/putil/bamWriter.cxx +++ b/panda/src/putil/bamWriter.cxx @@ -20,9 +20,28 @@ #include "bamWriter.h" #include "bamReader.h" #include "lightMutexHolder.h" +#include "simpleHashMap.h" #include +// Keeps track of older type names in case we want to write out older .bam +// files. +struct ObsoleteName { + std::string _name; + int _before_major; + int _before_minor; + + bool operator < (const ObsoleteName &other) const { + if (_before_major != other._before_major) { + return _before_major < other._before_major; + } + return _before_minor < other._before_minor; + } +}; + +// This is a SimpleHashMap to avoid static init ordering issues. +static SimpleHashMap > obsolete_type_names; + /** * */ @@ -504,7 +523,14 @@ write_handle(Datagram &packet, TypeHandle type) { if (inserted) { // This is the first time this TypeHandle has been written, so also // write out its definition. - packet.add_string(type.get_name()); + + if (_file_major == _bam_major_ver && _file_minor == _bam_minor_ver) { + packet.add_string(type.get_name()); + } else { + // We are writing an older .bam format, so we need to look up whether + // we may need to write an older type name. + packet.add_string(get_obsolete_type_name(type, _file_major, _file_minor)); + } // We also need to write the derivation of the TypeHandle, in case the // program reading this file later has never heard of this type before. @@ -518,6 +544,45 @@ write_handle(Datagram &packet, TypeHandle type) { } } +/** + * Returns the name that the given type had in an older .bam version. + */ +std::string BamWriter:: +get_obsolete_type_name(TypeHandle type, int major, int minor) { + int index = obsolete_type_names.find(type); + if (index >= 0) { + // Iterate over the names. It is sorted such that the lower versions are + // listed first. + for (const ObsoleteName &name : obsolete_type_names.get_data((size_t)index)) { + if (major < name._before_major || + (major == name._before_major && minor < name._before_minor)) { + // We have a hit. + return name._name; + } + } + } + + return TypeRegistry::ptr()->get_name(type, nullptr); +} + +/** + * Registers the given type as having an older name in .bam files *before* the + * indicated version. You can call this multiple times for the same type in + * order to establish a history of renames for this type. + */ +void BamWriter:: +record_obsolete_type_name(TypeHandle type, std::string name, + int before_major, int before_minor) { + // Make sure it is registered as alternate name for reading. + TypeRegistry *reg = TypeRegistry::ptr(); + reg->record_alternate_name(type, name); + + ObsoleteName obsolete_name; + obsolete_name._name = std::move(name); + obsolete_name._before_major = before_major; + obsolete_name._before_minor = before_minor; + obsolete_type_names[type].insert(std::move(obsolete_name)); +} /** * This is called by the TypedWritable destructor. It should remove the diff --git a/panda/src/putil/bamWriter.h b/panda/src/putil/bamWriter.h index b8c53aac38..780104b61c 100644 --- a/panda/src/putil/bamWriter.h +++ b/panda/src/putil/bamWriter.h @@ -111,6 +111,10 @@ public: bool register_pta(Datagram &packet, const void *ptr); void write_handle(Datagram &packet, TypeHandle type); + static std::string get_obsolete_type_name(TypeHandle type, int major, int minor); + static void record_obsolete_type_name(TypeHandle type, std::string name, + int before_major, int before_minor); + private: void object_destructs(TypedWritable *object); diff --git a/pandatool/src/eggprogs/eggMakeTube.cxx b/pandatool/src/eggprogs/eggMakeTube.cxx index 7017e97dcd..85ec85081d 100644 --- a/pandatool/src/eggprogs/eggMakeTube.cxx +++ b/pandatool/src/eggprogs/eggMakeTube.cxx @@ -29,7 +29,7 @@ EggMakeTube() { set_program_description ("egg-make-tube generates an egg file representing a \"tube\" model, " "a cylinder capped on both ends by hemispheres. This is similar " - "in shape to the CollisionTube object within Panda.\n\n" + "in shape to the CollisionCapsule object within Panda.\n\n" "This program can also generate spheres if you omit -b; in this " "case, you are generating a degenerate tube of length 0."); diff --git a/pandatool/src/eggprogs/eggMakeTube.h b/pandatool/src/eggprogs/eggMakeTube.h index 520d178aee..3031b1c74e 100644 --- a/pandatool/src/eggprogs/eggMakeTube.h +++ b/pandatool/src/eggprogs/eggMakeTube.h @@ -24,7 +24,7 @@ class EggVertex; /** * A program to generate an egg file representing a tube model, similar in - * shape to a CollisionTube. + * shape to a CollisionCapsule. */ class EggMakeTube : public EggMakeSomething { public: diff --git a/tests/collide/test_collision_tube.py b/tests/collide/test_collision_tube.py new file mode 100644 index 0000000000..3d97754d87 --- /dev/null +++ b/tests/collide/test_collision_tube.py @@ -0,0 +1,63 @@ +from panda3d import core + + +def test_collision_tube_alias(): + assert hasattr(core, 'CollisionCapsule') + assert hasattr(core, 'CollisionTube') + assert core.CollisionTube is core.CollisionCapsule + + +def test_collision_tube_write_old(): + buffer = core.DatagramBuffer() + writer = core.BamWriter(buffer) + assert writer.get_file_major_ver() == 6 + writer.set_file_minor_ver(43) + + capsule = core.CollisionCapsule((0, 0, -1), (0, 0, 1), 0.5) + writer.init() + writer.write_object(capsule) + writer.flush() + + data = buffer.data + assert b'CollisionTube' in data + assert b'CollisionCapsule' not in data + + +def test_collision_tube_write_new(): + buffer = core.DatagramBuffer() + writer = core.BamWriter(buffer) + assert writer.get_file_major_ver() == 6 + writer.set_file_minor_ver(44) + + capsule = core.CollisionCapsule((0, 0, -1), (0, 0, 1), 0.5) + writer.init() + writer.write_object(capsule) + writer.flush() + + data = buffer.data + assert b'CollisionTube' not in data + assert b'CollisionCapsule' in data + + +def test_collision_tube_read_old(): + # Make sure we can read an older file that contains CollisionTube. + buffer = core.DatagramBuffer(b'\x06\x00\x00\x00\x06\x00+\x00\x01\x00\xd6\x00\x00\x00\x00j\x01\r\x00CollisionTube\x01h\x01\x0e\x00CollisionSolid\x01B\x00\x11\x00CopyOnWriteObject\x01A\x00!\x00CachedTypedWritableReferenceCount\x01=\x00\x1b\x00TypedWritableReferenceCount\x02<\x00\r\x00TypedWritable\x01\x03\x00\x0b\x00TypedObject\x00\x07\x00\x0e\x00ReferenceCount\x00\x01\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80?\x00\x00\x00?\x01\x00\x00\x00\x01') + reader = core.BamReader(buffer) + reader.init() + assert reader.file_version == (6, 43) + + capsule = reader.read_object() + reader.resolve() + assert isinstance(capsule, core.CollisionCapsule) + + +def test_collision_tube_read_new(): + # Make sure we can read a newer file that contains CollisionCapsule. + buffer = core.DatagramBuffer(b'\x06\x00\x00\x00\x06\x00,\x00\x01\x00\xd9\x00\x00\x00\x00j\x01\x10\x00CollisionCapsule\x01h\x01\x0e\x00CollisionSolid\x01B\x00\x11\x00CopyOnWriteObject\x01A\x00!\x00CachedTypedWritableReferenceCount\x01=\x00\x1b\x00TypedWritableReferenceCount\x02<\x00\r\x00TypedWritable\x01\x03\x00\x0b\x00TypedObject\x00\x07\x00\x0e\x00ReferenceCount\x00\x01\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80?\x00\x00\x00?\x01\x00\x00\x00\x01') + reader = core.BamReader(buffer) + reader.init() + assert reader.file_version == (6, 44) + + capsule = reader.read_object() + reader.resolve() + assert isinstance(capsule, core.CollisionCapsule)