#![allow(dead_code)]
use std::collections::HashMap;
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct VertexColor {
pub r: f32,
pub g: f32,
pub b: f32,
pub a: f32,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct VertexColorMap {
pub colors: HashMap<usize, VertexColor>,
}
#[allow(dead_code)]
pub fn new_vertex_color_map() -> VertexColorMap {
VertexColorMap {
colors: HashMap::new(),
}
}
#[allow(dead_code)]
pub fn set_vertex_color(map: &mut VertexColorMap, index: usize, color: VertexColor) {
map.colors.insert(index, color);
}
#[allow(dead_code)]
pub fn get_vertex_color(map: &VertexColorMap, index: usize) -> VertexColor {
map.colors.get(&index).copied().unwrap_or(VertexColor {
r: 1.0,
g: 1.0,
b: 1.0,
a: 1.0,
})
}
#[allow(dead_code)]
pub fn blend_vertex_colors(a: &VertexColor, b: &VertexColor, factor: f32) -> VertexColor {
let f = factor.clamp(0.0, 1.0);
VertexColor {
r: a.r + (b.r - a.r) * f,
g: a.g + (b.g - a.g) * f,
b: a.b + (b.b - a.b) * f,
a: a.a + (b.a - a.a) * f,
}
}
#[allow(dead_code)]
pub fn vertex_color_count(map: &VertexColorMap) -> usize {
map.colors.len()
}
#[allow(dead_code)]
pub fn clear_vertex_colors(map: &mut VertexColorMap) {
map.colors.clear();
}
#[allow(dead_code)]
pub fn color_to_rgba(c: &VertexColor) -> [u8; 4] {
[
(c.r.clamp(0.0, 1.0) * 255.0) as u8,
(c.g.clamp(0.0, 1.0) * 255.0) as u8,
(c.b.clamp(0.0, 1.0) * 255.0) as u8,
(c.a.clamp(0.0, 1.0) * 255.0) as u8,
]
}
#[allow(dead_code)]
pub fn vertex_colors_to_bytes(map: &VertexColorMap) -> Vec<u8> {
let mut indices: Vec<usize> = map.colors.keys().copied().collect();
indices.sort_unstable();
let mut bytes = Vec::with_capacity(indices.len() * 4);
for idx in indices {
let c = map.colors[&idx];
let rgba = color_to_rgba(&c);
bytes.extend_from_slice(&rgba);
}
bytes
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_map_empty() {
let m = new_vertex_color_map();
assert_eq!(vertex_color_count(&m), 0);
}
#[test]
fn test_set_get_color() {
let mut m = new_vertex_color_map();
let c = VertexColor {
r: 1.0,
g: 0.0,
b: 0.0,
a: 1.0,
};
set_vertex_color(&mut m, 0, c);
let got = get_vertex_color(&m, 0);
assert!((got.r - 1.0).abs() < 1e-6);
assert!((got.g - 0.0).abs() < 1e-6);
}
#[test]
fn test_get_default_color() {
let m = new_vertex_color_map();
let c = get_vertex_color(&m, 99);
assert!((c.r - 1.0).abs() < 1e-6);
}
#[test]
fn test_blend_colors() {
let a = VertexColor {
r: 0.0,
g: 0.0,
b: 0.0,
a: 1.0,
};
let b = VertexColor {
r: 1.0,
g: 1.0,
b: 1.0,
a: 1.0,
};
let mid = blend_vertex_colors(&a, &b, 0.5);
assert!((mid.r - 0.5).abs() < 1e-6);
}
#[test]
fn test_color_count() {
let mut m = new_vertex_color_map();
set_vertex_color(
&mut m,
0,
VertexColor {
r: 1.0,
g: 0.0,
b: 0.0,
a: 1.0,
},
);
set_vertex_color(
&mut m,
1,
VertexColor {
r: 0.0,
g: 1.0,
b: 0.0,
a: 1.0,
},
);
assert_eq!(vertex_color_count(&m), 2);
}
#[test]
fn test_clear_colors() {
let mut m = new_vertex_color_map();
set_vertex_color(
&mut m,
0,
VertexColor {
r: 1.0,
g: 0.0,
b: 0.0,
a: 1.0,
},
);
clear_vertex_colors(&mut m);
assert_eq!(vertex_color_count(&m), 0);
}
#[test]
fn test_color_to_rgba() {
let c = VertexColor {
r: 1.0,
g: 0.5,
b: 0.0,
a: 1.0,
};
let rgba = color_to_rgba(&c);
assert_eq!(rgba[0], 255);
assert!((rgba[1] as f32 - 127.5).abs() < 1.5);
assert_eq!(rgba[2], 0);
assert_eq!(rgba[3], 255);
}
#[test]
fn test_vertex_colors_to_bytes() {
let mut m = new_vertex_color_map();
set_vertex_color(
&mut m,
0,
VertexColor {
r: 1.0,
g: 0.0,
b: 0.0,
a: 1.0,
},
);
let bytes = vertex_colors_to_bytes(&m);
assert_eq!(bytes.len(), 4);
assert_eq!(bytes[0], 255);
}
#[test]
fn test_blend_clamp() {
let a = VertexColor {
r: 0.0,
g: 0.0,
b: 0.0,
a: 0.0,
};
let b = VertexColor {
r: 1.0,
g: 1.0,
b: 1.0,
a: 1.0,
};
let out = blend_vertex_colors(&a, &b, 2.0);
assert!((out.r - 1.0).abs() < 1e-6);
}
#[test]
fn test_overwrite_color() {
let mut m = new_vertex_color_map();
set_vertex_color(
&mut m,
0,
VertexColor {
r: 1.0,
g: 0.0,
b: 0.0,
a: 1.0,
},
);
set_vertex_color(
&mut m,
0,
VertexColor {
r: 0.0,
g: 1.0,
b: 0.0,
a: 1.0,
},
);
let c = get_vertex_color(&m, 0);
assert!((c.g - 1.0).abs() < 1e-6);
assert_eq!(vertex_color_count(&m), 1);
}
}