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
This commit is contained in:
rdb 2018-12-23 19:44:53 +01:00
parent b40ecd6c51
commit bd6ef2b0ea
33 changed files with 360 additions and 214 deletions

View File

@ -1043,7 +1043,7 @@
<File RelativePath="..\panda\src\collide\collisionLine.I"></File> <File RelativePath="..\panda\src\collide\collisionLine.I"></File>
<File RelativePath="..\panda\src\collide\collisionHandlerFluidPusher.h"></File> <File RelativePath="..\panda\src\collide\collisionHandlerFluidPusher.h"></File>
<File RelativePath="..\panda\src\collide\config_collide.h"></File> <File RelativePath="..\panda\src\collide\config_collide.h"></File>
<File RelativePath="..\panda\src\collide\collisionTube.h"></File> <File RelativePath="..\panda\src\collide\collisionCapsule.h"></File>
<File RelativePath="..\panda\src\collide\collisionSegment.cxx"></File> <File RelativePath="..\panda\src\collide\collisionSegment.cxx"></File>
<File RelativePath="..\panda\src\collide\collisionBox.h"></File> <File RelativePath="..\panda\src\collide\collisionBox.h"></File>
<File RelativePath="..\panda\src\collide\collide_composite1.cxx"></File> <File RelativePath="..\panda\src\collide\collide_composite1.cxx"></File>
@ -1054,7 +1054,7 @@
<File RelativePath="..\panda\src\collide\collisionNode.h"></File> <File RelativePath="..\panda\src\collide\collisionNode.h"></File>
<File RelativePath="..\panda\src\collide\collisionGeom.I"></File> <File RelativePath="..\panda\src\collide\collisionGeom.I"></File>
<File RelativePath="..\panda\src\collide\collisionSegment.I"></File> <File RelativePath="..\panda\src\collide\collisionSegment.I"></File>
<File RelativePath="..\panda\src\collide\collisionTube.cxx"></File> <File RelativePath="..\panda\src\collide\collisionCapsule.cxx"></File>
<File RelativePath="..\panda\src\collide\collisionHandlerQueue.h"></File> <File RelativePath="..\panda\src\collide\collisionHandlerQueue.h"></File>
<File RelativePath="..\panda\src\collide\collisionParabola.I"></File> <File RelativePath="..\panda\src\collide\collisionParabola.I"></File>
<File RelativePath="..\panda\src\collide\collisionPlane.cxx"></File> <File RelativePath="..\panda\src\collide\collisionPlane.cxx"></File>
@ -1089,7 +1089,7 @@
<File RelativePath="..\panda\src\collide\collisionInvSphere.cxx"></File> <File RelativePath="..\panda\src\collide\collisionInvSphere.cxx"></File>
<File RelativePath="..\panda\src\collide\collisionLine.cxx"></File> <File RelativePath="..\panda\src\collide\collisionLine.cxx"></File>
<File RelativePath="..\panda\src\collide\collisionEntry.I"></File> <File RelativePath="..\panda\src\collide\collisionEntry.I"></File>
<File RelativePath="..\panda\src\collide\collisionTube.I"></File> <File RelativePath="..\panda\src\collide\collisionCapsule.I"></File>
<File RelativePath="..\panda\src\collide\collisionSolid.h"></File> <File RelativePath="..\panda\src\collide\collisionSolid.h"></File>
<File RelativePath="..\panda\src\collide\collisionPlane.I"></File> <File RelativePath="..\panda\src\collide\collisionPlane.I"></File>
<File RelativePath="..\panda\src\collide\collisionHandlerGravity.cxx"></File> <File RelativePath="..\panda\src\collide\collisionHandlerGravity.cxx"></File>

View File

@ -28,7 +28,7 @@
#include "collisionPlane.h" #include "collisionPlane.h"
#include "collisionSphere.h" #include "collisionSphere.h"
#include "collisionPolygon.h" #include "collisionPolygon.h"
#include "collisionTube.h" #include "collisionCapsule.h"
TypeHandle BulletBodyNode::_type_handle; TypeHandle BulletBodyNode::_type_handle;
@ -813,12 +813,12 @@ add_shapes_from_collision_solids(CollisionNode *cnode) {
do_add_shape(BulletBoxShape::make_from_solid(box), ts); do_add_shape(BulletBoxShape::make_from_solid(box), ts);
} }
// CollisionTube // CollisionCapsule
else if (CollisionTube::get_class_type() == type) { else if (CollisionCapsule::get_class_type() == type) {
CPT(CollisionTube) tube = DCAST(CollisionTube, solid); CPT(CollisionCapsule) capsule = DCAST(CollisionCapsule, solid);
CPT(TransformState) ts = TransformState::make_pos((tube->get_point_b() + tube->get_point_a()) / 2.0); 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 // CollisionPlane

View File

@ -87,16 +87,16 @@ ptr() const {
/** /**
* Constructs a new BulletCapsuleShape using the information from a * Constructs a new BulletCapsuleShape using the information from a
* CollisionTube from the builtin collision system. * CollisionCapsule from the builtin collision system.
*/ */
BulletCapsuleShape *BulletCapsuleShape:: BulletCapsuleShape *BulletCapsuleShape::
make_from_solid(const CollisionTube *solid) { make_from_solid(const CollisionCapsule *solid) {
PN_stdfloat radius = solid->get_radius(); 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(); 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); return new BulletCapsuleShape(radius, height, Z_up);
} }

View File

@ -20,7 +20,7 @@
#include "bullet_utils.h" #include "bullet_utils.h"
#include "bulletShape.h" #include "bulletShape.h"
#include "collisionTube.h" #include "collisionCapsule.h"
/** /**
* *
@ -35,7 +35,7 @@ PUBLISHED:
BulletCapsuleShape(const BulletCapsuleShape &copy); BulletCapsuleShape(const BulletCapsuleShape &copy);
INLINE ~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_radius() const;
INLINE PN_stdfloat get_half_height() const; INLINE PN_stdfloat get_half_height() const;

View File

@ -16,7 +16,7 @@
#include "collisionRay.h" #include "collisionRay.h"
#include "collisionSphere.h" #include "collisionSphere.h"
#include "collisionSegment.h" #include "collisionSegment.h"
#include "collisionTube.h" #include "collisionCapsule.h"
#include "collisionHandler.h" #include "collisionHandler.h"
#include "collisionEntry.h" #include "collisionEntry.h"
#include "config_collide.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:: PT(CollisionEntry) CollisionBox::
test_intersection_from_tube(const CollisionEntry &entry) const { test_intersection_from_capsule(const CollisionEntry &entry) const {
const CollisionTube *tube; const CollisionCapsule *capsule;
DCAST_INTO_R(tube, entry.get_from(), nullptr); DCAST_INTO_R(capsule, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat(); const LMatrix4 &wrt_mat = entry.get_wrt_mat();
LPoint3 from_a = tube->get_point_a() * wrt_mat; LPoint3 from_a = capsule->get_point_a() * wrt_mat;
LPoint3 from_b = tube->get_point_b() * wrt_mat; LPoint3 from_b = capsule->get_point_b() * wrt_mat;
LVector3 from_direction = from_b - from_a; 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); PN_stdfloat radius = csqrt(radius_sq);
LPoint3 box_min = get_min(); LPoint3 box_min = get_min();
@ -620,7 +620,7 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
LVector3 delta(0); LVector3 delta(0);
delta[edges[i].axis] = dimensions[edges[i].axis]; delta[edges[i].axis] = dimensions[edges[i].axis];
double u1, u2; 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(); PN_stdfloat dist_sq = ((from_a + from_direction * u1) - (vertex + delta * u2)).length_squared();
if (dist_sq < best_dist_sq) { if (dist_sq < best_dist_sq) {
best_dist_sq = 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_interior_point(point - interior_vec * radius);
new_entry->set_surface_point(surface_point); 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()); new_entry->set_surface_normal(get_effective_normal());
} else { } else {
new_entry->set_surface_normal(normal); new_entry->set_surface_normal(normal);

View File

@ -82,7 +82,7 @@ protected:
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_segment(const CollisionEntry &entry) const; test_intersection_from_segment(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_tube(const CollisionEntry &entry) const; test_intersection_from_capsule(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_box(const CollisionEntry &entry) const; test_intersection_from_box(const CollisionEntry &entry) const;

View File

@ -6,7 +6,7 @@
* license. You should have received a copy of this license along * license. You should have received a copy of this license along
* with this source code in a file named "LICENSE." * with this source code in a file named "LICENSE."
* *
* @file collisionTube.I * @file collisionCapsule.I
* @author drose * @author drose
* @date 2003-09-25 * @date 2003-09-25
*/ */
@ -14,8 +14,8 @@
/** /**
* *
*/ */
INLINE CollisionTube:: INLINE CollisionCapsule::
CollisionTube(const LPoint3 &a, const LPoint3 &b, PN_stdfloat radius) : CollisionCapsule(const LPoint3 &a, const LPoint3 &b, PN_stdfloat radius) :
_a(a), _b(b), _radius(radius) _a(a), _b(b), _radius(radius)
{ {
recalc_internals(); recalc_internals();
@ -25,8 +25,8 @@ CollisionTube(const LPoint3 &a, const LPoint3 &b, PN_stdfloat radius) :
/** /**
* *
*/ */
INLINE CollisionTube:: INLINE CollisionCapsule::
CollisionTube(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az, CollisionCapsule(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az,
PN_stdfloat bx, PN_stdfloat by, PN_stdfloat bz, PN_stdfloat bx, PN_stdfloat by, PN_stdfloat bz,
PN_stdfloat radius) : PN_stdfloat radius) :
_a(ax, ay, az), _b(bx, by, bz), _radius(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:: INLINE CollisionCapsule::
CollisionTube() { CollisionCapsule() {
} }
/** /**
* *
*/ */
INLINE CollisionTube:: INLINE CollisionCapsule::
CollisionTube(const CollisionTube &copy) : CollisionCapsule(const CollisionCapsule &copy) :
CollisionSolid(copy), CollisionSolid(copy),
_a(copy._a), _a(copy._a),
_b(copy._b), _b(copy._b),
@ -58,7 +58,7 @@ CollisionTube(const CollisionTube &copy) :
/** /**
* Flushes the PStatCollectors used during traversal. * Flushes the PStatCollectors used during traversal.
*/ */
INLINE void CollisionTube:: INLINE void CollisionCapsule::
flush_level() { flush_level() {
_volume_pcollector.flush_level(); _volume_pcollector.flush_level();
_test_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) { set_point_a(const LPoint3 &a) {
_a = a; _a = a;
recalc_internals(); 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(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
set_point_a(LPoint3(x, y, 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 { get_point_a() const {
return _a; return _a;
} }
@ -92,7 +92,7 @@ get_point_a() const {
/** /**
* *
*/ */
INLINE void CollisionTube:: INLINE void CollisionCapsule::
set_point_b(const LPoint3 &b) { set_point_b(const LPoint3 &b) {
_b = b; _b = b;
recalc_internals(); 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(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z) {
set_point_b(LPoint3(x, y, 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 { get_point_b() const {
return _b; return _b;
} }
@ -117,7 +117,7 @@ get_point_b() const {
/** /**
* *
*/ */
INLINE void CollisionTube:: INLINE void CollisionCapsule::
set_radius(PN_stdfloat radius) { set_radius(PN_stdfloat radius) {
nassertv(radius >= 0.0f); nassertv(radius >= 0.0f);
_radius = radius; _radius = radius;
@ -131,7 +131,7 @@ set_radius(PN_stdfloat radius) {
/** /**
* *
*/ */
INLINE PN_stdfloat CollisionTube:: INLINE PN_stdfloat CollisionCapsule::
get_radius() const { get_radius() const {
return _radius; return _radius;
} }

View File

@ -6,12 +6,12 @@
* license. You should have received a copy of this license along * license. You should have received a copy of this license along
* with this source code in a file named "LICENSE." * with this source code in a file named "LICENSE."
* *
* @file collisionTube.cxx * @file collisionCapsule.cxx
* @author drose * @author drose
* @date 2003-09-25 * @date 2003-09-25
*/ */
#include "collisionTube.h" #include "collisionCapsule.h"
#include "collisionSphere.h" #include "collisionSphere.h"
#include "collisionLine.h" #include "collisionLine.h"
#include "collisionRay.h" #include "collisionRay.h"
@ -35,30 +35,30 @@
#include "geomVertexWriter.h" #include "geomVertexWriter.h"
#include "boundingSphere.h" #include "boundingSphere.h"
PStatCollector CollisionTube::_volume_pcollector("Collision Volumes:CollisionTube"); PStatCollector CollisionCapsule::_volume_pcollector("Collision Volumes:CollisionCapsule");
PStatCollector CollisionTube::_test_pcollector("Collision Tests:CollisionTube"); PStatCollector CollisionCapsule::_test_pcollector("Collision Tests:CollisionCapsule");
TypeHandle CollisionTube::_type_handle; TypeHandle CollisionCapsule::_type_handle;
/** /**
* *
*/ */
CollisionSolid *CollisionTube:: CollisionSolid *CollisionCapsule::
make_copy() { make_copy() {
return new CollisionTube(*this); return new CollisionCapsule(*this);
} }
/** /**
* *
*/ */
PT(CollisionEntry) CollisionTube:: PT(CollisionEntry) CollisionCapsule::
test_intersection(const CollisionEntry &entry) const { 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. * Transforms the solid by the indicated matrix.
*/ */
void CollisionTube:: void CollisionCapsule::
xform(const LMatrix4 &mat) { xform(const LMatrix4 &mat) {
_a = _a * mat; _a = _a * mat;
_b = _b * mat; _b = _b * mat;
@ -77,7 +77,7 @@ xform(const LMatrix4 &mat) {
* collision purposes. The closest intersection point to this origin point is * collision purposes. The closest intersection point to this origin point is
* considered to be the most significant. * considered to be the most significant.
*/ */
LPoint3 CollisionTube:: LPoint3 CollisionCapsule::
get_collision_origin() const { get_collision_origin() const {
return get_point_a(); return get_point_a();
} }
@ -86,7 +86,7 @@ get_collision_origin() const {
* Returns a PStatCollector that is used to count the number of bounding * 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. * volume tests made against a solid of this type in a given frame.
*/ */
PStatCollector &CollisionTube:: PStatCollector &CollisionCapsule::
get_volume_pcollector() { get_volume_pcollector() {
return _volume_pcollector; return _volume_pcollector;
} }
@ -95,7 +95,7 @@ get_volume_pcollector() {
* Returns a PStatCollector that is used to count the number of intersection * Returns a PStatCollector that is used to count the number of intersection
* tests made against a solid of this type in a given frame. * tests made against a solid of this type in a given frame.
*/ */
PStatCollector &CollisionTube:: PStatCollector &CollisionCapsule::
get_test_pcollector() { get_test_pcollector() {
return _test_pcollector; return _test_pcollector;
} }
@ -103,15 +103,15 @@ get_test_pcollector() {
/** /**
* *
*/ */
void CollisionTube:: void CollisionCapsule::
output(std::ostream &out) const { 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 { compute_internal_bounds() const {
PT(BoundingVolume) bound = CollisionSolid::compute_internal_bounds(); 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 { test_intersection_from_sphere(const CollisionEntry &entry) const {
const CollisionSphere *sphere; const CollisionSphere *sphere;
DCAST_INTO_R(sphere, entry.get_from(), nullptr); 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; PN_stdfloat actual_t = 0.0f;
if (wrt_prev_space != wrt_space) { 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(); 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; LPoint3 into_intersection_point;
if (t2 > 1.0) { 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. // itself.
into_intersection_point = from_b; into_intersection_point = from_b;
} else { } 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. // beyond it. The first intersection point is at t2.
into_intersection_point = from_a + t2 * from_direction; 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 { test_intersection_from_line(const CollisionEntry &entry) const {
const CollisionLine *line; const CollisionLine *line;
DCAST_INTO_R(line, entry.get_from(), nullptr); 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 { test_intersection_from_ray(const CollisionEntry &entry) const {
const CollisionRay *ray; const CollisionRay *ray;
DCAST_INTO_R(ray, entry.get_from(), nullptr); DCAST_INTO_R(ray, entry.get_from(), nullptr);
@ -299,11 +299,11 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
LPoint3 into_intersection_point; LPoint3 into_intersection_point;
if (t1 < 0.0) { 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. // itself.
into_intersection_point = from_origin; into_intersection_point = from_origin;
} else { } 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; into_intersection_point = from_origin + t1 * from_direction;
} }
set_intersection_point(new_entry, into_intersection_point, 0.0); 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 { test_intersection_from_segment(const CollisionEntry &entry) const {
const CollisionSegment *segment; const CollisionSegment *segment;
DCAST_INTO_R(segment, entry.get_from(), nullptr); DCAST_INTO_R(segment, entry.get_from(), nullptr);
@ -362,11 +362,11 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
LPoint3 into_intersection_point; LPoint3 into_intersection_point;
if (t1 < 0.0) { 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. // itself.
into_intersection_point = from_a; into_intersection_point = from_a;
} else { } 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. // beyond it. The first intersection point is at t1.
into_intersection_point = from_a + t1 * from_direction; into_intersection_point = from_a + t1 * from_direction;
} }
@ -394,22 +394,22 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
/** /**
* *
*/ */
PT(CollisionEntry) CollisionTube:: PT(CollisionEntry) CollisionCapsule::
test_intersection_from_tube(const CollisionEntry &entry) const { test_intersection_from_capsule(const CollisionEntry &entry) const {
const CollisionTube *tube; const CollisionCapsule *capsule;
DCAST_INTO_R(tube, entry.get_from(), nullptr); DCAST_INTO_R(capsule, entry.get_from(), nullptr);
LPoint3 into_a = _a; LPoint3 into_a = _a;
LVector3 into_direction = _b - into_a; LVector3 into_direction = _b - into_a;
const LMatrix4 &wrt_mat = entry.get_wrt_mat(); const LMatrix4 &wrt_mat = entry.get_wrt_mat();
LPoint3 from_a = tube->get_point_a() * wrt_mat; LPoint3 from_a = capsule->get_point_a() * wrt_mat;
LPoint3 from_b = tube->get_point_b() * wrt_mat; LPoint3 from_b = capsule->get_point_b() * wrt_mat;
LVector3 from_direction = from_b - from_a; LVector3 from_direction = from_b - from_a;
LVector3 from_radius_v = 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 from_radius = length(from_radius_v);
// Determine the points on each segment with the smallest distance between. // 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 into_closest = into_a + into_direction * into_t;
LPoint3 from_closest = from_a + from_direction * from_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; LVector3 closest_vec = from_closest - into_closest;
PN_stdfloat distance = closest_vec.length(); PN_stdfloat distance = closest_vec.length();
if (distance > _radius + from_radius) { 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_surface_point(into_closest + surface_normal * _radius);
new_entry->set_interior_point(from_closest - surface_normal * from_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()); new_entry->set_surface_normal(get_effective_normal());
} else if (distance != 0) { } else if (distance != 0) {
new_entry->set_surface_normal(surface_normal); 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 { test_intersection_from_parabola(const CollisionEntry &entry) const {
const CollisionParabola *parabola; const CollisionParabola *parabola;
DCAST_INTO_R(parabola, entry.get_from(), nullptr); 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 * Fills the _viz_geom GeomNode up with Geoms suitable for rendering this
* solid. * solid.
*/ */
void CollisionTube:: void CollisionCapsule::
fill_viz_geom() { fill_viz_geom() {
if (collide_cat.is_debug()) { if (collide_cat.is_debug()) {
collide_cat.debug() collide_cat.debug()
<< "Recomputing viz for " << *this << "\n"; << "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 // 0, 0), and another at (0, length, 0). Then we'll rotate and translate it
// into place with the appropriate look_at matrix. // into place with the appropriate look_at matrix.
LVector3 direction = (_b - _a); LVector3 direction = (_b - _a);
@ -576,9 +576,9 @@ fill_viz_geom() {
/** /**
* Should be called internally to recompute the matrix and length when the * 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() { recalc_internals() {
LVector3 direction = (_b - _a); LVector3 direction = (_b - _a);
_length = direction.length(); _length = direction.length();
@ -595,7 +595,7 @@ recalc_internals() {
* Calculates a particular vertex on the surface of the first endcap * Calculates a particular vertex on the surface of the first endcap
* hemisphere, for use in generating the viz geometry. * 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) { 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 r = (PN_stdfloat)ri / (PN_stdfloat)num_rings;
PN_stdfloat s = (PN_stdfloat)si / (PN_stdfloat)num_slices; 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 * Calculates a particular vertex on the surface of the second endcap
* hemisphere, for use in generating the viz geometry. * 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, calc_sphere2_vertex(int ri, int si, int num_rings, int num_slices,
PN_stdfloat length) { PN_stdfloat length) {
PN_stdfloat r = (PN_stdfloat)ri / (PN_stdfloat)num_rings; 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 * Given line segments s1 and s2 defined by two points each, computes the
* point on each segment with the closest distance between them. * point on each segment with the closest distance between them.
*/ */
void CollisionTube:: void CollisionCapsule::
calc_closest_segment_points(double &t1, double &t2, calc_closest_segment_points(double &t1, double &t2,
const LPoint3 &from1, const LVector3 &delta1, const LPoint3 &from1, const LVector3 &delta1,
const LPoint3 &from2, const LVector3 &delta2) { 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 * 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 * 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 tube, it * 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 * 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. * from+t*delta that correspond to the two points of intersection.
*/ */
bool CollisionTube:: bool CollisionCapsule::
intersects_line(double &t1, double &t2, intersects_line(double &t1, double &t2,
const LPoint3 &from0, const LVector3 &delta0, const LPoint3 &from0, const LVector3 &delta0,
PN_stdfloat inflate_radius) const { 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. // with the y axis.
LPoint3 from = from0 * _inv_mat; LPoint3 from = from0 * _inv_mat;
LVector3 delta = delta0 * _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; t1 = t2 = 0.0;
return true; return true;
} }
@ -819,15 +819,15 @@ intersects_line(double &t1, double &t2,
PN_stdfloat t2_y = from[1] + t2 * delta[1]; PN_stdfloat t2_y = from[1] + t2 * delta[1];
if (t1_y < -radius && t2_y < -radius) { 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; return false;
} else if (t1_y > _length + radius && t2_y > _length + radius) { } 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; return false;
} }
if (t1_y < 0.0f) { 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. // against the first endcap.
double t1a, t2a; double t1a, t2a;
if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) { if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) {
@ -838,7 +838,7 @@ intersects_line(double &t1, double &t2,
t1 = t1a; t1 = t1a;
} else if (t1_y > _length) { } 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. // the second endcap.
double t1b, t2b; double t1b, t2b;
if (!sphere_intersects_line(t1b, t2b, _length, from, delta, radius)) { 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) { 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. // the first endcap.
double t1a, t2a; double t1a, t2a;
if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) { if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) {
@ -861,7 +861,7 @@ intersects_line(double &t1, double &t2,
t2 = t2a; t2 = t2a;
} else if (t2_y > _length) { } 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. // second endcap.
double t1b, t2b; double t1b, t2b;
if (!sphere_intersects_line(t1b, t2b, _length, from, delta, radius)) { 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 * whether it intersects one or the other endcaps. The y parameter specifies
* the center of the sphere (and hence the particular endcap). * 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, sphere_intersects_line(double &t1, double &t2, PN_stdfloat center_y,
const LPoint3 &from, const LVector3 &delta, const LPoint3 &from, const LVector3 &delta,
PN_stdfloat radius) { 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 * 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 * 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 * intersection, t is set to the parametric point of intersection, and true is
* returned; otherwise, false is returned. * returned; otherwise, false is returned.
*/ */
bool CollisionTube:: bool CollisionCapsule::
intersects_parabola(double &t, const LParabola &parabola, intersects_parabola(double &t, const LParabola &parabola,
double t1, double t2, double t1, double t2,
const LPoint3 &p1, const LPoint3 &p2) const { const LPoint3 &p1, const LPoint3 &p2) const {
@ -965,11 +965,11 @@ intersects_parabola(double &t, const LParabola &parabola,
} }
/** /**
* 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 * 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, calculate_surface_point_and_normal(const LPoint3 &surface_point,
double extra_radius, double extra_radius,
LPoint3 &result_point, 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 * point in the CollisionEntry, and also compute the relevant normal based on
* that point. * that point.
*/ */
void CollisionTube:: void CollisionCapsule::
set_intersection_point(CollisionEntry *new_entry, set_intersection_point(CollisionEntry *new_entry,
const LPoint3 &into_intersection_point, const LPoint3 &into_intersection_point,
double extra_radius) const { double extra_radius) const {
@ -1033,16 +1033,16 @@ set_intersection_point(CollisionEntry *new_entry,
new_entry->set_surface_normal(normal); new_entry->set_surface_normal(normal);
new_entry->set_surface_point(point); new_entry->set_surface_point(point);
// Also adjust the original point into the tube by the amount of // Also adjust the original point into the capsule by the amount of
// extra_radius, which should put it on the surface of the tube if our // extra_radius, which should put it on the surface of the capsule if our
// collision was tangential. // collision was tangential.
new_entry->set_interior_point(into_intersection_point - normal * extra_radius); 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() { register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 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 * Writes the contents of this object to the datagram for shipping out to a
* Bam file. * Bam file.
*/ */
void CollisionTube:: void CollisionCapsule::
write_datagram(BamWriter *manager, Datagram &dg) { write_datagram(BamWriter *manager, Datagram &dg) {
CollisionSolid::write_datagram(manager, dg); CollisionSolid::write_datagram(manager, dg);
_a.write_datagram(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 * 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 * type CollisionCapsule is encountered in the Bam file. It should create the
* CollisionTube and extract its information from the file. * CollisionCapsule and extract its information from the file.
*/ */
TypedWritable *CollisionTube:: TypedWritable *CollisionCapsule::
make_from_bam(const FactoryParams &params) { make_from_bam(const FactoryParams &params) {
CollisionTube *node = new CollisionTube(); CollisionCapsule *node = new CollisionCapsule();
DatagramIterator scan; DatagramIterator scan;
BamReader *manager; BamReader *manager;
@ -1078,9 +1078,9 @@ make_from_bam(const FactoryParams &params) {
/** /**
* This internal function is called by make_from_bam to read in all of the * 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) { fillin(DatagramIterator &scan, BamReader *manager) {
CollisionSolid::fillin(scan, manager); CollisionSolid::fillin(scan, manager);
_a.read_datagram(scan); _a.read_datagram(scan);

View File

@ -6,38 +6,39 @@
* license. You should have received a copy of this license along * license. You should have received a copy of this license along
* with this source code in a file named "LICENSE." * with this source code in a file named "LICENSE."
* *
* @file collisionTube.h * @file collisionCapsule.h
* @author drose * @author drose
* @date 2003-09-25 * @date 2003-09-25
*/ */
#ifndef COLLISIONTUBE_H #ifndef COLLISIONCAPSULE_H
#define COLLISIONTUBE_H #define COLLISIONCAPSULE_H
#include "pandabase.h" #include "pandabase.h"
#include "collisionSolid.h" #include "collisionSolid.h"
#include "parabola.h" #include "parabola.h"
/** /**
* This implements a solid roughly in cylindrical shape. It's not called a * This implements a solid consisting of a cylinder with hemispherical endcaps,
* CollisionCylinder because it's not a true cylinder; specifically, it has * also known as a capsule or a spherocylinder.
* rounded ends instead of flat ends. It looks more like a Contac pill. *
* This shape was previously erroneously called CollisionTube.
*/ */
class EXPCL_PANDA_COLLIDE CollisionTube : public CollisionSolid { class EXPCL_PANDA_COLLIDE CollisionCapsule : public CollisionSolid {
PUBLISHED: PUBLISHED:
INLINE explicit CollisionTube(const LPoint3 &a, const LPoint3 &db, INLINE explicit CollisionCapsule(const LPoint3 &a, const LPoint3 &db,
PN_stdfloat radius); PN_stdfloat radius);
INLINE explicit CollisionTube(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az, INLINE explicit CollisionCapsule(PN_stdfloat ax, PN_stdfloat ay, PN_stdfloat az,
PN_stdfloat bx, PN_stdfloat by, PN_stdfloat bz, PN_stdfloat bx, PN_stdfloat by, PN_stdfloat bz,
PN_stdfloat radius); PN_stdfloat radius);
virtual LPoint3 get_collision_origin() const; virtual LPoint3 get_collision_origin() const;
private: private:
INLINE CollisionTube(); INLINE CollisionCapsule();
public: public:
INLINE CollisionTube(const CollisionTube &copy); INLINE CollisionCapsule(const CollisionCapsule &copy);
virtual CollisionSolid *make_copy(); virtual CollisionSolid *make_copy();
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
@ -82,7 +83,7 @@ protected:
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_segment(const CollisionEntry &entry) const; test_intersection_from_segment(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_tube(const CollisionEntry &entry) const; test_intersection_from_capsule(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_parabola(const CollisionEntry &entry) const; test_intersection_from_parabola(const CollisionEntry &entry) const;
@ -141,7 +142,7 @@ public:
} }
static void init_type() { static void init_type() {
CollisionSolid::init_type(); CollisionSolid::init_type();
register_type(_type_handle, "CollisionTube", register_type(_type_handle, "CollisionCapsule",
CollisionSolid::get_class_type()); CollisionSolid::get_class_type());
} }
virtual TypeHandle get_type() const { virtual TypeHandle get_type() const {
@ -155,6 +156,13 @@ private:
friend class CollisionBox; friend class CollisionBox;
}; };
#include "collisionTube.I" BEGIN_PUBLISH
/**
* Alias for backward compatibility.
*/
typedef CollisionCapsule CollisionTube;
END_PUBLISH
#include "collisionCapsule.I"
#endif #endif

View File

@ -72,7 +72,7 @@ handle_entries() {
PosB = collider's current position PosB = collider's current position
M = movement vector (PosB - PosA) M = movement vector (PosB - PosA)
BV = bounding sphere that includes collider at PosA and PosB 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 VARIABLES
N = movement vector since most recent collision (or start of frame) N = movement vector since most recent collision (or start of frame)

View File

@ -18,7 +18,7 @@
#include "collisionLine.h" #include "collisionLine.h"
#include "collisionRay.h" #include "collisionRay.h"
#include "collisionSegment.h" #include "collisionSegment.h"
#include "collisionTube.h" #include "collisionCapsule.h"
#include "collisionParabola.h" #include "collisionParabola.h"
#include "config_collide.h" #include "config_collide.h"
#include "pointerToArray.h" #include "pointerToArray.h"
@ -298,16 +298,16 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
* *
*/ */
PT(CollisionEntry) CollisionPlane:: PT(CollisionEntry) CollisionPlane::
test_intersection_from_tube(const CollisionEntry &entry) const { test_intersection_from_capsule(const CollisionEntry &entry) const {
const CollisionTube *tube; const CollisionCapsule *capsule;
DCAST_INTO_R(tube, entry.get_from(), nullptr); DCAST_INTO_R(capsule, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat(); const LMatrix4 &wrt_mat = entry.get_wrt_mat();
LPoint3 from_a = tube->get_point_a() * wrt_mat; LPoint3 from_a = capsule->get_point_a() * wrt_mat;
LPoint3 from_b = tube->get_point_b() * wrt_mat; LPoint3 from_b = capsule->get_point_b() * wrt_mat;
LVector3 from_radius_v = 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 from_radius = length(from_radius_v);
PN_stdfloat dist_a = _plane.dist_to_plane(from_a); 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); 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); new_entry->set_surface_normal(normal);
PN_stdfloat t; 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); new_entry->set_surface_point(from_a - get_normal() * dist_a);
} else { } 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); new_entry->set_surface_point(from_a + t * from_direction);
} }
} else { } else {
// If it's completely parallel, pretend it's colliding in the center of // 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); new_entry->set_surface_point(from_a + 0.5f * from_direction - get_normal() * dist_a);
} }
if (IS_NEARLY_EQUAL(dist_a, dist_b)) { 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); new_entry->set_interior_point(from_a + 0.5f * from_direction - get_normal() * from_radius);
} else if (dist_a < dist_b) { } else if (dist_a < dist_b) {

View File

@ -72,7 +72,7 @@ protected:
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_segment(const CollisionEntry &entry) const; test_intersection_from_segment(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_tube(const CollisionEntry &entry) const; test_intersection_from_capsule(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_parabola(const CollisionEntry &entry) const; test_intersection_from_parabola(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)

View File

@ -17,7 +17,7 @@
#include "collisionLine.h" #include "collisionLine.h"
#include "collisionRay.h" #include "collisionRay.h"
#include "collisionSegment.h" #include "collisionSegment.h"
#include "collisionTube.h" #include "collisionCapsule.h"
#include "collisionParabola.h" #include "collisionParabola.h"
#include "collisionBox.h" #include "collisionBox.h"
#include "collisionEntry.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(). * 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:: PT(CollisionEntry) CollisionSolid::
test_intersection_from_tube(const CollisionEntry &) const { test_intersection_from_capsule(const CollisionEntry &) const {
report_undefined_intersection_test(CollisionTube::get_class_type(), report_undefined_intersection_test(CollisionCapsule::get_class_type(),
get_type()); get_type());
return nullptr; return nullptr;
} }

View File

@ -108,7 +108,7 @@ protected:
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_segment(const CollisionEntry &entry) const; test_intersection_from_segment(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_tube(const CollisionEntry &entry) const; test_intersection_from_capsule(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_parabola(const CollisionEntry &entry) const; test_intersection_from_parabola(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
@ -177,7 +177,7 @@ private:
friend class CollisionLine; friend class CollisionLine;
friend class CollisionRay; friend class CollisionRay;
friend class CollisionSegment; friend class CollisionSegment;
friend class CollisionTube; friend class CollisionCapsule;
friend class CollisionParabola; friend class CollisionParabola;
friend class CollisionHandlerFluidPusher; friend class CollisionHandlerFluidPusher;
friend class CollisionBox; friend class CollisionBox;

View File

@ -17,7 +17,7 @@
#include "collisionHandler.h" #include "collisionHandler.h"
#include "collisionEntry.h" #include "collisionEntry.h"
#include "collisionSegment.h" #include "collisionSegment.h"
#include "collisionTube.h" #include "collisionCapsule.h"
#include "collisionParabola.h" #include "collisionParabola.h"
#include "collisionBox.h" #include "collisionBox.h"
#include "config_collide.h" #include "config_collide.h"
@ -444,18 +444,18 @@ test_intersection_from_segment(const CollisionEntry &entry) const {
* *
*/ */
PT(CollisionEntry) CollisionSphere:: PT(CollisionEntry) CollisionSphere::
test_intersection_from_tube(const CollisionEntry &entry) const { test_intersection_from_capsule(const CollisionEntry &entry) const {
const CollisionTube *tube; const CollisionCapsule *capsule;
DCAST_INTO_R(tube, entry.get_from(), nullptr); DCAST_INTO_R(capsule, entry.get_from(), nullptr);
const LMatrix4 &wrt_mat = entry.get_wrt_mat(); const LMatrix4 &wrt_mat = entry.get_wrt_mat();
LPoint3 from_a = tube->get_point_a() * wrt_mat; LPoint3 from_a = capsule->get_point_a() * wrt_mat;
LPoint3 from_b = tube->get_point_b() * wrt_mat; LPoint3 from_b = capsule->get_point_b() * wrt_mat;
LVector3 from_direction = from_b - from_a; LVector3 from_direction = from_b - from_a;
LVector3 from_radius_v = 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 from_radius = length(from_radius_v);
double t1, t2; double t1, t2;
@ -465,8 +465,8 @@ test_intersection_from_tube(const CollisionEntry &entry) const {
} }
if (t2 < 0.0 || t1 > 1.0) { if (t2 < 0.0 || t1 > 1.0) {
// Both intersection points are before the start of the tube or after // Both intersection points are before the start of the capsule or after
// the end of the tube. // the end of the capsule.
return nullptr; 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_surface_point(get_center() + normal * get_radius());
new_entry->set_interior_point(inner_point - normal * from_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()); new_entry->set_surface_normal(get_effective_normal());
} else { } else {
new_entry->set_surface_normal(normal); new_entry->set_surface_normal(normal);

View File

@ -72,7 +72,7 @@ protected:
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_segment(const CollisionEntry &entry) const; test_intersection_from_segment(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_tube(const CollisionEntry &entry) const; test_intersection_from_capsule(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)
test_intersection_from_parabola(const CollisionEntry &entry) const; test_intersection_from_parabola(const CollisionEntry &entry) const;
virtual PT(CollisionEntry) virtual PT(CollisionEntry)

View File

@ -20,7 +20,7 @@
#include "collisionVisualizer.h" #include "collisionVisualizer.h"
#include "collisionSphere.h" #include "collisionSphere.h"
#include "collisionBox.h" #include "collisionBox.h"
#include "collisionTube.h" #include "collisionCapsule.h"
#include "collisionPolygon.h" #include "collisionPolygon.h"
#include "collisionPlane.h" #include "collisionPlane.h"
#include "config_collide.h" #include "config_collide.h"
@ -345,7 +345,7 @@ traverse(const NodePath &root) {
_geom_volume_pcollector.flush_level(); _geom_volume_pcollector.flush_level();
CollisionSphere::flush_level(); CollisionSphere::flush_level();
CollisionTube::flush_level(); CollisionCapsule::flush_level();
CollisionPolygon::flush_level(); CollisionPolygon::flush_level();
CollisionPlane::flush_level(); CollisionPlane::flush_level();
CollisionBox::flush_level(); CollisionBox::flush_level();

View File

@ -13,6 +13,7 @@
#include "config_collide.h" #include "config_collide.h"
#include "collisionBox.h" #include "collisionBox.h"
#include "collisionCapsule.h"
#include "collisionEntry.h" #include "collisionEntry.h"
#include "collisionHandler.h" #include "collisionHandler.h"
#include "collisionHandlerEvent.h" #include "collisionHandlerEvent.h"
@ -38,7 +39,6 @@
#include "collisionSolid.h" #include "collisionSolid.h"
#include "collisionSphere.h" #include "collisionSphere.h"
#include "collisionTraverser.h" #include "collisionTraverser.h"
#include "collisionTube.h"
#include "collisionVisualizer.h" #include "collisionVisualizer.h"
#include "dconfig.h" #include "dconfig.h"
@ -126,6 +126,7 @@ init_libcollide() {
initialized = true; initialized = true;
CollisionBox::init_type(); CollisionBox::init_type();
CollisionCapsule::init_type();
CollisionEntry::init_type(); CollisionEntry::init_type();
CollisionHandler::init_type(); CollisionHandler::init_type();
CollisionHandlerEvent::init_type(); CollisionHandlerEvent::init_type();
@ -150,14 +151,18 @@ init_libcollide() {
CollisionSolid::init_type(); CollisionSolid::init_type();
CollisionSphere::init_type(); CollisionSphere::init_type();
CollisionTraverser::init_type(); CollisionTraverser::init_type();
CollisionTube::init_type();
#ifdef DO_COLLISION_RECORDING #ifdef DO_COLLISION_RECORDING
CollisionRecorder::init_type(); CollisionRecorder::init_type();
CollisionVisualizer::init_type(); CollisionVisualizer::init_type();
#endif #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(); CollisionBox::register_with_read_factory();
CollisionCapsule::register_with_read_factory();
CollisionInvSphere::register_with_read_factory(); CollisionInvSphere::register_with_read_factory();
CollisionLine::register_with_read_factory(); CollisionLine::register_with_read_factory();
CollisionNode::register_with_read_factory(); CollisionNode::register_with_read_factory();
@ -168,5 +173,4 @@ init_libcollide() {
CollisionRay::register_with_read_factory(); CollisionRay::register_with_read_factory();
CollisionSegment::register_with_read_factory(); CollisionSegment::register_with_read_factory();
CollisionSphere::register_with_read_factory(); CollisionSphere::register_with_read_factory();
CollisionTube::register_with_read_factory();
} }

View File

@ -1,5 +1,6 @@
#include "config_collide.cxx" #include "config_collide.cxx"
#include "collisionBox.cxx" #include "collisionBox.cxx"
#include "collisionCapsule.cxx"
#include "collisionEntry.cxx" #include "collisionEntry.cxx"
#include "collisionGeom.cxx" #include "collisionGeom.cxx"
#include "collisionHandler.cxx" #include "collisionHandler.cxx"
@ -12,5 +13,3 @@
#include "collisionHandlerFluidPusher.cxx" #include "collisionHandlerFluidPusher.cxx"
#include "collisionHandlerQueue.cxx" #include "collisionHandlerQueue.cxx"
#include "collisionInvSphere.cxx" #include "collisionInvSphere.cxx"
#include "collisionLevelStateBase.cxx"
#include "collisionLevelState.cxx"

View File

@ -1,3 +1,5 @@
#include "collisionLevelStateBase.cxx"
#include "collisionLevelState.cxx"
#include "collisionLine.cxx" #include "collisionLine.cxx"
#include "collisionNode.cxx" #include "collisionNode.cxx"
#include "collisionParabola.cxx" #include "collisionParabola.cxx"
@ -10,5 +12,4 @@
#include "collisionSolid.cxx" #include "collisionSolid.cxx"
#include "collisionSphere.cxx" #include "collisionSphere.cxx"
#include "collisionTraverser.cxx" #include "collisionTraverser.cxx"
#include "collisionTube.cxx"
#include "collisionVisualizer.cxx" #include "collisionVisualizer.cxx"

View File

@ -110,8 +110,8 @@ PStatCollector GraphicsEngine::_volume_sphere_pcollector("Collision Volumes:Coll
PStatCollector GraphicsEngine::_test_sphere_pcollector("Collision Tests:CollisionSphere"); PStatCollector GraphicsEngine::_test_sphere_pcollector("Collision Tests:CollisionSphere");
PStatCollector GraphicsEngine::_volume_box_pcollector("Collision Volumes:CollisionBox"); PStatCollector GraphicsEngine::_volume_box_pcollector("Collision Volumes:CollisionBox");
PStatCollector GraphicsEngine::_test_box_pcollector("Collision Tests:CollisionBox"); PStatCollector GraphicsEngine::_test_box_pcollector("Collision Tests:CollisionBox");
PStatCollector GraphicsEngine::_volume_tube_pcollector("Collision Volumes:CollisionTube"); PStatCollector GraphicsEngine::_volume_capsule_pcollector("Collision Volumes:CollisionCapsule");
PStatCollector GraphicsEngine::_test_tube_pcollector("Collision Tests:CollisionTube"); PStatCollector GraphicsEngine::_test_capsule_pcollector("Collision Tests:CollisionCapsule");
PStatCollector GraphicsEngine::_volume_inv_sphere_pcollector("Collision Volumes:CollisionInvSphere"); PStatCollector GraphicsEngine::_volume_inv_sphere_pcollector("Collision Volumes:CollisionInvSphere");
PStatCollector GraphicsEngine::_test_inv_sphere_pcollector("Collision Tests:CollisionInvSphere"); PStatCollector GraphicsEngine::_test_inv_sphere_pcollector("Collision Tests:CollisionInvSphere");
PStatCollector GraphicsEngine::_volume_geom_pcollector("Collision Volumes:CollisionGeom"); PStatCollector GraphicsEngine::_volume_geom_pcollector("Collision Volumes:CollisionGeom");
@ -875,8 +875,8 @@ render_frame() {
_test_sphere_pcollector.clear_level(); _test_sphere_pcollector.clear_level();
_volume_box_pcollector.clear_level(); _volume_box_pcollector.clear_level();
_test_box_pcollector.clear_level(); _test_box_pcollector.clear_level();
_volume_tube_pcollector.clear_level(); _volume_capsule_pcollector.clear_level();
_test_tube_pcollector.clear_level(); _test_capsule_pcollector.clear_level();
_volume_inv_sphere_pcollector.clear_level(); _volume_inv_sphere_pcollector.clear_level();
_test_inv_sphere_pcollector.clear_level(); _test_inv_sphere_pcollector.clear_level();
_volume_geom_pcollector.clear_level(); _volume_geom_pcollector.clear_level();

View File

@ -401,8 +401,8 @@ private:
static PStatCollector _test_sphere_pcollector; static PStatCollector _test_sphere_pcollector;
static PStatCollector _volume_box_pcollector; static PStatCollector _volume_box_pcollector;
static PStatCollector _test_box_pcollector; static PStatCollector _test_box_pcollector;
static PStatCollector _volume_tube_pcollector; static PStatCollector _volume_capsule_pcollector;
static PStatCollector _test_tube_pcollector; static PStatCollector _test_capsule_pcollector;
static PStatCollector _volume_inv_sphere_pcollector; static PStatCollector _volume_inv_sphere_pcollector;
static PStatCollector _test_inv_sphere_pcollector; static PStatCollector _test_inv_sphere_pcollector;
static PStatCollector _volume_geom_pcollector; static PStatCollector _volume_geom_pcollector;

View File

@ -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 trigger: for things (usually not barriers or floors) that should trigger an
event when avatars intersect with them event when avatars intersect with them
sphere: for things that should have a collision sphere around 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 NOTES

View File

@ -897,7 +897,8 @@ string_cs_type(const string &strval) {
} else if (cmp_nocase_uh(strval, "inv-sphere") == 0 || } else if (cmp_nocase_uh(strval, "inv-sphere") == 0 ||
cmp_nocase_uh(strval, "invsphere") == 0) { cmp_nocase_uh(strval, "invsphere") == 0) {
return CST_inv_sphere; 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; return CST_tube;
} else if (cmp_nocase_uh(strval, "floor-mesh") == 0 || } else if (cmp_nocase_uh(strval, "floor-mesh") == 0 ||
cmp_nocase_uh(strval, "floormesh") == 0) { cmp_nocase_uh(strval, "floormesh") == 0) {

View File

@ -74,7 +74,7 @@
#include "collisionNode.h" #include "collisionNode.h"
#include "collisionSphere.h" #include "collisionSphere.h"
#include "collisionInvSphere.h" #include "collisionInvSphere.h"
#include "collisionTube.h" #include "collisionCapsule.h"
#include "collisionPlane.h" #include "collisionPlane.h"
#include "collisionPolygon.h" #include "collisionPolygon.h"
#include "collisionFloorMesh.h" #include "collisionFloorMesh.h"
@ -2865,7 +2865,7 @@ make_collision_solids(EggGroup *start_group, EggGroup *egg_group,
break; break;
case EggGroup::CST_tube: 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; break;
case EggGroup::CST_floor_mesh: 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. * with this group.
*/ */
void EggLoader:: void EggLoader::
make_collision_tube(EggGroup *egg_group, CollisionNode *cnode, make_collision_capsule(EggGroup *egg_group, CollisionNode *cnode,
EggGroup::CollideFlags flags) { EggGroup::CollideFlags flags) {
EggGroup *geom_group = find_collision_geometry(egg_group, flags); EggGroup *geom_group = find_collision_geometry(egg_group, flags);
if (geom_group != nullptr) { if (geom_group != nullptr) {
// Collect all of the vertices. // 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 // 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 // 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 // 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 // having point_a on the origin). It makes it easier to determine the
// length and radius of the cylinder. // 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_a = center - half;
LPoint3d point_b = center + half; LPoint3d point_b = center + half;
CollisionTube *cstube = CollisionCapsule *cscapsule =
new CollisionTube(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b), new CollisionCapsule(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b),
radius); radius);
apply_collision_flags(cstube, flags); apply_collision_flags(cscapsule, flags);
cnode->add_solid(cstube); cnode->add_solid(cscapsule);
} }
} }
} }

View File

@ -180,8 +180,8 @@ private:
EggGroup::CollideFlags flags); EggGroup::CollideFlags flags);
void make_collision_inv_sphere(EggGroup *egg_group, CollisionNode *cnode, void make_collision_inv_sphere(EggGroup *egg_group, CollisionNode *cnode,
EggGroup::CollideFlags flags); EggGroup::CollideFlags flags);
void make_collision_tube(EggGroup *egg_group, CollisionNode *cnode, void make_collision_capsule(EggGroup *egg_group, CollisionNode *cnode,
EggGroup::CollideFlags flags); EggGroup::CollideFlags flags);
void make_collision_floor_mesh(EggGroup *egg_group, CollisionNode *cnode, void make_collision_floor_mesh(EggGroup *egg_group, CollisionNode *cnode,
EggGroup::CollideFlags flags); EggGroup::CollideFlags flags);
void apply_collision_flags(CollisionSolid *solid, void apply_collision_flags(CollisionSolid *solid,

View File

@ -39,7 +39,7 @@
#include "collisionSphere.h" #include "collisionSphere.h"
#include "collisionBox.h" #include "collisionBox.h"
#include "collisionInvSphere.h" #include "collisionInvSphere.h"
#include "collisionTube.h" #include "collisionCapsule.h"
#include "textureStage.h" #include "textureStage.h"
#include "geomNode.h" #include "geomNode.h"
#include "geom.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(ev0));
egg_poly->add_vertex(cvpool->create_unique_vertex(ev1)); egg_poly->add_vertex(cvpool->create_unique_vertex(ev1));
} else if (child->is_of_type(CollisionTube::get_class_type())) { } else if (child->is_of_type(CollisionCapsule::get_class_type())) {
CPT(CollisionTube) tube = DCAST(CollisionTube, child); CPT(CollisionCapsule) capsule = DCAST(CollisionCapsule, child);
LPoint3 point_a = tube->get_point_a(); LPoint3 point_a = capsule->get_point_a();
LPoint3 point_b = tube->get_point_b(); LPoint3 point_b = capsule->get_point_b();
LPoint3 centroid = (point_a + point_b) * 0.5f; 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 axis = point_b - point_a;
LVector3 sideways; LVector3 sideways;
if (std::fabs(axis[2]) > std::fabs(axis[1])) { 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 = axis.cross(LVector3(0, 0, 1));
} }
sideways.normalize(); sideways.normalize();
sideways *= tube->get_radius(); sideways *= capsule->get_radius();
LVector3 extend = axis.normalized() * tube->get_radius(); LVector3 extend = axis.normalized() * capsule->get_radius();
EggGroup *egg_tube; EggGroup *egg_capsule;
if (num_solids == 1) { if (num_solids == 1) {
egg_tube = egg_group; egg_capsule = egg_group;
} else { } else {
egg_tube = new EggGroup; egg_capsule = new EggGroup;
egg_group->add_child(egg_tube); egg_group->add_child(egg_capsule);
} }
egg_tube->set_cs_type(EggGroup::CST_tube); egg_capsule->set_cs_type(EggGroup::CST_tube);
egg_tube->set_collide_flags(flags); egg_capsule->set_collide_flags(flags);
// Add two points for the endcaps, and then two points around the // Add two points for the endcaps, and then two points around the
// centroid to indicate the radius. // 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)); ev3.set_pos(LCAST(double, (centroid - sideways) * net_mat));
EggPolygon *egg_poly = new EggPolygon; 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(ev0));
egg_poly->add_vertex(cvpool->create_unique_vertex(ev1)); egg_poly->add_vertex(cvpool->create_unique_vertex(ev1));

View File

@ -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. // 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_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 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 15 on 2008-04-09 to add TextureAttrib::_implicit_sort.
// Bumped to minor version 16 on 2008-05-13 to add Texture::_quality_level. // 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 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 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 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 #endif

View File

@ -20,9 +20,28 @@
#include "bamWriter.h" #include "bamWriter.h"
#include "bamReader.h" #include "bamReader.h"
#include "lightMutexHolder.h" #include "lightMutexHolder.h"
#include "simpleHashMap.h"
#include <algorithm> #include <algorithm>
// 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<TypeHandle, std::set<ObsoleteName> > obsolete_type_names;
/** /**
* *
*/ */
@ -504,7 +523,14 @@ write_handle(Datagram &packet, TypeHandle type) {
if (inserted) { if (inserted) {
// This is the first time this TypeHandle has been written, so also // This is the first time this TypeHandle has been written, so also
// write out its definition. // 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 // 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. // 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 * This is called by the TypedWritable destructor. It should remove the

View File

@ -111,6 +111,10 @@ public:
bool register_pta(Datagram &packet, const void *ptr); bool register_pta(Datagram &packet, const void *ptr);
void write_handle(Datagram &packet, TypeHandle type); 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: private:
void object_destructs(TypedWritable *object); void object_destructs(TypedWritable *object);

View File

@ -29,7 +29,7 @@ EggMakeTube() {
set_program_description set_program_description
("egg-make-tube generates an egg file representing a \"tube\" model, " ("egg-make-tube generates an egg file representing a \"tube\" model, "
"a cylinder capped on both ends by hemispheres. This is similar " "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 " "This program can also generate spheres if you omit -b; in this "
"case, you are generating a degenerate tube of length 0."); "case, you are generating a degenerate tube of length 0.");

View File

@ -24,7 +24,7 @@ class EggVertex;
/** /**
* A program to generate an egg file representing a tube model, similar in * 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 { class EggMakeTube : public EggMakeSomething {
public: public:

View File

@ -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)