|
@@ -18,6 +18,11 @@
|
|
|
|
|
|
|
|
#include "cullBin.h"
|
|
#include "cullBin.h"
|
|
|
#include "config_pgraph.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");
|
|
PStatCollector CullBin::_cull_bin_pcollector("Cull:Sort");
|
|
|
|
|
|
|
@@ -63,6 +68,29 @@ void CullBin::
|
|
|
finish_cull(SceneSetup *, Thread *) {
|
|
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
|
|
// Function: CullBin::check_flash_color
|
|
|
// Access: Private
|
|
// Access: Private
|
|
@@ -96,3 +124,98 @@ check_flash_color() {
|
|
|
}
|
|
}
|
|
|
#endif // NDEBUG
|
|
#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);
|
|
|
|
|
+}
|