Add box-into-plane collision test
This commit is contained in:
parent
c644e7ae49
commit
f7b61d4fa4
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue