physis/
model_vertex_declarations.rs1use crate::model::NUM_VERTICES;
5use binrw::{BinRead, BinResult, BinWrite, binrw};
6use std::io::SeekFrom;
7
8const END_OF_STREAM: u8 = 0xFF;
10
11#[binrw]
13#[brw(repr = u8)]
14#[repr(u8)]
15#[derive(Copy, Clone, Debug, PartialEq)]
16pub enum VertexType {
17 Single1 = 0,
19 Single2 = 1,
21 Single3 = 2,
23 Single4 = 3,
25
26 Byte4 = 5,
28
29 Short2 = 6,
31 Short4 = 7,
33
34 ByteFloat4 = 8,
36
37 Short2n = 9,
39 Short4n = 10,
41
42 Half2 = 13,
44 Half4 = 14,
46
47 UnsignedShort2 = 16,
49 UnsignedShort4 = 17,
51}
52
53pub fn get_vertex_type_size(vertex_type: VertexType) -> usize {
55 match vertex_type {
57 VertexType::Single1 => 4,
58 VertexType::Single2 => 8,
59 VertexType::Single3 => 12,
60 VertexType::Single4 => 16,
61 VertexType::Byte4 => 4,
62 VertexType::Short2 => 4,
63 VertexType::Short4 => 8,
64 VertexType::ByteFloat4 => 4,
65 VertexType::Short2n => 4,
66 VertexType::Short4n => 4,
67 VertexType::Half2 => 4,
68 VertexType::Half4 => 8,
69 VertexType::UnsignedShort2 => 4,
70 VertexType::UnsignedShort4 => 8,
71 }
72}
73
74#[binrw]
76#[brw(repr = u8)]
77#[repr(u8)]
78#[derive(Copy, Clone, Debug, PartialEq)]
79pub enum VertexUsage {
80 Position = 0,
81 BlendWeights = 1,
82 BlendIndices = 2,
83 Normal = 3,
84 UV = 4,
85 Tangent = 5,
86 BiTangent = 6,
87 Color = 7,
88}
89
90#[binrw]
92#[derive(Copy, Clone, Debug, PartialEq)]
93#[allow(dead_code)]
94#[repr(C)]
95#[brw(little)]
96pub struct VertexElement {
97 pub stream: u8,
98 pub offset: u8,
99 pub vertex_type: VertexType,
100 pub vertex_usage: VertexUsage,
101 #[brw(pad_after = 3)]
102 pub usage_index: u8,
103}
104
105pub const VERTEX_ELEMENT_SIZE: usize = std::mem::size_of::<VertexElement>() + 3;
108
109#[derive(Clone, Debug, PartialEq)]
110pub struct VertexDeclaration {
111 pub elements: Vec<VertexElement>,
112}
113
114#[binrw::parser(reader, endian)]
115pub(crate) fn vertex_element_parser(count: u16) -> BinResult<Vec<VertexDeclaration>> {
116 let mut vertex_declarations: Vec<VertexDeclaration> =
117 vec![VertexDeclaration { elements: vec![] }; count.into()];
118 for declaration in &mut vertex_declarations {
119 let mut element = VertexElement::read_options(reader, endian, ())?;
120
121 loop {
122 declaration.elements.push(element);
123
124 element = VertexElement::read_options(reader, endian, ())?;
125
126 if element.stream == END_OF_STREAM {
127 break;
128 }
129 }
130
131 let to_seek = NUM_VERTICES as usize * 8 - (declaration.elements.len() + 1) * 8;
132 reader.seek(SeekFrom::Current(to_seek as i64))?;
133 }
134
135 Ok(vertex_declarations)
136}
137
138#[binrw::writer(writer, endian)]
139pub(crate) fn vertex_element_writer(declarations: &Vec<VertexDeclaration>) -> BinResult<()> {
140 for declaration in declarations {
142 for element in &declaration.elements {
143 element.write_options(writer, endian, ())?;
144 }
145
146 VertexElement {
147 stream: END_OF_STREAM,
148 offset: 0,
149 vertex_type: VertexType::Single1,
150 vertex_usage: VertexUsage::Position,
151 usage_index: 0,
152 }
153 .write_options(writer, endian, ())?;
154
155 let to_seek = (NUM_VERTICES as usize - 1 - declaration.elements.len()) * 8;
156 writer.seek(SeekFrom::Current(to_seek as i64))?;
157 }
158
159 Ok(())
160}