Radium Engine  1.5.20
Loading...
Searching...
No Matches
Color.hpp
1#pragma once
2
3#include <Core/CoreMacros.hpp>
4#include <Core/Math/Math.hpp>
5#include <Eigen/Core>
6#include <Eigen/Geometry> //homogeneous
7#include <random>
8
9namespace Ra {
10namespace Core {
11namespace Utils {
12
21uint32_t RA_CORE_API getNamedColorCode( std::string_view name );
22
37template <typename _Scalar>
38class ColorBase : public Eigen::Matrix<_Scalar, 4, 1>
39{
40 public:
41 using VectorType = Eigen::Matrix<_Scalar, 4, 1>;
42
43 explicit inline ColorBase() : ColorBase( _Scalar( 1. ), _Scalar( 1. ), _Scalar( 1. ) ) {}
44
45 template <typename S2>
46 inline ColorBase( S2 r, S2 g, S2 b, S2 alpha = S2( 1 ) ) :
47 VectorType( _Scalar( r ), _Scalar( g ), _Scalar( b ), _Scalar( alpha ) ) {}
48
50 template <typename S2>
51 inline ColorBase( const ColorBase<S2>& other ) : VectorType( other.template cast<_Scalar>() ) {}
52
54 template <typename Derived>
55 inline ColorBase( const Eigen::MatrixBase<Derived>& v ) :
56 VectorType( v.template cast<_Scalar>() ) {}
57
59 operator VectorType() { return *this; }
60
62 static inline ColorBase sRGBToLinearRGB( const ColorBase& srgb ) {
63 ColorBase<_Scalar> c( srgb );
64 for ( auto& u : c.rgb() ) {
65 if ( u < 0.04045_ra ) { u /= 12.92_ra; }
66 else { u = std::pow( ( u + 0.055_ra ) / 1.055_ra, 2.4_ra ); }
67 }
68 return c;
69 }
70
72 static inline ColorBase linearRGBTosRGB( const ColorBase& lrgb ) {
73 ColorBase<_Scalar> c( lrgb );
74 for ( auto& u : c.rgb() ) {
75 if ( u < 0.0031308_ra ) { u *= 12.92_ra; }
76 else { u = 1.055_ra * std::pow( u, 1_ra / 2.4_ra ) - 0.055_ra; }
77 }
78 return c;
79 }
80
81 template <typename Derived>
82 static inline ColorBase fromRGB( const Eigen::MatrixBase<Derived>& rgb,
83 Scalar alpha = Scalar( 1. ) ) {
84 ColorBase c( rgb.template cast<_Scalar>().homogeneous() );
85 c.alpha() = alpha;
86 return c;
87 }
88
89 Eigen::Block<VectorType, 3, 1> rgb() { return ( *this ).template head<3>(); }
90 const Eigen::Block<VectorType, 3, 1> rgb() const { return ( *this ).template head<3>(); }
91
92 Scalar alpha() const { return ( *this )( 3 ); }
93 Scalar& alpha() { return ( *this )( 3 ); }
94 bool hasValidAlpha() const { return Math::checkRange( alpha(), 0_ra, 1_ra ); }
95
96 static inline ColorBase<_Scalar> Alpha() {
97 return ColorBase<_Scalar>( _Scalar( 0. ), _Scalar( 0. ), _Scalar( 0. ), _Scalar( 0. ) );
98 }
99
100 static inline ColorBase<_Scalar> Black() {
101 return ColorBase<_Scalar>( _Scalar( 0. ), _Scalar( 0. ), _Scalar( 0. ) );
102 }
103
104 static inline ColorBase<_Scalar> Red() {
105 return ColorBase<_Scalar>( _Scalar( 1. ), _Scalar( 0. ), _Scalar( 0. ) );
106 }
107
108 static inline ColorBase<_Scalar> Green() {
109 return ColorBase<_Scalar>( _Scalar( 0. ), _Scalar( 1. ), _Scalar( 0. ) );
110 }
111
112 static inline ColorBase<_Scalar> Blue() {
113 return ColorBase<_Scalar>( _Scalar( 0. ), _Scalar( 0. ), _Scalar( 1. ) );
114 }
115
116 static inline ColorBase<_Scalar> Yellow() {
117 return ColorBase<_Scalar>( _Scalar( 1. ), _Scalar( 1. ), _Scalar( 0. ) );
118 }
119
120 static inline ColorBase<_Scalar> Magenta() {
121 return ColorBase<_Scalar>( _Scalar( 1. ), _Scalar( 0. ), _Scalar( 1. ) );
122 }
123
124 static inline ColorBase<_Scalar> Cyan() {
125 return ColorBase<_Scalar>( _Scalar( 0. ), _Scalar( 1. ), _Scalar( 1. ) );
126 }
127
128 static inline ColorBase<_Scalar> White() {
129 return ColorBase<_Scalar>( _Scalar( 1. ), _Scalar( 1. ), _Scalar( 1. ) );
130 }
131
132 static inline ColorBase<_Scalar> Grey( _Scalar f = _Scalar( 0.5 ), _Scalar a = _Scalar( 1. ) ) {
133 return ColorBase<_Scalar>( f, f, f, a );
134 }
135
136 static inline ColorBase<_Scalar> Skin() {
137 return ColorBase<_Scalar>( _Scalar( 1.0 ), _Scalar( 0.87 ), _Scalar( 0.74 ) );
138 }
139
144 static inline ColorBase<_Scalar> getNamedColor( std::string_view name ) {
145 return fromRGB24( getNamedColorCode( name ) );
146 }
147
148 // Convert to/from various int formats
149
150 static inline ColorBase<_Scalar> fromChars( uchar r, uchar g, uchar b, uchar a = 0xff ) {
151 return ColorBase<_Scalar>( _Scalar( r ) / 255.0f,
152 _Scalar( g ) / 255.0f,
153 _Scalar( b ) / 255.0f,
154 _Scalar( a ) / 255.0f );
155 }
156
157 static inline ColorBase<_Scalar> fromRGB24( uint32_t rgb ) {
158 uchar r = uchar( ( rgb >> 16 ) & 0xff );
159 uchar g = uchar( ( rgb >> 8 ) & 0xff );
160 uchar b = uchar( ( rgb >> 0 ) & 0xff );
161 return fromChars( r, g, b );
162 }
163
164 static inline ColorBase<_Scalar> fromRGBA32( uint32_t rgba ) {
165 uchar r = uchar( ( rgba >> 24 ) & 0xff );
166 uchar g = uchar( ( rgba >> 16 ) & 0xff );
167 uchar b = uchar( ( rgba >> 8 ) & 0xff );
168 uchar a = uchar( ( rgba >> 0 ) & 0xff );
169 return fromChars( r, g, b, a );
170 }
171
172 static inline ColorBase<_Scalar> fromARGB32( uint32_t argb ) {
173 uchar a = uchar( ( argb >> 24 ) & 0xff );
174 uchar r = uchar( ( argb >> 16 ) & 0xff );
175 uchar g = uchar( ( argb >> 8 ) & 0xff );
176 uchar b = uchar( ( argb >> 0 ) & 0xff );
177 return fromChars( r, g, b, a );
178 }
179
180 static inline ColorBase<_Scalar> fromHSV( const _Scalar hue,
181 const _Scalar saturation = 1.0,
182 const _Scalar value = 1.0,
183 const _Scalar alpha = 1.0 ) {
184 ColorBase<_Scalar> c;
185
186 if ( saturation == 0.0f ) {
187 c[0] = c[1] = c[2] = value;
188 c[3] = alpha;
189 return c;
190 }
191 _Scalar h = ( ( hue == 1.0f ) ? 0.0f : hue ) * 6.0f;
192 int i = int( std::floor( h ) );
193 _Scalar v1 = value * ( 1.0f - saturation );
194 _Scalar v2 = value * ( 1.0f - ( saturation * ( h - i ) ) );
195 _Scalar v3 = value * ( 1.0f - ( saturation * ( 1.0f - h - i ) ) );
196 switch ( i ) {
197 case 0: {
198 c[0] = value;
199 c[1] = v3;
200 c[2] = v1;
201 } break;
202 case 1: {
203 c[0] = v2;
204 c[1] = value;
205 c[2] = v1;
206 } break;
207 case 2: {
208 c[0] = v1;
209 c[1] = value;
210 c[2] = v3;
211 } break;
212 case 3: {
213 c[0] = v1;
214 c[1] = v2;
215 c[2] = value;
216 } break;
217 case 4: {
218 c[0] = v3;
219 c[1] = v1;
220 c[2] = value;
221 } break;
222 default: {
223 c[0] = value;
224 c[1] = v1;
225 c[2] = v2;
226 } break;
227 }
228 c[3] = alpha;
229 return c;
230 }
231
232 inline uint32_t toRGBA32() const {
233 ColorBase<_Scalar> c( ( *this ) * 255 );
234 Eigen::Matrix<int, 4, 1> scaled( c.x(), c.y(), c.z(), c.w() );
235 return ( uint32_t( scaled( 0 ) ) << 24 ) | ( uint32_t( scaled( 1 ) ) << 16 ) |
236 ( uint32_t( scaled( 2 ) ) << 8 ) | ( uint32_t( scaled( 3 ) ) << 0 );
237 }
238
239 inline uint32_t toARGB32() const {
240 ColorBase<_Scalar> c( ( *this ) * 255 );
241 Eigen::Matrix<int, 4, 1> scaled( c.x(), c.y(), c.z(), c.w() );
242 return ( uint32_t( scaled( 3 ) ) << 24 ) | ( uint32_t( scaled( 0 ) ) << 16 ) |
243 ( uint32_t( scaled( 1 ) ) << 8 ) | ( uint32_t( scaled( 2 ) ) << 0 );
244 }
245
246 static inline std::vector<ColorBase<_Scalar>> scatter( const uint size, const _Scalar gamma ) {
247 std::vector<ColorBase<_Scalar>> color( size );
248 if ( size > 1 )
249 for ( uint i = 0; i < size; ++i ) {
250 color[i] = fromHSV( ( _Scalar( i ) / _Scalar( size - 1 ) ) * 0.777 );
251 color[i] = ( color[i] + ColorBase<_Scalar>::Constant( gamma ) ) * 0.5;
252 }
253 else { color[0] = Red(); }
254 std::shuffle( color.begin(), color.end(), std::mt19937( std::random_device()() ) );
255 return color;
256 }
257};
258
259using Color = ColorBase<Scalar>;
260using Colorf = ColorBase<float>;
261using Colord = ColorBase<double>;
262
263} // namespace Utils
264} // namespace Core
265} // namespace Ra
static ColorBase sRGBToLinearRGB(const ColorBase &srgb)
convert the color expressed in sRGB color space to linear RGB
Definition Color.hpp:62
static ColorBase linearRGBTosRGB(const ColorBase &lrgb)
convert the color expressed in linear RGB color space to sRGB
Definition Color.hpp:72
static ColorBase< _Scalar > getNamedColor(std::string_view name)
Definition Color.hpp:144
ColorBase(const ColorBase< S2 > &other)
Copy constructor.
Definition Color.hpp:51
ColorBase(const Eigen::MatrixBase< Derived > &v)
Copy constructor from Eigen expressions: ColorBase<_Scalar> c( (*this) * 255 );
Definition Color.hpp:55
T floor(T... args)
bool checkRange(const Vector_Or_Scalar &v, const Scalar &min, const Scalar &max)
Definition Math.hpp:53
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3
T pow(T... args)
T shuffle(T... args)