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)
45 printf(
"No such file.\n");
57 std::ranges::reverse(fourcc);
59 size_t nextpos = f.
getPos() + size;
61 if (!memcmp(fourcc,
"MOHD", 4))
77 else if (!memcmp(fourcc,
"MODS", 4))
82 else if (!memcmp(fourcc,
"MODN", 4))
89 char* end = ptr + size;
93 std::string path(ptr, length);
102 else if (!memcmp(fourcc,
"MODI", 4))
109 for (
uint32 i = 0; i < fileDataIdCount; ++i)
119 else if (!memcmp(fourcc,
"MODD", 4))
124 else if (!memcmp(fourcc,
"MOGN", 4))
129 else if (!memcmp(fourcc,
"GFID", 4))
148 f.
read(&fileDataId, 4);
183 f.
seek((
int)nextpos);
194 unsigned int nVectors = 0;
195 fwrite(&nVectors,
sizeof(nVectors), 1, pOutfile);
196 fwrite(&
nGroups, 4, 1, pOutfile);
199 fwrite(&tcFlags,
sizeof(
ModelFlags), 1, pOutfile);
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)
221 printf(
"No such file.\n");
225 char fourcc[4] = { };
230 std::ranges::reverse(fourcc);
231 if (!memcmp(fourcc,
"MOGP", 4))
234 size_t nextpos = f.
getPos() + size;
235 if (!memcmp(fourcc,
"MOGP", 4))
255 if (rootWMO->
flags & 4)
265 else if (!memcmp(fourcc,
"MOPY", 4))
267 MPY2 = std::make_unique<uint16[]>(size);
268 std::unique_ptr<uint8[]> MOPY = std::make_unique<uint8[]>(size);
270 f.
read(MOPY.get(), size);
271 std::copy_n(MOPY.get(), size,
MPY2.get());
273 else if (!memcmp(fourcc,
"MPY2", 4))
275 MPY2 = std::make_unique<uint16[]>(size / 2);
279 else if (!memcmp(fourcc,
"MOVI", 4))
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());
286 else if (!memcmp(fourcc,
"MOVX", 4))
288 MOVX = std::make_unique<uint32[]>(size / 4);
291 else if (!memcmp(fourcc,
"MOVT", 4))
293 MOVT =
new float[size / 4];
297 else if (!memcmp(fourcc,
"MONR", 4))
300 else if (!memcmp(fourcc,
"MOTV", 4))
303 else if (!memcmp(fourcc,
"MOBA", 4))
309 else if (!memcmp(fourcc,
"MODR", 4))
314 else if (!memcmp(fourcc,
"MLIQ", 4))
329 for (
int i = 0; i < nLiquBytes; ++i)
353 f.
seek((
int)nextpos);
364 fwrite(
bbcorn1,
sizeof(
float), 3, output);
365 fwrite(
bbcorn2,
sizeof(
float), 3, output);
367 int nColTriangles = 0;
371 fwrite(GRP,1,4,output);
375 MobaEx =
new int[moba_batch*4];
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);
388 if(fwrite(
"INDX",4, 1, output) != 1)
390 printf(
"Error while writing file nbraches ID");
393 int wsize =
sizeof(
uint32) +
sizeof(
unsigned short) * nIdexes;
394 if(fwrite(&wsize,
sizeof(
int), 1, output) != 1)
396 printf(
"Error while writing file wsize");
399 if(fwrite(&nIdexes,
sizeof(
uint32), 1, output) != 1)
401 printf(
"Error while writing file nIndexes");
406 if (fwrite(
MOVX.get(),
sizeof(
uint32), nIdexes, output) != nIdexes)
408 printf(
"Error while writing file indexarray");
413 if(fwrite(
"VERT",4, 1, output) != 1)
415 printf(
"Error while writing file nbraches ID");
418 wsize =
sizeof(int) +
sizeof(
float) * 3 *
nVertices;
419 if(fwrite(&wsize,
sizeof(
int), 1, output) != 1)
421 printf(
"Error while writing file wsize");
424 if(fwrite(&
nVertices,
sizeof(
int), 1, output) != 1)
426 printf(
"Error while writing file nVertices");
433 printf(
"Error while writing file vectors");
443 fwrite(GRP,1,4,output);
446 MobaEx =
new int[moba_batch*4];
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);
460 std::unique_ptr<uint32[]> MovxEx = std::make_unique<uint32[]>(
nTriangles*3);
461 std::unique_ptr<int32[]> IndexRenum = std::make_unique<int32[]>(
nVertices);
462 std::fill_n(IndexRenum.get(),
nVertices, -1);
473 for (
int j=0; j<3; ++j)
475 IndexRenum[
MOVX[3*i + j]] = 1;
476 MovxEx[3*nColTriangles + j] =
MOVX[3*i + j];
485 if (IndexRenum[i] == 1)
487 IndexRenum[i] = nColVertices;
493 for (
int i=0; i<3*nColTriangles; ++i)
496 MovxEx[i] = IndexRenum[MovxEx[i]];
500 int INDX[] = {0x58444E49, nColTriangles*6+4, nColTriangles*3};
501 fwrite(INDX,4,3,output);
502 fwrite(MovxEx.get(),4,nColTriangles*3,output);
505 uint32 VERT[] = {0x54524556u, nColVertices*3*
static_cast<uint32>(
sizeof(float))+4, nColVertices};
506 int check = 3*nColVertices;
507 fwrite(VERT,4,3,output);
509 if(IndexRenum[i] >= 0)
510 check -= fwrite(
MOVT+3*i,
sizeof(
float), 3, output);
518 int LIQU_totalSize =
sizeof(
uint32);
525 int LIQU_h[] = { 0x5551494C, LIQU_totalSize };
526 fwrite(LIQU_h, 4, 2, output);
534 fwrite(&
LiquEx[i].height,
sizeof(
float), 1, output);
540 return nColTriangles;
545 if (liquidTypeId < 21 && liquidTypeId)
547 switch (((
static_cast<uint8>(liquidTypeId) - 1) & 3))
549 case 0:
return ((
mogpFlags & 0x80000) != 0) + 13;
595 position +=
Vec3D(533.33333f * 32, 533.33333f * 32, 0.0f);
596 bounds +=
Vec3D(533.33333f * 32, 533.33333f * 32, 0.0f);
600 if (mapObjDef.
Flags & 0x4)
601 scale = mapObjDef.
Scale / 1024.0f;
605 if (mapID != originalMapId)
607 if (mapObjDef.
Flags & 0x1)
621 fwrite(&nameSet,
sizeof(
uint8), 1, pDirfile);
622 fwrite(&uniqueId,
sizeof(
uint32), 1, pDirfile);
623 fwrite(&position,
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);
633 dirfileCache->emplace_back();
635 cacheModelData.
Flags =
flags & ~MOD_PARENT_SPAWN;
636 cacheModelData.
Data.resize(
646 uint8* cacheData = cacheModelData.
Data.data();
647#define CACHE_WRITE(value, size, count, dest) memcpy(dest, value, size * count); dest += size * count;
656 CACHE_WRITE(WmoInstName,
sizeof(
char), nlen, cacheData);
std::shared_ptr< CASC::Storage > CascStorage
struct CStringSentinel_T CStringSentinel
size_t read(void *dest, size_t bytes)
int16 parentOrFirstChildSplitGroupIndex
WMOGroup(std::string const &filename)
std::unique_ptr< uint16[]> MPY2
int16 nextSplitChildGroupIndex
std::vector< uint16 > DoodadReferences
bool open(WMORoot *rootWMO)
uint32 GetLiquidTypeId(uint32 liquidTypeId)
int ConvertToVMAPGroupWmo(FILE *output, bool preciseVectorData)
bool ShouldSkip(WMORoot const *root) const
std::unique_ptr< uint32[]> MOVX
std::vector< char > GroupNames
std::vector< uint32 > groupFileDataIDs
std::unordered_set< uint32 > ValidDoodadNames
bool ConvertToVMAPRootWmo(FILE *output)
WMORoot(std::string const &filename)
#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
constexpr CStringBoundedSentinel< Iterator > Checked(Iterator end) const
std::vector< WMO::MODS > Sets
std::vector< WMO::MODD > Spawns
std::unique_ptr< uint32[]> FileDataIds
std::unique_ptr< char[]> Paths
bool IsLiquidIgnored(uint32 liquidTypeId)
uint32 GenerateUniqueObjectId(uint32 clientId, uint16 clientDoodadId, bool isWmo)
std::shared_ptr< CASC::Storage > CascStorage
static Vec3D fixCoords(Vec3D const &v)