use crate::moc3::{Moc3DrawableMesh, Moc3DrawableVertex};
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct DrawableVertex {
position: [f32; 2],
uv: [f32; 2],
opacity: f32,
multiply: [f32; 3],
screen: [f32; 3],
}
impl DrawableVertex {
pub const STRIDE: usize = 44;
pub fn new(position: [f32; 2], uv: [f32; 2], opacity: f32) -> Self {
Self::with_colors(position, uv, opacity, [1.0, 1.0, 1.0], [0.0, 0.0, 0.0])
}
pub fn with_colors(
position: [f32; 2],
uv: [f32; 2],
opacity: f32,
multiply: [f32; 3],
screen: [f32; 3],
) -> Self {
Self {
position,
uv,
opacity,
multiply,
screen,
}
}
pub fn position(&self) -> [f32; 2] {
self.position
}
pub fn uv(&self) -> [f32; 2] {
self.uv
}
pub fn opacity(&self) -> f32 {
self.opacity
}
pub fn multiply(&self) -> [f32; 3] {
self.multiply
}
pub fn screen(&self) -> [f32; 3] {
self.screen
}
}
pub fn vertices_from_drawable(mesh: &Moc3DrawableMesh) -> Vec<DrawableVertex> {
mesh.vertices()
.iter()
.map(|vertex| {
vertex_from_drawable_vertex(
vertex,
mesh.opacity(),
mesh.multiply_color(),
mesh.screen_color(),
)
})
.collect()
}
pub fn encode_vertices_from_drawable(mesh: &Moc3DrawableMesh, bytes: &mut Vec<u8>) {
let byte_len = mesh.vertices().len() * DrawableVertex::STRIDE;
bytes.clear();
bytes.resize(byte_len, 0);
let opacity = mesh.opacity();
let multiply = mesh.multiply_color();
let screen = mesh.screen_color();
for (index, vertex) in mesh.vertices().iter().enumerate() {
encode_vertex_into(
vertex.position(),
vertex.uv(),
opacity,
multiply,
screen,
&mut bytes[index * DrawableVertex::STRIDE..][..DrawableVertex::STRIDE],
);
}
}
pub fn vertex_from_drawable_vertex(
vertex: &Moc3DrawableVertex,
opacity: f32,
multiply: [f32; 3],
screen: [f32; 3],
) -> DrawableVertex {
DrawableVertex::with_colors(vertex.position(), vertex.uv(), opacity, multiply, screen)
}
pub fn encode_vertices(vertices: &[DrawableVertex]) -> Vec<u8> {
let mut bytes = vec![0; vertices.len() * DrawableVertex::STRIDE];
for (index, vertex) in vertices.iter().enumerate() {
encode_vertex_into(
vertex.position,
vertex.uv,
vertex.opacity,
vertex.multiply,
vertex.screen,
&mut bytes[index * DrawableVertex::STRIDE..][..DrawableVertex::STRIDE],
);
}
bytes
}
fn encode_vertex_into(
position: [f32; 2],
uv: [f32; 2],
opacity: f32,
multiply: [f32; 3],
screen: [f32; 3],
bytes: &mut [u8],
) {
write_f32(bytes, 0, position[0]);
write_f32(bytes, 4, position[1]);
write_f32(bytes, 8, uv[0]);
write_f32(bytes, 12, uv[1]);
write_f32(bytes, 16, opacity);
write_f32(bytes, 20, multiply[0]);
write_f32(bytes, 24, multiply[1]);
write_f32(bytes, 28, multiply[2]);
write_f32(bytes, 32, screen[0]);
write_f32(bytes, 36, screen[1]);
write_f32(bytes, 40, screen[2]);
}
pub fn encode_indices(indices: &[u16]) -> Vec<u8> {
let mut bytes = vec![0; indices.len() * 2];
for (chunk, index) in bytes.chunks_exact_mut(2).zip(indices) {
chunk.copy_from_slice(&index.to_ne_bytes());
}
bytes
}
fn write_f32(bytes: &mut [u8], offset: usize, value: f32) {
bytes[offset..offset + 4].copy_from_slice(&value.to_ne_bytes());
}