use std::fmt;
use cgmath::{EuclideanSpace as _, Point3, Vector3};
use crate::math::{Face6, FreeCoordinate, GridPoint, Rgba};
use crate::util::{ConciseDebug, CustomFormat};
pub type TextureCoordinate = f32;
#[allow(clippy::exhaustive_structs)]
#[derive(Clone, Copy, PartialEq)]
pub struct BlockVertex<T> {
pub position: Point3<FreeCoordinate>,
pub face: Face6,
pub coloring: Coloring<T>,
}
impl<T: Clone> BlockVertex<T> {
#[cfg(test)]
pub(crate) fn remove_clamps(mut self) -> Self {
self.coloring = match self.coloring {
Coloring::Texture {
pos,
clamp_min: _,
clamp_max: _,
} => Coloring::Texture {
clamp_min: pos.clone(),
clamp_max: pos.clone(),
pos,
},
other => other,
};
self
}
}
#[allow(clippy::exhaustive_enums)]
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum Coloring<T> {
Solid(Rgba),
Texture {
pos: T,
clamp_min: T,
clamp_max: T,
},
}
impl<T> fmt::Debug for BlockVertex<T>
where
Coloring<T>: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
fmt,
"{{ p: {:?} n: {:?} c: {:?} }}",
self.position.custom_format(ConciseDebug),
self.face,
self.coloring
)
}
}
impl<T> fmt::Debug for Coloring<T>
where
T: CustomFormat<ConciseDebug>, {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Coloring::Solid(color) => write!(fmt, "Solid({color:?})"),
Coloring::Texture { pos, .. } => {
write!(fmt, "Texture({:?})", pos.custom_format(ConciseDebug))
}
}
}
}
pub trait GfxVertex: From<BlockVertex<Self::TexPoint>> + Copy + Sized {
const WANTS_DEPTH_SORTING: bool;
type Coordinate: cgmath::BaseFloat;
type TexPoint: Copy;
type BlockInst: Copy;
fn instantiate_block(cube: GridPoint) -> Self::BlockInst;
fn instantiate_vertex(&mut self, block: Self::BlockInst);
fn position(&self) -> Point3<Self::Coordinate>;
}
impl<T: Copy> GfxVertex for BlockVertex<T> {
const WANTS_DEPTH_SORTING: bool = true;
type Coordinate = FreeCoordinate;
type TexPoint = T;
type BlockInst = Vector3<FreeCoordinate>;
fn position(&self) -> Point3<FreeCoordinate> {
self.position
}
#[inline]
fn instantiate_block(cube: GridPoint) -> Self::BlockInst {
cube.to_vec().map(FreeCoordinate::from)
}
#[inline]
fn instantiate_vertex(&mut self, offset: Self::BlockInst) {
self.position += offset;
}
}