2nd pass portal clipping. This is integrated into scenegraph

This commit is contained in:
Asad M. Zaman 2004-06-04 01:34:14 +00:00
parent c32fbad9f8
commit d3d36911de
13 changed files with 213 additions and 183 deletions

View File

@ -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;
}

View File

@ -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 &copy) :
_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);
}
}
}

View File

@ -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() {

View File

@ -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 &copy) :
_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 &copy) {
_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)
{
}

View File

@ -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());

View File

@ -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 &copy);
INLINE void operator = (const CullTraverserData &copy);
@ -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:

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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"

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<LPoint3f> 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;

View File

@ -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;