[go: up one dir, main page]

File: SbColor.cpp

package info (click to toggle)
coin3 3.1.3-2.2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 48,368 kB
  • sloc: cpp: 314,329; ansic: 15,927; sh: 13,635; makefile: 8,772; perl: 2,149; lex: 1,302; lisp: 1,247; yacc: 184; xml: 175; sed: 68
file content (231 lines) | stat: -rw-r--r-- 6,955 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/**************************************************************************\
 *
 *  This file is part of the Coin 3D visualization library.
 *  Copyright (C) by Kongsberg Oil & Gas Technologies.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  ("GPL") version 2 as published by the Free Software Foundation.
 *  See the file LICENSE.GPL at the root directory of this source
 *  distribution for additional information about the GNU GPL.
 *
 *  For using Coin with software that can not be combined with the GNU
 *  GPL, and for taking advantage of the additional benefits of our
 *  support services, please contact Kongsberg Oil & Gas Technologies
 *  about acquiring a Coin Professional Edition License.
 *
 *  See http://www.coin3d.org/ for more information.
 *
 *  Kongsberg Oil & Gas Technologies, Bygdoy Alle 5, 0257 Oslo, NORWAY.
 *  http://www.sim.no/  sales@sim.no  coin-support@coin3d.org
 *
\**************************************************************************/

/*!
  \class SbColor SbColor.h Inventor/SbColor.h
  \brief The SbColor class contains the red, green and blue components
  which make up a color value.
  \ingroup base

  This class is used within other classes in Coin.  It inherits the
  SbVec3f class, interpreting the 3 component vector as a vector in
  the RGB cube where the red, green and blue components corresponds to
  x, y and z respectively.

  SbColor also adds a few extra methods for convenient handling of
  setting and getting color values as 32 bit packed values or as HSV
  values.

  \sa SbVec3f, SbColor4f */

#include <Inventor/SbColor.h>
#if COIN_DEBUG
#include <Inventor/errors/SoDebugError.h>
#endif // COIN_DEBUG

/*!
  Default constructor. The color value will be uninitialized.
 */
SbColor::SbColor(void)
  : SbVec3f()
{
}

/*!
  Construct and initialize an SbColor with the red, green and blue
  values given by the \c v vector.
 */
SbColor::SbColor(const SbVec3f& v)
  : SbVec3f(v)
{
}

/*!
  Construct and initialize an SbColor with the red, green and blue
  taken from given \c rgb array.
 */
SbColor::SbColor(const float* const rgb)
  : SbVec3f(rgb)
{
}

/*!
  Construct and initialize an SbColor with the given red, green and blue
  values.
 */
SbColor::SbColor(const float r, const float g, const float b)
  : SbVec3f(r, g, b)
{
}

/*!
  Set the color value as a 32 bit combined red/green/blue/alpha value.
  Each component is 8 bit wide (i.e. from 0x00 to 0xff), and the red
  value should be stored leftmost, like this: 0xRRGGBBAA.

  The transparency value is not stored internally in SbColor, just
  converted to a transparency value in [0, 1] and returned in the
  \c transparency field. A value of 1.0 means completely transparent
  and a value of 0.0 is completely opaque.

  \sa getPackedValue().
 */
SbColor&
SbColor::setPackedValue(const uint32_t rgba, float& transparency)
{
  // Should work regardless of endianness on run-time architecture.
  this->setValue((rgba >> 24)/255.0f,
                 ((rgba >> 16)&0xff)/255.0f,
                 ((rgba >> 8)&0xff)/255.0f);
  transparency = 1.0f - (rgba&0xff)/255.0f;
  return *this;
}

/*!
  Return color as a 32 bit packed integer in the form 0xRRGGBBAA. The
  transparency part of the return value is taken from the supplied
  \c transparency argument.

  \sa setPackedValue().
 */
uint32_t
SbColor::getPackedValue(const float transparency) const
{
  // Should work regardless of endianness on run-time architecture.
  return ((static_cast<uint32_t>(red()*255.0f + 0.5f) << 24) |
          (static_cast<uint32_t>(green()*255.0f + 0.5f) << 16) |
          (static_cast<uint32_t>(blue()*255.0f + 0.5f) << 8) |
          static_cast<uint32_t>((1.0f - transparency)*255.0f + 0.5f));
}

/*!
  Set the color as a \c hue, \c saturation, \c value triplet.
  The hue component should be normalized to within [0, 1] before you
  call this method, where 0 is equal to 0 and 1 is equal to 360.

  \sa getHSVValue().
 */
SbColor&
SbColor::setHSVValue(float hue, float saturation,
                     float value)
{
#if COIN_DEBUG
  if (!(hue>=0.0f && hue<=1.0f) ||
      !(saturation>=0.0f && saturation<=1.0f) ||
      !(value>=0.0f && value<=1.0f)) {
    SoDebugError::postWarning("SbColor::setHSVValue",
                              "One or more values out of range, clamping.");
    hue = SbClamp(hue, 0.f, 1.f);
    saturation = SbClamp(saturation, 0.f, 1.f);
    value = SbClamp(value, 0.f, 1.f);
  }
#endif // COIN_DEBUG

  // HSV to RGB conversion routine based on the one presented in
  // "Computer Graphics: Principles and Practice", 2nd ed., by Foley et
  // al.
  //
  // Valid input range for all values are [0, 1].
  //                                                       19980809 mortene.

  float h = hue;
  float s = saturation;
  float v = value;

  if(h == 1.0f) h = 0.0f;
  h *= 6.0f;
  int i = static_cast<int>(floor(h));
  float fraction = h - static_cast<float>(i);
  float p = v * (1.0f - s);
  float q = v * (1.0f - (s * fraction));
  float t = v * (1.0f - (s * (1.0f - fraction)));

  switch(i) {
  case 0: this->setValue(v, t, p); break;
  case 1: this->setValue(q, v, p); break;
  case 2: this->setValue(p, v, t); break;
  case 3: this->setValue(p, q, v); break;
  case 4: this->setValue(t, p, v); break;
  case 5: this->setValue(v, p, q); break;
  }

  return *this;
}

/*!
  Return the color as a \c hue, \c saturation, \c value triplet.

  \sa setHSVValue().
 */
void
SbColor::getHSVValue(float &h, float &s, float &v) const
{
  // RGB to HSV conversion routine based on the one presented in
  // "Computer Graphics: Principles and Practice", 2nd ed., by Foley et
  // al.
  //
  // Hue is normalized to [0, 1]. Undefined hue and value is set to 0.0
  // on valid <r, g, b> triplets. Results are undefined when any of the
  // red, green or blue values are invalid (i.e. outside [0, 1]).
  //
  //                                                     19980809 mortene.
  h = s = 0.0f;
  v = SbMax(SbMax(red(), green()), blue());
  float min = SbMin(SbMin(red(), green()), blue());

  float delta = v - min;
  if(v > 0.0f) s = delta/v;
  if(delta > 0.0f) {
    if(red() == v) h = (green() - blue())/delta;
    else if(green() == v) h = 2 + (blue() - red())/delta;
    else if(blue() == v) h = 4 + (red() - green())/delta;

    h *= 60.0f;
    if(h < 0.0f) h += 360.0f;
    h /= 360.0f;
  }
}

/*!
  Set the color as a \c hue, \c saturation, \c value triplet.
  The hue component should be normalized to within [0, 1] before you
  call this method, where 0 is equal to 0 and 1 is equal to 360.

  \sa getHSVValue().
 */
SbColor &
SbColor::setHSVValue(const float hsv[3])
{
  return this->setHSVValue(hsv[0], hsv[1], hsv[2]);
}

/*!
  Return the color as a \c hue, \c saturation, \c value triplet.

  \sa setHSVValue().
 */
void
SbColor::getHSVValue(float hsv[3]) const
{
  this->getHSVValue(hsv[0], hsv[1], hsv[2]);
}