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 float sc = doodadDef.
Scale / 1024.0f;
170 if (mapID != originalMapId)
174 fwrite(&tcflags,
sizeof(
uint8), 1, pDirfile);
175 fwrite(&nameSet,
sizeof(
uint8), 1, pDirfile);
176 fwrite(&uniqueId,
sizeof(
uint32), 1, pDirfile);
177 fwrite(&position,
sizeof(
Vec3D), 1, pDirfile);
179 fwrite(&sc,
sizeof(
float), 1, pDirfile);
180 uint32 nlen = strlen(ModelInstName);
181 fwrite(&nlen,
sizeof(
uint32), 1, pDirfile);
182 fwrite(ModelInstName,
sizeof(
char), nlen, pDirfile);
186 dirfileCache->emplace_back();
188 cacheModelData.
Flags = tcflags & ~MOD_PARENT_SPAWN;
189 cacheModelData.
Data.resize(
198 uint8* cacheData = cacheModelData.
Data.data();
199#define CACHE_WRITE(value, size, cnt, dest) memcpy(dest, value, size * cnt); dest += size * cnt;
207 CACHE_WRITE(ModelInstName,
sizeof(
char), nlen, cacheData);
212 FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache)
214 if (doodadData.
Sets.empty())
218 G3D::Matrix3 wmoRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::toRadians(wmo.
Rotation.
y), G3D::toRadians(wmo.
Rotation.
x), G3D::toRadians(wmo.
Rotation.
z));
221 wmoPosition += G3D::Vector3(533.33333f * 32, 533.33333f * 32, 0.0f);
224 auto extractSingleSet = [&](
WMO::MODS const& doodadSetData)
228 if (doodadIndex < doodadSetData.StartIndex ||
229 doodadIndex >= doodadSetData.StartIndex + doodadSetData.Count)
234 std::string ModelInstName;
235 if (doodadData.
Paths)
245 uint32 nlen = ModelInstName.length();
247 ASSERT(doodadId < std::numeric_limits<uint16>::max());
254 .toRotationMatrix() * wmoRotation)
255 .toEulerAnglesXYZ(rotation.z, rotation.x, rotation.y);
257 rotation.
z = G3D::toDegrees(rotation.z);
258 rotation.x = G3D::toDegrees(rotation.x);
259 rotation.y = G3D::toDegrees(rotation.y);
264 if (mapID != originalMapId)
268 fwrite(&tcflags,
sizeof(
uint8), 1, pDirfile);
269 fwrite(&nameSet,
sizeof(
uint8), 1, pDirfile);
270 fwrite(&uniqueId,
sizeof(
uint32), 1, pDirfile);
271 fwrite(&position,
sizeof(
Vec3D), 1, pDirfile);
272 fwrite(&rotation,
sizeof(
Vec3D), 1, pDirfile);
273 fwrite(&doodad.
Scale,
sizeof(
float), 1, pDirfile);
274 fwrite(&nlen,
sizeof(
uint32), 1, pDirfile);
275 fwrite(ModelInstName.c_str(),
sizeof(
char), nlen, pDirfile);
279 dirfileCache->emplace_back();
281 cacheModelData.
Flags = tcflags & ~MOD_PARENT_SPAWN;
282 cacheModelData.
Data.resize(
291 uint8* cacheData = cacheModelData.
Data.data();
298 CACHE_WRITE(ModelInstName.c_str(),
sizeof(
char), nlen, cacheData);
304 extractSingleSet(doodadData.
Sets[0]);
std::shared_ptr< CASC::Storage > CascStorage
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)
Vec3D fixCoordSystem(Vec3D const &v)
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) noexcept
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)
static Vec3D fixCoords(Vec3D const &v)