#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
pub a: u8,
}
impl Color {
pub const fn new(r: u8, g: u8, b: u8) -> Self {
Self { r, g, b, a: 255 }
}
pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
Self { r, g, b, a }
}
pub const RED: Self = Self::new(255, 0, 0);
pub const GREEN: Self = Self::new(0, 255, 0);
pub const BLUE: Self = Self::new(0, 0, 255);
pub const WHITE: Self = Self::new(255, 255, 255);
pub const BLACK: Self = Self::new(0, 0, 0);
pub const YELLOW: Self = Self::new(255, 255, 0);
pub const CYAN: Self = Self::new(0, 255, 255);
pub const MAGENTA: Self = Self::new(255, 0, 255);
pub const ORANGE: Self = Self::new(255, 165, 0);
pub const PURPLE: Self = Self::new(128, 0, 128);
pub const GRAY: Self = Self::new(128, 128, 128);
}
impl From<(u8, u8, u8)> for Color {
fn from((r, g, b): (u8, u8, u8)) -> Self {
Self::new(r, g, b)
}
}
impl From<(u8, u8, u8, u8)> for Color {
fn from((r, g, b, a): (u8, u8, u8, u8)) -> Self {
Self::rgba(r, g, b, a)
}
}
impl From<Color> for carla_sys::carla_rust::sensor::data::FfiColor {
fn from(color: Color) -> Self {
Self {
r: color.r,
g: color.g,
b: color.b,
a: color.a,
}
}
}
impl From<carla_sys::carla_rust::sensor::data::FfiColor> for Color {
fn from(ffi: carla_sys::carla_rust::sensor::data::FfiColor) -> Self {
Self {
r: ffi.r,
g: ffi.g,
b: ffi.b,
a: ffi.a,
}
}
}
#[cfg(carla_0100)]
#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(C)]
pub struct FloatColor {
pub r: f32,
pub g: f32,
pub b: f32,
pub a: f32,
}
#[cfg(carla_0100)]
impl FloatColor {
pub const fn new(r: f32, g: f32, b: f32) -> Self {
Self { r, g, b, a: 1.0 }
}
pub const fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
Self { r, g, b, a }
}
}
#[cfg(carla_0100)]
impl From<Color> for FloatColor {
fn from(c: Color) -> Self {
Self {
r: c.r as f32 / 255.0,
g: c.g as f32 / 255.0,
b: c.b as f32 / 255.0,
a: c.a as f32 / 255.0,
}
}
}
#[cfg(carla_0100)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MaterialParameter {
TexNormal,
TexAoRoughnessMetallicEmissive,
TexDiffuse,
TexEmissive,
}
#[cfg(carla_0100)]
impl MaterialParameter {
pub(crate) fn as_u8(self) -> u8 {
match self {
Self::TexNormal => 0,
Self::TexAoRoughnessMetallicEmissive => 1,
Self::TexDiffuse => 2,
Self::TexEmissive => 3,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_color_creation() {
let color = Color::new(100, 150, 200);
assert_eq!(color.r, 100);
assert_eq!(color.g, 150);
assert_eq!(color.b, 200);
assert_eq!(color.a, 255);
}
#[test]
fn test_color_rgba() {
let color = Color::rgba(10, 20, 30, 40);
assert_eq!(color.r, 10);
assert_eq!(color.g, 20);
assert_eq!(color.b, 30);
assert_eq!(color.a, 40);
}
#[test]
fn test_color_constants() {
assert_eq!(Color::RED, Color::new(255, 0, 0));
assert_eq!(Color::GREEN, Color::new(0, 255, 0));
assert_eq!(Color::BLUE, Color::new(0, 0, 255));
assert_eq!(Color::WHITE, Color::new(255, 255, 255));
assert_eq!(Color::BLACK, Color::new(0, 0, 0));
assert_eq!(Color::YELLOW, Color::new(255, 255, 0));
}
#[test]
fn test_from_rgb_tuple() {
let color: Color = (100, 150, 200).into();
assert_eq!(color.r, 100);
assert_eq!(color.g, 150);
assert_eq!(color.b, 200);
assert_eq!(color.a, 255);
}
#[test]
fn test_from_rgba_tuple() {
let color: Color = (10, 20, 30, 40).into();
assert_eq!(color.r, 10);
assert_eq!(color.g, 20);
assert_eq!(color.b, 30);
assert_eq!(color.a, 40);
}
}