pstats frustum cull, add set_final to bounded object
This commit is contained in:
parent
b9b5a40599
commit
fe70bd5e1d
|
|
@ -47,6 +47,9 @@ PStatCollector GraphicsStateGuardian::_transform_state_pcollector("State changes
|
|||
PStatCollector GraphicsStateGuardian::_texture_state_pcollector("State changes:Textures");
|
||||
PStatCollector GraphicsStateGuardian::_nodes_pcollector("Nodes");
|
||||
PStatCollector GraphicsStateGuardian::_geom_nodes_pcollector("Nodes:GeomNodes");
|
||||
PStatCollector GraphicsStateGuardian::_frustum_cull_volumes_pcollector("Cull volumes");
|
||||
PStatCollector GraphicsStateGuardian::_frustum_cull_transforms_pcollector("Cull volumes:Transforms");
|
||||
|
||||
#endif
|
||||
|
||||
TypeHandle GraphicsStateGuardian::_type_handle;
|
||||
|
|
@ -759,6 +762,10 @@ init_frame_pstats() {
|
|||
|
||||
_nodes_pcollector.clear_level();
|
||||
_geom_nodes_pcollector.clear_level();
|
||||
|
||||
// Not to mention the view-frustum-cull counters.
|
||||
_frustum_cull_volumes_pcollector.clear_level();
|
||||
_frustum_cull_transforms_pcollector.clear_level();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -232,6 +232,8 @@ public:
|
|||
static PStatCollector _texture_state_pcollector;
|
||||
static PStatCollector _nodes_pcollector;
|
||||
static PStatCollector _geom_nodes_pcollector;
|
||||
static PStatCollector _frustum_cull_volumes_pcollector;
|
||||
static PStatCollector _frustum_cull_transforms_pcollector;
|
||||
|
||||
private:
|
||||
// NOTE: on win32 another DLL (e.g. libpandadx.dll) cannot access
|
||||
|
|
|
|||
|
|
@ -18,20 +18,38 @@
|
|||
|
||||
#include <notify.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BoundedObject::is_bound_stale
|
||||
// Access: Published
|
||||
// Description: Returns true if the bound is currently marked stale
|
||||
// and will be recomputed the next time get_bound() is
|
||||
// called.
|
||||
//
|
||||
// This function is defined up at the top of this file,
|
||||
// because several of the inline functions below
|
||||
// reference it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH bool BoundedObject::
|
||||
is_bound_stale() const {
|
||||
return (_flags & F_bound_stale) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BoundedObject::Constructor
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH BoundedObject::
|
||||
BoundedObject() {
|
||||
_bound_type = BVT_dynamic_sphere;
|
||||
_bound_stale = true;
|
||||
_flags = F_bound_stale;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BoundedObject::set_bound
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Sets the type of the bounding volume that will be
|
||||
// dynamically computed for this particular node.
|
||||
// Presently, this should only be BVT_dynamic_sphere.
|
||||
|
|
@ -45,7 +63,7 @@ set_bound(BoundedObject::BoundingVolumeType type) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BoundedObject::set_bound
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Explicitly sets a new bounding volume on this node.
|
||||
// This will be a static bounding volume that will no
|
||||
// longer be recomputed automatically.
|
||||
|
|
@ -54,13 +72,13 @@ INLINE_GRAPH void BoundedObject::
|
|||
set_bound(const BoundingVolume &bound) {
|
||||
mark_bound_stale();
|
||||
_bound_type = BVT_static;
|
||||
_bound_stale = false;
|
||||
_flags &= ~F_bound_stale;
|
||||
_bound = bound.make_copy();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BoundedObject::get_bound
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the current bounding volume on this node,
|
||||
// possibly forcing a recompute. A node's bounding
|
||||
// volume encloses only the node itself, irrespective of
|
||||
|
|
@ -71,8 +89,8 @@ set_bound(const BoundingVolume &bound) {
|
|||
INLINE_GRAPH const BoundingVolume &BoundedObject::
|
||||
get_bound() const {
|
||||
if (_bound_type == BVT_static) {
|
||||
((BoundedObject *)this)->_bound_stale = false;
|
||||
} else if (_bound_stale || _bound == (BoundingVolume *)NULL) {
|
||||
((BoundedObject *)this)->_flags &= ~F_bound_stale;
|
||||
} else if (is_bound_stale() || _bound == (BoundingVolume *)NULL) {
|
||||
((BoundedObject *)this)->recompute_bound();
|
||||
}
|
||||
return *_bound;
|
||||
|
|
@ -80,7 +98,7 @@ get_bound() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BoundedObject::mark_bound_stale
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Marks the current bounding volume as stale, so that
|
||||
// it will be recomputed later. This may have a
|
||||
// cascading effect up to the root of all graphs of
|
||||
|
|
@ -90,10 +108,10 @@ get_bound() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH bool BoundedObject::
|
||||
mark_bound_stale() {
|
||||
if (_bound_stale) {
|
||||
if (is_bound_stale()) {
|
||||
return false;
|
||||
}
|
||||
_bound_stale = true;
|
||||
_flags |= F_bound_stale;
|
||||
propagate_stale_bound();
|
||||
|
||||
return true;
|
||||
|
|
@ -101,26 +119,52 @@ mark_bound_stale() {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BoundedObject::force_bound_stale
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Marks the current volume as stale and propagates the
|
||||
// effect at least one level, even if it had already
|
||||
// been marked stale.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH void BoundedObject::
|
||||
force_bound_stale() {
|
||||
_bound_stale = true;
|
||||
_flags |= F_bound_stale;
|
||||
propagate_stale_bound();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BoundedObject::is_bound_stale
|
||||
// Access: Public
|
||||
// Description: Returns true if the bound is currently marked stale
|
||||
// and will be recomputed the next time get_bound() is
|
||||
// called.
|
||||
// Function: BoundedObject::set_final
|
||||
// Access: Published
|
||||
// Description: Sets the "final" flag on this BoundedObject. If
|
||||
// this is true, than no bounding volume need be tested
|
||||
// below it; a positive intersection with this bounding
|
||||
// volume is deemed to be a positive intersection with
|
||||
// all geometry inside.
|
||||
//
|
||||
// This is useful to quickly force a larger bounding
|
||||
// volume around a node when the GeomNodes themselves
|
||||
// are inaccurate for some reason, without forcing a
|
||||
// recompute of every nested bounding volume. It's also
|
||||
// helpful when the bounding volume is tricked by some
|
||||
// special properties, like billboards, that may move
|
||||
// geometry out of its bounding volume otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH bool BoundedObject::
|
||||
is_bound_stale() const {
|
||||
return _bound_stale;
|
||||
INLINE_GRAPH void BoundedObject::
|
||||
set_final(bool flag) {
|
||||
if (flag) {
|
||||
_flags |= F_final;
|
||||
} else {
|
||||
_flags &= ~F_final;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BoundedObject::is_final
|
||||
// Access: Published
|
||||
// Description: Returns the current state of the "final" flag.
|
||||
// Initially, this flag is off (false), but it may be
|
||||
// changed by an explicit call to set_final(). See
|
||||
// set_final().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE_GRAPH bool BoundedObject::
|
||||
is_final() const {
|
||||
return (_flags & F_final) != 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,6 @@ recompute_bound() {
|
|||
_bound = NULL;
|
||||
}
|
||||
|
||||
_bound_stale = false;
|
||||
_flags &= ~F_bound_stale;
|
||||
// By default, the bound is empty.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,12 +53,19 @@ PUBLISHED:
|
|||
INLINE_GRAPH void force_bound_stale();
|
||||
INLINE_GRAPH bool is_bound_stale() const;
|
||||
|
||||
INLINE_GRAPH void set_final(bool flag);
|
||||
INLINE_GRAPH bool is_final() const;
|
||||
|
||||
protected:
|
||||
virtual void propagate_stale_bound();
|
||||
virtual void recompute_bound();
|
||||
|
||||
private:
|
||||
bool _bound_stale;
|
||||
enum Flags {
|
||||
F_bound_stale = 0x0001,
|
||||
F_final = 0x0002,
|
||||
};
|
||||
int _flags;
|
||||
BoundingVolumeType _bound_type;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -149,6 +149,8 @@ static LevelCollectorProperties level_properties[] = {
|
|||
{ 1, "Vertices:Display lists", { 0.8, 0.5, 1.0 } },
|
||||
{ 1, "Nodes", { 0.4, 0.2, 0.8 }, "", 500.0 },
|
||||
{ 1, "Nodes:GeomNodes", { 0.8, 0.2, 0.0 } },
|
||||
{ 1, "Cull volumes", { 0.7, 0.6, 0.9 }, "", 500.0 },
|
||||
{ 1, "Cull volumes:Transforms", { 0.9, 0.6, 0.0 } },
|
||||
{ 1, "State changes", { 1.0, 0.5, 0.2 }, "", 500.0 },
|
||||
{ 1, "State changes:Transforms", { 0.2, 0.2, 0.8 } },
|
||||
{ 1, "State changes:Textures", { 0.8, 0.2, 0.2 } },
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
#begin lib_target
|
||||
#define TARGET sgraphutil
|
||||
#define LOCAL_LIBS \
|
||||
graph sgraph sgattrib linmath putil gobj mathutil gsgbase display \
|
||||
pnmimage
|
||||
pstatclient graph sgraph sgattrib linmath putil gobj mathutil \
|
||||
gsgbase display pnmimage
|
||||
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
|
|
@ -18,7 +18,8 @@
|
|||
|
||||
#define INCLUDED_SOURCES \
|
||||
appTraverser.cxx config_sgraphutil.cxx directRenderTraverser.cxx \
|
||||
get_rel_pos.cxx sceneGraphAnalyzer.cxx sceneGraphReducer.cxx
|
||||
frustumCullTraverser.cxx get_rel_pos.cxx sceneGraphAnalyzer.cxx \
|
||||
sceneGraphReducer.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
appTraverser.I appTraverser.h config_sgraphutil.h \
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ FrustumCullTraverser(ArcChain &arc_chain, Node *root,
|
|||
|
||||
local_frustum = DCAST(GeometricBoundingVolume, _view_frustum->make_copy());
|
||||
local_frustum->xform(rel_from_camera);
|
||||
GraphicsStateGuardian::_frustum_cull_volumes_pcollector.add_level(1);
|
||||
GraphicsStateGuardian::_frustum_cull_transforms_pcollector.add_level(1);
|
||||
|
||||
if (sgraphutil_cat.is_spam()) {
|
||||
sgraphutil_cat.spam()
|
||||
|
|
@ -130,6 +132,7 @@ traverse(NodeRelation *arc, AttributeWrapper render_state,
|
|||
|
||||
nassertv(local_frustum != (GeometricBoundingVolume *)NULL);
|
||||
int result = local_frustum->contains(arc_gbv);
|
||||
GraphicsStateGuardian::_frustum_cull_volumes_pcollector.add_level(1);
|
||||
if (result == BoundingVolume::IF_no_intersection) {
|
||||
// No intersection at all. Cull.
|
||||
if (sgraphutil_cat.is_spam()) {
|
||||
|
|
@ -175,11 +178,16 @@ traverse(NodeRelation *arc, AttributeWrapper render_state,
|
|||
}
|
||||
|
||||
if (carry_on) {
|
||||
if (arc->has_transition(BillboardTransition::get_class_type())) {
|
||||
if (arc->is_final() ||
|
||||
arc->has_transition(BillboardTransition::get_class_type())) {
|
||||
// We can't reliably cull within a billboard, because the
|
||||
// geometry might get rotated out of its bounding volume.
|
||||
// So once we get within a billboard, we consider it all
|
||||
// visible.
|
||||
|
||||
// Also, if the arc has the "final" flag, the user is
|
||||
// claiming that there is some other reason we should
|
||||
// consider everything visible at this point. So be it.
|
||||
all_in = true;
|
||||
}
|
||||
|
||||
|
|
@ -205,6 +213,7 @@ traverse(NodeRelation *arc, AttributeWrapper render_state,
|
|||
// be.
|
||||
nassertv(local_frustum != (GeometricBoundingVolume *)NULL);
|
||||
local_frustum->xform(tt->get_matrix());
|
||||
GraphicsStateGuardian::_frustum_cull_transforms_pcollector.add_level(1);
|
||||
|
||||
if (sgraphutil_cat.is_spam()) {
|
||||
sgraphutil_cat.spam()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
// Filename: frustumCullTraverser.cxx
|
||||
// Created by: drose (14Jun01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "frustumCullTraverser.h"
|
||||
|
|
@ -33,11 +33,11 @@
|
|||
#include <transformTransition.h>
|
||||
#include <billboardTransition.h>
|
||||
#include <wrt.h>
|
||||
#include <pStatCollector.h>
|
||||
|
||||
#include "config_sgraphutil.h"
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : FrustumCullTraverser
|
||||
// Description : A special kind of depth-first traverser that can
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@
|
|||
#include "appTraverser.cxx"
|
||||
#include "config_sgraphutil.cxx"
|
||||
#include "directRenderTraverser.cxx"
|
||||
#include "frustumCullTraverser.cxx"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue