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)
 
bool ShouldSkip (WMORoot const *root) const
 

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)
161 :
162 filename(std::move(filename)), MOPY(nullptr), MOVI(nullptr), MoviEx(nullptr), MOVT(nullptr), MOBA(nullptr), MobaEx(nullptr),
163 hlq(nullptr), LiquEx(nullptr), LiquBytes(nullptr), groupName(0), descGroupName(0), mogpFlags(0),
164 moprIdx(0), moprNItems(0), nBatchA(0), nBatchB(0), nBatchC(0), fogIdx(0),
167{
168 memset(bbcorn1, 0, sizeof(bbcorn1));
169 memset(bbcorn2, 0, sizeof(bbcorn2));
170}
uint32 nBatchC
Definition wmo.h:142
float * MOVT
Definition wmo.h:128
int moba_size
Definition wmo.h:144
uint16 * MOVI
Definition wmo.h:126
uint16 nBatchA
Definition wmo.h:140
uint32 fogIdx
Definition wmo.h:142
uint32 groupLiquid
Definition wmo.h:142
uint16 moprIdx
Definition wmo.h:138
std::string filename
Definition wmo.h:121
int groupName
Definition wmo.h:134
int descGroupName
Definition wmo.h:134
int LiquEx_size
Definition wmo.h:145
uint32 groupWMOID
Definition wmo.h:142
uint16 nBatchB
Definition wmo.h:141
float bbcorn2[3]
Definition wmo.h:137
int mogpFlags
Definition wmo.h:135
unsigned int nVertices
Definition wmo.h:146
WMOLiquidVert * LiquEx
Definition wmo.h:132
uint16 * MOBA
Definition wmo.h:129
uint32 liquflags
Definition wmo.h:148
char * MOPY
Definition wmo.h:125
int nTriangles
Definition wmo.h:147
char * LiquBytes
Definition wmo.h:133
int mopy_size
Definition wmo.h:144
int * MobaEx
Definition wmo.h:130
WMOLiquidHeader * hlq
Definition wmo.h:131
uint16 * MoviEx
Definition wmo.h:127
uint16 moprNItems
Definition wmo.h:139
float bbcorn1[3]
Definition wmo.h:136

References bbcorn1, and bbcorn2.

◆ ~WMOGroup()

WMOGroup::~WMOGroup ( )
522{
523 delete [] MOPY;
524 delete [] MOVI;
525 delete [] MOVT;
526 delete [] MOBA;
527 delete hlq;
528 delete [] LiquEx;
529 delete [] LiquBytes;
530}

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

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)
490{
491 if (liquidTypeId < 21 && liquidTypeId)
492 {
493 switch (((static_cast<uint8>(liquidTypeId) - 1) & 3))
494 {
495 case 0: return ((mogpFlags & 0x80000) != 0) + 13;
496 case 1: return 14;
497 case 2: return 19;
498 case 3: return 20;
499 default: break;
500 }
501 }
502 return liquidTypeId;
503}
std::uint8_t uint8
Definition Define.h:109

References mogpFlags.

Referenced by open().

◆ open()

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

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().

◆ ShouldSkip()

bool WMOGroup::ShouldSkip ( WMORoot const *  root) const
506{
507 // skip unreachable
508 if (mogpFlags & 0x80)
509 return true;
510
511 // skip antiportals
512 if (mogpFlags & 0x4000000)
513 return true;
514
515 if (groupName < int32(root->GroupNames.size()) && !strcmp(&root->GroupNames[groupName], "antiportal"))
516 return true;
517
518 return false;
519}
std::int32_t int32
Definition Define.h:103

References groupName, WMORoot::GroupNames, and mogpFlags.

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(), and ShouldSkip().

◆ 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().


The documentation for this class was generated from the following files: