mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
patch by Josh Enes (bug 1074173)
This commit is contained in:
parent
829e79cf29
commit
8383427022
@ -202,12 +202,12 @@ apply_state(const CullTraverser *trav, const CullTraverserData *data,
|
||||
}
|
||||
|
||||
// Get the occluder geometry in cull-center space.
|
||||
const LMatrix4 &occluder_mat = occluder_transform->get_mat();
|
||||
const LMatrix4 &occluder_mat_cull = occluder_transform->get_mat();
|
||||
LPoint3 points_near[4];
|
||||
points_near[0] = occluder_node->get_vertex(0) * occluder_mat;
|
||||
points_near[1] = occluder_node->get_vertex(1) * occluder_mat;
|
||||
points_near[2] = occluder_node->get_vertex(2) * occluder_mat;
|
||||
points_near[3] = occluder_node->get_vertex(3) * occluder_mat;
|
||||
points_near[0] = occluder_node->get_vertex(0) * occluder_mat_cull;
|
||||
points_near[1] = occluder_node->get_vertex(1) * occluder_mat_cull;
|
||||
points_near[2] = occluder_node->get_vertex(2) * occluder_mat_cull;
|
||||
points_near[3] = occluder_node->get_vertex(3) * occluder_mat_cull;
|
||||
LPlane plane(points_near[0], points_near[1], points_near[2]);
|
||||
|
||||
if (plane.get_normal().dot(LVector3::forward()) >= 0.0) {
|
||||
@ -225,49 +225,6 @@ apply_state(const CullTraverser *trav, const CullTraverserData *data,
|
||||
}
|
||||
}
|
||||
|
||||
PN_stdfloat near_clip = lens->get_near();
|
||||
if (plane.dist_to_plane(LPoint3::zero()) <= near_clip) {
|
||||
// This occluder is behind the camera's near plane. Ignore it.
|
||||
if (pgraph_cat.is_spam()) {
|
||||
pgraph_cat.spam()
|
||||
<< "Ignoring occluder " << occluder << ": behind near plane.\n";
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
PN_stdfloat d0 = points_near[0].dot(LVector3::forward());
|
||||
PN_stdfloat d1 = points_near[1].dot(LVector3::forward());
|
||||
PN_stdfloat d2 = points_near[2].dot(LVector3::forward());
|
||||
PN_stdfloat d3 = points_near[3].dot(LVector3::forward());
|
||||
|
||||
if (d0 <= near_clip && d1 <= near_clip && d2 <= near_clip && d3 <= near_clip) {
|
||||
// All four corners of the occluder are behind the camera's
|
||||
// near plane. Ignore it.
|
||||
if (pgraph_cat.is_spam()) {
|
||||
pgraph_cat.spam()
|
||||
<< "Ignoring occluder " << occluder << ": behind near plane (test 2).\n";
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: it's possible for part of the occlusion polygon to
|
||||
// intersect the camera's y = 0 plane. If this happens, the
|
||||
// frustum will go insane and the occluder won't work. The
|
||||
// proper fix for this is to clip the polygon against the near
|
||||
// plane, producing a smaller polygon, and use that to
|
||||
// generate the frustum. But maybe it doesn't matter. In
|
||||
// lieu of this, we just toss out any occluder with *any*
|
||||
// corner behind the y = 0 plane.
|
||||
if (d0 <= 0.0 || d1 <= 0.0 || d2 <= 0.0 || d3 <= 0.0) {
|
||||
// One of the corners is behind the y = 0 plane. We can't
|
||||
// handle this case. Ignore it.
|
||||
if (pgraph_cat.is_spam()) {
|
||||
pgraph_cat.spam()
|
||||
<< "Ignoring occluder " << occluder << ": partly behind zero plane.\n";
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (occluder_node->get_min_coverage()) {
|
||||
LPoint3 coords[4];
|
||||
lens->project(points_near[0], coords[0]);
|
||||
@ -318,22 +275,28 @@ apply_state(const CullTraverser *trav, const CullTraverserData *data,
|
||||
// TODO: perhaps we should also check whether any existing
|
||||
// occluders are fully contained within this new one.
|
||||
|
||||
// Project those four lines to the camera's far plane.
|
||||
PN_stdfloat far_clip = scene->get_lens()->get_far();
|
||||
LPlane far_plane(-LVector3::forward(), LVector3::forward() * far_clip);
|
||||
// Get the occluder coordinates in global space.
|
||||
const LMatrix4 &occluder_mat = occluder.get_net_transform()->get_mat();
|
||||
points_near[0] = occluder_node->get_vertex(0) * occluder_mat;
|
||||
points_near[1] = occluder_node->get_vertex(1) * occluder_mat;
|
||||
points_near[2] = occluder_node->get_vertex(2) * occluder_mat;
|
||||
points_near[3] = occluder_node->get_vertex(3) * occluder_mat;
|
||||
|
||||
// For the far points, project PAST the far clip of the lens
|
||||
// to ensures we get stuff that might be intersecting the far clip.
|
||||
LPoint3 center = scene->get_cull_center().get_net_transform()->get_pos();
|
||||
PN_stdfloat far_clip = scene->get_lens()->get_far() * 2.0;
|
||||
LPoint3 points_far[4];
|
||||
far_plane.intersects_line(points_far[0], LPoint3::zero(), points_near[0]);
|
||||
far_plane.intersects_line(points_far[1], LPoint3::zero(), points_near[1]);
|
||||
far_plane.intersects_line(points_far[2], LPoint3::zero(), points_near[2]);
|
||||
far_plane.intersects_line(points_far[3], LPoint3::zero(), points_near[3]);
|
||||
points_far[0] = normalize(points_near[0] - center) * far_clip + points_near[0];
|
||||
points_far[1] = normalize(points_near[1] - center) * far_clip + points_near[1];
|
||||
points_far[2] = normalize(points_near[2] - center) * far_clip + points_near[2];
|
||||
points_far[3] = normalize(points_near[3] - center) * far_clip + points_near[3];
|
||||
|
||||
// With these points, construct the bounding frustum of the
|
||||
// occluded region.
|
||||
PT(BoundingHexahedron) frustum =
|
||||
new BoundingHexahedron(points_far[1], points_far[2], points_far[3], points_far[0],
|
||||
points_near[1], points_near[2], points_near[3], points_near[0]);
|
||||
frustum->xform(center_transform->get_mat());
|
||||
|
||||
new_planes->_occluders[occluder] = frustum;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user