mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
2nd pass portal clipping. This is integrated into scenegraph
This commit is contained in:
parent
c32fbad9f8
commit
d3d36911de
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user