00001 /* 00002 Copyright (c) 2010, The Cinder Project, All rights reserved. 00003 This code is intended for use with the Cinder C++ library: http://libcinder.org 00004 00005 Portions Copyright (c) 2010, The Barbarian Group 00006 All rights reserved. 00007 00008 Redistribution and use in source and binary forms, with or without modification, are permitted provided that 00009 the following conditions are met: 00010 00011 * Redistributions of source code must retain the above copyright notice, this list of conditions and 00012 the following disclaimer. 00013 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00014 the following disclaimer in the documentation and/or other materials provided with the distribution. 00015 00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00017 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00018 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00019 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00020 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00021 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00022 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00023 POSSIBILITY OF SUCH DAMAGE. 00024 */ 00025 00026 #pragma once 00027 00028 #include "cinder/Cinder.h" 00029 #include "cinder/ChanTraits.h" 00030 #include "cinder/Vector.h" 00031 #include "cinder/CinderMath.h" 00032 00033 namespace cinder { 00034 00035 typedef enum { 00036 CM_RGB, // Red[0 - 1.0] Green[0 - 1.0] Blue[0 - 1.0] 00037 CM_HSV // Hue[0 - 1.0] Saturation[0 - 1.0] Value[0 - 1.0] 00038 } ColorModel; 00039 00040 template<typename T> 00041 class ColorT 00042 { 00043 public: 00044 T r,g,b; 00045 00046 ColorT() : r( 0 ), g( 0 ), b( 0 ) {} 00047 ColorT( T aR, T aG, T aB ) 00048 : r( aR ), g( aG ), b( aB ) 00049 {} 00050 ColorT( const ColorT<T> &src ) 00051 : r( src.r ), g( src.g ), b( src.b ) 00052 {} 00053 00054 ColorT( ColorModel cm, const Vec3f &v ); 00055 ColorT( ColorModel cm, float x, float y, float z ); 00056 00057 template<typename FromT> 00058 ColorT( const ColorT<FromT> &src ) 00059 : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) ) 00060 {} 00061 00062 void set( ColorModel cm, const Vec3f &v ); 00063 00064 ColorT<T> operator=( const ColorT<T> &rhs ) 00065 { 00066 r = rhs.r; 00067 g = rhs.g; 00068 b = rhs.b; 00069 return * this; 00070 } 00071 00072 template<class FromT> 00073 ColorT<T> operator=( const ColorT<FromT> &rhs ) 00074 { 00075 r = CHANTRAIT<T>::convert( rhs.r ); 00076 g = CHANTRAIT<T>::convert( rhs.g ); 00077 b = CHANTRAIT<T>::convert( rhs.b ); 00078 return * this; 00079 } 00080 00081 Vec3f get( ColorModel cm ); 00082 00083 T& operator[]( int n ) 00084 { 00085 assert( n >= 0 && n <= 2 ); 00086 return (&r)[n]; 00087 } 00088 00089 const T& operator[]( int n ) const 00090 { 00091 assert( n >= 0 && n <= 2 ); 00092 return (&r)[n]; 00093 } 00094 00095 ColorT<T> operator+( const ColorT<T> &rhs ) const { return ColorT<T>( r + rhs.r, g + rhs.g, b + rhs.b ); } 00096 ColorT<T> operator-( const ColorT<T> &rhs ) const { return ColorT<T>( r - rhs.r, g - rhs.g, b - rhs.b ); } 00097 ColorT<T> operator*( const ColorT<T> &rhs ) const { return ColorT<T>( r * rhs.r, g * rhs.g, b * rhs.b ); } 00098 ColorT<T> operator/( const ColorT<T> &rhs ) const { return ColorT<T>( r / rhs.r, g / rhs.g, b / rhs.b ); } 00099 const ColorT<T>& operator+=( const ColorT<T> &rhs ) { r += rhs.r; g += rhs.g; b += rhs.b; return *this; } 00100 const ColorT<T>& operator-=( const ColorT<T> &rhs ) { r -= rhs.r; g -= rhs.g; b -= rhs.b; return *this; } 00101 const ColorT<T>& operator*=( const ColorT<T> &rhs ) { r *= rhs.r; g *= rhs.g; b *= rhs.b; return *this; } 00102 const ColorT<T>& operator/=( const ColorT<T> &rhs ) { r /= rhs.r; g /= rhs.g; b /= rhs.b; return *this; } 00103 ColorT<T> operator+( T rhs ) const { return ColorT<T>( r + rhs, g + rhs, b + rhs ); } 00104 ColorT<T> operator-( T rhs ) const { return ColorT<T>( r - rhs, g - rhs, b - rhs ); } 00105 ColorT<T> operator*( T rhs ) const { return ColorT<T>( r * rhs, g * rhs, b * rhs ); } 00106 ColorT<T> operator/( T rhs ) const { return ColorT<T>( r / rhs, g / rhs, b / rhs ); } 00107 const ColorT<T>& operator+=( T rhs ) { r += rhs; g += rhs; b += rhs; return *this; } 00108 const ColorT<T>& operator-=( T rhs ) { r -= rhs; g -= rhs; b -= rhs; return *this; } 00109 const ColorT<T>& operator*=( T rhs ) { r *= rhs; g *= rhs; b *= rhs; return *this; } 00110 const ColorT<T>& operator/=( T rhs ) { r /= rhs; g /= rhs; b /= rhs; return *this; } 00111 00112 typename CHANTRAIT<T>::Accum dot( const ColorT<T> &rhs ) const 00113 { 00114 return r*rhs.r + g*rhs.g + b*rhs.b; 00115 } 00116 00117 float distance( const ColorT<T> &rhs ) const 00118 { 00119 return math<float>::sqrt( static_cast<float>( (r - rhs.r)*(r - rhs.r) + (g - rhs.g)*(g - rhs.g) + (b - rhs.b)*(b - rhs.b)) ); 00120 } 00121 00122 typename CHANTRAIT<T>::Accum distanceSquared( const ColorT<T> &rhs ) const 00123 { 00124 return (r - rhs.r) * (r - rhs.r) + (g - rhs.g) * (g - rhs.g) + (b - rhs.b) * (b - rhs.b); 00125 } 00126 00127 float length() const 00128 { 00129 return math<float>::sqrt( static_cast<float>( r*r + g*g + b*b ) ); 00130 } 00131 00132 typename CHANTRAIT<T>::Accum lengthSquared() const 00133 { 00134 return r*r + g*g + b*b; 00135 } 00136 00137 // tests for zero-length 00138 void normalize() 00139 { 00140 float s = length(); 00141 if( s > 0.0f ) { 00142 r = static_cast<T>( r / s ); 00143 g = static_cast<T>( g / s ); 00144 b = static_cast<T>( b / s ); 00145 } 00146 } 00147 00148 ColorT<T> lerp( T fact, const ColorT<T> &d ) const 00149 { 00150 return ColorT<T>( r + ( d.r - r ) * fact, g + ( d.g - g ) * fact, b + ( d.b - b ) * fact ); 00151 } 00152 00153 static ColorT<T> max() 00154 { 00155 return ColorT<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() ); 00156 } 00157 00158 static ColorT<T> black() 00159 { 00160 return ColorT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) ); 00161 } 00162 00163 static ColorT<T> white() 00164 { 00165 return ColorT<T>( CHANTRAIT<T>::max(), CHANTRAIT<T>::max(), CHANTRAIT<T>::max() ); 00166 } 00167 00168 operator T*(){ return (T*) this; } 00169 operator const T*() const { return (const T*) this; } 00170 }; 00171 00172 00174 // ColorAT 00175 00176 template<typename T> 00177 class ColorAT { 00178 public: 00179 T r,g,b,a; 00180 00181 ColorAT() 00182 : r( 0 ), g( 0 ), b( 0 ), a( 0 ) 00183 {} 00184 ColorAT( T aR, T aG, T aB, T aA = CHANTRAIT<T>::convert( 1.0f ) ) 00185 : r( aR ), g( aG ), b( aB ), a( aA ) 00186 {} 00187 ColorAT( const ColorAT<T> &src ) 00188 : r( src.r ), g( src.g ), b( src.b ), a( src.a ) 00189 {} 00190 ColorAT( const ColorT<T> &col, T aA = CHANTRAIT<T>::convert( 1.0f ) ) 00191 : r( col.r ), g( col.g ), b( col.b ), a( aA ) 00192 {} 00193 00194 ColorAT( ColorModel cm, float c1, float c2, float c3, float aA = CHANTRAIT<T>::convert( 1.0f ) ); 00195 00196 template<typename FromT> 00197 ColorAT( const ColorT<FromT> &src ) 00198 : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) ), a( CHANTRAIT<T>::convert( 1.0f ) ) 00199 {} 00200 00201 00202 template<typename FromT> 00203 ColorAT( const ColorAT<FromT>& src ) 00204 : r( CHANTRAIT<T>::convert( src.r ) ), g( CHANTRAIT<T>::convert( src.g ) ), b( CHANTRAIT<T>::convert( src.b ) ), a( CHANTRAIT<T>::convert( src.a ) ) 00205 {} 00206 00207 ColorAT<T> operator=( const ColorAT<T>& rhs ) 00208 { 00209 r = rhs.r; 00210 g = rhs.g; 00211 b = rhs.b; 00212 a = rhs.a; 00213 return * this; 00214 } 00215 00216 template<class FromT> 00217 ColorAT<T> operator=( const ColorAT<FromT>& rhs ) 00218 { 00219 r = CHANTRAIT<T>::convert( rhs.r ); 00220 g = CHANTRAIT<T>::convert( rhs.g ); 00221 b = CHANTRAIT<T>::convert( rhs.b ); 00222 a = CHANTRAIT<T>::convert( rhs.a ); 00223 return * this; 00224 } 00225 00226 T& operator[]( int n ) 00227 { 00228 assert( n >= 0 && n <= 3 ); 00229 return (&r)[n]; 00230 } 00231 00232 const T& operator[]( int n ) const 00233 { 00234 assert( n >= 0 && n <= 3 ); 00235 return (&r)[n]; 00236 } 00237 00238 ColorAT<T> operator+( const ColorAT<T> &rhs ) const { return ColorAT<T>( r + rhs.r, g + rhs.g, b + rhs.b, a + rhs.a ); } 00239 ColorAT<T> operator-( const ColorAT<T> &rhs ) const { return ColorAT<T>( r - rhs.r, g - rhs.g, b - rhs.b, a - rhs.a ); } 00240 ColorAT<T> operator*( const ColorAT<T> &rhs ) const { return ColorAT<T>( r * rhs.r, g * rhs.g, b * rhs.b, a * rhs.a ); } 00241 ColorAT<T> operator/( const ColorAT<T> &rhs ) const { return ColorAT<T>( r / rhs.r, g / rhs.g, b / rhs.b, a / rhs.a ); } 00242 const ColorAT<T>& operator+=( const ColorAT<T> &rhs ) { r += rhs.r; g += rhs.g; b += rhs.b; a += rhs.a; return *this; } 00243 const ColorAT<T>& operator-=( const ColorAT<T> &rhs ) { r -= rhs.r; g -= rhs.g; b -= rhs.b; a -= rhs.a; return *this; } 00244 const ColorAT<T>& operator*=( const ColorAT<T> &rhs ) { r *= rhs.r; g *= rhs.g; b *= rhs.b; a *= rhs.a; return *this; } 00245 const ColorAT<T>& operator/=( const ColorAT<T> &rhs ) { r /= rhs.r; g /= rhs.g; b /= rhs.b; a /= rhs.a; return *this; } 00246 ColorAT<T> operator+( T rhs ) const { return ColorAT<T>( r + rhs, g + rhs, b + rhs, a + rhs ); } 00247 ColorAT<T> operator-( T rhs ) const { return ColorAT<T>( r - rhs, g - rhs, b - rhs, a - rhs ); } 00248 ColorAT<T> operator*( T rhs ) const { return ColorAT<T>( r * rhs, g * rhs, b * rhs, a * rhs ); } 00249 ColorAT<T> operator/( T rhs ) const { return ColorAT<T>( r / rhs, g / rhs, b / rhs, a / rhs ); } 00250 const ColorAT<T>& operator+=( T rhs ) { r += rhs; g += rhs; b += rhs; a += rhs; return *this; } 00251 const ColorAT<T>& operator-=( T rhs ) { r -= rhs; g -= rhs; b -= rhs; a -= rhs; return * this; } 00252 const ColorAT<T>& operator*=( T rhs ) { r *= rhs; g *= rhs; b *= rhs; a *= rhs; return * this; } 00253 const ColorAT<T>& operator/=( T rhs ) { r /= rhs; g /= rhs; b /= rhs; a /= rhs; return * this; } 00254 00255 float length() const 00256 { 00257 return math<float>::sqrt( static_cast<float>( r*r + g*g + b*b ) ); 00258 } 00259 00260 // tests for zero-length 00261 void normalize() 00262 { 00263 float s = length(); 00264 if( s > 0.0f ) { 00265 r = static_cast<T>( r / s ); 00266 g = static_cast<T>( g / s ); 00267 b = static_cast<T>( b / s ); 00268 } 00269 } 00270 00271 ColorAT<T> premultiplied() const 00272 { 00273 return ColorAT<T>( r * a, g * a, b * a, a ); 00274 } 00275 00276 typename CHANTRAIT<T>::Accum lengthSquared() const 00277 { 00278 return r * r + g * g + b * b; 00279 } 00280 00281 ColorAT<T> lerp( T fact, const ColorAT<T> &d ) const 00282 { 00283 return ColorAT<T>( r + ( d.r - r ) * fact, g + ( d.g - g ) * fact, b + ( d.b - b ) * fact, a + ( d.a - a ) * fact ); 00284 } 00285 00286 static ColorAT<T> zero() 00287 { 00288 return ColorAT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) ); 00289 } 00290 00291 static ColorAT<T> black() 00292 { 00293 return ColorAT<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), CHANTRAIT<T>::max() ); 00294 } 00295 00296 static ColorAT<T> white() 00297 { 00298 return ColorAT<T>( CHANTRAIT<T>::max(), CHANTRAIT<T>::max(), CHANTRAIT<T>::max(), CHANTRAIT<T>::max() ); 00299 } 00300 00301 operator T*(){ return (T*) this; } 00302 operator const T*() const { return (const T*) this; } 00303 operator ColorT<T>(){ return ColorT<T>( r, g, b ); } 00304 }; 00305 00306 // Free Functions 00307 00308 extern ColorT<float> hsvToRGB( const Vec3f &hsv ); 00309 extern Vec3f rgbToHSV( const ColorT<float> &c ); 00310 00311 extern std::ostream& operator<<( std::ostream &lhs, const ColorT<float> &rhs ); 00312 extern std::ostream& operator<<( std::ostream &lhs, const ColorAT<float> &rhs ); 00313 extern std::ostream& operator<<( std::ostream &lhs, const ColorT<uint8_t> &rhs ); 00314 extern std::ostream& operator<<( std::ostream &lhs, const ColorAT<uint8_t> &rhs ); 00315 00316 typedef ColorT<float> Color; 00317 typedef ColorT<float> Colorf; 00318 typedef ColorT<uint8_t> Color8u; 00319 typedef ColorAT<float> ColorA; 00320 typedef ColorAT<float> ColorAf; 00321 typedef ColorAT<uint8_t> ColorA8u; 00322 00323 } // namespace cinder