00001 // Filename: callbackNode.cxx 00002 // Created by: drose (13Mar09) 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 "pandabase.h" 00016 #include "callbackNode.h" 00017 #include "cullTraverser.h" 00018 #include "nodeCullCallbackData.h" 00019 #include "cullableObject.h" 00020 #include "cullHandler.h" 00021 #include "omniBoundingVolume.h" 00022 #include "config_pgraph.h" 00023 00024 TypeHandle CallbackNode::_type_handle; 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Function: CallbackNode::Constructor 00028 // Access: Published 00029 // Description: 00030 //////////////////////////////////////////////////////////////////// 00031 CallbackNode:: 00032 CallbackNode(const string &name) : 00033 PandaNode(name) 00034 { 00035 PandaNode::set_cull_callback(); 00036 00037 // Set up a default, infinite bounding volume, unless the user tells 00038 // us otherwise. Not sure if this is a great idea, because it means 00039 // a naive user will never set the bounding volume and always 00040 // trigger the callback--but that's not altogether a bad default 00041 // behavior. 00042 set_internal_bounds(new OmniBoundingVolume); 00043 } 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Function: CallbackNode::Copy Constructor 00047 // Access: Protected 00048 // Description: 00049 //////////////////////////////////////////////////////////////////// 00050 CallbackNode:: 00051 CallbackNode(const CallbackNode ©) : 00052 PandaNode(copy), 00053 _cycler(copy._cycler) 00054 { 00055 } 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: CallbackNode::make_copy 00059 // Access: Public, Virtual 00060 // Description: Returns a newly-allocated Node that is a shallow copy 00061 // of this one. It will be a different Node pointer, 00062 // but its internal data may or may not be shared with 00063 // that of the original Node. 00064 //////////////////////////////////////////////////////////////////// 00065 PandaNode *CallbackNode:: 00066 make_copy() const { 00067 return new CallbackNode(*this); 00068 } 00069 00070 //////////////////////////////////////////////////////////////////// 00071 // Function: CallbackNode::safe_to_combine 00072 // Access: Public, Virtual 00073 // Description: Returns true if it is generally safe to combine this 00074 // particular kind of PandaNode with other kinds of 00075 // PandaNodes of compatible type, adding children or 00076 // whatever. For instance, an LODNode should not be 00077 // combined with any other PandaNode, because its set of 00078 // children is meaningful. 00079 //////////////////////////////////////////////////////////////////// 00080 bool CallbackNode:: 00081 safe_to_combine() const { 00082 return false; 00083 } 00084 00085 //////////////////////////////////////////////////////////////////// 00086 // Function: CallbackNode::cull_callback 00087 // Access: Public, Virtual 00088 // Description: This function will be called during the cull 00089 // traversal to perform any additional operations that 00090 // should be performed at cull time. This may include 00091 // additional manipulation of render state or additional 00092 // visible/invisible decisions, or any other arbitrary 00093 // operation. 00094 // 00095 // Note that this function will *not* be called unless 00096 // set_cull_callback() is called in the constructor of 00097 // the derived class. It is necessary to call 00098 // set_cull_callback() to indicated that we require 00099 // cull_callback() to be called. 00100 // 00101 // By the time this function is called, the node has 00102 // already passed the bounding-volume test for the 00103 // viewing frustum, and the node's transform and state 00104 // have already been applied to the indicated 00105 // CullTraverserData object. 00106 // 00107 // The return value is true if this node should be 00108 // visible, or false if it should be culled. 00109 //////////////////////////////////////////////////////////////////// 00110 bool CallbackNode:: 00111 cull_callback(CullTraverser *trav, CullTraverserData &data) { 00112 CallbackObject *cbobj = get_cull_callback(); 00113 if (cbobj != (CallbackObject *)NULL) { 00114 NodeCullCallbackData cbdata(trav, data); 00115 cbobj->do_callback(&cbdata); 00116 00117 // No further cull: the callback takes care of all of it. 00118 return false; 00119 } 00120 00121 // Recurse onto the node's children. 00122 return true; 00123 } 00124 00125 //////////////////////////////////////////////////////////////////// 00126 // Function: CallbackNode::is_renderable 00127 // Access: Public, Virtual 00128 // Description: Returns true if there is some value to visiting this 00129 // particular node during the cull traversal for any 00130 // camera, false otherwise. This will be used to 00131 // optimize the result of get_net_draw_show_mask(), so 00132 // that any subtrees that contain only nodes for which 00133 // is_renderable() is false need not be visited. 00134 //////////////////////////////////////////////////////////////////// 00135 bool CallbackNode:: 00136 is_renderable() const { 00137 return true; 00138 } 00139 00140 //////////////////////////////////////////////////////////////////// 00141 // Function: CallbackNode::add_for_draw 00142 // Access: Public, Virtual 00143 // Description: Adds the node's contents to the CullResult we are 00144 // building up during the cull traversal, so that it 00145 // will be drawn at render time. For most nodes other 00146 // than GeomNodes, this is a do-nothing operation. 00147 //////////////////////////////////////////////////////////////////// 00148 void CallbackNode:: 00149 add_for_draw(CullTraverser *trav, CullTraverserData &data) { 00150 if (pgraph_cat.is_spam()) { 00151 pgraph_cat.spam() 00152 << "Found " << *this << " in state " << *data._state 00153 << " draw_mask = " << data._draw_mask << "\n"; 00154 } 00155 00156 // OK, render this node. Rendering this node means creating a 00157 // CullableObject for the draw_callback, if any. We don't need to 00158 // pass any Geoms, however. 00159 CallbackObject *cbobj = get_draw_callback(); 00160 if (cbobj != (CallbackObject *)NULL) { 00161 CullableObject *object = 00162 new CullableObject(NULL, data._state, 00163 data.get_net_transform(trav), 00164 data.get_modelview_transform(trav), 00165 trav->get_gsg()); 00166 object->set_draw_callback(cbobj); 00167 trav->get_cull_handler()->record_object(object, trav); 00168 } 00169 } 00170 00171 //////////////////////////////////////////////////////////////////// 00172 // Function: CallbackNode::output 00173 // Access: Public, Virtual 00174 // Description: Writes a brief description of the node to the 00175 // indicated output stream. This is invoked by the << 00176 // operator. It may be overridden in derived classes to 00177 // include some information relevant to the class. 00178 //////////////////////////////////////////////////////////////////// 00179 void CallbackNode:: 00180 output(ostream &out) const { 00181 PandaNode::output(out); 00182 } 00183 00184 //////////////////////////////////////////////////////////////////// 00185 // Function: CallbackNode::register_with_read_factory 00186 // Access: Public, Static 00187 // Description: Tells the BamReader how to create objects of type 00188 // CallbackNode. 00189 //////////////////////////////////////////////////////////////////// 00190 void CallbackNode:: 00191 register_with_read_factory() { 00192 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00193 } 00194 00195 //////////////////////////////////////////////////////////////////// 00196 // Function: CallbackNode::write_datagram 00197 // Access: Public, Virtual 00198 // Description: Writes the contents of this object to the datagram 00199 // for shipping out to a Bam file. 00200 //////////////////////////////////////////////////////////////////// 00201 void CallbackNode:: 00202 write_datagram(BamWriter *manager, Datagram &dg) { 00203 PandaNode::write_datagram(manager, dg); 00204 manager->write_cdata(dg, _cycler); 00205 } 00206 00207 //////////////////////////////////////////////////////////////////// 00208 // Function: CallbackNode::make_from_bam 00209 // Access: Protected, Static 00210 // Description: This function is called by the BamReader's factory 00211 // when a new object of type CallbackNode is encountered 00212 // in the Bam file. It should create the CallbackNode 00213 // and extract its information from the file. 00214 //////////////////////////////////////////////////////////////////// 00215 TypedWritable *CallbackNode:: 00216 make_from_bam(const FactoryParams ¶ms) { 00217 CallbackNode *node = new CallbackNode(""); 00218 DatagramIterator scan; 00219 BamReader *manager; 00220 00221 parse_params(params, scan, manager); 00222 node->fillin(scan, manager); 00223 00224 return node; 00225 } 00226 00227 //////////////////////////////////////////////////////////////////// 00228 // Function: CallbackNode::fillin 00229 // Access: Protected 00230 // Description: This internal function is called by make_from_bam to 00231 // read in all of the relevant data from the BamFile for 00232 // the new CallbackNode. 00233 //////////////////////////////////////////////////////////////////// 00234 void CallbackNode:: 00235 fillin(DatagramIterator &scan, BamReader *manager) { 00236 PandaNode::fillin(scan, manager); 00237 manager->read_cdata(scan, _cycler); 00238 } 00239 00240 //////////////////////////////////////////////////////////////////// 00241 // Function: CallbackNode::CData::make_copy 00242 // Access: Public, Virtual 00243 // Description: 00244 //////////////////////////////////////////////////////////////////// 00245 CycleData *CallbackNode::CData:: 00246 make_copy() const { 00247 return new CData(*this); 00248 } 00249 00250 //////////////////////////////////////////////////////////////////// 00251 // Function: CallbackNode::CData::write_datagram 00252 // Access: Public, Virtual 00253 // Description: Writes the contents of this object to the datagram 00254 // for shipping out to a Bam file. 00255 //////////////////////////////////////////////////////////////////// 00256 void CallbackNode::CData:: 00257 write_datagram(BamWriter *manager, Datagram &dg) const { 00258 } 00259 00260 //////////////////////////////////////////////////////////////////// 00261 // Function: CallbackNode::CData::fillin 00262 // Access: Public, Virtual 00263 // Description: This internal function is called by make_from_bam to 00264 // read in all of the relevant data from the BamFile for 00265 // the new CallbackNode. 00266 //////////////////////////////////////////////////////////////////// 00267 void CallbackNode::CData:: 00268 fillin(DatagramIterator &scan, BamReader *manager) { 00269 }