2023-12-13 17:23:53 -05:00
|
|
|
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
2024-02-25 09:01:59 -05:00
|
|
|
use crate::model::NUM_VERTICES;
|
2025-03-06 18:52:26 -05:00
|
|
|
use binrw::{BinRead, BinResult, BinWrite, binrw};
|
2024-04-20 13:18:03 -04:00
|
|
|
use std::io::SeekFrom;
|
2023-12-13 17:23:53 -05:00
|
|
|
|
2024-04-14 13:46:10 -04:00
|
|
|
/// Marker for end of stream (0xFF)
|
2023-12-13 17:23:53 -05:00
|
|
|
const END_OF_STREAM: u8 = 0xFF;
|
|
|
|
|
2024-04-14 13:46:10 -04:00
|
|
|
/// The format of the vertex stream.
|
2023-12-13 17:23:53 -05:00
|
|
|
#[binrw]
|
|
|
|
#[brw(repr = u8)]
|
2024-11-03 11:27:57 -05:00
|
|
|
#[repr(u8)]
|
2023-12-13 17:23:53 -05:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
|
|
pub enum VertexType {
|
2024-04-17 20:44:12 -04:00
|
|
|
/// 1 32-bit float
|
2024-02-25 08:54:16 -05:00
|
|
|
Single1 = 0,
|
2024-04-17 20:44:12 -04:00
|
|
|
/// 2 32-bit floats
|
2024-02-25 08:54:16 -05:00
|
|
|
Single2 = 1,
|
2024-04-17 20:44:12 -04:00
|
|
|
/// 3 32-bit floats
|
2023-12-13 17:23:53 -05:00
|
|
|
Single3 = 2,
|
2024-04-17 20:44:12 -04:00
|
|
|
/// 4 32-bit floats
|
2023-12-13 17:23:53 -05:00
|
|
|
Single4 = 3,
|
2024-04-17 20:44:12 -04:00
|
|
|
|
|
|
|
/// 4 bytes
|
2024-02-25 08:54:16 -05:00
|
|
|
Byte4 = 5,
|
2024-04-17 20:44:12 -04:00
|
|
|
|
|
|
|
/// 2 16-bit signed integers
|
|
|
|
Short2 = 6,
|
|
|
|
/// 4 16-bit signed integers
|
|
|
|
Short4 = 7,
|
|
|
|
|
|
|
|
/// 4 8-bit floats
|
2023-12-13 17:23:53 -05:00
|
|
|
ByteFloat4 = 8,
|
2024-04-17 20:44:12 -04:00
|
|
|
|
|
|
|
/// Duplicate of Short2?
|
|
|
|
Short2n = 9,
|
|
|
|
/// Duplicate of Short4?
|
|
|
|
Short4n = 10,
|
|
|
|
|
|
|
|
/// 2 16-bit floats
|
2023-12-13 17:23:53 -05:00
|
|
|
Half2 = 13,
|
2024-04-17 20:44:12 -04:00
|
|
|
/// 4 16-bit floats
|
2023-12-13 17:23:53 -05:00
|
|
|
Half4 = 14,
|
2024-04-14 13:22:47 -04:00
|
|
|
|
2024-04-17 20:44:12 -04:00
|
|
|
/// 2 16-bit unsigned integers
|
|
|
|
UnsignedShort2 = 16,
|
|
|
|
/// 4 16-bit unsigned integers
|
2024-04-20 13:18:03 -04:00
|
|
|
UnsignedShort4 = 17,
|
2023-12-13 17:23:53 -05:00
|
|
|
}
|
|
|
|
|
2024-11-03 11:00:33 -05:00
|
|
|
/// In bytes
|
|
|
|
pub fn get_vertex_type_size(vertex_type: VertexType) -> usize {
|
|
|
|
// TODO: Most of these are wrong
|
|
|
|
match vertex_type {
|
|
|
|
VertexType::Single1 => 4,
|
|
|
|
VertexType::Single2 => 8,
|
|
|
|
VertexType::Single3 => 12,
|
|
|
|
VertexType::Single4 => 16,
|
|
|
|
VertexType::Byte4 => 4,
|
|
|
|
VertexType::Short2 => 4,
|
|
|
|
VertexType::Short4 => 8,
|
|
|
|
VertexType::ByteFloat4 => 4,
|
|
|
|
VertexType::Short2n => 4,
|
|
|
|
VertexType::Short4n => 4,
|
|
|
|
VertexType::Half2 => 4,
|
|
|
|
VertexType::Half4 => 8,
|
|
|
|
VertexType::UnsignedShort2 => 4,
|
|
|
|
VertexType::UnsignedShort4 => 8,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-14 13:46:10 -04:00
|
|
|
/// What the vertex stream is used for.
|
2023-12-13 17:23:53 -05:00
|
|
|
#[binrw]
|
|
|
|
#[brw(repr = u8)]
|
2024-11-03 11:27:57 -05:00
|
|
|
#[repr(u8)]
|
2024-02-25 10:25:54 -05:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
2023-12-13 17:23:53 -05:00
|
|
|
pub enum VertexUsage {
|
|
|
|
Position = 0,
|
|
|
|
BlendWeights = 1,
|
|
|
|
BlendIndices = 2,
|
|
|
|
Normal = 3,
|
|
|
|
UV = 4,
|
2023-12-17 18:58:48 -05:00
|
|
|
Tangent = 5,
|
|
|
|
BiTangent = 6,
|
2023-12-13 17:23:53 -05:00
|
|
|
Color = 7,
|
|
|
|
}
|
|
|
|
|
2024-04-14 13:46:10 -04:00
|
|
|
/// Represents an element within a bigger vertex stream.
|
2023-12-13 17:23:53 -05:00
|
|
|
#[binrw]
|
2024-02-25 10:25:54 -05:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
2023-12-13 17:23:53 -05:00
|
|
|
#[allow(dead_code)]
|
2024-11-03 11:00:33 -05:00
|
|
|
#[repr(C)]
|
2023-12-13 17:23:53 -05:00
|
|
|
#[brw(little)]
|
|
|
|
pub struct VertexElement {
|
|
|
|
pub stream: u8,
|
|
|
|
pub offset: u8,
|
|
|
|
pub vertex_type: VertexType,
|
|
|
|
pub vertex_usage: VertexUsage,
|
|
|
|
#[brw(pad_after = 3)]
|
|
|
|
pub usage_index: u8,
|
|
|
|
}
|
|
|
|
|
2024-04-20 13:18:03 -04:00
|
|
|
/// Represents the true size of VertexElement. Always use this value instead of std::mem::size_of.
|
2024-04-14 13:46:10 -04:00
|
|
|
// 3 extra bytes to account for the padding that doesn't appear in the struct itself
|
2024-02-25 08:41:03 -05:00
|
|
|
pub const VERTEX_ELEMENT_SIZE: usize = std::mem::size_of::<VertexElement>() + 3;
|
|
|
|
|
2024-02-25 10:25:54 -05:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
2023-12-13 17:23:53 -05:00
|
|
|
pub struct VertexDeclaration {
|
|
|
|
pub elements: Vec<VertexElement>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[binrw::parser(reader, endian)]
|
|
|
|
pub(crate) fn vertex_element_parser(count: u16) -> BinResult<Vec<VertexDeclaration>> {
|
|
|
|
let mut vertex_declarations: Vec<VertexDeclaration> =
|
2024-04-20 13:18:03 -04:00
|
|
|
vec![VertexDeclaration { elements: vec![] }; count.into()];
|
2023-12-13 17:23:53 -05:00
|
|
|
for declaration in &mut vertex_declarations {
|
2024-04-16 22:05:39 -04:00
|
|
|
let mut element = VertexElement::read_options(reader, endian, ())?;
|
2023-12-13 17:23:53 -05:00
|
|
|
|
|
|
|
loop {
|
|
|
|
declaration.elements.push(element);
|
|
|
|
|
|
|
|
element = VertexElement::read_options(reader, endian, ())?;
|
|
|
|
|
|
|
|
if element.stream == END_OF_STREAM {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-25 09:01:59 -05:00
|
|
|
let to_seek = NUM_VERTICES as usize * 8 - (declaration.elements.len() + 1) * 8;
|
2023-12-13 17:23:53 -05:00
|
|
|
reader.seek(SeekFrom::Current(to_seek as i64))?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(vertex_declarations)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[binrw::writer(writer, endian)]
|
2024-04-20 13:18:03 -04:00
|
|
|
pub(crate) fn vertex_element_writer(declarations: &Vec<VertexDeclaration>) -> BinResult<()> {
|
2023-12-13 17:23:53 -05:00
|
|
|
// write vertex declarations
|
|
|
|
for declaration in declarations {
|
|
|
|
for element in &declaration.elements {
|
|
|
|
element.write_options(writer, endian, ())?;
|
|
|
|
}
|
|
|
|
|
2024-02-25 09:01:59 -05:00
|
|
|
VertexElement {
|
|
|
|
stream: END_OF_STREAM,
|
|
|
|
offset: 0,
|
|
|
|
vertex_type: VertexType::Single1,
|
|
|
|
vertex_usage: VertexUsage::Position,
|
2024-04-20 13:18:03 -04:00
|
|
|
usage_index: 0,
|
|
|
|
}
|
|
|
|
.write_options(writer, endian, ())?;
|
2023-12-13 17:23:53 -05:00
|
|
|
|
2024-02-25 09:01:59 -05:00
|
|
|
let to_seek = (NUM_VERTICES as usize - 1 - declaration.elements.len()) * 8;
|
2023-12-13 17:23:53 -05:00
|
|
|
writer.seek(SeekFrom::Current(to_seek as i64))?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|