aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tools/vmap4_extractor/adtfile.cpp22
-rw-r--r--src/tools/vmap4_extractor/adtfile.h2
-rw-r--r--src/tools/vmap4_extractor/gameobject_extract.cpp6
-rw-r--r--src/tools/vmap4_extractor/model.cpp138
-rw-r--r--src/tools/vmap4_extractor/model.h11
-rw-r--r--src/tools/vmap4_extractor/vec3d.h5
-rw-r--r--src/tools/vmap4_extractor/vmapexport.cpp44
-rw-r--r--src/tools/vmap4_extractor/vmapexport.h8
-rw-r--r--src/tools/vmap4_extractor/wdtfile.cpp4
-rw-r--r--src/tools/vmap4_extractor/wmo.cpp65
-rw-r--r--src/tools/vmap4_extractor/wmo.h36
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();