Lagrange
Loading...
Searching...
No Matches
Color.h
1/*
2 * Copyright 2019 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/internal/constants.h>
15
16#include <Eigen/Core>
17
18#include <algorithm>
19#include <cmath>
20#include <random>
21
22namespace lagrange {
23namespace ui {
24
25class Color : public Eigen::Vector4f
26{
27public:
28 using BaseType = Eigen::Vector4f;
29
30 static Color empty() { return Color(0, 0, 0, 0); }
31 static Color zero() { return Color(0, 0, 0, 0); }
32 static Color black() { return Color(0, 0, 0); }
33 static Color white() { return Color(1, 1, 1); }
34
35 static Color red() { return Color(1, 0, 0); }
36 static Color green() { return Color(0, 1, 0); }
37 static Color blue() { return Color(0, 0, 1); }
38
39 static Color cyan() { return Color(0, 1, 1); }
40 static Color yellow() { return Color(1, 1, 0); }
41 static Color purple() { return Color(1, 0, 1); }
42
43 Color(const Eigen::Vector4f& color)
44 : Eigen::Vector4f(color)
45 {}
46
47 Color(const Eigen::Vector3f& rgb, float alpha = 1.0f)
48 : Eigen::Vector4f(rgb.x(), rgb.y(), rgb.z(), alpha)
49 {}
50
51 Color(const float r, const float g, const float b, const float a)
52 : Color(Eigen::Vector4f(r, g, b, a))
53 {}
54
55 Color(const float r, const float g, const float b)
56 : Color(r, g, b, 1.0f)
57 {}
58
59 Color(const float v)
60 : Color(v, v, v, 1.0f)
61 {}
62
63 Color()
64 : Color(0, 0, 0, 0)
65 {}
66
67 template <typename Derived>
68 Color(const Eigen::MatrixBase<Derived>& p)
69 : Eigen::Vector4f(p)
70 {}
71
72 template <typename Derived>
73 Color& operator=(const Eigen::MatrixBase<Derived>& p)
74 {
75 this->Eigen::Vector4f::operator=(p);
76 return *this;
77 }
78
79 float& r() { return x(); }
80 float r() const { return x(); }
81
82 float& g() { return y(); }
83 float g() const { return y(); }
84
85 float& b() { return z(); }
86 float b() const { return z(); }
87
88 float& a() { return coeffRef(3); }
89 float a() const { return coeff(3); }
90
91 Eigen::Vector3f to_vec3() const { return Eigen::Vector3f(x(), y(), z()); }
92 Eigen::Vector4f to_vec4() const { return Eigen::Vector4f(x(), y(), z(), a()); }
93
94 Color operator+(const float v) const { return Color(r() + v, g() + v, b() + v, a()); }
95 Color operator-(const float v) const { return Color(r() - v, g() - v, b() - v, a()); }
96 Color operator/(const float v) const { return Color(r() / v, g() / v, b() / v, a()); }
97 Color operator*(const float v) const { return Color(r() * v, g() * v, b() * v, a()); }
98
99 Color operator+(const Color c) const
100 {
101 return Color(r() + c.r(), g() + c.g(), b() + c.b(), std::max(a(), c.a()));
102 }
103 Color operator-(const Color c) const
104 {
105 return Color(r() - c.r(), g() - c.g(), b() - c.b(), std::max(a(), c.a()));
106 }
107
111 void clamp()
112 {
113 if (r() < 0.0f) r() = 0.0f;
114 if (r() > 1.0f) r() = 1.0f;
115 if (g() < 0.0f) g() = 0.0f;
116 if (g() > 1.0f) g() = 1.0f;
117 if (b() < 0.0f) b() = 0.0f;
118 if (b() > 1.0f) b() = 1.0f;
119 }
120
121 Color clamped() const
122 {
123 return Color(
124 std::max(std::min(r(), 1.0f), 0.0f),
125 std::max(std::min(g(), 1.0f), 0.0f),
126 std::max(std::min(b(), 1.0f), 0.0f),
127 std::max(std::min(a(), 1.0f), 0.0f));
128 }
129
130 inline bool is_white() { return (r() + g() + b()) >= 3; }
131
132 inline bool is_black() { return (r() == 0 && g() == 0 && b() == 0); }
133
134 float distance(const Color c) const
135 {
136 return std::abs(c.r() - r()) + std::abs(c.g() - g()) + std::abs(c.b() - b());
137 }
138
148 template <typename URBG>
149 static const Color random_from(URBG&& urbg)
150 {
151 // static float tau = 0.5f;
152 //tau += (1.25f + (float)rand() / RAND_MAX);
153 std::uniform_real_distribution<float> dist(0.f, 2.f * lagrange::internal::pi);
154 float tau = dist(urbg);
155
156 const float value = static_cast<float>(lagrange::internal::pi) / 3.0f;
157
158 float center = 0.3f; // magic numbers!
159 float width = 0.3f;
160 return Color(
161 std::sin(tau + 0.0f * value) * width + center,
162 std::sin(tau + 2.0f * value) * width + center,
163 std::sin(tau + 4.0f * value) * width + center);
164 }
165
166 // given a number, will always return the same color for the same number, and will produce
167 // reasonably different colors for different numbers.
168 static const Color random(int i)
169 {
170 float tau = (float)i;
171 float value = (float)lagrange::internal::pi / 3;
172 float center = 0.3f;
173 float width = 0.3f;
174 return Color(
175 std::sin(tau + 0.0f * value) * width + center,
176 std::sin(tau + 2.0f * value) * width + center,
177 std::sin(tau + 4.0f * value) * width + center);
178 }
179
180 static Color integer_to_color(int i)
181 {
182 int r = (i & 0x000000FF);
183 int g = (i & 0x0000FF00) >> 8;
184 int b = (i & 0x00FF0000) >> 16;
185 return Color(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
186 }
187 int to_integer() const
188 {
189 int r = int(x() * 255.0f);
190 int g = int(y() * 255.0f) << 8;
191 int b = int(z() * 255.0f) << 16;
192 return (r | g) | b;
193 }
194};
195} // namespace ui
196} // namespace lagrange
Definition Color.h:26
void clamp()
Clamps the color.
Definition Color.h:111
static const Color random_from(URBG &&urbg)
Get a random color.
Definition Color.h:149
@ Color
Mesh attribute can have 1, 2, 3 or 4 channels.
Definition AttributeFwd.h:61
Lagrange UI Viewer and mini 3D engine.
Definition AcceleratedPicking.h:23
Main namespace for Lagrange.