mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -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::
|
INLINE void PortalClipper::
|
||||||
draw_camera_frustum() {
|
draw_camera_frustum() {
|
||||||
_color = Colorf(1,1,1,1);
|
_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
|
// Function: PortalClipper::facing_camera
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: checks if the _coords that forms the plane is
|
// Description: checks if any of the _coords is within the view frustum.
|
||||||
// facing the camera
|
// If so, then the portal is facing the camera. 2nd level
|
||||||
|
// test to make sure this portal is worth visiting
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE bool PortalClipper::
|
INLINE bool PortalClipper::
|
||||||
is_facing_camera()
|
is_facing_camera(const NodePath &node_path) {
|
||||||
{
|
int result = 0;
|
||||||
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));
|
// check if the camera_center to portal_center lineseg is in view
|
||||||
#if 0
|
for (int j=0; j<_num_vert; ++j) {
|
||||||
// use the camera's near plane to calculate direction
|
result |= _reduced_frustum->contains(_coords[j]);
|
||||||
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() << "frustum->contains(coord) result = " << result << endl;
|
||||||
pgraph_cat.debug() << "Found direction of " << direction << endl;
|
|
||||||
return (direction < _FACING_THRESHOLD);
|
return (result != 0);
|
||||||
#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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -144,8 +165,8 @@ get_plane_depth(float x, float z, Planef *portal_plane) {
|
|||||||
float y = 0.0;
|
float y = 0.0;
|
||||||
// Plane equation: Ax + By + Cz + D = 0
|
// Plane equation: Ax + By + Cz + D = 0
|
||||||
// y = (Ax + Cz + D) / -B
|
// y = (Ax + Cz + D) / -B
|
||||||
pgraph_cat.debug() << *portal_plane << endl;
|
pgraph_cat.spam() << *portal_plane << endl;
|
||||||
pgraph_cat.debug() << portal_plane->_v.v._0 << " " << portal_plane->_v.v._1 << " "
|
pgraph_cat.spam() << portal_plane->_v.v._0 << " " << portal_plane->_v.v._1 << " "
|
||||||
<< portal_plane->_v.v._2 << " " << portal_plane->_v.v._3 << endl;
|
<< portal_plane->_v.v._2 << " " << portal_plane->_v.v._3 << endl;
|
||||||
|
|
||||||
if (portal_plane->_v.v._1 != 0.0) {
|
if (portal_plane->_v.v._1 != 0.0) {
|
||||||
|
@ -47,7 +47,7 @@ PortalClipper(GeometricBoundingVolume *frustum, SceneSetup *scene_setup) {
|
|||||||
_geom_point = new GeomPoint;
|
_geom_point = new GeomPoint;
|
||||||
_geom_linestrip = new GeomLinestrip;
|
_geom_linestrip = new GeomLinestrip;
|
||||||
|
|
||||||
_hex_frustum = DCAST(BoundingHexahedron, frustum);
|
_view_frustum = _reduced_frustum = DCAST(BoundingHexahedron, frustum);
|
||||||
|
|
||||||
_scene_setup = scene_setup;
|
_scene_setup = scene_setup;
|
||||||
}
|
}
|
||||||
@ -203,7 +203,7 @@ draw_lines()
|
|||||||
//geom->write_verbose(cerr, 0);
|
//geom->write_verbose(cerr, 0);
|
||||||
|
|
||||||
_previous->add_geom(geom);
|
_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
|
// Get the Portal Node from this node_path
|
||||||
PandaNode *node = node_path.node();
|
PandaNode *node = node_path.node();
|
||||||
PortalNode *portal_node = NULL;
|
_portal_node = NULL;
|
||||||
if (node->is_of_type(PortalNode::get_class_type()))
|
if (node->is_of_type(PortalNode::get_class_type()))
|
||||||
portal_node = DCAST(PortalNode, node);
|
_portal_node = DCAST(PortalNode, node);
|
||||||
|
|
||||||
// walk the portal
|
// walk the portal
|
||||||
_num_vert = 0;
|
_num_vert = 0;
|
||||||
|
|
||||||
// Get the geometry from the portal
|
// Get the geometry from the portal
|
||||||
pgraph_cat.debug() << *portal_node << endl;
|
pgraph_cat.spam() << *_portal_node << endl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Get the World transformation matrix
|
// Get the World transformation matrix
|
||||||
CPT(TransformState) wtransform = portal_nodepath.get_transform(_scene_setup->get_scene_root());
|
CPT(TransformState) wtransform = portal_nodepath.get_transform(_scene_setup->get_scene_root());
|
||||||
LMatrix4f wmat = wtransform->get_mat();
|
LMatrix4f wmat = wtransform->get_mat();
|
||||||
pgraph_cat.debug() << wmat << endl;
|
pgraph_cat.spam() << wmat << endl;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Get the camera transformation matrix
|
// 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_cull_center());
|
||||||
//CPT(TransformState) ctransform = node_path.get_transform(_scene_setup->get_camera_path());
|
//CPT(TransformState) ctransform = node_path.get_transform(_scene_setup->get_camera_path());
|
||||||
LMatrix4f cmat = ctransform->get_mat();
|
LMatrix4f cmat = ctransform->get_mat();
|
||||||
pgraph_cat.debug() << cmat << endl;
|
pgraph_cat.spam() << cmat << endl;
|
||||||
|
|
||||||
Vertexf temp[4];
|
Vertexf temp[4];
|
||||||
temp[0] = portal_node->get_vertex(0);
|
temp[0] = _portal_node->get_vertex(0);
|
||||||
temp[1] = portal_node->get_vertex(1);
|
temp[1] = _portal_node->get_vertex(1);
|
||||||
temp[2] = portal_node->get_vertex(2);
|
temp[2] = _portal_node->get_vertex(2);
|
||||||
temp[3] = portal_node->get_vertex(3);
|
temp[3] = _portal_node->get_vertex(3);
|
||||||
|
|
||||||
pgraph_cat.debug() << "before transformation to camera space" << endl;
|
pgraph_cat.spam() << "before transformation to camera space" << endl;
|
||||||
pgraph_cat.debug() << temp[0] << endl;
|
pgraph_cat.spam() << temp[0] << endl;
|
||||||
pgraph_cat.debug() << temp[1] << endl;
|
pgraph_cat.spam() << temp[1] << endl;
|
||||||
pgraph_cat.debug() << temp[2] << endl;
|
pgraph_cat.spam() << temp[2] << endl;
|
||||||
pgraph_cat.debug() << temp[3] << endl;
|
pgraph_cat.spam() << temp[3] << endl;
|
||||||
|
|
||||||
temp[0] = temp[0]*cmat;
|
temp[0] = temp[0]*cmat;
|
||||||
temp[1] = temp[1]*cmat;
|
temp[1] = temp[1]*cmat;
|
||||||
temp[2] = temp[2]*cmat;
|
temp[2] = temp[2]*cmat;
|
||||||
temp[3] = temp[3]*cmat;
|
temp[3] = temp[3]*cmat;
|
||||||
|
|
||||||
pgraph_cat.debug() << "after transformation to camera space" << endl;
|
pgraph_cat.spam() << "after transformation to camera space" << endl;
|
||||||
pgraph_cat.debug() << temp[0] << endl;
|
pgraph_cat.spam() << temp[0] << endl;
|
||||||
pgraph_cat.debug() << temp[1] << endl;
|
pgraph_cat.spam() << temp[1] << endl;
|
||||||
pgraph_cat.debug() << temp[2] << endl;
|
pgraph_cat.spam() << temp[2] << endl;
|
||||||
pgraph_cat.debug() << temp[3] << endl;
|
pgraph_cat.spam() << temp[3] << endl;
|
||||||
|
|
||||||
float min_x, max_x, min_z, max_z;
|
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]);
|
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]);
|
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]);
|
Planef portal_plane(temp[0], temp[1], temp[2]);
|
||||||
@ -281,29 +281,30 @@ prepare_portal(const NodePath &node_path)
|
|||||||
float y;
|
float y;
|
||||||
|
|
||||||
y = get_plane_depth(min_x, min_z, &portal_plane);
|
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);
|
_coords[0].set(min_x, y, min_z);
|
||||||
|
|
||||||
y = get_plane_depth(max_x, min_z, &portal_plane);
|
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);
|
_coords[1].set(max_x, y, min_z);
|
||||||
|
|
||||||
y = get_plane_depth(max_x, max_z, &portal_plane);
|
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);
|
_coords[2].set(max_x, y, max_z);
|
||||||
|
|
||||||
y = get_plane_depth(min_x, max_z, &portal_plane);
|
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);
|
_coords[3].set(min_x, y, max_z);
|
||||||
|
|
||||||
pgraph_cat.debug() << "after min max calculation" << endl;
|
pgraph_cat.spam() << "after min max calculation" << endl;
|
||||||
pgraph_cat.debug() << _coords[0] << endl;
|
pgraph_cat.spam() << _coords[0] << endl;
|
||||||
pgraph_cat.debug() << _coords[1] << endl;
|
pgraph_cat.spam() << _coords[1] << endl;
|
||||||
pgraph_cat.debug() << _coords[2] << endl;
|
pgraph_cat.spam() << _coords[2] << endl;
|
||||||
pgraph_cat.debug() << _coords[3] << endl;
|
pgraph_cat.spam() << _coords[3] << endl;
|
||||||
|
|
||||||
// check if facing camera
|
// check if portal is in view
|
||||||
if (is_facing_camera()) {
|
if (is_in_view(node_path)) {
|
||||||
|
pgraph_cat.debug() << "portal passed 1st level test \n";
|
||||||
|
|
||||||
// ok, now lets add the original portal
|
// ok, now lets add the original portal
|
||||||
_color = Colorf(0,1,1,1);
|
_color = Colorf(0,1,1,1);
|
||||||
@ -314,15 +315,15 @@ prepare_portal(const NodePath &node_path)
|
|||||||
draw_to(temp[0]);
|
draw_to(temp[0]);
|
||||||
|
|
||||||
// ok, now lets add the min_max portal
|
// ok, now lets add the min_max portal
|
||||||
_color = Colorf(1,0,0,1);
|
_color = Colorf(1,1,0,1);
|
||||||
move_to(_coords[0]);
|
move_to(_coords[0]);
|
||||||
draw_to(_coords[1]);
|
draw_to(_coords[1]);
|
||||||
draw_to(_coords[2]);
|
draw_to(_coords[2]);
|
||||||
draw_to(_coords[3]);
|
draw_to(_coords[3]);
|
||||||
draw_to(_coords[0]);
|
draw_to(_coords[0]);
|
||||||
|
|
||||||
pgraph_cat.debug() << "assembled " << portal_node->get_name() << ": frustum points" << endl;
|
pgraph_cat.spam() << "assembled " << _portal_node->get_name() << ": frustum points" << endl;
|
||||||
_num_vert = portal_node->get_num_vertices();
|
_num_vert = _portal_node->get_num_vertices();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +336,7 @@ prepare_portal(const NodePath &node_path)
|
|||||||
void PortalClipper::
|
void PortalClipper::
|
||||||
clip_portal(const NodePath &node_path)
|
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)
|
if (!_num_vert)
|
||||||
return;
|
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
|
// 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.
|
// so we are only concerned with the 4 side planes.
|
||||||
for (int i=0; i<num_planes; ++i) {
|
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());
|
plane.output(pgraph_cat.debug());
|
||||||
pgraph_cat.debug() << endl;
|
pgraph_cat.debug() << endl;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (int i=1; i<num_planes-1; ++i) {
|
// ViewFrustum -> Logical Planes -> Portal Edge
|
||||||
Planef plane = _hex_frustum->get_plane(i);
|
// Plane0 -> far plane -> None
|
||||||
for (int j=0; j<_num_vert; ++j) {
|
// plane5 -> near plane -> None
|
||||||
float t;
|
// Plane1 -> bottom plane -> 0-1
|
||||||
LPoint3f from_origin = _coords[j];
|
// Plane3 -> top plane -> 1-2
|
||||||
LVector3f from_direction = _coords[(j+1)%_num_vert] - _coords[j];
|
// Plane2 -> right plane -> 2-3
|
||||||
bool is_intersect = plane.intersects_line(t, from_origin, from_direction);
|
// Plane4 -> left plane -> 3-0
|
||||||
if (is_intersect) {
|
|
||||||
pgraph_cat.debug() << "plane " << i << " intersected segement " << j << "->" << (j+1)%_num_vert << " at t=" << t << endl;
|
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;
|
float t;
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
// find intersection of 7->3 with far
|
// 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;
|
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
|
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;
|
intersect_points[0] = from_origin + t*from_direction;
|
||||||
pgraph_cat.debug() << intersect_points[0] << endl;
|
pgraph_cat.spam() << intersect_points[0] << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
visible = false;
|
visible = false;
|
||||||
|
|
||||||
// find intersection of 4->0 with far
|
// 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;
|
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
|
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;
|
intersect_points[1] = from_origin + t*from_direction;
|
||||||
pgraph_cat.debug() << intersect_points[1] << endl;
|
pgraph_cat.spam() << intersect_points[1] << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
visible = false;
|
visible = false;
|
||||||
|
|
||||||
// find intersection of 5->1 with far
|
// 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;
|
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
|
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;
|
intersect_points[2] = from_origin + t*from_direction;
|
||||||
pgraph_cat.debug() << intersect_points[2] << endl;
|
pgraph_cat.spam() << intersect_points[2] << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
visible = false;
|
visible = false;
|
||||||
|
|
||||||
// find intersection of 6->2 with far
|
// 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;
|
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
|
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;
|
intersect_points[3] = from_origin + t*from_direction;
|
||||||
pgraph_cat.debug() << intersect_points[3] << endl;
|
pgraph_cat.spam() << intersect_points[3] << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
visible = false;
|
visible = false;
|
||||||
|
|
||||||
if (!visible) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,14 +559,16 @@ get_reduced_frustum(const NodePath &node_path)
|
|||||||
PT(BoundingVolume) reduced_frustum = new
|
PT(BoundingVolume) reduced_frustum = new
|
||||||
BoundingHexahedron(intersect_points[1], intersect_points[2],
|
BoundingHexahedron(intersect_points[1], intersect_points[2],
|
||||||
intersect_points[3], intersect_points[0],
|
intersect_points[3], intersect_points[0],
|
||||||
_hex_frustum->get_point(4), _hex_frustum->get_point(5),
|
_view_frustum->get_point(4), _view_frustum->get_point(5),
|
||||||
_hex_frustum->get_point(6), _hex_frustum->get_point(7));
|
_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
|
// draw this hexahedron
|
||||||
_color = Colorf(0,0,1,1);
|
_color = Colorf(0,0,1,1);
|
||||||
draw_hexahedron(DCAST(BoundingHexahedron, reduced_frustum));
|
draw_hexahedron(DCAST(BoundingHexahedron, reduced_frustum));
|
||||||
|
|
||||||
|
_reduced_frustum = DCAST(BoundingHexahedron, reduced_frustum);
|
||||||
|
|
||||||
return reduced_frustum;
|
return reduced_frustum;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "geom.h"
|
#include "geom.h"
|
||||||
#include "sceneSetup.h"
|
#include "sceneSetup.h"
|
||||||
#include "renderState.h"
|
#include "renderState.h"
|
||||||
|
#include "portalNode.h"
|
||||||
#include "transformState.h"
|
#include "transformState.h"
|
||||||
#include "geometricBoundingVolume.h"
|
#include "geometricBoundingVolume.h"
|
||||||
#include "boundingHexahedron.h"
|
#include "boundingHexahedron.h"
|
||||||
@ -39,6 +40,7 @@
|
|||||||
#include "geomNode.h"
|
#include "geomNode.h"
|
||||||
|
|
||||||
class PandaNode;
|
class PandaNode;
|
||||||
|
class PortalNode;
|
||||||
class CullHandler;
|
class CullHandler;
|
||||||
class CullTraverserData;
|
class CullTraverserData;
|
||||||
class CullableObject;
|
class CullableObject;
|
||||||
@ -61,7 +63,8 @@ public:
|
|||||||
PortalClipper(GeometricBoundingVolume *frustum, SceneSetup *scene_setup);
|
PortalClipper(GeometricBoundingVolume *frustum, SceneSetup *scene_setup);
|
||||||
~PortalClipper();
|
~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 prepare_portal(const NodePath &node_path);
|
||||||
|
|
||||||
void clip_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 float get_plane_depth(float x, float z, Planef *portal_plane);
|
||||||
|
|
||||||
|
INLINE void set_reduced_frustum(BoundingHexahedron *frustum);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
return _type_handle;
|
return _type_handle;
|
||||||
@ -123,7 +128,10 @@ private:
|
|||||||
PT(GeomPoint) _geom_point;
|
PT(GeomPoint) _geom_point;
|
||||||
PT(GeomLinestrip) _geom_linestrip;
|
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;
|
int _num_vert;
|
||||||
Vertexf _coords[4];
|
Vertexf _coords[4];
|
||||||
|
@ -186,7 +186,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
|||||||
PT(BoundingVolume) reduced_frustum;
|
PT(BoundingVolume) reduced_frustum;
|
||||||
|
|
||||||
portal_viewer->prepare_portal(data._node_path.get_node_path());
|
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()))) {
|
if ((reduced_frustum = portal_viewer->get_reduced_frustum(data._node_path.get_node_path()))) {
|
||||||
// This reduced frustum is in camera space
|
// This reduced frustum is in camera space
|
||||||
pgraph_cat.debug() << "got reduced frustum " << reduced_frustum << endl;
|
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);
|
portal_viewer->_scene_setup->get_cull_center().get_transform(_zone_out);
|
||||||
vf->xform(cull_center_transform->get_mat());
|
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
|
// Get the net trasform of the _zone_out
|
||||||
CPT(TransformState) zone_transform = _zone_out.get_net_transform();
|
CPT(TransformState) zone_transform = _zone_out.get_net_transform();
|
||||||
@ -206,7 +206,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
|||||||
zone_transform,
|
zone_transform,
|
||||||
trav->get_initial_state(), vf,
|
trav->get_initial_state(), vf,
|
||||||
trav->get_guard_band());
|
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
|
// Make this zone show with the reduced frustum
|
||||||
_zone_out.show();
|
_zone_out.show();
|
||||||
trav->traverse(next_data);
|
trav->traverse(next_data);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user