From 77516513abfb5bc5e822933b70de994fbf4f6b37 Mon Sep 17 00:00:00 2001 From: David Rose Date: Sun, 14 Dec 2003 17:30:38 +0000 Subject: [PATCH] add CollisionSolid::respect_effective_normal --- panda/src/collide/collisionPlane.cxx | 9 ++++++-- panda/src/collide/collisionPolygon.cxx | 10 ++++++--- panda/src/collide/collisionSolid.I | 31 ++++++++++++++++++++++++++ panda/src/collide/collisionSolid.h | 10 ++++++--- panda/src/collide/collisionSphere.cxx | 4 +++- panda/src/collide/collisionTube.cxx | 6 ++++- 6 files changed, 60 insertions(+), 10 deletions(-) diff --git a/panda/src/collide/collisionPlane.cxx b/panda/src/collide/collisionPlane.cxx index 86c02916d7..6792687ad4 100644 --- a/panda/src/collide/collisionPlane.cxx +++ b/panda/src/collide/collisionPlane.cxx @@ -129,7 +129,9 @@ test_intersection_from_sphere(const CollisionEntry &entry) const { LVector3f from_normal = get_normal() * entry.get_inv_wrt_mat(); - new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : get_normal()); + LVector3f normal = (has_effective_normal() && sphere->get_respect_effective_normal()) ? get_effective_normal() : get_normal(); + + new_entry->set_surface_normal(normal); new_entry->set_surface_point(from_center - get_normal() * dist); new_entry->set_interior_point(from_center - get_normal() * from_radius); @@ -170,7 +172,10 @@ test_intersection_from_ray(const CollisionEntry &entry) const { PT(CollisionEntry) new_entry = new CollisionEntry(entry); LPoint3f into_intersection_point = from_origin + t * from_direction; - new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : get_normal()); + + LVector3f normal = (has_effective_normal() && ray->get_respect_effective_normal()) ? get_effective_normal() : get_normal(); + + new_entry->set_surface_normal(normal); new_entry->set_surface_point(into_intersection_point); return new_entry; diff --git a/panda/src/collide/collisionPolygon.cxx b/panda/src/collide/collisionPolygon.cxx index 25cc440e68..598947a7a3 100644 --- a/panda/src/collide/collisionPolygon.cxx +++ b/panda/src/collide/collisionPolygon.cxx @@ -451,7 +451,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const { float from_radius_2 = from_radius_v.length_squared(); float from_radius = csqrt(from_radius_2); - LVector3f normal = has_effective_normal() ? get_effective_normal() : get_normal(); + LVector3f normal = (has_effective_normal() && sphere->get_respect_effective_normal()) ? get_effective_normal() : get_normal(); #ifndef NDEBUG if (!IS_THRESHOLD_EQUAL(normal.length_squared(), 1.0f, 0.001), NULL) { collide_cat.info() @@ -613,7 +613,9 @@ test_intersection_from_ray(const CollisionEntry &entry) const { } PT(CollisionEntry) new_entry = new CollisionEntry(entry); - new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : get_normal()); + LVector3f normal = (has_effective_normal() && ray->get_respect_effective_normal()) ? get_effective_normal() : get_normal(); + + new_entry->set_surface_normal(normal); new_entry->set_surface_point(plane_point); return new_entry; @@ -682,7 +684,9 @@ test_intersection_from_segment(const CollisionEntry &entry) const { } PT(CollisionEntry) new_entry = new CollisionEntry(entry); - new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : get_normal()); + LVector3f normal = (has_effective_normal() && segment->get_respect_effective_normal()) ? get_effective_normal() : get_normal(); + + new_entry->set_surface_normal(normal); new_entry->set_surface_point(plane_point); return new_entry; diff --git a/panda/src/collide/collisionSolid.I b/panda/src/collide/collisionSolid.I index 23ae96e9dc..be026a1c7d 100644 --- a/panda/src/collide/collisionSolid.I +++ b/panda/src/collide/collisionSolid.I @@ -104,6 +104,37 @@ get_effective_normal() const { return _effective_normal; } +//////////////////////////////////////////////////////////////////// +// Function: CollisionSolid::set_respect_effective_normal +// Access: Published +// Description: This is only meaningful for CollisionSolids that will +// be added to a traverser as colliders. It is normally +// true, but if set false, it means that this particular +// solid does not care about the "effective" normal of +// other solids it meets, but rather always uses the +// true normal. +//////////////////////////////////////////////////////////////////// +INLINE void CollisionSolid:: +set_respect_effective_normal(bool respect_effective_normal) { + // For historical reasons, the bit we store is the opposite of the + // bool flag we present. + if (respect_effective_normal) { + _flags &= ~F_ignore_effective_normal; + } else { + _flags |= F_ignore_effective_normal; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionSolid::get_respect_effective_normal +// Access: Published +// Description: See set_respect_effective_normal(). +//////////////////////////////////////////////////////////////////// +INLINE bool CollisionSolid:: +get_respect_effective_normal() const { + return (_flags & F_ignore_effective_normal) == 0; +} + //////////////////////////////////////////////////////////////////// // Function: CollisionSolid::mark_viz_stale // Access: Protected diff --git a/panda/src/collide/collisionSolid.h b/panda/src/collide/collisionSolid.h index e56ee348a0..a8ea1d9f98 100644 --- a/panda/src/collide/collisionSolid.h +++ b/panda/src/collide/collisionSolid.h @@ -68,6 +68,9 @@ PUBLISHED: INLINE bool has_effective_normal() const; INLINE const LVector3f &get_effective_normal() const; + INLINE void set_respect_effective_normal(bool respect_effective_normal); + INLINE bool get_respect_effective_normal() const; + public: virtual PT(CollisionEntry) test_intersection(const CollisionEntry &entry) const; @@ -107,9 +110,10 @@ private: // Be careful reordering these bits, since they are written to a bam // file. enum Flags { - F_tangible = 0x01, - F_effective_normal = 0x02, - F_viz_geom_stale = 0x04, + F_tangible = 0x01, + F_effective_normal = 0x02, + F_viz_geom_stale = 0x04, + F_ignore_effective_normal = 0x08, }; int _flags; diff --git a/panda/src/collide/collisionSphere.cxx b/panda/src/collide/collisionSphere.cxx index b5e5987be4..252610c623 100644 --- a/panda/src/collide/collisionSphere.cxx +++ b/panda/src/collide/collisionSphere.cxx @@ -155,7 +155,9 @@ test_intersection_from_sphere(const CollisionEntry &entry) const { surface_normal = vec / vec_length; } - new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : surface_normal); + LVector3f normal = (has_effective_normal() && sphere->get_respect_effective_normal()) ? get_effective_normal() : surface_normal; + + new_entry->set_surface_normal(normal); new_entry->set_surface_point(into_center + surface_normal * into_radius); new_entry->set_interior_point(from_center - surface_normal * from_radius); diff --git a/panda/src/collide/collisionTube.cxx b/panda/src/collide/collisionTube.cxx index 845f742983..c81938ba1c 100644 --- a/panda/src/collide/collisionTube.cxx +++ b/panda/src/collide/collisionTube.cxx @@ -694,7 +694,11 @@ set_intersection_point(CollisionEntry *new_entry, // our collision was tangential. LPoint3f orig_point = into_intersection_point - normal * extra_radius; - new_entry->set_surface_normal(has_effective_normal() ? get_effective_normal() : normal); + if (has_effective_normal() && new_entry->get_from()->get_respect_effective_normal()) { + normal = get_effective_normal(); + } + + new_entry->set_surface_normal(normal); new_entry->set_surface_point(point); new_entry->set_interior_point(orig_point); }