llcolor4.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. /**
  2. * @file llcolor4.h
  3. * @brief LLColor4 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_V4COLOR_H
  33. #define LL_V4COLOR_H
  34. #include <string.h>
  35. #include "llerror.h"
  36. #include "llmath.h"
  37. #include "llsd.h"
  38. class LLColor3;
  39. class LLColor4U;
  40. class LLVector4;
  41. // LLColor4 = |x y z w|
  42. constexpr U32 LENGTHOFCOLOR4 = 4;
  43. // Give plenty of room for additional colors...
  44. constexpr U32 MAX_LENGTH_OF_COLOR_NAME = 15;
  45. class LLColor4
  46. {
  47. protected:
  48. LOG_CLASS(LLColor4);
  49. public:
  50. LL_INLINE LLColor4() noexcept
  51. {
  52. mV[VX] = mV[VY] = mV[VZ] = 0.f;
  53. mV[VW] = 1.f;
  54. }
  55. LL_INLINE LLColor4(F32 r, F32 g, F32 b) noexcept
  56. {
  57. mV[VX] = r;
  58. mV[VY] = g;
  59. mV[VZ] = b;
  60. mV[VW] = 1.f;
  61. }
  62. LL_INLINE LLColor4(F32 r, F32 g, F32 b, F32 a) noexcept
  63. {
  64. mV[VX] = r;
  65. mV[VY] = g;
  66. mV[VZ] = b;
  67. mV[VW] = a;
  68. }
  69. LL_INLINE LLColor4(U32 clr) noexcept
  70. {
  71. constexpr F32 SCALE = 1.f / 255.f;
  72. mV[VX] = (clr & 0xff) * SCALE;
  73. mV[VY] = ((clr >> 8) & 0xff) * SCALE;
  74. mV[VZ] = ((clr >> 16) & 0xff) * SCALE;
  75. mV[VW] = (clr >> 24) * SCALE;
  76. }
  77. LL_INLINE LLColor4(const F32* vec) noexcept
  78. {
  79. mV[VX] = vec[VX];
  80. mV[VY] = vec[VY];
  81. mV[VZ] = vec[VZ];
  82. mV[VW] = vec[VW];
  83. }
  84. // Initializes LLColor4 to (vec, a)
  85. LLColor4(const LLColor3& vec, F32 a = 1.f) noexcept;
  86. // "explicit" to avoid automatic conversions
  87. LL_INLINE explicit LLColor4(const LLSD& sd)
  88. {
  89. setValue(sd);
  90. }
  91. explicit LLColor4(const LLColor4U& color4u) noexcept;
  92. explicit LLColor4(const LLVector4& vector4) noexcept;
  93. // Allow the use of the default C++11 move constructor and assignation
  94. LLColor4(LLColor4&& other) noexcept = default;
  95. LLColor4& operator=(LLColor4&& other) noexcept = default;
  96. LLColor4(const LLColor4& other) = default;
  97. LLColor4& operator=(const LLColor4& other) = default;
  98. LL_INLINE LLSD getValue() const
  99. {
  100. LLSD ret;
  101. ret[0] = mV[0];
  102. ret[1] = mV[1];
  103. ret[2] = mV[2];
  104. ret[3] = mV[3];
  105. return ret;
  106. }
  107. void setValue(const LLSD& sd);
  108. void setHSL(F32 hue, F32 saturation, F32 luminance);
  109. void calcHSL(F32* hue, F32* saturation, F32* luminance) const;
  110. LL_INLINE const LLColor4& setToBlack()
  111. {
  112. mV[VX] = mV[VY] = mV[VZ] = 0.f;
  113. mV[VW] = 1.f;
  114. return *this;
  115. }
  116. LL_INLINE const LLColor4& setToWhite()
  117. {
  118. mV[VX] = mV[VY] = mV[VZ] = mV[VW] = 1.f;
  119. return *this;
  120. }
  121. LL_INLINE const LLColor4& set(F32 r, F32 g, F32 b, F32 a)
  122. {
  123. mV[VX] = r;
  124. mV[VY] = g;
  125. mV[VZ] = b;
  126. mV[VW] = a;
  127. return *this;
  128. }
  129. // Sets color without touching alpha
  130. LL_INLINE const LLColor4& set(F32 r, F32 g, F32 b)
  131. {
  132. mV[VX] = r;
  133. mV[VY] = g;
  134. mV[VZ] = b;
  135. return *this;
  136. }
  137. LL_INLINE const LLColor4& set(const LLColor4& vec)
  138. {
  139. mV[VX] = vec.mV[VX];
  140. mV[VY] = vec.mV[VY];
  141. mV[VZ] = vec.mV[VZ];
  142. mV[VW] = vec.mV[VW];
  143. return *this;
  144. }
  145. LL_INLINE const LLColor4& set(const F32* vec)
  146. {
  147. mV[VX] = vec[VX];
  148. mV[VY] = vec[VY];
  149. mV[VZ] = vec[VZ];
  150. mV[VW] = vec[VW];
  151. return *this;
  152. }
  153. LL_INLINE const LLColor4& set(const F64* vec)
  154. {
  155. mV[VX] = F32(vec[VX]);
  156. mV[VY] = F32(vec[VY]);
  157. mV[VZ] = F32(vec[VZ]);
  158. mV[VW] = F32(vec[VW]);
  159. return *this;
  160. }
  161. // Sets LLColor4 to LLColor3 vec (no change in alpha)
  162. const LLColor4& set(const LLColor3& vec);
  163. // Sets LLColor4 to LLColor3 vec, with alpha specified
  164. const LLColor4& set(const LLColor3& vec, F32 a);
  165. // Sets LLColor4 to color4u, rescaled.
  166. const LLColor4& set(const LLColor4U& color4u);
  167. LL_INLINE const LLColor4& setAlpha(F32 a)
  168. {
  169. mV[VW] = a;
  170. return *this;
  171. }
  172. // Sets from a vector of unknown type and size; may leave some data
  173. // unmodified.
  174. template<typename T>
  175. LL_INLINE const LLColor4& set(const std::vector<T>& v)
  176. {
  177. for (S32 i = 0, count = llmin((S32)v.size(), 4); i < count; ++i)
  178. {
  179. mV[i] = v[i];
  180. }
  181. return *this;
  182. }
  183. // Writes to a vector of unknown type and size; may leave some data
  184. // unmodified.
  185. template<typename T>
  186. LL_INLINE const LLColor4& write(std::vector<T>& v) const
  187. {
  188. for (S32 i = 0, count = llmin((S32)v.size(), 4); i < count; ++i)
  189. {
  190. v[i] = mV[i];
  191. }
  192. return *this;
  193. }
  194. // Returns magnitude of LLColor4
  195. LL_INLINE F32 length() const
  196. {
  197. return sqrtf(mV[VX] * mV[VX] + mV[VY] * mV[VY] + mV[VZ] * mV[VZ]);
  198. }
  199. // Returns magnitude squared of LLColor4, which is faster than length()
  200. LL_INLINE F32 lengthSquared() const
  201. {
  202. return mV[VX] * mV[VX] + mV[VY] * mV[VY] + mV[VZ] * mV[VZ];
  203. }
  204. LL_INLINE F32 normalize()
  205. {
  206. F32 mag = sqrtf(mV[VX] * mV[VX] + mV[VY] * mV[VY] + mV[VZ] * mV[VZ]);
  207. if (mag)
  208. {
  209. F32 oomag = 1.f / mag;
  210. mV[VX] *= oomag;
  211. mV[VY] *= oomag;
  212. mV[VZ] *= oomag;
  213. }
  214. return mag;
  215. }
  216. LL_INLINE bool isOpaque() { return mV[VALPHA] == 1.f; }
  217. LL_INLINE F32 operator[](int idx) const { return mV[idx]; }
  218. LL_INLINE F32& operator[](int idx) { return mV[idx]; }
  219. // Assigns vec3 to vec4 and returns vec4
  220. const LLColor4& operator=(const LLColor3& a);
  221. bool operator<(const LLColor4& rhs) const;
  222. friend std::ostream& operator<<(std::ostream& s, const LLColor4& a);
  223. // Returns vector a + b
  224. friend LLColor4 operator+(const LLColor4& a, const LLColor4& b);
  225. // Returns vector a minus b
  226. friend LLColor4 operator-(const LLColor4& a, const LLColor4& b);
  227. // Returns component wise a * b
  228. friend LLColor4 operator*(const LLColor4& a, const LLColor4& b);
  229. // Returns rgb times scaler k (no alpha change)
  230. friend LLColor4 operator*(const LLColor4& a, F32 k);
  231. // Returns rgb divided by scalar k (no alpha change)
  232. friend LLColor4 operator/(const LLColor4& a, F32 k);
  233. // Returns rgb times scaler k (no alpha change)
  234. friend LLColor4 operator*(F32 k, const LLColor4& a);
  235. // Returns alpha times scaler k (no rgb change)
  236. friend LLColor4 operator%(const LLColor4& a, F32 k);
  237. // Returns alpha times scaler k (no rgb change)
  238. friend LLColor4 operator%(F32 k, const LLColor4& a);
  239. friend bool operator==(const LLColor4& a, const LLColor4& b);
  240. friend bool operator!=(const LLColor4& a, const LLColor4& b);
  241. friend bool operator==(const LLColor4& a, const LLColor3& b);
  242. friend bool operator!=(const LLColor4& a, const LLColor3& b);
  243. // Returns vector a + b
  244. friend const LLColor4& operator+=(LLColor4& a, const LLColor4& b);
  245. // Returns vector a minus b
  246. friend const LLColor4& operator-=(LLColor4& a, const LLColor4& b);
  247. // Returns rgb times scaler k (no alpha change)
  248. friend const LLColor4& operator*=(LLColor4& a, F32 k);
  249. // Returns alpha times scaler k (no rgb change)
  250. friend const LLColor4& operator%=(LLColor4& a, F32 k);
  251. // Does not multiply alpha (used for lighting) !
  252. friend const LLColor4& operator*=(LLColor4& a, const LLColor4& b);
  253. // Conversion
  254. operator LLColor4U() const;
  255. LL_INLINE void clamp();
  256. static bool parseColor(const std::string& buf, LLColor4* color);
  257. static bool parseColor4(const std::string& buf, LLColor4* color);
  258. public:
  259. F32 mV[LENGTHOFCOLOR4];
  260. // Basic color values.
  261. static LLColor4 red;
  262. static LLColor4 green;
  263. static LLColor4 blue;
  264. static LLColor4 black;
  265. static LLColor4 white;
  266. static LLColor4 yellow;
  267. static LLColor4 magenta;
  268. static LLColor4 cyan;
  269. static LLColor4 smoke;
  270. static LLColor4 grey;
  271. static LLColor4 orange;
  272. static LLColor4 purple;
  273. static LLColor4 pink;
  274. static LLColor4 transparent;
  275. // Extra color values.
  276. static LLColor4 grey1;
  277. static LLColor4 grey2;
  278. static LLColor4 grey3;
  279. static LLColor4 grey4;
  280. static LLColor4 grey5;
  281. static LLColor4 red0;
  282. static LLColor4 red1;
  283. static LLColor4 red2;
  284. static LLColor4 red3;
  285. static LLColor4 red4;
  286. static LLColor4 red5;
  287. static LLColor4 green0;
  288. static LLColor4 green1;
  289. static LLColor4 green2;
  290. static LLColor4 green3;
  291. static LLColor4 green4;
  292. static LLColor4 green5;
  293. static LLColor4 green6;
  294. static LLColor4 green7;
  295. static LLColor4 green8;
  296. static LLColor4 green9;
  297. static LLColor4 blue0;
  298. static LLColor4 blue1;
  299. static LLColor4 blue2;
  300. static LLColor4 blue3;
  301. static LLColor4 blue4;
  302. static LLColor4 blue5;
  303. static LLColor4 blue6;
  304. static LLColor4 blue7;
  305. static LLColor4 yellow1;
  306. static LLColor4 yellow2;
  307. static LLColor4 yellow3;
  308. static LLColor4 yellow4;
  309. static LLColor4 yellow5;
  310. static LLColor4 yellow6;
  311. static LLColor4 yellow7;
  312. static LLColor4 yellow8;
  313. static LLColor4 yellow9;
  314. static LLColor4 orange1;
  315. static LLColor4 orange2;
  316. static LLColor4 orange3;
  317. static LLColor4 orange4;
  318. static LLColor4 orange5;
  319. static LLColor4 orange6;
  320. static LLColor4 magenta1;
  321. static LLColor4 magenta2;
  322. static LLColor4 magenta3;
  323. static LLColor4 magenta4;
  324. static LLColor4 purple1;
  325. static LLColor4 purple2;
  326. static LLColor4 purple3;
  327. static LLColor4 purple4;
  328. static LLColor4 purple5;
  329. static LLColor4 purple6;
  330. static LLColor4 pink1;
  331. static LLColor4 pink2;
  332. static LLColor4 cyan1;
  333. static LLColor4 cyan2;
  334. static LLColor4 cyan3;
  335. static LLColor4 cyan4;
  336. static LLColor4 cyan5;
  337. static LLColor4 cyan6;
  338. };
  339. // LLColor4 Operators
  340. LL_INLINE LLColor4 operator+(const LLColor4& a, const LLColor4& b)
  341. {
  342. return LLColor4(a.mV[VX] + b.mV[VX], a.mV[VY] + b.mV[VY],
  343. a.mV[VZ] + b.mV[VZ], a.mV[VW] + b.mV[VW]);
  344. }
  345. LL_INLINE LLColor4 operator-(const LLColor4& a, const LLColor4& b)
  346. {
  347. return LLColor4(a.mV[VX] - b.mV[VX], a.mV[VY] - b.mV[VY],
  348. a.mV[VZ] - b.mV[VZ], a.mV[VW] - b.mV[VW]);
  349. }
  350. LL_INLINE LLColor4 operator*(const LLColor4& a, const LLColor4& b)
  351. {
  352. return LLColor4(a.mV[VX] * b.mV[VX], a.mV[VY] * b.mV[VY],
  353. a.mV[VZ] * b.mV[VZ], a.mV[VW] * b.mV[VW]);
  354. }
  355. // Only affects rgb (not a !)
  356. LL_INLINE LLColor4 operator*(const LLColor4& a, F32 k)
  357. {
  358. return LLColor4(a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k, a.mV[VW]);
  359. }
  360. // Only affects rgb (not a !)
  361. LL_INLINE LLColor4 operator/(const LLColor4& a, F32 k)
  362. {
  363. const F32 ik = 1.f / k;
  364. return LLColor4(a.mV[VX] * ik, a.mV[VY] * ik, a.mV[VZ] * ik, a.mV[VW]);
  365. }
  366. LL_INLINE LLColor4 operator*(F32 k, const LLColor4& a)
  367. {
  368. // Only affects rgb (not a !)
  369. return LLColor4(a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k, a.mV[VW]);
  370. }
  371. LL_INLINE LLColor4 operator%(F32 k, const LLColor4& a)
  372. {
  373. // Only affects alpha (not rgb!)
  374. return LLColor4(a.mV[VX], a.mV[VY], a.mV[VZ], a.mV[VW] * k);
  375. }
  376. // Only affects alpha (not rgb !)
  377. LL_INLINE LLColor4 operator%(const LLColor4& a, F32 k)
  378. {
  379. return LLColor4(a.mV[VX], a.mV[VY], a.mV[VZ], a.mV[VW] * k);
  380. }
  381. LL_INLINE bool operator==(const LLColor4& a, const LLColor4& b)
  382. {
  383. return a.mV[VX] == b.mV[VX] && a.mV[VY] == b.mV[VY] &&
  384. a.mV[VZ] == b.mV[VZ] && a.mV[VW] == b.mV[VW];
  385. }
  386. LL_INLINE bool operator!=(const LLColor4& a, const LLColor4& b)
  387. {
  388. return a.mV[VX] != b.mV[VX] || a.mV[VY] != b.mV[VY] ||
  389. a.mV[VZ] != b.mV[VZ] || a.mV[VW] != b.mV[VW];
  390. }
  391. LL_INLINE const LLColor4& operator+=(LLColor4& a, const LLColor4& b)
  392. {
  393. a.mV[VX] += b.mV[VX];
  394. a.mV[VY] += b.mV[VY];
  395. a.mV[VZ] += b.mV[VZ];
  396. a.mV[VW] += b.mV[VW];
  397. return a;
  398. }
  399. LL_INLINE const LLColor4& operator-=(LLColor4& a, const LLColor4& b)
  400. {
  401. a.mV[VX] -= b.mV[VX];
  402. a.mV[VY] -= b.mV[VY];
  403. a.mV[VZ] -= b.mV[VZ];
  404. a.mV[VW] -= b.mV[VW];
  405. return a;
  406. }
  407. // Only affects rgb (not a !)
  408. LL_INLINE const LLColor4& operator*=(LLColor4& a, F32 k)
  409. {
  410. a.mV[VX] *= k;
  411. a.mV[VY] *= k;
  412. a.mV[VZ] *= k;
  413. return a;
  414. }
  415. // Only affects rgb (not a !)
  416. LL_INLINE const LLColor4& operator*=(LLColor4& a, const LLColor4& b)
  417. {
  418. a.mV[VX] *= b.mV[VX];
  419. a.mV[VY] *= b.mV[VY];
  420. a.mV[VZ] *= b.mV[VZ];
  421. return a;
  422. }
  423. LL_INLINE const LLColor4& operator%=(LLColor4& a, F32 k)
  424. {
  425. // Only affects alpha (not rgb!)
  426. a.mV[VW] *= k;
  427. return a;
  428. }
  429. // Non-member functions
  430. LL_INLINE F32 distVec(const LLColor4& a, const LLColor4& b)
  431. {
  432. LLColor4 vec = a - b;
  433. return vec.length();
  434. }
  435. LL_INLINE F32 distVec_squared(const LLColor4& a, const LLColor4& b)
  436. {
  437. LLColor4 vec = a - b;
  438. return vec.lengthSquared();
  439. }
  440. LL_INLINE LLColor4 lerp(const LLColor4& a, const LLColor4& b, F32 u)
  441. {
  442. return LLColor4(a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
  443. a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
  444. a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u,
  445. a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u);
  446. }
  447. LL_INLINE bool LLColor4::operator<(const LLColor4& rhs) const
  448. {
  449. if (mV[0] != rhs.mV[0])
  450. {
  451. return mV[0] < rhs.mV[0];
  452. }
  453. if (mV[1] != rhs.mV[1])
  454. {
  455. return mV[1] < rhs.mV[1];
  456. }
  457. if (mV[2] != rhs.mV[2])
  458. {
  459. return mV[2] < rhs.mV[2];
  460. }
  461. return mV[3] < rhs.mV[3];
  462. }
  463. LL_INLINE void LLColor4::clamp()
  464. {
  465. // Clamp the color...
  466. if (mV[0] < 0.f)
  467. {
  468. mV[0] = 0.f;
  469. }
  470. else if (mV[0] > 1.f)
  471. {
  472. mV[0] = 1.f;
  473. }
  474. if (mV[1] < 0.f)
  475. {
  476. mV[1] = 0.f;
  477. }
  478. else if (mV[1] > 1.f)
  479. {
  480. mV[1] = 1.f;
  481. }
  482. if (mV[2] < 0.f)
  483. {
  484. mV[2] = 0.f;
  485. }
  486. else if (mV[2] > 1.f)
  487. {
  488. mV[2] = 1.f;
  489. }
  490. if (mV[3] < 0.f)
  491. {
  492. mV[3] = 0.f;
  493. }
  494. else if (mV[3] > 1.f)
  495. {
  496. mV[3] = 1.f;
  497. }
  498. }
  499. LL_INLINE F32 color_max(const LLColor4& col)
  500. {
  501. return llmax(col.mV[0], col.mV[1], col.mV[2]);
  502. }
  503. LL_INLINE const LLColor4 srgbColor4(const LLColor4& a)
  504. {
  505. return LLColor4(linearToSRGB(a.mV[0]), linearToSRGB(a.mV[1]),
  506. linearToSRGB(a.mV[2]), a.mV[3]);
  507. }
  508. LL_INLINE const LLColor4 linearColor4(const LLColor4& a)
  509. {
  510. return LLColor4(sRGBtoLinear(a.mV[0]), sRGBtoLinear(a.mV[1]),
  511. sRGBtoLinear(a.mV[2]), a.mV[3]);
  512. }
  513. // Returns distance between a and b
  514. F32 distVec(const LLColor4& a, const LLColor4& b);
  515. // Returns distance squared between a and b
  516. F32 distVec_squared(const LLColor4& a, const LLColor4& b);
  517. LLColor3 vec4to3(const LLColor4& vec);
  518. LLColor4 vec3to4(const LLColor3& vec);
  519. LLColor4 lerp(const LLColor4& a, const LLColor4& b, F32 u);
  520. #endif