00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pandabase.h"
00020
00021 #include "fog.h"
00022
00023 #include "mathNumbers.h"
00024 #include "nodePath.h"
00025 #include "transformState.h"
00026 #include "bamReader.h"
00027 #include "bamWriter.h"
00028 #include "datagram.h"
00029 #include "datagramIterator.h"
00030
00031 #include <stddef.h>
00032
00033 TypeHandle Fog::_type_handle;
00034
00035 ostream &
00036 operator << (ostream &out, Fog::Mode mode) {
00037 switch (mode) {
00038 case Fog::M_linear:
00039 return out << "linear";
00040
00041 case Fog::M_exponential:
00042 return out << "exponential";
00043
00044 case Fog::M_exponential_squared:
00045 return out << "exponential-squared";
00046 }
00047
00048 return out << "**invalid**(" << (int)mode << ")";
00049 }
00050
00051
00052
00053
00054
00055
00056 Fog::
00057 Fog(const string &name) :
00058 PandaNode(name)
00059 {
00060 _mode = M_linear;
00061 _color.set(1.0f, 1.0f, 1.0f, 1.0f);
00062 _linear_onset_point.set(0.0f, 0.0f, 0.0f);
00063 _linear_opaque_point.set(0.0f, 100.0f, 0.0f);
00064 _exp_density = 0.5f;
00065 _linear_fallback_cosa = -1.0f;
00066 _linear_fallback_onset = 0.0f;
00067 _linear_fallback_opaque = 0.0f;
00068 _transformed_onset = 0.0f;
00069 _transformed_opaque = 0.0f;
00070 }
00071
00072
00073
00074
00075
00076
00077 Fog::
00078 Fog(const Fog ©) :
00079 PandaNode(copy)
00080 {
00081 _mode = copy._mode;
00082 _color = copy._color;
00083 _linear_onset_point = copy._linear_onset_point;
00084 _linear_opaque_point = copy._linear_opaque_point;
00085 _exp_density = copy._exp_density;
00086 _linear_fallback_cosa = copy._linear_fallback_cosa;
00087 _linear_fallback_onset = copy._linear_fallback_onset;
00088 _linear_fallback_opaque = copy._linear_fallback_opaque;
00089 _transformed_onset = copy._transformed_onset;
00090 _transformed_opaque = copy._transformed_opaque;
00091 }
00092
00093
00094
00095
00096
00097
00098 Fog::
00099 ~Fog() {
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 PandaNode *Fog::
00111 make_copy() const {
00112 return new Fog(*this);
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122 void Fog::
00123 xform(const LMatrix4f &mat) {
00124 _linear_onset_point = _linear_onset_point * mat;
00125 _linear_opaque_point = _linear_opaque_point * mat;
00126 }
00127
00128
00129
00130
00131
00132
00133 void Fog::
00134 output(ostream &out) const {
00135 out << "fog: " << _mode;
00136 switch (_mode) {
00137 case M_linear:
00138 out << "(" << _linear_onset_point << ") -> ("
00139 << _linear_opaque_point << ")";
00140 break;
00141
00142 case M_exponential:
00143 case M_exponential_squared:
00144 out << _exp_density;
00145 break;
00146 };
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 void Fog::
00159 adjust_to_camera(const TransformState *camera_transform) {
00160 LVector3f forward = LVector3f::forward();
00161
00162 LPoint3f onset_point, opaque_point;
00163 if (get_num_parents() != 0) {
00164
00165
00166 NodePath this_np(this);
00167
00168 CPT(TransformState) rel_transform =
00169 camera_transform->invert_compose(this_np.get_net_transform());
00170
00171 const LMatrix4f &mat = rel_transform->get_mat();
00172
00173
00174 LVector3f fog_vector = (_linear_opaque_point - _linear_onset_point) * mat;
00175 fog_vector.normalize();
00176 float cosa = fog_vector.dot(forward);
00177 if (cabs(cosa) < _linear_fallback_cosa) {
00178
00179
00180 _transformed_onset = _linear_fallback_onset;
00181 _transformed_opaque = _linear_fallback_opaque;
00182
00183 } else {
00184 _transformed_onset = forward.dot(_linear_onset_point * mat);
00185 _transformed_opaque = forward.dot(_linear_opaque_point * mat);
00186 }
00187
00188 } else {
00189
00190 _transformed_onset = forward.dot(_linear_onset_point);
00191 _transformed_opaque = forward.dot(_linear_opaque_point);
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200 void Fog::
00201 get_linear_range(float &onset, float &opaque) {
00202 onset = _transformed_onset;
00203 opaque = _transformed_opaque;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212 void Fog::
00213 register_with_read_factory() {
00214 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00215 }
00216
00217
00218
00219
00220
00221
00222
00223 void Fog::
00224 write_datagram(BamWriter *manager, Datagram &dg) {
00225 PandaNode::write_datagram(manager, dg);
00226
00227 dg.add_int8(_mode);
00228 _color.write_datagram(dg);
00229 _linear_onset_point.write_datagram(dg);
00230 _linear_opaque_point.write_datagram(dg);
00231 dg.add_float32(_exp_density);
00232 dg.add_float32(_linear_fallback_cosa);
00233 dg.add_float32(_linear_fallback_onset);
00234 dg.add_float32(_linear_fallback_opaque);
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 TypedWritable *Fog::
00246 make_from_bam(const FactoryParams ¶ms) {
00247 Fog *node = new Fog("");
00248 DatagramIterator scan;
00249 BamReader *manager;
00250
00251 parse_params(params, scan, manager);
00252 node->fillin(scan, manager);
00253
00254 return node;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264 void Fog::
00265 fillin(DatagramIterator &scan, BamReader *manager) {
00266 PandaNode::fillin(scan, manager);
00267
00268 _mode = (Mode)scan.get_int8();
00269 _color.read_datagram(scan);
00270 _linear_onset_point.read_datagram(scan);
00271 _linear_opaque_point.read_datagram(scan);
00272 _exp_density = scan.get_float32();
00273 _linear_fallback_cosa = scan.get_float32();
00274 _linear_fallback_onset = scan.get_float32();
00275 _linear_fallback_opaque = scan.get_float32();
00276 }