From 78f062149bec372b973cd925d11f89e37f568756 Mon Sep 17 00:00:00 2001 From: "Asad M. Zaman" Date: Tue, 14 Mar 2006 05:26:26 +0000 Subject: [PATCH] portalClipper that clips with clip planes --- panda/src/pgraph/portalClipper.cxx | 2 +- panda/src/pgraph/portalNode.I | 23 ++++++++ panda/src/pgraph/portalNode.cxx | 93 +++++++++++++++++++++++++----- panda/src/pgraph/portalNode.h | 24 ++++++++ 4 files changed, 128 insertions(+), 14 deletions(-) diff --git a/panda/src/pgraph/portalClipper.cxx b/panda/src/pgraph/portalClipper.cxx index fb6025c92c..866f0c7809 100755 --- a/panda/src/pgraph/portalClipper.cxx +++ b/panda/src/pgraph/portalClipper.cxx @@ -497,7 +497,7 @@ clip_portal(const NodePath &node_path) // Function: PortalClipper::get_reduced_frustum // Access: Public // Description: After clipping the portal, form the new sides and -// fill in the new frustum. Return true if success +// fill in the new frustum. Return the new frustum //////////////////////////////////////////////////////////////////// PT(BoundingVolume) PortalClipper:: get_reduced_frustum(const NodePath &node_path) diff --git a/panda/src/pgraph/portalNode.I b/panda/src/pgraph/portalNode.I index 8ea00d4908..e044f9d0e0 100755 --- a/panda/src/pgraph/portalNode.I +++ b/panda/src/pgraph/portalNode.I @@ -203,6 +203,29 @@ INLINE NodePath PortalNode::get_cell_out() const { return _cell_out; } +//////////////////////////////////////////////////////////////////// +// Function: PortalNode::set_clip_plane +// Access: Published +// Description: this is set if the portal will clip against its +// left and right planes +//////////////////////////////////////////////////////////////////// +INLINE void PortalNode::set_clip_plane(bool value) { + _clip_plane = value; + if (_clip_plane) { + enable_clipping_planes(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PortalNode::is_clip_plane +// Access: Published +// Description: Is this portal clipping against its left-right planes +//////////////////////////////////////////////////////////////////// +INLINE bool PortalNode::is_clip_plane() { + return _clip_plane; +} + + //////////////////////////////////////////////////////////////////// // Function: PortalNode::set_visible // Access: Published diff --git a/panda/src/pgraph/portalNode.cxx b/panda/src/pgraph/portalNode.cxx index f82aa7670a..b78457d9c3 100755 --- a/panda/src/pgraph/portalNode.cxx +++ b/panda/src/pgraph/portalNode.cxx @@ -31,6 +31,14 @@ #include "bamReader.h" #include "bamWriter.h" +#include "plane.h" + +/* +#ifndef CPPPARSER +#include "../collide/collisionPlane.h" +#endif +*/ + TypeHandle PortalNode::_type_handle; @@ -51,6 +59,7 @@ PortalNode(const string &name) : { _visible = false; _open = true; + _clip_plane = false; } //////////////////////////////////////////////////////////////////// @@ -73,6 +82,7 @@ PortalNode(const string &name, LPoint3f pos, float scale) : _visible = false; _open = true; + _clip_plane = false; } //////////////////////////////////////////////////////////////////// @@ -90,7 +100,8 @@ PortalNode(const PortalNode ©) : _cell_in(copy._cell_in), _cell_out(copy._cell_out), _visible(copy._visible), - _open(copy._open) + _open(copy._open), + _clip_plane(copy._clip_plane) { } @@ -128,6 +139,45 @@ preserve_name() const { return true; } +//////////////////////////////////////////////////////////////////// +// Function: PortalNode::enable_clipping_planes +// Access: Public, Virtual +// Description: initialize the clipping planes and renderstate +//////////////////////////////////////////////////////////////////// +void PortalNode:: +enable_clipping_planes() { + _left_plane_node = new PlaneNode("left"); + NodePath left_plane_np = NodePath(this).attach_new_node(_left_plane_node); + + _right_plane_node = new PlaneNode("right"); + NodePath right_plane_np = NodePath(this).attach_new_node(_right_plane_node); + + /* + // for debugging visialization, attach a collsion plane to left and right each + _left_coll_node = new CollisionNode("left_coll"); + _left_coll_node->set_into_collide_mask(CollideMask::all_off()); + // prepare a collision plane to be set later + PT(CollisionPlane) left_coll_plane = new CollisionPlane(Planef()); + _left_coll_node->add_solid(left_coll_plane); + // attach it onto the _left_plane_np + left_plane_np.attach_new_node(_left_coll_node); + + _right_coll_node = new CollisionNode("right_coll"); + _right_coll_node->set_into_collide_mask(CollideMask::all_off()); + // prepare a collision plane to be set later + PT(CollisionPlane) right_coll_plane = new CollisionPlane(Planef()); + _right_coll_node->add_solid(right_coll_plane); + // attach it onto the _left_plane_np + right_plane_np.attach_new_node(_right_coll_node); + */ + + CPT(RenderAttrib) plane_attrib = ClipPlaneAttrib::make(); + plane_attrib = DCAST(ClipPlaneAttrib, plane_attrib)->add_on_plane(NodePath(left_plane_np)); + plane_attrib = DCAST(ClipPlaneAttrib, plane_attrib)->add_on_plane(NodePath(right_plane_np)); + + _clip_state = RenderState::make(plane_attrib); +} + //////////////////////////////////////////////////////////////////// // Function: PortalNode::xform // Access: Public, Virtual @@ -223,16 +273,25 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { // keep a copy of this reduced frustum PT(BoundingHexahedron) new_bh = DCAST(BoundingHexahedron, vf->make_copy()); - // trasform it to cull_center space - // CPT(TransformState) cull_center_transform = - //portal_viewer->_scene_setup->get_cull_center().get_transform(_cell_out); + if (_clip_plane) { + // make a temp copy of this reduced frustum + PT(BoundingHexahedron) temp_bh = DCAST(BoundingHexahedron, vf->make_copy()); + CPT(TransformState) ftransform = + _cell_in.get_net_transform()->invert_compose(portal_viewer->_scene_setup->get_cull_center().get_net_transform()); + + temp_bh->xform(ftransform->get_mat()); + + // set left/right clipping plane + _left_plane_node->set_plane(-temp_bh->get_plane(4)); // left plane of bh + _right_plane_node->set_plane(-temp_bh->get_plane(2));// right plane of bh + + /* + // set this plane at the collision plane too for debugging + ((CollisionPlane*)_left_coll_node->get_solid(0))->set_plane(-temp_bh->get_plane(4)); + ((CollisionPlane*)_right_coll_node->get_solid(0))->set_plane(-temp_bh->get_plane(2)); + */ + } - /* - 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 as seen from the camera. CPT(TransformState) cell_transform = trav->get_camera_transform()->invert_compose(_cell_out.get_net_transform()); @@ -243,10 +302,18 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { new_bh->xform(frustum_transform->get_mat()); portal_cat.spam() << "new_bh is " << *new_bh << "\n"; - + + CPT(RenderState) next_state = data._state; + + // attach clipping state if there is any + if (_clip_plane) { + next_state = next_state->compose(_clip_state); + } + CullTraverserData next_data(_cell_out, cell_transform, - data._state, new_bh, NULL); + next_state, new_bh, NULL); + // data._state, new_bh, NULL); // Make this cell show with the reduced frustum // _cell_out.show(); @@ -254,7 +321,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { PT(BoundingHexahedron) old_bh = portal_viewer->get_reduced_frustum(); 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_below(next_data); portal_cat.spam() << "cull_callback: after traversing " << _cell_out.get_name() << endl; // make sure traverser is not drawing this node again // _cell_out.hide(); diff --git a/panda/src/pgraph/portalNode.h b/panda/src/pgraph/portalNode.h index edb0f93df7..4a1b965b4a 100755 --- a/panda/src/pgraph/portalNode.h +++ b/panda/src/pgraph/portalNode.h @@ -23,9 +23,16 @@ #include "portalMask.h" #include "pandaNode.h" +#include "planeNode.h" #include "nodePath.h" #include "pvector.h" +/* +#ifndef CPPPARSER +#include "../collide/collisionSolid.h" +#include "../collide/collisionNode.h" +#endif +*/ //////////////////////////////////////////////////////////////////// // Class : PortalNode // Description : A node in the scene graph that can hold a @@ -49,6 +56,8 @@ public: virtual void xform(const LMatrix4f &mat); virtual PandaNode *combine_with(PandaNode *other); + virtual void enable_clipping_planes(); + virtual bool has_cull_callback() const; virtual bool cull_callback(CullTraverser *trav, CullTraverserData &data); @@ -76,6 +85,9 @@ PUBLISHED: INLINE void set_cell_out(const NodePath &cell); INLINE NodePath get_cell_out() const; + INLINE void set_clip_plane(bool value); + INLINE bool is_clip_plane(); + INLINE void set_visible(bool value); INLINE bool is_visible(); @@ -108,6 +120,18 @@ private: NodePath _cell_in; // This is the cell it resides in NodePath _cell_out; // This is the cell it leads out to + // enable plane clipping on this portal + /* +#ifndef CPPPARSER + PT(CollisionNode) _left_coll_node; // for debugging visualization + PT(CollisionNode) _right_coll_node;// for debugging visualization +#endif + */ + bool _clip_plane; + PT(PlaneNode) _left_plane_node; + PT(PlaneNode) _right_plane_node; + CPT(RenderState) _clip_state; + bool _visible; bool _open;