mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 18:15:31 +01:00
Tools/vmapextractor: Improved vmap detail level by extracting wmo doodads (tables, chairs etc)
(cherry picked from commit fb0a1de5c1)
This commit is contained in:
@@ -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)
|
||||
{
|
||||
@@ -46,7 +43,10 @@ char* GetPlainName(char* FileName)
|
||||
|
||||
void fixnamen(char* name, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i < len-3; i++)
|
||||
if (len < 3)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < len - 3; i++)
|
||||
{
|
||||
if (i > 0 && name[i] >= 'A' && name[i] <= 'Z' && isalpha(name[i-1]))
|
||||
name[i] |= 0x20;
|
||||
@@ -60,11 +60,12 @@ void fixnamen(char* name, size_t len)
|
||||
|
||||
void fixname2(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)
|
||||
@@ -123,7 +124,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY)
|
||||
char* s = GetPlainName(p);
|
||||
fixname2(s, strlen(s));
|
||||
|
||||
ModelInstanceNames.push_back(s);
|
||||
ModelInstanceNames.emplace_back(s);
|
||||
|
||||
std::string path(p);
|
||||
ExtractSingleModel(path);
|
||||
@@ -147,7 +148,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY)
|
||||
char* s = GetPlainName(p);
|
||||
fixnamen(s, strlen(s));
|
||||
fixname2(s, strlen(s));
|
||||
WmoInstanceNames.push_back(s);
|
||||
WmoInstanceNames.emplace_back(s);
|
||||
|
||||
ExtractSingleWmo(path);
|
||||
|
||||
@@ -180,6 +181,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY)
|
||||
ADT::MODF mapObjDef;
|
||||
_file.read(&mapObjDef, sizeof(ADT::MODF));
|
||||
MapObject::Extract(mapObjDef, WmoInstanceNames[mapObjDef.Id].c_str(), map_num, tileX, tileY, dirfile);
|
||||
Doodad::ExtractSet(WmoDoodads[WmoInstanceNames[mapObjDef.Id]], mapObjDef, map_num, tileX, tileY, dirfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
|
||||
bool ExtractSingleModel(std::string& fname)
|
||||
{
|
||||
char * name = GetPlainName((char*)fname.c_str());
|
||||
char * ext = GetExtension(name);
|
||||
if (fname.length() < 4)
|
||||
return false;
|
||||
|
||||
// < 3.1.0 ADT MMDX section store filename.mdx filenames for corresponded .m2 file
|
||||
if (!strcmp(ext, ".mdx"))
|
||||
std::string extension = fname.substr(fname.length() - 4, 4);
|
||||
if (extension == ".mdx" || extension == ".MDX" || extension == ".mdl" || extension == ".MDL")
|
||||
{
|
||||
// replace .mdx -> .m2
|
||||
fname.erase(fname.length()-2,2);
|
||||
@@ -39,6 +39,12 @@ bool ExtractSingleModel(std::string& fname)
|
||||
// >= 3.1.0 ADT MMDX section store filename.m2 filenames for corresponded .m2 file
|
||||
// nothing do
|
||||
|
||||
std::string originalName = fname;
|
||||
|
||||
char* name = GetPlainName((char*)fname.c_str());
|
||||
fixnamen(name, strlen(name));
|
||||
fixname2(name, strlen(name));
|
||||
|
||||
std::string output(szWorkDirWmo);
|
||||
output += "/";
|
||||
output += name;
|
||||
@@ -46,7 +52,7 @@ bool ExtractSingleModel(std::string& fname)
|
||||
if (FileExists(output.c_str()))
|
||||
return true;
|
||||
|
||||
Model mdl(fname);
|
||||
Model mdl(originalName);
|
||||
if (!mdl.open())
|
||||
return false;
|
||||
|
||||
|
||||
@@ -17,14 +17,16 @@
|
||||
*/
|
||||
|
||||
#include "vmapexport.h"
|
||||
#include "Errors.h"
|
||||
#include "model.h"
|
||||
#include "wmo.h"
|
||||
#include "adtfile.h"
|
||||
#include "mpq_libmpq04.h"
|
||||
#include "VMapDefinitions.h"
|
||||
#include <cassert>
|
||||
#include <G3D/Quat.h>
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
|
||||
Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0)
|
||||
{
|
||||
@@ -134,21 +136,13 @@ 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)
|
||||
{
|
||||
return Vec3D(v.x, v.z, v.y);
|
||||
}
|
||||
|
||||
void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile)
|
||||
{
|
||||
// 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");
|
||||
@@ -164,20 +158,24 @@ 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 flags = MOD_M2;
|
||||
uint32 uniqueId = GenerateUniqueObjectId(doodadDef.UniqueId, 0);
|
||||
uint32 tcflags = MOD_M2;
|
||||
if (tileX == 65 && tileY == 65)
|
||||
flags |= MOD_WORLDSPAWN;
|
||||
tcflags |= MOD_WORLDSPAWN;
|
||||
|
||||
//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(&flags, 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);
|
||||
@@ -185,3 +183,86 @@ void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint
|
||||
fwrite(&nlen, sizeof(uint32), 1, pDirfile);
|
||||
fwrite(ModelInstName, sizeof(char), nlen, pDirfile);
|
||||
}
|
||||
|
||||
void Doodad::ExtractSet(WMODoodadData const& doodadData, ADT::MODF const& wmo, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile)
|
||||
{
|
||||
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);
|
||||
fixnamen(ModelInstName, nlen);
|
||||
fixname2(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;
|
||||
|
||||
//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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
#include <vector>
|
||||
|
||||
class MPQFile;
|
||||
namespace ADT { struct MDDF; }
|
||||
struct WMODoodadData;
|
||||
namespace ADT { struct MDDF; struct MODF; }
|
||||
|
||||
Vec3D fixCoordSystem(Vec3D v);
|
||||
Vec3D fixCoordSystem(Vec3D const& v);
|
||||
|
||||
class Model
|
||||
{
|
||||
@@ -55,6 +56,8 @@ public:
|
||||
namespace Doodad
|
||||
{
|
||||
void Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile);
|
||||
|
||||
void ExtractSet(WMODoodadData const& doodadData, ADT::MODF const& wmo, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -253,4 +253,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
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <errno.h>
|
||||
|
||||
@@ -59,12 +60,19 @@ char output_path[128]=".";
|
||||
char input_path[1024]=".";
|
||||
bool hasInputPathParam = false;
|
||||
bool preciseVectorData = false;
|
||||
std::unordered_map<std::string, WMODoodadData> WmoDoodads;
|
||||
|
||||
// Constants
|
||||
|
||||
//static const char * szWorkDirMaps = ".\\Maps";
|
||||
char const* szWorkDirWmo = "./Buildings";
|
||||
|
||||
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(char const* file)
|
||||
@@ -89,11 +97,13 @@ void strToLower(char* 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]);
|
||||
fixnamen(plain_name, strlen(plain_name));
|
||||
fixname2(plain_name, strlen(plain_name));
|
||||
sprintf(szLocalFile, "%s/%s", szWorkDirWmo, plain_name);
|
||||
fixnamen(szLocalFile,strlen(szLocalFile));
|
||||
|
||||
if (FileExists(szLocalFile))
|
||||
return true;
|
||||
@@ -117,9 +127,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;
|
||||
@@ -131,6 +141,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);
|
||||
if (froot.nGroups !=0)
|
||||
@@ -154,6 +166,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
#ifndef VMAPEXPORT_H
|
||||
#define VMAPEXPORT_H
|
||||
|
||||
#include "Define.h"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
enum ModelFlags
|
||||
{
|
||||
@@ -28,7 +30,12 @@ enum ModelFlags
|
||||
MOD_HAS_BOUND = 1<<2
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
@@ -104,6 +104,7 @@ bool WDTFile::init(uint32 mapId)
|
||||
ADT::MODF mapObjDef;
|
||||
_file.read(&mapObjDef, sizeof(ADT::MODF));
|
||||
MapObject::Extract(mapObjDef, _wmoNames[mapObjDef.Id].c_str(), mapId, 65, 65, dirfile);
|
||||
Doodad::ExtractSet(WmoDoodads[_wmoNames[mapObjDef.Id]], mapObjDef, mapId, 65, 65, dirfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,18 +18,20 @@
|
||||
|
||||
#include "vmapexport.h"
|
||||
#include "adtfile.h"
|
||||
#include "wmo.h"
|
||||
#include "vec3d.h"
|
||||
#include "mpq_libmpq04.h"
|
||||
|
||||
#include "VMapDefinitions.h"
|
||||
#include "wmo.h"
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -73,7 +75,37 @@ bool WMORoot::open()
|
||||
f.read(bbcorn1, 12);
|
||||
f.read(bbcorn2, 12);
|
||||
f.read(&flags, 4);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
fixnamen(s, strlen(s));
|
||||
fixname2(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,"MOTX"))
|
||||
@@ -91,15 +123,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"))
|
||||
{
|
||||
}
|
||||
@@ -226,6 +249,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;
|
||||
@@ -526,6 +554,7 @@ void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, uin
|
||||
bounds.max = fixCoords(mapObjDef.Bounds.max);
|
||||
|
||||
float scale = 1.0f;
|
||||
uint32 uniqueId = GenerateUniqueObjectId(mapObjDef.UniqueId, 0);
|
||||
uint32 flags = MOD_HAS_BOUND;
|
||||
if (tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN;
|
||||
//write mapID, tileX, tileY, Flags, NameSet, UniqueId, Pos, Rot, Scale, Bound_lo, Bound_hi, name
|
||||
@@ -534,7 +563,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);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#define WMO_H
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include "vec3d.h"
|
||||
#include "loadlib/loadlib.h"
|
||||
@@ -43,9 +43,37 @@ class WMOManager;
|
||||
class MPQFile;
|
||||
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(Vec3D const& 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:
|
||||
@@ -56,7 +84,10 @@ public:
|
||||
float bbcorn1[3];
|
||||
float bbcorn2[3];
|
||||
|
||||
WMORoot(std::string& filename);
|
||||
WMODoodadData DoodadData;
|
||||
std::unordered_set<uint32> ValidDoodadNames;
|
||||
|
||||
WMORoot(std::string const& filename);
|
||||
|
||||
bool open();
|
||||
bool ConvertToVMAPRootWmo(FILE* output);
|
||||
@@ -114,6 +145,8 @@ public:
|
||||
int nTriangles; // number when loaded
|
||||
uint32 liquflags;
|
||||
|
||||
std::vector<uint16> DoodadReferences;
|
||||
|
||||
WMOGroup(std::string const& filename);
|
||||
~WMOGroup();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user