diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/vmap4_extractor/adtfile.cpp | 22 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/adtfile.h | 2 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/gameobject_extract.cpp | 6 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/model.cpp | 138 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/model.h | 11 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/vec3d.h | 5 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/vmapexport.cpp | 44 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/vmapexport.h | 8 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/wdtfile.cpp | 4 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/wmo.cpp | 65 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/wmo.h | 36 |
11 files changed, 270 insertions, 71 deletions
diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index 5a2838df444..aea160fa884 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -21,10 +21,7 @@ #include "StringFormat.h" #include <algorithm> #include <cstdio> - -#ifdef WIN32 -#define snprintf _snprintf -#endif +#include "Errors.h" char const* GetPlainName(char const* FileName) { @@ -63,11 +60,12 @@ void FixNameCase(char* name, size_t len) void FixNameSpaces(char* name, size_t len) { - for (size_t i=0; i<len-3; i++) - { - if(name[i] == ' ') + if (len < 3) + return; + + for (size_t i = 0; i < len - 3; i++) + if (name[i] == ' ') name[i] = '_'; - } } char* GetExtension(char* FileName) @@ -137,7 +135,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMa FixNameCase(s, strlen(s)); FixNameSpaces(s, strlen(s)); - ModelInstanceNames.push_back(s); + ModelInstanceNames.emplace_back(s); ExtractSingleModel(path); @@ -161,7 +159,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMa FixNameCase(s, strlen(s)); FixNameSpaces(s, strlen(s)); - WmoInstanceNames.push_back(s); + WmoInstanceNames.emplace_back(s); ExtractSingleWmo(path); @@ -207,12 +205,14 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY, uint32 originalMa if (!(mapObjDef.Flags & 0x8)) { MapObject::Extract(mapObjDef, WmoInstanceNames[mapObjDef.Id].c_str(), map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); + Doodad::ExtractSet(WmoDoodads[WmoInstanceNames[mapObjDef.Id]], mapObjDef, map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); } else { std::string fileName = Trinity::StringFormat("FILE%08X.xxx", mapObjDef.Id); - ExtractSingleModel(fileName); + ExtractSingleWmo(fileName); MapObject::Extract(mapObjDef, fileName.c_str(), map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); + Doodad::ExtractSet(WmoDoodads[fileName], mapObjDef, map_num, tileX, tileY, originalMapId, dirfile, dirfileCache); } } diff --git a/src/tools/vmap4_extractor/adtfile.h b/src/tools/vmap4_extractor/adtfile.h index 871499e7589..349879daec2 100644 --- a/src/tools/vmap4_extractor/adtfile.h +++ b/src/tools/vmap4_extractor/adtfile.h @@ -44,7 +44,7 @@ namespace ADT Vec3D Rotation; AaBox3D Bounds; uint16 Flags; - uint16 DoodadSet; + uint16 DoodadSet; // can be larger than number of doodad sets in WMO uint16 NameSet; uint16 Scale; }; diff --git a/src/tools/vmap4_extractor/gameobject_extract.cpp b/src/tools/vmap4_extractor/gameobject_extract.cpp index 8cd8386db12..36d8b7c565a 100644 --- a/src/tools/vmap4_extractor/gameobject_extract.cpp +++ b/src/tools/vmap4_extractor/gameobject_extract.cpp @@ -30,7 +30,11 @@ bool ExtractSingleModel(std::string& fname) { - if (fname.substr(fname.length() - 4, 4) == ".mdx") + if (fname.length() < 4) + return false; + + std::string extension = fname.substr(fname.length() - 4, 4); + if (extension == ".mdx" || extension == ".MDX" || extension == ".mdl" || extension == ".MDL") { fname.erase(fname.length() - 2, 2); fname.append("2"); diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp index 25b1b3bc8d1..cfe5584921a 100644 --- a/src/tools/vmap4_extractor/model.cpp +++ b/src/tools/vmap4_extractor/model.cpp @@ -17,14 +17,16 @@ */ #include "vmapexport.h" +#include "Errors.h" #include "model.h" #include "wmo.h" #include "adtfile.h" #include "cascfile.h" #include "VMapDefinitions.h" -#include <cassert> +#include <G3D/Quat.h> #include <algorithm> #include <cstdio> +#include <limits> extern CASC::StorageHandle CascStorage; @@ -146,21 +148,14 @@ bool Model::ConvertToVMAPModel(const char * outfilename) } -Vec3D fixCoordSystem(Vec3D v) +Vec3D fixCoordSystem(Vec3D const& v) { return Vec3D(v.x, v.z, -v.y); } -Vec3D fixCoordSystem2(Vec3D v) +void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, + FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache) { - return Vec3D(v.x, v.z, v.y); -} - -void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache) -{ - // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float? - float sc = doodadDef.Scale / 1024.0f; - char tempname[512]; sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName); FILE* input = fopen(tempname, "r+b"); @@ -176,9 +171,13 @@ void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint if (count != 1 || nVertices == 0) return; + // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float? + float sc = doodadDef.Scale / 1024.0f; + Vec3D position = fixCoords(doodadDef.Position); uint16 nameSet = 0;// not used for models + uint32 uniqueId = GenerateUniqueObjectId(doodadDef.UniqueId, 0); uint32 tcflags = MOD_M2; if (tileX == 65 && tileY == 65) tcflags |= MOD_WORLDSPAWN; @@ -191,7 +190,7 @@ void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint fwrite(&tileY, sizeof(uint32), 1, pDirfile); fwrite(&tcflags, sizeof(uint32), 1, pDirfile); fwrite(&nameSet, sizeof(uint16), 1, pDirfile); - fwrite(&doodadDef.UniqueId, sizeof(uint32), 1, pDirfile); + fwrite(&uniqueId, sizeof(uint32), 1, pDirfile); fwrite(&position, sizeof(Vec3D), 1, pDirfile); fwrite(&doodadDef.Rotation, sizeof(Vec3D), 1, pDirfile); fwrite(&sc, sizeof(float), 1, pDirfile); @@ -206,7 +205,7 @@ void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint cacheModelData.Flags = tcflags & ~MOD_PARENT_SPAWN; cacheModelData.Data.resize( sizeof(uint16) + // nameSet - sizeof(uint32) + // doodadDef.UniqueId + sizeof(uint32) + // uniqueId sizeof(Vec3D) + // position sizeof(Vec3D) + // doodadDef.Rotation sizeof(float) + // sc @@ -217,13 +216,122 @@ void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint #define CACHE_WRITE(value, size, cnt, dest) memcpy(dest, value, size * cnt); dest += size * cnt; CACHE_WRITE(&nameSet, sizeof(uint16), 1, cacheData); - CACHE_WRITE(&doodadDef.UniqueId, sizeof(uint32), 1, cacheData); + CACHE_WRITE(&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 +void Doodad::ExtractSet(WMODoodadData const& doodadData, ADT::MODF const& wmo, uint32 mapID, uint32 tileX, uint32 tileY, uint32 originalMapId, + FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache) +{ + if (wmo.DoodadSet >= doodadData.Sets.size()) + return; + + G3D::Vector3 wmoPosition(wmo.Position.z, wmo.Position.x, wmo.Position.y); + G3D::Matrix3 wmoRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::toRadians(wmo.Rotation.y), G3D::toRadians(wmo.Rotation.x), G3D::toRadians(wmo.Rotation.z)); + + uint16 doodadId = 0; + WMO::MODS const& doodadSetData = doodadData.Sets[wmo.DoodadSet]; + for (uint16 doodadIndex : doodadData.References) + { + if (doodadIndex < doodadSetData.StartIndex || + doodadIndex >= doodadSetData.StartIndex + doodadSetData.Count) + continue; + + WMO::MODD const& doodad = doodadData.Spawns[doodadIndex]; + + char ModelInstName[1024]; + sprintf(ModelInstName, "%s", GetPlainName(&doodadData.Paths[doodad.NameIndex])); + uint32 nlen = strlen(ModelInstName); + FixNameCase(ModelInstName, nlen); + FixNameSpaces(ModelInstName, nlen); + if (nlen > 3) + { + char const* extension = &ModelInstName[nlen - 4]; + if (!strcmp(extension, ".mdx") || !strcmp(extension, ".mdl")) + { + ModelInstName[nlen - 2] = '2'; + ModelInstName[nlen - 1] = '\0'; + } + } + + char tempname[512]; + sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName); + FILE* input = fopen(tempname, "r+b"); + if (!input) + continue; + + fseek(input, 8, SEEK_SET); // get the correct no of vertices + int nVertices; + int count = fread(&nVertices, sizeof(int), 1, input); + fclose(input); + + if (count != 1 || nVertices == 0) + continue; + + ASSERT(doodadId < std::numeric_limits<uint16>::max()); + ++doodadId; + + G3D::Vector3 position = wmoPosition + (wmoRotation * G3D::Vector3(doodad.Position.x, doodad.Position.y, doodad.Position.z)); + + Vec3D rotation; + (G3D::Quat(doodad.Rotation.X, doodad.Rotation.Y, doodad.Rotation.Z, doodad.Rotation.W) + .toRotationMatrix() * wmoRotation) + .toEulerAnglesXYZ(rotation.z, rotation.x, rotation.y); + + rotation.z = G3D::toDegrees(rotation.z); + rotation.x = G3D::toDegrees(rotation.x); + rotation.y = G3D::toDegrees(rotation.y); + + uint16 nameSet = 0; // not used for models + uint32 uniqueId = GenerateUniqueObjectId(wmo.UniqueId, doodadId); + uint32 tcflags = MOD_M2; + if (tileX == 65 && tileY == 65) + tcflags |= MOD_WORLDSPAWN; + if (mapID != originalMapId) + tcflags |= MOD_PARENT_SPAWN; + + //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(&nameSet, sizeof(uint16), 1, pDirfile); + fwrite(&uniqueId, sizeof(uint32), 1, pDirfile); + fwrite(&position, sizeof(Vec3D), 1, pDirfile); + fwrite(&rotation, sizeof(Vec3D), 1, pDirfile); + fwrite(&doodad.Scale, sizeof(float), 1, pDirfile); + fwrite(&nlen, sizeof(uint32), 1, pDirfile); + fwrite(ModelInstName, sizeof(char), nlen, pDirfile); + + if (dirfileCache) + { + dirfileCache->emplace_back(); + ADTOutputCache& cacheModelData = dirfileCache->back(); + cacheModelData.Flags = tcflags & ~MOD_PARENT_SPAWN; + cacheModelData.Data.resize( + sizeof(uint16) + // nameSet + sizeof(uint32) + // uniqueId + sizeof(Vec3D) + // position + sizeof(Vec3D) + // rotation + sizeof(float) + // doodad.Scale + sizeof(uint32) + // nlen + nlen); // ModelInstName + + uint8* cacheData = cacheModelData.Data.data(); + CACHE_WRITE(&nameSet, sizeof(uint16), 1, cacheData); + CACHE_WRITE(&uniqueId, sizeof(uint32), 1, cacheData); + CACHE_WRITE(&position, sizeof(Vec3D), 1, cacheData); + CACHE_WRITE(&rotation, sizeof(Vec3D), 1, cacheData); + CACHE_WRITE(&doodad.Scale, sizeof(float), 1, cacheData); + CACHE_WRITE(&nlen, sizeof(uint32), 1, cacheData); + CACHE_WRITE(ModelInstName, sizeof(char), nlen, cacheData); + } } } + +#undef CACHE_WRITE diff --git a/src/tools/vmap4_extractor/model.h b/src/tools/vmap4_extractor/model.h index e9bb2873a52..f1e83606471 100644 --- a/src/tools/vmap4_extractor/model.h +++ b/src/tools/vmap4_extractor/model.h @@ -25,9 +25,10 @@ class CASCFile; struct ADTOutputCache; -namespace ADT { struct MDDF; } +struct WMODoodadData; +namespace ADT { struct MDDF; struct MODF; } -Vec3D fixCoordSystem(Vec3D v); +Vec3D fixCoordSystem(Vec3D const& v); class Model { @@ -54,7 +55,11 @@ public: namespace Doodad { - void Extract(ADT::MDDF const& doodadDef, 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); + + void ExtractSet(WMODoodadData const& doodadData, ADT::MODF const& wmo, 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 56d4513045b..ae64bdad615 100644 --- a/src/tools/vmap4_extractor/vec3d.h +++ b/src/tools/vmap4_extractor/vec3d.h @@ -251,4 +251,9 @@ inline void rotate(float x0, float y0, float *x, float *y, float angle) *y = xa*sinf(angle) + ya*cosf(angle) + y0; } +struct Quaternion +{ + float X, Y, Z, W; +}; + #endif diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index ea253dfd181..57949336dc8 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -65,10 +65,10 @@ std::map<uint32, map_info> map_ids; std::unordered_set<uint32> maps_that_are_parents; boost::filesystem::path input_path; bool preciseVectorData = false; +std::unordered_map<std::string, WMODoodadData> WmoDoodads; // Constants -//static const char * szWorkDirMaps = ".\\Maps"; const char* szWorkDirWmo = "./Buildings"; #define CASC_LOCALES_COUNT 17 @@ -141,6 +141,13 @@ uint32 GetInstalledLocalesMask() return 0; } +std::map<std::pair<uint32, uint16>, uint32> uniqueObjectIds; + +uint32 GenerateUniqueObjectId(uint32 clientId, uint16 clientDoodadId) +{ + return uniqueObjectIds.emplace(std::make_pair(clientId, clientDoodadId), uniqueObjectIds.size() + 1).first->second; +} + // Local testing functions bool FileExists(const char* file) { @@ -152,24 +159,16 @@ bool FileExists(const char* file) return false; } -void strToLower(char* str) -{ - while(*str) - { - *str=tolower(*str); - ++str; - } -} - bool ExtractSingleWmo(std::string& fname) { // Copy files from archive + std::string originalName = fname; char szLocalFile[1024]; - const char * plain_name = GetPlainName(fname.c_str()); + char* plain_name = GetPlainName(&fname[0]); + FixNameCase(plain_name, strlen(plain_name)); + FixNameSpaces(plain_name, strlen(plain_name)); sprintf(szLocalFile, "%s/%s", szWorkDirWmo, plain_name); - FixNameCase(szLocalFile, strlen(szLocalFile)); - FixNameSpaces(szLocalFile, strlen(szLocalFile)); if (FileExists(szLocalFile)) return true; @@ -193,9 +192,9 @@ bool ExtractSingleWmo(std::string& fname) return true; bool file_ok = true; - printf("Extracting %s\n", fname.c_str()); - WMORoot froot(fname); - if(!froot.open()) + printf("Extracting %s\n", originalName.c_str()); + WMORoot froot(originalName); + if (!froot.open()) { printf("Couldn't open RootWmo!!!\n"); return true; @@ -207,6 +206,8 @@ bool ExtractSingleWmo(std::string& fname) return false; } froot.ConvertToVMAPRootWmo(output); + WMODoodadData& doodads = WmoDoodads[plain_name]; + std::swap(doodads, froot.DoodadData); int Wmo_nVertices = 0; //printf("root has %d groups\n", froot->nGroups); for (std::size_t i = 0; i < froot.groupFileDataIDs.size(); ++i) @@ -221,6 +222,17 @@ bool ExtractSingleWmo(std::string& fname) } Wmo_nVertices += fgroup.ConvertToVMAPGroupWmo(output, preciseVectorData); + for (uint16 groupReference : fgroup.DoodadReferences) + { + if (groupReference >= doodads.Spawns.size()) + continue; + + uint32 doodadNameIndex = doodads.Spawns[groupReference].NameIndex; + if (froot.ValidDoodadNames.find(doodadNameIndex) == froot.ValidDoodadNames.end()) + continue; + + doodads.References.insert(groupReference); + } } fseek(output, 8, SEEK_SET); // store the correct no of vertices diff --git a/src/tools/vmap4_extractor/vmapexport.h b/src/tools/vmap4_extractor/vmapexport.h index b81073ebd81..74221e17a27 100644 --- a/src/tools/vmap4_extractor/vmapexport.h +++ b/src/tools/vmap4_extractor/vmapexport.h @@ -19,7 +19,9 @@ #ifndef VMAPEXPORT_H #define VMAPEXPORT_H +#include "Define.h" #include <string> +#include <unordered_map> enum ModelFlags { @@ -29,10 +31,14 @@ enum ModelFlags MOD_PARENT_SPAWN = 1 << 3 }; +struct WMODoodadData; + extern const char * szWorkDirWmo; +extern std::unordered_map<std::string, WMODoodadData> WmoDoodads; + +uint32 GenerateUniqueObjectId(uint32 clientId, uint16 clientDoodadId); bool FileExists(const char * file); -void strToLower(char* str); bool ExtractSingleWmo(std::string& fname); bool ExtractSingleModel(std::string& fname); diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index ad8e438b462..ba2689ed657 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -113,12 +113,14 @@ bool WDTFile::init(uint32 mapId) if (!(mapObjDef.Flags & 0x8)) { MapObject::Extract(mapObjDef, _wmoNames[mapObjDef.Id].c_str(), mapId, 65, 65, mapId, dirfile, nullptr); + Doodad::ExtractSet(WmoDoodads[_wmoNames[mapObjDef.Id]], mapObjDef, mapId, 65, 65, mapId, dirfile, nullptr); } else { std::string fileName = Trinity::StringFormat("FILE%08X.xxx", mapObjDef.Id); - ExtractSingleModel(fileName); + ExtractSingleWmo(fileName); MapObject::Extract(mapObjDef, fileName.c_str(), mapId, 65, 65, mapId, dirfile, nullptr); + Doodad::ExtractSet(WmoDoodads[fileName], mapObjDef, mapId, 65, 65, mapId, dirfile, nullptr); } } } diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index 0455ab718f9..01cd164bec3 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -17,20 +17,17 @@ */ #include "vmapexport.h" -#include "wmo.h" #include "adtfile.h" +#include "cascfile.h" #include "vec3d.h" #include "VMapDefinitions.h" +#include "wmo.h" +#include <fstream> +#include <map> #include <cstdio> #include <cstdlib> -#include <cassert> -#include <map> -#include <fstream> -#undef min -#undef max -#include "cascfile.h" -WMORoot::WMORoot(std::string &filename) +WMORoot::WMORoot(std::string const& 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) { @@ -78,6 +75,37 @@ bool WMORoot::open() f.read(&flags, 2); f.read(&numLod, 2); } + else if (!strcmp(fourcc, "MODS")) + { + DoodadData.Sets.resize(size / sizeof(WMO::MODS)); + f.read(DoodadData.Sets.data(), size); + } + else if (!strcmp(fourcc,"MODN")) + { + char* ptr = f.getPointer(); + char* end = ptr + size; + DoodadData.Paths = std::make_unique<char[]>(size); + memcpy(DoodadData.Paths.get(), ptr, size); + while (ptr < end) + { + std::string path = ptr; + + char* s = GetPlainName(ptr); + FixNameCase(s, strlen(s)); + FixNameSpaces(s, strlen(s)); + + uint32 doodadNameIndex = ptr - f.getPointer(); + ptr += path.length() + 1; + + if (ExtractSingleModel(path)) + ValidDoodadNames.insert(doodadNameIndex); + } + } + else if (!strcmp(fourcc,"MODD")) + { + DoodadData.Spawns.resize(size / sizeof(WMO::MODD)); + f.read(DoodadData.Spawns.data(), size); + } else if (!strcmp(fourcc, "GFID")) { // full LOD reading code for reference @@ -119,15 +147,6 @@ bool WMORoot::open() else if (!strcmp(fourcc,"MOLT")) { } - else if (!strcmp(fourcc,"MODN")) - { - } - else if (!strcmp(fourcc,"MODS")) - { - } - else if (!strcmp(fourcc,"MODD")) - { - } else if (!strcmp(fourcc,"MOSB")) { } @@ -251,6 +270,11 @@ bool WMOGroup::open(WMORoot* rootWMO) moba_size = size/2; f.read(MOBA, size); } + else if (!strcmp(fourcc,"MODR")) + { + DoodadReferences.resize(size / sizeof(uint16)); + f.read(DoodadReferences.data(), size); + } else if (!strcmp(fourcc,"MLIQ")) { liquflags |= 1; @@ -555,6 +579,7 @@ void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, uin float scale = 1.0f; if (mapObjDef.Flags & 0x4) scale = mapObjDef.Scale / 1024.0f; + uint32 uniqueId = GenerateUniqueObjectId(mapObjDef.UniqueId, 0); uint32 flags = MOD_HAS_BOUND; if (tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN; @@ -567,7 +592,7 @@ void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, uin fwrite(&tileY, sizeof(uint32), 1, pDirfile); fwrite(&flags, sizeof(uint32), 1, pDirfile); fwrite(&mapObjDef.NameSet, sizeof(uint16), 1, pDirfile); - fwrite(&mapObjDef.UniqueId, sizeof(uint32), 1, pDirfile); + fwrite(&uniqueId, sizeof(uint32), 1, pDirfile); fwrite(&position, sizeof(Vec3D), 1, pDirfile); fwrite(&mapObjDef.Rotation, sizeof(Vec3D), 1, pDirfile); fwrite(&scale, sizeof(float), 1, pDirfile); @@ -583,7 +608,7 @@ void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, uin cacheModelData.Flags = flags & ~MOD_PARENT_SPAWN; cacheModelData.Data.resize( sizeof(uint16) + // mapObjDef.NameSet - sizeof(uint32) + // mapObjDef.UniqueId + sizeof(uint32) + // uniqueId sizeof(Vec3D) + // position sizeof(Vec3D) + // mapObjDef.Rotation sizeof(float) + // scale @@ -595,7 +620,7 @@ void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, uin #define CACHE_WRITE(value, size, count, dest) memcpy(dest, value, size * count); dest += size * count; CACHE_WRITE(&mapObjDef.NameSet, sizeof(uint16), 1, cacheData); - CACHE_WRITE(&mapObjDef.UniqueId, sizeof(uint32), 1, cacheData); + CACHE_WRITE(&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); diff --git a/src/tools/vmap4_extractor/wmo.h b/src/tools/vmap4_extractor/wmo.h index f686bfb505b..6e290c1d548 100644 --- a/src/tools/vmap4_extractor/wmo.h +++ b/src/tools/vmap4_extractor/wmo.h @@ -20,7 +20,7 @@ #define WMO_H #include <string> -#include <set> +#include <unordered_set> #include <vector> #include "vec3d.h" #include "cascfile.h" @@ -44,9 +44,37 @@ class CASCFile; struct ADTOutputCache; namespace ADT { struct MODF; } +namespace WMO +{ + struct MODS + { + char Name[20]; + uint32 StartIndex; // index of first doodad instance in this set + uint32 Count; // number of doodad instances in this set + char _pad[4]; + }; + + struct MODD + { + uint32 NameIndex : 24; + Vec3D Position; + Quaternion Rotation; + float Scale; + uint32 Color; + }; +} + /* 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); } +struct WMODoodadData +{ + std::vector<WMO::MODS> Sets; + std::unique_ptr<char[]> Paths; + std::vector<WMO::MODD> Spawns; + std::unordered_set<uint16> References; +}; + class WMORoot { private: @@ -58,9 +86,11 @@ public: float bbcorn2[3]; uint16 flags, numLod; + WMODoodadData DoodadData; + std::unordered_set<uint32> ValidDoodadNames; std::vector<uint32> groupFileDataIDs; - WMORoot(std::string& filename); + WMORoot(std::string const& filename); bool open(); bool ConvertToVMAPRootWmo(FILE* output); @@ -118,6 +148,8 @@ public: int nTriangles; // number when loaded uint32 liquflags; + std::vector<uint16> DoodadReferences; + WMOGroup(std::string const& filename); ~WMOGroup(); |