use crate::{
core::algebra::{Vector2, Vector3, Vector4},
scene::mesh::buffer::{
VertexAttributeDataType, VertexAttributeDescriptor, VertexAttributeUsage, VertexTrait,
},
};
use bytemuck::{Pod, Zeroable};
use std::hash::{Hash, Hasher};
#[derive(Copy, Clone, Debug, Default, Pod, Zeroable)]
#[repr(C)] pub struct StaticVertex {
pub position: Vector3<f32>,
pub tex_coord: Vector2<f32>,
pub normal: Vector3<f32>,
pub tangent: Vector4<f32>,
}
impl StaticVertex {
pub fn from_pos_uv(position: Vector3<f32>, tex_coord: Vector2<f32>) -> Self {
Self {
position,
tex_coord,
normal: Vector3::new(0.0, 1.0, 0.0),
tangent: Vector4::default(),
}
}
pub fn from_pos_uv_normal(
position: Vector3<f32>,
tex_coord: Vector2<f32>,
normal: Vector3<f32>,
) -> Self {
Self {
position,
tex_coord,
normal,
tangent: Vector4::default(),
}
}
}
impl VertexTrait for StaticVertex {
fn layout() -> &'static [VertexAttributeDescriptor] {
static LAYOUT: [VertexAttributeDescriptor; 4] = [
VertexAttributeDescriptor {
usage: VertexAttributeUsage::Position,
data_type: VertexAttributeDataType::F32,
size: 3,
divisor: 0,
shader_location: 0,
normalized: false,
},
VertexAttributeDescriptor {
usage: VertexAttributeUsage::TexCoord0,
data_type: VertexAttributeDataType::F32,
size: 2,
divisor: 0,
shader_location: 1,
normalized: false,
},
VertexAttributeDescriptor {
usage: VertexAttributeUsage::Normal,
data_type: VertexAttributeDataType::F32,
size: 3,
divisor: 0,
shader_location: 2,
normalized: false,
},
VertexAttributeDescriptor {
usage: VertexAttributeUsage::Tangent,
data_type: VertexAttributeDataType::F32,
size: 4,
divisor: 0,
shader_location: 3,
normalized: false,
},
];
&LAYOUT
}
}
impl PartialEq for StaticVertex {
fn eq(&self, other: &Self) -> bool {
self.position == other.position
&& self.tex_coord == other.tex_coord
&& self.normal == other.normal
&& self.tangent == other.tangent
}
}
impl Hash for StaticVertex {
fn hash<H: Hasher>(&self, state: &mut H) {
#[allow(unsafe_code)]
unsafe {
let bytes = self as *const Self as *const u8;
state.write(std::slice::from_raw_parts(
bytes,
std::mem::size_of::<Self>(),
))
}
}
}
#[derive(Copy, Clone, Debug, Default)]
#[repr(C)] pub struct AnimatedVertex {
pub position: Vector3<f32>,
pub tex_coord: Vector2<f32>,
pub normal: Vector3<f32>,
pub tangent: Vector4<f32>,
pub bone_weights: [f32; 4],
pub bone_indices: [u8; 4],
}
impl VertexTrait for AnimatedVertex {
fn layout() -> &'static [VertexAttributeDescriptor] {
&[
VertexAttributeDescriptor {
usage: VertexAttributeUsage::Position,
data_type: VertexAttributeDataType::F32,
size: 3,
divisor: 0,
shader_location: 0,
normalized: false,
},
VertexAttributeDescriptor {
usage: VertexAttributeUsage::TexCoord0,
data_type: VertexAttributeDataType::F32,
size: 2,
divisor: 0,
shader_location: 1,
normalized: false,
},
VertexAttributeDescriptor {
usage: VertexAttributeUsage::Normal,
data_type: VertexAttributeDataType::F32,
size: 3,
divisor: 0,
shader_location: 2,
normalized: false,
},
VertexAttributeDescriptor {
usage: VertexAttributeUsage::Tangent,
data_type: VertexAttributeDataType::F32,
size: 4,
divisor: 0,
shader_location: 3,
normalized: false,
},
VertexAttributeDescriptor {
usage: VertexAttributeUsage::BoneWeight,
data_type: VertexAttributeDataType::F32,
size: 4,
divisor: 0,
shader_location: 4,
normalized: false,
},
VertexAttributeDescriptor {
usage: VertexAttributeUsage::BoneIndices,
data_type: VertexAttributeDataType::U8,
size: 4,
divisor: 0,
shader_location: 5,
normalized: false,
},
]
}
}
impl PartialEq for AnimatedVertex {
fn eq(&self, other: &Self) -> bool {
self.position == other.position
&& self.tex_coord == other.tex_coord
&& self.normal == other.normal
&& self.tangent == other.tangent
&& self.bone_weights == other.bone_weights
&& self.bone_indices == other.bone_indices
}
}
impl Hash for AnimatedVertex {
fn hash<H: Hasher>(&self, state: &mut H) {
#[allow(unsafe_code)]
unsafe {
let bytes = self as *const Self as *const u8;
state.write(std::slice::from_raw_parts(
bytes,
std::mem::size_of::<Self>(),
))
}
}
}
#[derive(Copy, Clone, Debug, Default)]
#[repr(C)] pub struct SimpleVertex {
pub position: Vector3<f32>,
}
impl SimpleVertex {
pub fn new(x: f32, y: f32, z: f32) -> Self {
Self {
position: Vector3::new(x, y, z),
}
}
}
impl VertexTrait for SimpleVertex {
fn layout() -> &'static [VertexAttributeDescriptor] {
&[VertexAttributeDescriptor {
usage: VertexAttributeUsage::Position,
data_type: VertexAttributeDataType::F32,
size: 3,
divisor: 0,
shader_location: 0,
normalized: false,
}]
}
}
impl PartialEq for SimpleVertex {
fn eq(&self, other: &Self) -> bool {
self.position == other.position
}
}
impl Hash for SimpleVertex {
fn hash<H: Hasher>(&self, state: &mut H) {
#[allow(unsafe_code)]
unsafe {
let bytes = self as *const Self as *const u8;
state.write(std::slice::from_raw_parts(
bytes,
std::mem::size_of::<Self>(),
))
}
}
}