mirror of
https://github.com/vmangos/core
synced 2026-08-14 16:29:10 -04:00
195 lines
4.8 KiB
C++
195 lines
4.8 KiB
C++
|
|
#include <iostream>
|
||
|
|
|
||
|
|
#define FAIL() { printf("[FAIL]\n"); return 1; }
|
||
|
|
#define OK() { printf("[OK]\n");}
|
||
|
|
|
||
|
|
typedef unsigned int uint32;
|
||
|
|
typedef unsigned short uint16;
|
||
|
|
|
||
|
|
struct Header
|
||
|
|
{
|
||
|
|
char magic[8];
|
||
|
|
int nVertices;
|
||
|
|
uint32 groupsCount;
|
||
|
|
uint32 rootWmoId, flags, groupid;
|
||
|
|
float bbox1[3];
|
||
|
|
float bbox2[3];
|
||
|
|
uint32 liquidFlags;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct Chuck
|
||
|
|
{
|
||
|
|
char chuck[4];
|
||
|
|
uint32 size;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct Vertex
|
||
|
|
{
|
||
|
|
float x, y, z;
|
||
|
|
void FixCoord()
|
||
|
|
{
|
||
|
|
float tmp = z;
|
||
|
|
z = -y;
|
||
|
|
y = tmp;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
enum FileType
|
||
|
|
{
|
||
|
|
FILE_BUILDING,
|
||
|
|
FILE_VMO,
|
||
|
|
};
|
||
|
|
|
||
|
|
int main(int argc, char **argv)
|
||
|
|
{
|
||
|
|
// Reading arguments
|
||
|
|
printf("* Model File Reader\n");
|
||
|
|
if (argc != 2)
|
||
|
|
{
|
||
|
|
printf("Usage : %s file\n", argv[0]);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
std::string fName = std::string(argv[1]);
|
||
|
|
FileType type = (fName.find(".vmo") == std::string::npos) ? FILE_BUILDING : FILE_VMO;
|
||
|
|
|
||
|
|
printf("* Opening file `%s` (type `%s`) ... ", fName.c_str(), type == FILE_BUILDING ? "building" : "vmo");
|
||
|
|
FILE* file = fopen(fName.c_str(), "rb");
|
||
|
|
if (!file)
|
||
|
|
FAIL();
|
||
|
|
OK();
|
||
|
|
|
||
|
|
// Reading the file
|
||
|
|
// Header BUILDING
|
||
|
|
if (type == FILE_BUILDING)
|
||
|
|
{
|
||
|
|
uint32 size = sizeof(Header);
|
||
|
|
Header header;
|
||
|
|
|
||
|
|
printf("* Reading header (%u bytes) ... ", size);
|
||
|
|
if (!fread(&header, size, 1, file)) {
|
||
|
|
fclose(file);
|
||
|
|
FAIL();
|
||
|
|
}
|
||
|
|
OK();
|
||
|
|
|
||
|
|
printf("- MAGIC : `%s`\n", std::string(header.magic).substr(0, 8).c_str());
|
||
|
|
printf("- %i vertices\n", header.nVertices);
|
||
|
|
printf("- Box : [%f:%f:%f][%f:%f:%f]\n",
|
||
|
|
header.bbox1[0], header.bbox1[1], header.bbox1[2],
|
||
|
|
header.bbox2[0], header.bbox2[1], header.bbox2[2]);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
printf("* Reading header (magic) ... ");
|
||
|
|
char magic[8] = {0};
|
||
|
|
if (fread(&magic, 1, 8, file) != 8) {
|
||
|
|
fclose(file);
|
||
|
|
FAIL();
|
||
|
|
}
|
||
|
|
OK();
|
||
|
|
printf("- MAGIC : `%s`\n", std::string(magic).substr(0, 8).c_str());
|
||
|
|
}
|
||
|
|
uint32 branches = 0, indexes = 0, nVertices = 0, rootWmoId = 0;
|
||
|
|
uint16 *pIndexes = NULL;
|
||
|
|
Vertex *pVertices = NULL;
|
||
|
|
uint32 *pBranches = NULL;
|
||
|
|
|
||
|
|
while (true)
|
||
|
|
{
|
||
|
|
Chuck chk;
|
||
|
|
printf("* Reading chuck ... ");
|
||
|
|
if (!fread(&chk, sizeof(Chuck), 1, file))
|
||
|
|
{
|
||
|
|
printf("[EOF]\n");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
std::string sChk = std::string(chk.chuck).substr(0, 4);
|
||
|
|
printf("[`%s`/%u]", sChk.c_str(), chk.size);
|
||
|
|
if (sChk == "GRP ")
|
||
|
|
{
|
||
|
|
if (!fread(&branches, 4, 1, file) || !fread(&indexes, 4, 1, file))
|
||
|
|
FAIL();
|
||
|
|
if (pBranches)
|
||
|
|
delete[] pBranches;
|
||
|
|
pBranches = NULL;
|
||
|
|
|
||
|
|
if (branches > 1)
|
||
|
|
{
|
||
|
|
pBranches = new uint32[branches-1];
|
||
|
|
if (fread(pBranches, 4, branches-1, file) != (branches-1))
|
||
|
|
{
|
||
|
|
delete[] pBranches;
|
||
|
|
FAIL();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
OK();
|
||
|
|
printf("- %u branches / %u indexes.\n", branches, indexes);
|
||
|
|
}
|
||
|
|
else if (sChk == "INDX")
|
||
|
|
{
|
||
|
|
// Re-read indexes count.
|
||
|
|
if (!fread(&indexes, 4, 1, file))
|
||
|
|
FAIL();
|
||
|
|
if (pIndexes)
|
||
|
|
delete[] pIndexes;
|
||
|
|
|
||
|
|
pIndexes = new uint16[indexes];
|
||
|
|
if (fread(pIndexes, sizeof(uint16), indexes, file) != indexes)
|
||
|
|
{
|
||
|
|
delete[] pIndexes;
|
||
|
|
FAIL();
|
||
|
|
}
|
||
|
|
OK();
|
||
|
|
}
|
||
|
|
else if (sChk == "VERT")
|
||
|
|
{
|
||
|
|
if (!fread(&nVertices, 4, 1, file))
|
||
|
|
FAIL();
|
||
|
|
if (pVertices)
|
||
|
|
delete[] pVertices;
|
||
|
|
pVertices = new Vertex[nVertices];
|
||
|
|
if (fread(pVertices, sizeof(Vertex), nVertices, file) != nVertices)
|
||
|
|
{
|
||
|
|
delete[] pVertices;
|
||
|
|
FAIL();
|
||
|
|
}
|
||
|
|
OK();
|
||
|
|
}
|
||
|
|
else if (sChk == "WMOD")
|
||
|
|
{
|
||
|
|
if (!fread(&rootWmoId, 4, 1, file))
|
||
|
|
FAIL();
|
||
|
|
OK();
|
||
|
|
printf("- RootWmoID = %u\n", rootWmoId);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
printf("\n* Unknow Chuck. Skipped.\n");
|
||
|
|
fseek(file, chk.size, SEEK_CUR);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
fclose(file);
|
||
|
|
|
||
|
|
printf("* Opening out.obj ... ");
|
||
|
|
FILE* output = fopen("out.obj", "w+");
|
||
|
|
if (!output)
|
||
|
|
FAIL();
|
||
|
|
OK();
|
||
|
|
|
||
|
|
printf("* Writing vertices ... ");
|
||
|
|
for (uint32 i = 0; i < nVertices; ++i)
|
||
|
|
{
|
||
|
|
pVertices[i].FixCoord();
|
||
|
|
fprintf(output, "v %f %f %f\n", pVertices[i].x, pVertices[i].y, pVertices[i].z);
|
||
|
|
}
|
||
|
|
OK();
|
||
|
|
|
||
|
|
printf("* Writing triangles definition ... ");
|
||
|
|
for (uint32 i = 0; i < (indexes-2); i += 3)
|
||
|
|
fprintf(output, "f %u %u %u\n", pIndexes[i]+1, pIndexes[i+1]+1, pIndexes[i+2]+1);
|
||
|
|
OK();
|
||
|
|
fclose(output);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|