mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
commit teedee's portal fixes
This commit is contained in:
parent
92852073f2
commit
b72ae7c513
@ -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 ©) :
|
||||
_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 ©) {
|
||||
_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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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)) {
|
||||
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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
@ -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 ©) :
|
||||
_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;
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user