Panda3D
 All Classes Functions Variables Enumerations
polylightNode.cxx
1 // Filename: PolylightNode.cxx
2 // Created by: sshodhan (02Jun04)
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 "polylightNode.h"
16 #include "config_pgraph.h"
17 #include "nodePath.h"
18 #include "clockObject.h"
19 #include "bamReader.h"
20 #include "bamWriter.h"
21 #include "datagram.h"
22 #include "datagramIterator.h"
23 
24 #include <time.h>
25 #include <math.h>
26 
27 TypeHandle PolylightNode::_type_handle;
28 
29 ////////////////////////////////////////////////////////////////////
30 // Function: PolylightNode::Constructor
31 // Access: Published
32 // Description: Use PolylightNode() to construct a new
33 // PolylightNode object.
34 ////////////////////////////////////////////////////////////////////
36 PolylightNode(const string &name) :
37 PandaNode(name)
38 {
39  _enabled = true;
40  set_pos(0,0,0);
41  set_color(1,1,1);
42  _radius = 50;
43  set_attenuation(ALINEAR);
44  _a0 = 1.0;
45  _a1 = 0.1;
46  _a2 = 0.01;
47  _flickering = true;
48  set_flicker_type(FRANDOM);
49  _offset = -0.5;
50  _scale = 0.1;
51  _step_size = 0.1;
52  _sin_freq = 2.0;
53 }
54 
55 ////////////////////////////////////////////////////////////////////
56 // Function: PolylightNode::make_copy
57 // Access: Public, Virtual
58 // Description: Returns a newly-allocated Node that is a shallow copy
59 // of this one. It will be a different Node pointer,
60 // but its internal data may or may not be shared with
61 // that of the original Node.
62 ////////////////////////////////////////////////////////////////////
64 make_copy() const {
65  return new PolylightNode(*this);
66 }
67 
68 ////////////////////////////////////////////////////////////////////
69 // Function: PolylightNode::xform
70 // Access: Public, Virtual
71 // Description: Transforms the contents of this node by the indicated
72 // matrix, if it means anything to do so. For most
73 // kinds of nodes, this does nothing.
74 ////////////////////////////////////////////////////////////////////
75 void PolylightNode::
76 xform(const LMatrix4 &mat) {
77  nassertv(!mat.is_nan());
78 
79  if (mat.almost_equal(LMatrix4::ident_mat())) {
80  return;
81  }
82 
83  _position = _position * mat;
84 
85  // This is a little cheesy and fails miserably in the presence of a
86  // non-uniform scale.
87  LVector3 radius_v = LVector3(_radius, 0.0f, 0.0f) * mat;
88  _radius = length(radius_v);
90 }
91 
92 ////////////////////////////////////////////////////////////////////
93 // Function: PolylightNode::Constructor
94 // Access: Public
95 // Description: If flickering is on, the do_poly_light function
96 // in PolylightNodeEffect will compute this light's color
97 // based on the variations applied in this function
98 // Variation can be sin or random
99 // Use offset, scale and step_size to tweak
100 // Future addition: custom function variations to flicker
101 ////////////////////////////////////////////////////////////////////
103  PN_stdfloat r,g,b;
104 
105  PN_stdfloat variation= 0.0;
106  LColor color = get_color(); //color = get_color_scenegraph();
107 
108  r = color[0];
109  g = color[1];
110  b = color[2];
111 
112  if (_flicker_type == FRANDOM) {
113  //srand((int)ClockObject::get_global_clock()->get_frame_time());
114  variation = (rand()%100); // a value between 0-99
115  variation /= 100.0;
116  if (polylight_info)
117  pgraph_cat.info() << "Random Variation: " << variation << endl;
118  } else if (_flicker_type == FSIN) {
120  variation = sinf(now*_sin_freq);
121  if (polylight_info)
122  pgraph_cat.info() << "Variation: " << variation << endl;
123  // can't use negative variation, so make it positive
124  if (variation < 0.0)
125  variation *= -1.0;
126  } else if (_flicker_type == FCUSTOM) {
127  // fixed point list of variation values coming soon...
128  //double index = (ClockObject::get_global_clock()->get_frame_time() % len(fixed_points)) * ClockObject::get_global_clock()->get_dt();
129  //index *= _speed;
130  /*if (!(int)index > len(fixed_points) {
131  variation = _fixed_points[(int)index];
132  variation += _offset;
133  variation *= _scale;
134  }*/
135  }
136 
137  //variation += _offset;
138  //variation *= _scale;
139 
140  //printf("Variation: %f\n",variation);
141  r += r * variation;
142  g += g * variation;
143  b += b * variation;
144 
145  /* CLAMPING
146  if (fabs(r - color[0]) > 0.5 || fabs(g - color[1]) > 0.5 || fabs(b - color[2]) > 0.5) {
147  r = color[0];
148  g = color[1];
149  b = color[2];
150  }
151  */
152  pgraph_cat.debug() << "Color R:" << r << "; G:" << g << "; B:" << b << endl;
153  return LColor(r,g,b,1.0);
154 }
155 
156 ////////////////////////////////////////////////////////////////////
157 // Function: PolylightNode::compare_to
158 // Access: Published
159 // Description: Returns a number less than zero if this PolylightNode
160 // sorts before the other one, greater than zero if it
161 // sorts after, or zero if they are equivalent.
162 //
163 // Two PolylightNodes are considered equivalent if they
164 // consist of exactly the same properties
165 // Otherwise, they are different; different
166 // PolylightNodes will be ranked in a consistent but
167 // undefined ordering; the ordering is useful only for
168 // placing the PolylightNodes in a sorted container like an
169 // STL set.
170 ////////////////////////////////////////////////////////////////////
171 int PolylightNode::
172 compare_to(const PolylightNode &other) const {
173 
174  if (_enabled != other._enabled) {
175  return _enabled ? 1 :-1;
176  }
177 
178  if (_radius != other._radius) {
179  return _radius < other._radius ? -1 :1;
180  }
181  LVecBase3 position = get_pos();
182  LVecBase3 other_position = other.get_pos();
183  if (position != other_position) {
184  return position < other_position ? -1 :1;
185  }
186 
187  LColor color = get_color();
188  LColor other_color = other.get_color();
189  if (color != other_color) {
190  return color < other_color ? -1 :1;
191  }
192 
193  if (_attenuation_type != other._attenuation_type) {
194  return _attenuation_type < other._attenuation_type ? -1 :1;
195  }
196 
197  if (_a0 != other._a0) {
198  return _a0 < other._a0 ? -1 :1;
199  }
200 
201  if (_a1 != other._a1) {
202  return _a1 < other._a1 ? -1 :1;
203  }
204 
205  if (_a2 != other._a2) {
206  return _a2 < other._a2 ? -1 :1;
207  }
208 
209  if (_flickering != other._flickering) {
210  return _flickering ? 1 :-1;
211  }
212 
213  if (_flicker_type != other._flicker_type) {
214  return _flicker_type < other._flicker_type ? -1 :1;
215  }
216 
217  if (_offset != other._offset) {
218  return _offset < other._offset ? -1 :1;
219  }
220 
221  if (_scale != other._scale) {
222  return _scale < other._scale ? -1 :1;
223  }
224 
225  if (_step_size != other._step_size) {
226  return _step_size < other._step_size ? -1 :1;
227  }
228 
229  if (_sin_freq != other._sin_freq) {
230  return _sin_freq < other._sin_freq ? -1 :1;
231  }
232 
233 
234  return 0;
235 }
236 
237 
238 
239 
240 ////////////////////////////////////////////////////////////////////
241 // Function: PolylightNode::register_with_read_factory
242 // Access: Public, Static
243 // Description: Tells the BamReader how to create objects of type
244 // PolylightNode
245 ////////////////////////////////////////////////////////////////////
246 void PolylightNode::
248  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
249 }
250 
251 ////////////////////////////////////////////////////////////////////
252 // Function: PolylightNode::write_datagram
253 // Access: Public, Virtual
254 // Description: Writes the contents of this object to the datagram
255 // for shipping out to a Bam file.
256 ////////////////////////////////////////////////////////////////////
257 void PolylightNode::
259  PandaNode::write_datagram(manager, dg);
260  _position.write_datagram(dg);
262  color.set(_color[0], _color[1], _color[2]);
263  color.write_datagram(dg);
264  dg.add_stdfloat(_radius);
265 }
266 
267 ////////////////////////////////////////////////////////////////////
268 // Function: PolylightNode::make_from_bam
269 // Access: Protected, Static
270 // Description: This function is called by the BamReader's factory
271 // when a new object of type CompassEffect is encountered
272 // in the Bam file. It should create the CompassEffect
273 // and extract its information from the file.
274 ////////////////////////////////////////////////////////////////////
275 TypedWritable *PolylightNode::
276 make_from_bam(const FactoryParams &params) {
277  PolylightNode *light = new PolylightNode("");
278  DatagramIterator scan;
279  BamReader *manager;
280 
281  parse_params(params, scan, manager);
282  light->fillin(scan, manager);
283 
284  return light;
285 }
286 
287 ////////////////////////////////////////////////////////////////////
288 // Function: PolylightNode::fillin
289 // Access: Protected
290 // Description: This internal function is called by make_from_bam to
291 // read in all of the relevant data from the BamFile for
292 // the new CompassEffect.
293 ////////////////////////////////////////////////////////////////////
294 void PolylightNode::
295 fillin(DatagramIterator &scan, BamReader *manager) {
296  PandaNode::fillin(scan, manager);
297  _position.read_datagram(scan);
299  color.read_datagram(scan);
300  set_color(color[0], color[1], color[2]);
301  _radius = scan.get_stdfloat();
302 }
303 
304 
305 
306 ////////////////////////////////////////////////////////////////////
307 // Function: PolylightNode::output
308 // Access: Public, Virtual
309 // Description:
310 ////////////////////////////////////////////////////////////////////
311 void PolylightNode::
312 output(ostream &out) const {
313  out << get_type() << ":";
314  //out << "Position: " << get_x() << " " << get_y() << " " << get_z() << "\n";
315  //out << "Color: " << get_r() << " " << get_g() << " " << get_b() << "\n";
316  out << "Radius: " << get_radius() << "\n";
317 }
318 
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:271
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this node by the indicated matrix, if it means anything to do so...
static const LMatrix4f & ident_mat()
Returns an identity matrix.
Definition: lmatrix.h:903
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
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
PolylightNode(const string &name)
Use PolylightNode() to construct a new PolylightNode object.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
void read_datagram(DatagramIterator &source)
Reads the vector from the Datagram using get_stdfloat().
Definition: lvecBase3.h:1373
bool set_flicker_type(Flicker_Type type)
Flicker type can be FRANDOM or FSIN At a later point there might be a FCUSTOM Custom flicker will be ...
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
PN_stdfloat get_radius() const
Get radius of the spherical light volume.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
static void register_with_read_factory()
Tells the BamReader how to create objects of type PolylightNode.
void set_pos(const LPoint3 &position)
Set this light&#39;s position.
Definition: polylightNode.I:88
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
LColor get_color() const
Returns the light&#39;s color as LColor.
void mark_internal_bounds_stale(Thread *current_thread=Thread::get_current_thread())
Should be called by a derived class to mark the internal bounding volume stale, so that compute_inter...
Definition: pandaNode.cxx:2467
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
double get_frame_time(Thread *current_thread=Thread::get_current_thread()) const
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
Definition: clockObject.I:48
bool set_attenuation(Attenuation_Type type)
Set ALINEAR or AQUADRATIC attenuation.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
A PolylightNode.
Definition: polylightNode.h:31
virtual PandaNode * make_copy() const
Returns a newly-allocated Node that is a shallow copy of this one.
LColor flicker() const
If flickering is on, the do_poly_light function in PolylightNodeEffect will compute this light&#39;s colo...
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
LPoint3 get_pos() const
Returns position as a LPoint3.
void set_color(const LColor &color)
Set the light&#39;s color...
bool almost_equal(const LMatrix4f &other, float threshold) const
Returns true if two matrices are memberwise equal within a specified tolerance.
Definition: lmatrix.cxx:879
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
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
void write_datagram(Datagram &destination) const
Writes the vector to the Datagram using add_stdfloat().
Definition: lvecBase3.h:1355
bool is_nan() const
Returns true if any component of the matrix is not-a-number, false otherwise.
Definition: lmatrix.h:1417
int compare_to(const PolylightNode &other) const
Returns a number less than zero if this PolylightNode sorts before the other one, greater than zero i...