nwn_lib_rs/trn/
trrn.rs

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/// Terrain geometry, texture and grass
12#[derive(Debug)]
13pub struct Trrn {
14    /// Name of the megatile
15    pub name: FixedSizeString<128>,
16    /// megatile terrain textures
17    pub textures: [Texture; 6],
18    /// vertices list
19    pub vertices: Vec<Vertex>,
20    /// triangles list
21    pub triangles: Vec<Triangle>,
22    /// 32 bit DDS bitmap. r,g,b,a defines the intensity of textures 0,1,2,3
23    pub dds_a: Vec<u8>,
24    /// 32 bit DDS bitmap. r,g defines the intensity of textures 4,5
25    pub dds_b: Vec<u8>,
26    /// Grass
27    pub grass: Vec<Grass>,
28}
29
30/// Terrain texture name and color
31#[derive(Debug, Copy, Clone)]
32pub struct Texture {
33    pub name: FixedSizeString<32>,
34    pub color: [f32; 3],
35}
36/// Vertex information, with normals + colors + texture coordinates + weights
37#[derive(Debug)]
38pub struct Vertex {
39    /// 3d coordinates of the vertex
40    pub pos: [f32; 3],
41    /// normal vector
42    pub normal: [f32; 3],
43    /// BGRA format. A is unused.
44    pub color: [u8; 4],
45    /// texture coordinates
46    pub uv: [f32; 2],
47    /// XY1 ?
48    pub weights: [f32; 2],
49}
50/// Triangle information (vertices only)
51#[derive(Debug)]
52pub struct Triangle {
53    pub vertices: [u16; 3],
54}
55/// Grass data
56#[derive(Debug)]
57pub struct Grass {
58    /// Blades group name (unused?)
59    pub name: FixedSizeString<32>,
60    /// Grass texture name
61    pub texture: FixedSizeString<32>,
62    /// Grass blades list
63    pub blades: Vec<GrassBlade>,
64}
65#[derive(Debug)]
66pub struct GrassBlade {
67    ///
68    pub pos: [f32; 3],
69    /// TODO: check if normal vector, or just a direction in XY plane
70    pub normal: [f32; 3],
71    ///
72    pub uv: [f32; 3],
73}
74
75impl Trrn {
76    /// Parses TRRN data
77    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        // Gather texture names & colors
85        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        //
94        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        // DDS
140        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    /// Serializes TRRN data
202    pub fn to_bytes(&self) -> Vec<u8> {
203        let mut output = vec![];
204        output.extend(self.name.as_bytes());
205
206        // texture names & colors
207        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        // vertices
218        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        // triangles
231        output.extend(
232            self.triangles
233                .iter()
234                .flat_map(|t| t.vertices.iter().flat_map(|v| v.to_le_bytes())),
235        );
236
237        // DDS
238        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        // Grass
244        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}