DisplayRegion::make_cull_result_graph()

This commit is contained in:
David Rose 2007-06-15 16:54:30 +00:00
parent 0b703e2f14
commit 3b528350bb
18 changed files with 324 additions and 0 deletions

View File

@ -110,3 +110,17 @@ draw(bool force, Thread *current_thread) {
}
}
////////////////////////////////////////////////////////////////////
// Function: CullBinBackToFront::fill_result_graph
// Access: Protected, Virtual
// Description: Called by CullBin::make_result_graph() to add all the
// geoms to the special cull result scene graph.
////////////////////////////////////////////////////////////////////
void CullBinBackToFront::
fill_result_graph(CullBin::ResultGraphBuilder &builder) {
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;
builder.add_object(object);
}
}

View File

@ -51,6 +51,9 @@ public:
virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
virtual void draw(bool force, Thread *current_thread);
protected:
virtual void fill_result_graph(ResultGraphBuilder &builder);
private:
class ObjectData {
public:

View File

@ -96,3 +96,17 @@ draw(bool force, Thread *current_thread) {
}
}
////////////////////////////////////////////////////////////////////
// Function: CullBinFixed::fill_result_graph
// Access: Protected, Virtual
// Description: Called by CullBin::make_result_graph() to add all the
// geoms to the special cull result scene graph.
////////////////////////////////////////////////////////////////////
void CullBinFixed::
fill_result_graph(CullBin::ResultGraphBuilder &builder) {
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;
builder.add_object(object);
}
}

View File

@ -53,6 +53,9 @@ public:
virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
virtual void draw(bool force, Thread *current_thread);
protected:
virtual void fill_result_graph(ResultGraphBuilder &builder);
private:
class ObjectData {
public:

View File

@ -110,3 +110,17 @@ draw(bool force, Thread *current_thread) {
}
}
////////////////////////////////////////////////////////////////////
// Function: CullBinFrontToBack::fill_result_graph
// Access: Protected, Virtual
// Description: Called by CullBin::make_result_graph() to add all the
// geoms to the special cull result scene graph.
////////////////////////////////////////////////////////////////////
void CullBinFrontToBack::
fill_result_graph(CullBin::ResultGraphBuilder &builder) {
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;
builder.add_object(object);
}
}

View File

@ -51,6 +51,9 @@ public:
virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
virtual void draw(bool force, Thread *current_thread);
protected:
virtual void fill_result_graph(ResultGraphBuilder &builder);
private:
class ObjectData {
public:

View File

@ -95,3 +95,17 @@ draw(bool force, Thread *current_thread) {
}
}
////////////////////////////////////////////////////////////////////
// Function: CullBinStateSorted::fill_result_graph
// Access: Protected, Virtual
// Description: Called by CullBin::make_result_graph() to add all the
// geoms to the special cull result scene graph.
////////////////////////////////////////////////////////////////////
void CullBinStateSorted::
fill_result_graph(CullBin::ResultGraphBuilder &builder) {
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi)._object;
builder.add_object(object);
}
}

View File

@ -55,6 +55,9 @@ public:
virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
virtual void draw(bool force, Thread *current_thread);
protected:
virtual void fill_result_graph(ResultGraphBuilder &builder);
private:
class ObjectData {
public:

View File

@ -76,3 +76,17 @@ draw(bool force, Thread *current_thread) {
}
}
////////////////////////////////////////////////////////////////////
// Function: CullBinUnsorted::fill_result_graph
// Access: Protected, Virtual
// Description: Called by CullBin::make_result_graph() to add all the
// geoms to the special cull result scene graph.
////////////////////////////////////////////////////////////////////
void CullBinUnsorted::
fill_result_graph(CullBin::ResultGraphBuilder &builder) {
Objects::const_iterator oi;
for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
CullableObject *object = (*oi);
builder.add_object(object);
}
}

View File

@ -45,6 +45,9 @@ public:
virtual void add_object(CullableObject *object, Thread *current_thread);
virtual void draw(bool force, Thread *current_thread);
protected:
virtual void fill_result_graph(ResultGraphBuilder &builder);
private:
typedef pvector<CullableObject *> Objects;
Objects _objects;

View File

@ -524,6 +524,36 @@ get_screenshot(PNMImage &image) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::make_cull_result_graph
// Access: Public
// Description: Returns a special scene graph constructed to
// represent the results of the last frame's cull
// operation.
//
// This will be a hierarchy of nodes, one node for each
// bin, each of which will in term be a parent of a
// number of GeomNodes, representing the geometry drawn
// in each bin.
//
// This is useful mainly for high-level debugging and
// abstraction tools; it should not be mistaken for the
// low-level cull result itself, which is constructed
// and maintained internally. No such scene graph is
// normally constructed during the rendering of a frame;
// this is an artificial construct created for the
// purpose of making it easy to analyze the results of
// the cull operation.
////////////////////////////////////////////////////////////////////
PT(PandaNode) DisplayRegion::
make_cull_result_graph() {
CullResult *cull_result = get_cull_result(Thread::get_current_thread());
if (cull_result == (CullResult *)NULL) {
return NULL;
}
return cull_result->make_result_graph();
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::win_display_regions_changed
// Access: Private

View File

@ -125,6 +125,8 @@ PUBLISHED:
const Filename &filename, const string &image_comment = "");
bool get_screenshot(PNMImage &image);
PT(PandaNode) make_cull_result_graph();
public:
INLINE void set_cull_result(CullResult *cull_result, SceneSetup *scene_setup,
Thread *current_thread);

View File

@ -845,6 +845,7 @@ do_enable_default_keys() {
define_key("shift-c", "toggle collision surfaces", event_C, this);
define_key("shift-b", "report bounding volume", event_B, this);
define_key("shift-l", "list hierarchy", event_L, this);
define_key("shift-a", "analyze hierarchy", event_A, this);
define_key("h", "highlight node", event_h, this);
define_key("arrow_up", "move highlight to parent", event_arrow_up, this);
define_key("arrow_down", "move highlight to child", event_arrow_down, this);
@ -1110,6 +1111,24 @@ event_L(const Event *, void *data) {
node.ls();
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::event_A
// Access: Public, Static
// Description: Default handler for shift-A key: analyze the contents
// of the scene graph, or the highlighted node.
////////////////////////////////////////////////////////////////////
void PandaFramework::
event_A(const Event *, void *data) {
PandaFramework *self = (PandaFramework *)data;
NodePath node = self->get_highlight();
if (node.is_empty()) {
node = self->get_models();
}
node.analyze();
}
////////////////////////////////////////////////////////////////////
// Function: PandaFramework::event_h
// Access: Public, Static

View File

@ -136,6 +136,7 @@ public:
static void event_C(const Event *, void *data);
static void event_B(const Event *, void *data);
static void event_L(const Event *, void *data);
static void event_A(const Event *, void *data);
static void event_h(const Event *, void *data);
static void event_arrow_up(const Event *, void *data);
static void event_arrow_down(const Event *, void *data);

View File

@ -18,6 +18,11 @@
#include "cullBin.h"
#include "config_pgraph.h"
#include "pandaNode.h"
#include "geomNode.h"
#include "cullableObject.h"
#include "decalEffect.h"
#include "string_utils.h"
PStatCollector CullBin::_cull_bin_pcollector("Cull:Sort");
@ -63,6 +68,29 @@ void CullBin::
finish_cull(SceneSetup *, Thread *) {
}
////////////////////////////////////////////////////////////////////
// Function: CullBin::make_result_graph
// Access: Public
// Description: Returns a special scene graph constructed to
// represent the results of the cull. This will be a
// single node with a list of GeomNode children, which
// represent the various geom objects discovered by the
// cull.
//
// This is useful mainly for high-level debugging and
// abstraction tools; it should not be mistaken for the
// low-level cull result itself. For the low-level cull
// result, use draw() to efficiently draw the culled
// scene.
////////////////////////////////////////////////////////////////////
PT(PandaNode) CullBin::
make_result_graph() {
PT(PandaNode) root_node = new PandaNode(get_name());
ResultGraphBuilder builder(root_node);
fill_result_graph(builder);
return root_node;
}
////////////////////////////////////////////////////////////////////
// Function: CullBin::check_flash_color
// Access: Private
@ -96,3 +124,98 @@ check_flash_color() {
}
#endif // NDEBUG
}
////////////////////////////////////////////////////////////////////
// Function: CullBin::ResultGraphBuilder::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CullBin::ResultGraphBuilder::
ResultGraphBuilder(PandaNode *root_node) :
_root_node(root_node),
_object_index(0)
{
}
////////////////////////////////////////////////////////////////////
// Function: CullBin::ResultGraphBuilder::add_object
// Access: Public
// Description: Called in fill_result_graph() by a derived CullBin
// class to add each culled object to the result
// returned by make_result_graph().
////////////////////////////////////////////////////////////////////
void CullBin::ResultGraphBuilder::
add_object(CullableObject *object) {
if (_current_transform != object->_modelview_transform ||
_current_state != object->_state ||
object->_next != (CullableObject *)NULL) {
// Create a new GeomNode to hold the net transform and state. We
// choose to create a new GeomNode for each new state, to make it
// clearer to the observer when the state changes.
_current_transform = object->_modelview_transform;
_current_state = object->_state;
_current_node = new GeomNode("object_" + format_string(_object_index));
_root_node->add_child(_current_node);
_current_node->set_transform(_current_transform);
_current_node->set_state(_current_state);
}
record_one_object(_current_node, object);
if (object->_next != (CullableObject *)NULL) {
// Collect the decal base pieces.
CullableObject *base = object->_next;
while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) {
record_one_object(_current_node, base);
base = base->_next;
}
if (base != (CullableObject *)NULL) {
// Now, collect all the decals.
_current_node->set_effect(DecalEffect::make());
int decal_index = 0;
CPT(TransformState) transform;
CPT(RenderState) state;
PT(GeomNode) decal_node;
CullableObject *decal = base->_next;
while (decal != (CullableObject *)NULL) {
if (transform != decal->_modelview_transform ||
state != decal->_state ||
decal->_next != (CullableObject *)NULL) {
// Create a new GeomNode to hold the net transform.
transform = decal->_modelview_transform;
state = decal->_state;
decal_node = new GeomNode("decal_" + format_string(decal_index));
_current_node->add_child(decal_node);
decal_node->set_transform(transform);
decal_node->set_state(state);
}
record_one_object(decal_node, decal);
decal = decal->_next;
++decal_index;
}
}
// Reset the current node pointer for next time so the decal root
// will remain in its own node.
_current_node.clear();
_current_transform.clear();
_current_state.clear();
}
++_object_index;
}
////////////////////////////////////////////////////////////////////
// Function: CullBin::ResultGraphBuilder::record_one_object
// Access: Private
// Description: Records a single object, without regard to decalling.
////////////////////////////////////////////////////////////////////
void CullBin::ResultGraphBuilder::
record_one_object(GeomNode *node, CullableObject *object) {
PT(Geom) new_geom = object->_geom->make_copy();
new_geom->set_vertex_data(object->_munged_data);
node->add_geom(new_geom);
}

View File

@ -29,6 +29,10 @@
class CullableObject;
class GraphicsStateGuardianBase;
class SceneSetup;
class TransformState;
class RenderState;
class PandaNode;
class GeomNode;
////////////////////////////////////////////////////////////////////
// Class : CullBin
@ -60,9 +64,15 @@ public:
virtual void draw(bool force, Thread *current_thread)=0;
PT(PandaNode) make_result_graph();
INLINE bool has_flash_color() const;
INLINE const Colorf &get_flash_color() const;
protected:
class ResultGraphBuilder;
virtual void fill_result_graph(ResultGraphBuilder &builder)=0;
private:
void check_flash_color();
@ -74,6 +84,23 @@ protected:
bool _has_flash_color;
Colorf _flash_color;
// Used in make_result_graph() and fill_result_graph().
class ResultGraphBuilder {
public:
ResultGraphBuilder(PandaNode *root_node);
void add_object(CullableObject *object);
private:
void record_one_object(GeomNode *node, CullableObject *object);
private:
int _object_index;
CPT(TransformState) _current_transform;
CPT(RenderState) _current_state;
PT(PandaNode) _root_node;
PT(GeomNode) _current_node;
};
static PStatCollector _cull_bin_pcollector;
PStatCollector _cull_this_pcollector;
PStatCollector _draw_this_pcollector;

View File

@ -270,6 +270,41 @@ draw(Thread *current_thread) {
}
}
////////////////////////////////////////////////////////////////////
// Function: CullResult::make_result_graph
// Access: Public
// Description: Returns a special scene graph constructed to
// represent the results of the cull. This will be a
// hierarchy of nodes, one node for each bin, each of
// which will in term be a parent of a number of
// GeomNodes, representing the geometry drawn in each
// bin.
//
// This is useful mainly for high-level debugging and
// abstraction tools; it should not be mistaken for the
// low-level cull result itself. For the low-level cull
// result, use draw() to efficiently draw the culled
// scene.
////////////////////////////////////////////////////////////////////
PT(PandaNode) CullResult::
make_result_graph() {
PT(PandaNode) root_node = new PandaNode("cull_result");
// Ask the bin manager for the correct order to draw all the bins.
CullBinManager *bin_manager = CullBinManager::get_global_ptr();
int num_bins = bin_manager->get_num_bins();
for (int i = 0; i < num_bins; i++) {
int bin_index = bin_manager->get_bin(i);
nassertr(bin_index >= 0, NULL);
if (bin_index < (int)_bins.size() && _bins[bin_index] != (CullBin *)NULL) {
root_node->add_child(_bins[bin_index]->make_result_graph());
}
}
return root_node;
}
////////////////////////////////////////////////////////////////////
// Function: CullResult::bin_removed
// Access: Public, Static

View File

@ -63,6 +63,8 @@ public:
void finish_cull(SceneSetup *scene_setup, Thread *current_thread);
void draw(Thread *current_thread);
PT(PandaNode) make_result_graph();
public:
static void bin_removed(int bin_index);