00001 
00032 #ifndef LL_V4COLORU_H
00033 #define LL_V4COLORU_H
00034 
00035 #include "llerror.h"
00036 
00037 #include "llmath.h"
00038 
00039 
00040 #include "v3color.h"
00041 #include "v4color.h"
00042 
00043 
00044 class LLColor4;
00045 
00046 
00047 
00048 static const U32 LENGTHOFCOLOR4U = 4;
00049 
00050 
00051 class LLColor4U
00052 {
00053 public:
00054 
00055         union
00056         {
00057                 U8         mV[LENGTHOFCOLOR4U];
00058                 U32        mAll;
00059                 LLColor4*  mSources;
00060                 LLColor4U* mSourcesU;
00061         };
00062 
00063 
00064         LLColor4U();                                            
00065         LLColor4U(U8 r, U8 g, U8 b);            
00066         LLColor4U(U8 r, U8 g, U8 b, U8 a);              
00067         LLColor4U(const U8 *vec);                       
00068         LLColor4U(const LLSD& sd)
00069         {
00070                 setValue(sd);
00071         }
00072 
00073         void setValue(const LLSD& sd)
00074         {
00075                 mV[0] = sd[0].asInteger();
00076                 mV[1] = sd[1].asInteger();
00077                 mV[2] = sd[2].asInteger();
00078                 mV[3] = sd[3].asInteger();
00079         }
00080 
00081         const LLColor4U& operator=(const LLSD& sd)
00082         {
00083                 setValue(sd);
00084                 return *this;
00085         }
00086 
00087         LLSD getValue() const
00088         {
00089                 LLSD ret;
00090                 ret[0] = mV[0];
00091                 ret[1] = mV[1];
00092                 ret[2] = mV[2];
00093                 ret[3] = mV[3];
00094                 return ret;
00095         }
00096 
00097         const LLColor4U&        setToBlack();                                           
00098         const LLColor4U&        setToWhite();                                           
00099 
00100         const LLColor4U&        setVec(U8 r, U8 g, U8 b, U8 a); 
00101         const LLColor4U&        setVec(U8 r, U8 g, U8 b);       
00102         const LLColor4U&        setVec(const LLColor4U &vec);   
00103         const LLColor4U&        setVec(const U8 *vec);                  
00104 
00105         const LLColor4U&    setAlpha(U8 a);
00106 
00107         F32                     magVec() const;                         
00108         F32                     magVecSquared() const;          
00109 
00110         friend std::ostream&     operator<<(std::ostream& s, const LLColor4U &a);               
00111         friend LLColor4U operator+(const LLColor4U &a, const LLColor4U &b);     
00112         friend LLColor4U operator-(const LLColor4U &a, const LLColor4U &b);     
00113         friend LLColor4U operator*(const LLColor4U &a, const LLColor4U &b);     
00114         friend bool operator==(const LLColor4U &a, const LLColor4U &b);         
00115         friend bool operator!=(const LLColor4U &a, const LLColor4U &b);         
00116 
00117         friend const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b);   
00118         friend const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b);   
00119         friend const LLColor4U& operator*=(LLColor4U &a, U8 k);                         
00120         friend const LLColor4U& operator%=(LLColor4U &a, U8 k);                         
00121 
00122         LLColor4U addClampMax(const LLColor4U &color);                                          
00123 
00124         LLColor4U multAll(const F32 k);                                                                         
00125         const LLColor4U& combine();
00126 
00127         inline void setVecScaleClamp(const LLColor3 &color);
00128         inline void setVecScaleClamp(const LLColor4 &color);
00129 
00130         static BOOL parseColor4U(const char* buf, LLColor4U* value);
00131 
00132         static LLColor4U white;
00133         static LLColor4U black;
00134         static LLColor4U red;
00135         static LLColor4U green;
00136         static LLColor4U blue;
00137 };
00138 
00139 
00140 
00141 F32             distVec(const LLColor4U &a, const LLColor4U &b);                        
00142 F32             distVec_squared(const LLColor4U &a, const LLColor4U &b);        
00143 
00144 
00145 inline LLColor4U::LLColor4U()
00146 {
00147         mV[VX] = 0;
00148         mV[VY] = 0;
00149         mV[VZ] = 0;
00150         mV[VW] = 255;
00151 }
00152 
00153 inline LLColor4U::LLColor4U(U8 r, U8 g, U8 b)
00154 {
00155         mV[VX] = r;
00156         mV[VY] = g;
00157         mV[VZ] = b;
00158         mV[VW] = 255;
00159 }
00160 
00161 inline LLColor4U::LLColor4U(U8 r, U8 g, U8 b, U8 a)
00162 {
00163         mV[VX] = r;
00164         mV[VY] = g;
00165         mV[VZ] = b;
00166         mV[VW] = a;
00167 }
00168 
00169 inline LLColor4U::LLColor4U(const U8 *vec)
00170 {
00171         mV[VX] = vec[VX];
00172         mV[VY] = vec[VY];
00173         mV[VZ] = vec[VZ];
00174         mV[VW] = vec[VW];
00175 }
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 inline const LLColor4U& LLColor4U::setToBlack(void)
00185 {
00186         mV[VX] = 0;
00187         mV[VY] = 0;
00188         mV[VZ] = 0;
00189         mV[VW] = 255;
00190         return (*this);
00191 }
00192 
00193 inline const LLColor4U& LLColor4U::setToWhite(void)
00194 {
00195         mV[VX] = 255;
00196         mV[VY] = 255;
00197         mV[VZ] = 255;
00198         mV[VW] = 255;
00199         return (*this);
00200 }
00201 
00202 inline const LLColor4U& LLColor4U::setVec(const U8 x, const U8 y, const U8 z)
00203 {
00204         mV[VX] = x;
00205         mV[VY] = y;
00206         mV[VZ] = z;
00207 
00208 
00209 
00210 
00211         return (*this);
00212 }
00213 
00214 inline const LLColor4U& LLColor4U::setVec(const U8 r, const U8 g, const U8 b, U8 a)
00215 {
00216         mV[0] = r;
00217         mV[1] = g;
00218         mV[2] = b;
00219         mV[3] = a;  
00220         return (*this);
00221 }
00222 
00223 inline const LLColor4U& LLColor4U::setVec(const LLColor4U &vec)
00224 {
00225         mV[VX] = vec.mV[VX];
00226         mV[VY] = vec.mV[VY];
00227         mV[VZ] = vec.mV[VZ];
00228         mV[VW] = vec.mV[VW];
00229         return (*this);
00230 }
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 inline const LLColor4U& LLColor4U::setVec(const U8 *vec)
00244 {
00245         mV[VX] = vec[VX];
00246         mV[VY] = vec[VY];
00247         mV[VZ] = vec[VZ];
00248         mV[VW] = vec[VW];
00249         return (*this);
00250 }
00251 
00252 inline const LLColor4U& LLColor4U::setAlpha(U8 a)
00253 {
00254         mV[VW] = a;
00255         return (*this);
00256 }
00257 
00258 
00259 
00260 
00261 inline F32              LLColor4U::magVec(void) const
00262 {
00263         return fsqrtf( ((F32)mV[VX]) * mV[VX] + ((F32)mV[VY]) * mV[VY] + ((F32)mV[VZ]) * mV[VZ] );
00264 }
00265 
00266 inline F32              LLColor4U::magVecSquared(void) const
00267 {
00268         return ((F32)mV[VX]) * mV[VX] + ((F32)mV[VY]) * mV[VY] + ((F32)mV[VZ]) * mV[VZ];
00269 }
00270 
00271 inline LLColor4U operator+(const LLColor4U &a, const LLColor4U &b)
00272 {
00273         return LLColor4U(
00274                 a.mV[VX] + b.mV[VX],
00275                 a.mV[VY] + b.mV[VY],
00276                 a.mV[VZ] + b.mV[VZ],
00277                 a.mV[VW] + b.mV[VW]);
00278 }
00279 
00280 inline LLColor4U operator-(const LLColor4U &a, const LLColor4U &b)
00281 {
00282         return LLColor4U(
00283                 a.mV[VX] - b.mV[VX],
00284                 a.mV[VY] - b.mV[VY],
00285                 a.mV[VZ] - b.mV[VZ],
00286                 a.mV[VW] - b.mV[VW]);
00287 }
00288 
00289 inline LLColor4U  operator*(const LLColor4U &a, const LLColor4U &b)
00290 {
00291         return LLColor4U(
00292                 a.mV[VX] * b.mV[VX],
00293                 a.mV[VY] * b.mV[VY],
00294                 a.mV[VZ] * b.mV[VZ],
00295                 a.mV[VW] * b.mV[VW]);
00296 }
00297 
00298 inline LLColor4U LLColor4U::addClampMax(const LLColor4U &color)
00299 {
00300         return LLColor4U(llmin((S32)mV[VX] + color.mV[VX], 255),
00301                                         llmin((S32)mV[VY] + color.mV[VY], 255),
00302                                         llmin((S32)mV[VZ] + color.mV[VZ], 255),
00303                                         llmin((S32)mV[VW] + color.mV[VW], 255));
00304 }
00305 
00306 inline LLColor4U LLColor4U::multAll(const F32 k)
00307 {
00308         
00309         return LLColor4U(
00310                 (U8)llround(mV[VX] * k),
00311                 (U8)llround(mV[VY] * k),
00312                 (U8)llround(mV[VZ] * k),
00313                 (U8)llround(mV[VW] * k));
00314 }
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 inline bool operator==(const LLColor4U &a, const LLColor4U &b)
00358 {
00359         return (  (a.mV[VX] == b.mV[VX])
00360                         &&(a.mV[VY] == b.mV[VY])
00361                         &&(a.mV[VZ] == b.mV[VZ])
00362                         &&(a.mV[VW] == b.mV[VW]));
00363 }
00364 
00365 inline bool operator!=(const LLColor4U &a, const LLColor4U &b)
00366 {
00367         return (  (a.mV[VX] != b.mV[VX])
00368                         ||(a.mV[VY] != b.mV[VY])
00369                         ||(a.mV[VZ] != b.mV[VZ])
00370                         ||(a.mV[VW] != b.mV[VW]));
00371 }
00372 
00373 inline const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b)
00374 {
00375         a.mV[VX] += b.mV[VX];
00376         a.mV[VY] += b.mV[VY];
00377         a.mV[VZ] += b.mV[VZ];
00378         a.mV[VW] += b.mV[VW];
00379         return a;
00380 }
00381 
00382 inline const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b)
00383 {
00384         a.mV[VX] -= b.mV[VX];
00385         a.mV[VY] -= b.mV[VY];
00386         a.mV[VZ] -= b.mV[VZ];
00387         a.mV[VW] -= b.mV[VW];
00388         return a;
00389 }
00390 
00391 inline const LLColor4U& operator*=(LLColor4U &a, U8 k)
00392 {
00393         
00394         a.mV[VX] *= k;
00395         a.mV[VY] *= k;
00396         a.mV[VZ] *= k;
00397         return a;
00398 }
00399 
00400 inline const LLColor4U& operator%=(LLColor4U &a, U8 k)
00401 {
00402         
00403         a.mV[VW] *= k;
00404         return a;
00405 }
00406 
00407 inline F32              distVec(const LLColor4U &a, const LLColor4U &b)
00408 {
00409         LLColor4U vec = a - b;
00410         return (vec.magVec());
00411 }
00412 
00413 inline F32              distVec_squared(const LLColor4U &a, const LLColor4U &b)
00414 {
00415         LLColor4U vec = a - b;
00416         return (vec.magVecSquared());
00417 }
00418 
00419 void LLColor4U::setVecScaleClamp(const LLColor4& color)
00420 {
00421         F32 color_scale_factor = 255.f;
00422         F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]);
00423         if (max_color > 1.f)
00424         {
00425                 color_scale_factor /= max_color;
00426         }
00427         const S32 MAX_COLOR = 255;
00428         S32 r = llround(color.mV[0] * color_scale_factor);
00429         if (r > MAX_COLOR)
00430         {
00431                 r = MAX_COLOR;
00432         }
00433         else if (r < 0)
00434         {
00435                 r = 0;
00436         }
00437         mV[0] = r;
00438 
00439         S32 g = llround(color.mV[1] * color_scale_factor);
00440         if (g > MAX_COLOR)
00441         {
00442                 g = MAX_COLOR;
00443         }
00444         else if (g < 0)
00445         {
00446                 g = 0;
00447         }
00448         mV[1] = g;
00449 
00450         S32 b = llround(color.mV[2] * color_scale_factor);
00451         if (b > MAX_COLOR)
00452         {
00453                 b = MAX_COLOR;
00454         }
00455         else if (b < 0)
00456         {
00457                 b = 0;
00458         }
00459         mV[2] = b;
00460 
00461         
00462         S32 a = llround(color.mV[3] * MAX_COLOR);
00463         if (a > MAX_COLOR)
00464         {
00465                 a = MAX_COLOR;
00466         }
00467         else if (a < 0)
00468         {
00469                 a = 0;
00470         }
00471         mV[3] = a;
00472 }
00473 
00474 void LLColor4U::setVecScaleClamp(const LLColor3& color)
00475 {
00476         F32 color_scale_factor = 255.f;
00477         F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]);
00478         if (max_color > 1.f)
00479         {
00480                 color_scale_factor /= max_color;
00481         }
00482 
00483         const S32 MAX_COLOR = 255;
00484         S32 r = llround(color.mV[0] * color_scale_factor);
00485         if (r > MAX_COLOR)
00486         {
00487                 r = MAX_COLOR;
00488         }
00489         else
00490         if (r < 0)
00491         {
00492                 r = 0;
00493         }
00494         mV[0] = r;
00495 
00496         S32 g = llround(color.mV[1] * color_scale_factor);
00497         if (g > MAX_COLOR)
00498         {
00499                 g = MAX_COLOR;
00500         }
00501         else
00502         if (g < 0)
00503         {
00504                 g = 0;
00505         }
00506         mV[1] = g;
00507 
00508         S32 b = llround(color.mV[2] * color_scale_factor);
00509         if (b > MAX_COLOR)
00510         {
00511                 b = MAX_COLOR;
00512         }
00513         if (b < 0)
00514         {
00515                 b = 0;
00516         }
00517         mV[2] = b;
00518 
00519         mV[3] = 255;
00520 }
00521 
00522 
00523 #endif
00524