llcolor3.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. /**
  2. * @file llcolor3.h
  3. * @brief LLColor3 class header file.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_V3COLOR_H
  33. #define LL_V3COLOR_H
  34. #include "llmath.h"
  35. #include "llsd.h"
  36. class LLColor4;
  37. class LLVector4;
  38. constexpr U32 LENGTHOFCOLOR3 = 3;
  39. class LLColor3
  40. {
  41. public:
  42. LL_INLINE LLColor3() noexcept { mV[0] = mV[1] = mV[2] = 0.f; }
  43. LL_INLINE LLColor3(F32 r, F32 g, F32 b) noexcept
  44. {
  45. mV[VX] = r;
  46. mV[VY] = g;
  47. mV[VZ] = b;
  48. }
  49. LL_INLINE LLColor3(const F32* vec) noexcept
  50. {
  51. mV[VX] = vec[VX];
  52. mV[VY] = vec[VY];
  53. mV[VZ] = vec[VZ];
  54. }
  55. explicit LLColor3(const LLColor4& a) noexcept;
  56. explicit LLColor3(const LLVector4& a) noexcept;
  57. LL_INLINE LLColor3(const LLSD& sd) { setValue(sd); }
  58. // Allow the use of the default C++11 move constructor and assignation
  59. LLColor3(LLColor3&& other) noexcept = default;
  60. LLColor3& operator=(LLColor3&& other) noexcept = default;
  61. LLColor3(const LLColor3& other) = default;
  62. LLColor3& operator=(const LLColor3& other) = default;
  63. // Takes a string of format "RRGGBB" where RR is hex 00..FF
  64. LLColor3(const char* color_string) noexcept;
  65. LL_INLINE LLSD getValue() const
  66. {
  67. LLSD ret;
  68. ret[0] = mV[0];
  69. ret[1] = mV[1];
  70. ret[2] = mV[2];
  71. return ret;
  72. }
  73. LL_INLINE void setValue(const LLSD& sd)
  74. {
  75. mV[0] = (F32)sd[0].asReal();
  76. mV[1] = (F32)sd[1].asReal();
  77. mV[2] = (F32)sd[2].asReal();
  78. }
  79. void setHSL(F32 hue, F32 saturation, F32 luminance);
  80. void calcHSL(F32* hue, F32* saturation, F32* luminance) const;
  81. // Desaturate the color by a given factor, also optionnally darken it. HB
  82. LL_INLINE void desaturate(F32 factor, F32 darkening = 1.f)
  83. {
  84. if (factor > 1.f)
  85. {
  86. F32 h, s, l;
  87. calcHSL(&h, &s, &l);
  88. setHSL(h, s / factor, l / llmax(darkening, 1.f));
  89. }
  90. }
  91. LL_INLINE const LLColor3& setToBlack()
  92. {
  93. mV[0] = mV[1] = mV[2] = 0.f;
  94. return *this;
  95. }
  96. LL_INLINE const LLColor3& setToWhite()
  97. {
  98. mV[0] = mV[1] = mV[2] = 1.f;
  99. return *this;
  100. }
  101. LL_INLINE const LLColor3& set(F32 r, F32 g, F32 b)
  102. {
  103. mV[0] = r;
  104. mV[1] = g;
  105. mV[2] = b;
  106. return *this;
  107. }
  108. LL_INLINE const LLColor3& set(const LLColor3& vec)
  109. {
  110. mV[0] = vec.mV[0];
  111. mV[1] = vec.mV[1];
  112. mV[2] = vec.mV[2];
  113. return *this;
  114. }
  115. LL_INLINE const LLColor3& set(const F32* vec)
  116. {
  117. mV[0] = vec[0];
  118. mV[1] = vec[1];
  119. mV[2] = vec[2];
  120. return *this;
  121. }
  122. // Sets from a vector of unknown type and size; may leave some data
  123. // unmodified.
  124. template<typename T>
  125. LL_INLINE const LLColor3& set(const std::vector<T>& v)
  126. {
  127. for (S32 i = 0, count = llmin((S32)v.size(), 3); i < count; ++i)
  128. {
  129. mV[i] = v[i];
  130. }
  131. return *this;
  132. }
  133. // Writes to a vector of unknown type and size; may leave some data
  134. // unmodified.
  135. template<typename T>
  136. LL_INLINE const LLColor3& write(std::vector<T>& v) const
  137. {
  138. for (S32 i = 0, count = llmin((S32)v.size(), 3); i < count; ++i)
  139. {
  140. v[i] = mV[i];
  141. }
  142. return *this;
  143. }
  144. // Returns magnitude of LLColor3
  145. LL_INLINE F32 length() const
  146. {
  147. return sqrtf(mV[0] * mV[0] + mV[1] * mV[1] + mV[2] * mV[2]);
  148. }
  149. // Returns magnitude squared of LLColor3
  150. LL_INLINE F32 lengthSquared() const
  151. {
  152. return mV[0] * mV[0] + mV[1] * mV[1] + mV[2] * mV[2];
  153. }
  154. // Normalizes and returns the magnitude of LLColor3
  155. LL_INLINE F32 normalize()
  156. {
  157. F32 mag = sqrtf(mV[0] * mV[0] + mV[1] * mV[1] + mV[2] * mV[2]);
  158. if (mag)
  159. {
  160. F32 oomag = 1.f / mag;
  161. mV[0] *= oomag;
  162. mV[1] *= oomag;
  163. mV[2] *= oomag;
  164. }
  165. return mag;
  166. }
  167. // Returns brightness of LLColor3
  168. LL_INLINE F32 brightness() const
  169. {
  170. constexpr F32 scaler = 1.f / 3.f;
  171. return (mV[0] + mV[1] + mV[2]) * scaler;
  172. }
  173. LL_INLINE LLColor3 divide(const LLColor3& col2)
  174. {
  175. return LLColor3(mV[0] / col2.mV[0], mV[1] / col2.mV[1],
  176. mV[2] / col2.mV[2]);
  177. }
  178. LL_INLINE LLColor3 color_norm()
  179. {
  180. F32 k = 1.f / length();
  181. return LLColor3(mV[0] * k, mV[1] * k, mV[2] * k);
  182. }
  183. const LLColor3& operator=(const LLColor4& a) noexcept;
  184. // Prints a
  185. friend std::ostream& operator<<(std::ostream& s, const LLColor3& a);
  186. // Returns vector a + b
  187. friend LLColor3 operator+(const LLColor3& a, const LLColor3& b);
  188. // Returns vector a minus b
  189. friend LLColor3 operator-(const LLColor3& a, const LLColor3& b);
  190. // Returns vector a + b
  191. friend const LLColor3& operator+=(LLColor3& a, const LLColor3& b);
  192. // Returns vector a minus b
  193. friend const LLColor3& operator-=(LLColor3& a, const LLColor3& b);
  194. // Returns component wise a * b
  195. friend const LLColor3& operator*=(LLColor3& a, const LLColor3& b);
  196. // Returns component wise a * b
  197. friend LLColor3 operator*(const LLColor3& a, const LLColor3& b);
  198. // Returns a times scaler k
  199. friend LLColor3 operator*(const LLColor3& a, F32 k);
  200. // Returns a times scaler k
  201. friend LLColor3 operator*(F32 k, const LLColor3& a);
  202. // Returns a == b
  203. friend bool operator==(const LLColor3& a, const LLColor3& b);
  204. // Returns a != b
  205. friend bool operator!=(const LLColor3& a, const LLColor3& b);
  206. // Returns a times scaler k
  207. friend const LLColor3& operator*=(LLColor3& a, F32 k);
  208. // Returns vector 1-rgb (inverse)
  209. friend LLColor3 operator-(const LLColor3& a);
  210. // Clamps the color...
  211. LL_INLINE void clamp()
  212. {
  213. if (mV[0] < 0.f)
  214. {
  215. mV[0] = 0.f;
  216. }
  217. else if (mV[0] > 1.f)
  218. {
  219. mV[0] = 1.f;
  220. }
  221. if (mV[1] < 0.f)
  222. {
  223. mV[1] = 0.f;
  224. }
  225. else if (mV[1] > 1.f)
  226. {
  227. mV[1] = 1.f;
  228. }
  229. if (mV[2] < 0.f)
  230. {
  231. mV[2] = 0.f;
  232. }
  233. else if (mV[2] > 1.f)
  234. {
  235. mV[2] = 1.f;
  236. }
  237. }
  238. // Tries and multiples the color by 'factor', but without going beyond 1.f
  239. // on any of its component (i.e. 'factor' is reduced if needed to avoid
  240. // overshooting the maximum on any component). A negative factor would also
  241. // cause this method to do nothing at all. HB
  242. void adjust(F32 factor);
  243. public:
  244. F32 mV[LENGTHOFCOLOR3];
  245. static LLColor3 white;
  246. static LLColor3 black;
  247. static LLColor3 grey;
  248. };
  249. // Non-member functions
  250. LLColor3 lerp(const LLColor3& a, const LLColor3& b, F32 u);
  251. // Returns distance between a and b:
  252. F32 distVec(const LLColor3& a, const LLColor3& b);
  253. // Returns distance squared between a and b
  254. F32 distVec_squared(const LLColor3& a, const LLColor3& b);
  255. LL_INLINE LLColor3 operator+(const LLColor3& a, const LLColor3& b)
  256. {
  257. return LLColor3(a.mV[0] + b.mV[0], a.mV[1] + b.mV[1], a.mV[2] + b.mV[2]);
  258. }
  259. LL_INLINE LLColor3 operator-(const LLColor3& a, const LLColor3& b)
  260. {
  261. return LLColor3(a.mV[0] - b.mV[0], a.mV[1] - b.mV[1], a.mV[2] - b.mV[2]);
  262. }
  263. LL_INLINE LLColor3 operator*(const LLColor3& a, const LLColor3& b)
  264. {
  265. return LLColor3(a.mV[0] * b.mV[0], a.mV[1] * b.mV[1], a.mV[2] * b.mV[2]);
  266. }
  267. LL_INLINE LLColor3 operator*(const LLColor3& a, F32 k)
  268. {
  269. return LLColor3(a.mV[0] * k, a.mV[1] * k, a.mV[2] * k);
  270. }
  271. LL_INLINE LLColor3 operator*(F32 k, const LLColor3& a)
  272. {
  273. return LLColor3(a.mV[0] * k, a.mV[1] * k, a.mV[2] * k);
  274. }
  275. LL_INLINE bool operator==(const LLColor3& a, const LLColor3& b)
  276. {
  277. return a.mV[0] == b.mV[0] && a.mV[1] == b.mV[1] && a.mV[2] == b.mV[2];
  278. }
  279. LL_INLINE bool operator!=(const LLColor3& a, const LLColor3& b)
  280. {
  281. return a.mV[0] != b.mV[0] || a.mV[1] != b.mV[1] || a.mV[2] != b.mV[2];
  282. }
  283. LL_INLINE const LLColor3& operator*=(LLColor3& a, const LLColor3& b)
  284. {
  285. a.mV[0] *= b.mV[0];
  286. a.mV[1] *= b.mV[1];
  287. a.mV[2] *= b.mV[2];
  288. return a;
  289. }
  290. LL_INLINE const LLColor3& operator+=(LLColor3& a, const LLColor3& b)
  291. {
  292. a.mV[0] += b.mV[0];
  293. a.mV[1] += b.mV[1];
  294. a.mV[2] += b.mV[2];
  295. return a;
  296. }
  297. LL_INLINE const LLColor3& operator-=(LLColor3& a, const LLColor3& b)
  298. {
  299. a.mV[0] -= b.mV[0];
  300. a.mV[1] -= b.mV[1];
  301. a.mV[2] -= b.mV[2];
  302. return a;
  303. }
  304. LL_INLINE const LLColor3& operator*=(LLColor3& a, F32 k)
  305. {
  306. a.mV[0] *= k;
  307. a.mV[1] *= k;
  308. a.mV[2] *= k;
  309. return a;
  310. }
  311. LL_INLINE LLColor3 operator-(const LLColor3& a)
  312. {
  313. return LLColor3(1.f - a.mV[0], 1.f - a.mV[1], 1.f - a.mV[2]);
  314. }
  315. // Non-member functions
  316. LL_INLINE F32 distVec(const LLColor3& a, const LLColor3& b)
  317. {
  318. F32 x = a.mV[0] - b.mV[0];
  319. F32 y = a.mV[1] - b.mV[1];
  320. F32 z = a.mV[2] - b.mV[2];
  321. return sqrtf(x * x + y * y + z * z);
  322. }
  323. LL_INLINE F32 distVec_squared(const LLColor3& a, const LLColor3& b)
  324. {
  325. F32 x = a.mV[0] - b.mV[0];
  326. F32 y = a.mV[1] - b.mV[1];
  327. F32 z = a.mV[2] - b.mV[2];
  328. return x * x + y * y + z * z;
  329. }
  330. LL_INLINE LLColor3 lerp(const LLColor3& a, const LLColor3& b, F32 u)
  331. {
  332. return LLColor3(a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
  333. a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
  334. a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);
  335. }
  336. LL_INLINE LLColor3 componentDiv(const LLColor3& left, const LLColor3& right)
  337. {
  338. return LLColor3(left.mV[0] / right.mV[0],
  339. left.mV[1] / right.mV[1],
  340. left.mV[2] / right.mV[2]);
  341. }
  342. LL_INLINE LLColor3 componentMult(const LLColor3& left, const LLColor3& right)
  343. {
  344. return LLColor3(left.mV[0] * right.mV[0],
  345. left.mV[1] * right.mV[1],
  346. left.mV[2] * right.mV[2]);
  347. }
  348. LL_INLINE LLColor3 componentExp(const LLColor3& v)
  349. {
  350. return LLColor3(expf(v.mV[0]), expf(v.mV[1]), expf(v.mV[2]));
  351. }
  352. LL_INLINE LLColor3 componentPow(const LLColor3& v, F32 exponent)
  353. {
  354. return LLColor3(powf(v.mV[0], exponent),
  355. powf(v.mV[1], exponent),
  356. powf(v.mV[2], exponent));
  357. }
  358. LL_INLINE LLColor3 componentSaturate(const LLColor3& v)
  359. {
  360. return LLColor3(llmax(llmin(v.mV[0], 1.f), 0.f),
  361. llmax(llmin(v.mV[1], 1.f), 0.f),
  362. llmax(llmin(v.mV[2], 1.f), 0.f));
  363. }
  364. LL_INLINE LLColor3 componentSqrt(const LLColor3& v)
  365. {
  366. return LLColor3(sqrtf(v.mV[0]), sqrtf(v.mV[1]), sqrtf(v.mV[2]));
  367. }
  368. LL_INLINE void componentMultBy(LLColor3& left, const LLColor3& right)
  369. {
  370. left.mV[0] *= right.mV[0];
  371. left.mV[1] *= right.mV[1];
  372. left.mV[2] *= right.mV[2];
  373. }
  374. LL_INLINE LLColor3 colorMix(const LLColor3& left, const LLColor3& right,
  375. F32 amount)
  376. {
  377. return left + (right - left) * amount;
  378. }
  379. LL_INLINE LLColor3 smear(F32 val)
  380. {
  381. return LLColor3(val, val, val);
  382. }
  383. LL_INLINE F32 color_intens(const LLColor3& col)
  384. {
  385. return col.mV[0] + col.mV[1] + col.mV[2];
  386. }
  387. LL_INLINE F32 color_max(const LLColor3& col)
  388. {
  389. return llmax(col.mV[0], col.mV[1], col.mV[2]);
  390. }
  391. LL_INLINE F32 color_min(const LLColor3& col)
  392. {
  393. return llmin(col.mV[0], col.mV[1], col.mV[2]);
  394. }
  395. LL_INLINE const LLColor3 srgbColor3(const LLColor3& a)
  396. {
  397. return LLColor3(linearToSRGB(a.mV[0]), linearToSRGB(a.mV[1]),
  398. linearToSRGB(a.mV[2]));
  399. }
  400. LL_INLINE const LLColor3 linearColor3p(const F32* v)
  401. {
  402. return LLColor3(sRGBtoLinear(v[0]), sRGBtoLinear(v[1]),
  403. sRGBtoLinear(v[2]));
  404. }
  405. // Avoids a trivial/pointless template and guarantees inlining. HB
  406. #define linearColor3(a) linearColor3p((a).mV)
  407. // Avoids a trivial/pointless template which would require the #inclusion of
  408. // llvector3.h by this header file, and guarantees inlining. HB
  409. #define linearColor3v(a) LLVector3(linearColor3p((a).mV).mV)
  410. #endif