1 /**************************************************************************\
2 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32
33 /*!
34 \class SbColor4f SbColor4f.h Inventor/SbColor4f.h
35 \brief The SbColor4f class contains the red, green, blue and alpha
36 components which make up a color value.
37
38 \ingroup base
39
40 This class is used internally within other classes in Coin. It contains
41 a 4 component vector as a position in the RGB cube with an additional
42 transparency value.
43
44 The red, green and blue values should be between 0.0 and 1.0, where
45 0.0 is interpreted as minimum intensity, and 1.0 is maximum intensity.
46 The transparency value is also between 0.0 and 1.0.
47
48 SbColor4f contains methods for convenient handling of setting and
49 getting color values as 32 bit packed values or as HSV values.
50
51 Note: this class is not part of Open Inventor, but is an extension to
52 the API. Don't use it if you want your code to be compatible with
53 Open Inventor.
54
55 \sa SbColor
56 */
57
58 #include <cassert>
59 #include <Inventor/SbColor4f.h>
60 #include <Inventor/SbVec4f.h>
61 #if COIN_DEBUG
62 #include <Inventor/errors/SoDebugError.h>
63 #endif // COIN_DEBUG
64
65 /*!
66 Default constructor. The color value will be uninitialized until
67 explicitly set.
68 */
SbColor4f(void)69 SbColor4f::SbColor4f(void)
70 {
71 }
72
73 /*!
74 Construct and initialize an SbColor4f with the red, green, blue
75 and alpha values given by the \c v vector.
76 */
SbColor4f(const SbVec4f & v)77 SbColor4f::SbColor4f(const SbVec4f& v)
78 {
79 this->vec[0] = v[0];
80 this->vec[1] = v[1];
81 this->vec[2] = v[2];
82 this->vec[3] = v[3];
83 }
84
85 /*!
86 Construct and initialize an SbColor4f with the red, green, blue
87 and alpha taken from given \c rgba array
88 */
SbColor4f(const float * const rgba)89 SbColor4f::SbColor4f(const float* const rgba)
90 {
91 this->vec[0] = rgba[0];
92 this->vec[1] = rgba[1];
93 this->vec[2] = rgba[2];
94 this->vec[3] = rgba[3];
95 }
96
97 /*!
98 Construct and initialize an SbColor4f with the red, green and blue
99 components from the SbColor \c rgb, and the alpha value from the
100 supplied \c alpha argument.
101 */
SbColor4f(const SbColor & rgb,const float alpha)102 SbColor4f::SbColor4f(const SbColor &rgb, const float alpha)
103 {
104 this->vec[0] = rgb[0];
105 this->vec[1] = rgb[1];
106 this->vec[2] = rgb[2];
107 this->vec[3] = alpha;
108 }
109
110 /*!
111 Construct and initialize an SbColor4f with the given red, green, blue
112 and alpha values.
113 */
SbColor4f(const float r,const float g,const float b,const float a)114 SbColor4f::SbColor4f(const float r, const float g, const float b,
115 const float a)
116 {
117 this->vec[0] = r;
118 this->vec[1] = g;
119 this->vec[2] = b;
120 this->vec[3] = a;
121 }
122
123
124 /*!
125 Set a new color.
126 */
127 void
setValue(const float r,const float g,const float b,const float a)128 SbColor4f::setValue(const float r, const float g, const float b,
129 const float a)
130 {
131 this->vec[0] = r;
132 this->vec[1] = g;
133 this->vec[2] = b;
134 this->vec[3] = a;
135 }
136
137 /*!
138 Set a new color. The elements of the array will be read in turned
139 as red, green, blue and transparency.
140 */
141 void
setValue(const float col[4])142 SbColor4f::setValue(const float col[4])
143 {
144 this->vec[0] = col[0];
145 this->vec[1] = col[1];
146 this->vec[2] = col[2];
147 this->vec[3] = col[3];
148 }
149
150 /*!
151 Return pointer to array of 4 float values representing the red, green,
152 blue and transparency values of the color.
153 */
154 const float *
getValue() const155 SbColor4f::getValue() const
156 {
157 return this->vec;
158 }
159
160 /*!
161 Return components of the stored color.
162 */
163 void
getValue(float & r,float & g,float & b,float & a)164 SbColor4f::getValue(float &r, float &g, float &b, float &a)
165 {
166 r = this->vec[0];
167 g = this->vec[1];
168 b = this->vec[2];
169 a = this->vec[3];
170 }
171
172
173 /*!
174 Set the color value as a 32 bit combined red/green/blue/alpha value.
175 Each component is 8 bit wide (i.e. from 0x00 to 0xff), and the red
176 value should be stored leftmost, like this: 0xRRGGBBAA.
177
178 \sa getPackedValue().
179 */
180 SbColor4f&
setPackedValue(const uint32_t rgba)181 SbColor4f::setPackedValue(const uint32_t rgba)
182 {
183 this->setValue((rgba >> 24)/255.0f,
184 ((rgba >> 16)&0xff)/255.0f,
185 ((rgba >> 8)&0xff)/255.0f,
186 (rgba & 0xff)/255.0f);
187 return *this;
188 }
189
190 /*!
191 Return color as a 32 bit packed integer in the form 0xRRGGBBAA.
192 \sa setPackedValue().
193 */
194 uint32_t
getPackedValue() const195 SbColor4f::getPackedValue() const
196 {
197 return ((static_cast<uint32_t>(red()*255.0f + 0.5f) << 24) |
198 (static_cast<uint32_t>(green()*255.0f + 0.5f) << 16) |
199 (static_cast<uint32_t>(blue()*255.0f + 0.5f) << 8) |
200 static_cast<uint32_t>(alpha()*255.0f + 0.5f));
201 }
202
203 /*!
204 Sets the RGB components of the color. The alpha component is
205 left unchanged.
206 */
207 SbColor4f&
setRGB(const SbColor & col)208 SbColor4f::setRGB(const SbColor &col)
209 {
210 this->vec[0] = col[0];
211 this->vec[1] = col[1];
212 this->vec[2] = col[2];
213 return *this;
214 }
215
216 /*!
217 Returns the RGB components of this color.
218 */
219 void
getRGB(SbColor & color)220 SbColor4f::getRGB(SbColor &color)
221 {
222 color[0] = this->red();
223 color[1] = this->green();
224 color[2] = this->blue();
225 }
226
227 /*!
228 Set the color as a \c hue, \c saturation, \c value triplet.
229 The hue component should be normalized to within [0, 1] before you
230 call this method, where 0 is equal to 0� and 1 is equal to 360�.
231
232 \sa getHSVValue().
233 */
234 SbColor4f&
setHSVValue(float hue,float saturation,float value,float alpha)235 SbColor4f::setHSVValue(float hue, float saturation,
236 float value, float alpha)
237 {
238 #if COIN_DEBUG
239 if (!(hue>=0.0f && hue<=1.0f)) {
240 SoDebugError::postWarning("SbColor4f::setHSVValue",
241 "'hue' (%f) not within [0.0,1.0]; clamping.",
242 hue);
243 if (hue<0.0f) hue=0.0f;
244 else if (hue>1.0f) hue=1.0f;
245 }
246
247 if (!(saturation>=0.0f && saturation<=1.0f)) {
248 SoDebugError::postWarning("SbColor4f::setHSVValue",
249 "'saturation' (%f) not within [0.0,1.0]; "
250 "clamping.", saturation);
251 if (saturation<0.0f) saturation=0.0f;
252 else if (saturation>1.0f) saturation=1.0f;
253 }
254
255 if (!(value>=0.0f && value<=1.0f)) {
256 SoDebugError::postWarning("SbColor4f::setHSVValue",
257 "'value' (%f) not within [0.0,1.0]; clamping.",
258 value);
259 if (value<0.0f) value=0.0f;
260 else if (value>1.0f) value=1.0f;
261 }
262 if (!(alpha >= 0.0f && alpha <= 1.0f)) {
263 SoDebugError::postWarning("SbColor4f::setHSVValue",
264 "'alpha' (%f) not within [0.0,1.0]; clamping.",
265 alpha);
266 alpha = SbClamp(alpha, 0.0f, 1.0f);
267 }
268
269 #endif // COIN_DEBUG
270
271 SbColor col;
272 col.setHSVValue(hue, saturation, value);
273 this->vec[0] = col[0];
274 this->vec[1] = col[1];
275 this->vec[2] = col[2];
276 this->vec[3] = alpha;
277 return *this;
278 }
279
280 /*!
281 Return the color as a \c hue, \c saturation, \c value triplet. Alpha
282 component is ignored.
283
284 \sa setHSVValue().
285 */
286 void
getHSVValue(float & h,float & s,float & v) const287 SbColor4f::getHSVValue(float &h, float &s, float &v) const
288 {
289 SbColor col;
290 col[0] = this->vec[0];
291 col[1] = this->vec[1];
292 col[2] = this->vec[2];
293 col.getHSVValue(h, s, v);
294 }
295
296 /*!
297 Set the color as a \c hue, \c saturation, \c value triplet.
298 The hue component should be normalized to within [0, 1] before you
299 call this method, where 0 is equal to 0� and 1 is equal to 360�.
300
301 \sa getHSVValue().
302 */
303 SbColor4f&
setHSVValue(const float hsv[3],float a)304 SbColor4f::setHSVValue(const float hsv[3], float a)
305 {
306 return this->setHSVValue(hsv[0], hsv[1], hsv[2], a);
307 }
308
309 /*!
310 Return the color as a \c hue, \c saturation, \c value triplet. Alpha
311 component is ignored.
312
313 \sa setHSVValue().
314 */
315 void
getHSVValue(float hsv[3]) const316 SbColor4f::getHSVValue(float hsv[3]) const
317 {
318 this->getHSVValue(hsv[0], hsv[1], hsv[2]);
319 }
320
321 /*!
322 Returns the color component represented by the given index \a idx.
323 0 is red, 1 is green, 2 is blue and 3 is the transparency value.
324 */
325 //$ EXPORT INLINE
326 float
operator [](const int idx) const327 SbColor4f::operator[](const int idx) const
328 {
329 return this->vec[idx];
330 }
331
332 /*!
333 Returns the color component represented by the given index \a idx.
334 0 is red, 1 is green, 2 is blue and 3 is the transparency value.
335 */
336 //$ EXPORT INLINE
337 float &
operator [](const int idx)338 SbColor4f::operator[](const int idx)
339 {
340 return this->vec[idx];
341 }
342
343 /*!
344 Multiplies the RGB components by \c d. The alpha component is left
345 unchanged.
346 */
347 SbColor4f &
operator *=(const float d)348 SbColor4f::operator*=(const float d)
349 {
350 this->vec[0] *= d;
351 this->vec[1] *= d;
352 this->vec[2] *= d;
353 return *this;
354 }
355
356 /*!
357 Divides the RGB components by \c d. The alpha component is left
358 unchanged.
359 */
360 SbColor4f &
operator /=(const float d)361 SbColor4f::operator/=(const float d)
362 {
363 this->vec[0] /= d;
364 this->vec[1] /= d;
365 this->vec[2] /= d;
366 return *this;
367 }
368
369 /*!
370 Adds the RGB components. Alpha is ignored.
371 */
372 SbColor4f &
operator +=(const SbColor4f & c)373 SbColor4f::operator+=(const SbColor4f &c)
374 {
375 this->vec[0] += c[0];
376 this->vec[1] += c[1];
377 this->vec[2] += c[2];
378 return *this;
379 }
380
381 /*!
382 Subtracts the RGB components. Alpha is ignored.
383 */
384 SbColor4f &
operator -=(const SbColor4f & c)385 SbColor4f::operator-=(const SbColor4f &c)
386 {
387 this->vec[0] -= c[0];
388 this->vec[1] -= c[1];
389 this->vec[2] -= c[2];
390 return *this;
391 }
392
393 /*!
394 Multiplies the RGB components by \c d. Alpha is left unchanged.
395 */
396 SbColor4f
operator *(const SbColor4f & c,const float d)397 operator *(const SbColor4f &c, const float d)
398 {
399 return SbColor4f(c.vec[0]*d, c.vec[1]*d, c.vec[2]*d, c.vec[3]);
400 }
401
402 /*!
403 Multiplies the RGB components by \c d. Alpha is left unchanged.
404 */
405 SbColor4f
operator *(const float d,const SbColor4f & c)406 operator *(const float d, const SbColor4f &c)
407 {
408 return SbColor4f(c.vec[0]*d, c.vec[1]*d, c.vec[2]*d, c.vec[3]);
409 }
410
411 /*!
412 Divides the RGB components by \c d. Alpha is left unchanged.
413 */
414 SbColor4f
operator /(const SbColor4f & c,const float d)415 operator /(const SbColor4f &c, const float d)
416 {
417 assert(d != 0.0f);
418 float inv = 1.0f / d;
419 return SbColor4f(c.vec[0]*inv,
420 c.vec[1]*inv,
421 c.vec[2]*inv,
422 c.vec[3]);
423 }
424
425 /*!
426 Adds the RGB components of the two colors. Alpha is taken from the
427 first color (\c v1).
428 */
429 SbColor4f
operator +(const SbColor4f & v1,const SbColor4f & v2)430 operator +(const SbColor4f &v1, const SbColor4f &v2)
431 {
432 return SbColor4f(v1.vec[0] + v2.vec[0],
433 v1.vec[1] + v2.vec[1],
434 v1.vec[2] + v2.vec[2],
435 v1.vec[3]);
436 }
437
438 /*!
439 Subtracts the RGB components of the two colors. Alpha is taken from the
440 first color (\c v1).
441 */
442 SbColor4f
operator -(const SbColor4f & v1,const SbColor4f & v2)443 operator -(const SbColor4f &v1, const SbColor4f &v2)
444 {
445 return SbColor4f(v1.vec[0] - v2.vec[0],
446 v1.vec[1] - v2.vec[1],
447 v1.vec[2] - v2.vec[2],
448 v1.vec[3]);
449 }
450
451 /*!
452 Check if two colors are equal. Returns 1 if equal, 0 if unequal.
453 */
454 int
operator ==(const SbColor4f & v1,const SbColor4f & v2)455 operator ==(const SbColor4f &v1, const SbColor4f &v2)
456 {
457 return (v1.vec[0] == v2.vec[0] &&
458 v1.vec[1] == v2.vec[1] &&
459 v1.vec[2] == v2.vec[2] &&
460 v1.vec[3] == v2.vec[3]);
461 }
462
463 /*!
464 Check if two colors are unequal. Returns 0 if equal, 1 if unequal.
465 */
466 //$ EXPORT INLINE
467 int
operator !=(const SbColor4f & v1,const SbColor4f & v2)468 operator !=(const SbColor4f &v1, const SbColor4f &v2)
469 {
470 return !(v1 == v2);
471 }
472