Panda3D
|
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 ©) : 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 }