wowlib 0.0.0
Read & write World of Warcraft client files — a C++26 core
Loading...
Searching...
No Matches
geometry.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <array>
7#include <cstdint>
8#include <utility>
9
10#include <welder/vocabulary.hpp>
11
13#include <wowlib/core/lang.hpp>
17
19 // --- MOPY / MPY2 / MOBA / MORB / MOBS / MOBN --------------------------------
20
21 enum class [[
22 =welder::weld,
23 =welder::flags,
24 =welder::doc("Per-triangle flag bits (MOPY and MPY2).")
25 ]] PolyFlags : std::uint8_t {
27 welder::doc("A transition face, blending exterior and interior lighting.")
28 ]] = 0x1,
29 NoCamCollide [[=welder::doc("The camera does not collide with this face.")
30 ]] = 0x2,
31 Detail [[=welder::doc("A detail face.")]] = 0x4,
32 Collision [[=welder::doc("Collision-only (also turns off water ripples).")]] = 0x8,
33 Hint [[=welder::doc("A hint face.")]] = 0x10,
34 Render [[=welder::doc("A rendered face.")]] = 0x20,
35 CullObjects [[=
36 welder::doc("Enables game-object culling against this face.")]] = 0x40,
37 CollideHit [[=welder::doc("Collides with projectiles/hit tests.")]] = 0x80
38 };
40 struct [[
41 =welder::weld,
42 =welder::doc("Per-triangle material info (MOPY).")
43 ]] SMOPoly {
44 [[=welder::doc("Triangle flags; PolyFlags bits.")]]
47 [[=welder::doc("Index into MOMT; 0xFF for collision-only faces.")]]
48 std::uint8_t materialId = 0;
49 };
50
51 static_assert(sizeof(SMOPoly) == 0x2);
52
53 struct [[
54 =welder::weld,
55 =welder::doc(R"(
56 Per-triangle material info v2 (MPY2, 10.0+): the MOPY replacement with
57 16-bit fields for multiple-material support.)")
58 ]] Poly2 {
59 [[=welder::doc("Triangle flags; PolyFlags bits, plus 0x100 for MOQG "
60 "ground-type queries.")]]
61 std::uint16_t flags = 0;
63 [[=welder::doc("Index into MOMT.")]]
64 std::uint16_t materialId = 0;
65 };
66
67 static_assert(sizeof(Poly2) == 0x4);
68
71 This base exists ENTIRELY for the language bindings (Python, Lua): it gives
72 the per-version WMOBatch* classes a common welded supertype so binding users
73 can write version-agnostic code (isinstance,
74 WMOBatch.for_version(expansion)). It has no role in the C++ API, where you
75 use the concrete SMOBatch<V> directly. It is an empty (elided) base, so the
76 binary specializations stay trivially copyable and 0x18 bytes. */
77 struct [[
78 =welder::weld,
79 =welder::weld_as("WMOBatch"),
81 =welder::doc("A MOBA render batch, abstract over the client version. "
82 "Construct a concrete version with "
83 "WMOBatch.for_version(expansion).")
84 ]] WMOBatchBase {};
85
89 namespace detail {
90 // The annotated era layouts; instantiate through the canonicalizing
91 // aliases below, never directly.
92 template <ClientVersion V>
93 struct SMOBatch;
94
95 template <ClientVersion V> requires(V < WmoBatchLargeMaterial)
96 struct [[
97 =welder::weld,
98 =welder::doc(
99 "One MOBA render batch: an index range sharing one material, "
100 "with its low-resolution culling box.")
102 [[=welder::doc("Culling box minimum corner (rounded vertex bounds).")]]
103 std::array<std::int16_t, 3> boxMin{};
104
105 [[=welder::doc("Culling box maximum corner.")]]
106 std::array<std::int16_t, 3> boxMax{};
107
108 [[=welder::doc("First face index in MOVI.")]]
109 std::uint32_t startIndex = 0;
110
111 [[=welder::doc("Number of MOVI indices.")]]
112 std::uint16_t count = 0;
113
114 [[=welder::doc("First vertex used in MOVT.")]]
115 std::uint16_t minIndex = 0;
116
117 [[=welder::doc("Last vertex used, inclusive.")]]
118 std::uint16_t maxIndex = 0;
119
120 [[=welder::doc("Batch flags.")]]
121 std::uint8_t flags = 0;
122
123 [[=welder::doc("Index into MOMT.")]]
124 std::uint8_t materialId = 0;
125
126
127
128 };
129
130 template <ClientVersion V> requires(V >= WmoBatchLargeMaterial)
131 struct [[
132 =welder::weld,
133 =welder::doc(
134 "One MOBA render batch: an index range sharing one material "
135 "(Legion+ layout with the 16-bit material id).")
138 [[=welder::mark::exclude]]std::array<std::uint8_t, 10> unknown{};
139
140 [[=welder::doc("16-bit material id; used when flags has 0x2.")]]
141 std::uint16_t materialIdLarge = 0;
142
143 [[=welder::doc("First face index in MOVI.")]]
144 std::uint32_t startIndex = 0;
145
146 [[=welder::doc("Number of MOVI indices.")]]
147 std::uint16_t count = 0;
148
149 [[=welder::doc("First vertex used in MOVT.")]]
150 std::uint16_t minIndex = 0;
152 [[=welder::doc("Last vertex used, inclusive.")]]
153 std::uint16_t maxIndex = 0;
155 [[=welder::doc("Batch flags; 0x2: use material_id_large.")]]
156 std::uint8_t flags = 0;
158 [[=welder::doc("Index into MOMT (when it fits 8 bits).")]]
159 std::uint8_t materialId = 0;
160
161
162
163 };
164 }
169 template <ClientVersion V>
172
173 static_assert(sizeof(SMOBatch<versions::Wotlk>) == 0x18);
174 static_assert(sizeof(SMOBatch<versions::Shadowlands>) == 0x18);
175
176 struct [[
177 =welder::weld,
178 =welder::doc(R"(
179 One MORB entry (Cata+): a triangle-strip override of the matching MOBA
180 batch's start and count. Same count as MOBA; ignored unless the client
181 renders strips.)")
183 [[=welder::doc("Replacement first-index into the MORI strips.")]]
184 std::uint32_t startIndex = 0;
185
186 [[=welder::doc("Replacement index count.")]]
187 std::uint16_t indexCount = 0;
188
189 [[=welder::doc("Alignment padding; zero in client files.")]]
190 std::uint16_t padding = 0;
191 };
192
193 static_assert(sizeof(RenderBatchOverride) == 0x8);
195 struct [[
196 =welder::weld,
197 =welder::doc(
198 "One MOBS shadow batch (Cata+): the shadow-pass counterpart of "
199 "a MOBA render batch.")
202 [[=welder::mark::exclude]] std::array<std::uint8_t, 10> unknown{};
204 [[=welder::doc("16-bit material id; used when flags has 0x2.")]]
205 std::uint16_t materialIdLarge = 0;
207 [[=welder::doc("Start value; divided by 3 on use (a face index).")]]
208 std::int32_t start = 0;
209
210 [[=welder::doc("Count value; divided by 3 on use (a face count).")]]
211 std::int16_t count = 0;
212
214 [[=welder::mark::exclude]] std::array<std::uint8_t, 4> unknown2{};
215
216 [[=welder::doc("Batch flags; 0x2: use material_id_large.")]]
217 std::uint8_t flags = 0;
218
219 [[=welder::doc("Index into MOMT (when it fits 8 bits).")]]
220 std::uint8_t materialId = 0;
221 };
222
223 static_assert(sizeof(ShadowBatch) == 0x18);
224
225 struct [[
226 =welder::weld,
227 =welder::doc("One MOBN BSP node for collision: a split plane or a leaf "
228 "referencing faces through MOBR.")
229 ]] CAaBspNode {
230 [[=welder::doc("0-2: split axis, 0x4: leaf.")]]
231 std::uint16_t flags = 0;
232
233 [[=welder::doc("Negative-side child node, -1 for none.")]]
234 std::int16_t negChild = -1;
235
236 [[=welder::doc("Positive-side child node, -1 for none.")]]
237 std::int16_t posChild = -1;
238
239 [[=welder::doc("Face count in MOBR (leaves).")]]
240 std::uint16_t nFaces = 0;
241
242 [[=welder::doc("First face index in MOBR.")]]
243 std::uint32_t faceStart = 0;
244
245 [[=welder::doc("Split plane distance from the model origin.")]]
246 float planeDist = 0;
247 };
248
249 static_assert(sizeof(CAaBspNode) == 0x10);
250}
Client version identity, the flavor axis that separates a client's CONTENT version from the engine ge...
Flag-testing convenience for the binary formats' bit-mask enums.
Binding-language identities welder's core does not name.
#define WOWLIB_CS_FAMILY_SURFACE
The C# rod's family-surface opt-in, spellable in every build.
Definition lang.hpp:44
WMO group-file chunk binary structs (the MOGP header, render batches, BSP nodes, group lights) and th...
Definition geometry.hpp:18
PolyFlags
Per-triangle flag bits (MOPY and MPY2).
Definition geometry.hpp:22
@ Collision
Collision-only (also turns off water ripples).
Definition geometry.hpp:26
@ CollideHit
Collides with projectiles/hit tests.
Definition geometry.hpp:30
@ Transition
A transition face, blending exterior and interior lighting.
Definition geometry.hpp:23
@ NoCamCollide
The camera does not collide with this face.
Definition geometry.hpp:24
@ CullObjects
Enables game-object culling against this face.
Definition geometry.hpp:29
detail::SMOBatch< canonicalVersion(V, WmoBatchPivots, WmoVersions)> SMOBatch
A MOBA render batch — the canonicalizing face of detail::SMOBatch (WmoBatchPivots: the culling box gi...
Definition geometry.hpp:143
constexpr ClientVersion WmoBatchLargeMaterial
legion 7.0.1.20740: SMOBatch's culling-box prelude gives way to a large (uint16) material id.
constexpr std::array WmoBatchPivots
SMOBatch: the culling-box prelude gives way to the large material id.
constexpr std::array WmoVersions
The versions WMO is instantiated (and welded) for: every targeted last-minor-of-major release,...
constexpr ClientVersion canonicalVersion(ClientVersion v, std::span< const ClientVersion > pivots, std::span< const ClientVersion > grid)
The canonical version v collapses to: the FIRST grid version in v's range.
One MOBN BSP node for collision: a split plane or a leaf referencing faces through MOBR.
Definition geometry.hpp:189
float planeDist
Split plane distance from the model origin.
Definition geometry.hpp:206
std::uint16_t flags
0-2: split axis, 0x4: leaf.
Definition geometry.hpp:191
std::uint16_t nFaces
Face count in MOBR (leaves).
Definition geometry.hpp:200
std::int16_t posChild
Positive-side child node, -1 for none.
Definition geometry.hpp:197
std::int16_t negChild
Negative-side child node, -1 for none.
Definition geometry.hpp:194
std::uint32_t faceStart
First face index in MOBR.
Definition geometry.hpp:203
std::uint16_t flags
Triangle flags; PolyFlags bits, plus 0x100 for MOQG ground-type queries.
Definition geometry.hpp:46
std::uint16_t materialId
Index into MOMT.
Definition geometry.hpp:49
std::uint32_t startIndex
Replacement first-index into the MORI strips.
Definition geometry.hpp:151
std::uint16_t padding
Alignment padding; zero in client files.
Definition geometry.hpp:157
std::uint16_t indexCount
Replacement index count.
Definition geometry.hpp:154
Per-triangle material info (MOPY).
Definition geometry.hpp:34
std::uint8_t materialId
Index into MOMT; 0xFF for collision-only faces.
Definition geometry.hpp:39
PolyFlags flags
Triangle flags; PolyFlags bits.
Definition geometry.hpp:36
One MOBS shadow batch (Cata+): the shadow-pass counterpart of a MOBA render batch.
Definition geometry.hpp:163
std::int16_t count
Count value; divided by 3 on use (a face count).
Definition geometry.hpp:174
std::array< std::uint8_t, 4 > unknown2
Undeciphered middle fields.
Definition geometry.hpp:177
std::uint8_t flags
Batch flags; 0x2: use material_id_large.
Definition geometry.hpp:180
std::uint16_t materialIdLarge
16-bit material id; used when flags has 0x2.
Definition geometry.hpp:168
std::int32_t start
Start value; divided by 3 on use (a face index).
Definition geometry.hpp:171
std::uint8_t materialId
Index into MOMT (when it fits 8 bits).
Definition geometry.hpp:183
std::array< std::uint8_t, 10 > unknown
Undeciphered leading fields.
Definition geometry.hpp:165
The version-agnostic base of every SMOBatch<V>, welded as "WMOBatch".
Definition geometry.hpp:65
std::array< std::int16_t, 3 > boxMax
Culling box maximum corner.
Definition geometry.hpp:83
std::uint16_t maxIndex
Last vertex used, inclusive.
Definition geometry.hpp:95
std::array< std::uint8_t, 10 > unknown
The nulled remains of the pre-7.0 culling box.
Definition geometry.hpp:111
std::uint16_t minIndex
First vertex used in MOVT.
Definition geometry.hpp:92
std::uint16_t materialIdLarge
16-bit material id; used when flags has 0x2.
Definition geometry.hpp:114
std::uint32_t startIndex
First face index in MOVI.
Definition geometry.hpp:86
std::array< std::int16_t, 3 > boxMin
Culling box minimum corner (rounded vertex bounds).
Definition geometry.hpp:80
The binary-level math and color primitives shared across WoW file formats (wowdev....
#define WOWLIB_EMPTY_BASES
Empty-base optimization for a binary struct that carries a (welded, empty) facade base: gcc/clang alw...
Definition types.hpp:24
WMO version pivots that change a binary-struct layout (not just chunk presence).