1#![allow(dead_code)]
2
3use crate::parsing::*;
4use nom::number::complete::*;
5use nom::{
6 bytes, character,
7 multi::{count, fill},
8 Err, Finish, IResult, Needed, Offset,
9};
10
11#[derive(Debug)]
13pub struct Trrn {
14 pub name: FixedSizeString<128>,
16 pub textures: [Texture; 6],
18 pub vertices: Vec<Vertex>,
20 pub triangles: Vec<Triangle>,
22 pub dds_a: Vec<u8>,
24 pub dds_b: Vec<u8>,
26 pub grass: Vec<Grass>,
28}
29
30#[derive(Debug, Copy, Clone)]
32pub struct Texture {
33 pub name: FixedSizeString<32>,
34 pub color: [f32; 3],
35}
36#[derive(Debug)]
38pub struct Vertex {
39 pub pos: [f32; 3],
41 pub normal: [f32; 3],
43 pub color: [u8; 4],
45 pub uv: [f32; 2],
47 pub weights: [f32; 2],
49}
50#[derive(Debug)]
52pub struct Triangle {
53 pub vertices: [u16; 3],
54}
55#[derive(Debug)]
57pub struct Grass {
58 pub name: FixedSizeString<32>,
60 pub texture: FixedSizeString<32>,
62 pub blades: Vec<GrassBlade>,
64}
65#[derive(Debug)]
66pub struct GrassBlade {
67 pub pos: [f32; 3],
69 pub normal: [f32; 3],
71 pub uv: [f32; 3],
73}
74
75impl Trrn {
76 pub fn from_bytes(input: &[u8]) -> NWNParseResult<Self> {
78 let (input, name) = FixedSizeString::from_bytes(input).unwrap();
79 let mut textures = [Texture {
80 name: FixedSizeString::empty(),
81 color: [0f32, 0f32, 0f32],
82 }; 6];
83
84 let mut input = input;
86 for tex in &mut textures {
87 (input, tex.name) = FixedSizeString::from_bytes(input)?;
88 }
89 for tex in &mut textures {
90 (input, ()) = fill(le_f32, &mut tex.color)(input)?;
91 }
92
93 let (input, vert_count) = le_u32(input)?;
95 let (input, tri_count) = le_u32(input)?;
96
97 let (input, vertices) = count(
98 |input| -> NWNParseResult<Vertex> {
99 let mut pos = [0f32; 3];
100 let (input, ()) = fill(le_f32, &mut pos)(input)?;
101
102 let mut normal = [0f32; 3];
103 let (input, ()) = fill(le_f32, &mut normal)(input)?;
104
105 let mut color = [0u8; 4];
106 let (input, ()) = fill(le_u8, &mut color)(input)?;
107
108 let mut uv = [0f32; 2];
109 let (input, ()) = fill(le_f32, &mut uv)(input)?;
110
111 let mut weights = [0f32; 2];
112 let (input, ()) = fill(le_f32, &mut weights)(input)?;
113
114 Ok((
115 input,
116 Vertex {
117 pos,
118 normal,
119 color,
120 uv,
121 weights,
122 },
123 ))
124 },
125 vert_count as usize,
126 )(input)
127 .map_err(|e| e.map(|e| e.add_context_msg("while parsing vertices".to_string())))?;
128
129 let (input, triangles) = count(
130 |input| -> NWNParseResult<Triangle> {
131 let mut vertices = [0u16; 3];
132 let (input, ()) = fill(le_u16, &mut vertices)(input)?;
133 Ok((input, Triangle { vertices }))
134 },
135 tri_count as usize,
136 )(input)
137 .map_err(|e| e.map(|e| e.add_context_msg("while parsing triangles".to_string())))?;
138
139 let (input, dds_a_size) = le_u32(input)?;
141 let (input, dds_a) = count(le_u8, dds_a_size as usize)(input).map_err(|e| {
142 e.map(|e: NWNParseError| e.add_context_msg("while parsing DDS A".to_string()))
143 })?;
144
145 let (input, dds_b_size) = le_u32(input)?;
146 let (input, dds_b) = count(le_u8, dds_b_size as usize)(input).map_err(|e| {
147 e.map(|e: NWNParseError| e.add_context_msg("while parsing DDS B".to_string()))
148 })?;
149
150 let (input, grass_count) = le_u32(input)?;
151 let (input, grass) = count(
152 |input| -> NWNParseResult<Grass> {
153 let (input, name) = FixedSizeString::from_bytes(input)?;
154 let (input, texture) = FixedSizeString::from_bytes(input)?;
155
156 let (input, blade_count) = le_u32(input)?;
157 let (input, blades) = count(
158 |input| -> NWNParseResult<GrassBlade> {
159 let mut pos = [0f32; 3];
160 let (input, ()) = fill(le_f32, &mut pos)(input)?;
161
162 let mut normal = [0f32; 3];
163 let (input, ()) = fill(le_f32, &mut normal)(input)?;
164
165 let mut uv = [0f32; 3];
166 let (input, ()) = fill(le_f32, &mut uv)(input)?;
167
168 Ok((input, GrassBlade { pos, normal, uv }))
169 },
170 blade_count as usize,
171 )(input)
172 .map_err(|e| e.map(|e| e.add_context_msg("while parsing blades".to_string())))?;
173
174 Ok((
175 input,
176 Grass {
177 name,
178 texture,
179 blades,
180 },
181 ))
182 },
183 grass_count as usize,
184 )(input)
185 .map_err(|e| e.map(|e| e.add_context_msg("while parsing grass".to_string())))?;
186
187 Ok((
188 input,
189 Self {
190 name,
191 textures,
192 vertices,
193 triangles,
194 dds_a,
195 dds_b,
196 grass,
197 },
198 ))
199 }
200
201 pub fn to_bytes(&self) -> Vec<u8> {
203 let mut output = vec![];
204 output.extend(self.name.as_bytes());
205
206 output.extend(self.textures.iter().flat_map(|t| t.name.as_bytes()));
208 output.extend(
209 self.textures
210 .iter()
211 .flat_map(|t| t.color.iter().flat_map(|v| v.to_le_bytes())),
212 );
213
214 output.extend((self.vertices.len() as u32).to_le_bytes());
215 output.extend((self.triangles.len() as u32).to_le_bytes());
216
217 output.extend(self.vertices.iter().flat_map(|vertex| {
219 let mut output = vec![];
220
221 output.extend(vertex.pos.iter().flat_map(|v| v.to_le_bytes()));
222 output.extend(vertex.normal.iter().flat_map(|v| v.to_le_bytes()));
223 output.extend(vertex.color.iter().flat_map(|v| v.to_le_bytes()));
224 output.extend(vertex.uv.iter().flat_map(|v| v.to_le_bytes()));
225 output.extend(vertex.weights.iter().flat_map(|v| v.to_le_bytes()));
226
227 output
228 }));
229
230 output.extend(
232 self.triangles
233 .iter()
234 .flat_map(|t| t.vertices.iter().flat_map(|v| v.to_le_bytes())),
235 );
236
237 output.extend((self.dds_a.len() as u32).to_le_bytes());
239 output.extend(&self.dds_a);
240 output.extend((self.dds_b.len() as u32).to_le_bytes());
241 output.extend(&self.dds_b);
242
243 output.extend((self.grass.len() as u32).to_le_bytes());
245 output.extend(self.grass.iter().flat_map(|grass| {
246 let mut output = vec![];
247
248 output.extend(grass.name.as_bytes());
249 output.extend(grass.texture.as_bytes());
250
251 output.extend((grass.blades.len() as u32).to_le_bytes());
252 output.extend(grass.blades.iter().flat_map(|blade| {
253 let mut output = vec![];
254
255 output.extend(blade.pos.iter().flat_map(|v| v.to_le_bytes()));
256 output.extend(blade.normal.iter().flat_map(|v| v.to_le_bytes()));
257 output.extend(blade.uv.iter().flat_map(|v| v.to_le_bytes()));
258
259 output
260 }));
261
262 output
263 }));
264
265 output
266 }
267}