diff options
| author | Shauren <shauren.trinity@gmail.com> | 2018-04-07 21:56:19 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2018-04-07 21:56:19 +0200 |
| commit | 2c64bb97e6fddcbd15ef39fde3d0828bbf600ec6 (patch) | |
| tree | 27f9cf5bbfa3693a33b2289da36e5f6307001ce0 /src/tools/vmap4_extractor | |
| parent | 5c7a5ddcf4735a38c76ae16b416abff2dc94fb62 (diff) | |
Tools:
* mapextractor - fixed fatigue in Thousand Needles
* mapextractor - fixed compressing liquid data
* vmapextractor - fixed extracting liquids inside WMOs
* vmapextractor - implemented new WMO flags
* vmapextractor - store model type for gameobject models
* mmap_generator - fixed processing liquids broken in e5d23103f37c40d2e946fa0e2db66d2f527ad9af
Diffstat (limited to 'src/tools/vmap4_extractor')
| -rw-r--r-- | src/tools/vmap4_extractor/adtfile.cpp | 64 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/adtfile.h | 109 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/gameobject_extract.cpp | 8 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/model.cpp | 67 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/model.h | 15 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/vec3d.h | 6 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/vmapexport.cpp | 3 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/vmapexport.h | 1 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/wdtfile.cpp | 21 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/wmo.cpp | 225 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/wmo.h | 31 |
11 files changed, 227 insertions, 323 deletions
diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index 76292c33a1f..5a2838df444 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -18,7 +18,7 @@ #include "vmapexport.h" #include "adtfile.h" - +#include "StringFormat.h" #include <algorithm> #include <cstdio> @@ -79,7 +79,7 @@ char* GetExtension(char* FileName) extern CASC::StorageHandle CascStorage; -ADTFile::ADTFile(char* filename, bool cache) : ADT(CascStorage, filename, false), nWMO(0), nMDX(0) +ADTFile::ADTFile(char* filename, bool cache) : _file(CascStorage, filename, false) { Adtfilename.append(filename); cacheable = cache; @@ -91,7 +91,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMa if (dirfileCache) return initFromCache(map_num, tileX, tileY, originalMapId); - if (ADT.isEof()) + if (_file.isEof()) return false; uint32 size; @@ -106,15 +106,15 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMa if (cacheable) dirfileCache = new std::vector<ADTOutputCache>(); - while (!ADT.isEof()) + while (!_file.isEof()) { char fourcc[5]; - ADT.read(&fourcc,4); - ADT.read(&size, 4); + _file.read(&fourcc,4); + _file.read(&size, 4); flipcc(fourcc); fourcc[4] = 0; - size_t nextpos = ADT.getPos() + size; + size_t nextpos = _file.getPos() + size; if (!strcmp(fourcc,"MCIN")) { @@ -127,7 +127,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMa if (size) { char* buf = new char[size]; - ADT.read(buf, size); + _file.read(buf, size); char* p = buf; while (p < buf + size) { @@ -151,7 +151,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMa if (size) { char* buf = new char[size]; - ADT.read(buf, size); + _file.read(buf, size); char* p = buf; while (p < buf + size) { @@ -171,16 +171,25 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMa } } //====================== - else if (!strcmp(fourcc,"MDDF")) + else if (!strcmp(fourcc, "MDDF")) { if (size) { - nMDX = (int)size / 36; - for (int i=0; i<nMDX; ++i) + uint32 doodadCount = size / sizeof(ADT::MDDF); + for (uint32 i = 0; i < doodadCount; ++i) { - uint32 id; - ADT.read(&id, 4); - ModelInstance inst(ADT, ModelInstanceNames[id].c_str(), map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); + ADT::MDDF doodadDef; + _file.read(&doodadDef, sizeof(ADT::MDDF)); + if (!(doodadDef.Flags & 0x40)) + { + Doodad::Extract(doodadDef, ModelInstanceNames[doodadDef.Id].c_str(), map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); + } + else + { + std::string fileName = Trinity::StringFormat("FILE%08X.xxx", doodadDef.Id); + ExtractSingleModel(fileName); + Doodad::Extract(doodadDef, fileName.c_str(), map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); + } } ModelInstanceNames.clear(); @@ -190,12 +199,21 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMa { if (size) { - nWMO = (int)size / 64; - for (int i=0; i<nWMO; ++i) + uint32 mapObjectCount = size / sizeof(ADT::MODF); + for (uint32 i = 0; i < mapObjectCount; ++i) { - uint32 id; - ADT.read(&id, 4); - WMOInstance inst(ADT, WmoInstanceNames[id].c_str(), map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); + ADT::MODF mapObjDef; + _file.read(&mapObjDef, sizeof(ADT::MODF)); + if (!(mapObjDef.Flags & 0x8)) + { + MapObject::Extract(mapObjDef, WmoInstanceNames[mapObjDef.Id].c_str(), map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); + } + else + { + std::string fileName = Trinity::StringFormat("FILE%08X.xxx", mapObjDef.Id); + ExtractSingleModel(fileName); + MapObject::Extract(mapObjDef, fileName.c_str(), map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); + } } WmoInstanceNames.clear(); @@ -203,10 +221,10 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMa } //====================== - ADT.seek(nextpos); + _file.seek(nextpos); } - ADT.close(); + _file.close(); fclose(dirfile); return true; } @@ -242,6 +260,6 @@ bool ADTFile::initFromCache(uint32 map_num, uint32 tileX, uint32 tileY, uint32 o ADTFile::~ADTFile() { - ADT.close(); + _file.close(); delete dirfileCache; } diff --git a/src/tools/vmap4_extractor/adtfile.h b/src/tools/vmap4_extractor/adtfile.h index efe35647147..871499e7589 100644 --- a/src/tools/vmap4_extractor/adtfile.h +++ b/src/tools/vmap4_extractor/adtfile.h @@ -23,88 +23,33 @@ #include "wmo.h" #include "model.h" -#define TILESIZE (533.33333f) -#define CHUNKSIZE ((TILESIZE) / 16.0f) -#define UNITSIZE (CHUNKSIZE / 8.0f) - -class Liquid; - -typedef struct -{ - float x; - float y; - float z; -}svec; - -struct vec -{ - double x; - double y; - double z; -}; - -struct triangle -{ - vec v[3]; -}; - -typedef struct -{ - float v9[16*8+1][16*8+1]; - float v8[16*8][16*8]; -}Cell; - -typedef struct +#pragma pack(push, 1) +namespace ADT { - double v9[9][9]; - double v8[8][8]; - uint16 area_id; - //Liquid *lq; - float waterlevel[9][9]; - uint8 flag; -}chunk; + struct MDDF + { + uint32 Id; + uint32 UniqueId; + Vec3D Position; + Vec3D Rotation; + uint16 Scale; + uint16 Flags; + }; -typedef struct -{ - chunk ch[16][16]; -}mcell; - -struct MapChunkHeader -{ - uint32 flags; - uint32 ix; - uint32 iy; - uint32 nLayers; - uint32 nDoodadRefs; - uint32 ofsHeight; - uint32 ofsNormal; - uint32 ofsLayer; - uint32 ofsRefs; - uint32 ofsAlpha; - uint32 sizeAlpha; - uint32 ofsShadow; - uint32 sizeShadow; - uint32 areaid; - uint32 nMapObjRefs; - uint32 holes; - uint16 s1; - uint16 s2; - uint32 d1; - uint32 d2; - uint32 d3; - uint32 predTex; - uint32 nEffectDoodad; - uint32 ofsSndEmitters; - uint32 nSndEmitters; - uint32 ofsLiquid; - uint32 sizeLiquid; - float zpos; - float xpos; - float ypos; - uint32 textureId; - uint32 props; - uint32 effectId; -}; + struct MODF + { + uint32 Id; + uint32 UniqueId; + Vec3D Position; + Vec3D Rotation; + AaBox3D Bounds; + uint16 Flags; + uint16 DoodadSet; + uint16 NameSet; + uint16 Scale; + }; +} +#pragma pack(pop) struct ADTOutputCache { @@ -115,15 +60,13 @@ struct ADTOutputCache class ADTFile { private: - CASCFile ADT; + CASCFile _file; std::string Adtfilename; bool cacheable; std::vector<ADTOutputCache>* dirfileCache; public: ADTFile(char* filename, bool cache); ~ADTFile(); - int nWMO; - int nMDX; std::vector<std::string> WmoInstanceNames; std::vector<std::string> ModelInstanceNames; bool init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMapId); diff --git a/src/tools/vmap4_extractor/gameobject_extract.cpp b/src/tools/vmap4_extractor/gameobject_extract.cpp index 7e0a871670f..8cd8386db12 100644 --- a/src/tools/vmap4_extractor/gameobject_extract.cpp +++ b/src/tools/vmap4_extractor/gameobject_extract.cpp @@ -23,6 +23,7 @@ #include "model.h" #include "StringFormat.h" #include "vmapexport.h" +#include "VMapDefinitions.h" #include <CascLib.h> #include <algorithm> #include <cstdio> @@ -101,6 +102,8 @@ void ExtractGameobjectModels() return; } + fwrite(VMAP::RAW_VMAP_MAGIC, 1, 8, model_list); + for (uint32 rec = 0; rec < db2.GetRecordCount(); ++rec) { DB2Record record = db2.GetRecord(rec); @@ -114,8 +117,12 @@ void ExtractGameobjectModels() if (!GetHeaderMagic(fileName, &header)) continue; + uint8 isWmo = 0; if (header == MODEL_WMO) + { + isWmo = 1; result = ExtractSingleWmo(fileName); + } else if (header == MODEL_MD20 || header == MODEL_MD21) result = ExtractSingleModel(fileName); else @@ -126,6 +133,7 @@ void ExtractGameobjectModels() uint32 displayId = record.GetId(); uint32 path_length = fileName.length(); fwrite(&displayId, sizeof(uint32), 1, model_list); + fwrite(&isWmo, sizeof(uint8), 1, model_list); fwrite(&path_length, sizeof(uint32), 1, model_list); fwrite(fileName.c_str(), sizeof(char), path_length, model_list); } diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp index 7ba041ef95e..25b1b3bc8d1 100644 --- a/src/tools/vmap4_extractor/model.cpp +++ b/src/tools/vmap4_extractor/model.cpp @@ -21,6 +21,7 @@ #include "wmo.h" #include "adtfile.h" #include "cascfile.h" +#include "VMapDefinitions.h" #include <cassert> #include <algorithm> #include <cstdio> @@ -89,7 +90,7 @@ bool Model::ConvertToVMAPModel(const char * outfilename) printf("Can't create the output file '%s'\n",outfilename); return false; } - fwrite(szRawVMAPMagic, 8, 1, output); + fwrite(VMAP::RAW_VMAP_MAGIC, 8, 1, output); uint32 nVertices = header.nBoundingVertices; fwrite(&nVertices, sizeof(int), 1, output); uint32 nofgroups = 1; @@ -155,29 +156,17 @@ Vec3D fixCoordSystem2(Vec3D v) return Vec3D(v.x, v.z, v.y); } -ModelInstance::ModelInstance(CASCFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache) - : id(0), scale(0), flags(0) +void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache) { - float ff[3]; - f.read(&id, 4); - f.read(ff, 12); - pos = fixCoords(Vec3D(ff[0], ff[1], ff[2])); - f.read(ff, 12); - rot = Vec3D(ff[0], ff[1], ff[2]); - f.read(&scale, 2); - f.read(&flags, 2); // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float? - sc = scale / 1024.0f; + float sc = doodadDef.Scale / 1024.0f; char tempname[512]; sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName); FILE* input = fopen(tempname, "r+b"); if (!input) - { - //printf("ModelInstance::ModelInstance couldn't open %s\n", tempname); return; - } fseek(input, 8, SEEK_SET); // get the correct no of vertices int nVertices; @@ -187,22 +176,24 @@ ModelInstance::ModelInstance(CASCFile& f, char const* ModelInstName, uint32 mapI if (count != 1 || nVertices == 0) return; - uint16 adtId = 0;// not used for models + Vec3D position = fixCoords(doodadDef.Position); + + uint16 nameSet = 0;// not used for models uint32 tcflags = MOD_M2; if (tileX == 65 && tileY == 65) tcflags |= MOD_WORLDSPAWN; if (mapID != originalMapId) tcflags |= MOD_PARENT_SPAWN; - //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, name + //write mapID, tileX, tileY, Flags, NameSet, UniqueId, Pos, Rot, Scale, name fwrite(&mapID, sizeof(uint32), 1, pDirfile); fwrite(&tileX, sizeof(uint32), 1, pDirfile); fwrite(&tileY, sizeof(uint32), 1, pDirfile); fwrite(&tcflags, sizeof(uint32), 1, pDirfile); - fwrite(&adtId, sizeof(uint16), 1, pDirfile); - fwrite(&id, sizeof(uint32), 1, pDirfile); - fwrite(&pos, sizeof(float), 3, pDirfile); - fwrite(&rot, sizeof(float), 3, pDirfile); + fwrite(&nameSet, sizeof(uint16), 1, pDirfile); + fwrite(&doodadDef.UniqueId, sizeof(uint32), 1, pDirfile); + fwrite(&position, sizeof(Vec3D), 1, pDirfile); + fwrite(&doodadDef.Rotation, sizeof(Vec3D), 1, pDirfile); fwrite(&sc, sizeof(float), 1, pDirfile); uint32 nlen = strlen(ModelInstName); fwrite(&nlen, sizeof(uint32), 1, pDirfile); @@ -214,41 +205,25 @@ ModelInstance::ModelInstance(CASCFile& f, char const* ModelInstName, uint32 mapI ADTOutputCache& cacheModelData = dirfileCache->back(); cacheModelData.Flags = tcflags & ~MOD_PARENT_SPAWN; cacheModelData.Data.resize( - sizeof(uint16) + // adtId - sizeof(uint32) + // id - sizeof(float) * 3 + // pos - sizeof(float) * 3 + // rot + sizeof(uint16) + // nameSet + sizeof(uint32) + // doodadDef.UniqueId + sizeof(Vec3D) + // position + sizeof(Vec3D) + // doodadDef.Rotation sizeof(float) + // sc sizeof(uint32) + // nlen nlen); // ModelInstName uint8* cacheData = cacheModelData.Data.data(); -#define CACHE_WRITE(value, size, count, dest) memcpy(dest, value, size * count); dest += size * count; +#define CACHE_WRITE(value, size, cnt, dest) memcpy(dest, value, size * cnt); dest += size * cnt; - CACHE_WRITE(&adtId, sizeof(uint16), 1, cacheData); - CACHE_WRITE(&id, sizeof(uint32), 1, cacheData); - CACHE_WRITE(&pos, sizeof(float), 3, cacheData); - CACHE_WRITE(&rot, sizeof(float), 3, cacheData); + CACHE_WRITE(&nameSet, sizeof(uint16), 1, cacheData); + CACHE_WRITE(&doodadDef.UniqueId, sizeof(uint32), 1, cacheData); + CACHE_WRITE(&position, sizeof(Vec3D), 1, cacheData); + CACHE_WRITE(&doodadDef.Rotation, sizeof(Vec3D), 1, cacheData); CACHE_WRITE(&sc, sizeof(float), 1, cacheData); CACHE_WRITE(&nlen, sizeof(uint32), 1, cacheData); CACHE_WRITE(ModelInstName, sizeof(char), nlen, cacheData); #undef CACHE_WRITE } - - /* int realx1 = (int) ((float) pos.x / 533.333333f); - int realy1 = (int) ((float) pos.z / 533.333333f); - int realx2 = (int) ((float) pos.x / 533.333333f); - int realy2 = (int) ((float) pos.z / 533.333333f); - - fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n", - MapName, - ModelInstName, - (float) pos.x, (float) pos.y, (float) pos.z, - (float) rot.x, (float) rot.y, (float) rot.z, - sc, - nVertices, - realx1, realy1, - realx2, realy2 - ); */ } diff --git a/src/tools/vmap4_extractor/model.h b/src/tools/vmap4_extractor/model.h index 8e8a8c899d6..e9bb2873a52 100644 --- a/src/tools/vmap4_extractor/model.h +++ b/src/tools/vmap4_extractor/model.h @@ -25,6 +25,7 @@ class CASCFile; struct ADTOutputCache; +namespace ADT { struct MDDF; } Vec3D fixCoordSystem(Vec3D v); @@ -51,17 +52,9 @@ public: ~Model() { _unload(); } }; -class ModelInstance +namespace Doodad { -public: - uint32 id; - Vec3D pos, rot; - uint16 scale, flags; - float sc; - - ModelInstance() : id(0), scale(0), flags(0), sc(0.0f) {} - ModelInstance(CASCFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache); - -}; + void Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache); +} #endif diff --git a/src/tools/vmap4_extractor/vec3d.h b/src/tools/vmap4_extractor/vec3d.h index 0fa5f328e58..56d4513045b 100644 --- a/src/tools/vmap4_extractor/vec3d.h +++ b/src/tools/vmap4_extractor/vec3d.h @@ -137,6 +137,12 @@ public: } }; +class AaBox3D +{ +public: + Vec3D min; + Vec3D max; +}; class Vec2D { diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 2a4cf4fcd54..0e2df86f09f 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -70,7 +70,6 @@ bool preciseVectorData = false; //static const char * szWorkDirMaps = ".\\Maps"; const char* szWorkDirWmo = "./Buildings"; -const char* szRawVMAPMagic = "VMAP046"; #define CASC_LOCALES_COUNT 17 char const* CascLocaleNames[CASC_LOCALES_COUNT] = @@ -214,7 +213,7 @@ bool ExtractSingleWmo(std::string& fname) { std::string s = Trinity::StringFormat("FILE%08X.xxx", froot.groupFileDataIDs[i]); WMOGroup fgroup(s); - if(!fgroup.open()) + if (!fgroup.open(&froot)) { printf("Could not open all Group file for: %s\n", plain_name); file_ok = false; diff --git a/src/tools/vmap4_extractor/vmapexport.h b/src/tools/vmap4_extractor/vmapexport.h index c798fb496ba..b81073ebd81 100644 --- a/src/tools/vmap4_extractor/vmapexport.h +++ b/src/tools/vmap4_extractor/vmapexport.h @@ -30,7 +30,6 @@ enum ModelFlags }; extern const char * szWorkDirWmo; -extern const char * szRawVMAPMagic; // vmap magic string for extracted raw vmap data bool FileExists(const char * file); void strToLower(char* str); diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index 1f10e7883b0..ad8e438b462 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -20,6 +20,7 @@ #include "wdtfile.h" #include "adtfile.h" #include "Common.h" +#include "StringFormat.h" #include <cstdio> char * wdtGetPlainName(char * FileName) @@ -104,13 +105,21 @@ bool WDTFile::init(uint32 mapId) // global wmo instance data if (size) { - int32 gnWMO = (int)size / 64; - - for (int i = 0; i < gnWMO; ++i) + uint32 mapObjectCount = size / sizeof(ADT::MODF); + for (uint32 i = 0; i < mapObjectCount; ++i) { - int id; - _file.read(&id, 4); - WMOInstance inst(_file, _wmoNames[id].c_str(), mapId, 65, 65, mapId, dirfile, nullptr); + ADT::MODF mapObjDef; + _file.read(&mapObjDef, sizeof(ADT::MODF)); + if (!(mapObjDef.Flags & 0x8)) + { + MapObject::Extract(mapObjDef, _wmoNames[mapObjDef.Id].c_str(), mapId, 65, 65, mapId, dirfile, nullptr); + } + else + { + std::string fileName = Trinity::StringFormat("FILE%08X.xxx", mapObjDef.Id); + ExtractSingleModel(fileName); + MapObject::Extract(mapObjDef, fileName.c_str(), mapId, 65, 65, mapId, dirfile, nullptr); + } } } } diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index 1c30f503af4..5d804bcf8d4 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -20,6 +20,7 @@ #include "wmo.h" #include "adtfile.h" #include "vec3d.h" +#include "VMapDefinitions.h" #include <cstdio> #include <cstdlib> #include <cassert> @@ -29,8 +30,6 @@ #undef max #include "cascfile.h" -using namespace std; - WMORoot::WMORoot(std::string &filename) : filename(filename), color(0), nTextures(0), nGroups(0), nPortals(0), nLights(0), nDoodadNames(0), nDoodadDefs(0), nDoodadSets(0), RootWMOID(0), flags(0), numLod(0) @@ -102,7 +101,6 @@ bool WMORoot::open() if (fileDataId) groupFileDataIDs.push_back(fileDataId); } - // break; //} } /* @@ -156,7 +154,7 @@ bool WMORoot::ConvertToVMAPRootWmo(FILE* pOutfile) { //printf("Convert RootWmo...\n"); - fwrite(szRawVMAPMagic, 1, 8, pOutfile); + fwrite(VMAP::RAW_VMAP_MAGIC, 1, 8, pOutfile); unsigned int nVectors = 0; fwrite(&nVectors,sizeof(nVectors), 1, pOutfile); // will be filled later fwrite(&nGroups, 4, 1, pOutfile); @@ -168,14 +166,14 @@ WMOGroup::WMOGroup(const std::string &filename) : filename(filename), MOPY(0), MOVI(0), MoviEx(0), MOVT(0), MOBA(0), MobaEx(0), hlq(0), LiquEx(0), LiquBytes(0), groupName(0), descGroupName(0), mogpFlags(0), moprIdx(0), moprNItems(0), nBatchA(0), nBatchB(0), nBatchC(0), fogIdx(0), - liquidType(0), groupWMOID(0), mopy_size(0), moba_size(0), LiquEx_size(0), + groupLiquid(0), groupWMOID(0), mopy_size(0), moba_size(0), LiquEx_size(0), nVertices(0), nTriangles(0), liquflags(0) { memset(bbcorn1, 0, sizeof(bbcorn1)); memset(bbcorn2, 0, sizeof(bbcorn2)); } -bool WMOGroup::open() +bool WMOGroup::open(WMORoot* rootWMO) { CASCFile f(CascStorage, filename.c_str()); if(f.isEof ()) @@ -209,9 +207,19 @@ bool WMOGroup::open() f.read(&nBatchB, 2); f.read(&nBatchC, 4); f.read(&fogIdx, 4); - f.read(&liquidType, 4); + f.read(&groupLiquid, 4); f.read(&groupWMOID,4); + // according to WoW.Dev Wiki: + if (rootWMO->flags & 4) + groupLiquid = GetLiquidTypeId(groupLiquid); + else if (groupLiquid == 15) + groupLiquid = 0; + else + groupLiquid = GetLiquidTypeId(groupLiquid + 1); + + if (groupLiquid) + liquflags |= 2; } else if (!strcmp(fourcc,"MOPY")) { @@ -247,7 +255,7 @@ bool WMOGroup::open() { liquflags |= 1; hlq = new WMOLiquidHeader(); - f.read(hlq, 0x1E); + f.read(hlq, sizeof(WMOLiquidHeader)); LiquEx_size = sizeof(WMOLiquidVert) * hlq->xverts * hlq->yverts; LiquEx = new WMOLiquidVert[hlq->xverts * hlq->yverts]; f.read(LiquEx, LiquEx_size); @@ -255,6 +263,19 @@ bool WMOGroup::open() LiquBytes = new char[nLiquBytes]; f.read(LiquBytes, nLiquBytes); + // Determine legacy liquid type + if (!groupLiquid) + { + for (int i = 0; i < hlq->xtiles * hlq->ytiles; ++i) + { + if ((LiquBytes[i] & 0xF) != 15) + { + groupLiquid = GetLiquidTypeId((LiquBytes[i] & 0xF) + 1); + break; + } + } + } + /* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app); llog << filename; llog << "\nbbox: " << bbcorn1[0] << ", " << bbcorn1[1] << ", " << bbcorn1[2] << " | " << bbcorn2[0] << ", " << bbcorn2[1] << ", " << bbcorn2[2]; @@ -429,78 +450,54 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool precise } //------LIQU------------------------ - if (LiquEx_size != 0) + if (liquflags & 3) { - int LIQU_h[] = {0x5551494C, static_cast<int>(sizeof(WMOLiquidHeader) + LiquEx_size) + hlq->xtiles*hlq->ytiles};// "LIQU" - fwrite(LIQU_h, 4, 2, output); - - // according to WoW.Dev Wiki: - uint32 liquidEntry; - if (rootWMO->flags & 4) - liquidEntry = liquidType; - else if (liquidType == 15) - liquidEntry = 0; - else - liquidEntry = liquidType + 1; - - if (!liquidEntry) + int LIQU_totalSize = sizeof(uint32); + if (liquflags & 1) { - int v1; // edx@1 - int v2; // eax@1 - - v1 = hlq->xtiles * hlq->ytiles; - v2 = 0; - if (v1 > 0) - { - while ((LiquBytes[v2] & 0xF) == 15) - { - ++v2; - if (v2 >= v1) - break; - } - - if (v2 < v1 && (LiquBytes[v2] & 0xF) != 15) - liquidEntry = (LiquBytes[v2] & 0xF) + 1; - } + LIQU_totalSize += sizeof(WMOLiquidHeader); + LIQU_totalSize += LiquEx_size / sizeof(WMOLiquidVert) * sizeof(float); + LIQU_totalSize += hlq->xtiles * hlq->ytiles; } - - if (liquidEntry && liquidEntry < 21) - { - switch ((liquidEntry - 1) & 3) - { - case 0: - liquidEntry = ((mogpFlags & 0x80000) != 0) + 13; - break; - case 1: - liquidEntry = 14; - break; - case 2: - liquidEntry = 19; - break; - case 3: - liquidEntry = 20; - break; - } - } - - hlq->type = liquidEntry; + int LIQU_h[] = { 0x5551494C, LIQU_totalSize };// "LIQU" + fwrite(LIQU_h, 4, 2, output); /* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app); llog << filename; llog << ":\nliquidEntry: " << liquidEntry << " type: " << hlq->type << " (root:" << rootWMO->flags << " group:" << flags << ")\n"; llog.close(); */ - fwrite(hlq, sizeof(WMOLiquidHeader), 1, output); - // only need height values, the other values are unknown anyway - for (uint32 i = 0; i<LiquEx_size/sizeof(WMOLiquidVert); ++i) - fwrite(&LiquEx[i].height, sizeof(float), 1, output); - // todo: compress to bit field - fwrite(LiquBytes, 1, hlq->xtiles*hlq->ytiles, output); + fwrite(&groupLiquid, sizeof(uint32), 1, output); + if (liquflags & 1) + { + fwrite(hlq, sizeof(WMOLiquidHeader), 1, output); + // only need height values, the other values are unknown anyway + for (uint32 i = 0; i < LiquEx_size / sizeof(WMOLiquidVert); ++i) + fwrite(&LiquEx[i].height, sizeof(float), 1, output); + // todo: compress to bit field + fwrite(LiquBytes, 1, hlq->xtiles * hlq->ytiles, output); + } } return nColTriangles; } +uint32 WMOGroup::GetLiquidTypeId(uint32 liquidTypeId) +{ + if (liquidTypeId < 21 && liquidTypeId) + { + switch (((static_cast<uint8>(liquidTypeId) - 1) & 3)) + { + case 0: return ((mogpFlags & 0x80000) != 0) + 13; + case 1: return 14; + case 2: return 19; + case 3: return 20; + default: break; + } + } + return liquidTypeId; +} + WMOGroup::~WMOGroup() { delete [] MOPY; @@ -512,33 +509,11 @@ WMOGroup::~WMOGroup() delete [] LiquBytes; } -WMOInstance::WMOInstance(CASCFile& f, char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache) - : currx(0), curry(0), wmo(NULL), doodadset(0), pos(), indx(0), id(0) +void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache) { - float ff[3]; - f.read(&id, 4); - f.read(ff,12); - pos = Vec3D(ff[0],ff[1],ff[2]); - f.read(ff,12); - rot = Vec3D(ff[0],ff[1],ff[2]); - f.read(ff,12); - pos2 = Vec3D(ff[0],ff[1],ff[2]); // bounding box corners - f.read(ff,12); - pos3 = Vec3D(ff[0],ff[1],ff[2]); // bounding box corners - - uint16 fflags; - f.read(&fflags, 2); - - uint16 doodadSet; - f.read(&doodadSet, 2); - - uint16 trash,adtId; - f.read(&adtId,2); - f.read(&trash,2); - // destructible wmo, do not dump. we can handle the vmap for these // in dynamic tree (gameobject vmaps) - if ((fflags & 0x01) != 0) + if ((mapObjDef.Flags & 0x1) != 0) return; //-----------add_in _dir_file---------------- @@ -562,37 +537,41 @@ WMOInstance::WMOInstance(CASCFile& f, char const* WmoInstName, uint32 mapID, uin if (count != 1 || nVertices == 0) return; - float x,z; - x = pos.x; - z = pos.z; - if(x==0 && z == 0) + Vec3D position = mapObjDef.Position; + + float x, z; + x = position.x; + z = position.z; + if (x == 0 && z == 0) { - pos.x = 533.33333f*32; - pos.z = 533.33333f*32; + position.x = 533.33333f * 32; + position.z = 533.33333f * 32; } - pos = fixCoords(pos); - pos2 = fixCoords(pos2); - pos3 = fixCoords(pos3); + position = fixCoords(position); + AaBox3D bounds; + bounds.min = fixCoords(mapObjDef.Bounds.min); + bounds.max = fixCoords(mapObjDef.Bounds.max); float scale = 1.0f; + if (mapObjDef.Flags & 0x4) + scale = mapObjDef.Scale / 1024.0f; uint32 flags = MOD_HAS_BOUND; if (tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN; if (mapID != originalMapId) flags |= MOD_PARENT_SPAWN; - //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name + //write mapID, tileX, tileY, Flags, NameSet, UniqueId, Pos, Rot, Scale, Bound_lo, Bound_hi, name fwrite(&mapID, sizeof(uint32), 1, pDirfile); fwrite(&tileX, sizeof(uint32), 1, pDirfile); fwrite(&tileY, sizeof(uint32), 1, pDirfile); fwrite(&flags, sizeof(uint32), 1, pDirfile); - fwrite(&adtId, sizeof(uint16), 1, pDirfile); - fwrite(&id, sizeof(uint32), 1, pDirfile); - fwrite(&pos, sizeof(float), 3, pDirfile); - fwrite(&rot, sizeof(float), 3, pDirfile); + fwrite(&mapObjDef.NameSet, sizeof(uint16), 1, pDirfile); + fwrite(&mapObjDef.UniqueId, sizeof(uint32), 1, pDirfile); + fwrite(&position, sizeof(Vec3D), 1, pDirfile); + fwrite(&mapObjDef.Rotation, sizeof(Vec3D), 1, pDirfile); fwrite(&scale, sizeof(float), 1, pDirfile); - fwrite(&pos2, sizeof(float), 3, pDirfile); - fwrite(&pos3, sizeof(float), 3, pDirfile); + fwrite(&bounds, sizeof(AaBox3D), 1, pDirfile); uint32 nlen = strlen(WmoInstName); fwrite(&nlen, sizeof(uint32), 1, pDirfile); fwrite(WmoInstName, sizeof(char), nlen, pDirfile); @@ -603,41 +582,27 @@ WMOInstance::WMOInstance(CASCFile& f, char const* WmoInstName, uint32 mapID, uin ADTOutputCache& cacheModelData = dirfileCache->back(); cacheModelData.Flags = flags & ~MOD_PARENT_SPAWN; cacheModelData.Data.resize( - sizeof(uint16) + // adtId - sizeof(uint32) + // id - sizeof(float) * 3 + // pos - sizeof(float) * 3 + // rot + sizeof(uint16) + // mapObjDef.NameSet + sizeof(uint32) + // mapObjDef.UniqueId + sizeof(Vec3D) + // position + sizeof(Vec3D) + // mapObjDef.Rotation sizeof(float) + // scale - sizeof(float) * 3 + // pos2 - sizeof(float) * 3 + // pos3 + sizeof(AaBox3D) + // bounds sizeof(uint32) + // nlen nlen); // WmoInstName uint8* cacheData = cacheModelData.Data.data(); #define CACHE_WRITE(value, size, count, dest) memcpy(dest, value, size * count); dest += size * count; - CACHE_WRITE(&adtId, sizeof(uint16), 1, cacheData); - CACHE_WRITE(&id, sizeof(uint32), 1, cacheData); - CACHE_WRITE(&pos, sizeof(float), 3, cacheData); - CACHE_WRITE(&rot, sizeof(float), 3, cacheData); + CACHE_WRITE(&mapObjDef.NameSet, sizeof(uint16), 1, cacheData); + CACHE_WRITE(&mapObjDef.UniqueId, sizeof(uint32), 1, cacheData); + CACHE_WRITE(&position, sizeof(Vec3D), 1, cacheData); + CACHE_WRITE(&mapObjDef.Rotation, sizeof(Vec3D), 1, cacheData); CACHE_WRITE(&scale, sizeof(float), 1, cacheData); - CACHE_WRITE(&pos2, sizeof(float), 3, cacheData); - CACHE_WRITE(&pos3, sizeof(float), 3, cacheData); + CACHE_WRITE(&bounds, sizeof(AaBox3D), 1, cacheData); CACHE_WRITE(&nlen, sizeof(uint32), 1, cacheData); CACHE_WRITE(WmoInstName, sizeof(char), nlen, cacheData); #undef CACHE_WRITE } - - /* fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n", - MapName, - WmoInstName, - (float) x, (float) pos.y, (float) z, - (float) rot.x, (float) rot.y, (float) rot.z, - nVertices, - realx1, realy1, - realx2, realy2 - ); */ - - // fclose(dirfile); } diff --git a/src/tools/vmap4_extractor/wmo.h b/src/tools/vmap4_extractor/wmo.h index 8bb147e986f..6bc33eb9cbc 100644 --- a/src/tools/vmap4_extractor/wmo.h +++ b/src/tools/vmap4_extractor/wmo.h @@ -18,8 +18,6 @@ #ifndef WMO_H #define WMO_H -#define TILESIZE (533.33333f) -#define CHUNKSIZE ((TILESIZE) / 16.0f) #include <string> #include <set> @@ -44,6 +42,7 @@ class WMOInstance; class WMOManager; class CASCFile; struct ADTOutputCache; +namespace ADT { struct MODF; } /* for whatever reason a certain company just can't stick to one coordinate system... */ static inline Vec3D fixCoords(const Vec3D &v){ return Vec3D(v.z, v.x, v.y); } @@ -67,17 +66,17 @@ public: bool ConvertToVMAPRootWmo(FILE* output); }; +#pragma pack(push, 1) + struct WMOLiquidHeader { int xverts, yverts, xtiles, ytiles; float pos_x; float pos_y; float pos_z; - short type; + short material; }; -#pragma pack(push, 1) - struct WMOLiquidVert { uint16 unk1; @@ -111,7 +110,7 @@ public: uint16 moprNItems; uint16 nBatchA; uint16 nBatchB; - uint32 nBatchC, fogIdx, liquidType, groupWMOID; + uint32 nBatchC, fogIdx, groupLiquid, groupWMOID; int mopy_size, moba_size; int LiquEx_size; @@ -122,24 +121,14 @@ public: WMOGroup(std::string const& filename); ~WMOGroup(); - bool open(); + bool open(WMORoot* rootWMO); int ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool preciseVectorData); + uint32 GetLiquidTypeId(uint32 liquidTypeId); }; -class WMOInstance +namespace MapObject { - static std::set<int> ids; -public: - std::string MapName; - int currx; - int curry; - WMOGroup* wmo; - int doodadset; - Vec3D pos; - Vec3D pos2, pos3, rot; - uint32 indx, id; - - WMOInstance(CASCFile&f , char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache); -}; + void Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache); +} #endif |
