AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
WMOGroup Class Reference

#include "wmo.h"

Public Member Functions

 WMOGroup (std::string const &filename)
 
 ~WMOGroup ()
 
bool open (WMORoot *rootWMO)
 
int ConvertToVMAPGroupWmo (FILE *output, bool preciseVectorData)
 
uint32 GetLiquidTypeId (uint32 liquidTypeId)
 

Public Attributes

char * MOPY
 
uint16MOVI
 
uint16MoviEx
 
float * MOVT
 
uint16MOBA
 
int * MobaEx
 
WMOLiquidHeaderhlq
 
WMOLiquidVertLiquEx
 
char * LiquBytes
 
int groupName
 
int descGroupName
 
int mogpFlags
 
float bbcorn1 [3]
 
float bbcorn2 [3]
 
uint16 moprIdx
 
uint16 moprNItems
 
uint16 nBatchA
 
uint16 nBatchB
 
uint32 nBatchC
 
uint32 fogIdx
 
uint32 groupLiquid
 
uint32 groupWMOID
 
int mopy_size
 
int moba_size
 
int LiquEx_size
 
unsigned int nVertices
 
int nTriangles
 
uint32 liquflags
 
std::vector< uint16DoodadReferences
 

Private Attributes

std::string filename
 

Detailed Description

Constructor & Destructor Documentation

◆ WMOGroup()

WMOGroup::WMOGroup ( std::string const &  filename)
157 :
158 filename(std::move(filename)), MOPY(nullptr), MOVI(nullptr), MoviEx(nullptr), MOVT(nullptr), MOBA(nullptr), MobaEx(nullptr),
159 hlq(nullptr), LiquEx(nullptr), LiquBytes(nullptr), groupName(0), descGroupName(0), mogpFlags(0),
160 moprIdx(0), moprNItems(0), nBatchA(0), nBatchB(0), nBatchC(0), fogIdx(0),
163{
164 memset(bbcorn1, 0, sizeof(bbcorn1));
165 memset(bbcorn2, 0, sizeof(bbcorn2));
166}
uint32 nBatchC
Definition: wmo.h:141
float * MOVT
Definition: wmo.h:127
int moba_size
Definition: wmo.h:143
uint16 * MOVI
Definition: wmo.h:125
uint16 nBatchA
Definition: wmo.h:139
uint32 fogIdx
Definition: wmo.h:141
uint32 groupLiquid
Definition: wmo.h:141
uint16 moprIdx
Definition: wmo.h:137
std::string filename
Definition: wmo.h:120
int groupName
Definition: wmo.h:133
int descGroupName
Definition: wmo.h:133
int LiquEx_size
Definition: wmo.h:144
uint32 groupWMOID
Definition: wmo.h:141
uint16 nBatchB
Definition: wmo.h:140
float bbcorn2[3]
Definition: wmo.h:136
int mogpFlags
Definition: wmo.h:134
unsigned int nVertices
Definition: wmo.h:145
WMOLiquidVert * LiquEx
Definition: wmo.h:131
uint16 * MOBA
Definition: wmo.h:128
uint32 liquflags
Definition: wmo.h:147
char * MOPY
Definition: wmo.h:124
int nTriangles
Definition: wmo.h:146
char * LiquBytes
Definition: wmo.h:132
int mopy_size
Definition: wmo.h:143
int * MobaEx
Definition: wmo.h:129
WMOLiquidHeader * hlq
Definition: wmo.h:130
uint16 * MoviEx
Definition: wmo.h:126
uint16 moprNItems
Definition: wmo.h:138
float bbcorn1[3]
Definition: wmo.h:135

References bbcorn1, and bbcorn2.

◆ ~WMOGroup()

WMOGroup::~WMOGroup ( )
500{
501 delete [] MOPY;
502 delete [] MOVI;
503 delete [] MOVT;
504 delete [] MOBA;
505 delete hlq;
506 delete [] LiquEx;
507 delete [] LiquBytes;
508}

References hlq, LiquBytes, LiquEx, MOBA, MOPY, MOVI, and MOVT.

Member Function Documentation

◆ ConvertToVMAPGroupWmo()

int WMOGroup::ConvertToVMAPGroupWmo ( FILE *  output,
bool  preciseVectorData 
)
Todo:
: compress to bit field
293{
294 fwrite(&mogpFlags, sizeof(uint32), 1, output);
295 fwrite(&groupWMOID, sizeof(uint32), 1, output);
296 // group bound
297 fwrite(bbcorn1, sizeof(float), 3, output);
298 fwrite(bbcorn2, sizeof(float), 3, output);
299 fwrite(&liquflags, sizeof(uint32), 1, output);
300 int nColTriangles = 0;
302 {
303 char GRP[] = "GRP ";
304 fwrite(GRP, 1, 4, output);
305
306 int k = 0;
307 int moba_batch = moba_size / 12;
308 MobaEx = new int[moba_batch * 4];
309 for (int i = 8; i < moba_size; i += 12)
310 {
311 MobaEx[k++] = MOBA[i];
312 }
313 int moba_size_grp = moba_batch * 4 + 4;
314 fwrite(&moba_size_grp, 4, 1, output);
315 fwrite(&moba_batch, 4, 1, output);
316 fwrite(MobaEx, 4, k, output);
317 delete [] MobaEx;
318
319 uint32 nIdexes = nTriangles * 3;
320
321 if (fwrite("INDX", 4, 1, output) != 1)
322 {
323 printf("Error while writing file nbraches ID");
324 exit(0);
325 }
326 int wsize = sizeof(uint32) + sizeof(unsigned short) * nIdexes;
327 if (fwrite(&wsize, sizeof(int), 1, output) != 1)
328 {
329 printf("Error while writing file wsize");
330 // no need to exit?
331 }
332 if (fwrite(&nIdexes, sizeof(uint32), 1, output) != 1)
333 {
334 printf("Error while writing file nIndexes");
335 exit(0);
336 }
337 if (nIdexes > 0)
338 {
339 if (fwrite(MOVI, sizeof(unsigned short), nIdexes, output) != nIdexes)
340 {
341 printf("Error while writing file indexarray");
342 exit(0);
343 }
344 }
345
346 if (fwrite("VERT", 4, 1, output) != 1)
347 {
348 printf("Error while writing file nbraches ID");
349 exit(0);
350 }
351 wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
352 if (fwrite(&wsize, sizeof(int), 1, output) != 1)
353 {
354 printf("Error while writing file wsize");
355 // no need to exit?
356 }
357 if (fwrite(&nVertices, sizeof(int), 1, output) != 1)
358 {
359 printf("Error while writing file nVertices");
360 exit(0);
361 }
362 if (nVertices > 0)
363 {
364 if (fwrite(MOVT, sizeof(float) * 3, nVertices, output) != nVertices)
365 {
366 printf("Error while writing file vectors");
367 exit(0);
368 }
369 }
370
371 nColTriangles = nTriangles;
372 }
373 else
374 {
375 char GRP[] = "GRP ";
376 fwrite(GRP, 1, 4, output);
377 int k = 0;
378 int moba_batch = moba_size / 12;
379 MobaEx = new int[moba_batch * 4];
380 for (int i = 8; i < moba_size; i += 12)
381 {
382 MobaEx[k++] = MOBA[i];
383 }
384
385 int moba_size_grp = moba_batch * 4 + 4;
386 fwrite(&moba_size_grp, 4, 1, output);
387 fwrite(&moba_batch, 4, 1, output);
388 fwrite(MobaEx, 4, k, output);
389 delete [] MobaEx;
390
391 //-------INDX------------------------------------
392 //-------MOPY--------
393 MoviEx = new uint16[nTriangles * 3]; // "worst case" size...
394 int* IndexRenum = new int[nVertices];
395 memset(IndexRenum, 0xFF, nVertices * sizeof(int));
396 for (int i = 0; i < nTriangles; ++i)
397 {
398 // Skip no collision triangles
399 bool isRenderFace = (MOPY[2 * i] & WMO_MATERIAL_RENDER) && !(MOPY[2 * i] & WMO_MATERIAL_DETAIL);
400 bool isCollision = MOPY[2 * i] & WMO_MATERIAL_COLLISION || isRenderFace;
401 if (!isCollision)
402 continue;
403 // Use this triangle
404 for (int j = 0; j < 3; ++j)
405 {
406 IndexRenum[MOVI[3 * i + j]] = 1;
407 MoviEx[3 * nColTriangles + j] = MOVI[3 * i + j];
408 }
409 ++nColTriangles;
410 }
411
412 // assign new vertex index numbers
413 int nColVertices = 0;
414 for (uint32 i = 0; i < nVertices; ++i)
415 {
416 if (IndexRenum[i] == 1)
417 {
418 IndexRenum[i] = nColVertices;
419 ++nColVertices;
420 }
421 }
422
423 // translate triangle indices to new numbers
424 for (int i = 0; i < 3 * nColTriangles; ++i)
425 {
426 assert(MoviEx[i] < nVertices);
427 MoviEx[i] = IndexRenum[MoviEx[i]];
428 }
429
430 // write triangle indices
431 int INDX[] = {0x58444E49, nColTriangles * 6 + 4, nColTriangles * 3};
432 fwrite(INDX, 4, 3, output);
433 fwrite(MoviEx, 2, nColTriangles * 3, output);
434
435 // write vertices
436 int VERT[] = {0x54524556, nColVertices * 3 * static_cast<int>(sizeof(float)) + 4, nColVertices}; // "VERT"
437 int check = 3 * nColVertices;
438 fwrite(VERT, 4, 3, output);
439 for (uint32 i = 0; i < nVertices; ++i)
440 if (IndexRenum[i] >= 0)
441 check -= fwrite(MOVT + 3 * i, sizeof(float), 3, output);
442
443 assert(check == 0);
444
445 delete [] MoviEx;
446 delete [] IndexRenum;
447 }
448
449 //------LIQU------------------------
450 if (liquflags & 3)
451 {
452 int LIQU_totalSize = sizeof(uint32);
453 if (liquflags & 1)
454 {
455 LIQU_totalSize += sizeof(WMOLiquidHeader);
456 LIQU_totalSize += LiquEx_size / sizeof(WMOLiquidVert) * sizeof(float);
457 LIQU_totalSize += hlq->xtiles * hlq->ytiles;
458 }
459
460 int LIQU_h[] = { 0x5551494C, LIQU_totalSize };// "LIQU"
461 fwrite(LIQU_h, 4, 2, output);
462
463 /* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
464 llog << filename;
465 llog << ":\nliquidEntry: " << liquidEntry << " type: " << hlq->type << " (root:" << rootWMO->liquidType << " group:" << liquidType << ")\n";
466 llog.close(); */
467
468 fwrite(&groupLiquid, sizeof(uint32), 1, output);
469 if (liquflags & 1)
470 {
471 fwrite(hlq, sizeof(WMOLiquidHeader), 1, output);
472 // only need height values, the other values are unknown anyway
473 for (uint32 i = 0; i < LiquEx_size / sizeof(WMOLiquidVert); ++i)
474 fwrite(&LiquEx[i].height, sizeof(float), 1, output);
476 fwrite(LiquBytes, 1, hlq->xtiles * hlq->ytiles, output);
477 }
478 }
479
480 return nColTriangles;
481}
std::uint32_t uint32
Definition: Define.h:108
std::uint16_t uint16
Definition: Define.h:109
bool preciseVectorData
Definition: vmapexport.cpp:63
@ WMO_MATERIAL_DETAIL
Definition: wmo.h:34
@ WMO_MATERIAL_COLLISION
Definition: wmo.h:35
@ WMO_MATERIAL_RENDER
Definition: wmo.h:37
Definition: wmo.h:100
int ytiles
Definition: wmo.h:101
int xtiles
Definition: wmo.h:101
Definition: wmo.h:109

References bbcorn1, bbcorn2, groupLiquid, groupWMOID, hlq, LiquBytes, LiquEx, LiquEx_size, liquflags, MOBA, moba_size, MobaEx, mogpFlags, MOPY, MOVI, MoviEx, MOVT, nTriangles, nVertices, preciseVectorData, WMO_MATERIAL_COLLISION, WMO_MATERIAL_DETAIL, WMO_MATERIAL_RENDER, WMOLiquidHeader::xtiles, and WMOLiquidHeader::ytiles.

Referenced by ExtractSingleWmo().

◆ GetLiquidTypeId()

uint32 WMOGroup::GetLiquidTypeId ( uint32  liquidTypeId)
484{
485 if (liquidTypeId < 21 && liquidTypeId)
486 {
487 switch (((static_cast<uint8>(liquidTypeId) - 1) & 3))
488 {
489 case 0: return ((mogpFlags & 0x80000) != 0) + 13;
490 case 1: return 14;
491 case 2: return 19;
492 case 3: return 20;
493 default: break;
494 }
495 }
496 return liquidTypeId;
497}
std::uint8_t uint8
Definition: Define.h:110

References mogpFlags.

Referenced by open().

◆ open()

bool WMOGroup::open ( WMORoot rootWMO)
169{
170 MPQFile f(filename.c_str());
171 if (f.isEof ())
172 {
173 printf("No such file.\n");
174 return false;
175 }
176 uint32 size;
177 char fourcc[5];
178 while (!f.isEof())
179 {
180 f.read(fourcc, 4);
181 f.read(&size, 4);
182 flipcc(fourcc);
183 if (!strcmp(fourcc, "MOGP")) //Fix sizeoff = Data size.
184 {
185 size = 68;
186 }
187 fourcc[4] = 0;
188 size_t nextpos = f.getPos() + size;
189 LiquEx_size = 0;
190 liquflags = 0;
191
192 if (!strcmp(fourcc, "MOGP")) //header
193 {
194 f.read(&groupName, 4);
195 f.read(&descGroupName, 4);
196 f.read(&mogpFlags, 4);
197 f.read(bbcorn1, 12);
198 f.read(bbcorn2, 12);
199 f.read(&moprIdx, 2);
200 f.read(&moprNItems, 2);
201 f.read(&nBatchA, 2);
202 f.read(&nBatchB, 2);
203 f.read(&nBatchC, 4);
204 f.read(&fogIdx, 4);
205 f.read(&groupLiquid, 4);
206 f.read(&groupWMOID, 4);
207
208 // according to WoW.Dev Wiki:
209 if (rootWMO->flags & 4)
211 else if (groupLiquid == 15)
212 groupLiquid = 0;
213 else
215
216 if (groupLiquid)
217 liquflags |= 2;
218 }
219 else if (!strcmp(fourcc, "MOPY"))
220 {
221 MOPY = new char[size];
222 mopy_size = size;
223 nTriangles = (int)size / 2;
224 f.read(MOPY, size);
225 }
226 else if (!strcmp(fourcc, "MOVI"))
227 {
228 MOVI = new uint16[size / 2];
229 f.read(MOVI, size);
230 }
231 else if (!strcmp(fourcc, "MOVT"))
232 {
233 MOVT = new float[size / 4];
234 f.read(MOVT, size);
235 nVertices = (int)size / 12;
236 }
237 else if (!strcmp(fourcc, "MONR"))
238 {
239 }
240 else if (!strcmp(fourcc, "MOTV"))
241 {
242 }
243 else if (!strcmp(fourcc, "MOBA"))
244 {
245 MOBA = new uint16[size / 2];
246 moba_size = size / 2;
247 f.read(MOBA, size);
248 }
249 else if (!strcmp(fourcc,"MODR"))
250 {
251 DoodadReferences.resize(size / sizeof(uint16));
252 f.read(DoodadReferences.data(), size);
253 }
254 else if (!strcmp(fourcc,"MLIQ"))
255 {
256 liquflags |= 1;
257 hlq = new WMOLiquidHeader();
258 f.read(hlq, sizeof(WMOLiquidHeader));
261 f.read(LiquEx, LiquEx_size);
262 int nLiquBytes = hlq->xtiles * hlq->ytiles;
263 LiquBytes = new char[nLiquBytes];
264 f.read(LiquBytes, nLiquBytes);
265
266 // Determine legacy liquid type
267 if (!groupLiquid)
268 {
269 for (int i = 0; i < hlq->xtiles * hlq->ytiles; ++i)
270 {
271 if ((LiquBytes[i] & 0xF) != 15)
272 {
273 groupLiquid = GetLiquidTypeId((LiquBytes[i] & 0xF) + 1);
274 break;
275 }
276 }
277 }
278
279 /* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app);
280 llog << filename;
281 llog << "\nbbox: " << bbcorn1[0] << ", " << bbcorn1[1] << ", " << bbcorn1[2] << " | " << bbcorn2[0] << ", " << bbcorn2[1] << ", " << bbcorn2[2];
282 llog << "\nlpos: " << hlq->pos_x << ", " << hlq->pos_y << ", " << hlq->pos_z;
283 llog << "\nx-/yvert: " << hlq->xverts << "/" << hlq->yverts << " size: " << size << " expected size: " << 30 + hlq->xverts*hlq->yverts*8 + hlq->xtiles*hlq->ytiles << std::endl;
284 llog.close(); */
285 }
286 f.seek((int)nextpos);
287 }
288 f.close();
289 return true;
290}
Definition: mpq_libmpq04.h:75
uint32 flags
Definition: wmo.h:84
int xverts
Definition: wmo.h:101
int yverts
Definition: wmo.h:101
std::vector< uint16 > DoodadReferences
Definition: wmo.h:149
uint32 GetLiquidTypeId(uint32 liquidTypeId)
Definition: wmo.cpp:483
void flipcc(char *fcc)
Definition: mpq_libmpq04.h:99

References bbcorn1, bbcorn2, MPQFile::close(), descGroupName, DoodadReferences, filename, WMORoot::flags, flipcc(), fogIdx, GetLiquidTypeId(), MPQFile::getPos(), groupLiquid, groupName, groupWMOID, hlq, MPQFile::isEof(), LiquBytes, LiquEx, LiquEx_size, liquflags, MOBA, moba_size, mogpFlags, moprIdx, moprNItems, MOPY, mopy_size, MOVI, MOVT, nBatchA, nBatchB, nBatchC, nTriangles, nVertices, MPQFile::read(), MPQFile::seek(), WMOLiquidHeader::xtiles, WMOLiquidHeader::xverts, WMOLiquidHeader::ytiles, and WMOLiquidHeader::yverts.

Referenced by ExtractSingleWmo().

Member Data Documentation

◆ bbcorn1

float WMOGroup::bbcorn1[3]

◆ bbcorn2

float WMOGroup::bbcorn2[3]

◆ descGroupName

int WMOGroup::descGroupName

Referenced by open().

◆ DoodadReferences

std::vector<uint16> WMOGroup::DoodadReferences

Referenced by ExtractSingleWmo(), and open().

◆ filename

std::string WMOGroup::filename
private

Referenced by open().

◆ fogIdx

uint32 WMOGroup::fogIdx

Referenced by open().

◆ groupLiquid

uint32 WMOGroup::groupLiquid

Referenced by ConvertToVMAPGroupWmo(), and open().

◆ groupName

int WMOGroup::groupName

Referenced by open().

◆ groupWMOID

uint32 WMOGroup::groupWMOID

Referenced by ConvertToVMAPGroupWmo(), and open().

◆ hlq

WMOLiquidHeader* WMOGroup::hlq

◆ LiquBytes

char* WMOGroup::LiquBytes

◆ LiquEx

WMOLiquidVert* WMOGroup::LiquEx

◆ LiquEx_size

int WMOGroup::LiquEx_size

Referenced by ConvertToVMAPGroupWmo(), and open().

◆ liquflags

uint32 WMOGroup::liquflags

Referenced by ConvertToVMAPGroupWmo(), and open().

◆ MOBA

uint16* WMOGroup::MOBA

◆ moba_size

int WMOGroup::moba_size

Referenced by ConvertToVMAPGroupWmo(), and open().

◆ MobaEx

int* WMOGroup::MobaEx

Referenced by ConvertToVMAPGroupWmo().

◆ mogpFlags

int WMOGroup::mogpFlags

◆ moprIdx

uint16 WMOGroup::moprIdx

Referenced by open().

◆ moprNItems

uint16 WMOGroup::moprNItems

Referenced by open().

◆ MOPY

char* WMOGroup::MOPY

◆ mopy_size

int WMOGroup::mopy_size

Referenced by open().

◆ MOVI

uint16* WMOGroup::MOVI

◆ MoviEx

uint16* WMOGroup::MoviEx

Referenced by ConvertToVMAPGroupWmo().

◆ MOVT

float* WMOGroup::MOVT

◆ nBatchA

uint16 WMOGroup::nBatchA

Referenced by open().

◆ nBatchB

uint16 WMOGroup::nBatchB

Referenced by open().

◆ nBatchC

uint32 WMOGroup::nBatchC

Referenced by open().

◆ nTriangles

int WMOGroup::nTriangles

Referenced by ConvertToVMAPGroupWmo(), and open().

◆ nVertices

unsigned int WMOGroup::nVertices

Referenced by ConvertToVMAPGroupWmo(), and open().