Panda3D
colorInterpolationManager.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file colorInterpolationManager.cxx
10  * @author joswilso
11  * @date 2005-06-02
12  */
13 
15 #include "mathNumbers.h"
16 
17 using std::max;
18 using std::min;
19 
20 TypeHandle ColorInterpolationFunction::_type_handle;
21 TypeHandle ColorInterpolationFunctionConstant::_type_handle;
22 TypeHandle ColorInterpolationFunctionLinear::_type_handle;
23 TypeHandle ColorInterpolationFunctionStepwave::_type_handle;
24 TypeHandle ColorInterpolationFunctionSinusoid::_type_handle;
25 
26 /**
27  * constructor
28  */
29 
32 }
33 
34 /**
35  * destructor
36  */
37 
40 }
41 
42 /**
43  * default constructor
44  */
45 
48  _c_a(1.0f,1.0f,1.0f,1.0f) {
49 }
50 
51 /**
52  * constructor
53  */
54 
56 ColorInterpolationFunctionConstant(const LColor &color_a) :
57  _c_a(color_a) {
58 }
59 
60 /**
61  * Returns the color associated with this instance.
62  */
63 
64 LColor ColorInterpolationFunctionConstant::
65 interpolate(const PN_stdfloat t) const {
66  return _c_a;
67 }
68 
69 /**
70  * default constructor
71  */
72 
75  _c_b(1.0f,1.0f,1.0f,1.0f) {
76 }
77 
78 /**
79  * constructor
80  */
81 
83 ColorInterpolationFunctionLinear(const LColor &color_a,
84  const LColor &color_b) :
86  _c_b(color_b) {
87 }
88 
89 /**
90  * Returns the linear mixture of A and B according to 't'.
91  */
92 
93 LColor ColorInterpolationFunctionLinear::
94 interpolate(const PN_stdfloat t) const {
95  return (1.0f-t)*_c_a + t*_c_b;
96 }
97 
98 /**
99  * default constructor
100  */
101 
104  _w_a(0.5f),
105  _w_b(0.5f) {
106 }
107 
108 /**
109  * constructor
110  */
111 
114  const LColor &color_b,
115  const PN_stdfloat width_a,
116  const PN_stdfloat width_b) :
117  ColorInterpolationFunctionLinear(color_a,color_b),
118  _w_a(width_a),
119  _w_b(width_b) {
120 }
121 
122 /**
123  * Returns either A or B.
124  */
125 
126 LColor ColorInterpolationFunctionStepwave::
127 interpolate(const PN_stdfloat t) const {
128  if(fmodf(t,(_w_a+_w_b))<_w_a) {
129  return _c_a;
130  }
131  return _c_b;
132 }
133 
134 /**
135  * default constructor
136  */
137 
140  _period(1.0f) {
141 }
142 
143 /**
144  * constructor
145  */
146 
149  const LColor &color_b,
150  const PN_stdfloat period) :
151  ColorInterpolationFunctionLinear(color_a,color_b),
152  _period(period) {
153 }
154 
155 /**
156  * Returns a sinusoidal blended color between A and B. Period defines the time
157  * it will take to return to A.
158  */
159 
160 LColor ColorInterpolationFunctionSinusoid::
161 interpolate(const PN_stdfloat t) const {
162  PN_stdfloat weight_a = (1.0f+cos(t*MathNumbers::pi_f*2.0f/_period))/2.0f;
163  return (weight_a*_c_a)+((1.0f-weight_a)*_c_b);
164 }
165 
166 /**
167  * constructor
168  */
169 
172  const PN_stdfloat &time_begin,
173  const PN_stdfloat &time_end,
174  const bool is_modulated,
175  const int id) :
176  _color_inter_func(function),
177  _t_begin(time_begin),
178  _t_end(time_end),
179  _t_total(time_end-time_begin),
180  _is_modulated(is_modulated),
181  _enabled(true),
182  _id(id) {
183 }
184 
185 /**
186  * copy constructor
187  */
188 
191  _color_inter_func(copy._color_inter_func),
192  _t_begin(copy._t_begin),
193  _t_end(copy._t_end),
194  _t_total(copy._t_total),
195  _is_modulated(copy._is_modulated),
196  _enabled(copy._enabled),
197  _id(copy._id) {
198 }
199 
200 /**
201  * destructor
202  */
203 
206 }
207 
208 /**
209  * Returns the interpolated color according to the segment's function and
210  * start and end times. 't' is a value in [0-1] where corresponds to
211  * beginning of the segment and 1 corresponds to the end.
212  */
213 
215 interpolateColor(const PN_stdfloat t) const {
216  return _color_inter_func->interpolate((t-_t_begin)/_t_total);
217 }
218 
219 /**
220  * default constructor
221  */
222 
225  _default_color(LColor(1.0f,1.0f,1.0f,1.0f)),
226  _id_generator(0) {
227 }
228 
229 /**
230  * constructor
231  */
232 
234 ColorInterpolationManager(const LColor &c) :
235  _default_color(c),
236  _id_generator(0) {
237 }
238 
239 /**
240  * copy constructor
241  */
242 
245  _default_color(copy._default_color),
246  _i_segs(copy._i_segs),
247  _id_generator(copy._id_generator) {
248 }
249 
250 /**
251  * destructor
252  */
253 
256 }
257 
258 /**
259  * Adds a constant segment of the specified color to the manager and returns
260  * the segment's id as known by the manager.
261  */
262 
264 add_constant(const PN_stdfloat time_begin, const PN_stdfloat time_end, const LColor &color, const bool is_modulated) {
266  PT(ColorInterpolationSegment) sPtr = new ColorInterpolationSegment(fPtr,time_begin,time_end,is_modulated,_id_generator);
267 
268  _i_segs.push_back(sPtr);
269 
270  return _id_generator++;
271 }
272 
273 /**
274  * Adds a linear segment between two colors to the manager and returns the
275  * segment's id as known by the manager.
276  */
277 
279 add_linear(const PN_stdfloat time_begin, const PN_stdfloat time_end, const LColor &color_a, const LColor &color_b, const bool is_modulated) {
281  PT(ColorInterpolationSegment) sPtr = new ColorInterpolationSegment(fPtr,time_begin,time_end,is_modulated,_id_generator);
282 
283  _i_segs.push_back(sPtr);
284 
285  return _id_generator++;
286 }
287 
288 /**
289  * Adds a stepwave segment of two colors to the manager and returns the
290  * segment's id as known by the manager.
291  */
292 
294 add_stepwave(const PN_stdfloat time_begin, const PN_stdfloat time_end, const LColor &color_a, const LColor &color_b, const PN_stdfloat width_a, const PN_stdfloat width_b,const bool is_modulated) {
295  PT(ColorInterpolationFunctionStepwave) fPtr = new ColorInterpolationFunctionStepwave(color_a, color_b, width_a, width_b);
296  PT(ColorInterpolationSegment) sPtr = new ColorInterpolationSegment(fPtr,time_begin,time_end,is_modulated,_id_generator);
297 
298  _i_segs.push_back(sPtr);
299 
300  return _id_generator++;
301 }
302 
303 /**
304  * Adds a stepwave segment of two colors and a specified period to the manager
305  * and returns the segment's id as known by the manager.
306  */
307 
309 add_sinusoid(const PN_stdfloat time_begin, const PN_stdfloat time_end, const LColor &color_a, const LColor &color_b, const PN_stdfloat period,const bool is_modulated) {
310  PT(ColorInterpolationFunctionSinusoid) fPtr = new ColorInterpolationFunctionSinusoid(color_a, color_b, period);
311  PT(ColorInterpolationSegment) sPtr = new ColorInterpolationSegment(fPtr,time_begin,time_end,is_modulated,_id_generator);
312 
313  _i_segs.push_back(sPtr);
314 
315  return _id_generator++;
316 }
317 
318 /**
319  * Removes the segment of 'id' from the manager.
320  */
321 
323 clear_segment(const int seg_id) {
324  pvector<PT(ColorInterpolationSegment)>::iterator iter;
325 
326  for(iter = _i_segs.begin();iter != _i_segs.end();++iter) {
327  if( seg_id == (*iter)->get_id() ) {
328  _i_segs.erase(iter);
329  return;
330  }
331  }
332 }
333 
334 /**
335  * Removes all segments from the manager.
336  */
337 
340  _i_segs.clear();
341  _id_generator = 0;
342 }
343 
344 /**
345  * For time 'interpolated_time', this returns the additive composite color of
346  * all segments that influence that instant in the particle's lifetime. If no
347  * segments cover that time, the manager's default color is returned.
348  */
349 
351 generateColor(const PN_stdfloat interpolated_time) {
352  bool segment_found = false;
353  LColor out(_default_color);
354  ColorInterpolationSegment *cur_seg;
355  pvector<PT(ColorInterpolationSegment)>::iterator iter;
356 
357  for (iter = _i_segs.begin();iter != _i_segs.end();++iter) {
358  cur_seg = (*iter);
359  if( cur_seg->is_enabled() &&
360  interpolated_time >= cur_seg->get_time_begin()
361  && interpolated_time <= cur_seg->get_time_end() ) {
362  segment_found = true;
363  LColor cur_color = cur_seg->interpolateColor(interpolated_time);
364  if( cur_seg->is_modulated() ) {
365  out[0] *= cur_color[0];
366  out[1] *= cur_color[1];
367  out[2] *= cur_color[2];
368  out[3] *= cur_color[3];
369  }
370  else {
371  out[0] += cur_color[0];
372  out[1] += cur_color[1];
373  out[2] += cur_color[2];
374  out[3] += cur_color[3];
375  }
376  }
377  }
378 
379  if(segment_found) {
380  out[0] = max((PN_stdfloat)0.0, min(out[0], (PN_stdfloat)1.0));
381  out[1] = max((PN_stdfloat)0.0, min(out[1], (PN_stdfloat)1.0));
382  out[2] = max((PN_stdfloat)0.0, min(out[2], (PN_stdfloat)1.0));
383  out[3] = max((PN_stdfloat)0.0, min(out[3], (PN_stdfloat)1.0));
384  return out;
385  }
386 
387  return _default_color;
388 }
virtual ~ColorInterpolationSegment()
destructor
ColorInterpolationManager()
default constructor
int add_sinusoid(const PN_stdfloat time_begin=0.0f, const PN_stdfloat time_end=1.0f, const LColor &color_a=LColor(1.0f, 0.0f, 0.0f, 1.0f), const LColor &color_b=LColor(0.0f, 1.0f, 0.0f, 1.0f), const PN_stdfloat period=1.0f, const bool is_modulated=true)
Adds a stepwave segment of two colors and a specified period to the manager and returns the segment's...
A single unit of interpolation.
void clear_segment(const int seg_id)
Removes the segment of 'id' from the manager.
int add_constant(const PN_stdfloat time_begin=0.0f, const PN_stdfloat time_end=1.0f, const LColor &color=LColor(1.0f, 1.0f, 1.0f, 1.0f), const bool is_modulated=true)
Adds a constant segment of the specified color to the manager and returns the segment's id as known b...
virtual ~ColorInterpolationManager()
destructor
ColorInterpolationSegment(ColorInterpolationFunction *function, const PN_stdfloat &time_begin, const PN_stdfloat &time_end, const bool is_modulated, const int id)
constructor
bool is_enabled() const
Returns whether the segments effects are being applied.
LColor interpolateColor(const PN_stdfloat t) const
Returns the interpolated color according to the segment's function and start and end times.
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
void clear_to_initial()
Removes all segments from the manager.
int add_linear(const PN_stdfloat time_begin=0.0f, const PN_stdfloat time_end=1.0f, const LColor &color_a=LColor(1.0f, 0.0f, 0.0f, 1.0f), const LColor &color_b=LColor(0.0f, 1.0f, 0.0f, 1.0f), const bool is_modulated=true)
Adds a linear segment between two colors to the manager and returns the segment's id as known by the ...
High level class for color interpolation.
Defines a discrete cyclical transition between two colors.
PN_stdfloat get_time_begin() const
Returns the point in the particle's lifetime at which this segment begins its effect.
Defines a sinusoidal blending between two colors.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Abstract class from which all other functions should inherit.
int add_stepwave(const PN_stdfloat time_begin=0.0f, const PN_stdfloat time_end=1.0f, const LColor &color_a=LColor(1.0f, 0.0f, 0.0f, 1.0f), const LColor &color_b=LColor(0.0f, 1.0f, 0.0f, 1.0f), const PN_stdfloat width_a=0.5f, const PN_stdfloat width_b=0.5f, const bool is_modulated=true)
Adds a stepwave segment of two colors to the manager and returns the segment's id as known by the man...
PN_stdfloat get_time_end() const
Returns the point in the particle's lifetime at which this segment's effect stops.
LColor generateColor(const PN_stdfloat interpolated_time)
For time 'interpolated_time', this returns the additive composite color of all segments that influenc...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
virtual ~ColorInterpolationFunction()
destructor
bool is_modulated() const
Returns whether the function is additive or modulated.
Defines a constant color over the lifetime of the segment.
Defines a linear interpolation over the lifetime of the segment.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.