Ver código fonte

commit teedee's portal fixes

rdb 15 anos atrás
pai
commit
b72ae7c513

+ 5 - 1
panda/src/pgraph/cullTraverserData.I

@@ -32,6 +32,7 @@ CullTraverserData(const NodePath &start,
   _draw_mask(DrawMask::all_on())
 {
   _node_reader.check_bounds();
+  _portal_depth = 0;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -47,7 +48,8 @@ CullTraverserData(const CullTraverserData &copy) :
   _state(copy._state),
   _view_frustum(copy._view_frustum),
   _cull_planes(copy._cull_planes),
-  _draw_mask(copy._draw_mask)
+  _draw_mask(copy._draw_mask),
+  _portal_depth(copy._portal_depth)
 {
 }
 
@@ -65,6 +67,7 @@ operator = (const CullTraverserData &copy) {
   _view_frustum = copy._view_frustum;
   _cull_planes = copy._cull_planes;
   _draw_mask = copy._draw_mask;
+  _portal_depth = copy._portal_depth;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -84,6 +87,7 @@ CullTraverserData(const CullTraverserData &parent, PandaNode *child) :
   _draw_mask(parent._draw_mask)
 {
   _node_reader.check_bounds();
+  _portal_depth = parent._portal_depth;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 0
panda/src/pgraph/cullTraverserData.h

@@ -83,6 +83,7 @@ public:
   PT(GeometricBoundingVolume) _view_frustum;
   CPT(CullPlanes) _cull_planes;
   DrawMask _draw_mask;
+  int _portal_depth;
 
 private:
   bool is_in_view_impl();

+ 2 - 9
panda/src/pgraph/portalClipper.I

@@ -175,15 +175,8 @@ get_reduced_viewport(LPoint2f& min, LPoint2f& max) const  {
 ////////////////////////////////////////////////////////////////////
 INLINE bool PortalClipper::
 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
-  //portal_cat.spam() << portal_plane.get_normal() << "; " << -view_plane.get_normal() << endl;
-  //float direction = portal_plane.get_normal().dot(-view_plane.get_normal());
-  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);
+  portal_cat.debug() << "portal plane check value: " << portal_plane[3] << "\n";
+  return (portal_plane[3] > 0);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 23 - 9
panda/src/pgraph/portalClipper.cxx

@@ -269,14 +269,28 @@ prepare_portal(const NodePath &node_path)
   // check if the portal intersects with the cameras 0 point (center of projection). In that case the portal will invert itself.
   // portals intersecting the near plane or the 0 point are a weird case anyhow, therefore we don't reduce the frustum any further
   // and just return true. In effect the portal doesn't reduce visibility but will draw everything in its out cell
-  if ((temp[0][1] <= 0) || (temp[1][1] <= 0) || (temp[2][1] <= 0) || (temp[3][1] <= 0)) {
-      portal_cat.debug() << "portal intersects with center of projection.." << endl;
-      return true;
+  const Lens *lens = _scene_setup->get_lens();
+  LVector3f forward = LVector3f::forward(lens->get_coordinate_system());
+  int forward_axis;
+  if (forward[1]) {
+    forward_axis = 1;
+  }
+  else if (forward[2]) {
+    forward_axis = 2;
+  }
+  else {
+    forward_axis = 0;
+  }
+  if ((temp[0][forward_axis] * forward[forward_axis] <= 0) ||
+    (temp[1][forward_axis] * forward[forward_axis] <= 0) ||
+    (temp[2][forward_axis] * forward[forward_axis] <= 0) ||
+    (temp[3][forward_axis] * forward[forward_axis] <= 0)) {
+    portal_cat.debug() << "portal intersects with center of projection.." << endl;
+    return true;
   }
   
   // project portal points, so they are in the -1..1 range
   LPoint3f projected_coords[4];
-  const Lens *lens = _scene_setup->get_lens();
   lens->project(temp[0], projected_coords[0]);
   lens->project(temp[1], projected_coords[1]);
   lens->project(temp[2], projected_coords[2]);
@@ -336,11 +350,11 @@ prepare_portal(const NodePath &node_path)
 
     // lets first add the clipped portal (in yellow)
     _color = Colorf(1,1,0,1);
-    move_to((near_point[0]+far_point[0])/2.0); // I choose a point in the middle between near and far.. could also be some other z value.. 
-    draw_to((near_point[1]+far_point[1])/2.0);
-    draw_to((near_point[2]+far_point[2])/2.0);
-    draw_to((near_point[3]+far_point[3])/2.0);
-    draw_to((near_point[0]+far_point[0])/2.0);
+    move_to((near_point[0]*0.99+far_point[0]*0.01)); // I choose a point in the middle between near and far.. could also be some other z value.. 
+    draw_to((near_point[1]*0.99+far_point[1]*0.01));
+    draw_to((near_point[2]*0.99+far_point[2]*0.01));
+    draw_to((near_point[3]*0.99+far_point[3]*0.01));
+    draw_to((near_point[0]*0.99+far_point[0]*0.01));
 
     // ok, now lets add the original portal (in cyan) 
     _color = Colorf(0,1,1,1);

+ 0 - 2
panda/src/pgraph/portalClipper.h

@@ -41,8 +41,6 @@ class CullTraverserData;
 class CullableObject;
 class NodePath;
 
-#define _FACING_THRESHOLD 0.0  //about 90 degrees with the camera
-
 ////////////////////////////////////////////////////////////////////
 //       Class : PortalClipper
 // Description : This object performs a depth-first traversal of the

+ 18 - 0
panda/src/pgraph/portalNode.I

@@ -257,3 +257,21 @@ INLINE void PortalNode::set_open(bool value) {
 INLINE bool PortalNode::is_open() {
   return _open;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: PortalNode::set_max_depth
+//       Access: Published
+//  Description: Set the maximum depth this portal will be visible at
+////////////////////////////////////////////////////////////////////
+INLINE void PortalNode::set_max_depth(int value) {
+  _max_depth = value;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PortalNode::get_max_depth
+//       Access: Published
+//  Description: Returns the maximum depth this portal will be visible at
+////////////////////////////////////////////////////////////////////
+INLINE int PortalNode::get_max_depth() {
+  return _max_depth;
+}

+ 7 - 2
panda/src/pgraph/portalNode.cxx

@@ -52,6 +52,7 @@ PortalNode(const string &name) :
   _visible = false;
   _open = true;
   _clip_plane = false;
+  _max_depth = 10;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -77,6 +78,7 @@ PortalNode(const string &name, LPoint3f pos, float scale) :
   _visible = false;
   _open = true;
   _clip_plane = false;
+  _max_depth = 10;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -95,7 +97,8 @@ PortalNode(const PortalNode &copy) :
   _cell_out(copy._cell_out),
   _clip_plane(copy._clip_plane),
   _visible(copy._visible),
-  _open(copy._open)
+  _open(copy._open),
+  _max_depth(copy._max_depth)
 {
 }
 
@@ -226,8 +229,9 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
 
   PortalClipper *portal_viewer = trav->get_portal_clipper();
   set_visible(false);
-  if (is_open() && !_cell_out.is_empty() && portal_viewer) {
+  if (is_open() && !_cell_out.is_empty() && portal_viewer && data._portal_depth <= _max_depth) {
     portal_cat.debug() << "checking portal node  " << *this << endl;
+    portal_cat.debug() << "portal_depth is " << data._portal_depth << endl;
     PT(GeometricBoundingVolume) vf = trav->get_view_frustum();
     PT(BoundingVolume) reduced_frustum;
     
@@ -304,6 +308,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
                                     cell_transform,
                                     next_state, new_bh,
                                     current_thread);
+        next_data._portal_depth = data._portal_depth + 1;
 
         portal_viewer->set_reduced_frustum(new_bh);
         portal_cat.spam() << "cull_callback: before traversing " << _cell_out.get_name() << endl;

+ 4 - 0
panda/src/pgraph/portalNode.h

@@ -82,6 +82,9 @@ PUBLISHED:
   INLINE void set_visible(bool value);
   INLINE bool is_visible();
 
+  INLINE void set_max_depth(int value);
+  INLINE int get_max_depth();
+
   INLINE void set_open(bool value);
   INLINE bool is_open();
 
@@ -124,6 +127,7 @@ private:
 
   bool _visible;
   bool _open;
+  int _max_depth;
 
 public:
   static void register_with_read_factory();