Panda3D
fog.cxx
1 // Filename: fog.cxx
2 // Created by: drose (14Mar02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "pandabase.h"
16 
17 #include "fog.h"
18 
19 #include "mathNumbers.h"
20 #include "nodePath.h"
21 #include "transformState.h"
22 #include "bamReader.h"
23 #include "bamWriter.h"
24 #include "datagram.h"
25 #include "datagramIterator.h"
26 
27 #include <stddef.h>
28 
29 TypeHandle Fog::_type_handle;
30 
31 ostream &
32 operator << (ostream &out, Fog::Mode mode) {
33  switch (mode) {
34  case Fog::M_linear:
35  return out << "linear";
36 
37  case Fog::M_exponential:
38  return out << "exponential";
39 
40  case Fog::M_exponential_squared:
41  return out << "exponential-squared";
42  }
43 
44  return out << "**invalid**(" << (int)mode << ")";
45 }
46 
47 ////////////////////////////////////////////////////////////////////
48 // Function: Fog::Constructor
49 // Access: Published
50 // Description:
51 ////////////////////////////////////////////////////////////////////
52 Fog::
53 Fog(const string &name) :
54  PandaNode(name)
55 {
56  _mode = M_linear;
57  _color.set(1.0f, 1.0f, 1.0f, 1.0f);
58  _linear_onset_point.set(0.0f, 0.0f, 0.0f);
59  _linear_opaque_point.set(0.0f, 100.0f, 0.0f);
60  _exp_density = 0.5f;
61  _linear_fallback_cosa = -1.0f;
62  _linear_fallback_onset = 0.0f;
63  _linear_fallback_opaque = 0.0f;
64  _transformed_onset = 0.0f;
65  _transformed_opaque = 0.0f;
66 }
67 
68 ////////////////////////////////////////////////////////////////////
69 // Function: Fog::Copy Constructor
70 // Access: Protected
71 // Description:
72 ////////////////////////////////////////////////////////////////////
73 Fog::
74 Fog(const Fog &copy) :
75  PandaNode(copy)
76 {
77  _mode = copy._mode;
78  _color = copy._color;
79  _linear_onset_point = copy._linear_onset_point;
80  _linear_opaque_point = copy._linear_opaque_point;
81  _exp_density = copy._exp_density;
82  _linear_fallback_cosa = copy._linear_fallback_cosa;
83  _linear_fallback_onset = copy._linear_fallback_onset;
84  _linear_fallback_opaque = copy._linear_fallback_opaque;
85  _transformed_onset = copy._transformed_onset;
86  _transformed_opaque = copy._transformed_opaque;
87 }
88 
89 ////////////////////////////////////////////////////////////////////
90 // Function: Fog::Destructor
91 // Access: Public, Virtual
92 // Description:
93 ////////////////////////////////////////////////////////////////////
94 Fog::
95 ~Fog() {
96 }
97 
98 ////////////////////////////////////////////////////////////////////
99 // Function: Fog::make_copy
100 // Access: Public, Virtual
101 // Description: Returns a newly-allocated Node that is a shallow copy
102 // of this one. It will be a different Node pointer,
103 // but its internal data may or may not be shared with
104 // that of the original Node.
105 ////////////////////////////////////////////////////////////////////
107 make_copy() const {
108  return new Fog(*this);
109 }
110 
111 ////////////////////////////////////////////////////////////////////
112 // Function: Fog::xform
113 // Access: Public, Virtual
114 // Description: Transforms the contents of this node by the indicated
115 // matrix, if it means anything to do so. For most
116 // kinds of nodes, this does nothing.
117 ////////////////////////////////////////////////////////////////////
118 void Fog::
119 xform(const LMatrix4 &mat) {
120  _linear_onset_point = _linear_onset_point * mat;
121  _linear_opaque_point = _linear_opaque_point * mat;
122 }
123 
124 ////////////////////////////////////////////////////////////////////
125 // Function: Fog::output
126 // Access: Public
127 // Description:
128 ////////////////////////////////////////////////////////////////////
129 void Fog::
130 output(ostream &out) const {
131  out << "fog: " << _mode;
132  switch (_mode) {
133  case M_linear:
134  out << "(" << _linear_onset_point << ") -> ("
135  << _linear_opaque_point << ")";
136  break;
137 
138  case M_exponential:
139  case M_exponential_squared:
140  out << _exp_density;
141  break;
142  };
143 }
144 
145 ////////////////////////////////////////////////////////////////////
146 // Function: Fog::adjust_to_camera
147 // Access: Public
148 // Description: This function is intended to be called by the cull
149 // traverser to compute the appropriate camera-relative
150 // onset and opaque distances, based on the fog node's
151 // position within the scene graph (if linear fog is in
152 // effect).
153 ////////////////////////////////////////////////////////////////////
154 void Fog::
155 adjust_to_camera(const TransformState *camera_transform) {
156  LVector3 forward = LVector3::forward();
157 
158  LPoint3 onset_point, opaque_point;
159  if (get_num_parents() != 0) {
160  // Linear fog is relative to the fog's net transform in the scene
161  // graph.
162  NodePath this_np(this);
163 
164  CPT(TransformState) rel_transform =
165  camera_transform->invert_compose(this_np.get_net_transform());
166 
167  const LMatrix4 &mat = rel_transform->get_mat();
168 
169  // How far out of whack are we?
170  LVector3 fog_vector = (_linear_opaque_point - _linear_onset_point) * mat;
171  fog_vector.normalize();
172  PN_stdfloat cosa = fog_vector.dot(forward);
173  if (cabs(cosa) < _linear_fallback_cosa) {
174  // The fog vector is too far from the eye vector; use the
175  // fallback mode.
176  _transformed_onset = _linear_fallback_onset;
177  _transformed_opaque = _linear_fallback_opaque;
178 
179  } else {
180  _transformed_onset = forward.dot(_linear_onset_point * mat);
181  _transformed_opaque = forward.dot(_linear_opaque_point * mat);
182  }
183 
184  } else {
185  // Not a camera-relative fog.
186  _transformed_onset = forward.dot(_linear_onset_point);
187  _transformed_opaque = forward.dot(_linear_opaque_point);
188  }
189 }
190 
191 ////////////////////////////////////////////////////////////////////
192 // Function: Fog::get_linear_range
193 // Access: Public
194 // Description: Retrieves the current onset and offset ranges.
195 ////////////////////////////////////////////////////////////////////
196 void Fog::
197 get_linear_range(PN_stdfloat &onset, PN_stdfloat &opaque) {
198  onset = _transformed_onset;
199  opaque = _transformed_opaque;
200 }
201 
202 ////////////////////////////////////////////////////////////////////
203 // Function: Fog::register_with_read_factory
204 // Access: Public, Static
205 // Description: Tells the BamReader how to create objects of type
206 // Fog.
207 ////////////////////////////////////////////////////////////////////
208 void Fog::
210  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
211 }
212 
213 ////////////////////////////////////////////////////////////////////
214 // Function: Fog::write_datagram
215 // Access: Public, Virtual
216 // Description: Writes the contents of this object to the datagram
217 // for shipping out to a Bam file.
218 ////////////////////////////////////////////////////////////////////
219 void Fog::
221  PandaNode::write_datagram(manager, dg);
222 
223  dg.add_int8(_mode);
224  _color.write_datagram(dg);
225  _linear_onset_point.write_datagram(dg);
226  _linear_opaque_point.write_datagram(dg);
227  dg.add_stdfloat(_exp_density);
228  dg.add_stdfloat(_linear_fallback_cosa);
229  dg.add_stdfloat(_linear_fallback_onset);
230  dg.add_stdfloat(_linear_fallback_opaque);
231 }
232 
233 ////////////////////////////////////////////////////////////////////
234 // Function: Fog::make_from_bam
235 // Access: Protected, Static
236 // Description: This function is called by the BamReader's factory
237 // when a new object of type Fog is encountered
238 // in the Bam file. It should create the Fog
239 // and extract its information from the file.
240 ////////////////////////////////////////////////////////////////////
241 TypedWritable *Fog::
242 make_from_bam(const FactoryParams &params) {
243  Fog *node = new Fog("");
244  DatagramIterator scan;
245  BamReader *manager;
246 
247  parse_params(params, scan, manager);
248  node->fillin(scan, manager);
249 
250  return node;
251 }
252 
253 ////////////////////////////////////////////////////////////////////
254 // Function: Fog::fillin
255 // Access: Protected
256 // Description: This internal function is called by make_from_bam to
257 // read in all of the relevant data from the BamFile for
258 // the new Fog.
259 ////////////////////////////////////////////////////////////////////
260 void Fog::
261 fillin(DatagramIterator &scan, BamReader *manager) {
262  PandaNode::fillin(scan, manager);
263 
264  _mode = (Mode)scan.get_int8();
265  _color.read_datagram(scan);
266  _linear_onset_point.read_datagram(scan);
267  _linear_opaque_point.read_datagram(scan);
268  _exp_density = scan.get_stdfloat();
269  _linear_fallback_cosa = scan.get_stdfloat();
270  _linear_fallback_onset = scan.get_stdfloat();
271  _linear_fallback_opaque = scan.get_stdfloat();
272 }
void get_linear_range(PN_stdfloat &onset, PN_stdfloat &opaque)
Retrieves the current onset and offset ranges.
Definition: fog.cxx:197
PN_int8 get_int8()
Extracts a signed 8-bit integer.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: pandaNode.cxx:4164
static void register_with_read_factory()
Tells the BamReader how to create objects of type Fog.
Definition: fog.cxx:209
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
void add_int8(PN_int8 value)
Adds a signed 8-bit integer to the datagram.
Definition: datagram.I:128
void read_datagram(DatagramIterator &source)
Reads the vector from the Datagram using get_stdfloat().
Definition: lvecBase3.h:1389
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
Definition: fog.cxx:107
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
void adjust_to_camera(const TransformState *camera_transform)
This function is intended to be called by the cull traverser to compute the appropriate camera-relati...
Definition: fog.cxx:155
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
static LVector3f forward(CoordinateSystem cs=CS_default)
Returns the forward vector for the given coordinate system.
Definition: lvector3.h:579
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: fog.cxx:220
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
Definition: datagram.I:240
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
void write_datagram(Datagram &destination) const
Writes the vector to the Datagram using add_stdfloat().
Definition: lvecBase3.h:1371
Specifies how atmospheric fog effects are applied to geometry.
Definition: fog.h:46
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void read_datagram(DatagramIterator &source)
Reads the vector from the Datagram using get_stdfloat().
Definition: lvecBase4.h:1458
int get_num_parents(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of parent nodes this node has.
Definition: pandaNode.I:26
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
void write_datagram(Datagram &destination) const
Writes the vector to the Datagram using add_stdfloat().
Definition: lvecBase4.h:1438
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this node by the indicated matrix, if it means anything to do so...
Definition: fog.cxx:119
bool normalize()
Normalizes the vector in place.
Definition: lvecBase3.h:783
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:165