pstats frustum cull, add set_final to bounded object

This commit is contained in:
David Rose 2001-06-15 02:02:31 +00:00
parent b9b5a40599
commit fe70bd5e1d
11 changed files with 120 additions and 28 deletions

View File

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

View File

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

View File

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

View File

@ -65,6 +65,6 @@ recompute_bound() {
_bound = NULL;
}
_bound_stale = false;
_flags &= ~F_bound_stale;
// By default, the bound is empty.
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,4 +2,5 @@
#include "appTraverser.cxx"
#include "config_sgraphutil.cxx"
#include "directRenderTraverser.cxx"
#include "frustumCullTraverser.cxx"