mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 09:23:03 -04:00
add CollisionBox::test_intersection_from_segment() from forum user teedee
This commit is contained in:
parent
0a6aeea792
commit
5a635059b6
@ -531,6 +531,91 @@ test_intersection_from_ray(const CollisionEntry &entry) const {
|
||||
return new_entry;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::test_intersection_from_segment
|
||||
// Access: Public, Virtual
|
||||
// Description: Double dispatch point for segment as a FROM object
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(CollisionEntry) CollisionBox::
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const {
|
||||
const CollisionSegment *seg;
|
||||
DCAST_INTO_R(seg, entry.get_from(), 0);
|
||||
const LMatrix4f &wrt_mat = entry.get_wrt_mat();
|
||||
|
||||
LPoint3f from_origin = seg->get_point_a() * wrt_mat;
|
||||
LPoint3f from_extent = seg->get_point_b() * wrt_mat;
|
||||
LVector3f from_direction = from_extent - from_origin;
|
||||
|
||||
int i, j;
|
||||
float t, near_t;
|
||||
bool intersect;
|
||||
Planef plane;
|
||||
Planef near_plane;
|
||||
|
||||
//Returns the details about the first plane of the box that the
|
||||
//segment intersects.
|
||||
for(i = 0, intersect = false, t = 0, j = 0; i < 6 && j < 2; i++) {
|
||||
plane = get_plane(i);
|
||||
|
||||
if (!plane.intersects_line(t, from_origin, from_direction)) {
|
||||
// No intersection. The segment is parallel to the plane.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t < 0.0f || t > 1.0f) {
|
||||
// The intersection point is before the start of the segment,
|
||||
// or after the end of the segment, so the segment is either
|
||||
// entirely in front of or behind the plane.
|
||||
continue;
|
||||
}
|
||||
LPoint3f plane_point = from_origin + t * from_direction;
|
||||
LPoint2f p = to_2d(plane_point, i);
|
||||
|
||||
if (!point_is_inside(p, _points[i])){
|
||||
continue;
|
||||
}
|
||||
intersect = true;
|
||||
if(j) {
|
||||
if(t < near_t) {
|
||||
near_plane = plane;
|
||||
near_t = t;
|
||||
}
|
||||
}
|
||||
else {
|
||||
near_plane = plane;
|
||||
near_t = t;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
|
||||
|
||||
if(!intersect) {
|
||||
//No intersection with ANY of the box's planes has been detected
|
||||
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);
|
||||
|
||||
LPoint3f into_intersection_point = from_origin + near_t * from_direction;
|
||||
|
||||
LVector3f normal =
|
||||
(has_effective_normal() && seg->get_respect_effective_normal())
|
||||
? get_effective_normal() : near_plane.get_normal();
|
||||
|
||||
new_entry->set_surface_normal(normal);
|
||||
new_entry->set_surface_point(into_intersection_point);
|
||||
|
||||
return new_entry;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CollisionBox::test_intersection_from_box
|
||||
// Access: Public, Virtual
|
||||
|
@ -78,6 +78,8 @@ protected:
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_ray(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_segment(const CollisionEntry &entry) const;
|
||||
virtual PT(CollisionEntry)
|
||||
test_intersection_from_box(const CollisionEntry &entry) const;
|
||||
|
||||
virtual void fill_viz_geom();
|
||||
|
Loading…
x
Reference in New Issue
Block a user