Panda3D
|
00001 // Filename: lensNode.cxx 00002 // Created by: drose (26Feb02) 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 "lensNode.h" 00016 #include "geometricBoundingVolume.h" 00017 #include "bamWriter.h" 00018 #include "bamReader.h" 00019 #include "datagram.h" 00020 #include "datagramIterator.h" 00021 #include "perspectiveLens.h" 00022 #include "geomNode.h" 00023 00024 TypeHandle LensNode::_type_handle; 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Function: LensNode::Constructor 00028 // Access: Published 00029 // Description: 00030 //////////////////////////////////////////////////////////////////// 00031 LensNode:: 00032 LensNode(const string &name, Lens *lens) : 00033 PandaNode(name) 00034 { 00035 if (lens == NULL) { 00036 lens = new PerspectiveLens; 00037 } 00038 set_lens(0, lens); 00039 } 00040 00041 //////////////////////////////////////////////////////////////////// 00042 // Function: LensNode::Copy Constructor 00043 // Access: Protected 00044 // Description: 00045 //////////////////////////////////////////////////////////////////// 00046 LensNode:: 00047 LensNode(const LensNode ©) : 00048 PandaNode(copy), 00049 _lenses(copy._lenses) 00050 { 00051 } 00052 00053 //////////////////////////////////////////////////////////////////// 00054 // Function: LensNode::xform 00055 // Access: Published, Virtual 00056 // Description: Transforms the contents of this PandaNode by the 00057 // indicated matrix, if it means anything to do so. For 00058 // most kinds of PandaNodes, this does nothing. 00059 //////////////////////////////////////////////////////////////////// 00060 void LensNode:: 00061 xform(const LMatrix4 &mat) { 00062 PandaNode::xform(mat); 00063 // We need to actually transform the lens here. 00064 } 00065 00066 //////////////////////////////////////////////////////////////////// 00067 // Function: LensNode::make_copy 00068 // Access: Published, Virtual 00069 // Description: Returns a newly-allocated Node that is a shallow copy 00070 // of this one. It will be a different Node pointer, 00071 // but its internal data may or may not be shared with 00072 // that of the original Node. 00073 //////////////////////////////////////////////////////////////////// 00074 PandaNode *LensNode:: 00075 make_copy() const { 00076 return new LensNode(*this); 00077 } 00078 00079 //////////////////////////////////////////////////////////////////// 00080 // Function: LensNode::set_lens 00081 // Access: Published 00082 // Description: Sets the indicated lens. Although a LensNode 00083 // normally holds only one lens, it may optionally 00084 // include multiple lenses, each with a different index 00085 // number. The different lenses may be referenced by 00086 // index number on the DisplayRegion. Adding a new lens 00087 // automatically makes it active. 00088 //////////////////////////////////////////////////////////////////// 00089 void LensNode:: 00090 set_lens(int index, Lens *lens) { 00091 nassertv(index >= 0 && index < max_lenses); // Sanity check 00092 00093 while (index >= (int)_lenses.size()) { 00094 LensSlot slot; 00095 slot._is_active = false; 00096 _lenses.push_back(slot); 00097 } 00098 00099 _lenses[index]._lens = lens; 00100 _lenses[index]._is_active = true; 00101 00102 if (_shown_frustum != (PandaNode *)NULL) { 00103 show_frustum(); 00104 } 00105 } 00106 00107 //////////////////////////////////////////////////////////////////// 00108 // Function: LensNode::set_lens_active 00109 // Access: Published 00110 // Description: Sets the active flag for the nth lens. When a lens 00111 // is inactive, it is not used for rendering, and any 00112 // DisplayRegions associated with it are implicitly 00113 // inactive as well. Returns true if the flag is 00114 // changed, false if it already had this value. 00115 //////////////////////////////////////////////////////////////////// 00116 bool LensNode:: 00117 set_lens_active(int index, bool flag) { 00118 nassertr(index >= 0 && index < max_lenses, false); 00119 00120 while (index >= (int)_lenses.size()) { 00121 LensSlot slot; 00122 slot._is_active = false; 00123 _lenses.push_back(slot); 00124 } 00125 00126 if (_lenses[index]._is_active == flag) { 00127 return false; 00128 } 00129 00130 _lenses[index]._is_active = flag; 00131 00132 if (_shown_frustum != (PandaNode *)NULL) { 00133 show_frustum(); 00134 } 00135 return true; 00136 } 00137 00138 //////////////////////////////////////////////////////////////////// 00139 // Function: LensNode::is_in_view 00140 // Access: Published 00141 // Description: Returns true if the given point is within the bounds 00142 // of the lens of the LensNode (i.e. if the camera can 00143 // see the point). 00144 //////////////////////////////////////////////////////////////////// 00145 bool LensNode:: 00146 is_in_view(int index, const LPoint3 &pos) { 00147 Lens *lens = get_lens(index); 00148 nassertr(lens != (Lens *)NULL, false); 00149 PT(BoundingVolume) bv = lens->make_bounds(); 00150 if (bv == (BoundingVolume *)NULL) { 00151 return false; 00152 } 00153 GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, bv); 00154 int ret = gbv->contains(pos); 00155 return (ret != 0); 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: LensNode::show_frustum 00160 // Access: Published 00161 // Description: Enables the drawing of the lens's frustum to aid in 00162 // visualization. This actually creates a GeomNode 00163 // which is parented to the LensNode. 00164 //////////////////////////////////////////////////////////////////// 00165 void LensNode:: 00166 show_frustum() { 00167 if (_shown_frustum != (PandaNode *)NULL) { 00168 hide_frustum(); 00169 } 00170 PT(GeomNode) geom_node = new GeomNode("frustum"); 00171 _shown_frustum = geom_node; 00172 add_child(_shown_frustum); 00173 00174 for (Lenses::const_iterator li = _lenses.begin(); 00175 li != _lenses.end(); 00176 ++li) { 00177 if ((*li)._is_active && (*li)._lens != (Lens *)NULL) { 00178 geom_node->add_geom((*li)._lens->make_geometry()); 00179 } 00180 } 00181 } 00182 00183 //////////////////////////////////////////////////////////////////// 00184 // Function: LensNode::hide_frustum 00185 // Access: Published 00186 // Description: Disables the drawing of the lens's frustum to aid in 00187 // visualization. 00188 //////////////////////////////////////////////////////////////////// 00189 void LensNode:: 00190 hide_frustum() { 00191 if (_shown_frustum != (PandaNode *)NULL) { 00192 remove_child(_shown_frustum); 00193 _shown_frustum = (PandaNode *)NULL; 00194 } 00195 } 00196 00197 //////////////////////////////////////////////////////////////////// 00198 // Function: LensNode::output 00199 // Access: Public, Virtual 00200 // Description: 00201 //////////////////////////////////////////////////////////////////// 00202 void LensNode:: 00203 output(ostream &out) const { 00204 PandaNode::output(out); 00205 00206 out << " ("; 00207 for (Lenses::const_iterator li = _lenses.begin(); 00208 li != _lenses.end(); 00209 ++li) { 00210 if ((*li)._is_active && (*li)._lens != (Lens *)NULL) { 00211 out << " "; 00212 (*li)._lens->output(out); 00213 } 00214 } 00215 out << " )"; 00216 } 00217 00218 //////////////////////////////////////////////////////////////////// 00219 // Function: LensNode::write 00220 // Access: Public, Virtual 00221 // Description: 00222 //////////////////////////////////////////////////////////////////// 00223 void LensNode:: 00224 write(ostream &out, int indent_level) const { 00225 PandaNode::write(out, indent_level); 00226 00227 for (Lenses::const_iterator li = _lenses.begin(); 00228 li != _lenses.end(); 00229 ++li) { 00230 if ((*li)._is_active && (*li)._lens != (Lens *)NULL) { 00231 (*li)._lens->write(out, indent_level + 2); 00232 } 00233 } 00234 } 00235 00236 //////////////////////////////////////////////////////////////////// 00237 // Function: LensNode::register_with_read_factory 00238 // Access: Public, Static 00239 // Description: Tells the BamReader how to create objects of type 00240 // LensNode. 00241 //////////////////////////////////////////////////////////////////// 00242 void LensNode:: 00243 register_with_read_factory() { 00244 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00245 } 00246 00247 //////////////////////////////////////////////////////////////////// 00248 // Function: LensNode::write_datagram 00249 // Access: Public, Virtual 00250 // Description: Writes the contents of this object to the datagram 00251 // for shipping out to a Bam file. 00252 //////////////////////////////////////////////////////////////////// 00253 void LensNode:: 00254 write_datagram(BamWriter *manager, Datagram &dg) { 00255 PandaNode::write_datagram(manager, dg); 00256 00257 // For now, we only write out lens 0, simply because that's what we 00258 // always have done. Should probably write out all lenses for the 00259 // future. 00260 manager->write_pointer(dg, get_lens(0)); 00261 } 00262 00263 //////////////////////////////////////////////////////////////////// 00264 // Function: LensNode::complete_pointers 00265 // Access: Public, Virtual 00266 // Description: Receives an array of pointers, one for each time 00267 // manager->read_pointer() was called in fillin(). 00268 // Returns the number of pointers processed. 00269 //////////////////////////////////////////////////////////////////// 00270 int LensNode:: 00271 complete_pointers(TypedWritable **p_list, BamReader *manager) { 00272 int pi = PandaNode::complete_pointers(p_list, manager); 00273 set_lens(0, DCAST(Lens, p_list[pi++])); 00274 return pi; 00275 } 00276 00277 //////////////////////////////////////////////////////////////////// 00278 // Function: LensNode::make_from_bam 00279 // Access: Protected, Static 00280 // Description: This function is called by the BamReader's factory 00281 // when a new object of type LensNode is encountered 00282 // in the Bam file. It should create the LensNode 00283 // and extract its information from the file. 00284 //////////////////////////////////////////////////////////////////// 00285 TypedWritable *LensNode:: 00286 make_from_bam(const FactoryParams ¶ms) { 00287 LensNode *node = new LensNode(""); 00288 DatagramIterator scan; 00289 BamReader *manager; 00290 00291 parse_params(params, scan, manager); 00292 node->fillin(scan, manager); 00293 00294 return node; 00295 } 00296 00297 //////////////////////////////////////////////////////////////////// 00298 // Function: LensNode::fillin 00299 // Access: Protected 00300 // Description: This internal function is called by make_from_bam to 00301 // read in all of the relevant data from the BamFile for 00302 // the new LensNode. 00303 //////////////////////////////////////////////////////////////////// 00304 void LensNode:: 00305 fillin(DatagramIterator &scan, BamReader *manager) { 00306 PandaNode::fillin(scan, manager); 00307 00308 manager->read_pointer(scan); 00309 }