00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef COLOR_3F_H_
00026 #define COLOR_3F_H_
00027
00028 #include <Core/System/Math.h>
00029
00030 namespace Lamp{
00031
00032 class Color3c;
00033 class Color4c;
00034 class Color4f;
00035
00036
00037
00038
00039
00040
00041
00042 class Color3f{
00043 public:
00044
00045
00046
00047
00048 union{
00049
00050 struct{
00051
00052 float r;
00053
00054 float g;
00055
00056 float b;
00057 };
00058
00059
00060 struct{
00061
00062 float h;
00063
00064 float s;
00065
00066 float v;
00067 };
00068
00069
00070 float array[3];
00071 };
00072
00073
00074
00075
00076
00077 static const Color3f white;
00078
00079
00080 static const Color3f gray;
00081
00082
00083 static const Color3f black;
00084
00085
00086 static const Color3f red;
00087
00088
00089 static const Color3f green;
00090
00091
00092 static const Color3f blue;
00093
00094
00095 static const Color3f yellow;
00096
00097
00098 static const Color3f cyan;
00099
00100
00101 static const Color3f magenta;
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 Color3f(){}
00112
00113
00114
00115
00116
00117
00118
00119 inline Color3f(float sourceR, float sourceG, float sourceB) :
00120 r(sourceR), g(sourceG), b(sourceB){
00121 }
00122
00123
00124
00125
00126
00127 explicit Color3f(const Color3c& source);
00128
00129
00130
00131
00132
00133 explicit Color3f(const Color4c& source);
00134
00135
00136
00137
00138
00139 explicit Color3f(const Color4f& source);
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 inline void set(float sourceR, float sourceG, float sourceB){
00151 r = sourceR;
00152 g = sourceG;
00153 b = sourceB;
00154 }
00155
00156
00157
00158
00159
00160 void set(const Color3c& source);
00161
00162
00163
00164
00165
00166 void set(const Color4c& source);
00167
00168
00169
00170
00171
00172 void set(const Color4f& source);
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 inline Color3f operator +(const Color3f& addColor) const{
00183 return Color3f(r + addColor.r, g + addColor.g, b + addColor.b);
00184 }
00185
00186
00187
00188
00189
00190
00191 inline Color3f operator -(const Color3f& subColor) const{
00192 return Color3f(r - subColor.r, g - subColor.g, b - subColor.b);
00193 }
00194
00195
00196
00197
00198
00199
00200 inline Color3f operator *(const Color3f& mulColor) const{
00201 return Color3f(r * mulColor.r, g * mulColor.g, b * mulColor.b);
00202 }
00203
00204
00205
00206
00207
00208
00209 inline Color3f operator *(float mulValue) const{
00210 return Color3f(r * mulValue, g * mulValue, b * mulValue);
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 inline friend Color3f operator *(float mulValue, const Color3f& mulColor){
00220 return Color3f(mulColor.r * mulValue,
00221 mulColor.g * mulValue, mulColor.b * mulValue);
00222 }
00223
00224
00225
00226
00227
00228 inline Color3f operator +() const{ return *this; }
00229
00230
00231
00232
00233
00234 inline Color3f operator -() const{ return Color3f(-r, -g, -b); }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 inline Color3f& operator +=(const Color3f& addColor){
00245 r += addColor.r;
00246 g += addColor.g;
00247 b += addColor.b;
00248 return (*this);
00249 }
00250
00251
00252
00253
00254
00255
00256 inline Color3f& operator -=(const Color3f& subColor){
00257 r -= subColor.r;
00258 g -= subColor.g;
00259 b -= subColor.b;
00260 return (*this);
00261 }
00262
00263
00264
00265
00266
00267
00268 inline Color3f& operator *=(const Color3f& mulColor){
00269 r *= mulColor.r;
00270 g *= mulColor.g;
00271 b *= mulColor.b;
00272 return (*this);
00273 }
00274
00275
00276
00277
00278
00279
00280 inline Color3f& operator *=(float mulValue){
00281 r *= mulValue;
00282 g *= mulValue;
00283 b *= mulValue;
00284 return (*this);
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 inline Color3f& clamp(float lower = 0.f, float upper = 1.f){
00297 Assert(upper > lower);
00298 if(r > upper){ r = upper; }
00299 else if(r < lower){ r = lower; }
00300 if(g > upper){ g = upper; }
00301 else if(g < lower){ g = lower; }
00302 if(b > upper){ b = upper; }
00303 else if(b < lower){ b = lower; }
00304 return (*this);
00305 }
00306
00307
00308
00309
00310
00311
00312 inline Color3f& lowerClamp(float lower = 0.f){
00313 if(r < lower){ r = lower; }
00314 if(g < lower){ g = lower; }
00315 if(b < lower){ b = lower; }
00316 return (*this);
00317 }
00318
00319
00320
00321
00322
00323
00324 inline Color3f& upperClamp(float upper = 1.f){
00325 if(r > upper){ r = upper; }
00326 if(g > upper){ g = upper; }
00327 if(b > upper){ b = upper; }
00328 return (*this);
00329 }
00330
00331
00332
00333
00334
00335 inline Color3f& negative(){
00336 set(1.f - r, 1.f - g, 1.f - b);
00337 return (*this);
00338 }
00339
00340
00341
00342
00343
00344
00345 inline void setHSV(const Color3f& hsv){
00346 float value = hsv.v;
00347 if(hsv.s <= Math::epsilon){
00348 set(value, value, value);
00349 return;
00350 }
00351 float hue = hsv.h * 6.f;
00352 float integer = Math::floor(hue);
00353 float decimal = hue - integer;
00354 float temp0 = value * (1.f - hsv.s);
00355 float temp1 = value * (1.f - (hsv.s * decimal));
00356 float temp2 = value * (1.f - (hsv.s * (1.f - decimal)));
00357 if(integer < 1.f){
00358 set(value, temp2, temp0);
00359 }else if(integer < 2.f){
00360 set(temp1, value, temp0);
00361 }else if(integer < 3.f){
00362 set(temp0, value, temp2);
00363 }else if(integer < 4.f){
00364 set(temp0, temp1, value);
00365 }else if(integer < 5.f){
00366 set(temp2, temp0, value);
00367 }else{
00368 set(value, temp0, temp1);
00369 }
00370 }
00371
00372
00373
00374
00375
00376 inline Color3f getHSV() const{
00377 Color3f hsv;
00378
00379 float maximum = Math::maximum(r, Math::maximum(g, b));
00380 hsv.v = maximum;
00381
00382 float minimum = Math::minimum(r, Math::minimum(g, b));
00383 float chroma = maximum - minimum;
00384 if(maximum <= Math::epsilon){
00385 hsv.s = 0.f;
00386 hsv.h = 0.f;
00387 return hsv;
00388 }else{
00389 hsv.s = chroma / maximum;
00390 }
00391 if(chroma <= Math::epsilon){
00392 hsv.h = 0.f;
00393 return hsv;
00394 }
00395 float hueScale = (1 / chroma) * 0.16666667f;
00396 if(r == maximum){
00397 hsv.h = (g - b) * hueScale;
00398 }else if(g == maximum){
00399 hsv.h = (b - r) * hueScale + 0.33333338f;
00400 }else{
00401 hsv.h = (r - g) * hueScale + 0.66666667f;
00402 }
00403 if(hsv.h < 0.f){ hsv.h += 1.f; }
00404 return hsv;
00405 }
00406
00407
00408
00409
00410
00411
00412 inline float getHue() const{
00413 float maximum = Math::maximum(r, Math::maximum(g, b));
00414 if(maximum <= Math::epsilon){ return 0.f; }
00415 float minimum = Math::minimum(r, Math::minimum(g, b));
00416 float chroma = maximum - minimum;
00417 if(chroma <= Math::epsilon){ return 0.f; }
00418 float hueScale = (1 / chroma) * 0.1666667f;
00419 float hue;
00420 if(r == maximum){
00421 hue = (g - b) * hueScale;
00422 }else if(g == maximum){
00423 hue = (b - r) * hueScale + 0.3333333f;
00424 }else{
00425 hue = (r - g) * hueScale + 0.6666667f;
00426 }
00427 if(hue < 0.f){ hue += 1.f; }
00428 }
00429
00430
00431
00432
00433
00434 inline float getSaturation() const{
00435 float maximum = Math::maximum(r, Math::maximum(g, b));
00436 if(maximum <= Math::epsilon){ return 0.f; }
00437 float minimum = Math::minimum(r, Math::minimum(g, b));
00438 float chroma = maximum - minimum;
00439 return chroma / maximum;
00440 }
00441
00442
00443
00444
00445
00446 inline float getValue() const{
00447 return Math::maximum(r, Math::maximum(g, b));
00448 }
00449
00450
00451
00452
00453
00454 inline float getLuminance() const{
00455 return (r * 0.298912f + g * 0.586611f + b * 0.114477f);
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 inline static Color3f lerp(
00467 const Color3f& source, const Color3f& target, float alpha){
00468 float beta = 1.f - alpha;
00469 Color3f result;
00470 result.r = source.r * beta + target.r * alpha;
00471 result.g = source.g * beta + target.g * alpha;
00472 result.b = source.b * beta + target.b * alpha;
00473 return result;
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 inline bool operator ==(const Color3f& target) const{
00485 return ((r == target.r) && (g == target.g) && (b == target.b));
00486 }
00487
00488
00489
00490
00491
00492
00493
00494 inline bool epsilonEquals(const Color3f& target, float epsilon) const{
00495 Assert(epsilon >= 0.f);
00496 return (
00497 (Math::abs(r - target.r) <= epsilon) &&
00498 (Math::abs(g - target.g) <= epsilon) &&
00499 (Math::abs(b - target.b) <= epsilon));
00500 }
00501
00502
00503
00504
00505
00506
00507 inline bool operator !=(const Color3f& target) const{
00508 return ((r != target.r) || (g != target.g) || (b != target.b));
00509 }
00510
00511
00512
00513
00514
00515
00516
00517 inline bool notEpsilonEquals(const Color3f& target, float epsilon) const{
00518 Assert(epsilon >= 0.f);
00519 return (
00520 (Math::abs(r - target.r) > epsilon) ||
00521 (Math::abs(g - target.g) > epsilon) ||
00522 (Math::abs(b - target.b) > epsilon));
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532 inline String toString() const{
00533 String returnString;
00534 returnString.format("( %.8f, %.8f, %.8f )", r, g, b);
00535 return returnString;
00536 }
00537
00538
00539 private:
00540
00541 };
00542
00543
00544 }
00545 #endif // End of COLOR_3F_H_
00546