1use std::collections::HashMap;
2
3use crate::types::{BoundingBox, Color, Vec3};
4use crate::version::WmoVersion;
5use crate::wmo_group_types::WmoGroupFlags;
6use bitflags::bitflags;
7
8#[derive(Debug)]
10pub struct WmoRoot {
11 pub version: WmoVersion,
13
14 pub materials: Vec<WmoMaterial>,
16
17 pub groups: Vec<WmoGroupInfo>,
19
20 pub portals: Vec<WmoPortal>,
22
23 pub portal_references: Vec<WmoPortalReference>,
25
26 pub visible_block_lists: Vec<Vec<u16>>,
28
29 pub lights: Vec<WmoLight>,
31
32 pub doodad_defs: Vec<WmoDoodadDef>,
34
35 pub doodad_sets: Vec<WmoDoodadSet>,
37
38 pub bounding_box: BoundingBox,
40
41 pub textures: Vec<String>,
43
44 pub texture_offset_index_map: HashMap<u32, u32>,
46
47 pub header: WmoHeader,
49
50 pub skybox: Option<String>,
52
53 pub convex_volume_planes: Option<WmoConvexVolumePlanes>,
56}
57
58#[derive(Debug, Clone)]
60pub struct WmoHeader {
61 pub n_materials: u32,
63
64 pub n_groups: u32,
66
67 pub n_portals: u32,
69
70 pub n_lights: u32,
72
73 pub n_doodad_names: u32,
75
76 pub n_doodad_defs: u32,
78
79 pub n_doodad_sets: u32,
81
82 pub flags: WmoFlags,
84
85 pub ambient_color: Color,
87}
88
89bitflags! {
90 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
92 pub struct WmoFlags: u32 {
93 const HAS_VERTEX_COLORS = 0x01;
95 const OUTDOOR = 0x02;
97 const NO_TERRAIN_SHADOWS = 0x04;
99 const HAS_LIQUIDS = 0x08;
101 const INDOOR_MAP = 0x10;
103 const HAS_SKYBOX = 0x20;
105 const SPECIAL_PASS = 0x40;
107 const USE_SCENE_GRAPH = 0x80;
109 const SHOW_MINIMAP_OUTDOOR = 0x100;
111 const MOUNT_ALLOWED = 0x200;
113 }
114}
115
116#[derive(Debug, Clone)]
118pub struct WmoMaterial {
119 pub flags: WmoMaterialFlags,
121
122 pub shader: u32,
124
125 pub blend_mode: u32,
127
128 pub texture1: u32,
130
131 pub emissive_color: Color,
133
134 pub sidn_color: Color,
136
137 pub framebuffer_blend: Color,
139
140 pub texture2: u32,
142
143 pub diffuse_color: Color,
145
146 pub ground_type: u32,
148}
149
150bitflags! {
151 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
153 pub struct WmoMaterialFlags: u32 {
154 const UNLIT = 0x01;
156 const UNFOGGED = 0x02;
158 const TWO_SIDED = 0x04;
160 const EXTERIOR_LIGHT = 0x08;
162 const WINDOW_LIGHT = 0x10;
164 const CLAMP_S = 0x20;
166 const CLAMP_T = 0x40;
168 const UNUSED1 = 0x80;
170 const SHADOW_BATCH_1 = 0x100;
172 const SHADOW_BATCH_2 = 0x200;
174 const UNUSED2 = 0x400;
176 const UNUSED3 = 0x800;
178 }
179}
180
181impl WmoMaterial {
182 pub fn get_texture1_index(&self, texture_offset_index_map: &HashMap<u32, u32>) -> u32 {
183 texture_offset_index_map
184 .get(&self.texture1)
185 .copied()
186 .unwrap()
187 }
188
189 pub fn get_texture2_index(&self, texture_offset_index_map: &HashMap<u32, u32>) -> u32 {
190 texture_offset_index_map
191 .get(&self.texture2)
192 .copied()
193 .unwrap()
194 }
195}
196
197#[derive(Debug, Clone)]
199pub struct WmoGroupInfo {
200 pub flags: WmoGroupFlags,
202
203 pub bounding_box: BoundingBox,
205
206 pub name: String,
208}
209
210#[derive(Debug, Clone)]
212pub struct WmoPortal {
213 pub vertices: Vec<Vec3>,
215
216 pub normal: Vec3,
218}
219
220#[derive(Debug, Clone)]
222pub struct WmoPortalReference {
223 pub portal_index: u16,
225
226 pub group_index: u16,
228
229 pub side: u16,
231}
232
233#[derive(Debug, Clone)]
235pub struct WmoLight {
236 pub light_type: WmoLightType,
238
239 pub position: Vec3,
241
242 pub color: Color,
244
245 pub intensity: f32,
247
248 pub attenuation_start: f32,
250
251 pub attenuation_end: f32,
253
254 pub use_attenuation: bool,
256
257 pub properties: WmoLightProperties,
259}
260
261#[derive(Debug, Clone, Copy, PartialEq, Eq)]
263pub enum WmoLightType {
264 Omni = 0,
266
267 Spot = 1,
269
270 Directional = 2,
272
273 Ambient = 3,
275}
276
277impl WmoLightType {
278 pub fn from_raw(raw: u8) -> Option<Self> {
280 match raw {
281 0 => Some(Self::Omni),
282 1 => Some(Self::Spot),
283 2 => Some(Self::Directional),
284 3 => Some(Self::Ambient),
285 _ => {
287 tracing::warn!("Unknown light type {}, defaulting to Omni", raw);
289 Some(Self::Omni)
290 }
291 }
292 }
293}
294
295#[derive(Debug, Clone)]
297pub enum WmoLightProperties {
298 Omni,
300
301 Spot {
303 direction: Vec3,
305
306 hotspot: f32,
308
309 falloff: f32,
311 },
312
313 Directional {
315 direction: Vec3,
317 },
318
319 Ambient,
321}
322
323#[derive(Debug, Clone)]
325pub struct WmoDoodadDef {
326 pub name_offset: u32,
328
329 pub position: Vec3,
331
332 pub orientation: [f32; 4],
334
335 pub scale: f32,
337
338 pub color: Color,
340
341 pub set_index: u16,
343}
344
345#[derive(Debug, Clone)]
347pub struct WmoDoodadSet {
348 pub name: String,
350
351 pub start_doodad: u32,
353
354 pub n_doodads: u32,
356}
357
358#[derive(Debug, Clone)]
362pub struct WmoConvexVolumePlane {
363 pub normal: Vec3,
365
366 pub distance: f32,
368
369 pub flags: u32,
371}
372
373#[derive(Debug, Clone)]
376pub struct WmoConvexVolumePlanes {
377 pub planes: Vec<WmoConvexVolumePlane>,
380}