1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
use crate::types::{BoundingBox, Color, Vec3};
use bitflags::bitflags;
/// Represents a WMO group file
#[derive(Debug)]
pub struct WmoGroup {
/// Group header
pub header: WmoGroupHeader,
/// Materials used in this group
pub materials: Vec<u16>,
/// Vertices that make up the geometry
pub vertices: Vec<Vec3>,
/// Normal vectors for vertices
pub normals: Vec<Vec3>,
/// Texture coordinates
pub tex_coords: Vec<TexCoord>,
/// Batch information for rendering
pub batches: Vec<WmoBatch>,
/// Triangle indices
pub indices: Vec<u16>,
/// Vertices colors (if present)
pub vertex_colors: Option<Vec<Color>>,
/// BSP tree nodes (if present)
pub bsp_nodes: Option<Vec<WmoBspNode>>,
/// Liquid data (if present)
pub liquid: Option<WmoLiquid>,
/// Doodad references (if present)
pub doodad_refs: Option<Vec<u16>>,
}
/// Header for a WMO group
#[derive(Debug, Clone)]
pub struct WmoGroupHeader {
/// Group flags
pub flags: WmoGroupFlags,
/// Bounding box
pub bounding_box: BoundingBox,
/// Name offset in MOGN chunk of root file
pub name_offset: u32,
/// Index of this group
pub group_index: u32,
}
impl WmoGroupHeader {
pub const SIZE: usize = 68;
}
bitflags! {
/// WMO group flags
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct WmoGroupFlags: u32 {
/// Has base vertices
const HAS_BASE_VERTICES = 0x01;
/// Has vertex lighting information
const HAS_VERTEX_LIGHTING = 0x02;
/// Has normals
const HAS_NORMALS = 0x04;
/// Has some light
const HAS_LIGHT = 0x08;
/// Has doodads
const HAS_DOODADS = 0x10;
/// Has liquids
const HAS_WATER = 0x20;
/// Indoor
const INDOOR = 0x40;
/// Show skybox
const SHOW_SKYBOX = 0x80;
/// Has exterior lights
const EXTERIOR_LIGHTS = 0x100;
/// Unused 1
const UNUSED1 = 0x200;
/// Unreachable
const UNREACHABLE = 0x400;
/// For custom use
const CUSTOM = 0x800;
/// Use ambient lighting
const USE_AMBIENT = 0x1000;
/// Has vertex colors
const HAS_VERTEX_COLORS = 0x2000;
/// Uses scene graph for rendering
const USE_SCENE_GRAPH = 0x4000;
/// Has more motion types
const HAS_MORE_MOTION_TYPES = 0x8000;
/// Mount allowed
const MOUNT_ALLOWED = 0x10000;
/// Has exterior BSP
const EXTERIOR_BSP = 0x20000;
}
}
/// Texture coordinates
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct TexCoord {
pub u: f32,
pub v: f32,
}
/// Represents a rendering batch in a WMO group
#[derive(Debug, Clone)]
pub struct WmoBatch {
/// Flags for the batch
pub flags: [u8; 10],
/// Material ID
pub material_id: u16,
/// Start index in the indices array
pub start_index: u32,
/// Number of indices
pub count: u16,
/// Start vertex
pub start_vertex: u16,
/// End vertex
pub end_vertex: u16,
/// Whether a large material ID is used
pub use_large_material_id: bool,
}
/// BSP tree node for collision and visibility
#[derive(Debug, Clone)]
pub struct WmoBspNode {
/// Plane split information
pub plane: WmoPlane,
/// Child nodes or triangles
pub children: [i16; 2],
/// First triangle index
pub first_face: u16,
/// Number of triangles
pub num_faces: u16,
}
/// Plane used in BSP node calculations
#[derive(Debug, Clone, Copy)]
pub struct WmoPlane {
/// Normal vector
pub normal: Vec3,
/// Distance from origin
pub distance: f32,
}
/// Liquid data in a WMO group
#[derive(Debug, Clone)]
pub struct WmoLiquid {
/// Liquid type
pub liquid_type: u32,
/// Liquid flags
pub flags: u32,
/// Grid dimensions
pub width: u32,
pub height: u32,
/// Vertices for liquid surface
pub vertices: Vec<WmoLiquidVertex>,
/// Flags for each liquid cell
pub tile_flags: Option<Vec<u8>>,
}
/// Vertex in a liquid surface
#[derive(Debug, Clone, Copy)]
pub struct WmoLiquidVertex {
/// Position
pub position: Vec3,
/// Height of the liquid
pub height: f32,
}
/// Material information for a group
#[derive(Debug, Clone)]
pub struct WmoMaterialInfo {
/// Material ID in the root file
pub material_id: u16,
/// Flags specific to this usage
pub flags: u8,
}