diff --git a/panda/src/pgraph/cullTraverser.I b/panda/src/pgraph/cullTraverser.I index fbeba01c05..c1b0a757bd 100644 --- a/panda/src/pgraph/cullTraverser.I +++ b/panda/src/pgraph/cullTraverser.I @@ -234,3 +234,24 @@ INLINE CullHandler *CullTraverser:: get_cull_handler() const { return _cull_handler; } +//////////////////////////////////////////////////////////////////// +// Function: CullTraverser::set_portal_clipper +// Access: Public +// Description: Specifies _portal_clipper object pointer that +// subsequent traverse() or traverse_below may use. +//////////////////////////////////////////////////////////////////// +INLINE void CullTraverser:: +set_portal_clipper(PortalClipper *portal_clipper) { + _portal_clipper = portal_clipper; +} + +//////////////////////////////////////////////////////////////////// +// Function: CullTraverser::get_portal_clipper +// Access: Public +// Description: Returns the _portal_clipper pointer +//////////////////////////////////////////////////////////////////// + +INLINE PortalClipper *CullTraverser:: +get_portal_clipper() const { + return _portal_clipper; +} diff --git a/panda/src/pgraph/cullTraverser.cxx b/panda/src/pgraph/cullTraverser.cxx index 7296aa640f..236f5a2370 100644 --- a/panda/src/pgraph/cullTraverser.cxx +++ b/panda/src/pgraph/cullTraverser.cxx @@ -48,6 +48,7 @@ CullTraverser() { _initial_state = RenderState::make_empty(); _depth_offset_decals = false; _cull_handler = (CullHandler *)NULL; + _portal_clipper = (PortalClipper *)NULL; } //////////////////////////////////////////////////////////////////// @@ -63,7 +64,8 @@ CullTraverser(const CullTraverser ©) : _depth_offset_decals(copy._depth_offset_decals), _view_frustum(copy._view_frustum), _guard_band(copy._guard_band), - _cull_handler(copy._cull_handler) + _cull_handler(copy._cull_handler), + _portal_clipper(copy._portal_clipper) { } @@ -94,32 +96,16 @@ traverse(const NodePath &root, bool python_cull_control) { // This local_frustum is in camera space PortalClipper portal_viewer(local_frustum, _scene_setup); portal_viewer.draw_camera_frustum(); - -#if 0 - PT(BoundingVolume) reduced_frustum; - - // right now it is returning only one reduced frustum - portal_viewer.prepare_portal(); - //portal_viewer.clip_portal(portal_idx); - if ((reduced_frustum = portal_viewer.get_reduced_frustum())) { - // This reduced frustum is in camera space - pgraph_cat.debug() << "got reduced frustum " << reduced_frustum << endl; - vf = DCAST(GeometricBoundingVolume, reduced_frustum); - - // trasform it to cull_center space - CPT(TransformState) cull_center_transform = - _scene_setup->get_cull_center().get_transform(_scene_setup->get_scene_root()); - vf->xform(cull_center_transform->get_mat()); - } - pgraph_cat.debug() << "vf is " << *vf << "\n"; -#endif + // store this pointer in this + set_portal_clipper(&portal_viewer); + CullTraverserData data(root, get_render_transform(), TransformState::make_identity(), _initial_state, _view_frustum, - vf, _guard_band); + _guard_band); - traverse(data, &portal_viewer); + traverse(data); // finally add the lines to be drawn portal_viewer.draw_lines(); @@ -131,14 +117,13 @@ traverse(const NodePath &root, bool python_cull_control) { CullTraverserData my_data(data, portal_viewer._previous); my_data._render_transform = my_data._render_transform->compose(transform); traverse(my_data); - pgraph_cat.debug() << "finished portal culling\n"; - pgraph_cat.debug() << "**********end*********\n"; + pgraph_cat.debug() << "******finished portal culling*********\n"; } else { CullTraverserData data(root, get_render_transform(), TransformState::make_identity(), _initial_state, _view_frustum, - NULL, _guard_band); + _guard_band); traverse(data); } @@ -152,7 +137,7 @@ traverse(const NodePath &root, bool python_cull_control) { // has not yet been converted into the node's space. //////////////////////////////////////////////////////////////////// void CullTraverser:: -traverse(CullTraverserData &data, PortalClipper *portal_viewer) { +traverse(CullTraverserData &data) { // Most nodes will have no transform or state, and will not // contain decals or require a special cull callback. As an // optimization, we should tag nodes with these properties as @@ -162,50 +147,6 @@ traverse(CullTraverserData &data, PortalClipper *portal_viewer) { PandaNode *node = data.node(); pgraph_cat.spam() << "\n" << data._node_path << "\n"; -#if 0 - // let me see the names, curious - unsigned int loc = node->get_name().find("pTypeArchway"); - if (loc != string::npos) { - node->output(pgraph_cat.spam()); - pgraph_cat.spam() << endl; - if (data._reduced_frustum) { - pgraph_cat.debug() << "setting reduced frustum to this node\n"; - - if (data._view_frustum) { - pgraph_cat.spam() << *data._view_frustum << endl; - } - pgraph_cat.spam() << *data._reduced_frustum << endl; - - data._view_frustum = data._reduced_frustum; - data._reduced_frustum = NULL; - } - } -#else - if (node->is_of_type(PortalNode::get_class_type())) { - PortalNode *portal_node = DCAST(PortalNode, node); - if (portal_node->is_visible()) { - pgraph_cat.debug() << "portal node visible " << *portal_node << endl; - PT(GeometricBoundingVolume) vf = _view_frustum; - PT(BoundingVolume) reduced_frustum; - - // right now it is returning only one reduced frustum - portal_viewer->prepare_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; - vf = DCAST(GeometricBoundingVolume, reduced_frustum); - - // trasform it to cull_center space - CPT(TransformState) cull_center_transform = - _scene_setup->get_cull_center().get_transform(_scene_setup->get_scene_root()); - vf->xform(cull_center_transform->get_mat()); - } - pgraph_cat.debug() << "vf is " << *vf << "\n"; - } - } -#endif - const RenderEffects *node_effects = node->get_effects(); if (node_effects->has_show_bounds()) { // If we should show the bounding volume for this node, make it @@ -231,7 +172,7 @@ traverse(CullTraverserData &data, PortalClipper *portal_viewer) { } } - traverse_below(data, portal_viewer); + traverse_below(data); } } @@ -243,7 +184,7 @@ traverse(CullTraverserData &data, PortalClipper *portal_viewer) { // node's space. //////////////////////////////////////////////////////////////////// void CullTraverser:: -traverse_below(CullTraverserData &data, PortalClipper *portal_viewer) { +traverse_below(CullTraverserData &data) { _nodes_pcollector.add_level(1); PandaNode *node = data.node(); @@ -290,14 +231,14 @@ traverse_below(CullTraverserData &data, PortalClipper *portal_viewer) { int i = node->get_first_visible_child(); while (i < num_children) { CullTraverserData next_data(data, node->get_child(i)); - traverse(next_data, portal_viewer); + traverse(next_data); i = node->get_next_visible_child(i); } } else { for (int i = 0; i < num_children; i++) { CullTraverserData next_data(data, node->get_child(i)); - traverse(next_data, portal_viewer); + traverse(next_data); } } } diff --git a/panda/src/pgraph/cullTraverser.h b/panda/src/pgraph/cullTraverser.h index fcfc0b68e0..bcabc0757b 100644 --- a/panda/src/pgraph/cullTraverser.h +++ b/panda/src/pgraph/cullTraverser.h @@ -75,9 +75,12 @@ public: INLINE void set_cull_handler(CullHandler *cull_handler); INLINE CullHandler *get_cull_handler() const; + INLINE void set_portal_clipper(PortalClipper *portal_clipper); + INLINE PortalClipper *get_portal_clipper() const; + void traverse(const NodePath &root, bool python_cull_control=false); - void traverse(CullTraverserData &data, PortalClipper *portal_viewer=NULL); - void traverse_below(CullTraverserData &data, PortalClipper *portal_viewer=NULL); + void traverse(CullTraverserData &data); + void traverse_below(CullTraverserData &data); public: // Statistics @@ -101,6 +104,7 @@ private: PT(GeometricBoundingVolume) _view_frustum; PT(GeometricBoundingVolume) _guard_band; CullHandler *_cull_handler; + PortalClipper *_portal_clipper; public: static TypeHandle get_class_type() { diff --git a/panda/src/pgraph/cullTraverserData.I b/panda/src/pgraph/cullTraverserData.I index 063ef9e634..289a01baf2 100644 --- a/panda/src/pgraph/cullTraverserData.I +++ b/panda/src/pgraph/cullTraverserData.I @@ -27,14 +27,12 @@ CullTraverserData(const NodePath &start, const TransformState *net_transform, const RenderState *state, GeometricBoundingVolume *view_frustum, - GeometricBoundingVolume *reduced_frustum, GeometricBoundingVolume *guard_band) : _node_path(start), _render_transform(render_transform), _net_transform(net_transform), _state(state), _view_frustum(view_frustum), - _reduced_frustum(reduced_frustum), _guard_band(guard_band) { } @@ -51,7 +49,6 @@ CullTraverserData(const CullTraverserData ©) : _net_transform(copy._net_transform), _state(copy._state), _view_frustum(copy._view_frustum), - _reduced_frustum(copy._reduced_frustum), _guard_band(copy._guard_band) { } @@ -68,7 +65,6 @@ operator = (const CullTraverserData ©) { _net_transform = copy._net_transform; _state = copy._state; _view_frustum = copy._view_frustum; - _reduced_frustum = copy._reduced_frustum; _guard_band = copy._guard_band; } @@ -85,7 +81,6 @@ CullTraverserData(const CullTraverserData &parent, PandaNode *child) : _net_transform(parent._net_transform), _state(parent._state), _view_frustum(parent._view_frustum), - _reduced_frustum(parent._reduced_frustum), _guard_band(parent._guard_band) { } diff --git a/panda/src/pgraph/cullTraverserData.cxx b/panda/src/pgraph/cullTraverserData.cxx index 243c5c51b0..6ae3029aab 100644 --- a/panda/src/pgraph/cullTraverserData.cxx +++ b/panda/src/pgraph/cullTraverserData.cxx @@ -62,7 +62,6 @@ apply_transform_and_state(CullTraverser *trav, _render_transform = _render_transform->compose(node_transform); if ((_view_frustum != (GeometricBoundingVolume *)NULL) || - (_reduced_frustum != (GeometricBoundingVolume *)NULL) || (_guard_band != (GeometricBoundingVolume *)NULL)) { // We need to move the viewing frustums into the node's // coordinate space by applying the node's inverse transform. @@ -71,7 +70,6 @@ apply_transform_and_state(CullTraverser *trav, // trying, we'll just give up on frustum culling from this // point down. _view_frustum = (GeometricBoundingVolume *)NULL; - _reduced_frustum = (GeometricBoundingVolume *)NULL; _guard_band = (GeometricBoundingVolume *)NULL; } else { @@ -85,11 +83,6 @@ apply_transform_and_state(CullTraverser *trav, _view_frustum->xform(inv_transform->get_mat()); } - if (_reduced_frustum != (GeometricBoundingVolume *)NULL) { - _reduced_frustum = DCAST(GeometricBoundingVolume, _reduced_frustum->make_copy()); - _reduced_frustum->xform(inv_transform->get_mat()); - } - if (_guard_band != (GeometricBoundingVolume *)NULL) { _guard_band = DCAST(GeometricBoundingVolume, _guard_band->make_copy()); _guard_band->xform(inv_transform->get_mat()); diff --git a/panda/src/pgraph/cullTraverserData.h b/panda/src/pgraph/cullTraverserData.h index 3dc245bb90..32f318bb89 100644 --- a/panda/src/pgraph/cullTraverserData.h +++ b/panda/src/pgraph/cullTraverserData.h @@ -52,7 +52,6 @@ public: const TransformState *net_transform, const RenderState *state, GeometricBoundingVolume *view_frustum, - GeometricBoundingVolume *reduced_frustum, GeometricBoundingVolume *guard_band); INLINE CullTraverserData(const CullTraverserData ©); INLINE void operator = (const CullTraverserData ©); @@ -74,7 +73,6 @@ public: CPT(TransformState) _net_transform; CPT(RenderState) _state; PT(GeometricBoundingVolume) _view_frustum; - PT(GeometricBoundingVolume) _reduced_frustum; PT(GeometricBoundingVolume) _guard_band; private: diff --git a/panda/src/pgraph/portalClipper.I b/panda/src/pgraph/portalClipper.I index 90e6422a42..3481fffbda 100755 --- a/panda/src/pgraph/portalClipper.I +++ b/panda/src/pgraph/portalClipper.I @@ -133,3 +133,24 @@ is_facing_camera() pgraph_cat.debug() << "Found direction of " << direction << endl; return (direction < _FACING_THRESHOLD); } + +//////////////////////////////////////////////////////////////////// +// Function: PortalClipper::get_plane_depth +// Access: Public +// Description: Given the x and z, solve for y: from the plane +//////////////////////////////////////////////////////////////////// +INLINE float PortalClipper:: +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 << " " + << portal_plane->_v.v._2 << " " << portal_plane->_v.v._3 << endl; + + if (portal_plane->_v.v._1 != 0.0) { + y = (((portal_plane->_v.v._0*x)+(portal_plane->_v.v._2*z)+portal_plane->_v.v._3) + / -(portal_plane->_v.v._1)); + } + return y; +} diff --git a/panda/src/pgraph/portalClipper.cxx b/panda/src/pgraph/portalClipper.cxx index 4eb3367fab..e57fa20856 100755 --- a/panda/src/pgraph/portalClipper.cxx +++ b/panda/src/pgraph/portalClipper.cxx @@ -112,19 +112,6 @@ draw_to(const LVecBase3f &v) { //////////////////////////////////////////////////////////////////// void PortalClipper:: draw_hexahedron(BoundingHexahedron *frustum) { - /* - pgraph_cat.debug() << "frustum points " << frustum->get_num_points() << endl; - - pgraph_cat.debug() << frustum->get_point(0) << endl; - pgraph_cat.debug() << frustum->get_point(1) << endl; - pgraph_cat.debug() << frustum->get_point(2) << endl; - pgraph_cat.debug() << frustum->get_point(3) << endl; - pgraph_cat.debug() << frustum->get_point(4) << endl; - pgraph_cat.debug() << frustum->get_point(5) << endl; - pgraph_cat.debug() << frustum->get_point(6) << endl; - pgraph_cat.debug() << frustum->get_point(7) << endl; - */ - // walk the view frustum as it should be drawn move_to(frustum->get_point(0)); draw_to(frustum->get_point(1)); @@ -255,22 +242,78 @@ prepare_portal(const NodePath &node_path) //CPT(TransformState) ctransform = node_path.get_transform(_scene_setup->get_camera_path()); LMatrix4f cmat = ctransform->get_mat(); pgraph_cat.debug() << 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); + + 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; - _coords[0] = portal_node->get_vertex(0)*cmat; - _coords[1] = portal_node->get_vertex(1)*cmat; - _coords[2] = portal_node->get_vertex(2)*cmat; - _coords[3] = portal_node->get_vertex(3)*cmat; - + 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; + + float min_x, max_x, min_z, max_z; + + min_x = min(min(min(temp[0][0], temp[1][0]), temp[2][0]), temp[3][0]); + max_x = max(max(max(temp[0][0], temp[1][0]), temp[2][0]), temp[3][0]); + 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; + + + Planef portal_plane(temp[0], temp[1], temp[2]); + + float y; + + y = get_plane_depth(min_x, min_z, &portal_plane); + pgraph_cat.debug() << "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; + _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; + _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; + _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; - + // check if facing camera if (is_facing_camera()) { - // ok, now lets add the near plane to this portal + // ok, now lets add the original portal + _color = Colorf(0,1,1,1); + move_to(temp[0]); + draw_to(temp[1]); + draw_to(temp[2]); + draw_to(temp[3]); + draw_to(temp[0]); + + // ok, now lets add the min_max portal _color = Colorf(1,0,0,1); move_to(_coords[0]); draw_to(_coords[1]); @@ -336,20 +379,6 @@ get_reduced_frustum(const NodePath &node_path) int num_planes = 6; LPoint3f intersect_points[4]; -#if 0 - // calculate the new side planes - for (int i=0; i<_num_vert; ++i) { - // get the vectors, Vi+1 and Vi - LVector3f front(_coords[(i+1)%_num_vert]); - LVector3f back(_coords[i]); - // get the cross product of these two vectors - LVector3f normal = front.cross(back); - normal.normalize(); - frustum_planes[i+1] = Planef(normal, LPoint3f(0,0,0)); - frustum_planes[i+1].output(pgraph_cat.debug()); - pgraph_cat.debug() << endl; - } -#else // another approach to actually finding the points, so that // I can reuse the current BoundingHexahedron object. Apparently, // it is better to construct this BH with bounding points, rather @@ -360,48 +389,48 @@ get_reduced_frustum(const NodePath &node_path) float t; bool visible = true; - // find intersection of 7->0 with far + // find intersection of 7->3 with far LPoint3f from_origin = _hex_frustum->get_point(7); - LVector3f from_direction = _coords[0] - from_origin; + LVector3f from_direction = _coords[3] - from_origin; bool is_intersect = _hex_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->0 at t=" << t << endl; + pgraph_cat.debug() << "far plane intersected 7->3 at t=" << t << endl; intersect_points[0] = from_origin + t*from_direction; pgraph_cat.debug() << intersect_points[0] << endl; } else visible = false; - // find intersection of 4->1 with far + // find intersection of 4->0 with far from_origin = _hex_frustum->get_point(4); - from_direction = _coords[1] - from_origin; + from_direction = _coords[0] - from_origin; is_intersect = _hex_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->1 at t=" << t << endl; + pgraph_cat.debug() << "far plane intersected 4->0 at t=" << t << endl; intersect_points[1] = from_origin + t*from_direction; pgraph_cat.debug() << intersect_points[1] << endl; } else visible = false; - // find intersection of 5->2 with far + // find intersection of 5->1 with far from_origin = _hex_frustum->get_point(5); - from_direction = _coords[2] - from_origin; + from_direction = _coords[1] - from_origin; is_intersect = _hex_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->2 at t=" << t << endl; + pgraph_cat.debug() << "far plane intersected 5->1 at t=" << t << endl; intersect_points[2] = from_origin + t*from_direction; pgraph_cat.debug() << intersect_points[2] << endl; } else visible = false; - // find intersection of 6->3 with far + // find intersection of 6->2 with far from_origin = _hex_frustum->get_point(6); - from_direction = _coords[3] - from_origin; + from_direction = _coords[2] - from_origin; is_intersect = _hex_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->3 at t=" << t << endl; + pgraph_cat.debug() << "far plane intersected 6->2 at t=" << t << endl; intersect_points[3] = from_origin + t*from_direction; pgraph_cat.debug() << intersect_points[3] << endl; } @@ -426,6 +455,5 @@ get_reduced_frustum(const NodePath &node_path) _color = Colorf(0,0,1,1); draw_hexahedron(DCAST(BoundingHexahedron, reduced_frustum)); -#endif return reduced_frustum; } diff --git a/panda/src/pgraph/portalClipper.h b/panda/src/pgraph/portalClipper.h index 7fab00a3e1..6440c940a7 100755 --- a/panda/src/pgraph/portalClipper.h +++ b/panda/src/pgraph/portalClipper.h @@ -78,6 +78,7 @@ public: INLINE void draw_to(float x, float y, float z); void draw_to(const LVecBase3f &v); + INLINE float get_plane_depth(float x, float z, Planef *portal_plane); public: static TypeHandle get_class_type() { @@ -123,13 +124,13 @@ private: PT(GeomLinestrip) _geom_linestrip; BoundingHexahedron *_hex_frustum; - SceneSetup *_scene_setup; int _num_vert; Vertexf _coords[4]; public: PT(GeomNode) _previous; + SceneSetup *_scene_setup; }; #include "portalClipper.I" diff --git a/panda/src/pgraph/portalNode.I b/panda/src/pgraph/portalNode.I index 3ee52f7448..9eb85366f9 100755 --- a/panda/src/pgraph/portalNode.I +++ b/panda/src/pgraph/portalNode.I @@ -173,7 +173,7 @@ get_vertex(int n) const { // Access: Published // Description: Sets the zone that this portal belongs to //////////////////////////////////////////////////////////////////// -INLINE void PortalNode::set_zone_in(PandaNode *zone) { +INLINE void PortalNode::set_zone_in(const NodePath &zone) { _zone_in = zone; } @@ -182,7 +182,7 @@ INLINE void PortalNode::set_zone_in(PandaNode *zone) { // Access: Published // Description: Sets the zone that this portal belongs to //////////////////////////////////////////////////////////////////// -INLINE PandaNode *PortalNode::get_zone_in() const { +INLINE NodePath PortalNode::get_zone_in() const { return _zone_in; } //////////////////////////////////////////////////////////////////// @@ -190,7 +190,7 @@ INLINE PandaNode *PortalNode::get_zone_in() const { // Access: Published // Description: Sets the zone that this portal leads out to //////////////////////////////////////////////////////////////////// -INLINE void PortalNode::set_zone_out(PandaNode *zone) { +INLINE void PortalNode::set_zone_out(const NodePath &zone) { _zone_out = zone; } @@ -199,7 +199,7 @@ INLINE void PortalNode::set_zone_out(PandaNode *zone) { // Access: Published // Description: Sets the zone that this portal leads out to //////////////////////////////////////////////////////////////////// -INLINE PandaNode *PortalNode::get_zone_out() const { +INLINE NodePath PortalNode::get_zone_out() const { return _zone_out; } diff --git a/panda/src/pgraph/portalNode.cxx b/panda/src/pgraph/portalNode.cxx index 2f877e7acb..6feee55024 100755 --- a/panda/src/pgraph/portalNode.cxx +++ b/panda/src/pgraph/portalNode.cxx @@ -22,6 +22,7 @@ #include "cullTraverserData.h" #include "cullTraverser.h" #include "renderState.h" +#include "portalClipper.h" #include "transformState.h" #include "colorScaleAttrib.h" #include "transparencyAttrib.h" @@ -158,7 +159,7 @@ combine_with(PandaNode *other) { //////////////////////////////////////////////////////////////////// bool PortalNode:: has_cull_callback() const { - return false; + return true; } //////////////////////////////////////////////////////////////////// @@ -176,16 +177,43 @@ has_cull_callback() const { //////////////////////////////////////////////////////////////////// bool PortalNode:: cull_callback(CullTraverser *trav, CullTraverserData &data) { - - // Calculate the reduced frustum for this portal + PortalClipper *portal_viewer = trav->get_portal_clipper(); + if (!_zone_out.is_empty() && portal_viewer) { + //CullTraverserData next_data(data, _zone_out); + if (is_visible()) { + pgraph_cat.debug() << "portal node visible " << *this << endl; + PT(GeometricBoundingVolume) vf = trav->get_view_frustum(); + PT(BoundingVolume) reduced_frustum; + + portal_viewer->prepare_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; + vf = DCAST(GeometricBoundingVolume, reduced_frustum); + + // trasform it to cull_center space + CPT(TransformState) cull_center_transform = + 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"; - CullTraverserData next_data(data, _zone_out); - - // We don't want to inherit the render state from above for these - // guys. - next_data._state = RenderState::make_empty(); - trav->traverse(next_data); + // Get the net trasform of the _zone_out + CPT(TransformState) zone_transform = _zone_out.get_net_transform(); + CullTraverserData next_data(_zone_out, trav->get_render_transform()->compose(zone_transform), + zone_transform, + trav->get_initial_state(), vf, + trav->get_guard_band()); + pgraph_cat.debug() << "cull_callback: traversing " << _zone_out.get_name() << endl; + // Make this zone show with the reduced frustum + _zone_out.show(); + trav->traverse(next_data); + // make sure traverser is not drawing this node again + _zone_out.hide(); + } + } // Now carry on to render our child nodes. return true; } diff --git a/panda/src/pgraph/portalNode.h b/panda/src/pgraph/portalNode.h index 03f0c745c6..559a75844b 100755 --- a/panda/src/pgraph/portalNode.h +++ b/panda/src/pgraph/portalNode.h @@ -68,11 +68,11 @@ PUBLISHED: INLINE int get_num_vertices() const; INLINE const LPoint3f &get_vertex(int n) const; - INLINE void set_zone_in(PandaNode *zone); - INLINE PandaNode *get_zone_in() const; + INLINE void set_zone_in(const NodePath &zone); + INLINE NodePath get_zone_in() const; - INLINE void set_zone_out(PandaNode *zone); - INLINE PandaNode *get_zone_out() const; + INLINE void set_zone_out(const NodePath &zone); + INLINE NodePath get_zone_out() const; INLINE void set_visible(bool value); INLINE bool is_visible(); @@ -99,8 +99,8 @@ private: typedef pvector Vertices; Vertices _vertices; - PT(PandaNode) _zone_in; // This is the zone it resides in - PT(PandaNode) _zone_out; // This is the zone it leads out to + NodePath _zone_in; // This is the zone it resides in + NodePath _zone_out; // This is the zone it leads out to bool _visible; diff --git a/panda/src/pgraph/sceneGraphReducer.cxx b/panda/src/pgraph/sceneGraphReducer.cxx index 6843ce5c9b..10d54f96db 100644 --- a/panda/src/pgraph/sceneGraphReducer.cxx +++ b/panda/src/pgraph/sceneGraphReducer.cxx @@ -91,22 +91,22 @@ flatten(PandaNode *root, bool combine_siblings) { void SceneGraphReducer:: r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs, int attrib_types, GeomTransformer &transformer) { - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "r_apply_attribs(" << *node << "), node's attribs are:\n"; - node->get_transform()->write(pgraph_cat.debug(false), 2); - node->get_state()->write(pgraph_cat.debug(false), 2); - node->get_effects()->write(pgraph_cat.debug(false), 2); + node->get_transform()->write(pgraph_cat.spam(false), 2); + node->get_state()->write(pgraph_cat.spam(false), 2); + node->get_effects()->write(pgraph_cat.spam(false), 2); } AccumulatedAttribs next_attribs(attribs); next_attribs.collect(node, attrib_types); - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "Got attribs from " << *node << "\n" << "Accumulated attribs are:\n"; - next_attribs.write(pgraph_cat.debug(false), attrib_types, 2); + next_attribs.write(pgraph_cat.spam(false), attrib_types, 2); } // Check to see if we can't propagate any of these attribs past @@ -115,16 +115,16 @@ r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs, const RenderEffects *effects = node->get_effects(); if (!effects->safe_to_transform()) { - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "Node " << *node << " contains a non-transformable effect; leaving transform here.\n"; } apply_types |= TT_transform; } if (!node->safe_to_transform()) { - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "Cannot safely transform nodes of type " << node->get_type() << "; leaving a transform here but carrying on otherwise.\n"; } @@ -145,8 +145,8 @@ r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs, } if (!children_transform_friendly) { - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "Node " << *node << " has a child that cannot modify its transform; leaving transform here.\n"; } @@ -167,8 +167,8 @@ r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs, if (child_node->get_num_parents() > 1) { if (!child_node->safe_to_flatten()) { - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "Cannot duplicate nodes of type " << child_node->get_type() << ".\n"; resist_copy = true; @@ -183,8 +183,8 @@ r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs, resist_copy = true; } else { - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "Duplicated " << *child_node << "\n"; } @@ -421,15 +421,15 @@ consider_siblings(PandaNode *parent_node, PandaNode *child1, bool SceneGraphReducer:: do_flatten_child(PandaNode *grandparent_node, PandaNode *parent_node, PandaNode *child_node) { - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "Collapsing " << *parent_node << " and " << *child_node << "\n"; } PT(PandaNode) new_parent = collapse_nodes(parent_node, child_node, false); if (new_parent == (PandaNode *)NULL) { - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "Decided not to collapse " << *parent_node << " and " << *child_node << "\n"; } @@ -466,15 +466,15 @@ do_flatten_child(PandaNode *grandparent_node, PandaNode *parent_node, PandaNode *SceneGraphReducer:: do_flatten_siblings(PandaNode *parent_node, PandaNode *child1, PandaNode *child2) { - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "Collapsing " << *child1 << " and " << *child2 << "\n"; } PT(PandaNode) new_child = collapse_nodes(child2, child1, true); if (new_child == (PandaNode *)NULL) { - if (pgraph_cat.is_debug()) { - pgraph_cat.debug() + if (pgraph_cat.is_spam()) { + pgraph_cat.spam() << "Decided not to collapse " << *child1 << " and " << *child2 << "\n"; } return NULL;