aboutsummaryrefslogtreecommitdiff
path: root/src/tools/vmap4_extractor
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2018-04-07 21:56:19 +0200
committerShauren <shauren.trinity@gmail.com>2018-04-07 21:56:19 +0200
commit2c64bb97e6fddcbd15ef39fde3d0828bbf600ec6 (patch)
tree27f9cf5bbfa3693a33b2289da36e5f6307001ce0 /src/tools/vmap4_extractor
parent5c7a5ddcf4735a38c76ae16b416abff2dc94fb62 (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.cpp64
-rw-r--r--src/tools/vmap4_extractor/adtfile.h109
-rw-r--r--src/tools/vmap4_extractor/gameobject_extract.cpp8
-rw-r--r--src/tools/vmap4_extractor/model.cpp67
-rw-r--r--src/tools/vmap4_extractor/model.h15
-rw-r--r--src/tools/vmap4_extractor/vec3d.h6
-rw-r--r--src/tools/vmap4_extractor/vmapexport.cpp3
-rw-r--r--src/tools/vmap4_extractor/vmapexport.h1
-rw-r--r--src/tools/vmap4_extractor/wdtfile.cpp21
-rw-r--r--src/tools/vmap4_extractor/wmo.cpp225
-rw-r--r--src/tools/vmap4_extractor/wmo.h31
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