Skip to content

Commit 03bc5d7

Browse files
authored
two-way conversions between Color-Vec4 and Color-[f32; 4] (#688)
two-way conversions between `Color`-`Vec4` and `Color`-`[f32; 4]` - use `impl From` instead of `impl Into`
1 parent c32e637 commit 03bc5d7

File tree

1 file changed

+196
-46
lines changed

1 file changed

+196
-46
lines changed

crates/bevy_render/src/color.rs

Lines changed: 196 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use bevy_property::Property;
1111
use serde::{Deserialize, Serialize};
1212
use std::ops::{Add, AddAssign, Mul, MulAssign};
1313

14+
// TODO: Separate types for non-linear sRGB and linear sRGB, with conversions between
15+
// see comment on bevy issue #688 https://github.com/bevyengine/bevy/pull/688#issuecomment-711414011
1416
/// RGBA color in the Linear sRGB colorspace (often colloquially referred to as "linear", "RGB", or "linear RGB").
1517
#[repr(C)]
1618
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Property)]
@@ -76,6 +78,7 @@ impl Color {
7678
}
7779
}
7880

81+
/// New ``Color`` from sRGB colorspace.
7982
pub fn hex<T: AsRef<str>>(hex: T) -> Result<Color, HexColorError> {
8083
let hex = hex.as_ref();
8184

@@ -134,72 +137,90 @@ impl Color {
134137
red: self.red.nonlinear_to_linear_srgb(),
135138
green: self.green.nonlinear_to_linear_srgb(),
136139
blue: self.blue.nonlinear_to_linear_srgb(),
137-
alpha: self.alpha, //alpha is always linear
140+
alpha: self.alpha, // alpha is always linear
138141
}
139142
}
140143

141144
// non-linear-sRGB Component Getter
145+
146+
/// Get red in sRGB colorspace.
142147
pub fn r(&self) -> f32 {
143148
self.red.linear_to_nonlinear_srgb()
144149
}
145150

151+
/// Get green in sRGB colorspace.
146152
pub fn g(&self) -> f32 {
147153
self.green.linear_to_nonlinear_srgb()
148154
}
149155

156+
/// Get blue in sRGB colorspace.
150157
pub fn b(&self) -> f32 {
151158
self.blue.linear_to_nonlinear_srgb()
152159
}
153160

154161
// linear-sRGB Component Getter
155-
pub fn g_linear(&self) -> f32 {
156-
self.green
157-
}
158162

163+
/// Get red in linear colorspace.
159164
pub fn r_linear(&self) -> f32 {
160165
self.red
161166
}
162167

168+
/// Get green in linear colorspace.
169+
pub fn g_linear(&self) -> f32 {
170+
self.green
171+
}
172+
173+
/// Get blue in linear colorspace.
163174
pub fn b_linear(&self) -> f32 {
164175
self.blue
165176
}
166177

178+
/// Get alpha.
167179
pub fn a(&self) -> f32 {
168180
self.alpha
169181
}
170182

171183
// non-linear-sRGB Component Setter
184+
185+
/// Set red in sRGB colorspace.
172186
pub fn set_r(&mut self, r: f32) -> &mut Self {
173187
self.red = r.nonlinear_to_linear_srgb();
174188
self
175189
}
176190

191+
/// Set green in sRGB colorspace.
177192
pub fn set_g(&mut self, g: f32) -> &mut Self {
178193
self.green = g.nonlinear_to_linear_srgb();
179194
self
180195
}
181196

197+
/// Set blue in sRGB colorspace.
182198
pub fn set_b(&mut self, b: f32) -> &mut Self {
183199
self.blue = b.nonlinear_to_linear_srgb();
184200
self
185201
}
186202

187203
// linear-sRGB Component Setter
204+
205+
/// Set red in linear colorspace.
188206
pub fn set_r_linear(&mut self, r: f32) -> &mut Self {
189207
self.red = r;
190208
self
191209
}
192210

211+
/// Set green in linear colorspace.
193212
pub fn set_g_linear(&mut self, g: f32) -> &mut Self {
194213
self.green = g;
195214
self
196215
}
197216

217+
/// Set blue in linear colorspace.
198218
pub fn set_b_linear(&mut self, b: f32) -> &mut Self {
199219
self.blue = b;
200220
self
201221
}
202222

223+
/// Set alpha.
203224
pub fn set_a(&mut self, a: f32) -> &mut Self {
204225
self.alpha = a;
205226
self
@@ -249,91 +270,119 @@ impl Add<Vec4> for Color {
249270
}
250271
}
251272

252-
impl From<Vec4> for Color {
253-
fn from(vec4: Vec4) -> Self {
254-
Color {
255-
red: vec4.x(),
256-
green: vec4.y(),
257-
blue: vec4.z(),
258-
alpha: vec4.w(),
259-
}
273+
impl From<Color> for [f32; 4] {
274+
fn from(color: Color) -> Self {
275+
[color.r(), color.g(), color.b(), color.a()]
260276
}
261277
}
262278

263279
impl From<[f32; 4]> for Color {
264-
fn from(value: [f32; 4]) -> Self {
265-
Color::rgba(value[0], value[1], value[2], value[3])
280+
fn from([r, g, b, a]: [f32; 4]) -> Self {
281+
Color::rgba(r, g, b, a)
282+
}
283+
}
284+
285+
impl From<Color> for Vec4 {
286+
fn from(color: Color) -> Self {
287+
Vec4::new(color.r(), color.g(), color.b(), color.a())
266288
}
267289
}
268290

269-
impl Into<[f32; 4]> for Color {
270-
fn into(self) -> [f32; 4] {
271-
[self.red, self.green, self.blue, self.alpha]
291+
impl From<Vec4> for Color {
292+
fn from(vec4: Vec4) -> Self {
293+
Color::rgba(vec4.x(), vec4.y(), vec4.z(), vec4.w())
272294
}
273295
}
274296

275297
impl Mul<f32> for Color {
276298
type Output = Color;
277299

278300
fn mul(self, rhs: f32) -> Self::Output {
279-
Color {
280-
red: self.red * rhs,
281-
green: self.green * rhs,
282-
blue: self.blue * rhs,
283-
alpha: self.alpha * rhs,
284-
}
301+
Color::rgba(self.r() * rhs, self.g() * rhs, self.b() * rhs, self.a())
285302
}
286303
}
287304

288305
impl MulAssign<f32> for Color {
289306
fn mul_assign(&mut self, rhs: f32) {
290-
self.red *= rhs;
291-
self.green *= rhs;
292-
self.blue *= rhs;
293-
self.alpha *= rhs;
307+
self.set_r(self.r() * rhs);
308+
self.set_g(self.g() * rhs);
309+
self.set_b(self.b() * rhs);
294310
}
295311
}
296312

297313
impl Mul<Vec4> for Color {
298314
type Output = Color;
299315

300316
fn mul(self, rhs: Vec4) -> Self::Output {
301-
Color {
302-
red: self.red * rhs.x(),
303-
green: self.green * rhs.y(),
304-
blue: self.blue * rhs.z(),
305-
alpha: self.alpha * rhs.w(),
306-
}
317+
Color::rgba(
318+
self.r() * rhs.x(),
319+
self.g() * rhs.y(),
320+
self.b() * rhs.z(),
321+
self.a() * rhs.w(),
322+
)
307323
}
308324
}
309325

310326
impl MulAssign<Vec4> for Color {
311327
fn mul_assign(&mut self, rhs: Vec4) {
312-
self.red *= rhs.x();
313-
self.green *= rhs.y();
314-
self.blue *= rhs.z();
315-
self.alpha *= rhs.w();
328+
self.set_r(self.r() * rhs.x());
329+
self.set_g(self.g() * rhs.y());
330+
self.set_b(self.b() * rhs.z());
331+
self.set_a(self.a() * rhs.w());
316332
}
317333
}
318334

319335
impl Mul<Vec3> for Color {
320336
type Output = Color;
321337

322338
fn mul(self, rhs: Vec3) -> Self::Output {
323-
Color {
324-
red: self.red * rhs.x(),
325-
green: self.green * rhs.y(),
326-
blue: self.blue * rhs.z(),
327-
alpha: self.alpha,
328-
}
339+
Color::rgba(
340+
self.r() * rhs.x(),
341+
self.g() * rhs.y(),
342+
self.b() * rhs.z(),
343+
self.a(),
344+
)
329345
}
330346
}
331347

332348
impl MulAssign<Vec3> for Color {
333349
fn mul_assign(&mut self, rhs: Vec3) {
334-
self.red *= rhs.x();
335-
self.green *= rhs.y();
336-
self.blue *= rhs.z();
350+
self.set_r(self.r() * rhs.x());
351+
self.set_g(self.g() * rhs.y());
352+
self.set_b(self.b() * rhs.z());
353+
}
354+
}
355+
356+
impl Mul<[f32; 4]> for Color {
357+
type Output = Color;
358+
359+
fn mul(self, [r, g, b, a]: [f32; 4]) -> Self::Output {
360+
Color::rgba(self.r() * r, self.g() * g, self.b() * b, self.a() * a)
361+
}
362+
}
363+
364+
impl MulAssign<[f32; 4]> for Color {
365+
fn mul_assign(&mut self, [r, g, b, a]: [f32; 4]) {
366+
self.set_r(self.r() * r);
367+
self.set_g(self.g() * g);
368+
self.set_b(self.b() * b);
369+
self.set_a(self.a() * a);
370+
}
371+
}
372+
373+
impl Mul<[f32; 3]> for Color {
374+
type Output = Color;
375+
376+
fn mul(self, [r, g, b]: [f32; 3]) -> Self::Output {
377+
Color::rgba(self.r() * r, self.g() * g, self.b() * b, self.a())
378+
}
379+
}
380+
381+
impl MulAssign<[f32; 3]> for Color {
382+
fn mul_assign(&mut self, [r, g, b]: [f32; 3]) {
383+
self.set_r(self.r() * r);
384+
self.set_g(self.g() * g);
385+
self.set_b(self.b() * b);
337386
}
338387
}
339388

@@ -359,6 +408,12 @@ pub enum ColorSource {
359408
Texture(Handle<Texture>),
360409
}
361410

411+
impl From<[f32; 4]> for ColorSource {
412+
fn from(f32s: [f32; 4]) -> Self {
413+
ColorSource::Color(f32s.into())
414+
}
415+
}
416+
362417
impl From<Vec4> for ColorSource {
363418
fn from(vec4: Vec4) -> Self {
364419
ColorSource::Color(vec4.into())
@@ -449,3 +504,98 @@ fn test_hex_color() {
449504

450505
assert!(Color::hex("1234567890").is_err());
451506
}
507+
508+
#[test]
509+
fn test_conversions_vec4() {
510+
let starting_vec4 = Vec4::new(0.4, 0.5, 0.6, 1.0);
511+
let starting_color = Color::from(starting_vec4);
512+
513+
assert_eq!(starting_vec4, Vec4::from(starting_color),);
514+
515+
let transformation = Vec4::new(0.5, 0.5, 0.5, 1.0);
516+
517+
assert_eq!(
518+
starting_color * transformation,
519+
Color::from(starting_vec4 * transformation),
520+
);
521+
}
522+
523+
#[test]
524+
fn test_mul_and_mulassign_f32() {
525+
let transformation = 0.5;
526+
let starting_color = Color::rgba(0.4, 0.5, 0.6, 1.0);
527+
528+
assert_eq!(
529+
starting_color * transformation,
530+
Color::rgba(0.4 * 0.5, 0.5 * 0.5, 0.6 * 0.5, 1.0),
531+
);
532+
533+
let mut mutated_color = starting_color;
534+
mutated_color *= transformation;
535+
536+
assert_eq!(starting_color * transformation, mutated_color,);
537+
}
538+
539+
#[test]
540+
fn test_mul_and_mulassign_f32by3() {
541+
let transformation = [0.4, 0.5, 0.6];
542+
let starting_color = Color::rgba(0.4, 0.5, 0.6, 1.0);
543+
544+
assert_eq!(
545+
starting_color * transformation,
546+
Color::rgba(0.4 * 0.4, 0.5 * 0.5, 0.6 * 0.6, 1.0),
547+
);
548+
549+
let mut mutated_color = starting_color;
550+
mutated_color *= transformation;
551+
552+
assert_eq!(starting_color * transformation, mutated_color,);
553+
}
554+
555+
#[test]
556+
fn test_mul_and_mulassign_f32by4() {
557+
let transformation = [0.4, 0.5, 0.6, 0.9];
558+
let starting_color = Color::rgba(0.4, 0.5, 0.6, 1.0);
559+
560+
assert_eq!(
561+
starting_color * transformation,
562+
Color::rgba(0.4 * 0.4, 0.5 * 0.5, 0.6 * 0.6, 1.0 * 0.9),
563+
);
564+
565+
let mut mutated_color = starting_color;
566+
mutated_color *= transformation;
567+
568+
assert_eq!(starting_color * transformation, mutated_color,);
569+
}
570+
571+
#[test]
572+
fn test_mul_and_mulassign_vec3() {
573+
let transformation = Vec3::new(0.2, 0.3, 0.4);
574+
let starting_color = Color::rgba(0.4, 0.5, 0.6, 1.0);
575+
576+
assert_eq!(
577+
starting_color * transformation,
578+
Color::rgba(0.4 * 0.2, 0.5 * 0.3, 0.6 * 0.4, 1.0),
579+
);
580+
581+
let mut mutated_color = starting_color;
582+
mutated_color *= transformation;
583+
584+
assert_eq!(starting_color * transformation, mutated_color,);
585+
}
586+
587+
#[test]
588+
fn test_mul_and_mulassign_vec4() {
589+
let transformation = Vec4::new(0.2, 0.3, 0.4, 0.5);
590+
let starting_color = Color::rgba(0.4, 0.5, 0.6, 1.0);
591+
592+
assert_eq!(
593+
starting_color * transformation,
594+
Color::rgba(0.4 * 0.2, 0.5 * 0.3, 0.6 * 0.4, 1.0 * 0.5),
595+
);
596+
597+
let mut mutated_color = starting_color;
598+
mutated_color *= transformation;
599+
600+
assert_eq!(starting_color * transformation, mutated_color,);
601+
}

0 commit comments

Comments
 (0)