mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
portals are now clipped against view frustum to generate reduced frustums. There is a bug, which I will work on Monday
This commit is contained in:
parent
862e9811c6
commit
01171fd7d2
@ -97,41 +97,62 @@ draw_to(float x, float y, float z) {
|
||||
INLINE void PortalClipper::
|
||||
draw_camera_frustum() {
|
||||
_color = Colorf(1,1,1,1);
|
||||
draw_hexahedron(_hex_frustum);
|
||||
draw_hexahedron(_view_frustum);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PortalClipper::set_reduced_frustum
|
||||
// Access: Public
|
||||
// Description: set the current reduced frustum before traversing
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PortalClipper::
|
||||
set_reduced_frustum(BoundingHexahedron *frustum) {
|
||||
_reduced_frustum = frustum;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PortalClipper::is_in_view
|
||||
// Access: Public
|
||||
// Description: checks if portal_node is within the view frustum.
|
||||
// If so, then the portal is worth considering. This
|
||||
// is a 1st level test to weed out most of the portals
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PortalClipper::
|
||||
is_in_view(const NodePath &node_path) {
|
||||
|
||||
const BoundingVolume *bv = &_portal_node->get_bound();
|
||||
|
||||
// I am about to xform this gbv, so lets make a copy
|
||||
BoundingVolume *cbv = bv->make_copy();
|
||||
GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, cbv);
|
||||
|
||||
// trasform it to camera space
|
||||
CPT(TransformState) ctransform = node_path.get_transform(_scene_setup->get_cull_center());
|
||||
gbv->xform(ctransform->get_mat());
|
||||
|
||||
int result = _reduced_frustum->contains(gbv);
|
||||
pgraph_cat.debug() << "1st level test if portal is in view " << result << endl;
|
||||
return (result != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PortalClipper::facing_camera
|
||||
// Access: Public
|
||||
// Description: checks if the _coords that forms the plane is
|
||||
// facing the camera
|
||||
// Description: checks if any of the _coords is within the view frustum.
|
||||
// If so, then the portal is facing the camera. 2nd level
|
||||
// test to make sure this portal is worth visiting
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool PortalClipper::
|
||||
is_facing_camera()
|
||||
{
|
||||
Planef portal_plane(_coords[0], _coords[1], _coords[2]);
|
||||
Planef camera_plane(_hex_frustum->get_point(4), _hex_frustum->get_point(5), _hex_frustum->get_point(6));
|
||||
#if 0
|
||||
// use the camera's near plane to calculate direction
|
||||
pgraph_cat.debug() << portal_plane.get_normal() << "; " << -camera_plane.get_normal() << endl;
|
||||
float direction = portal_plane.get_normal().dot(-camera_plane.get_normal());
|
||||
pgraph_cat.debug() << "Found direction of " << direction << endl;
|
||||
return (direction < _FACING_THRESHOLD);
|
||||
#else
|
||||
// use the center of camera's near plane to the center of the
|
||||
// portal_plane to calulate the direction
|
||||
LPoint3f portal_center = (_coords[0] + _coords[1] + _coords[2] + _coords[3]) / 4;
|
||||
LPoint3f camera_center = (_hex_frustum->get_point(4) + _hex_frustum->get_point(5) + _hex_frustum->get_point(6) + _hex_frustum->get_point(7)) / 4;
|
||||
LVector3f camera_to_portal = portal_center - camera_center;
|
||||
camera_to_portal.normalize();
|
||||
pgraph_cat.debug() << "portal_center " << portal_center << "; camera_center " << camera_center << "; camera_to_portal " << camera_to_portal << endl;
|
||||
float direction = camera_plane.get_normal().dot(camera_to_portal);
|
||||
_color = Colorf(0,1,0,1);
|
||||
move_to(camera_center);
|
||||
draw_to(portal_center);
|
||||
#endif
|
||||
pgraph_cat.debug() << "Found direction of " << direction << endl;
|
||||
return (direction < _FACING_THRESHOLD);
|
||||
is_facing_camera(const NodePath &node_path) {
|
||||
int result = 0;
|
||||
|
||||
// check if the camera_center to portal_center lineseg is in view
|
||||
for (int j=0; j<_num_vert; ++j) {
|
||||
result |= _reduced_frustum->contains(_coords[j]);
|
||||
}
|
||||
pgraph_cat.debug() << "frustum->contains(coord) result = " << result << endl;
|
||||
|
||||
return (result != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -144,8 +165,8 @@ get_plane_depth(float x, float z, Planef *portal_plane) {
|
||||
float y = 0.0;
|
||||
// Plane equation: Ax + By + Cz + D = 0
|
||||
// y = (Ax + Cz + D) / -B
|
||||
pgraph_cat.debug() << *portal_plane << endl;
|
||||
pgraph_cat.debug() << portal_plane->_v.v._0 << " " << portal_plane->_v.v._1 << " "
|
||||
pgraph_cat.spam() << *portal_plane << endl;
|
||||
pgraph_cat.spam() << portal_plane->_v.v._0 << " " << portal_plane->_v.v._1 << " "
|
||||
<< portal_plane->_v.v._2 << " " << portal_plane->_v.v._3 << endl;
|
||||
|
||||
if (portal_plane->_v.v._1 != 0.0) {
|
||||
|
@ -47,7 +47,7 @@ PortalClipper(GeometricBoundingVolume *frustum, SceneSetup *scene_setup) {
|
||||
_geom_point = new GeomPoint;
|
||||
_geom_linestrip = new GeomLinestrip;
|
||||
|
||||
_hex_frustum = DCAST(BoundingHexahedron, frustum);
|
||||
_view_frustum = _reduced_frustum = DCAST(BoundingHexahedron, frustum);
|
||||
|
||||
_scene_setup = scene_setup;
|
||||
}
|
||||
@ -203,7 +203,7 @@ draw_lines()
|
||||
//geom->write_verbose(cerr, 0);
|
||||
|
||||
_previous->add_geom(geom);
|
||||
pgraph_cat.debug() << "added geometry" << endl;
|
||||
pgraph_cat.spam() << "added geometry" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -220,51 +220,51 @@ prepare_portal(const NodePath &node_path)
|
||||
|
||||
// Get the Portal Node from this node_path
|
||||
PandaNode *node = node_path.node();
|
||||
PortalNode *portal_node = NULL;
|
||||
_portal_node = NULL;
|
||||
if (node->is_of_type(PortalNode::get_class_type()))
|
||||
portal_node = DCAST(PortalNode, node);
|
||||
_portal_node = DCAST(PortalNode, node);
|
||||
|
||||
// walk the portal
|
||||
_num_vert = 0;
|
||||
|
||||
// Get the geometry from the portal
|
||||
pgraph_cat.debug() << *portal_node << endl;
|
||||
pgraph_cat.spam() << *_portal_node << endl;
|
||||
|
||||
/*
|
||||
// Get the World transformation matrix
|
||||
CPT(TransformState) wtransform = portal_nodepath.get_transform(_scene_setup->get_scene_root());
|
||||
LMatrix4f wmat = wtransform->get_mat();
|
||||
pgraph_cat.debug() << wmat << endl;
|
||||
pgraph_cat.spam() << wmat << endl;
|
||||
*/
|
||||
|
||||
// Get the camera transformation matrix
|
||||
CPT(TransformState) ctransform = node_path.get_transform(_scene_setup->get_cull_center());
|
||||
//CPT(TransformState) ctransform = node_path.get_transform(_scene_setup->get_camera_path());
|
||||
LMatrix4f cmat = ctransform->get_mat();
|
||||
pgraph_cat.debug() << cmat << endl;
|
||||
pgraph_cat.spam() << cmat << endl;
|
||||
|
||||
Vertexf temp[4];
|
||||
temp[0] = portal_node->get_vertex(0);
|
||||
temp[1] = portal_node->get_vertex(1);
|
||||
temp[2] = portal_node->get_vertex(2);
|
||||
temp[3] = portal_node->get_vertex(3);
|
||||
temp[0] = _portal_node->get_vertex(0);
|
||||
temp[1] = _portal_node->get_vertex(1);
|
||||
temp[2] = _portal_node->get_vertex(2);
|
||||
temp[3] = _portal_node->get_vertex(3);
|
||||
|
||||
pgraph_cat.debug() << "before transformation to camera space" << endl;
|
||||
pgraph_cat.debug() << temp[0] << endl;
|
||||
pgraph_cat.debug() << temp[1] << endl;
|
||||
pgraph_cat.debug() << temp[2] << endl;
|
||||
pgraph_cat.debug() << temp[3] << endl;
|
||||
pgraph_cat.spam() << "before transformation to camera space" << endl;
|
||||
pgraph_cat.spam() << temp[0] << endl;
|
||||
pgraph_cat.spam() << temp[1] << endl;
|
||||
pgraph_cat.spam() << temp[2] << endl;
|
||||
pgraph_cat.spam() << temp[3] << endl;
|
||||
|
||||
temp[0] = temp[0]*cmat;
|
||||
temp[1] = temp[1]*cmat;
|
||||
temp[2] = temp[2]*cmat;
|
||||
temp[3] = temp[3]*cmat;
|
||||
|
||||
pgraph_cat.debug() << "after transformation to camera space" << endl;
|
||||
pgraph_cat.debug() << temp[0] << endl;
|
||||
pgraph_cat.debug() << temp[1] << endl;
|
||||
pgraph_cat.debug() << temp[2] << endl;
|
||||
pgraph_cat.debug() << temp[3] << endl;
|
||||
pgraph_cat.spam() << "after transformation to camera space" << endl;
|
||||
pgraph_cat.spam() << temp[0] << endl;
|
||||
pgraph_cat.spam() << temp[1] << endl;
|
||||
pgraph_cat.spam() << temp[2] << endl;
|
||||
pgraph_cat.spam() << temp[3] << endl;
|
||||
|
||||
float min_x, max_x, min_z, max_z;
|
||||
|
||||
@ -273,7 +273,7 @@ prepare_portal(const NodePath &node_path)
|
||||
min_z = min(min(min(temp[0][2], temp[1][2]), temp[2][2]), temp[3][2]);
|
||||
max_z = max(max(max(temp[0][2], temp[1][2]), temp[2][2]), temp[3][2]);
|
||||
|
||||
pgraph_cat.debug() << "min_x " << min_x << ";max_x " << max_x << ";min_z " << min_z << ";max_z " << max_z << endl;
|
||||
pgraph_cat.spam() << "min_x " << min_x << ";max_x " << max_x << ";min_z " << min_z << ";max_z " << max_z << endl;
|
||||
|
||||
|
||||
Planef portal_plane(temp[0], temp[1], temp[2]);
|
||||
@ -281,29 +281,30 @@ prepare_portal(const NodePath &node_path)
|
||||
float y;
|
||||
|
||||
y = get_plane_depth(min_x, min_z, &portal_plane);
|
||||
pgraph_cat.debug() << "plane's depth is " << y << endl;
|
||||
pgraph_cat.spam() << "plane's depth is " << y << endl;
|
||||
_coords[0].set(min_x, y, min_z);
|
||||
|
||||
y = get_plane_depth(max_x, min_z, &portal_plane);
|
||||
pgraph_cat.debug() << "plane's depth is " << y << endl;
|
||||
pgraph_cat.spam() << "plane's depth is " << y << endl;
|
||||
_coords[1].set(max_x, y, min_z);
|
||||
|
||||
y = get_plane_depth(max_x, max_z, &portal_plane);
|
||||
pgraph_cat.debug() << "plane's depth is " << y << endl;
|
||||
pgraph_cat.spam() << "plane's depth is " << y << endl;
|
||||
_coords[2].set(max_x, y, max_z);
|
||||
|
||||
y = get_plane_depth(min_x, max_z, &portal_plane);
|
||||
pgraph_cat.debug() << "plane's depth is " << y << endl;
|
||||
pgraph_cat.spam() << "plane's depth is " << y << endl;
|
||||
_coords[3].set(min_x, y, max_z);
|
||||
|
||||
pgraph_cat.debug() << "after min max calculation" << endl;
|
||||
pgraph_cat.debug() << _coords[0] << endl;
|
||||
pgraph_cat.debug() << _coords[1] << endl;
|
||||
pgraph_cat.debug() << _coords[2] << endl;
|
||||
pgraph_cat.debug() << _coords[3] << endl;
|
||||
pgraph_cat.spam() << "after min max calculation" << endl;
|
||||
pgraph_cat.spam() << _coords[0] << endl;
|
||||
pgraph_cat.spam() << _coords[1] << endl;
|
||||
pgraph_cat.spam() << _coords[2] << endl;
|
||||
pgraph_cat.spam() << _coords[3] << endl;
|
||||
|
||||
// check if facing camera
|
||||
if (is_facing_camera()) {
|
||||
// check if portal is in view
|
||||
if (is_in_view(node_path)) {
|
||||
pgraph_cat.debug() << "portal passed 1st level test \n";
|
||||
|
||||
// ok, now lets add the original portal
|
||||
_color = Colorf(0,1,1,1);
|
||||
@ -314,15 +315,15 @@ prepare_portal(const NodePath &node_path)
|
||||
draw_to(temp[0]);
|
||||
|
||||
// ok, now lets add the min_max portal
|
||||
_color = Colorf(1,0,0,1);
|
||||
_color = Colorf(1,1,0,1);
|
||||
move_to(_coords[0]);
|
||||
draw_to(_coords[1]);
|
||||
draw_to(_coords[2]);
|
||||
draw_to(_coords[3]);
|
||||
draw_to(_coords[0]);
|
||||
|
||||
pgraph_cat.debug() << "assembled " << portal_node->get_name() << ": frustum points" << endl;
|
||||
_num_vert = portal_node->get_num_vertices();
|
||||
pgraph_cat.spam() << "assembled " << _portal_node->get_name() << ": frustum points" << endl;
|
||||
_num_vert = _portal_node->get_num_vertices();
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,7 +336,7 @@ prepare_portal(const NodePath &node_path)
|
||||
void PortalClipper::
|
||||
clip_portal(const NodePath &node_path)
|
||||
{
|
||||
int num_planes = _hex_frustum->get_num_planes();
|
||||
int num_planes = _view_frustum->get_num_planes();
|
||||
|
||||
if (!_num_vert)
|
||||
return;
|
||||
@ -346,24 +347,136 @@ clip_portal(const NodePath &node_path)
|
||||
// print out the planes. plane 0 should be far and plane 5 should be near
|
||||
// so we are only concerned with the 4 side planes.
|
||||
for (int i=0; i<num_planes; ++i) {
|
||||
Planef plane = _hex_frustum->get_plane(i);
|
||||
Planef plane = _view_frustum->get_plane(i);
|
||||
plane.output(pgraph_cat.debug());
|
||||
pgraph_cat.debug() << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
for (int i=1; i<num_planes-1; ++i) {
|
||||
Planef plane = _hex_frustum->get_plane(i);
|
||||
for (int j=0; j<_num_vert; ++j) {
|
||||
float t;
|
||||
LPoint3f from_origin = _coords[j];
|
||||
LVector3f from_direction = _coords[(j+1)%_num_vert] - _coords[j];
|
||||
bool is_intersect = plane.intersects_line(t, from_origin, from_direction);
|
||||
if (is_intersect) {
|
||||
pgraph_cat.debug() << "plane " << i << " intersected segement " << j << "->" << (j+1)%_num_vert << " at t=" << t << endl;
|
||||
// ViewFrustum -> Logical Planes -> Portal Edge
|
||||
// Plane0 -> far plane -> None
|
||||
// plane5 -> near plane -> None
|
||||
// Plane1 -> bottom plane -> 0-1
|
||||
// Plane3 -> top plane -> 1-2
|
||||
// Plane2 -> right plane -> 2-3
|
||||
// Plane4 -> left plane -> 3-0
|
||||
|
||||
int j;
|
||||
float t;
|
||||
Planef plane;
|
||||
bool is_intersect;
|
||||
LPoint3f from_origin;
|
||||
LPoint3f cut_point;
|
||||
LVector3f from_direction;
|
||||
|
||||
// Look for intersection with the view frustum's bottom_plane to bottom_edge of portal
|
||||
plane = _view_frustum->get_plane(1);
|
||||
for (j=0; j<_num_vert; ++j) {
|
||||
from_origin = _coords[j];
|
||||
from_direction = _coords[(j+1)%_num_vert] - _coords[j];
|
||||
is_intersect = plane.intersects_line(t, from_origin, from_direction);
|
||||
if (is_intersect && (t > 0.0 && t < 1.0)) {
|
||||
pgraph_cat.debug() << "bottom plane intersected segement " << j << "->"
|
||||
<< (j+1)%_num_vert << " at t=" << t << endl;
|
||||
cut_point = from_origin + t*from_direction;
|
||||
pgraph_cat.debug() << "cut_point: " << cut_point << endl;
|
||||
if (j == 1) {
|
||||
// means bottom should cut 1->2 by moving 1 to the intersection point
|
||||
_coords[1] = cut_point;
|
||||
}
|
||||
else if (j == 3) {
|
||||
// means bottom should cut 3->0 by moving 0 to the intersection point
|
||||
_coords[0] = cut_point;
|
||||
}
|
||||
else
|
||||
pgraph_cat.debug() << "ignored for now for simplicity \n";
|
||||
}
|
||||
}
|
||||
|
||||
// Look for intersection with the view frustum's top_plane to top_edge of portal
|
||||
plane = _view_frustum->get_plane(3);
|
||||
for (j=0; j<_num_vert; ++j) {
|
||||
from_origin = _coords[j];
|
||||
from_direction = _coords[(j+1)%_num_vert] - _coords[j];
|
||||
is_intersect = plane.intersects_line(t, from_origin, from_direction);
|
||||
if (is_intersect && (t > 0.0 && t < 1.0)) {
|
||||
pgraph_cat.debug() << "top plane intersected segement " << j << "->"
|
||||
<< (j+1)%_num_vert << " at t=" << t << endl;
|
||||
cut_point = from_origin + t*from_direction;
|
||||
pgraph_cat.debug() << "cut_point: " << cut_point << endl;
|
||||
if (j == 1) {
|
||||
// means top should cut 1->2 by moving 2 to the intersection point
|
||||
_coords[2] = cut_point;
|
||||
}
|
||||
else if (j == 3) {
|
||||
// means top should cut 3->0 by moving 3 to the intersection point
|
||||
_coords[3] = cut_point;
|
||||
}
|
||||
else
|
||||
pgraph_cat.debug() << "ignored for now for simplicity \n";
|
||||
}
|
||||
}
|
||||
|
||||
// Look for intersection with the view frustum's right_plane to right_edge of portal
|
||||
plane = _view_frustum->get_plane(2);
|
||||
for (j=0; j<_num_vert; ++j) {
|
||||
from_origin = _coords[j];
|
||||
from_direction = _coords[(j+1)%_num_vert] - _coords[j];
|
||||
is_intersect = plane.intersects_line(t, from_origin, from_direction);
|
||||
if (is_intersect && (t > 0.0 && t < 1.0)) {
|
||||
pgraph_cat.debug() << "right plane intersected segement " << j << "->"
|
||||
<< (j+1)%_num_vert << " at t=" << t << endl;
|
||||
cut_point = from_origin + t*from_direction;
|
||||
pgraph_cat.debug() << "cut_point: " << cut_point << endl;
|
||||
if (j == 0) {
|
||||
// means right should cut 0->1 by moving 1 to the intersection point
|
||||
_coords[1] = cut_point;
|
||||
}
|
||||
else if (j == 2) {
|
||||
// means bottom should cut 2->3 by moving 2 to the intersection point
|
||||
_coords[2] = cut_point;
|
||||
}
|
||||
else
|
||||
pgraph_cat.debug() << "ignored for now for simplicity \n";
|
||||
}
|
||||
}
|
||||
|
||||
// Look for intersection with the view frustum's left_plane to left_edge of portal
|
||||
plane = _view_frustum->get_plane(4);
|
||||
for (j=0; j<_num_vert; ++j) {
|
||||
from_origin = _coords[j];
|
||||
from_direction = _coords[(j+1)%_num_vert] - _coords[j];
|
||||
is_intersect = plane.intersects_line(t, from_origin, from_direction);
|
||||
if (is_intersect && (t > 0.0 && t < 1.0)) {
|
||||
pgraph_cat.debug() << "left plane intersected segement " << j << "->"
|
||||
<< (j+1)%_num_vert << " at t=" << t << endl;
|
||||
cut_point = from_origin + t*from_direction;
|
||||
pgraph_cat.debug() << "cut_point: " << cut_point << endl;
|
||||
if (j == 0) {
|
||||
// means left should cut 0->1 by moving 0 to the intersection point
|
||||
_coords[0] = cut_point;
|
||||
}
|
||||
else if (j == 2) {
|
||||
// means bottom should cut 2->3 by moving 3 to the intersection point
|
||||
_coords[3] = cut_point;
|
||||
}
|
||||
else
|
||||
pgraph_cat.debug() << "ignored for now for simplicity \n";
|
||||
}
|
||||
}
|
||||
// ok, now lets add the clipped portal
|
||||
_color = Colorf(1,0,0,1);
|
||||
move_to(_coords[0]);
|
||||
draw_to(_coords[1]);
|
||||
draw_to(_coords[2]);
|
||||
draw_to(_coords[3]);
|
||||
draw_to(_coords[0]);
|
||||
|
||||
// 2nd level test, more accurate to determine if the portal is worth visiting
|
||||
if (!is_facing_camera(node_path)) {
|
||||
pgraph_cat.debug() << "portal failed 2nd level test \n";
|
||||
_num_vert = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -390,55 +503,55 @@ get_reduced_frustum(const NodePath &node_path)
|
||||
float t;
|
||||
bool visible = true;
|
||||
// find intersection of 7->3 with far
|
||||
LPoint3f from_origin = _hex_frustum->get_point(7);
|
||||
LPoint3f from_origin = _view_frustum->get_point(7);
|
||||
LVector3f from_direction = _coords[3] - from_origin;
|
||||
bool is_intersect = _hex_frustum->get_plane(0).intersects_line(t, from_origin, from_direction);
|
||||
bool is_intersect = _view_frustum->get_plane(0).intersects_line(t, from_origin, from_direction);
|
||||
if (is_intersect && t >= 0.0) { // has to be positive, else camera is not looking at the portal
|
||||
pgraph_cat.debug() << "far plane intersected 7->3 at t=" << t << endl;
|
||||
pgraph_cat.spam() << "far plane intersected 7->3 at t=" << t << endl;
|
||||
intersect_points[0] = from_origin + t*from_direction;
|
||||
pgraph_cat.debug() << intersect_points[0] << endl;
|
||||
pgraph_cat.spam() << intersect_points[0] << endl;
|
||||
}
|
||||
else
|
||||
visible = false;
|
||||
|
||||
// find intersection of 4->0 with far
|
||||
from_origin = _hex_frustum->get_point(4);
|
||||
from_origin = _view_frustum->get_point(4);
|
||||
from_direction = _coords[0] - from_origin;
|
||||
is_intersect = _hex_frustum->get_plane(0).intersects_line(t, from_origin, from_direction);
|
||||
is_intersect = _view_frustum->get_plane(0).intersects_line(t, from_origin, from_direction);
|
||||
if (is_intersect && t >= 0.0) { // has to be positive, else camera is not looking at the portal
|
||||
pgraph_cat.debug() << "far plane intersected 4->0 at t=" << t << endl;
|
||||
pgraph_cat.spam() << "far plane intersected 4->0 at t=" << t << endl;
|
||||
intersect_points[1] = from_origin + t*from_direction;
|
||||
pgraph_cat.debug() << intersect_points[1] << endl;
|
||||
pgraph_cat.spam() << intersect_points[1] << endl;
|
||||
}
|
||||
else
|
||||
visible = false;
|
||||
|
||||
// find intersection of 5->1 with far
|
||||
from_origin = _hex_frustum->get_point(5);
|
||||
from_origin = _view_frustum->get_point(5);
|
||||
from_direction = _coords[1] - from_origin;
|
||||
is_intersect = _hex_frustum->get_plane(0).intersects_line(t, from_origin, from_direction);
|
||||
is_intersect = _view_frustum->get_plane(0).intersects_line(t, from_origin, from_direction);
|
||||
if (is_intersect && t >= 0.0) { // has to be positive, else camera is not looking at the portal
|
||||
pgraph_cat.debug() << "far plane intersected 5->1 at t=" << t << endl;
|
||||
pgraph_cat.spam() << "far plane intersected 5->1 at t=" << t << endl;
|
||||
intersect_points[2] = from_origin + t*from_direction;
|
||||
pgraph_cat.debug() << intersect_points[2] << endl;
|
||||
pgraph_cat.spam() << intersect_points[2] << endl;
|
||||
}
|
||||
else
|
||||
visible = false;
|
||||
|
||||
// find intersection of 6->2 with far
|
||||
from_origin = _hex_frustum->get_point(6);
|
||||
from_origin = _view_frustum->get_point(6);
|
||||
from_direction = _coords[2] - from_origin;
|
||||
is_intersect = _hex_frustum->get_plane(0).intersects_line(t, from_origin, from_direction);
|
||||
is_intersect = _view_frustum->get_plane(0).intersects_line(t, from_origin, from_direction);
|
||||
if (is_intersect && t >= 0.0) { // has to be positive, else camera is not looking at the portal
|
||||
pgraph_cat.debug() << "far plane intersected 6->2 at t=" << t << endl;
|
||||
pgraph_cat.spam() << "far plane intersected 6->2 at t=" << t << endl;
|
||||
intersect_points[3] = from_origin + t*from_direction;
|
||||
pgraph_cat.debug() << intersect_points[3] << endl;
|
||||
pgraph_cat.spam() << intersect_points[3] << endl;
|
||||
}
|
||||
else
|
||||
visible = false;
|
||||
|
||||
if (!visible) {
|
||||
pgraph_cat.debug() << "portal is not visible from current camera look at" << endl;
|
||||
pgraph_cat.spam() << "portal is not visible from current camera look at" << endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -446,14 +559,16 @@ get_reduced_frustum(const NodePath &node_path)
|
||||
PT(BoundingVolume) reduced_frustum = new
|
||||
BoundingHexahedron(intersect_points[1], intersect_points[2],
|
||||
intersect_points[3], intersect_points[0],
|
||||
_hex_frustum->get_point(4), _hex_frustum->get_point(5),
|
||||
_hex_frustum->get_point(6), _hex_frustum->get_point(7));
|
||||
_view_frustum->get_point(4), _view_frustum->get_point(5),
|
||||
_view_frustum->get_point(6), _view_frustum->get_point(7));
|
||||
|
||||
pgraph_cat.debug() << *reduced_frustum << endl;
|
||||
pgraph_cat.spam() << *reduced_frustum << endl;
|
||||
|
||||
// draw this hexahedron
|
||||
_color = Colorf(0,0,1,1);
|
||||
draw_hexahedron(DCAST(BoundingHexahedron, reduced_frustum));
|
||||
|
||||
_reduced_frustum = DCAST(BoundingHexahedron, reduced_frustum);
|
||||
|
||||
return reduced_frustum;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "geom.h"
|
||||
#include "sceneSetup.h"
|
||||
#include "renderState.h"
|
||||
#include "portalNode.h"
|
||||
#include "transformState.h"
|
||||
#include "geometricBoundingVolume.h"
|
||||
#include "boundingHexahedron.h"
|
||||
@ -39,6 +40,7 @@
|
||||
#include "geomNode.h"
|
||||
|
||||
class PandaNode;
|
||||
class PortalNode;
|
||||
class CullHandler;
|
||||
class CullTraverserData;
|
||||
class CullableObject;
|
||||
@ -61,7 +63,8 @@ public:
|
||||
PortalClipper(GeometricBoundingVolume *frustum, SceneSetup *scene_setup);
|
||||
~PortalClipper();
|
||||
|
||||
INLINE bool is_facing_camera();
|
||||
INLINE bool is_in_view(const NodePath &node_path);
|
||||
INLINE bool is_facing_camera(const NodePath &node_path);
|
||||
void prepare_portal(const NodePath &node_path);
|
||||
|
||||
void clip_portal(const NodePath &node_path);
|
||||
@ -80,6 +83,8 @@ public:
|
||||
|
||||
INLINE float get_plane_depth(float x, float z, Planef *portal_plane);
|
||||
|
||||
INLINE void set_reduced_frustum(BoundingHexahedron *frustum);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
@ -123,7 +128,10 @@ private:
|
||||
PT(GeomPoint) _geom_point;
|
||||
PT(GeomLinestrip) _geom_linestrip;
|
||||
|
||||
BoundingHexahedron *_hex_frustum;
|
||||
BoundingHexahedron *_view_frustum;
|
||||
BoundingHexahedron *_reduced_frustum;
|
||||
|
||||
PortalNode *_portal_node; // current working portal for dereference ease
|
||||
|
||||
int _num_vert;
|
||||
Vertexf _coords[4];
|
||||
|
@ -186,7 +186,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
PT(BoundingVolume) reduced_frustum;
|
||||
|
||||
portal_viewer->prepare_portal(data._node_path.get_node_path());
|
||||
//portal_viewer->clip_portal(data._node_path.get_node_path());
|
||||
portal_viewer->clip_portal(data._node_path.get_node_path());
|
||||
if ((reduced_frustum = portal_viewer->get_reduced_frustum(data._node_path.get_node_path()))) {
|
||||
// This reduced frustum is in camera space
|
||||
pgraph_cat.debug() << "got reduced frustum " << reduced_frustum << endl;
|
||||
@ -197,7 +197,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
portal_viewer->_scene_setup->get_cull_center().get_transform(_zone_out);
|
||||
vf->xform(cull_center_transform->get_mat());
|
||||
}
|
||||
pgraph_cat.debug() << "vf is " << *vf << "\n";
|
||||
pgraph_cat.spam() << "vf is " << *vf << "\n";
|
||||
|
||||
// Get the net trasform of the _zone_out
|
||||
CPT(TransformState) zone_transform = _zone_out.get_net_transform();
|
||||
@ -206,7 +206,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
||||
zone_transform,
|
||||
trav->get_initial_state(), vf,
|
||||
trav->get_guard_band());
|
||||
pgraph_cat.debug() << "cull_callback: traversing " << _zone_out.get_name() << endl;
|
||||
pgraph_cat.spam() << "cull_callback: traversing " << _zone_out.get_name() << endl;
|
||||
// Make this zone show with the reduced frustum
|
||||
_zone_out.show();
|
||||
trav->traverse(next_data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user