diff --git a/panda/src/collide/collisionBox.I b/panda/src/collide/collisionBox.I index 3036fc2e27..c99850f1c8 100644 --- a/panda/src/collide/collisionBox.I +++ b/panda/src/collide/collisionBox.I @@ -130,6 +130,16 @@ get_center() const { return _center; } +//////////////////////////////////////////////////////////////////// +// Function: CollisionBox::get_dimensions +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE LVector3 CollisionBox:: +get_dimensions() const { + return _max - _min; +} + //////////////////////////////////////////////////////////////////// // Function: CollisionBox::get_radius // Access: Published diff --git a/panda/src/collide/collisionBox.h b/panda/src/collide/collisionBox.h index 2afe521d1e..1d875b9876 100644 --- a/panda/src/collide/collisionBox.h +++ b/panda/src/collide/collisionBox.h @@ -68,6 +68,7 @@ PUBLISHED: INLINE void set_center(const LPoint3 ¢er); INLINE void set_center(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z); INLINE const LPoint3 &get_center() const; + INLINE LVector3 get_dimensions() const; INLINE PN_stdfloat get_radius() const; protected: diff --git a/panda/src/collide/collisionPlane.cxx b/panda/src/collide/collisionPlane.cxx index 5d02de8670..6721c7e1bc 100644 --- a/panda/src/collide/collisionPlane.cxx +++ b/panda/src/collide/collisionPlane.cxx @@ -390,6 +390,51 @@ test_intersection_from_parabola(const CollisionEntry &entry) const { return new_entry; } +//////////////////////////////////////////////////////////////////// +// Function: CollisionPlane::test_intersection_from_box +// Access: Public, Virtual +// Description: This is part of the double-dispatch implementation of +// test_intersection(). It is called when the "from" +// object is a box. +//////////////////////////////////////////////////////////////////// +PT(CollisionEntry) CollisionPlane:: +test_intersection_from_box(const CollisionEntry &entry) const { + const CollisionBox *box; + DCAST_INTO_R(box, entry.get_from(), 0); + + const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + + LPoint3 from_center = box->get_center() * wrt_mat; + LVector3 from_extents = box->get_dimensions() * wrt_mat * 0.5; + PN_stdfloat dist = _plane.dist_to_plane(from_center); + + LVecBase3 box_x = entry.get_wrt_mat().get_row3(0); + LVecBase3 box_y = entry.get_wrt_mat().get_row3(1); + LVecBase3 box_z = entry.get_wrt_mat().get_row3(2); + + if (abs(dist) > + abs(box_x.dot(_plane.get_normal()) * from_extents[0]) + + abs(box_y.dot(_plane.get_normal()) * from_extents[1]) + + abs(box_z.dot(_plane.get_normal()) * from_extents[2])) { + // No collision. + return NULL; + } + + if (collide_cat.is_debug()) { + collide_cat.debug() + << "intersection detected from " << entry.get_from_node_path() + << " into " << entry.get_into_node_path() << "\n"; + } + PT(CollisionEntry) new_entry = new CollisionEntry(entry); + + LVector3 normal = (has_effective_normal() && box->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); + + return new_entry; +} + //////////////////////////////////////////////////////////////////// // Function: CollisionPlane::fill_viz_geom // Access: Protected, Virtual diff --git a/panda/src/collide/collisionPlane.h b/panda/src/collide/collisionPlane.h index c24f7b7b6b..ccdc6de91f 100644 --- a/panda/src/collide/collisionPlane.h +++ b/panda/src/collide/collisionPlane.h @@ -71,6 +71,8 @@ protected: test_intersection_from_segment(const CollisionEntry &entry) const; virtual PT(CollisionEntry) test_intersection_from_parabola(const CollisionEntry &entry) const; + virtual PT(CollisionEntry) + test_intersection_from_box(const CollisionEntry &entry) const; virtual void fill_viz_geom();