33Model::Model(std::string &filename) : filename(filename), header(), vertices(nullptr), indices(nullptr)
53 while (m2start + 4 < f.
getSize() && memcmp(ptr,
"MD20", 4) != 0)
91 FILE* output = fopen(outfilename,
"wb");
94 printf(
"Can't create the output file '%s'\n", outfilename);
99 fwrite(&nVertices,
sizeof(
int), 1, output);
101 fwrite(&nofgroups,
sizeof(
uint32), 1, output);
102 fwrite(N, 4, 1, output);
104 fwrite(&tcFlags,
sizeof(
ModelFlags), 1, output);
105 fwrite(N, 4 * 2, 1, output);
107 fwrite(N, 4, 1, output);
108 fwrite(
"GRP ", 4, 1, output);
111 wsize =
sizeof(branches) +
sizeof(
uint32) * branches;
112 fwrite(&wsize,
sizeof(
int), 1, output);
113 fwrite(&branches,
sizeof(branches), 1, output);
115 fwrite(&nIndexes,
sizeof(
uint32), 1, output);
116 fwrite(
"INDX", 4, 1, output);
117 wsize =
sizeof(
uint32) +
sizeof(
unsigned short) * nIndexes;
118 fwrite(&wsize,
sizeof(
int), 1, output);
119 fwrite(&nIndexes,
sizeof(
uint32), 1, output);
122 for (
uint32 i = 0; i < nIndexes; ++i)
124 if ((i % 3) - 1 == 0 && i + 1 < nIndexes)
134 fwrite(
"VERT", 4, 1, output);
135 wsize =
sizeof(int) +
sizeof(
float) * 3 * nVertices;
136 fwrite(&wsize,
sizeof(
int), 1, output);
137 fwrite(&nVertices,
sizeof(
int), 1, output);
140 for (
uint32 vpos = 0; vpos < nVertices; ++vpos)
147 fwrite(
vertices,
sizeof(
float) * 3, nVertices, output);
163 FILE* input = fopen(tempname.c_str(),
"r+b");
168 fseek(input, 8, SEEK_SET);
170 int count = fread(&nVertices,
sizeof(
int), 1, input);
173 if (count != 1 || nVertices == 0)
177 float sc = doodadDef.
Scale / 1024.0f;
184 if (mapID != originalMapId)
188 fwrite(&mapID,
sizeof(
uint32), 1, pDirfile);
189 fwrite(&tcflags,
sizeof(
uint8), 1, pDirfile);
190 fwrite(&nameSet,
sizeof(
uint8), 1, pDirfile);
191 fwrite(&uniqueId,
sizeof(
uint32), 1, pDirfile);
192 fwrite(&position,
sizeof(
Vec3D), 1, pDirfile);
194 fwrite(&sc,
sizeof(
float), 1, pDirfile);
195 uint32 nlen = strlen(ModelInstName);
196 fwrite(&nlen,
sizeof(
uint32), 1, pDirfile);
197 fwrite(ModelInstName,
sizeof(
char), nlen, pDirfile);
201 dirfileCache->emplace_back();
203 cacheModelData.
Flags = tcflags & ~MOD_PARENT_SPAWN;
204 cacheModelData.
Data.resize(
213 uint8* cacheData = cacheModelData.
Data.data();
214#define CACHE_WRITE(value, size, cnt, dest) memcpy(dest, value, size * cnt); dest += size * cnt;
222 CACHE_WRITE(ModelInstName,
sizeof(
char), nlen, cacheData);
227 FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache)
229 if (doodadData.
Sets.empty())
233 G3D::Matrix3 wmoRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::toRadians(wmo.
Rotation.
y), G3D::toRadians(wmo.
Rotation.
x), G3D::toRadians(wmo.
Rotation.
z));
236 wmoPosition += G3D::Vector3(533.33333f * 32, 533.33333f * 32, 0.0f);
239 auto extractSingleSet = [&](
WMO::MODS const& doodadSetData)
243 if (doodadIndex < doodadSetData.StartIndex ||
244 doodadIndex >= doodadSetData.StartIndex + doodadSetData.Count)
249 std::string ModelInstName;
250 if (doodadData.
Paths)
257 uint32 nlen = ModelInstName.length();
259 if (ModelInstName.ends_with(
".mdx") || ModelInstName.ends_with(
".mdl"))
260 ModelInstName.replace(ModelInstName.length() - 2, 2,
"2");
263 FILE* input = fopen(tempname.c_str(),
"r+b");
267 fseek(input, 8, SEEK_SET);
269 int count = fread(&nVertices,
sizeof(
int), 1, input);
272 if (count != 1 || nVertices == 0)
275 ASSERT(doodadId < std::numeric_limits<uint16>::max());
282 .toRotationMatrix() * wmoRotation)
283 .toEulerAnglesXYZ(rotation.z, rotation.x, rotation.y);
285 rotation.
z = G3D::toDegrees(rotation.z);
286 rotation.x = G3D::toDegrees(rotation.x);
287 rotation.y = G3D::toDegrees(rotation.y);
292 if (mapID != originalMapId)
296 fwrite(&mapID,
sizeof(
uint32), 1, pDirfile);
297 fwrite(&tcflags,
sizeof(
uint8), 1, pDirfile);
298 fwrite(&nameSet,
sizeof(
uint8), 1, pDirfile);
299 fwrite(&uniqueId,
sizeof(
uint32), 1, pDirfile);
300 fwrite(&position,
sizeof(
Vec3D), 1, pDirfile);
301 fwrite(&rotation,
sizeof(
Vec3D), 1, pDirfile);
302 fwrite(&doodad.
Scale,
sizeof(
float), 1, pDirfile);
303 fwrite(&nlen,
sizeof(
uint32), 1, pDirfile);
304 fwrite(ModelInstName.c_str(),
sizeof(
char), nlen, pDirfile);
308 dirfileCache->emplace_back();
310 cacheModelData.
Flags = tcflags & ~MOD_PARENT_SPAWN;
311 cacheModelData.
Data.resize(
320 uint8* cacheData = cacheModelData.
Data.data();
327 CACHE_WRITE(ModelInstName.c_str(),
sizeof(
char), nlen, cacheData);
333 extractSingleSet(doodadData.
Sets[0]);
char const * GetPlainName(char const *FileName)
void NormalizeFileName(char *name, size_t len)
void seekRelative(int offset)
size_t read(void *dest, size_t bytes)
Model(std::string &filename)
bool ConvertToVMAPModel(char const *outfilename)
std::shared_ptr< CASC::Storage > CascStorage
Vec3D fixCoordSystem(Vec3D const &v)
#define CACHE_WRITE(value, size, cnt, dest)
void Extract(ADT::MDDF const &doodadDef, char const *ModelInstName, uint32 mapID, uint32 originalMapId, FILE *pDirfile, std::vector< ADTOutputCache > *dirfileCache)
void ExtractSet(WMODoodadData const &doodadData, ADT::MODF const &wmo, bool isGlobalWmo, uint32 mapID, uint32 originalMapId, FILE *pDirfile, std::vector< ADTOutputCache > *dirfileCache)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args)
Default TC string format function.
const char RAW_VMAP_MAGIC[]
std::vector< uint8 > Data
std::unordered_set< uint16 > References
std::vector< WMO::MODS > Sets
std::vector< WMO::MODD > Spawns
std::unique_ptr< uint32[]> FileDataIds
std::unique_ptr< char[]> Paths
uint32 GenerateUniqueObjectId(uint32 clientId, uint16 clientDoodadId, bool isWmo)
char const * szWorkDirWmo
static Vec3D fixCoords(Vec3D const &v)