247 lines
6.7 KiB
Text
247 lines
6.7 KiB
Text
/**
|
|
* PANDA 3D SOFTWARE
|
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
*
|
|
* All use of this software is subject to the terms of the revised BSD
|
|
* license. You should have received a copy of this license along
|
|
* with this source code in a file named "LICENSE."
|
|
*
|
|
* @file cullTraverser.I
|
|
* @author drose
|
|
* @date 2002-02-23
|
|
*/
|
|
|
|
/**
|
|
* Returns the GraphicsStateGuardian in effect.
|
|
*/
|
|
INLINE GraphicsStateGuardianBase *CullTraverser::
|
|
get_gsg() const {
|
|
return _gsg;
|
|
}
|
|
|
|
/**
|
|
* Returns the currently-executing thread object, as passed to the
|
|
* CullTraverser constructor.
|
|
*/
|
|
INLINE Thread *CullTraverser::
|
|
get_current_thread() const {
|
|
return _current_thread;
|
|
}
|
|
|
|
/**
|
|
* Returns the SceneSetup object.
|
|
*/
|
|
INLINE SceneSetup *CullTraverser::
|
|
get_scene() const {
|
|
return _scene_setup;
|
|
}
|
|
|
|
/**
|
|
* Returns true if a nonempty tag state key has been specified for the scene's
|
|
* camera, false otherwise.
|
|
*/
|
|
INLINE bool CullTraverser::
|
|
has_tag_state_key() const {
|
|
return _has_tag_state_key;
|
|
}
|
|
|
|
/**
|
|
* Returns the tag state key that has been specified for the scene's camera,
|
|
* if any.
|
|
*/
|
|
INLINE const std::string &CullTraverser::
|
|
get_tag_state_key() const {
|
|
return _tag_state_key;
|
|
}
|
|
|
|
/**
|
|
* Returns the position of the camera relative to the starting node.
|
|
*/
|
|
INLINE const TransformState *CullTraverser::
|
|
get_camera_transform() const {
|
|
return _scene_setup->get_camera_transform();
|
|
}
|
|
|
|
/**
|
|
* Returns the position of the starting node relative to the camera. This is
|
|
* the inverse of the camera transform.
|
|
*
|
|
* Note that this value is always the position of the starting node, not the
|
|
* current node, even if it is sampled during a traversal. To get the
|
|
* transform of the current node use
|
|
* CullTraverserData::get_modelview_transform().
|
|
*/
|
|
INLINE const TransformState *CullTraverser::
|
|
get_world_transform() const {
|
|
return _scene_setup->get_world_transform();
|
|
}
|
|
|
|
/**
|
|
* Returns the initial RenderState at the top of the scene graph we are
|
|
* traversing, or the empty state if the initial state was never set.
|
|
*/
|
|
INLINE const RenderState *CullTraverser::
|
|
get_initial_state() const {
|
|
return _initial_state;
|
|
}
|
|
|
|
/**
|
|
* Returns true, as depth offsets are the only way that we implement decals
|
|
* nowadays.
|
|
*/
|
|
INLINE bool CullTraverser::
|
|
get_depth_offset_decals() const {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Changes the visibility mask for the camera viewing the scene. This is
|
|
* normally set automatically at the time setup_scene() is called; you should
|
|
* change this only if you want to render some set of objects different from
|
|
* what the camera normally would draw.
|
|
*/
|
|
INLINE void CullTraverser::
|
|
set_camera_mask(const DrawMask &camera_mask) {
|
|
_camera_mask = camera_mask;
|
|
}
|
|
|
|
/**
|
|
* Returns the visibility mask from the camera viewing the scene.
|
|
*/
|
|
INLINE const DrawMask &CullTraverser::
|
|
get_camera_mask() const {
|
|
return _camera_mask;
|
|
}
|
|
|
|
/**
|
|
* Specifies the bounding volume that corresponds to the view frustum. Any
|
|
* primitives that fall entirely outside of this volume are not drawn.
|
|
*
|
|
* Nowadays, this gets set automatically by set_scene().
|
|
*/
|
|
INLINE void CullTraverser::
|
|
set_view_frustum(GeometricBoundingVolume *view_frustum) {
|
|
_view_frustum = view_frustum;
|
|
}
|
|
|
|
/**
|
|
* Returns the bounding volume that corresponds to the view frustum, or NULL
|
|
* if the view frustum is not in use or has not been set.
|
|
*
|
|
* Note that the view frustum returned here is always in the coordinate space
|
|
* of the starting node, not the current node, even if it is sampled during a
|
|
* traversal. To get the view frustum in the current node's coordinate space,
|
|
* check in the current CullTraverserData.
|
|
*/
|
|
INLINE GeometricBoundingVolume *CullTraverser::
|
|
get_view_frustum() const {
|
|
return _view_frustum;
|
|
}
|
|
|
|
/**
|
|
* Specifies the object that will receive the culled Geoms. This must be set
|
|
* before calling traverse().
|
|
*/
|
|
INLINE void CullTraverser::
|
|
set_cull_handler(CullHandler *cull_handler) {
|
|
_cull_handler = cull_handler;
|
|
}
|
|
|
|
/**
|
|
* Returns the object that will receive the culled Geoms.
|
|
*/
|
|
INLINE CullHandler *CullTraverser::
|
|
get_cull_handler() const {
|
|
return _cull_handler;
|
|
}
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* Returns the _portal_clipper pointer
|
|
*/
|
|
INLINE PortalClipper *CullTraverser::
|
|
get_portal_clipper() const {
|
|
return _portal_clipper;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the cull traversal is effectively in incomplete_render
|
|
* state, considering both the GSG's incomplete_render and the current
|
|
* DisplayRegion's incomplete_render flags. This returns the flag during the
|
|
* cull traversal; see GSG::get_effective_incomplete_render() for this same
|
|
* flag during the draw traversal.
|
|
*/
|
|
INLINE bool CullTraverser::
|
|
get_effective_incomplete_render() const {
|
|
return _effective_incomplete_render;
|
|
}
|
|
|
|
/**
|
|
* Flushes the PStatCollectors used during traversal.
|
|
*/
|
|
INLINE void CullTraverser::
|
|
flush_level() {
|
|
_nodes_pcollector.flush_level();
|
|
_geom_nodes_pcollector.flush_level();
|
|
_geoms_pcollector.flush_level();
|
|
_geoms_occluded_pcollector.flush_level();
|
|
}
|
|
|
|
/**
|
|
* This is implemented inline to reduce recursion.
|
|
*/
|
|
INLINE void CullTraverser::
|
|
do_traverse(CullTraverserData &data) {
|
|
if (is_in_view(data)) {
|
|
if (pgraph_cat.is_spam()) {
|
|
pgraph_cat.spam()
|
|
<< "\n" << data.get_node_path()
|
|
<< " " << data._draw_mask << "\n";
|
|
}
|
|
|
|
PandaNodePipelineReader *node_reader = data.node_reader();
|
|
int fancy_bits = node_reader->get_fancy_bits();
|
|
|
|
if (fancy_bits == 0 && data._cull_planes->is_empty()) {
|
|
// Nothing interesting in this node; just move on.
|
|
|
|
} else {
|
|
// Something in this node is worth taking a closer look.
|
|
const RenderEffects *node_effects = node_reader->get_effects();
|
|
if (node_effects->has_show_bounds()) {
|
|
// If we should show the bounding volume for this node, make it up
|
|
// now.
|
|
show_bounds(data, node_effects->has_show_tight_bounds());
|
|
}
|
|
|
|
data.apply_transform_and_state(this);
|
|
|
|
const FogAttrib *fog = (const FogAttrib *)
|
|
node_reader->get_state()->get_attrib(FogAttrib::get_class_slot());
|
|
|
|
if (fog != nullptr && fog->get_fog() != nullptr) {
|
|
// If we just introduced a FogAttrib here, call adjust_to_camera()
|
|
// now. This maybe isn't the perfect time to call it, but it's good
|
|
// enough; and at this time we have all the information we need for
|
|
// it.
|
|
fog->get_fog()->adjust_to_camera(get_camera_transform());
|
|
}
|
|
|
|
if (fancy_bits & PandaNode::FB_cull_callback) {
|
|
PandaNode *node = data.node();
|
|
if (!node->cull_callback(this, data)) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
traverse_below(data);
|
|
}
|
|
}
|