00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00049
00050
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
00070
00071
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
00091
00092
00093
00094 Fog::
00095 ~Fog() {
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 PandaNode *Fog::
00107 make_copy() const {
00108 return new Fog(*this);
00109 }
00110
00111
00112
00113
00114
00115
00116
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
00126
00127
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
00147
00148
00149
00150
00151
00152
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
00161
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
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
00175
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
00186 _transformed_onset = forward.dot(_linear_onset_point);
00187 _transformed_opaque = forward.dot(_linear_opaque_point);
00188 }
00189 }
00190
00191
00192
00193
00194
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
00204
00205
00206
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
00215
00216
00217
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
00235
00236
00237
00238
00239
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
00255
00256
00257
00258
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 }