00001 // Filename: camera.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 "pandabase.h" 00016 #include "camera.h" 00017 #include "lens.h" 00018 #include "throw_event.h" 00019 00020 TypeHandle Camera::_type_handle; 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: Camera::Constructor 00024 // Access: Published 00025 // Description: 00026 //////////////////////////////////////////////////////////////////// 00027 Camera:: 00028 Camera(const string &name, Lens *lens) : 00029 LensNode(name, lens), 00030 _active(true), 00031 _camera_mask(~PandaNode::get_overall_bit()), 00032 _initial_state(RenderState::make_empty()) 00033 { 00034 } 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: Camera::Copy Constructor 00038 // Access: Published 00039 // Description: 00040 //////////////////////////////////////////////////////////////////// 00041 Camera:: 00042 Camera(const Camera ©) : 00043 LensNode(copy), 00044 _active(copy._active), 00045 _scene(copy._scene), 00046 _camera_mask(copy._camera_mask), 00047 _initial_state(copy._initial_state), 00048 _tag_state_key(copy._tag_state_key), 00049 _tag_states(copy._tag_states) 00050 { 00051 } 00052 00053 //////////////////////////////////////////////////////////////////// 00054 // Function: Camera::Destructor 00055 // Access: Public, Virtual 00056 // Description: 00057 //////////////////////////////////////////////////////////////////// 00058 Camera:: 00059 ~Camera() { 00060 // We don't have to destroy the display region(s) associated with 00061 // the camera; they're responsible for themselves. However, they 00062 // should have removed themselves before we destruct, or something 00063 // went wrong. 00064 nassertv(_display_regions.empty()); 00065 } 00066 00067 //////////////////////////////////////////////////////////////////// 00068 // Function: Camera::make_copy 00069 // Access: Public, Virtual 00070 // Description: Returns a newly-allocated Node that is a shallow copy 00071 // of this one. It will be a different Node pointer, 00072 // but its internal data may or may not be shared with 00073 // that of the original Node. 00074 //////////////////////////////////////////////////////////////////// 00075 PandaNode *Camera:: 00076 make_copy() const { 00077 return new Camera(*this); 00078 } 00079 00080 //////////////////////////////////////////////////////////////////// 00081 // Function: Camera::safe_to_flatten 00082 // Access: Public, Virtual 00083 // Description: Returns true if it is generally safe to flatten out 00084 // this particular kind of Node by duplicating 00085 // instances, false otherwise (for instance, a Camera 00086 // cannot be safely flattened, because the Camera 00087 // pointer itself is meaningful). 00088 //////////////////////////////////////////////////////////////////// 00089 bool Camera:: 00090 safe_to_flatten() const { 00091 return false; 00092 } 00093 00094 //////////////////////////////////////////////////////////////////// 00095 // Function: Camera::safe_to_transform 00096 // Access: Public, Virtual 00097 // Description: Returns true if it is generally safe to transform 00098 // this particular kind of Node by calling the xform() 00099 // method, false otherwise. For instance, it's usually 00100 // a bad idea to attempt to xform a Character. 00101 //////////////////////////////////////////////////////////////////// 00102 bool Camera:: 00103 safe_to_transform() const { 00104 return false; 00105 } 00106 00107 //////////////////////////////////////////////////////////////////// 00108 // Function: Camera::set_tag_state 00109 // Access: Published 00110 // Description: Associates a particular state transition with the 00111 // indicated tag value. When a node is encountered 00112 // during traversal with the tag key specified by 00113 // set_tag_state_key(), if the value of that tag matches 00114 // tag_state, then the indicated state is applied to 00115 // this node--but only when it is rendered by this 00116 // camera. 00117 // 00118 // This can be used to apply special effects to nodes 00119 // when they are rendered by certain cameras. It is 00120 // particularly useful for multipass rendering, in which 00121 // specialty cameras might be needed to render the scene 00122 // with a particular set of effects. 00123 //////////////////////////////////////////////////////////////////// 00124 void Camera:: 00125 set_tag_state(const string &tag_state, const RenderState *state) { 00126 _tag_states[tag_state] = state; 00127 } 00128 00129 //////////////////////////////////////////////////////////////////// 00130 // Function: Camera::clear_tag_state 00131 // Access: Published 00132 // Description: Removes the association established by a previous 00133 // call to set_tag_state(). 00134 //////////////////////////////////////////////////////////////////// 00135 void Camera:: 00136 clear_tag_state(const string &tag_state) { 00137 _tag_states.erase(tag_state); 00138 } 00139 00140 //////////////////////////////////////////////////////////////////// 00141 // Function: Camera::has_tag_state 00142 // Access: Published 00143 // Description: Returns true if set_tag_state() has previously been 00144 // called with the indicated tag state, false otherwise. 00145 //////////////////////////////////////////////////////////////////// 00146 bool Camera:: 00147 has_tag_state(const string &tag_state) const { 00148 TagStates::const_iterator tsi; 00149 tsi = _tag_states.find(tag_state); 00150 return (tsi != _tag_states.end()); 00151 } 00152 00153 //////////////////////////////////////////////////////////////////// 00154 // Function: Camera::get_tag_state 00155 // Access: Published 00156 // Description: Returns the state associated with the indicated tag 00157 // state by a previous call to set_tag_state(), or the 00158 // empty state if nothing has been associated. 00159 //////////////////////////////////////////////////////////////////// 00160 CPT(RenderState) Camera:: 00161 get_tag_state(const string &tag_state) const { 00162 TagStates::const_iterator tsi; 00163 tsi = _tag_states.find(tag_state); 00164 if (tsi != _tag_states.end()) { 00165 return (*tsi).second; 00166 } 00167 return RenderState::make_empty(); 00168 } 00169 00170 //////////////////////////////////////////////////////////////////// 00171 // Function: Camera::set_aux_scene_data 00172 // Access: Published 00173 // Description: Associates the indicated AuxSceneData object with the 00174 // given NodePath, possibly replacing a previous 00175 // data defined for the same NodePath, if any. 00176 //////////////////////////////////////////////////////////////////// 00177 void Camera:: 00178 set_aux_scene_data(const NodePath &node_path, AuxSceneData *data) { 00179 if (data == (AuxSceneData *)NULL) { 00180 clear_aux_scene_data(node_path); 00181 } else { 00182 _aux_data[node_path] = data; 00183 } 00184 } 00185 00186 //////////////////////////////////////////////////////////////////// 00187 // Function: Camera::clear_aux_scene_data 00188 // Access: Published 00189 // Description: Removes the AuxSceneData associated with the 00190 // indicated NodePath. Returns true if it is removed 00191 // successfully, false if it was already gone. 00192 //////////////////////////////////////////////////////////////////// 00193 bool Camera:: 00194 clear_aux_scene_data(const NodePath &node_path) { 00195 AuxData::iterator ai; 00196 ai = _aux_data.find(node_path); 00197 if (ai != _aux_data.end()) { 00198 _aux_data.erase(ai); 00199 return true; 00200 } 00201 00202 return false; 00203 } 00204 00205 //////////////////////////////////////////////////////////////////// 00206 // Function: Camera::get_aux_scene_data 00207 // Access: Published 00208 // Description: Returns the AuxSceneData associated with the 00209 // indicated NodePath, or NULL if nothing is associated. 00210 //////////////////////////////////////////////////////////////////// 00211 AuxSceneData *Camera:: 00212 get_aux_scene_data(const NodePath &node_path) const { 00213 AuxData::const_iterator ai; 00214 ai = _aux_data.find(node_path); 00215 if (ai != _aux_data.end()) { 00216 return (*ai).second; 00217 } 00218 00219 return NULL; 00220 } 00221 00222 //////////////////////////////////////////////////////////////////// 00223 // Function: Camera::list_aux_scene_data 00224 // Access: Published 00225 // Description: Outputs all of the NodePaths and AuxSceneDatas in 00226 // use. 00227 //////////////////////////////////////////////////////////////////// 00228 void Camera:: 00229 list_aux_scene_data(ostream &out) const { 00230 out << _aux_data.size() << " data objects held:\n"; 00231 AuxData::const_iterator ai; 00232 for (ai = _aux_data.begin(); ai != _aux_data.end(); ++ai) { 00233 out << (*ai).first << " " << *(*ai).second << "\n"; 00234 } 00235 } 00236 00237 //////////////////////////////////////////////////////////////////// 00238 // Function: Camera::cleanup_aux_scene_data 00239 // Access: Published 00240 // Description: Walks through the list of currently-assigned 00241 // AuxSceneData objects and releases any that are 00242 // past their expiration times. Returns the number of 00243 // elements released. 00244 //////////////////////////////////////////////////////////////////// 00245 int Camera:: 00246 cleanup_aux_scene_data(Thread *current_thread) { 00247 int num_deleted = 0; 00248 00249 double now = ClockObject::get_global_clock()->get_frame_time(current_thread); 00250 00251 AuxData::iterator ai; 00252 ai = _aux_data.begin(); 00253 while (ai != _aux_data.end()) { 00254 AuxData::iterator anext = ai; 00255 ++anext; 00256 00257 if (now > (*ai).second->get_expiration_time()) { 00258 _aux_data.erase(ai); 00259 num_deleted++; 00260 } 00261 00262 ai = anext; 00263 } 00264 00265 return num_deleted; 00266 } 00267 00268 //////////////////////////////////////////////////////////////////// 00269 // Function: Camera::add_display_region 00270 // Access: Private 00271 // Description: Adds the indicated DisplayRegion to the set of 00272 // DisplayRegions shared by the camera. This is only 00273 // intended to be called from the DisplayRegion. 00274 //////////////////////////////////////////////////////////////////// 00275 void Camera:: 00276 add_display_region(DisplayRegionBase *display_region) { 00277 _display_regions.push_back(display_region); 00278 } 00279 00280 //////////////////////////////////////////////////////////////////// 00281 // Function: Camera::remove_display_region 00282 // Access: Private 00283 // Description: Removes the indicated DisplayRegion from the set of 00284 // DisplayRegions shared by the camera. This is only 00285 // intended to be called from the DisplayRegion. 00286 //////////////////////////////////////////////////////////////////// 00287 void Camera:: 00288 remove_display_region(DisplayRegionBase *display_region) { 00289 DisplayRegions::iterator dri = 00290 find(_display_regions.begin(), _display_regions.end(), display_region); 00291 if (dri != _display_regions.end()) { 00292 _display_regions.erase(dri); 00293 } 00294 } 00295 00296 //////////////////////////////////////////////////////////////////// 00297 // Function: Camera::register_with_read_factory 00298 // Access: Public, Static 00299 // Description: Tells the BamReader how to create objects of type 00300 // Camera. 00301 //////////////////////////////////////////////////////////////////// 00302 void Camera:: 00303 register_with_read_factory() { 00304 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00305 } 00306 00307 //////////////////////////////////////////////////////////////////// 00308 // Function: Camera::write_datagram 00309 // Access: Public, Virtual 00310 // Description: Writes the contents of this object to the datagram 00311 // for shipping out to a Bam file. 00312 //////////////////////////////////////////////////////////////////// 00313 void Camera:: 00314 write_datagram(BamWriter *manager, Datagram &dg) { 00315 LensNode::write_datagram(manager, dg); 00316 00317 dg.add_bool(_active); 00318 dg.add_uint32(_camera_mask.get_word()); 00319 } 00320 00321 //////////////////////////////////////////////////////////////////// 00322 // Function: Camera::make_from_bam 00323 // Access: Protected, Static 00324 // Description: This function is called by the BamReader's factory 00325 // when a new object of type Camera is encountered 00326 // in the Bam file. It should create the Camera 00327 // and extract its information from the file. 00328 //////////////////////////////////////////////////////////////////// 00329 TypedWritable *Camera:: 00330 make_from_bam(const FactoryParams ¶ms) { 00331 Camera *node = new Camera(""); 00332 DatagramIterator scan; 00333 BamReader *manager; 00334 00335 parse_params(params, scan, manager); 00336 node->fillin(scan, manager); 00337 00338 return node; 00339 } 00340 00341 //////////////////////////////////////////////////////////////////// 00342 // Function: Camera::fillin 00343 // Access: Protected 00344 // Description: This internal function is called by make_from_bam to 00345 // read in all of the relevant data from the BamFile for 00346 // the new Camera. 00347 //////////////////////////////////////////////////////////////////// 00348 void Camera:: 00349 fillin(DatagramIterator &scan, BamReader *manager) { 00350 LensNode::fillin(scan, manager); 00351 00352 _active = scan.get_bool(); 00353 _camera_mask.set_word(scan.get_uint32()); 00354 }