revised portals to accommodate space changes

This commit is contained in:
Asad M. Zaman 2005-09-20 01:27:38 +00:00
parent 1686ae3ff9
commit 8c5c7a6a82
7 changed files with 126 additions and 87 deletions

View File

@ -99,6 +99,7 @@
ConfigureDef(config_pgraph); ConfigureDef(config_pgraph);
NotifyCategoryDef(pgraph, ""); NotifyCategoryDef(pgraph, "");
NotifyCategoryDef(loader, ""); NotifyCategoryDef(loader, "");
NotifyCategoryDef(portal, "");
ConfigureFn(config_pgraph) { ConfigureFn(config_pgraph) {
init_libpgraph(); init_libpgraph();

View File

@ -32,6 +32,7 @@ class DSearchPath;
ConfigureDecl(config_pgraph, EXPCL_PANDA, EXPTP_PANDA); ConfigureDecl(config_pgraph, EXPCL_PANDA, EXPTP_PANDA);
NotifyCategoryDecl(pgraph, EXPCL_PANDA, EXPTP_PANDA); NotifyCategoryDecl(pgraph, EXPCL_PANDA, EXPTP_PANDA);
NotifyCategoryDecl(loader, EXPCL_PANDA, EXPTP_PANDA); NotifyCategoryDecl(loader, EXPCL_PANDA, EXPTP_PANDA);
NotifyCategoryDecl(portal, EXPCL_PANDA, EXPTP_PANDA);
extern ConfigVariableBool fake_view_frustum_cull; extern ConfigVariableBool fake_view_frustum_cull;
extern ConfigVariableBool allow_portal_cull; extern ConfigVariableBool allow_portal_cull;

View File

@ -129,12 +129,14 @@ get_reduced_frustum() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE bool PortalClipper:: INLINE bool PortalClipper::
is_facing_view(Planef portal_plane) { is_facing_view(Planef portal_plane) {
Planef view_plane(_reduced_frustum->get_point(4), _reduced_frustum->get_point(5), _reduced_frustum->get_point(6)); // Planef view_plane(_reduced_frustum->get_point(4), _reduced_frustum->get_point(5), _reduced_frustum->get_point(6));
// use the view_frustum's near plane to calculate direction // use the view_frustum's near plane to calculate direction
pgraph_cat.spam() << portal_plane.get_normal() << "; " << -view_plane.get_normal() << endl; //portal_cat.spam() << portal_plane.get_normal() << "; " << -view_plane.get_normal() << endl;
float direction = portal_plane.get_normal().dot(-view_plane.get_normal()); //float direction = portal_plane.get_normal().dot(-view_plane.get_normal());
pgraph_cat.spam() << "Found direction of " << direction << endl; portal_cat.spam() << portal_plane.get_normal() << "; " << Normalf::forward() << endl;
float direction = portal_plane.get_normal().dot(Normalf::forward());
portal_cat.spam() << "Found direction of " << direction << endl;
return (direction < _FACING_THRESHOLD); return (direction < _FACING_THRESHOLD);
} }
@ -157,7 +159,7 @@ is_whole_portal_in_view(LMatrix4f cmat) {
int result = _reduced_frustum->contains(gbv); int result = _reduced_frustum->contains(gbv);
pgraph_cat.spam() << "1st level test if portal: " << *_reduced_frustum << " is in view " << result << endl; portal_cat.spam() << "1st level test if portal: " << *_reduced_frustum << " is in view " << result << endl;
return (result != 0); return (result != 0);
} }
@ -176,7 +178,7 @@ is_partial_portal_in_view() {
for (int j=0; j<_num_vert; ++j) { for (int j=0; j<_num_vert; ++j) {
result |= _reduced_frustum->contains(_coords[j]); result |= _reduced_frustum->contains(_coords[j]);
} }
pgraph_cat.spam() << "frustum: " << *_reduced_frustum << " contains(coord) result = " << result << endl; portal_cat.spam() << "frustum: " << *_reduced_frustum << " contains(coord) result = " << result << endl;
return (result != 0); return (result != 0);
} }
@ -191,8 +193,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.spam() << *portal_plane << endl; portal_cat.spam() << *portal_plane << endl;
pgraph_cat.spam() << portal_plane->_v.v._0 << " " << portal_plane->_v.v._1 << " " portal_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) {

View File

@ -235,20 +235,20 @@ prepare_portal(const NodePath &node_path)
_num_vert = 0; _num_vert = 0;
// Get the geometry from the portal // Get the geometry from the portal
pgraph_cat.spam() << *_portal_node << endl; portal_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.spam() << wmat << endl; portal_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.spam() << cmat << endl; portal_cat.spam() << cmat << endl;
Vertexf temp[4]; Vertexf temp[4];
temp[0] = _portal_node->get_vertex(0); temp[0] = _portal_node->get_vertex(0);
@ -256,11 +256,11 @@ prepare_portal(const NodePath &node_path)
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.spam() << "before transformation to camera space" << endl; portal_cat.spam() << "before transformation to camera space" << endl;
pgraph_cat.spam() << temp[0] << endl; portal_cat.spam() << temp[0] << endl;
pgraph_cat.spam() << temp[1] << endl; portal_cat.spam() << temp[1] << endl;
pgraph_cat.spam() << temp[2] << endl; portal_cat.spam() << temp[2] << endl;
pgraph_cat.spam() << temp[3] << endl; portal_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;
@ -269,15 +269,15 @@ prepare_portal(const NodePath &node_path)
Planef portal_plane(temp[0], temp[1], temp[2]); Planef portal_plane(temp[0], temp[1], temp[2]);
if (!is_facing_view(portal_plane)) { if (!is_facing_view(portal_plane)) {
pgraph_cat.debug() << "portal failed 1st level test \n"; portal_cat.debug() << "portal failed 1st level test \n";
return; return;
} }
pgraph_cat.spam() << "after transformation to camera space" << endl; portal_cat.spam() << "after transformation to camera space" << endl;
pgraph_cat.spam() << temp[0] << endl; portal_cat.spam() << temp[0] << endl;
pgraph_cat.spam() << temp[1] << endl; portal_cat.spam() << temp[1] << endl;
pgraph_cat.spam() << temp[2] << endl; portal_cat.spam() << temp[2] << endl;
pgraph_cat.spam() << temp[3] << endl; portal_cat.spam() << temp[3] << endl;
float min_x, max_x, min_z, max_z; float min_x, max_x, min_z, max_z;
@ -286,31 +286,31 @@ 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.spam() << "min_x " << min_x << ";max_x " << max_x << ";min_z " << min_z << ";max_z " << max_z << endl; portal_cat.spam() << "min_x " << min_x << ";max_x " << max_x << ";min_z " << min_z << ";max_z " << max_z << endl;
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.spam() << "plane's depth is " << y << endl; portal_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.spam() << "plane's depth is " << y << endl; portal_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.spam() << "plane's depth is " << y << endl; portal_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.spam() << "plane's depth is " << y << endl; portal_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.spam() << "after min max calculation" << endl; portal_cat.spam() << "after min max calculation" << endl;
pgraph_cat.spam() << _coords[0] << endl; portal_cat.spam() << _coords[0] << endl;
pgraph_cat.spam() << _coords[1] << endl; portal_cat.spam() << _coords[1] << endl;
pgraph_cat.spam() << _coords[2] << endl; portal_cat.spam() << _coords[2] << endl;
pgraph_cat.spam() << _coords[3] << endl; portal_cat.spam() << _coords[3] << endl;
// check if portal is in view // check if portal is in view
if (is_whole_portal_in_view(cmat)) { if (is_whole_portal_in_view(cmat)) {
@ -330,11 +330,11 @@ prepare_portal(const NodePath &node_path)
draw_to(_coords[3]); draw_to(_coords[3]);
draw_to(_coords[0]); draw_to(_coords[0]);
pgraph_cat.spam() << "assembled " << _portal_node->get_name() << ": frustum points" << endl; portal_cat.spam() << "assembled " << _portal_node->get_name() << ": frustum points" << endl;
_num_vert = _portal_node->get_num_vertices(); _num_vert = _portal_node->get_num_vertices();
} }
else else
pgraph_cat.debug() << "portal failed 2nd level test \n"; portal_cat.debug() << "portal failed 2nd level test \n";
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -374,10 +374,10 @@ clip_portal(const NodePath &node_path)
is_intersect = plane.intersects_line(t, from_origin, from_direction); is_intersect = plane.intersects_line(t, from_origin, from_direction);
if (is_intersect && (t >= 0.0 && t <= 1.0)) { if (is_intersect && (t >= 0.0 && t <= 1.0)) {
xect |= 1 << 0; xect |= 1 << 0;
pgraph_cat.debug() << "bottom plane intersected segment " << j << "->" portal_cat.debug() << "bottom plane intersected segment " << j << "->"
<< (j+1)%_num_vert << " at t=" << t << endl; << (j+1)%_num_vert << " at t=" << t << endl;
cut_point = from_origin + t*from_direction; cut_point = from_origin + t*from_direction;
pgraph_cat.spam() << "cut_point: " << cut_point << endl; portal_cat.spam() << "cut_point: " << cut_point << endl;
if (j == 1) { if (j == 1) {
// means bottom should cut 1->2 by moving 1 to the intersection point // means bottom should cut 1->2 by moving 1 to the intersection point
_coords[1] = cut_point; _coords[1] = cut_point;
@ -387,10 +387,10 @@ clip_portal(const NodePath &node_path)
_coords[0] = cut_point; _coords[0] = cut_point;
} }
else else
pgraph_cat.debug() << "ignored for now for simplicity \n"; portal_cat.debug() << "ignored for now for simplicity \n";
} }
else else
pgraph_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl; portal_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl;
} }
// Look for intersection with the view frustum's top_plane and portal edges // Look for intersection with the view frustum's top_plane and portal edges
@ -401,10 +401,10 @@ clip_portal(const NodePath &node_path)
is_intersect = plane.intersects_line(t, from_origin, from_direction); is_intersect = plane.intersects_line(t, from_origin, from_direction);
if (is_intersect && (t >= 0.0 && t <= 1.0)) { if (is_intersect && (t >= 0.0 && t <= 1.0)) {
xect |= 1 << 1; xect |= 1 << 1;
pgraph_cat.debug() << "top plane intersected segment " << j << "->" portal_cat.debug() << "top plane intersected segment " << j << "->"
<< (j+1)%_num_vert << " at t=" << t << endl; << (j+1)%_num_vert << " at t=" << t << endl;
cut_point = from_origin + t*from_direction; cut_point = from_origin + t*from_direction;
pgraph_cat.spam() << "cut_point: " << cut_point << endl; portal_cat.spam() << "cut_point: " << cut_point << endl;
if (j == 1) { if (j == 1) {
// means top should cut 1->2 by moving 2 to the intersection point // means top should cut 1->2 by moving 2 to the intersection point
_coords[2] = cut_point; _coords[2] = cut_point;
@ -414,10 +414,10 @@ clip_portal(const NodePath &node_path)
_coords[3] = cut_point; _coords[3] = cut_point;
} }
else else
pgraph_cat.debug() << "ignored for now for simplicity \n"; portal_cat.debug() << "ignored for now for simplicity \n";
} }
else else
pgraph_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl; portal_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl;
} }
// Look for intersection with the view frustum's right_plane and portal edges // Look for intersection with the view frustum's right_plane and portal edges
@ -428,10 +428,10 @@ clip_portal(const NodePath &node_path)
is_intersect = plane.intersects_line(t, from_origin, from_direction); is_intersect = plane.intersects_line(t, from_origin, from_direction);
if (is_intersect && (t >= 0.0 && t <= 1.0)) { if (is_intersect && (t >= 0.0 && t <= 1.0)) {
xect |= 1 << 2; xect |= 1 << 2;
pgraph_cat.debug() << "right plane intersected segment " << j << "->" portal_cat.debug() << "right plane intersected segment " << j << "->"
<< (j+1)%_num_vert << " at t=" << t << endl; << (j+1)%_num_vert << " at t=" << t << endl;
cut_point = from_origin + t*from_direction; cut_point = from_origin + t*from_direction;
pgraph_cat.spam() << "cut_point: " << cut_point << endl; portal_cat.spam() << "cut_point: " << cut_point << endl;
if (j == 0) { if (j == 0) {
// means right should cut 0->1 by moving 1 to the intersection point // means right should cut 0->1 by moving 1 to the intersection point
_coords[1] = cut_point; _coords[1] = cut_point;
@ -441,10 +441,10 @@ clip_portal(const NodePath &node_path)
_coords[2] = cut_point; _coords[2] = cut_point;
} }
else else
pgraph_cat.debug() << "ignored for now for simplicity \n"; portal_cat.debug() << "ignored for now for simplicity \n";
} }
else else
pgraph_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl; portal_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl;
} }
// Look for intersection with the view frustum's left_plane and portal edges // Look for intersection with the view frustum's left_plane and portal edges
@ -455,10 +455,10 @@ clip_portal(const NodePath &node_path)
is_intersect = plane.intersects_line(t, from_origin, from_direction); is_intersect = plane.intersects_line(t, from_origin, from_direction);
if (is_intersect && (t >= 0.0 && t <= 1.0)) { if (is_intersect && (t >= 0.0 && t <= 1.0)) {
xect |= 1 << 3; xect |= 1 << 3;
pgraph_cat.debug() << "left plane intersected segment " << j << "->" portal_cat.debug() << "left plane intersected segment " << j << "->"
<< (j+1)%_num_vert << " at t=" << t << endl; << (j+1)%_num_vert << " at t=" << t << endl;
cut_point = from_origin + t*from_direction; cut_point = from_origin + t*from_direction;
pgraph_cat.spam() << "cut_point: " << cut_point << endl; portal_cat.spam() << "cut_point: " << cut_point << endl;
if (j == 0) { if (j == 0) {
// means left should cut 0->1 by moving 0 to the intersection point // means left should cut 0->1 by moving 0 to the intersection point
_coords[0] = cut_point; _coords[0] = cut_point;
@ -468,10 +468,10 @@ clip_portal(const NodePath &node_path)
_coords[3] = cut_point; _coords[3] = cut_point;
} }
else else
pgraph_cat.debug() << "ignored for now for simplicity \n"; portal_cat.debug() << "ignored for now for simplicity \n";
} }
else else
pgraph_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl; portal_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl;
} }
// ok, now lets add the clipped portal // ok, now lets add the clipped portal
_color = Colorf(1,0,0,1); _color = Colorf(1,0,0,1);
@ -482,12 +482,12 @@ clip_portal(const NodePath &node_path)
draw_to(_coords[0]); draw_to(_coords[0]);
// 3rd level test, more accurate to determine if the portal is worth visiting // 3rd level test, more accurate to determine if the portal is worth visiting
pgraph_cat.debug() << "portal clipper flag: " << xect << endl; portal_cat.debug() << "portal clipper flag: " << xect << endl;
if (xect == 0xf) { //if all four planes intersected the portal, it is visible if (xect == 0xf) { //if all four planes intersected the portal, it is visible
return; return;
} }
if (!is_partial_portal_in_view()) { if (!is_partial_portal_in_view()) {
pgraph_cat.debug() << "portal failed 3rd level test \n"; portal_cat.debug() << "portal failed 3rd level test \n";
_num_vert = 0; _num_vert = 0;
} }
} }
@ -521,9 +521,9 @@ get_reduced_frustum(const NodePath &node_path)
LVector3f from_direction = _coords[3] - from_origin; LVector3f from_direction = _coords[3] - from_origin;
bool is_intersect = _reduced_frustum->get_plane(0).intersects_line(t, from_origin, from_direction); bool is_intersect = _reduced_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.spam() << "far plane intersected 7->3 at t=" << t << endl; portal_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.spam() << intersect_points[0] << endl; portal_cat.spam() << intersect_points[0] << endl;
} }
else else
visible = false; visible = false;
@ -533,9 +533,9 @@ get_reduced_frustum(const NodePath &node_path)
from_direction = _coords[0] - from_origin; from_direction = _coords[0] - from_origin;
is_intersect = _reduced_frustum->get_plane(0).intersects_line(t, from_origin, from_direction); is_intersect = _reduced_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.spam() << "far plane intersected 4->0 at t=" << t << endl; portal_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.spam() << intersect_points[1] << endl; portal_cat.spam() << intersect_points[1] << endl;
} }
else else
visible = false; visible = false;
@ -545,9 +545,9 @@ get_reduced_frustum(const NodePath &node_path)
from_direction = _coords[1] - from_origin; from_direction = _coords[1] - from_origin;
is_intersect = _reduced_frustum->get_plane(0).intersects_line(t, from_origin, from_direction); is_intersect = _reduced_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.spam() << "far plane intersected 5->1 at t=" << t << endl; portal_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.spam() << intersect_points[2] << endl; portal_cat.spam() << intersect_points[2] << endl;
} }
else else
visible = false; visible = false;
@ -557,15 +557,15 @@ get_reduced_frustum(const NodePath &node_path)
from_direction = _coords[2] - from_origin; from_direction = _coords[2] - from_origin;
is_intersect = _reduced_frustum->get_plane(0).intersects_line(t, from_origin, from_direction); is_intersect = _reduced_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.spam() << "far plane intersected 6->2 at t=" << t << endl; portal_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.spam() << intersect_points[3] << endl; portal_cat.spam() << intersect_points[3] << endl;
} }
else else
visible = false; visible = false;
if (!visible) { if (!visible) {
pgraph_cat.spam() << "portal is not visible from current camera look at" << endl; portal_cat.spam() << "portal is not visible from current camera look at" << endl;
return NULL; return NULL;
} }
@ -576,7 +576,7 @@ get_reduced_frustum(const NodePath &node_path)
_reduced_frustum->get_point(4), _reduced_frustum->get_point(5), _reduced_frustum->get_point(4), _reduced_frustum->get_point(5),
_reduced_frustum->get_point(6), _reduced_frustum->get_point(7)); _reduced_frustum->get_point(6), _reduced_frustum->get_point(7));
pgraph_cat.debug() << *reduced_frustum << endl; portal_cat.debug() << *reduced_frustum << endl;
// draw this hexahedron // draw this hexahedron
_color = Colorf(0,0,1,1); _color = Colorf(0,0,1,1);

View File

@ -206,7 +206,7 @@ INLINE NodePath PortalNode::get_cell_out() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PortalNode::set_visible // Function: PortalNode::set_visible
// Access: Published // Access: Published
// Description: Python sets this based on curent camera zone // Description: this is set if the portal is facing camera
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void PortalNode::set_visible(bool value) { INLINE void PortalNode::set_visible(bool value) {
_visible = value; _visible = value;
@ -215,8 +215,26 @@ INLINE void PortalNode::set_visible(bool value) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: PortalNode::is_visible // Function: PortalNode::is_visible
// Access: Published // Access: Published
// Description: Is this portal visible from current camera zone // Description: Is this portal facing the camera
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE bool PortalNode::is_visible() { INLINE bool PortalNode::is_visible() {
return _visible; return _visible;
} }
////////////////////////////////////////////////////////////////////
// Function: PortalNode::set_open
// Access: Published
// Description: Python sets this based on curent camera zone
////////////////////////////////////////////////////////////////////
INLINE void PortalNode::set_open(bool value) {
_open = value;
}
////////////////////////////////////////////////////////////////////
// Function: PortalNode::is_open
// Access: Published
// Description: Is this portal open from current camera zone
////////////////////////////////////////////////////////////////////
INLINE bool PortalNode::is_open() {
return _open;
}

View File

@ -49,7 +49,8 @@ PortalNode(const string &name) :
_into_portal_mask(PortalMask::all_on()), _into_portal_mask(PortalMask::all_on()),
_flags(0) _flags(0)
{ {
_visible = true; _visible = false;
_open = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -70,7 +71,8 @@ PortalNode(const string &name, LPoint3f pos, float scale) :
add_vertex(LPoint3f(pos[0]+1.0*scale, pos[1], pos[2]+1.0*scale)); add_vertex(LPoint3f(pos[0]+1.0*scale, pos[1], pos[2]+1.0*scale));
add_vertex(LPoint3f(pos[0]-1.0*scale, pos[1], pos[2]+1.0*scale)); add_vertex(LPoint3f(pos[0]-1.0*scale, pos[1], pos[2]+1.0*scale));
_visible = true; _visible = false;
_open = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -87,7 +89,8 @@ PortalNode(const PortalNode &copy) :
_vertices(copy._vertices), _vertices(copy._vertices),
_cell_in(copy._cell_in), _cell_in(copy._cell_in),
_cell_out(copy._cell_out), _cell_out(copy._cell_out),
_visible(copy._visible) _visible(copy._visible),
_open(copy._open)
{ {
} }
@ -201,9 +204,10 @@ has_cull_callback() const {
bool PortalNode:: bool PortalNode::
cull_callback(CullTraverser *trav, CullTraverserData &data) { cull_callback(CullTraverser *trav, CullTraverserData &data) {
PortalClipper *portal_viewer = trav->get_portal_clipper(); PortalClipper *portal_viewer = trav->get_portal_clipper();
if (is_visible() && !_cell_out.is_empty() && portal_viewer) { set_visible(false);
if (is_open() && !_cell_out.is_empty() && portal_viewer) {
//CullTraverserData next_data(data, _cell_out); //CullTraverserData next_data(data, _cell_out);
pgraph_cat.debug() << "checking portal node " << *this << endl; portal_cat.debug() << "checking portal node " << *this << endl;
PT(GeometricBoundingVolume) vf = trav->get_view_frustum(); PT(GeometricBoundingVolume) vf = trav->get_view_frustum();
PT(BoundingVolume) reduced_frustum; PT(BoundingVolume) reduced_frustum;
@ -211,40 +215,49 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
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()))) {
set_visible(true);
// This reduced frustum is in camera space // This reduced frustum is in camera space
pgraph_cat.debug() << "got reduced frustum " << reduced_frustum << endl; portal_cat.debug() << "got reduced frustum " << reduced_frustum << endl;
vf = DCAST(GeometricBoundingVolume, reduced_frustum); vf = DCAST(GeometricBoundingVolume, reduced_frustum);
// keep a copy of this reduced frustum // keep a copy of this reduced frustum
BoundingHexahedron *new_bh = DCAST(BoundingHexahedron, vf->make_copy()); PT(BoundingHexahedron) new_bh = DCAST(BoundingHexahedron, vf->make_copy());
// trasform it to cull_center space // trasform it to cull_center space
CPT(TransformState) cull_center_transform = // CPT(TransformState) cull_center_transform =
portal_viewer->_scene_setup->get_cull_center().get_transform(_cell_out); //portal_viewer->_scene_setup->get_cull_center().get_transform(_cell_out);
vf->xform(cull_center_transform->get_mat());
pgraph_cat.spam() << "vf is " << *vf << "\n"; /*
CPT(TransformState) transform = portal_viewer->_scene_setup->get_cull_center().get_net_transform();
CPT(TransformState) portal_transform =
data._modelview_transform->compose(transform);
*/
// Get the net trasform of the _cell_out // Get the net trasform of the _cell_out as seen from the camera.
CPT(TransformState) cell_transform = _cell_out.get_net_transform(); CPT(TransformState) cell_transform =
trav->get_camera_transform()->invert_compose(_cell_out.get_net_transform());
CPT(TransformState) frustum_transform =
_cell_out.get_net_transform()->invert_compose(portal_viewer->_scene_setup->get_cull_center().get_net_transform());
new_bh->xform(frustum_transform->get_mat());
portal_cat.spam() << "new_bh is " << *new_bh << "\n";
CullTraverserData next_data(_cell_out, CullTraverserData next_data(_cell_out,
cell_transform, cell_transform,
trav->get_initial_state(), vf, data._state, new_bh, NULL);
trav->get_guard_band());
pgraph_cat.spam() << "cull_callback: traversing " << _cell_out.get_name() << endl;
// Make this cell show with the reduced frustum // Make this cell show with the reduced frustum
_cell_out.show(); // _cell_out.show();
// all nodes visible through this portal, should have this node's frustum // all nodes visible through this portal, should have this node's frustum
BoundingHexahedron *old_bh = portal_viewer->get_reduced_frustum(); PT(BoundingHexahedron) old_bh = portal_viewer->get_reduced_frustum();
portal_viewer->set_reduced_frustum(new_bh); portal_viewer->set_reduced_frustum(new_bh);
portal_cat.spam() << "cull_callback: before traversing " << _cell_out.get_name() << endl;
trav->traverse(next_data); trav->traverse(next_data);
portal_cat.spam() << "cull_callback: after traversing " << _cell_out.get_name() << endl;
// make sure traverser is not drawing this node again // make sure traverser is not drawing this node again
_cell_out.hide(); // _cell_out.hide();
// reset portal viewer frustum for the siblings; // reset portal viewer frustum for the siblings;
portal_viewer->set_reduced_frustum(old_bh); portal_viewer->set_reduced_frustum(old_bh);

View File

@ -79,6 +79,9 @@ PUBLISHED:
INLINE void set_visible(bool value); INLINE void set_visible(bool value);
INLINE bool is_visible(); INLINE bool is_visible();
INLINE void set_open(bool value);
INLINE bool is_open();
// void draw () const; // void draw () const;
protected: protected:
@ -107,6 +110,7 @@ private:
NodePath _cell_out; // This is the cell it leads out to NodePath _cell_out; // This is the cell it leads out to
bool _visible; bool _visible;
bool _open;
public: public:
static void register_with_read_factory(); static void register_with_read_factory();