#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub type Vec3 = [f32; 3];
pub type Vec4 = [f32; 4];
pub type Mat3 = [f32; 9];
pub type Mat4 = [f32; 16];
pub type Quat = [f32; 4];
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum BufferElementType {
Float32,
Float16,
SInt8,
SInt16,
SInt32,
UInt8,
UInt16,
UInt32,
}
impl BufferElementType {
pub const fn float16() -> Self {
Self::Float16
}
pub const fn float32() -> Self {
Self::Float32
}
pub const fn new_int(signed: bool, bits: usize) -> Self {
match bits {
8 => {
if signed {
Self::SInt8
} else {
Self::UInt8
}
}
16 => {
if signed {
Self::SInt16
} else {
Self::UInt16
}
}
32 => {
if signed {
Self::SInt32
} else {
Self::UInt32
}
}
_ => {
panic!("An int value must be 8, 16 or 32 bits");
}
}
}
pub fn byte_length(self) -> u32 {
use BufferElementType::*;
match self {
Float32 => 4,
Float16 => 2,
SInt8 => 1,
SInt16 => 2,
SInt32 => 4,
UInt8 => 1,
UInt16 => 2,
UInt32 => 4,
}
}
}
#[derive(Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct VertexDesc {
attr: VertexAttr,
byte_offset: u16,
dims: [u8; 2],
ele_type: BufferElementType,
}
impl std::fmt::Debug for VertexDesc {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
if self.dims[0] == 0 {
write!(
fmt,
"VertexDesc{{{:?}: {:?} @ {}}}",
self.attr, self.ele_type, self.byte_offset
)
} else if self.dims[1] == 0 {
write!(
fmt,
"VertexDesc{{{:?}: {:?}[{}] @ {}}}",
self.attr, self.ele_type, self.dims[0], self.byte_offset
)
} else {
write!(
fmt,
"VertexDesc{{{:?}: {:?}[{}, {}] @ {}}}",
self.attr, self.ele_type, self.dims[0], self.dims[1], self.byte_offset
)
}
}
}
impl VertexDesc {
pub fn scalar(attr: VertexAttr, ele_type: BufferElementType, byte_offset: u16) -> Self {
Self {
attr,
byte_offset,
dims: [0, 0],
ele_type,
}
}
pub fn vec(attr: VertexAttr, ele_type: BufferElementType, len: u8, byte_offset: u16) -> Self {
Self {
attr,
byte_offset,
dims: [len, 0],
ele_type,
}
}
pub fn mat(
attr: VertexAttr,
ele_type: BufferElementType,
dims: [u8; 2],
byte_offset: u16,
) -> Self {
Self {
attr,
byte_offset,
dims,
ele_type,
}
}
pub fn new(
attr: VertexAttr,
ele_type: BufferElementType,
dims: [u8; 2],
byte_offset: u16,
) -> Self {
Self {
attr,
byte_offset,
dims,
ele_type,
}
}
#[inline]
pub fn vertex_attr(&self) -> VertexAttr {
self.attr
}
#[inline]
pub fn byte_offset(&self) -> u16 {
self.byte_offset
}
#[inline]
pub fn dims(&self) -> [u8; 2] {
self.dims
}
#[inline]
pub fn ele_type(&self) -> BufferElementType {
self.ele_type
}
#[inline]
pub fn count(&self) -> u32 {
if self.dims[0] == 0 {
1
} else if self.dims[1] == 0 {
self.dims[0] as u32
} else {
(self.dims[0] as u32) * (self.dims[1] as u32)
}
}
pub fn byte_length(&self) -> u32 {
self.count() * self.ele_type.byte_length()
}
}
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum VertexAttr {
Position,
Normal,
Color,
Tangent,
Joints,
Weights,
TexCoords0,
TexCoords1,
TexCoords2,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum PrimitiveType {
Points,
Lines,
LineLoop,
LineStrip,
#[default]
Triangles,
TriangleStrip,
TriangleFan,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MaterialAspect {
Color,
Normal,
MetallicRoughness,
Occlusion,
Emission,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ShortIndex(u16);
impl std::default::Default for ShortIndex {
fn default() -> Self {
Self(65535)
}
}
impl ShortIndex {
#[inline]
pub fn none() -> Self {
Default::default()
}
#[inline]
pub fn as_usize(self) -> usize {
assert!(self.0 != 65535);
self.0 as usize
}
#[inline]
pub fn is_none(self) -> bool {
self.0 == 65535
}
#[inline]
pub fn is_some(self) -> bool {
self.0 != 65535
}
}
impl From<usize> for ShortIndex {
fn from(index: usize) -> Self {
assert!(index < 65535);
Self(index as u16)
}
}
impl From<ShortIndex> for Option<usize> {
fn from(index: ShortIndex) -> Option<usize> {
if index.is_none() {
None
} else {
Some(index.as_usize())
}
}
}
impl<I: Into<usize>> From<Option<I>> for ShortIndex {
fn from(opt_index: Option<I>) -> Self {
if let Some(index) = opt_index {
let index: usize = index.into();
assert!(index < 65535);
Self(index as u16)
} else {
Self(65535_u16)
}
}
}