Panda3D
Loading...
Searching...
No Matches
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
17using std::max;
18using std::min;
19
20TypeHandle ColorInterpolationFunction::_type_handle;
21TypeHandle ColorInterpolationFunctionConstant::_type_handle;
22TypeHandle ColorInterpolationFunctionLinear::_type_handle;
23TypeHandle ColorInterpolationFunctionStepwave::_type_handle;
24TypeHandle ColorInterpolationFunctionSinusoid::_type_handle;
25
26/**
27 * constructor
28 */
29
33
34/**
35 * destructor
36 */
37
41
42/**
43 * default constructor
44 */
45
50
51/**
52 * constructor
53 */
54
56ColorInterpolationFunctionConstant(const LColor &color_a) :
57 _c_a(color_a) {
58}
59
60/**
61 * Returns the color associated with this instance.
62 */
63
64LColor ColorInterpolationFunctionConstant::
65interpolate(const PN_stdfloat t) const {
66 return _c_a;
67}
68
69/**
70 * default constructor
71 */
72
77
78/**
79 * constructor
80 */
81
83ColorInterpolationFunctionLinear(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
93LColor ColorInterpolationFunctionLinear::
94interpolate(const PN_stdfloat t) const {
95 return (1.0f-t)*_c_a + t*_c_b;
96}
97
98/**
99 * default constructor
100 */
101
107
108/**
109 * constructor
110 */
111
113ColorInterpolationFunctionStepwave(const LColor &color_a,
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
126LColor ColorInterpolationFunctionStepwave::
127interpolate(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
142
143/**
144 * constructor
145 */
146
148ColorInterpolationFunctionSinusoid(const LColor &color_a,
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
160LColor ColorInterpolationFunctionSinusoid::
161interpolate(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
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
215interpolateColor(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
234ColorInterpolationManager(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
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
264add_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
279add_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
294add_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
309add_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
323clear_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
351generateColor(const PN_stdfloat interpolated_time) {
352 bool segment_found = false;
353 LColor out(_default_color);
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}
Defines a constant color over the lifetime of the segment.
Defines a linear interpolation over the lifetime of the segment.
Defines a sinusoidal blending between two colors.
Defines a discrete cyclical transition between two colors.
Abstract class from which all other functions should inherit.
virtual ~ColorInterpolationFunction()
destructor
High level class for color interpolation.
ColorInterpolationManager()
default constructor
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...
void clear_to_initial()
Removes all segments from the manager.
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...
LColor generateColor(const PN_stdfloat interpolated_time)
For time 'interpolated_time', this returns the additive composite color of all segments that influenc...
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 ...
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...
void clear_segment(const int seg_id)
Removes the segment of 'id' from the manager.
A single unit of interpolation.
bool is_modulated() const
Returns whether the function is additive or modulated.
ColorInterpolationSegment(ColorInterpolationFunction *function, const PN_stdfloat &time_begin, const PN_stdfloat &time_end, const bool is_modulated, const int id)
constructor
PN_stdfloat get_time_begin() const
Returns the point in the particle's lifetime at which this segment begins its effect.
LColor interpolateColor(const PN_stdfloat t) const
Returns the interpolated color according to the segment's function and start and end times.
PN_stdfloat get_time_end() const
Returns the point in the particle's lifetime at which this segment's effect stops.
bool is_enabled() const
Returns whether the segments effects are being applied.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
This is our own Panda specialization on the default STL vector.
Definition pvector.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.