00001 // Filename: lodNode.cxx 00002 // Created by: drose (06Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "lodNode.h" 00020 #include "cullTraverserData.h" 00021 #include "cullTraverser.h" 00022 00023 TypeHandle LODNode::_type_handle; 00024 00025 //////////////////////////////////////////////////////////////////// 00026 // Function: LODNode::CData::make_copy 00027 // Access: Public, Virtual 00028 // Description: 00029 //////////////////////////////////////////////////////////////////// 00030 CycleData *LODNode::CData:: 00031 make_copy() const { 00032 return new CData(*this); 00033 } 00034 00035 //////////////////////////////////////////////////////////////////// 00036 // Function: LODNode::CData::write_datagram 00037 // Access: Public, Virtual 00038 // Description: Writes the contents of this object to the datagram 00039 // for shipping out to a Bam file. 00040 //////////////////////////////////////////////////////////////////// 00041 void LODNode::CData:: 00042 write_datagram(BamWriter *manager, Datagram &dg) const { 00043 _lod.write_datagram(dg); 00044 } 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Function: LODNode::CData::fillin 00048 // Access: Public, Virtual 00049 // Description: This internal function is called by make_from_bam to 00050 // read in all of the relevant data from the BamFile for 00051 // the new LODNode. 00052 //////////////////////////////////////////////////////////////////// 00053 void LODNode::CData:: 00054 fillin(DatagramIterator &scan, BamReader *manager) { 00055 _lod.read_datagram(scan); 00056 } 00057 00058 //////////////////////////////////////////////////////////////////// 00059 // Function: LODNode::make_copy 00060 // Access: Public, Virtual 00061 // Description: Returns a newly-allocated Node that is a shallow copy 00062 // of this one. It will be a different Node pointer, 00063 // but its internal data may or may not be shared with 00064 // that of the original Node. 00065 //////////////////////////////////////////////////////////////////// 00066 PandaNode *LODNode:: 00067 make_copy() const { 00068 return new LODNode(*this); 00069 } 00070 00071 //////////////////////////////////////////////////////////////////// 00072 // Function: LODNode::safe_to_combine 00073 // Access: Public, Virtual 00074 // Description: Returns true if it is generally safe to combine this 00075 // particular kind of PandaNode with other kinds of 00076 // PandaNodes, adding children or whatever. For 00077 // instance, an LODNode should not be combined with any 00078 // other PandaNode, because its set of children is 00079 // meaningful. 00080 //////////////////////////////////////////////////////////////////// 00081 bool LODNode:: 00082 safe_to_combine() const { 00083 return false; 00084 } 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Function: LODNode::xform 00088 // Access: Public, Virtual 00089 // Description: Transforms the contents of this PandaNode by the 00090 // indicated matrix, if it means anything to do so. For 00091 // most kinds of PandaNodes, this does nothing. 00092 //////////////////////////////////////////////////////////////////// 00093 void LODNode:: 00094 xform(const LMatrix4f &mat) { 00095 CDWriter cdata(_cycler); 00096 cdata->_lod.xform(mat); 00097 } 00098 00099 //////////////////////////////////////////////////////////////////// 00100 // Function: LODNode::has_cull_callback 00101 // Access: Public, Virtual 00102 // Description: Should be overridden by derived classes to return 00103 // true if cull_callback() has been defined. Otherwise, 00104 // returns false to indicate cull_callback() does not 00105 // need to be called for this node during the cull 00106 // traversal. 00107 //////////////////////////////////////////////////////////////////// 00108 bool LODNode:: 00109 has_cull_callback() const { 00110 return true; 00111 } 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Function: LODNode::cull_callback 00115 // Access: Public, Virtual 00116 // Description: If has_cull_callback() returns true, this function 00117 // will be called during the cull traversal to perform 00118 // any additional operations that should be performed at 00119 // cull time. This may include additional manipulation 00120 // of render state or additional visible/invisible 00121 // decisions, or any other arbitrary operation. 00122 // 00123 // By the time this function is called, the node has 00124 // already passed the bounding-volume test for the 00125 // viewing frustum, and the node's transform and state 00126 // have already been applied to the indicated 00127 // CullTraverserData object. 00128 // 00129 // The return value is true if this node should be 00130 // visible, or false if it should be culled. 00131 //////////////////////////////////////////////////////////////////// 00132 bool LODNode:: 00133 cull_callback(CullTraverser *trav, CullTraverserData &data) { 00134 if (data._net_transform->is_singular()) { 00135 // If we're under a singular transform, we can't compute the LOD; 00136 // select none of them instead. 00137 select_child(get_num_children()); 00138 00139 } else { 00140 CDReader cdata(_cycler); 00141 LPoint3f camera_pos(0, 0, 0); 00142 00143 // Get the LOD center in camera space 00144 CPT(TransformState) rel_transform = 00145 trav->get_camera_transform()->invert_compose(data._net_transform); 00146 LPoint3f center = cdata->_lod._center * rel_transform->get_mat(); 00147 00148 // Determine which child to traverse 00149 int index = cdata->_lod.compute_child(camera_pos, center); 00150 select_child(index); 00151 } 00152 00153 return true; 00154 } 00155 00156 //////////////////////////////////////////////////////////////////// 00157 // Function: LODNode::output 00158 // Access: Public, Virtual 00159 // Description: 00160 //////////////////////////////////////////////////////////////////// 00161 void LODNode:: 00162 output(ostream &out) const { 00163 SelectiveChildNode::output(out); 00164 CDReader cdata(_cycler); 00165 out << " "; 00166 cdata->_lod.output(out); 00167 } 00168 00169 //////////////////////////////////////////////////////////////////// 00170 // Function: LODNode::register_with_read_factory 00171 // Access: Public, Static 00172 // Description: Tells the BamReader how to create objects of type 00173 // LODNode. 00174 //////////////////////////////////////////////////////////////////// 00175 void LODNode:: 00176 register_with_read_factory() { 00177 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00178 } 00179 00180 //////////////////////////////////////////////////////////////////// 00181 // Function: LODNode::write_datagram 00182 // Access: Public, Virtual 00183 // Description: Writes the contents of this object to the datagram 00184 // for shipping out to a Bam file. 00185 //////////////////////////////////////////////////////////////////// 00186 void LODNode:: 00187 write_datagram(BamWriter *manager, Datagram &dg) { 00188 SelectiveChildNode::write_datagram(manager, dg); 00189 manager->write_cdata(dg, _cycler); 00190 } 00191 00192 //////////////////////////////////////////////////////////////////// 00193 // Function: LODNode::make_from_bam 00194 // Access: Protected, Static 00195 // Description: This function is called by the BamReader's factory 00196 // when a new object of type LODNode is encountered 00197 // in the Bam file. It should create the LODNode 00198 // and extract its information from the file. 00199 //////////////////////////////////////////////////////////////////// 00200 TypedWritable *LODNode:: 00201 make_from_bam(const FactoryParams ¶ms) { 00202 LODNode *node = new LODNode(""); 00203 DatagramIterator scan; 00204 BamReader *manager; 00205 00206 parse_params(params, scan, manager); 00207 node->fillin(scan, manager); 00208 00209 return node; 00210 } 00211 00212 //////////////////////////////////////////////////////////////////// 00213 // Function: LODNode::fillin 00214 // Access: Protected 00215 // Description: This internal function is called by make_from_bam to 00216 // read in all of the relevant data from the BamFile for 00217 // the new LODNode. 00218 //////////////////////////////////////////////////////////////////// 00219 void LODNode:: 00220 fillin(DatagramIterator &scan, BamReader *manager) { 00221 SelectiveChildNode::fillin(scan, manager); 00222 manager->read_cdata(scan, _cycler); 00223 }