Panda3D
|
00001 // Filename: fog.cxx 00002 // Created by: drose (14Mar02) 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 00017 #include "fog.h" 00018 00019 #include "mathNumbers.h" 00020 #include "nodePath.h" 00021 #include "transformState.h" 00022 #include "bamReader.h" 00023 #include "bamWriter.h" 00024 #include "datagram.h" 00025 #include "datagramIterator.h" 00026 00027 #include <stddef.h> 00028 00029 TypeHandle Fog::_type_handle; 00030 00031 ostream & 00032 operator << (ostream &out, Fog::Mode mode) { 00033 switch (mode) { 00034 case Fog::M_linear: 00035 return out << "linear"; 00036 00037 case Fog::M_exponential: 00038 return out << "exponential"; 00039 00040 case Fog::M_exponential_squared: 00041 return out << "exponential-squared"; 00042 } 00043 00044 return out << "**invalid**(" << (int)mode << ")"; 00045 } 00046 00047 //////////////////////////////////////////////////////////////////// 00048 // Function: Fog::Constructor 00049 // Access: Published 00050 // Description: 00051 //////////////////////////////////////////////////////////////////// 00052 Fog:: 00053 Fog(const string &name) : 00054 PandaNode(name) 00055 { 00056 _mode = M_linear; 00057 _color.set(1.0f, 1.0f, 1.0f, 1.0f); 00058 _linear_onset_point.set(0.0f, 0.0f, 0.0f); 00059 _linear_opaque_point.set(0.0f, 100.0f, 0.0f); 00060 _exp_density = 0.5f; 00061 _linear_fallback_cosa = -1.0f; 00062 _linear_fallback_onset = 0.0f; 00063 _linear_fallback_opaque = 0.0f; 00064 _transformed_onset = 0.0f; 00065 _transformed_opaque = 0.0f; 00066 } 00067 00068 //////////////////////////////////////////////////////////////////// 00069 // Function: Fog::Copy Constructor 00070 // Access: Protected 00071 // Description: 00072 //////////////////////////////////////////////////////////////////// 00073 Fog:: 00074 Fog(const Fog ©) : 00075 PandaNode(copy) 00076 { 00077 _mode = copy._mode; 00078 _color = copy._color; 00079 _linear_onset_point = copy._linear_onset_point; 00080 _linear_opaque_point = copy._linear_opaque_point; 00081 _exp_density = copy._exp_density; 00082 _linear_fallback_cosa = copy._linear_fallback_cosa; 00083 _linear_fallback_onset = copy._linear_fallback_onset; 00084 _linear_fallback_opaque = copy._linear_fallback_opaque; 00085 _transformed_onset = copy._transformed_onset; 00086 _transformed_opaque = copy._transformed_opaque; 00087 } 00088 00089 //////////////////////////////////////////////////////////////////// 00090 // Function: Fog::Destructor 00091 // Access: Public, Virtual 00092 // Description: 00093 //////////////////////////////////////////////////////////////////// 00094 Fog:: 00095 ~Fog() { 00096 } 00097 00098 //////////////////////////////////////////////////////////////////// 00099 // Function: Fog::make_copy 00100 // Access: Public, Virtual 00101 // Description: Returns a newly-allocated Node that is a shallow copy 00102 // of this one. It will be a different Node pointer, 00103 // but its internal data may or may not be shared with 00104 // that of the original Node. 00105 //////////////////////////////////////////////////////////////////// 00106 PandaNode *Fog:: 00107 make_copy() const { 00108 return new Fog(*this); 00109 } 00110 00111 //////////////////////////////////////////////////////////////////// 00112 // Function: Fog::xform 00113 // Access: Public, Virtual 00114 // Description: Transforms the contents of this node by the indicated 00115 // matrix, if it means anything to do so. For most 00116 // kinds of nodes, this does nothing. 00117 //////////////////////////////////////////////////////////////////// 00118 void Fog:: 00119 xform(const LMatrix4 &mat) { 00120 _linear_onset_point = _linear_onset_point * mat; 00121 _linear_opaque_point = _linear_opaque_point * mat; 00122 } 00123 00124 //////////////////////////////////////////////////////////////////// 00125 // Function: Fog::output 00126 // Access: Public 00127 // Description: 00128 //////////////////////////////////////////////////////////////////// 00129 void Fog:: 00130 output(ostream &out) const { 00131 out << "fog: " << _mode; 00132 switch (_mode) { 00133 case M_linear: 00134 out << "(" << _linear_onset_point << ") -> (" 00135 << _linear_opaque_point << ")"; 00136 break; 00137 00138 case M_exponential: 00139 case M_exponential_squared: 00140 out << _exp_density; 00141 break; 00142 }; 00143 } 00144 00145 //////////////////////////////////////////////////////////////////// 00146 // Function: Fog::adjust_to_camera 00147 // Access: Public 00148 // Description: This function is intended to be called by the cull 00149 // traverser to compute the appropriate camera-relative 00150 // onset and opaque distances, based on the fog node's 00151 // position within the scene graph (if linear fog is in 00152 // effect). 00153 //////////////////////////////////////////////////////////////////// 00154 void Fog:: 00155 adjust_to_camera(const TransformState *camera_transform) { 00156 LVector3 forward = LVector3::forward(); 00157 00158 LPoint3 onset_point, opaque_point; 00159 if (get_num_parents() != 0) { 00160 // Linear fog is relative to the fog's net transform in the scene 00161 // graph. 00162 NodePath this_np(this); 00163 00164 CPT(TransformState) rel_transform = 00165 camera_transform->invert_compose(this_np.get_net_transform()); 00166 00167 const LMatrix4 &mat = rel_transform->get_mat(); 00168 00169 // How far out of whack are we? 00170 LVector3 fog_vector = (_linear_opaque_point - _linear_onset_point) * mat; 00171 fog_vector.normalize(); 00172 PN_stdfloat cosa = fog_vector.dot(forward); 00173 if (cabs(cosa) < _linear_fallback_cosa) { 00174 // The fog vector is too far from the eye vector; use the 00175 // fallback mode. 00176 _transformed_onset = _linear_fallback_onset; 00177 _transformed_opaque = _linear_fallback_opaque; 00178 00179 } else { 00180 _transformed_onset = forward.dot(_linear_onset_point * mat); 00181 _transformed_opaque = forward.dot(_linear_opaque_point * mat); 00182 } 00183 00184 } else { 00185 // Not a camera-relative fog. 00186 _transformed_onset = forward.dot(_linear_onset_point); 00187 _transformed_opaque = forward.dot(_linear_opaque_point); 00188 } 00189 } 00190 00191 //////////////////////////////////////////////////////////////////// 00192 // Function: Fog::get_linear_range 00193 // Access: Public 00194 // Description: Retrieves the current onset and offset ranges. 00195 //////////////////////////////////////////////////////////////////// 00196 void Fog:: 00197 get_linear_range(PN_stdfloat &onset, PN_stdfloat &opaque) { 00198 onset = _transformed_onset; 00199 opaque = _transformed_opaque; 00200 } 00201 00202 //////////////////////////////////////////////////////////////////// 00203 // Function: Fog::register_with_read_factory 00204 // Access: Public, Static 00205 // Description: Tells the BamReader how to create objects of type 00206 // Fog. 00207 //////////////////////////////////////////////////////////////////// 00208 void Fog:: 00209 register_with_read_factory() { 00210 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00211 } 00212 00213 //////////////////////////////////////////////////////////////////// 00214 // Function: Fog::write_datagram 00215 // Access: Public, Virtual 00216 // Description: Writes the contents of this object to the datagram 00217 // for shipping out to a Bam file. 00218 //////////////////////////////////////////////////////////////////// 00219 void Fog:: 00220 write_datagram(BamWriter *manager, Datagram &dg) { 00221 PandaNode::write_datagram(manager, dg); 00222 00223 dg.add_int8(_mode); 00224 _color.write_datagram(dg); 00225 _linear_onset_point.write_datagram(dg); 00226 _linear_opaque_point.write_datagram(dg); 00227 dg.add_stdfloat(_exp_density); 00228 dg.add_stdfloat(_linear_fallback_cosa); 00229 dg.add_stdfloat(_linear_fallback_onset); 00230 dg.add_stdfloat(_linear_fallback_opaque); 00231 } 00232 00233 //////////////////////////////////////////////////////////////////// 00234 // Function: Fog::make_from_bam 00235 // Access: Protected, Static 00236 // Description: This function is called by the BamReader's factory 00237 // when a new object of type Fog is encountered 00238 // in the Bam file. It should create the Fog 00239 // and extract its information from the file. 00240 //////////////////////////////////////////////////////////////////// 00241 TypedWritable *Fog:: 00242 make_from_bam(const FactoryParams ¶ms) { 00243 Fog *node = new Fog(""); 00244 DatagramIterator scan; 00245 BamReader *manager; 00246 00247 parse_params(params, scan, manager); 00248 node->fillin(scan, manager); 00249 00250 return node; 00251 } 00252 00253 //////////////////////////////////////////////////////////////////// 00254 // Function: Fog::fillin 00255 // Access: Protected 00256 // Description: This internal function is called by make_from_bam to 00257 // read in all of the relevant data from the BamFile for 00258 // the new Fog. 00259 //////////////////////////////////////////////////////////////////// 00260 void Fog:: 00261 fillin(DatagramIterator &scan, BamReader *manager) { 00262 PandaNode::fillin(scan, manager); 00263 00264 _mode = (Mode)scan.get_int8(); 00265 _color.read_datagram(scan); 00266 _linear_onset_point.read_datagram(scan); 00267 _linear_opaque_point.read_datagram(scan); 00268 _exp_density = scan.get_stdfloat(); 00269 _linear_fallback_cosa = scan.get_stdfloat(); 00270 _linear_fallback_onset = scan.get_stdfloat(); 00271 _linear_fallback_opaque = scan.get_stdfloat(); 00272 }