00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __VCGLIB_COLOR4
00025 #define __VCGLIB_COLOR4
00026
00027 #include <vcg/space/point3.h>
00028 #include <vcg/space/point4.h>
00029
00030 namespace vcg {
00031
00039 template <class T>
00040 class Color4 : public Point4<T>
00041 {
00042 typedef Point4<T> Base;
00043 public:
00046 enum ColorConstant {
00047 Black = 0xff000000,
00048 Gray = 0xff808080,
00049 White = 0xffffffff,
00050
00051 Red = 0xff0000ff,
00052 Green = 0xff00ff00,
00053 Blue = 0xffff0000,
00054
00055 Cyan = 0xffffff00,
00056 Yellow = 0xff00ffff,
00057 Magenta = 0xffff00ff,
00058
00059 LightGray =0xffc0c0c0,
00060 LightRed =0xff8080ff,
00061 LightGreen =0xff80ff80,
00062 LightBlue =0xffff8080,
00063
00064 DarkGray =0xff404040,
00065 DarkRed =0xff000040,
00066 DarkGreen =0xff004000,
00067 DarkBlue =0xff400000
00068 };
00069
00070 inline Color4 ( const T nx, const T ny, const T nz , const T nw ) :Point4<T>(nx,ny,nz,nw) {}
00071 inline Color4 ( const Point4<T> &c) :Point4<T>(c) {}
00072 inline Color4 (){}
00073 inline Color4 (ColorConstant cc);
00074 inline Color4 (unsigned int cc);
00075
00076 template <class Q>
00077 inline void Import(const Color4<Q> & b )
00078 {
00079 (*this)[0] = T(b[0]);
00080 (*this)[1] = T(b[1]);
00081 (*this)[2] = T(b[2]);
00082 (*this)[3] = T(b[3]);
00083 }
00084
00085 template <class Q>
00086 inline void Import(const Point4<Q> & b )
00087 {
00088 (*this)[0] = T(b[0]);
00089 (*this)[1] = T(b[1]);
00090 (*this)[2] = T(b[2]);
00091 (*this)[3] = T(b[3]);
00092 }
00093
00094 template <class Q>
00095 static inline Color4 Construct( const Color4<Q> & b )
00096 {
00097 return Color4(T(b[0]),T(b[1]),T(b[2]),T(b[3]));
00098 }
00099
00100
00101
00102
00103 inline Color4 operator + ( const Color4 & p) const
00104 {
00105 return Color4( (*this)[0]+p.V()[0], (*this)[1]+p.V()[1], (*this)[2]+p.V()[2], (*this)[3]+p.V()[3] );
00106 }
00107
00108 template <class ScalarInterpType>
00109 inline void lerp(const Color4 &c0, const Color4 &c1, const ScalarInterpType x)
00110 {
00111 assert(x>=0);
00112 assert(x<=1);
00113
00114 (*this)[0]=(T)(c1.V()[0]*x + c0.V()[0]*(1.0f-x));
00115 (*this)[1]=(T)(c1.V()[1]*x + c0.V()[1]*(1.0f-x));
00116 (*this)[2]=(T)(c1.V()[2]*x + c0.V()[2]*(1.0f-x));
00117 (*this)[3]=(T)(c1.V()[3]*x + c0.V()[3]*(1.0f-x));
00118 }
00119
00120 template <class ScalarInterpType>
00121 inline void lerp(const Color4 &c0, const Color4 &c1, const Color4 &c2, const Point3<ScalarInterpType> &ip)
00122 {
00123 assert(fabs(ip[0]+ip[1]+ip[2]-1)<0.00001);
00124
00125 (*this)[0]=(T)(c0[0]*ip[0] + c1[0]*ip[1]+ c2[0]*ip[2]);
00126 (*this)[1]=(T)(c0[1]*ip[0] + c1[1]*ip[1]+ c2[1]*ip[2]);
00127 (*this)[2]=(T)(c0[2]*ip[0] + c1[2]*ip[1]+ c2[2]*ip[2]);
00128 (*this)[3]=(T)(c0[3]*ip[0] + c1[3]*ip[1]+ c2[3]*ip[2]);
00129 }
00130
00131
00133 inline void SetColorRamp(const float &minf,const float &maxf ,float v )
00134 {
00135 if(minf>maxf) { SetColorRamp(maxf,minf,maxf+(minf-v)); return; }
00136
00137 float step=(maxf-minf)/4;
00138 if(v < minf ) { *this=Color4<T>(Color4<T>::Red); return; }
00139 v-=minf;
00140 if(v<step) { lerp(Color4<T>(Color4<T>::Red), Color4<T>(Color4<T>::Yellow),v/step); return;}
00141 v-=step;
00142 if(v<step) { lerp(Color4<T>(Color4<T>::Yellow),Color4<T>(Color4<T>::Green), v/step); return;}
00143 v-=step;
00144 if(v<step) { lerp(Color4<T>(Color4<T>::Green), Color4<T>(Color4<T>::Cyan), v/step); return;}
00145 v-=step;
00146 if(v<step) { lerp(Color4<T>(Color4<T>::Cyan), Color4<T>(Color4<T>::Blue), v/step); return;}
00147
00148 *this= Color4<T>(Color4<T>::Blue);
00149 }
00150
00151 inline void SetColorRampParula(const float &minf,const float &maxf ,float v)
00152 {
00153 if(minf>maxf) { SetColorRampParula(maxf,minf,maxf+(minf-v)); return; }
00154 SetColorRampParula((v-minf)/(maxf-minf));
00155 }
00156
00157 inline void SetColorRampParula(float v)
00158 {
00159 if(v<0) v=0;
00160 else if(v>1) v=1;
00161
00162 unsigned int ParuVal[9]={0xff801627, 0xffe16303, 0xffd48514,
00163 0xffc6a706, 0xff9eb938, 0xff73bf92,
00164 0xff56bad9, 0xff2ecefc, 0xff0afaff};
00165 int ind = int(floor(v*8.0f));
00166 float div = (v*8.0f - ind);
00167 if(div<0) div=0;
00168 else if(div>1) div=1;
00169 lerp(Color4<T>(ParuVal[ind]), Color4<T>(ParuVal[ind+1]), div);
00170 }
00171
00172 void SetHSVColor( float h, float s, float v)
00173 {
00174 float r,g,b;
00175 if(s==0.0){
00176 r = g = b = v;
00177 (*this)[0]=(unsigned char)(255*r);
00178 (*this)[1]=(unsigned char)(255*g);
00179 (*this)[2]=(unsigned char)(255*b);
00180 (*this)[3]=255;
00181 return;
00182 }
00183 if(h==1.0) h = 0.0;
00184
00185 int i = int( floor(h*6.0) );
00186 float f = float(h*6.0f - floor(h*6.0f));
00187
00188 float p = v*(1.0f-s);
00189 float q = v*(1.0f-s*f);
00190 float t = v*(1.0f-s*(1.0f-f));
00191
00192 switch(i)
00193 {
00194 case 0: r=v; g=t; b=p; break;
00195 case 1: r=q; g=v; b=p; break;
00196 case 2: r=p; g=v; b=t; break;
00197 case 3: r=p; g=q; b=v; break;
00198 case 4: r=t; g=p; b=v; break;
00199 case 5: r=v; g=p; b=q; break;
00200 default: r=0;g=0;b=0; assert(0);break;
00201 }
00202 (*this)[0]=(unsigned char)(255*r);
00203 (*this)[1]=(unsigned char)(255*g);
00204 (*this)[2]=(unsigned char)(255*b);
00205 (*this)[3]=255;
00206 }
00207
00208 inline static Color4 GrayShade(float f)
00209 {
00210 if(f<0) f=0.0f;
00211 else if(f>1) f=1.0f;
00212
00213 return Color4(f,f,f,1);
00214 }
00215
00216 inline void SetGrayShade(float f)
00217 {
00218 if(f<0) f=0.0f;
00219 else if(f>1) f=1.0f;
00220
00221 Import(Color4<float>(f,f,f,1));
00222 }
00223
00224
00231 inline static Color4 Scatter(int range, int value,float Sat=.3f,float Val=.9f)
00232 {
00233 int b, k, m=range;
00234 int r =range;
00235
00236 for (b=0, k=1; k<range; k<<=1)
00237 if (value<<1>=m) {
00238 if (b==0) r = k;
00239 b += k;
00240 value -= (m+1)>>1;
00241 m >>= 1;
00242 }
00243 else m = (m+1)>>1;
00244 if (r>range-b) r = range-b;
00245
00246
00247 Color4 rc;
00248 rc.SetHSVColor(float(b)/float(range),Sat,Val);
00249 return rc;
00250 }
00251
00252 inline static Color4 ColorRamp(const float &minf,const float &maxf ,float v )
00253 {
00254 Color4 rc;
00255 rc.SetColorRamp(minf,maxf,v);
00256 return rc;
00257 }
00258
00259 inline static unsigned short ToUnsignedB5G5R5(Color4 &) { return 0;}
00260 inline static unsigned short ToUnsignedR5G5B5(Color4 &) { return 0;}
00261
00262 inline static Color4 FromUnsignedB5G5R5(unsigned short)
00263 {
00264 return Color4(Color4::White);
00265 }
00266 inline static Color4 FromUnsignedR5G5B5(unsigned short)
00267 {
00268 return Color4(Color4::White);
00269 }
00270
00271 };
00272
00273 template <> template <>
00274 inline void Color4<float>::Import(const Color4<unsigned char> &b)
00275 {
00276 (*this)[0]=b[0]/255.0f;
00277 (*this)[1]=b[1]/255.0f;
00278 (*this)[2]=b[2]/255.0f;
00279 (*this)[3]=b[3]/255.0f;
00280 }
00281
00282 template <> template <>
00283 inline void Color4<unsigned char>::Import(const Color4<float> &b)
00284 {
00285 (*this)[0]=(unsigned char)(b[0]*255.0f);
00286 (*this)[1]=(unsigned char)(b[1]*255.0f);
00287 (*this)[2]=(unsigned char)(b[2]*255.0f);
00288 (*this)[3]=(unsigned char)(b[3]*255.0f);
00289 }
00290
00291 template <> template <>
00292 inline void Color4<unsigned char>::Import(const Point4<float> &b)
00293 {
00294 (*this)[0]=(unsigned char)(b[0]*255.0f);
00295 (*this)[1]=(unsigned char)(b[1]*255.0f);
00296 (*this)[2]=(unsigned char)(b[2]*255.0f);
00297 (*this)[3]=(unsigned char)(b[3]*255.0f);
00298 }
00299
00300 template <> template <>
00301 inline Color4<unsigned char> Color4<unsigned char>::Construct( const Color4<float> & b )
00302 {
00303 return Color4<unsigned char>(
00304 (unsigned char)(b[0]*255.0f),
00305 (unsigned char)(b[1]*255.0f),
00306 (unsigned char)(b[2]*255.0f),
00307 (unsigned char)(b[3]*255.0f));
00308 }
00309
00310 template <> template <>
00311 inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
00312 {
00313 return Color4<float>(
00314 (float)(b[0])/255.0f,
00315 (float)(b[1])/255.0f,
00316 (float)(b[2])/255.0f,
00317 (float)(b[3])/255.0f);
00318 }
00319
00320 template<>
00321 inline Color4<unsigned char>::Color4(Color4<unsigned char>::ColorConstant cc)
00322 {
00323 *((int *)this )= cc;
00324 }
00325
00326 template<>
00327 inline Color4<float>::Color4(Color4<float>::ColorConstant cc)
00328 {
00329 Import(Color4<unsigned char>((Color4<unsigned char>::ColorConstant)cc));
00330 }
00331
00332 template<>
00333 inline Color4<unsigned char>::Color4(unsigned int cc)
00334 {
00335 *((int *)this )= cc;
00336 }
00337
00338 template<>
00339 inline Color4<float>::Color4(unsigned int cc)
00340 {
00341 Import(Color4<unsigned char>(cc));
00342 }
00343
00344 inline Color4<float> Clamp(Color4<float> &c)
00345 {
00346 c[0]=math::Clamp(c[0],0.0f,1.0f);
00347 c[1]=math::Clamp(c[1],0.0f,1.0f);
00348 c[2]=math::Clamp(c[2],0.0f,1.0f);
00349 c[3]=math::Clamp(c[3],0.0f,1.0f);
00350 return c;
00351 }
00352
00353 template<>
00354 inline Color4<unsigned char> Color4<unsigned char>::operator + ( const Color4<unsigned char> & p) const
00355 {
00356 return Color4<unsigned char>(
00357 (unsigned char)(math::Clamp(int((*this)[0])+int(p[0]),0,255)),
00358 (unsigned char)(math::Clamp(int((*this)[1])+int(p[1]),0,255)),
00359 (unsigned char)(math::Clamp(int((*this)[2])+int(p[2]),0,255)),
00360 (unsigned char)(math::Clamp(int((*this)[3])+int(p[3]),0,255))
00361 );
00362 }
00363
00364
00365 typedef Color4<unsigned char> Color4b;
00366 typedef Color4<float> Color4f;
00367 typedef Color4<double> Color4d;
00368
00369
00370 template<>
00371 inline unsigned short Color4<unsigned char>::ToUnsignedB5G5R5(Color4<unsigned char> &cc)
00372 {
00373 unsigned short r = cc[0]/8;
00374 unsigned short g = cc[1]/8;
00375 unsigned short b = cc[2]/8;
00376 unsigned short res = b + g*32 + r*1024;
00377 return res;
00378 }
00379
00380 template<>
00381 inline unsigned short Color4<unsigned char>::ToUnsignedR5G5B5(Color4<unsigned char> &cc)
00382 {
00383 unsigned short r = cc[0]/8;
00384 unsigned short g = cc[1]/8;
00385 unsigned short b = cc[2]/8;
00386 unsigned short res = r + g*32 + b*1024;
00387 return res;
00388 }
00389
00390
00391 template<>
00392 inline Color4<unsigned char> Color4<unsigned char>::FromUnsignedR5G5B5(unsigned short val)
00393 {
00394 unsigned short r = val % 32 *8;
00395 unsigned short g = ((val/32)%32)*8;
00396 unsigned short b = ((val/1024)%32)*8;
00397 Color4b cc((unsigned char)r,(unsigned char)g,(unsigned char)b,(unsigned char)255);
00398 return cc;
00399 }
00400
00401 template<>
00402 inline Color4<unsigned char> Color4<unsigned char>::FromUnsignedB5G5R5(unsigned short val)
00403 {
00404 unsigned short b = val % 32 *8;
00405 unsigned short g = ((val/32)%32)*8;
00406 unsigned short r = ((val/1024)%32)*8;
00407 Color4b cc((unsigned char)r,(unsigned char)g,(unsigned char)b,(unsigned char)255);
00408 return cc;
00409 }
00410
00414 }
00415
00416 #endif