TrinityCore
Loading...
Searching...
No Matches
wmo.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "wmo.h"
19#include "adtfile.h"
20#include "cascfile.h"
21#include "Errors.h"
22#include "StringFormat.h"
23#include "Util.h"
24#include "VMapDefinitions.h"
25#include "vmapexport.h"
26#include <algorithm>
27#include <cstdio>
28#include <cstdlib>
29
30WMORoot::WMORoot(std::string const& filename)
31 : filename(filename), color(0), nTextures(0), nGroups(0), nPortals(0), nLights(0),
32 nDoodadNames(0), nDoodadDefs(0), nDoodadSets(0), RootWMOID(0), flags(0), numLod(0)
33{
34 memset(bbcorn1, 0, sizeof(bbcorn1));
35 memset(bbcorn2, 0, sizeof(bbcorn2));
36}
37
38extern std::shared_ptr<CASC::Storage> CascStorage;
39
41{
42 CASCFile f(CascStorage, filename.c_str());
43 if(f.isEof ())
44 {
45 printf("No such file.\n");
46 return false;
47 }
48
49 uint32 size;
50 char fourcc[4];
51
52 while (!f.isEof())
53 {
54 f.read(fourcc,4);
55 f.read(&size, 4);
56
57 std::ranges::reverse(fourcc);
58
59 size_t nextpos = f.getPos() + size;
60
61 if (!memcmp(fourcc, "MOHD", 4)) // header
62 {
63 f.read(&nTextures, 4);
64 f.read(&nGroups, 4);
65 f.read(&nPortals, 4);
66 f.read(&nLights, 4);
67 f.read(&nDoodadNames, 4);
68 f.read(&nDoodadDefs, 4);
69 f.read(&nDoodadSets, 4);
70 f.read(&color, 4);
71 f.read(&RootWMOID, 4);
72 f.read(bbcorn1, 12);
73 f.read(bbcorn2, 12);
74 f.read(&flags, 2);
75 f.read(&numLod, 2);
76 }
77 else if (!memcmp(fourcc, "MODS", 4))
78 {
79 DoodadData.Sets.resize(size / sizeof(WMO::MODS));
80 f.read(DoodadData.Sets.data(), size);
81 }
82 else if (!memcmp(fourcc, "MODN", 4))
83 {
85
86 DoodadData.Paths = std::make_unique<char[]>(size);
87 f.read(DoodadData.Paths.get(), size);
88 char* ptr = DoodadData.Paths.get();
89 char* end = ptr + size;
90 while (ptr < end)
91 {
92 std::size_t length = std::ranges::distance(ptr, CStringSentinel.Checked(end));
93 std::string path(ptr, length);
94
95 uint32 doodadNameIndex = ptr - DoodadData.Paths.get();
96 ptr += length + 1;
97
98 if (ExtractSingleModel(path))
99 ValidDoodadNames.insert(doodadNameIndex);
100 }
101 }
102 else if (!memcmp(fourcc, "MODI", 4))
103 {
105
106 uint32 fileDataIdCount = size / sizeof(uint32);
107 DoodadData.FileDataIds = std::make_unique<uint32[]>(fileDataIdCount);
108 f.read(DoodadData.FileDataIds.get(), size);
109 for (uint32 i = 0; i < fileDataIdCount; ++i)
110 {
111 if (!DoodadData.FileDataIds[i])
112 continue;
113
114 std::string path = Trinity::StringFormat("FILE{:08X}.xxx", DoodadData.FileDataIds[i]);
115 if (ExtractSingleModel(path))
116 ValidDoodadNames.insert(i);
117 }
118 }
119 else if (!memcmp(fourcc, "MODD", 4))
120 {
121 DoodadData.Spawns.resize(size / sizeof(WMO::MODD));
122 f.read(DoodadData.Spawns.data(), size);
123 }
124 else if (!memcmp(fourcc, "MOGN", 4))
125 {
126 GroupNames.resize(size);
127 f.read(GroupNames.data(), size);
128 }
129 else if (!memcmp(fourcc, "GFID", 4))
130 {
131 // full LOD reading code for reference
132 // commented out as we are not interested in any of them beyond first, most detailed
133
134 //uint16 lodCount = 1;
135 //if (flags & 0x10)
136 //{
137 // if (numLod)
138 // lodCount = numLod;
139 // else
140 // lodCount = 3;
141 //}
142
143 //for (uint32 lod = 0; lod < lodCount; ++lod)
144 //{
145 for (uint32 gp = 0; gp < nGroups; ++gp)
146 {
147 uint32 fileDataId;
148 f.read(&fileDataId, 4);
149 if (fileDataId)
150 groupFileDataIDs.push_back(fileDataId);
151 }
152 //}
153 }
154 /*
155 else if (!memcmp(fourcc, "MOTX", 4))
156 {
157 }
158 else if (!memcmp(fourcc, "MOMT", 4))
159 {
160 }
161 else if (!memcmp(fourcc, "MOGI", 4))
162 {
163 }
164 else if (!memcmp(fourcc, "MOLT", 4))
165 {
166 }
167 else if (!memcmp(fourcc, "MOSB", 4))
168 {
169 }
170 else if (!memcmp(fourcc, "MOPV", 4))
171 {
172 }
173 else if (!memcmp(fourcc, "MOPT", 4))
174 {
175 }
176 else if (!memcmp(fourcc, "MOPR", 4))
177 {
178 }
179 else if (!memcmp(fourcc, "MFOG", 4))
180 {
181 }
182 */
183 f.seek((int)nextpos);
184 }
185 f.close ();
186 return true;
187}
188
190{
191 //printf("Convert RootWmo...\n");
192
193 fwrite(VMAP::RAW_VMAP_MAGIC, 1, 8, pOutfile);
194 unsigned int nVectors = 0;
195 fwrite(&nVectors,sizeof(nVectors), 1, pOutfile); // will be filled later
196 fwrite(&nGroups, 4, 1, pOutfile);
197 fwrite(&RootWMOID, 4, 1, pOutfile);
199 fwrite(&tcFlags, sizeof(ModelFlags), 1, pOutfile);
200 return true;
201}
202
203WMOGroup::WMOGroup(const std::string &filename) :
204 filename(filename), MPY2(nullptr), MOVX(nullptr), MOVT(nullptr), MOBA(nullptr), MobaEx(nullptr),
205 hlq(nullptr), LiquEx(nullptr), LiquBytes(nullptr), groupName(0), descGroupName(0), mogpFlags(0),
206 moprIdx(0), moprNItems(0), nBatchA(0), nBatchB(0), nBatchC(0), fogIdx(0),
207 groupLiquid(0), groupWMOID(0), mogpFlags2(0),
208 parentOrFirstChildSplitGroupIndex(0), nextSplitChildGroupIndex(0),
209 moba_size(0), LiquEx_size(0),
210 nVertices(0), nTriangles(0), liquflags(0)
211{
212 memset(bbcorn1, 0, sizeof(bbcorn1));
213 memset(bbcorn2, 0, sizeof(bbcorn2));
214}
215
217{
218 CASCFile f(CascStorage, filename.c_str());
219 if(f.isEof ())
220 {
221 printf("No such file.\n");
222 return false;
223 }
224 uint32 size;
225 char fourcc[4] = { };
226 while (!f.isEof())
227 {
228 f.read(fourcc,4);
229 f.read(&size, 4);
230 std::ranges::reverse(fourcc);
231 if (!memcmp(fourcc, "MOGP", 4)) //size specified in MOGP chunk is all the other chunks combined, adjust to read MOGP-only
232 size = 68;
233
234 size_t nextpos = f.getPos() + size;
235 if (!memcmp(fourcc, "MOGP", 4))//header
236 {
237 f.read(&groupName, 4);
238 f.read(&descGroupName, 4);
239 f.read(&mogpFlags, 4);
240 f.read(bbcorn1, 12);
241 f.read(bbcorn2, 12);
242 f.read(&moprIdx, 2);
243 f.read(&moprNItems, 2);
244 f.read(&nBatchA, 2);
245 f.read(&nBatchB, 2);
246 f.read(&nBatchC, 4);
247 f.read(&fogIdx, 4);
248 f.read(&groupLiquid, 4);
249 f.read(&groupWMOID, 4);
250 f.read(&mogpFlags2, 4);
253
254 // according to WoW.Dev Wiki:
255 if (rootWMO->flags & 4)
257 else if (groupLiquid == 15)
258 groupLiquid = 0;
259 else
261
263 liquflags |= 2;
264 }
265 else if (!memcmp(fourcc, "MOPY", 4))
266 {
267 MPY2 = std::make_unique<uint16[]>(size);
268 std::unique_ptr<uint8[]> MOPY = std::make_unique<uint8[]>(size);
269 nTriangles = (int)size / 2;
270 f.read(MOPY.get(), size);
271 std::copy_n(MOPY.get(), size, MPY2.get());
272 }
273 else if (!memcmp(fourcc, "MPY2", 4))
274 {
275 MPY2 = std::make_unique<uint16[]>(size / 2);
276 nTriangles = (int)size / 4;
277 f.read(MPY2.get(), size);
278 }
279 else if (!memcmp(fourcc, "MOVI", 4))
280 {
281 MOVX = std::make_unique<uint32[]>(size / 2);
282 std::unique_ptr<uint16[]> MOVI = std::make_unique<uint16[]>(size / 2);
283 f.read(MOVI.get(), size);
284 std::copy_n(MOVI.get(), size / 2, MOVX.get());
285 }
286 else if (!memcmp(fourcc, "MOVX", 4))
287 {
288 MOVX = std::make_unique<uint32[]>(size / 4);
289 f.read(MOVX.get(), size);
290 }
291 else if (!memcmp(fourcc, "MOVT", 4))
292 {
293 MOVT = new float[size / 4];
294 f.read(MOVT, size);
295 nVertices = (int)size / 12;
296 }
297 else if (!memcmp(fourcc, "MONR", 4))
298 {
299 }
300 else if (!memcmp(fourcc, "MOTV", 4))
301 {
302 }
303 else if (!memcmp(fourcc, "MOBA", 4))
304 {
305 MOBA = new uint16[size / 2];
306 moba_size = size / 2;
307 f.read(MOBA, size);
308 }
309 else if (!memcmp(fourcc, "MODR", 4))
310 {
311 DoodadReferences.resize(size / sizeof(uint16));
312 f.read(DoodadReferences.data(), size);
313 }
314 else if (!memcmp(fourcc, "MLIQ", 4))
315 {
316 liquflags |= 1;
317 hlq = new WMOLiquidHeader();
318 f.read(hlq, sizeof(WMOLiquidHeader));
322 int nLiquBytes = hlq->xtiles * hlq->ytiles;
323 LiquBytes = new char[nLiquBytes];
324 f.read(LiquBytes, nLiquBytes);
325
326 // Determine legacy liquid type
327 if (!groupLiquid)
328 {
329 for (int i = 0; i < nLiquBytes; ++i)
330 {
331 if ((LiquBytes[i] & 0xF) != 15)
332 {
333 groupLiquid = GetLiquidTypeId((LiquBytes[i] & 0xF) + 1);
334 break;
335 }
336 }
337 }
338
340 liquflags = 0;
341
342 /*
343 if (auto llog = Trinity::make_unique_ptr_with_deleter<&::fclose>(fopen("Buildings/liquid.log", "a")))
344 {
345 fprintf(llog.get(), "%s\n", filename.c_str());
346 fprintf(llog.get(), "type: %u\n", groupLiquid);
347 fprintf(llog.get(), "bbox: %f, %f, %f | %f, %f, %f\n", bbcorn1[0], bbcorn1[1], bbcorn1[2], bbcorn2[0], bbcorn2[1], bbcorn2[2]);
348 fprintf(llog.get(), "lpos: %f, %f, %f\n", hlq->pos_x, hlq->pos_y, hlq->pos_z);
349 fprintf(llog.get(), "x/y vert: %d/%d\n", hlq->xverts, hlq->yverts);
350 }
351 */
352 }
353 f.seek((int)nextpos);
354 }
355 f.close();
356 return true;
357}
358
360{
361 fwrite(&mogpFlags,sizeof(uint32),1,output);
362 fwrite(&groupWMOID,sizeof(uint32),1,output);
363 // group bound
364 fwrite(bbcorn1, sizeof(float), 3, output);
365 fwrite(bbcorn2, sizeof(float), 3, output);
366 fwrite(&liquflags,sizeof(uint32),1,output);
367 int nColTriangles = 0;
369 {
370 char GRP[] = "GRP ";
371 fwrite(GRP,1,4,output);
372
373 int k = 0;
374 int moba_batch = moba_size/12;
375 MobaEx = new int[moba_batch*4];
376 for(int i=8; i<moba_size; i+=12)
377 {
378 MobaEx[k++] = MOBA[i];
379 }
380 int moba_size_grp = moba_batch*4+4;
381 fwrite(&moba_size_grp,4,1,output);
382 fwrite(&moba_batch,4,1,output);
383 fwrite(MobaEx,4,k,output);
384 delete [] MobaEx;
385
386 uint32 nIdexes = nTriangles * 3;
387
388 if(fwrite("INDX",4, 1, output) != 1)
389 {
390 printf("Error while writing file nbraches ID");
391 exit(0);
392 }
393 int wsize = sizeof(uint32) + sizeof(unsigned short) * nIdexes;
394 if(fwrite(&wsize, sizeof(int), 1, output) != 1)
395 {
396 printf("Error while writing file wsize");
397 // no need to exit?
398 }
399 if(fwrite(&nIdexes, sizeof(uint32), 1, output) != 1)
400 {
401 printf("Error while writing file nIndexes");
402 exit(0);
403 }
404 if(nIdexes >0)
405 {
406 if (fwrite(MOVX.get(), sizeof(uint32), nIdexes, output) != nIdexes)
407 {
408 printf("Error while writing file indexarray");
409 exit(0);
410 }
411 }
412
413 if(fwrite("VERT",4, 1, output) != 1)
414 {
415 printf("Error while writing file nbraches ID");
416 exit(0);
417 }
418 wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
419 if(fwrite(&wsize, sizeof(int), 1, output) != 1)
420 {
421 printf("Error while writing file wsize");
422 // no need to exit?
423 }
424 if(fwrite(&nVertices, sizeof(int), 1, output) != 1)
425 {
426 printf("Error while writing file nVertices");
427 exit(0);
428 }
429 if(nVertices >0)
430 {
431 if(fwrite(MOVT, sizeof(float)*3, nVertices, output) != nVertices)
432 {
433 printf("Error while writing file vectors");
434 exit(0);
435 }
436 }
437
438 nColTriangles = nTriangles;
439 }
440 else
441 {
442 char GRP[] = "GRP ";
443 fwrite(GRP,1,4,output);
444 int k = 0;
445 int moba_batch = moba_size/12;
446 MobaEx = new int[moba_batch*4];
447 for(int i=8; i<moba_size; i+=12)
448 {
449 MobaEx[k++] = MOBA[i];
450 }
451
452 int moba_size_grp = moba_batch*4+4;
453 fwrite(&moba_size_grp,4,1,output);
454 fwrite(&moba_batch,4,1,output);
455 fwrite(MobaEx,4,k,output);
456 delete [] MobaEx;
457
458 //-------INDX------------------------------------
459 //-------MOPY/MPY2--------
460 std::unique_ptr<uint32[]> MovxEx = std::make_unique<uint32[]>(nTriangles*3); // "worst case" size...
461 std::unique_ptr<int32[]> IndexRenum = std::make_unique<int32[]>(nVertices);
462 std::fill_n(IndexRenum.get(), nVertices, -1);
463 for (int i=0; i<nTriangles; ++i)
464 {
465 // Skip no collision triangles
466 bool isRenderFace = (MPY2[2 * i] & WMO_MATERIAL_RENDER) && !(MPY2[2 * i] & WMO_MATERIAL_DETAIL);
467 bool isCollision = MPY2[2 * i] & WMO_MATERIAL_COLLISION || isRenderFace;
468
469 if (!isCollision)
470 continue;
471
472 // Use this triangle
473 for (int j=0; j<3; ++j)
474 {
475 IndexRenum[MOVX[3*i + j]] = 1;
476 MovxEx[3*nColTriangles + j] = MOVX[3*i + j];
477 }
478 ++nColTriangles;
479 }
480
481 // assign new vertex index numbers
482 uint32 nColVertices = 0;
483 for (uint32 i=0; i<nVertices; ++i)
484 {
485 if (IndexRenum[i] == 1)
486 {
487 IndexRenum[i] = nColVertices;
488 ++nColVertices;
489 }
490 }
491
492 // translate triangle indices to new numbers
493 for (int i=0; i<3*nColTriangles; ++i)
494 {
495 ASSERT(MovxEx[i] < nVertices);
496 MovxEx[i] = IndexRenum[MovxEx[i]];
497 }
498
499 // write triangle indices
500 int INDX[] = {0x58444E49, nColTriangles*6+4, nColTriangles*3};
501 fwrite(INDX,4,3,output);
502 fwrite(MovxEx.get(),4,nColTriangles*3,output);
503
504 // write vertices
505 uint32 VERT[] = {0x54524556u, nColVertices*3*static_cast<uint32>(sizeof(float))+4, nColVertices};// "VERT"
506 int check = 3*nColVertices;
507 fwrite(VERT,4,3,output);
508 for (uint32 i=0; i<nVertices; ++i)
509 if(IndexRenum[i] >= 0)
510 check -= fwrite(MOVT+3*i, sizeof(float), 3, output);
511
512 ASSERT(check==0);
513 }
514
515 //------LIQU------------------------
516 if (liquflags & 3)
517 {
518 int LIQU_totalSize = sizeof(uint32);
519 if (liquflags & 1)
520 {
521 LIQU_totalSize += sizeof(WMOLiquidHeader);
522 LIQU_totalSize += LiquEx_size / sizeof(WMOLiquidVert) * sizeof(float);
523 LIQU_totalSize += hlq->xtiles * hlq->ytiles;
524 }
525 int LIQU_h[] = { 0x5551494C, LIQU_totalSize };// "LIQU"
526 fwrite(LIQU_h, 4, 2, output);
527
528 fwrite(&groupLiquid, sizeof(uint32), 1, output);
529 if (liquflags & 1)
530 {
531 fwrite(hlq, sizeof(WMOLiquidHeader), 1, output);
532 // only need height values, the other values are unknown anyway
533 for (uint32 i = 0; i < LiquEx_size / sizeof(WMOLiquidVert); ++i)
534 fwrite(&LiquEx[i].height, sizeof(float), 1, output);
535 // todo: compress to bit field
536 fwrite(LiquBytes, 1, hlq->xtiles * hlq->ytiles, output);
537 }
538 }
539
540 return nColTriangles;
541}
542
544{
545 if (liquidTypeId < 21 && liquidTypeId)
546 {
547 switch (((static_cast<uint8>(liquidTypeId) - 1) & 3))
548 {
549 case 0: return ((mogpFlags & 0x80000) != 0) + 13;
550 case 1: return 14;
551 case 2: return 19;
552 case 3: return 20;
553 default: break;
554 }
555 }
556 return liquidTypeId;
557}
558
559bool WMOGroup::ShouldSkip(WMORoot const* root) const
560{
561 // skip unreachable
562 if (mogpFlags & 0x80)
563 return true;
564
565 // skip antiportals
566 if (mogpFlags & 0x4000000)
567 return true;
568
569 if (groupName < std::ssize(root->GroupNames) && !strcmp(&root->GroupNames[groupName], "antiportal"))
570 return true;
571
572 return false;
573}
574
576{
577 delete [] MOVT;
578 delete [] MOBA;
579 delete hlq;
580 delete [] LiquEx;
581 delete [] LiquBytes;
582}
583
584void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, bool isGlobalWmo, uint32 mapID, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache)
585{
586 //-----------add_in _dir_file----------------
587
588 Vec3D position = fixCoords(mapObjDef.Position);
589 AaBox3D bounds;
590 bounds.min = fixCoords(mapObjDef.Bounds.min);
591 bounds.max = fixCoords(mapObjDef.Bounds.max);
592
593 if (isGlobalWmo)
594 {
595 position += Vec3D(533.33333f * 32, 533.33333f * 32, 0.0f);
596 bounds += Vec3D(533.33333f * 32, 533.33333f * 32, 0.0f);
597 }
598
599 float scale = 1.0f;
600 if (mapObjDef.Flags & 0x4)
601 scale = mapObjDef.Scale / 1024.0f;
602 uint32 uniqueId = GenerateUniqueObjectId(mapObjDef.UniqueId, 0, true);
604 uint8 nameSet = mapObjDef.NameSet;
605 if (mapID != originalMapId)
607 if (mapObjDef.Flags & 0x1)
608 {
610 //if (FILE* destro = fopen("Buildings/destructible.log", "a"))
611 //{
612 // fprintf(destro, R"( { fileName: "%s", fileDataID: %u, mapId: %u, uniqueId: %u, pos: { x: %f, y: %f, z: %f }, rot: { x: %f, y: %f, z: %f } },)" "\n",
613 // WmoInstName, mapObjDef.Id, mapID, mapObjDef.UniqueId, 533.33333f * 32 - mapObjDef.Position.z, 533.33333f * 32 - mapObjDef.Position.x, mapObjDef.Position.y,
614 // mapObjDef.Rotation.x, mapObjDef.Rotation.y, mapObjDef.Rotation.z);
615 // fclose(destro);
616 //}
617 }
618
619 //write Flags, NameSet, UniqueId, Pos, Rot, Scale, Bound_lo, Bound_hi, name
620 fwrite(&flags, sizeof(uint8), 1, pDirfile);
621 fwrite(&nameSet, sizeof(uint8), 1, pDirfile);
622 fwrite(&uniqueId, sizeof(uint32), 1, pDirfile);
623 fwrite(&position, sizeof(Vec3D), 1, pDirfile);
624 fwrite(&mapObjDef.Rotation, sizeof(Vec3D), 1, pDirfile);
625 fwrite(&scale, sizeof(float), 1, pDirfile);
626 fwrite(&bounds, sizeof(AaBox3D), 1, pDirfile);
627 uint32 nlen = strlen(WmoInstName);
628 fwrite(&nlen, sizeof(uint32), 1, pDirfile);
629 fwrite(WmoInstName, sizeof(char), nlen, pDirfile);
630
631 if (dirfileCache)
632 {
633 dirfileCache->emplace_back();
634 ADTOutputCache& cacheModelData = dirfileCache->back();
635 cacheModelData.Flags = flags & ~MOD_PARENT_SPAWN;
636 cacheModelData.Data.resize(
637 sizeof(uint8) + // nameSet
638 sizeof(uint32) + // uniqueId
639 sizeof(Vec3D) + // position
640 sizeof(Vec3D) + // mapObjDef.Rotation
641 sizeof(float) + // scale
642 sizeof(AaBox3D) + // bounds
643 sizeof(uint32) + // nlen
644 nlen); // WmoInstName
645
646 uint8* cacheData = cacheModelData.Data.data();
647#define CACHE_WRITE(value, size, count, dest) memcpy(dest, value, size * count); dest += size * count;
648
649 CACHE_WRITE(&nameSet, sizeof(uint8), 1, cacheData);
650 CACHE_WRITE(&uniqueId, sizeof(uint32), 1, cacheData);
651 CACHE_WRITE(&position, sizeof(Vec3D), 1, cacheData);
652 CACHE_WRITE(&mapObjDef.Rotation, sizeof(Vec3D), 1, cacheData);
653 CACHE_WRITE(&scale, sizeof(float), 1, cacheData);
654 CACHE_WRITE(&bounds, sizeof(AaBox3D), 1, cacheData);
655 CACHE_WRITE(&nlen, sizeof(uint32), 1, cacheData);
656 CACHE_WRITE(WmoInstName, sizeof(char), nlen, cacheData);
657
658#undef CACHE_WRITE
659 }
660}
uint8_t uint8
Definition Define.h:156
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
uint16 flags
#define ASSERT
Definition Errors.h:80
std::shared_ptr< CASC::Storage > CascStorage
Definition System.cpp:51
struct CStringSentinel_T CStringSentinel
Vec3D max
Definition vec3d.h:63
Vec3D min
Definition vec3d.h:62
bool isEof()
Definition cascfile.h:45
void seek(int offset)
Definition cascfile.cpp:99
size_t read(void *dest, size_t bytes)
Definition cascfile.cpp:80
size_t getPos()
Definition cascfile.h:42
void close()
Definition cascfile.cpp:111
Definition vec3d.h:22
uint32 nBatchC
Definition wmo.h:144
float * MOVT
Definition wmo.h:130
int moba_size
Definition wmo.h:149
int16 parentOrFirstChildSplitGroupIndex
Definition wmo.h:146
WMOGroup(std::string const &filename)
Definition wmo.cpp:203
std::unique_ptr< uint16[]> MPY2
Definition wmo.h:128
uint16 nBatchA
Definition wmo.h:142
uint32 fogIdx
Definition wmo.h:144
uint32 groupLiquid
Definition wmo.h:144
uint16 moprIdx
Definition wmo.h:140
int16 nextSplitChildGroupIndex
Definition wmo.h:147
std::string filename
Definition wmo.h:124
int groupName
Definition wmo.h:136
int descGroupName
Definition wmo.h:136
int LiquEx_size
Definition wmo.h:150
uint32 groupWMOID
Definition wmo.h:144
uint16 nBatchB
Definition wmo.h:143
uint32 mogpFlags2
Definition wmo.h:145
float bbcorn2[3]
Definition wmo.h:139
std::vector< uint16 > DoodadReferences
Definition wmo.h:155
int mogpFlags
Definition wmo.h:137
unsigned int nVertices
Definition wmo.h:151
WMOLiquidVert * LiquEx
Definition wmo.h:134
uint16 * MOBA
Definition wmo.h:131
uint32 liquflags
Definition wmo.h:153
bool open(WMORoot *rootWMO)
Definition wmo.cpp:216
int nTriangles
Definition wmo.h:152
uint32 GetLiquidTypeId(uint32 liquidTypeId)
Definition wmo.cpp:543
char * LiquBytes
Definition wmo.h:135
~WMOGroup()
Definition wmo.cpp:575
int * MobaEx
Definition wmo.h:132
WMOLiquidHeader * hlq
Definition wmo.h:133
int ConvertToVMAPGroupWmo(FILE *output, bool preciseVectorData)
Definition wmo.cpp:359
bool ShouldSkip(WMORoot const *root) const
Definition wmo.cpp:559
uint16 moprNItems
Definition wmo.h:141
float bbcorn1[3]
Definition wmo.h:138
std::unique_ptr< uint32[]> MOVX
Definition wmo.h:129
Definition wmo.h:80
float bbcorn1[3]
Definition wmo.h:86
std::vector< char > GroupNames
Definition wmo.h:90
uint32 nDoodadSets
Definition wmo.h:85
uint32 nDoodadDefs
Definition wmo.h:85
WMODoodadData DoodadData
Definition wmo.h:91
uint16 numLod
Definition wmo.h:88
std::vector< uint32 > groupFileDataIDs
Definition wmo.h:93
uint32 nLights
Definition wmo.h:85
uint32 nPortals
Definition wmo.h:85
bool open()
Definition wmo.cpp:40
float bbcorn2[3]
Definition wmo.h:87
uint32 nGroups
Definition wmo.h:85
std::unordered_set< uint32 > ValidDoodadNames
Definition wmo.h:92
uint16 flags
Definition wmo.h:88
std::string filename
Definition wmo.h:82
bool ConvertToVMAPRootWmo(FILE *output)
Definition wmo.cpp:189
uint32 nDoodadNames
Definition wmo.h:85
unsigned int color
Definition wmo.h:84
uint32 nTextures
Definition wmo.h:85
WMORoot(std::string const &filename)
Definition wmo.cpp:30
uint32 RootWMOID
Definition wmo.h:85
ExtractedModelData const * ExtractSingleModel(std::string &fname)
#define CACHE_WRITE(value, size, cnt, dest)
void Extract(ADT::MODF const &mapObjDef, char const *WmoInstName, bool isGlobalWmo, uint32 mapID, uint32 originalMapId, FILE *pDirfile, std::vector< ADTOutputCache > *dirfileCache)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args) noexcept
Default TC string format function.
const char RAW_VMAP_MAGIC[]
std::vector< uint8 > Data
Definition adtfile.h:56
uint8 Flags
Definition adtfile.h:55
uint16 Flags
Definition adtfile.h:45
uint16 Scale
Definition adtfile.h:48
AaBox3D Bounds
Definition adtfile.h:44
Vec3D Rotation
Definition adtfile.h:43
uint16 NameSet
Definition adtfile.h:47
uint32 UniqueId
Definition adtfile.h:41
Vec3D Position
Definition adtfile.h:42
constexpr CStringBoundedSentinel< Iterator > Checked(Iterator end) const
Definition Util.h:394
std::vector< WMO::MODS > Sets
Definition wmo.h:72
std::vector< WMO::MODD > Spawns
Definition wmo.h:75
std::unique_ptr< uint32[]> FileDataIds
Definition wmo.h:74
std::unique_ptr< char[]> Paths
Definition wmo.h:73
bool preciseVectorData
bool IsLiquidIgnored(uint32 liquidTypeId)
uint32 GenerateUniqueObjectId(uint32 clientId, uint16 clientDoodadId, bool isWmo)
ModelFlags
Definition vmapexport.h:36
@ MOD_PATH_ONLY
Definition vmapexport.h:31
@ MOD_PARENT_SPAWN
Definition vmapexport.h:30
@ MOD_HAS_BOUND
Definition vmapexport.h:29
std::shared_ptr< CASC::Storage > CascStorage
Definition System.cpp:51
@ WMO_MATERIAL_DETAIL
Definition wmo.h:33
@ WMO_MATERIAL_COLLISION
Definition wmo.h:34
@ WMO_MATERIAL_RENDER
Definition wmo.h:36
static Vec3D fixCoords(Vec3D const &v)
Definition wmo.h:68