Panda3D

colorInterpolationManager.cxx

00001 // Filename: colorInterpolationManager.cxx
00002 // Created by:  joswilso (02Jun05)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 #include "colorInterpolationManager.h"
00015 #include "mathNumbers.h"
00016 
00017 TypeHandle ColorInterpolationFunction::_type_handle;
00018 TypeHandle ColorInterpolationFunctionConstant::_type_handle;
00019 TypeHandle ColorInterpolationFunctionLinear::_type_handle;
00020 TypeHandle ColorInterpolationFunctionStepwave::_type_handle;
00021 TypeHandle ColorInterpolationFunctionSinusoid::_type_handle;
00022 
00023 ////////////////////////////////////////////////////////////////////
00024 //    Function : ColorInterpolationFunction::ColorInterpolationFunction
00025 //      Access : public
00026 // Description : constructor
00027 ////////////////////////////////////////////////////////////////////
00028 
00029 ColorInterpolationFunction::
00030 ColorInterpolationFunction() {
00031 }
00032 
00033 ////////////////////////////////////////////////////////////////////
00034 //    Function : ColorInterpolationFunction::~ColorInterpolationFunction
00035 //      Access : public
00036 // Description : destructor
00037 ////////////////////////////////////////////////////////////////////
00038 
00039 ColorInterpolationFunction::
00040 ~ColorInterpolationFunction() {
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //    Function : ColorInterpolationFunctionConstant::ColorInterpolationFunctionConstant
00045 //      Access : public
00046 // Description : default constructor
00047 ////////////////////////////////////////////////////////////////////
00048 
00049 ColorInterpolationFunctionConstant::
00050 ColorInterpolationFunctionConstant() :
00051   _c_a(1.0f,1.0f,1.0f,1.0f) {
00052 }
00053 
00054 ////////////////////////////////////////////////////////////////////
00055 //    Function : ColorInterpolationFunctionConstant::ColorInterpolationFunctionConstant
00056 //      Access : public
00057 // Description : constructor
00058 ////////////////////////////////////////////////////////////////////
00059 
00060 ColorInterpolationFunctionConstant::
00061 ColorInterpolationFunctionConstant(const LColor &color_a) :
00062   _c_a(color_a) {
00063 }
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //    Function : ColorInterpolationFunctionConstant::interpolate
00067 //      Access : protected
00068 // Description : Returns the color associated with this instance.
00069 ////////////////////////////////////////////////////////////////////
00070 
00071 LColor ColorInterpolationFunctionConstant::
00072 interpolate(const PN_stdfloat t) const {
00073   return _c_a;
00074 }
00075 
00076 ////////////////////////////////////////////////////////////////////
00077 //    Function : ColorInterpolationFunctionLinear::ColorInterpolationFunctionLinear
00078 //      Access : public
00079 // Description : default constructor
00080 ////////////////////////////////////////////////////////////////////
00081 
00082 ColorInterpolationFunctionLinear::
00083 ColorInterpolationFunctionLinear() :
00084   _c_b(1.0f,1.0f,1.0f,1.0f) {
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////
00088 //    Function : ColorInterpolationFunctionLinear::ColorInterpolationFunctionLinear
00089 //      Access : public
00090 // Description : constructor
00091 ////////////////////////////////////////////////////////////////////
00092 
00093 ColorInterpolationFunctionLinear::
00094 ColorInterpolationFunctionLinear(const LColor &color_a, 
00095                                  const LColor &color_b) :
00096   ColorInterpolationFunctionConstant(color_a),
00097   _c_b(color_b) {
00098 }
00099 
00100 ////////////////////////////////////////////////////////////////////
00101 //    Function : ColorInterpolationFunctionLinear::interpolate
00102 //      Access : protected
00103 // Description : Returns the linear mixture of A and B according to 't'.
00104 ////////////////////////////////////////////////////////////////////
00105 
00106 LColor ColorInterpolationFunctionLinear::
00107 interpolate(const PN_stdfloat t) const {
00108   return (1.0f-t)*_c_a + t*_c_b;
00109 }
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //    Function : ColorInterpolationFunctionStepwave::ColorInterpolationFunctionStepwave
00113 //      Access : public
00114 // Description : default constructor
00115 ////////////////////////////////////////////////////////////////////
00116 
00117 ColorInterpolationFunctionStepwave::
00118 ColorInterpolationFunctionStepwave() :
00119   _w_a(0.5f),
00120   _w_b(0.5f) {
00121 }
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //    Function : ColorInterpolationFunctionStepwave::ColorInterpolationFunctionStepwave
00125 //      Access : public
00126 // Description : constructor
00127 ////////////////////////////////////////////////////////////////////
00128 
00129 ColorInterpolationFunctionStepwave::
00130 ColorInterpolationFunctionStepwave(const LColor &color_a,
00131                                    const LColor &color_b, 
00132                                    const PN_stdfloat width_a,
00133                                    const PN_stdfloat width_b) :
00134   ColorInterpolationFunctionLinear(color_a,color_b),
00135   _w_a(width_a),
00136   _w_b(width_b) {
00137 }
00138 
00139 ////////////////////////////////////////////////////////////////////
00140 //    Function : ColorInterpolationFunctionStepwave::interpolate
00141 //      Access : protected
00142 // Description : Returns either A or B.
00143 ////////////////////////////////////////////////////////////////////
00144 
00145 LColor ColorInterpolationFunctionStepwave::
00146 interpolate(const PN_stdfloat t) const { 
00147   if(fmodf(t,(_w_a+_w_b))<_w_a) {
00148       return _c_a;
00149   }
00150   return _c_b;
00151 }
00152 
00153 ////////////////////////////////////////////////////////////////////
00154 //    Function : ColorInterpolationFunctionSinusoid::ColorInterpolationFunctionSinusoid
00155 //      Access : public
00156 // Description : default constructor
00157 ////////////////////////////////////////////////////////////////////
00158 
00159 ColorInterpolationFunctionSinusoid::
00160 ColorInterpolationFunctionSinusoid() :
00161   _period(1.0f) {
00162 }
00163 
00164 ////////////////////////////////////////////////////////////////////
00165 //    Function : ColorInterpolationFunctionSinusoid::ColorInterpolationFunctionSinusoid
00166 //      Access : public
00167 // Description : constructor
00168 ////////////////////////////////////////////////////////////////////
00169 
00170 ColorInterpolationFunctionSinusoid::
00171 ColorInterpolationFunctionSinusoid(const LColor &color_a, 
00172                                    const LColor &color_b, 
00173                                    const PN_stdfloat period) :
00174   ColorInterpolationFunctionLinear(color_a,color_b),
00175   _period(period) {
00176 }
00177 
00178 ////////////////////////////////////////////////////////////////////
00179 //    Function : ColorInterpolationFunctionSinusoid::interpolate
00180 //      Access : protected
00181 // Description : Returns a sinusoidal blended color between A and B.
00182 //               Period defines the time it will take to return to
00183 //               A.
00184 ////////////////////////////////////////////////////////////////////
00185 
00186 LColor ColorInterpolationFunctionSinusoid::
00187 interpolate(const PN_stdfloat t) const {
00188   PN_stdfloat weight_a = (1.0f+cos(t*MathNumbers::pi_f*2.0f/_period))/2.0f;
00189   return (weight_a*_c_a)+((1.0f-weight_a)*_c_b);
00190 }
00191 
00192 ////////////////////////////////////////////////////////////////////
00193 //    Function : ColorInterpolationSegment::ColorInterpolationSegment
00194 //      Access : public
00195 // Description : constructor
00196 ////////////////////////////////////////////////////////////////////
00197 
00198 ColorInterpolationSegment::
00199 ColorInterpolationSegment(ColorInterpolationFunction* function,
00200                           const PN_stdfloat &time_begin,
00201                           const PN_stdfloat &time_end,
00202                           const bool is_modulated,
00203                           const int id) :
00204   _color_inter_func(function),
00205   _t_begin(time_begin),
00206   _t_end(time_end),
00207   _t_total(time_end-time_begin),
00208   _is_modulated(is_modulated),
00209   _enabled(true),
00210   _id(id) {
00211 }
00212 
00213 ////////////////////////////////////////////////////////////////////
00214 //    Function : ColorInterpolationSegment::ColorInterpolationSegment
00215 //      Access : public
00216 // Description : copy constructor
00217 ////////////////////////////////////////////////////////////////////
00218 
00219 ColorInterpolationSegment::
00220 ColorInterpolationSegment(const ColorInterpolationSegment &copy) :
00221   _color_inter_func(copy._color_inter_func),
00222   _t_begin(copy._t_begin),
00223   _t_end(copy._t_end),
00224   _t_total(copy._t_total),
00225   _is_modulated(copy._is_modulated),
00226   _enabled(copy._enabled),
00227   _id(copy._id) {
00228 }
00229 
00230 ////////////////////////////////////////////////////////////////////
00231 //    Function : ColorInterpolationSegment::~ColorInterpolationSegment
00232 //      Access : public
00233 // Description : destructor
00234 ////////////////////////////////////////////////////////////////////
00235 
00236 ColorInterpolationSegment::
00237 ~ColorInterpolationSegment() {
00238 }
00239 
00240 ////////////////////////////////////////////////////////////////////
00241 //    Function : ColorInterpolationSegment::interpolateColor
00242 //      Access : public
00243 // Description : Returns the interpolated color according to the
00244 //               segment's function and start and end times.  't' is
00245 //               a value in [0-1] where corresponds to beginning of
00246 //               the segment and 1 corresponds to the end.
00247 ////////////////////////////////////////////////////////////////////
00248 
00249 LColor ColorInterpolationSegment::
00250 interpolateColor(const PN_stdfloat t) const {
00251   return _color_inter_func->interpolate((t-_t_begin)/_t_total);
00252 }
00253 
00254 ////////////////////////////////////////////////////////////////////
00255 //    Function : ColorInterpolationManager::ColorInterpolationManager
00256 //      Access : public
00257 // Description : default constructor
00258 ////////////////////////////////////////////////////////////////////
00259 
00260 ColorInterpolationManager::
00261 ColorInterpolationManager() :
00262   _default_color(LColor(1.0f,1.0f,1.0f,1.0f)),
00263   _id_generator(0) {
00264 }
00265 
00266 ////////////////////////////////////////////////////////////////////
00267 //    Function : ColorInterpolationManager::ColorInterpolationManager
00268 //      Access : public
00269 // Description : constructor
00270 ////////////////////////////////////////////////////////////////////
00271 
00272 ColorInterpolationManager::
00273 ColorInterpolationManager(const LColor &c) :
00274   _default_color(c),
00275   _id_generator(0) {
00276 }
00277 
00278 ////////////////////////////////////////////////////////////////////
00279 //    Function : ColorInterpolationManager::ColorInterpolationManager
00280 //      Access : public
00281 // Description : copy constructor
00282 ////////////////////////////////////////////////////////////////////
00283 
00284 ColorInterpolationManager::
00285 ColorInterpolationManager(const ColorInterpolationManager& copy) :
00286   _default_color(copy._default_color),
00287   _i_segs(copy._i_segs),
00288   _id_generator(copy._id_generator) {
00289 }
00290 
00291 ////////////////////////////////////////////////////////////////////
00292 //    Function : ColorInterpolationManager::~ColorInterpolationManager
00293 //      Access : public
00294 // Description : destructor
00295 ////////////////////////////////////////////////////////////////////
00296 
00297 ColorInterpolationManager::
00298 ~ColorInterpolationManager() {
00299 }
00300 
00301 ////////////////////////////////////////////////////////////////////
00302 //    Function : ColorInterpolationManager::add_constant
00303 //      Access : public
00304 // Description : Adds a constant segment of the specified color to the
00305 //               manager and returns the segment's id as known
00306 //               by the manager.
00307 ////////////////////////////////////////////////////////////////////
00308 
00309 int ColorInterpolationManager::
00310 add_constant(const PN_stdfloat time_begin, const PN_stdfloat time_end, const LColor &color, const bool is_modulated) {
00311   PT(ColorInterpolationFunctionConstant) fPtr = new ColorInterpolationFunctionConstant(color);
00312   PT(ColorInterpolationSegment) sPtr = new ColorInterpolationSegment(fPtr,time_begin,time_end,is_modulated,_id_generator);
00313 
00314   _i_segs.push_back(sPtr);
00315 
00316   return _id_generator++;
00317 }
00318 
00319 ////////////////////////////////////////////////////////////////////
00320 //    Function : ColorInterpolationManager::add_linear
00321 //      Access : public
00322 // Description : Adds a linear segment between two colors to the manager 
00323 //               and returns the segment's id as known by the manager.
00324 ////////////////////////////////////////////////////////////////////
00325 
00326 int ColorInterpolationManager::
00327 add_linear(const PN_stdfloat time_begin, const PN_stdfloat time_end, const LColor &color_a, const LColor &color_b, const bool is_modulated) {
00328   PT(ColorInterpolationFunctionLinear) fPtr = new ColorInterpolationFunctionLinear(color_a, color_b);
00329   PT(ColorInterpolationSegment) sPtr = new ColorInterpolationSegment(fPtr,time_begin,time_end,is_modulated,_id_generator);
00330 
00331   _i_segs.push_back(sPtr);
00332 
00333   return _id_generator++;
00334 }
00335 
00336 ////////////////////////////////////////////////////////////////////
00337 //    Function : ColorInterpolationManager::add_stepwave
00338 //      Access : public
00339 // Description : Adds a stepwave segment of two colors to the manager 
00340 //               and returns the segment's id as known by the manager.
00341 ////////////////////////////////////////////////////////////////////
00342 
00343 int ColorInterpolationManager::
00344 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) {
00345   PT(ColorInterpolationFunctionStepwave) fPtr = new ColorInterpolationFunctionStepwave(color_a, color_b, width_a, width_b);
00346   PT(ColorInterpolationSegment) sPtr = new ColorInterpolationSegment(fPtr,time_begin,time_end,is_modulated,_id_generator);
00347 
00348   _i_segs.push_back(sPtr);
00349 
00350   return _id_generator++;
00351 }
00352 
00353 ////////////////////////////////////////////////////////////////////
00354 //    Function : ColorInterpolationManager::add_sinusoid
00355 //      Access : public
00356 // Description : Adds a stepwave segment of two colors and a specified
00357 //               period to the manager and returns the segment's 
00358 //               id as known by the manager.
00359 ////////////////////////////////////////////////////////////////////
00360 
00361 int ColorInterpolationManager::
00362 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) {
00363   PT(ColorInterpolationFunctionSinusoid) fPtr = new ColorInterpolationFunctionSinusoid(color_a, color_b, period);
00364   PT(ColorInterpolationSegment) sPtr = new ColorInterpolationSegment(fPtr,time_begin,time_end,is_modulated,_id_generator);
00365 
00366   _i_segs.push_back(sPtr);
00367 
00368   return _id_generator++;
00369 }
00370 
00371 ////////////////////////////////////////////////////////////////////
00372 //    Function : ColorInterpolationManager::clear_segment
00373 //      Access : public
00374 // Description : Removes the segment of 'id' from the manager.
00375 ////////////////////////////////////////////////////////////////////
00376 
00377 void ColorInterpolationManager::
00378 clear_segment(const int seg_id) {
00379   pvector<PT(ColorInterpolationSegment)>::iterator iter;
00380 
00381   for(iter = _i_segs.begin();iter != _i_segs.end();++iter) {
00382     if( seg_id == (*iter)->get_id() ) {
00383         _i_segs.erase(iter);
00384         return;
00385       }
00386   }
00387 }
00388 
00389 ////////////////////////////////////////////////////////////////////
00390 //    Function : ColorInterpolationManager::clear_to_initial
00391 //      Access : public
00392 // Description : Removes all segments from the manager.
00393 ////////////////////////////////////////////////////////////////////
00394 
00395 void ColorInterpolationManager::
00396 clear_to_initial() {
00397   _i_segs.clear();
00398   _id_generator = 0;
00399 }
00400 
00401 ////////////////////////////////////////////////////////////////////
00402 //    Function : ColorInterpolationManager::
00403 //      Access : public
00404 // Description : For time 'interpolated_time', this returns the
00405 //               additive composite color of all segments that influence 
00406 //               that instant in the particle's lifetime. If no segments
00407 //               cover that time, the manager's default color is returned.
00408 ////////////////////////////////////////////////////////////////////
00409 
00410 LColor ColorInterpolationManager::
00411 generateColor(const PN_stdfloat interpolated_time) {
00412   bool segment_found = false;
00413   LColor out(_default_color);
00414   ColorInterpolationSegment *cur_seg;
00415   pvector<PT(ColorInterpolationSegment)>::iterator iter;
00416 
00417   for (iter = _i_segs.begin();iter != _i_segs.end();++iter) {
00418     cur_seg = (*iter);
00419     if( cur_seg->is_enabled() && 
00420         interpolated_time >= cur_seg->get_time_begin() 
00421         && interpolated_time <= cur_seg->get_time_end() ) {
00422       segment_found = true;
00423       LColor cur_color = cur_seg->interpolateColor(interpolated_time);
00424       if( cur_seg->is_modulated() ) {
00425         out[0] *= cur_color[0];
00426         out[1] *= cur_color[1];
00427         out[2] *= cur_color[2];
00428         out[3] *= cur_color[3];
00429       }
00430       else {
00431         out[0] += cur_color[0];
00432         out[1] += cur_color[1];
00433         out[2] += cur_color[2];
00434         out[3] += cur_color[3];
00435       }
00436     }
00437   }
00438   
00439   if(segment_found) {
00440       out[0] = max((PN_stdfloat)0.0, min(out[0], (PN_stdfloat)1.0));
00441       out[1] = max((PN_stdfloat)0.0, min(out[1], (PN_stdfloat)1.0));
00442       out[2] = max((PN_stdfloat)0.0, min(out[2], (PN_stdfloat)1.0));
00443       out[3] = max((PN_stdfloat)0.0, min(out[3], (PN_stdfloat)1.0));
00444     return out;
00445   }
00446   
00447   return _default_color;
00448 }
 All Classes Functions Variables Enumerations