vmangos/contrib/model_reader/reader.cpp

195 lines
4.8 KiB
C++
Raw Permalink Normal View History

2017-03-10 00:38:11 +03:00
#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;
}