mirror of
https://github.com/bevyengine/bevy
synced 2024-12-18 17:13:10 +00:00
Add no_std
support to bevy_color
(#16633)
# Objective - Contributes to #15460 ## Solution - Added the following new features: - `std` (default) - `alloc` - `encase` (default) - `libm` ## Testing - Added to `compile-check-no-std` CI command ## Notes - `ColorCurve` requires `alloc` due to how the underlying `EvenCore` type works. - `Srgba::to_hex` requires `alloc` to return a `String`. - This was otherwise a _very_ simple change
This commit is contained in:
parent
4be75305f2
commit
73c6479f65
9 changed files with 48 additions and 15 deletions
|
@ -17,18 +17,26 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
|
||||||
"bevy",
|
"bevy",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
bytemuck = { version = "1", features = ["derive"] }
|
bytemuck = { version = "1", features = ["derive"] }
|
||||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
serde = { version = "1.0", features = [
|
||||||
|
"derive",
|
||||||
|
], default-features = false, optional = true }
|
||||||
derive_more = { version = "1", default-features = false, features = [
|
derive_more = { version = "1", default-features = false, features = [
|
||||||
"error",
|
"error",
|
||||||
"from",
|
"from",
|
||||||
"display",
|
"display",
|
||||||
] }
|
] }
|
||||||
wgpu-types = { version = "23", default-features = false, optional = true }
|
wgpu-types = { version = "23", default-features = false, optional = true }
|
||||||
encase = { version = "0.10", default-features = false }
|
encase = { version = "0.10", default-features = false, optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["bevy_reflect"]
|
default = ["std", "bevy_reflect", "encase"]
|
||||||
|
std = ["alloc", "bevy_math/std", "serde?/std"]
|
||||||
|
alloc = ["bevy_math/alloc", "serde?/alloc"]
|
||||||
serialize = ["serde", "bevy_math/serialize"]
|
serialize = ["serde", "bevy_math/serialize"]
|
||||||
|
bevy_reflect = ["dep:bevy_reflect", "std"]
|
||||||
|
wgpu-types = ["dep:wgpu-types", "std"]
|
||||||
|
encase = ["dep:encase", "std"]
|
||||||
|
libm = ["bevy_math/libm"]
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
//! Module for calculating distance between two colors in the same color space.
|
//! Module for calculating distance between two colors in the same color space.
|
||||||
|
|
||||||
|
use bevy_math::ops;
|
||||||
|
|
||||||
/// Calculate the distance between this and another color as if they were coordinates
|
/// Calculate the distance between this and another color as if they were coordinates
|
||||||
/// in a Euclidean space. Alpha is not considered in the distance calculation.
|
/// in a Euclidean space. Alpha is not considered in the distance calculation.
|
||||||
pub trait EuclideanDistance: Sized {
|
pub trait EuclideanDistance: Sized {
|
||||||
/// Distance from `self` to `other`.
|
/// Distance from `self` to `other`.
|
||||||
fn distance(&self, other: &Self) -> f32 {
|
fn distance(&self, other: &Self) -> f32 {
|
||||||
self.distance_squared(other).sqrt()
|
ops::sqrt(self.distance_squared(other))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Distance squared from `self` to `other`.
|
/// Distance squared from `self` to `other`.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::Mix;
|
use crate::Mix;
|
||||||
|
use alloc::vec::Vec;
|
||||||
use bevy_math::curve::{
|
use bevy_math::curve::{
|
||||||
cores::{EvenCore, EvenCoreError},
|
cores::{EvenCore, EvenCoreError},
|
||||||
Curve, Interval,
|
Curve, Interval,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use bevy_math::{Vec3, Vec4};
|
use bevy_math::{ops, Vec3, Vec4};
|
||||||
|
|
||||||
/// Methods for changing the luminance of a color. Note that these methods are not
|
/// Methods for changing the luminance of a color. Note that these methods are not
|
||||||
/// guaranteed to produce consistent results across color spaces,
|
/// guaranteed to produce consistent results across color spaces,
|
||||||
|
@ -90,7 +90,7 @@ pub trait Hue: Sized {
|
||||||
|
|
||||||
/// Return a new version of this color with the hue channel rotated by the given degrees.
|
/// Return a new version of this color with the hue channel rotated by the given degrees.
|
||||||
fn rotate_hue(&self, degrees: f32) -> Self {
|
fn rotate_hue(&self, degrees: f32) -> Self {
|
||||||
let rotated_hue = (self.hue() + degrees).rem_euclid(360.);
|
let rotated_hue = ops::rem_euclid(self.hue() + degrees, 360.);
|
||||||
self.with_hue(rotated_hue)
|
self.with_hue(rotated_hue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,8 +131,8 @@ pub trait ColorToPacked {
|
||||||
/// takes the shortest path around the color wheel, and that the result is always between
|
/// takes the shortest path around the color wheel, and that the result is always between
|
||||||
/// 0 and 360.
|
/// 0 and 360.
|
||||||
pub(crate) fn lerp_hue(a: f32, b: f32, t: f32) -> f32 {
|
pub(crate) fn lerp_hue(a: f32, b: f32, t: f32) -> f32 {
|
||||||
let diff = (b - a + 180.0).rem_euclid(360.) - 180.;
|
let diff = ops::rem_euclid(b - a + 180.0, 360.) - 180.;
|
||||||
(a + diff * t).rem_euclid(360.0)
|
ops::rem_euclid(a + diff * t, 360.)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
Alpha, ColorToComponents, Gray, Hue, Lcha, LinearRgba, Mix, Srgba, StandardColor, Xyza,
|
Alpha, ColorToComponents, Gray, Hue, Lcha, LinearRgba, Mix, Srgba, StandardColor, Xyza,
|
||||||
};
|
};
|
||||||
use bevy_math::{Vec3, Vec4};
|
use bevy_math::{ops, Vec3, Vec4};
|
||||||
#[cfg(feature = "bevy_reflect")]
|
#[cfg(feature = "bevy_reflect")]
|
||||||
use bevy_reflect::prelude::*;
|
use bevy_reflect::prelude::*;
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ impl From<Hwba> for Srgba {
|
||||||
let v = 1. - blackness;
|
let v = 1. - blackness;
|
||||||
|
|
||||||
let h = (hue % 360.) / 60.;
|
let h = (hue % 360.) / 60.;
|
||||||
let i = h.floor();
|
let i = ops::floor(h);
|
||||||
let f = h - i;
|
let f = h - i;
|
||||||
|
|
||||||
let i = i as u8;
|
let i = i as u8;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
html_logo_url = "https://bevyengine.org/assets/icon.png",
|
html_logo_url = "https://bevyengine.org/assets/icon.png",
|
||||||
html_favicon_url = "https://bevyengine.org/assets/icon.png"
|
html_favicon_url = "https://bevyengine.org/assets/icon.png"
|
||||||
)]
|
)]
|
||||||
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
//! Representations of colors in various color spaces.
|
//! Representations of colors in various color spaces.
|
||||||
//!
|
//!
|
||||||
|
@ -89,8 +90,12 @@
|
||||||
//! println!("Hsla: {:?}", hsla);
|
//! println!("Hsla: {:?}", hsla);
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
mod color;
|
mod color;
|
||||||
pub mod color_difference;
|
pub mod color_difference;
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
mod color_gradient;
|
mod color_gradient;
|
||||||
mod color_ops;
|
mod color_ops;
|
||||||
mod color_range;
|
mod color_range;
|
||||||
|
@ -121,6 +126,7 @@ pub mod prelude {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use color::*;
|
pub use color::*;
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
pub use color_gradient::*;
|
pub use color_gradient::*;
|
||||||
pub use color_ops::*;
|
pub use color_ops::*;
|
||||||
pub use color_range::*;
|
pub use color_range::*;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
|
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
|
||||||
ColorToPacked, Gray, Luminance, Mix, StandardColor,
|
ColorToPacked, Gray, Luminance, Mix, StandardColor,
|
||||||
};
|
};
|
||||||
use bevy_math::{Vec3, Vec4};
|
use bevy_math::{ops, Vec3, Vec4};
|
||||||
#[cfg(feature = "bevy_reflect")]
|
#[cfg(feature = "bevy_reflect")]
|
||||||
use bevy_reflect::prelude::*;
|
use bevy_reflect::prelude::*;
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
@ -302,11 +302,11 @@ impl ColorToComponents for LinearRgba {
|
||||||
impl ColorToPacked for LinearRgba {
|
impl ColorToPacked for LinearRgba {
|
||||||
fn to_u8_array(self) -> [u8; 4] {
|
fn to_u8_array(self) -> [u8; 4] {
|
||||||
[self.red, self.green, self.blue, self.alpha]
|
[self.red, self.green, self.blue, self.alpha]
|
||||||
.map(|v| (v.clamp(0.0, 1.0) * 255.0).round() as u8)
|
.map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_u8_array_no_alpha(self) -> [u8; 3] {
|
fn to_u8_array_no_alpha(self) -> [u8; 3] {
|
||||||
[self.red, self.green, self.blue].map(|v| (v.clamp(0.0, 1.0) * 255.0).round() as u8)
|
[self.red, self.green, self.blue].map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_u8_array(color: [u8; 4]) -> Self {
|
fn from_u8_array(color: [u8; 4]) -> Self {
|
||||||
|
@ -332,6 +332,7 @@ impl From<LinearRgba> for wgpu_types::Color {
|
||||||
|
|
||||||
// [`LinearRgba`] is intended to be used with shaders
|
// [`LinearRgba`] is intended to be used with shaders
|
||||||
// So it's the only color type that implements [`ShaderType`] to make it easier to use inside shaders
|
// So it's the only color type that implements [`ShaderType`] to make it easier to use inside shaders
|
||||||
|
#[cfg(feature = "encase")]
|
||||||
impl encase::ShaderType for LinearRgba {
|
impl encase::ShaderType for LinearRgba {
|
||||||
type ExtraMetadata = ();
|
type ExtraMetadata = ();
|
||||||
|
|
||||||
|
@ -353,6 +354,7 @@ impl encase::ShaderType for LinearRgba {
|
||||||
const UNIFORM_COMPAT_ASSERT: fn() = || {};
|
const UNIFORM_COMPAT_ASSERT: fn() = || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encase")]
|
||||||
impl encase::private::WriteInto for LinearRgba {
|
impl encase::private::WriteInto for LinearRgba {
|
||||||
fn write_into<B: encase::private::BufferMut>(&self, writer: &mut encase::private::Writer<B>) {
|
fn write_into<B: encase::private::BufferMut>(&self, writer: &mut encase::private::Writer<B>) {
|
||||||
for el in &[self.red, self.green, self.blue, self.alpha] {
|
for el in &[self.red, self.green, self.blue, self.alpha] {
|
||||||
|
@ -361,6 +363,7 @@ impl encase::private::WriteInto for LinearRgba {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encase")]
|
||||||
impl encase::private::ReadFrom for LinearRgba {
|
impl encase::private::ReadFrom for LinearRgba {
|
||||||
fn read_from<B: encase::private::BufferRef>(
|
fn read_from<B: encase::private::BufferRef>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -380,6 +383,7 @@ impl encase::private::ReadFrom for LinearRgba {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encase")]
|
||||||
impl encase::private::CreateFrom for LinearRgba {
|
impl encase::private::CreateFrom for LinearRgba {
|
||||||
fn create_from<B>(reader: &mut encase::private::Reader<B>) -> Self
|
fn create_from<B>(reader: &mut encase::private::Reader<B>) -> Self
|
||||||
where
|
where
|
||||||
|
@ -400,6 +404,7 @@ impl encase::private::CreateFrom for LinearRgba {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "encase")]
|
||||||
impl encase::ShaderSize for LinearRgba {}
|
impl encase::ShaderSize for LinearRgba {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -2,6 +2,8 @@ use crate::{
|
||||||
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
|
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
|
||||||
ColorToPacked, Gray, LinearRgba, Luminance, Mix, StandardColor, Xyza,
|
ColorToPacked, Gray, LinearRgba, Luminance, Mix, StandardColor, Xyza,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
use alloc::{format, string::String};
|
||||||
use bevy_math::{ops, Vec3, Vec4};
|
use bevy_math::{ops, Vec3, Vec4};
|
||||||
#[cfg(feature = "bevy_reflect")]
|
#[cfg(feature = "bevy_reflect")]
|
||||||
use bevy_reflect::prelude::*;
|
use bevy_reflect::prelude::*;
|
||||||
|
@ -167,6 +169,7 @@ impl Srgba {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert this color to CSS-style hexadecimal notation.
|
/// Convert this color to CSS-style hexadecimal notation.
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
pub fn to_hex(&self) -> String {
|
pub fn to_hex(&self) -> String {
|
||||||
let [r, g, b, a] = self.to_u8_array();
|
let [r, g, b, a] = self.to_u8_array();
|
||||||
match a {
|
match a {
|
||||||
|
@ -366,11 +369,11 @@ impl ColorToComponents for Srgba {
|
||||||
impl ColorToPacked for Srgba {
|
impl ColorToPacked for Srgba {
|
||||||
fn to_u8_array(self) -> [u8; 4] {
|
fn to_u8_array(self) -> [u8; 4] {
|
||||||
[self.red, self.green, self.blue, self.alpha]
|
[self.red, self.green, self.blue, self.alpha]
|
||||||
.map(|v| (v.clamp(0.0, 1.0) * 255.0).round() as u8)
|
.map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_u8_array_no_alpha(self) -> [u8; 3] {
|
fn to_u8_array_no_alpha(self) -> [u8; 3] {
|
||||||
[self.red, self.green, self.blue].map(|v| (v.clamp(0.0, 1.0) * 255.0).round() as u8)
|
[self.red, self.green, self.blue].map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_u8_array(color: [u8; 4]) -> Self {
|
fn from_u8_array(color: [u8; 4]) -> Self {
|
||||||
|
|
|
@ -86,6 +86,14 @@ impl Prepare for CompileCheckNoStdCommand {
|
||||||
"Please fix compiler errors in output above for bevy_math no_std compatibility.",
|
"Please fix compiler errors in output above for bevy_math no_std compatibility.",
|
||||||
));
|
));
|
||||||
|
|
||||||
|
commands.push(PreparedCommand::new::<Self>(
|
||||||
|
cmd!(
|
||||||
|
sh,
|
||||||
|
"cargo check -p bevy_color --no-default-features --features libm --target {target}"
|
||||||
|
),
|
||||||
|
"Please fix compiler errors in output above for bevy_color no_std compatibility.",
|
||||||
|
));
|
||||||
|
|
||||||
commands
|
commands
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue