diff --git a/panda/src/pgraph/portalClipper.I b/panda/src/pgraph/portalClipper.I index e46d20e0d6..13b035861f 100755 --- a/panda/src/pgraph/portalClipper.I +++ b/panda/src/pgraph/portalClipper.I @@ -101,16 +101,26 @@ draw_camera_frustum() { } //////////////////////////////////////////////////////////////////// -// Function: PortalClipper::set_view_frustum +// Function: PortalClipper::set_reduced_frustum // Access: Public -// Description: set the current view frustum before traversing +// Description: Set the current view frustum that is being calculated +// by the portal clipper // //////////////////////////////////////////////////////////////////// INLINE void PortalClipper:: -set_view_frustum(BoundingHexahedron *frustum) { - _view_frustum = frustum; +set_reduced_frustum(BoundingHexahedron *frustum) { + _reduced_frustum = frustum; } +//////////////////////////////////////////////////////////////////// +// Function: PortalClipper::get_reduced_frustum +// Access: Published +// Description: Return the reduced frustum +//////////////////////////////////////////////////////////////////// +INLINE BoundingHexahedron *PortalClipper:: +get_reduced_frustum() const { + return _reduced_frustum; +} //////////////////////////////////////////////////////////////////// // Function: PortalClipper::is_facing_view // Access: Public @@ -118,9 +128,8 @@ set_view_frustum(BoundingHexahedron *frustum) { // is facing the camera's near plane //////////////////////////////////////////////////////////////////// INLINE bool PortalClipper:: -is_facing_view(Planef portal_plane) -{ - Planef view_plane(_view_frustum->get_point(4), _view_frustum->get_point(5), _view_frustum->get_point(6)); +is_facing_view(Planef portal_plane) { + 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 pgraph_cat.spam() << portal_plane.get_normal() << "; " << -view_plane.get_normal() << endl; @@ -134,24 +143,21 @@ is_facing_view(Planef portal_plane) // 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 +// is a 2nd level test to weed out most of the portals //////////////////////////////////////////////////////////////////// INLINE bool PortalClipper:: -is_whole_portal_in_view(const NodePath &node_path) { - - const BoundingVolume *bv = &_portal_node->get_bound(); - +is_whole_portal_in_view(LMatrix4f cmat) { // I am about to xform this gbv, so lets make a copy + const BoundingVolume *bv = &_portal_node->get_bound(); 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()); + gbv->xform(cmat); - int result = _view_frustum->contains(gbv); + int result = _reduced_frustum->contains(gbv); - pgraph_cat.spam() << "1st level test if portal: " << *_view_frustum << " is in view " << result << endl; + pgraph_cat.spam() << "1st level test if portal: " << *_reduced_frustum << " is in view " << result << endl; return (result != 0); } @@ -163,14 +169,14 @@ is_whole_portal_in_view(const NodePath &node_path) { // test to make sure this portal is worth visiting //////////////////////////////////////////////////////////////////// INLINE bool PortalClipper:: -is_partial_portal_in_view(const NodePath &node_path) { +is_partial_portal_in_view() { int result = 0; - + // check if any of the _coords in tested frustum for (int j=0; j<_num_vert; ++j) { - result |= _view_frustum->contains(_coords[j]); + result |= _reduced_frustum->contains(_coords[j]); } - pgraph_cat.spam() << "frustum: " << *_view_frustum << " contains(coord) result = " << result << endl; + pgraph_cat.spam() << "frustum: " << *_reduced_frustum << " contains(coord) result = " << result << endl; return (result != 0); } diff --git a/panda/src/pgraph/portalClipper.cxx b/panda/src/pgraph/portalClipper.cxx index b22c2a1a7c..84b09e0ed2 100755 --- a/panda/src/pgraph/portalClipper.cxx +++ b/panda/src/pgraph/portalClipper.cxx @@ -47,7 +47,7 @@ PortalClipper(GeometricBoundingVolume *frustum, SceneSetup *scene_setup) { _geom_point = new GeomPoint; _geom_linestrip = new GeomLinestrip; - _view_frustum = DCAST(BoundingHexahedron, frustum); + _view_frustum = _reduced_frustum = DCAST(BoundingHexahedron, frustum); _scene_setup = scene_setup; } @@ -306,7 +306,7 @@ prepare_portal(const NodePath &node_path) pgraph_cat.spam() << _coords[3] << endl; // check if portal is in view - if (is_whole_portal_in_view(node_path)) { + if (is_whole_portal_in_view(cmat)) { // ok, now lets add the original portal _color = Colorf(0,1,1,1); move_to(temp[0]); @@ -339,23 +339,9 @@ prepare_portal(const NodePath &node_path) void PortalClipper:: clip_portal(const NodePath &node_path) { - int num_planes = _view_frustum->get_num_planes(); - if (!_num_vert) return; - /* - pgraph_cat.debug() << "Number of planes " << num_planes << endl; - - // 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; iget_plane(i); - plane.output(pgraph_cat.debug()); - pgraph_cat.debug() << endl; - } - */ - // ViewFrustum -> Logical Planes -> Portal Edge // Plane0 -> far plane -> None // plane5 -> near plane -> None @@ -374,7 +360,7 @@ clip_portal(const NodePath &node_path) LVector3f from_direction; // Look for intersection with the view frustum's bottom_plane and portal edges - plane = _view_frustum->get_plane(1); + plane = _reduced_frustum->get_plane(1); for (j=0; j<_num_vert; ++j) { from_origin = _coords[j]; from_direction = _coords[(j+1)%_num_vert] - _coords[j]; @@ -397,11 +383,11 @@ clip_portal(const NodePath &node_path) pgraph_cat.debug() << "ignored for now for simplicity \n"; } else - pgraph_cat.debug() << "is_intersect: " << is_intersect << " at t = " << t << endl; + pgraph_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl; } // Look for intersection with the view frustum's top_plane and portal edges - plane = _view_frustum->get_plane(3); + plane = _reduced_frustum->get_plane(3); for (j=0; j<_num_vert; ++j) { from_origin = _coords[j]; from_direction = _coords[(j+1)%_num_vert] - _coords[j]; @@ -424,11 +410,11 @@ clip_portal(const NodePath &node_path) pgraph_cat.debug() << "ignored for now for simplicity \n"; } else - pgraph_cat.debug() << "is_intersect: " << is_intersect << " at t = " << t << endl; + pgraph_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl; } // Look for intersection with the view frustum's right_plane and portal edges - plane = _view_frustum->get_plane(2); + plane = _reduced_frustum->get_plane(2); for (j=0; j<_num_vert; ++j) { from_origin = _coords[j]; from_direction = _coords[(j+1)%_num_vert] - _coords[j]; @@ -451,11 +437,11 @@ clip_portal(const NodePath &node_path) pgraph_cat.debug() << "ignored for now for simplicity \n"; } else - pgraph_cat.debug() << "is_intersect: " << is_intersect << " at t = " << t << endl; + pgraph_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl; } // Look for intersection with the view frustum's left_plane and portal edges - plane = _view_frustum->get_plane(4); + plane = _reduced_frustum->get_plane(4); for (j=0; j<_num_vert; ++j) { from_origin = _coords[j]; from_direction = _coords[(j+1)%_num_vert] - _coords[j]; @@ -478,7 +464,7 @@ clip_portal(const NodePath &node_path) pgraph_cat.debug() << "ignored for now for simplicity \n"; } else - pgraph_cat.debug() << "is_intersect: " << is_intersect << " at t = " << t << endl; + pgraph_cat.spam() << "is_intersect: " << is_intersect << " at t = " << t << endl; } // ok, now lets add the clipped portal _color = Colorf(1,0,0,1); @@ -493,7 +479,7 @@ clip_portal(const NodePath &node_path) if (xect == 0xf) { //if all four planes intersected the portal, it is visible return; } - if (!is_partial_portal_in_view(node_path)) { + if (!is_partial_portal_in_view()) { pgraph_cat.debug() << "portal failed 3rd level test \n"; _num_vert = 0; } @@ -522,10 +508,11 @@ get_reduced_frustum(const NodePath &node_path) float t; bool visible = true; + // find intersection of 7->3 with far - LPoint3f from_origin = _view_frustum->get_point(7); + LPoint3f from_origin = _reduced_frustum->get_point(7); LVector3f from_direction = _coords[3] - from_origin; - bool is_intersect = _view_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 pgraph_cat.spam() << "far plane intersected 7->3 at t=" << t << endl; intersect_points[0] = from_origin + t*from_direction; @@ -535,9 +522,9 @@ get_reduced_frustum(const NodePath &node_path) visible = false; // find intersection of 4->0 with far - from_origin = _view_frustum->get_point(4); + from_origin = _reduced_frustum->get_point(4); from_direction = _coords[0] - from_origin; - is_intersect = _view_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 pgraph_cat.spam() << "far plane intersected 4->0 at t=" << t << endl; intersect_points[1] = from_origin + t*from_direction; @@ -547,9 +534,9 @@ get_reduced_frustum(const NodePath &node_path) visible = false; // find intersection of 5->1 with far - from_origin = _view_frustum->get_point(5); + from_origin = _reduced_frustum->get_point(5); from_direction = _coords[1] - from_origin; - is_intersect = _view_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 pgraph_cat.spam() << "far plane intersected 5->1 at t=" << t << endl; intersect_points[2] = from_origin + t*from_direction; @@ -559,9 +546,9 @@ get_reduced_frustum(const NodePath &node_path) visible = false; // find intersection of 6->2 with far - from_origin = _view_frustum->get_point(6); + from_origin = _reduced_frustum->get_point(6); from_direction = _coords[2] - from_origin; - is_intersect = _view_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 pgraph_cat.spam() << "far plane intersected 6->2 at t=" << t << endl; intersect_points[3] = from_origin + t*from_direction; @@ -579,8 +566,8 @@ 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], - _view_frustum->get_point(4), _view_frustum->get_point(5), - _view_frustum->get_point(6), _view_frustum->get_point(7)); + _reduced_frustum->get_point(4), _reduced_frustum->get_point(5), + _reduced_frustum->get_point(6), _reduced_frustum->get_point(7)); pgraph_cat.debug() << *reduced_frustum << endl; diff --git a/panda/src/pgraph/portalClipper.h b/panda/src/pgraph/portalClipper.h index e38bd6fd35..fb35732c43 100755 --- a/panda/src/pgraph/portalClipper.h +++ b/panda/src/pgraph/portalClipper.h @@ -63,9 +63,9 @@ public: PortalClipper(GeometricBoundingVolume *frustum, SceneSetup *scene_setup); ~PortalClipper(); - INLINE bool is_whole_portal_in_view(const NodePath &node_path); - INLINE bool is_partial_portal_in_view(const NodePath &node_path); + INLINE bool is_partial_portal_in_view(); INLINE bool is_facing_view(Planef portal_plane); + INLINE bool is_whole_portal_in_view(LMatrix4f cmat); void prepare_portal(const NodePath &node_path); void clip_portal(const NodePath &node_path); @@ -83,7 +83,8 @@ public: INLINE float get_plane_depth(float x, float z, Planef *portal_plane); - INLINE void set_view_frustum(BoundingHexahedron *frustum); + INLINE BoundingHexahedron *get_reduced_frustum() const; + INLINE void set_reduced_frustum(BoundingHexahedron *bh); public: static TypeHandle get_class_type() { @@ -129,6 +130,7 @@ private: PT(GeomLinestrip) _geom_linestrip; BoundingHexahedron *_view_frustum; + BoundingHexahedron *_reduced_frustum; PortalNode *_portal_node; // current working portal for dereference ease diff --git a/panda/src/pgraph/portalNode.cxx b/panda/src/pgraph/portalNode.cxx index e0e49ef0e5..527cbc9fff 100755 --- a/panda/src/pgraph/portalNode.cxx +++ b/panda/src/pgraph/portalNode.cxx @@ -63,9 +63,9 @@ PortalNode(const PortalNode ©) : _into_portal_mask(copy._into_portal_mask), _flags(copy._flags) { - _zone_in = NULL; - _zone_out = NULL; - _visible = true; + _zone_in = copy._zone_in; + _zone_out = copy._zone_in; + _visible = copy._visible; } //////////////////////////////////////////////////////////////////// @@ -192,7 +192,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { pgraph_cat.debug() << "got reduced frustum " << reduced_frustum << endl; vf = DCAST(GeometricBoundingVolume, reduced_frustum); - portal_viewer->set_view_frustum(DCAST(BoundingHexahedron,vf->make_copy())); + // keep a copy of this reduced frustum + BoundingHexahedron *new_bh = DCAST(BoundingHexahedron, vf->make_copy()); // trasform it to cull_center space CPT(TransformState) cull_center_transform = @@ -208,12 +209,22 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { zone_transform, trav->get_initial_state(), vf, trav->get_guard_band()); + pgraph_cat.spam() << "cull_callback: traversing " << _zone_out.get_name() << endl; + // Make this zone show with the reduced frustum _zone_out.show(); + + // all nodes visible through this portal, should have this node's frustum + BoundingHexahedron *old_bh = portal_viewer->get_reduced_frustum(); + portal_viewer->set_reduced_frustum(new_bh); trav->traverse(next_data); + // make sure traverser is not drawing this node again _zone_out.hide(); + + // reset portal viewer frustum for the siblings; + portal_viewer->set_reduced_frustum(old_bh); } } // Now carry on to render our child nodes. diff --git a/panda/src/pgraph/portalNode.h b/panda/src/pgraph/portalNode.h index 559a75844b..9055117ae4 100755 --- a/panda/src/pgraph/portalNode.h +++ b/panda/src/pgraph/portalNode.h @@ -77,6 +77,7 @@ PUBLISHED: INLINE void set_visible(bool value); INLINE bool is_visible(); + protected: virtual BoundingVolume *recompute_bound(); virtual BoundingVolume *recompute_internal_bound();