Panda3D
|
00001 // Filename: cullBin.cxx 00002 // Created by: drose (28Feb02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "cullBin.h" 00016 #include "config_pgraph.h" 00017 #include "pandaNode.h" 00018 #include "geomNode.h" 00019 #include "cullableObject.h" 00020 #include "decalEffect.h" 00021 #include "string_utils.h" 00022 00023 PStatCollector CullBin::_cull_bin_pcollector("Cull:Sort"); 00024 00025 TypeHandle CullBin::_type_handle; 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: CullBin::Destructor 00029 // Access: Public, Virtual 00030 // Description: 00031 //////////////////////////////////////////////////////////////////// 00032 CullBin:: 00033 ~CullBin() { 00034 } 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: CullBin::make_next 00038 // Access: Public, Virtual 00039 // Description: Returns a newly-allocated CullBin object that 00040 // contains a copy of just the subset of the data from 00041 // this CullBin object that is worth keeping around 00042 // for next frame. 00043 // 00044 // If a particular CullBin object has no data worth 00045 // preserving till next frame, it is acceptable to 00046 // return NULL (which is the default behavior of this 00047 // method). 00048 //////////////////////////////////////////////////////////////////// 00049 PT(CullBin) CullBin:: 00050 make_next() const { 00051 return (CullBin *)NULL; 00052 } 00053 00054 //////////////////////////////////////////////////////////////////// 00055 // Function: CullBin::finish_cull 00056 // Access: Public, Virtual 00057 // Description: Called after all the geoms have been added, this 00058 // indicates that the cull process is finished for this 00059 // frame and gives the bins a chance to do any 00060 // post-processing (like sorting) before moving on to 00061 // draw. 00062 //////////////////////////////////////////////////////////////////// 00063 void CullBin:: 00064 finish_cull(SceneSetup *, Thread *) { 00065 } 00066 00067 //////////////////////////////////////////////////////////////////// 00068 // Function: CullBin::make_result_graph 00069 // Access: Public 00070 // Description: Returns a special scene graph constructed to 00071 // represent the results of the cull. This will be a 00072 // single node with a list of GeomNode children, which 00073 // represent the various geom objects discovered by the 00074 // cull. 00075 // 00076 // This is useful mainly for high-level debugging and 00077 // abstraction tools; it should not be mistaken for the 00078 // low-level cull result itself. For the low-level cull 00079 // result, use draw() to efficiently draw the culled 00080 // scene. 00081 //////////////////////////////////////////////////////////////////// 00082 PT(PandaNode) CullBin:: 00083 make_result_graph() { 00084 PT(PandaNode) root_node = new PandaNode(get_name()); 00085 ResultGraphBuilder builder(root_node); 00086 fill_result_graph(builder); 00087 return root_node; 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: CullBin::check_flash_color 00092 // Access: Private 00093 // Description: Checks the config variables for a user variable of 00094 // the name flash-bin-binname. If found, it defines the 00095 // r g b color to flash geometry in this bin. 00096 //////////////////////////////////////////////////////////////////// 00097 void CullBin:: 00098 check_flash_color() { 00099 #ifdef NDEBUG 00100 _has_flash_color = false; 00101 #else 00102 ConfigVariableDouble flash_bin 00103 ("flash-bin-" + _name, "", "", ConfigVariable::F_dynamic); 00104 if (flash_bin.get_num_words() == 0) { 00105 _has_flash_color = false; 00106 00107 } else if (flash_bin.get_num_words() == 3) { 00108 _has_flash_color = true; 00109 _flash_color.set(flash_bin[0], flash_bin[1], flash_bin[2], 1.0f); 00110 00111 } else if (flash_bin.get_num_words() == 4) { 00112 _has_flash_color = true; 00113 _flash_color.set(flash_bin[0], flash_bin[1], flash_bin[2], flash_bin[3]); 00114 00115 } else { 00116 _has_flash_color = false; 00117 pgraph_cat.warning() 00118 << "Invalid value for flash-bin-" << _name << ": " 00119 << flash_bin.get_string_value() << "\n"; 00120 } 00121 #endif // NDEBUG 00122 } 00123 00124 //////////////////////////////////////////////////////////////////// 00125 // Function: CullBin::ResultGraphBuilder::Constructor 00126 // Access: Public 00127 // Description: 00128 //////////////////////////////////////////////////////////////////// 00129 CullBin::ResultGraphBuilder:: 00130 ResultGraphBuilder(PandaNode *root_node) : 00131 _object_index(0), 00132 _root_node(root_node) 00133 { 00134 } 00135 00136 //////////////////////////////////////////////////////////////////// 00137 // Function: CullBin::ResultGraphBuilder::add_object 00138 // Access: Public 00139 // Description: Called in fill_result_graph() by a derived CullBin 00140 // class to add each culled object to the result 00141 // returned by make_result_graph(). 00142 //////////////////////////////////////////////////////////////////// 00143 void CullBin::ResultGraphBuilder:: 00144 add_object(CullableObject *object) { 00145 if (_current_transform != object->_modelview_transform || 00146 _current_state != object->_state || 00147 object->is_fancy()) { 00148 // Create a new GeomNode to hold the net transform and state. We 00149 // choose to create a new GeomNode for each new state, to make it 00150 // clearer to the observer when the state changes. 00151 _current_transform = object->_modelview_transform; 00152 _current_state = object->_state; 00153 _current_node = new GeomNode("object_" + format_string(_object_index)); 00154 _root_node->add_child(_current_node); 00155 _current_node->set_transform(_current_transform); 00156 _current_node->set_state(_current_state); 00157 } 00158 00159 record_one_object(_current_node, object); 00160 00161 if (object->get_next() != (CullableObject *)NULL) { 00162 // Collect the decal base pieces. 00163 CullableObject *base = object->get_next(); 00164 while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) { 00165 record_one_object(_current_node, base); 00166 base = base->get_next(); 00167 } 00168 00169 if (base != (CullableObject *)NULL) { 00170 // Now, collect all the decals. 00171 _current_node->set_effect(DecalEffect::make()); 00172 int decal_index = 0; 00173 00174 CPT(TransformState) transform; 00175 CPT(RenderState) state; 00176 PT(GeomNode) decal_node; 00177 CullableObject *decal = base->get_next(); 00178 while (decal != (CullableObject *)NULL) { 00179 if (transform != decal->_modelview_transform || 00180 state != decal->_state || 00181 decal->get_next() != (CullableObject *)NULL) { 00182 // Create a new GeomNode to hold the net transform. 00183 transform = decal->_modelview_transform; 00184 state = decal->_state; 00185 decal_node = new GeomNode("decal_" + format_string(decal_index)); 00186 _current_node->add_child(decal_node); 00187 decal_node->set_transform(transform); 00188 decal_node->set_state(state); 00189 } 00190 00191 record_one_object(decal_node, decal); 00192 decal = decal->get_next(); 00193 ++decal_index; 00194 } 00195 } 00196 00197 // Reset the current node pointer for next time so the decal root 00198 // will remain in its own node. 00199 _current_node.clear(); 00200 _current_transform.clear(); 00201 _current_state.clear(); 00202 } 00203 00204 ++_object_index; 00205 } 00206 00207 //////////////////////////////////////////////////////////////////// 00208 // Function: CullBin::ResultGraphBuilder::record_one_object 00209 // Access: Private 00210 // Description: Records a single object, without regard to decalling. 00211 //////////////////////////////////////////////////////////////////// 00212 void CullBin::ResultGraphBuilder:: 00213 record_one_object(GeomNode *node, CullableObject *object) { 00214 PT(Geom) new_geom = object->_geom->make_copy(); 00215 new_geom->set_vertex_data(object->_munged_data); 00216 node->add_geom(new_geom); 00217 }