use crate::vertex::private::Format;
pub unsafe trait Vertex {
type Position: Component;
type Color: Component3D;
type Texture: Component2D;
}
pub(crate) fn verts_as_bytes<V>(verts: &[V]) -> &[u8]
where
V: Vertex,
{
use std::{mem, slice};
unsafe { slice::from_raw_parts(verts.as_ptr().cast(), mem::size_of_val(verts)) }
}
pub(crate) struct VertexInfo {
pub dimensions: u64,
pub has_color: bool,
pub has_texture: bool,
}
impl VertexInfo {
pub const fn new<V>() -> Self
where
V: Vertex,
{
Self {
dimensions: V::Position::N_FLOATS,
has_color: V::Color::OPTIONAL_N_FLOATS.is_some(),
has_texture: V::Texture::OPTIONAL_N_FLOATS.is_some(),
}
}
}
pub trait Component: private::Component {
const N_FLOATS: u64;
}
impl<C> Component for C
where
C: private::Component,
{
const N_FLOATS: u64 = C::Format::N_FLOATS;
}
pub trait Component2D: private::OptionalComponent {
const OPTIONAL_N_FLOATS: Option<u64>;
}
impl<C> Component2D for C
where
C: Component<Format = private::FormatFloatX2>,
{
const OPTIONAL_N_FLOATS: Option<u64> = Some(C::Format::N_FLOATS);
}
impl Component2D for () {
const OPTIONAL_N_FLOATS: Option<u64> = None;
}
pub trait Component3D: private::OptionalComponent {
const OPTIONAL_N_FLOATS: Option<u64>;
}
impl<C> Component3D for C
where
C: Component<Format = private::FormatFloatX3>,
{
const OPTIONAL_N_FLOATS: Option<u64> = Some(C::Format::N_FLOATS);
}
impl Component3D for () {
const OPTIONAL_N_FLOATS: Option<u64> = None;
}
mod private {
use glam::{Vec2, Vec3};
pub trait Format {
const N_FLOATS: u64;
}
pub struct FormatFloatX2;
impl Format for FormatFloatX2 {
const N_FLOATS: u64 = 2;
}
pub struct FormatFloatX3;
impl Format for FormatFloatX3 {
const N_FLOATS: u64 = 3;
}
pub trait Component {
type Format: Format;
}
impl Component for (f32, f32) {
type Format = FormatFloatX2;
}
impl Component for (f32, f32, f32) {
type Format = FormatFloatX3;
}
impl Component for [f32; 2] {
type Format = FormatFloatX2;
}
impl Component for [f32; 3] {
type Format = FormatFloatX3;
}
impl Component for Vec2 {
type Format = FormatFloatX2;
}
impl Component for Vec3 {
type Format = FormatFloatX3;
}
pub trait OptionalComponent {}
impl<C> OptionalComponent for C where C: Component {}
impl OptionalComponent for () {}
}