mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-15 18:10:26 +00:00
197 lines
5.9 KiB
C++
197 lines
5.9 KiB
C++
/*
|
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: http://github.com/azerothcore/azerothcore-wotlk/LICENSE-GPL2
|
|
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
|
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
|
*/
|
|
|
|
#include "vmapexport.h"
|
|
#include "model.h"
|
|
#include "wmo.h"
|
|
#include "mpq_libmpq04.h"
|
|
#include <cassert>
|
|
#include <algorithm>
|
|
#include <cstdio>
|
|
|
|
Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0)
|
|
{
|
|
memset(&header, 0, sizeof(header));
|
|
}
|
|
|
|
bool Model::open()
|
|
{
|
|
MPQFile f(filename.c_str());
|
|
|
|
if (f.isEof())
|
|
{
|
|
f.close();
|
|
// Do not show this error on console to avoid confusion, the extractor can continue working even if some models fail to load
|
|
//printf("Error loading model %s\n", filename.c_str());
|
|
return false;
|
|
}
|
|
|
|
_unload();
|
|
|
|
memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
|
|
if(header.nBoundingTriangles > 0)
|
|
{
|
|
f.seek(0);
|
|
f.seekRelative(header.ofsBoundingVertices);
|
|
vertices = new Vec3D[header.nBoundingVertices];
|
|
f.read(vertices,header.nBoundingVertices*12);
|
|
for (uint32 i=0; i<header.nBoundingVertices; i++)
|
|
vertices[i] = fixCoordSystem(vertices[i]);
|
|
f.seek(0);
|
|
f.seekRelative(header.ofsBoundingTriangles);
|
|
indices = new uint16[header.nBoundingTriangles];
|
|
f.read(indices,header.nBoundingTriangles*2);
|
|
f.close();
|
|
}
|
|
else
|
|
{
|
|
//printf("not included %s\n", filename.c_str());
|
|
f.close();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool Model::ConvertToVMAPModel(const char * outfilename)
|
|
{
|
|
int N[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
|
|
FILE* output=fopen(outfilename, "wb");
|
|
if (!output)
|
|
{
|
|
printf("Can't create the output file '%s'\n",outfilename);
|
|
return false;
|
|
}
|
|
fwrite(szRawVMAPMagic, 8, 1, output);
|
|
uint32 nVertices = header.nBoundingVertices;
|
|
fwrite(&nVertices, sizeof(int), 1, output);
|
|
uint32 nofgroups = 1;
|
|
fwrite(&nofgroups,sizeof(uint32), 1, output);
|
|
fwrite(N,4*3,1,output);// rootwmoid, flags, groupid
|
|
fwrite(N,sizeof(float),3*2,output);//bbox, only needed for WMO currently
|
|
fwrite(N,4,1,output);// liquidflags
|
|
fwrite("GRP ",4,1,output);
|
|
uint32 branches = 1;
|
|
int wsize;
|
|
wsize = sizeof(branches) + sizeof(uint32) * branches;
|
|
fwrite(&wsize, sizeof(int), 1, output);
|
|
fwrite(&branches,sizeof(branches), 1, output);
|
|
uint32 nIndexes = header.nBoundingTriangles;
|
|
fwrite(&nIndexes,sizeof(uint32), 1, output);
|
|
fwrite("INDX",4, 1, output);
|
|
wsize = sizeof(uint32) + sizeof(unsigned short) * nIndexes;
|
|
fwrite(&wsize, sizeof(int), 1, output);
|
|
fwrite(&nIndexes, sizeof(uint32), 1, output);
|
|
if (nIndexes > 0)
|
|
{
|
|
for (uint32 i = 0; i < nIndexes; ++i)
|
|
{
|
|
if ((i % 3) - 1 == 0 && i + 1 < nIndexes)
|
|
{
|
|
uint16 tmp = indices[i];
|
|
indices[i] = indices[i + 1];
|
|
indices[i + 1] = tmp;
|
|
}
|
|
}
|
|
fwrite(indices, sizeof(unsigned short), nIndexes, output);
|
|
}
|
|
fwrite("VERT", 4, 1, output);
|
|
wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
|
|
fwrite(&wsize, sizeof(int), 1, output);
|
|
fwrite(&nVertices, sizeof(int), 1, output);
|
|
if (nVertices >0)
|
|
{
|
|
for (uint32 vpos = 0; vpos < nVertices; ++vpos)
|
|
{
|
|
float tmp = vertices[vpos].y;
|
|
vertices[vpos].y = -vertices[vpos].z;
|
|
vertices[vpos].z = tmp;
|
|
}
|
|
|
|
fwrite(vertices, sizeof(float)*3, nVertices, output);
|
|
}
|
|
|
|
fclose(output);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
Vec3D fixCoordSystem(Vec3D v)
|
|
{
|
|
return Vec3D(v.x, v.z, -v.y);
|
|
}
|
|
|
|
Vec3D fixCoordSystem2(Vec3D v)
|
|
{
|
|
return Vec3D(v.x, v.z, v.y);
|
|
}
|
|
|
|
ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile)
|
|
{
|
|
float ff[3];
|
|
f.read(&id, 4);
|
|
f.read(ff, 12);
|
|
pos = fixCoords(Vec3D(ff[0], ff[1], ff[2]));
|
|
f.read(ff, 12);
|
|
rot = Vec3D(ff[0], ff[1], ff[2]);
|
|
f.read(&scale, 2);
|
|
f.read(&flags, 2);
|
|
// scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
|
|
sc = scale / 1024.0f;
|
|
|
|
char tempname[512];
|
|
sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName);
|
|
FILE* input = fopen(tempname, "r+b");
|
|
|
|
if (!input)
|
|
{
|
|
//printf("ModelInstance::ModelInstance couldn't open %s\n", tempname);
|
|
return;
|
|
}
|
|
|
|
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)
|
|
return;
|
|
|
|
uint16 adtId = 0;// not used for models
|
|
uint32 flags = MOD_M2;
|
|
if (tileX == 65 && tileY == 65)
|
|
flags |= MOD_WORLDSPAWN;
|
|
|
|
//write mapID, tileX, tileY, Flags, ID, 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(&adtId, sizeof(uint16), 1, pDirfile);
|
|
fwrite(&id, sizeof(uint32), 1, pDirfile);
|
|
fwrite(&pos, sizeof(float), 3, pDirfile);
|
|
fwrite(&rot, sizeof(float), 3, pDirfile);
|
|
fwrite(&sc, sizeof(float), 1, pDirfile);
|
|
uint32 nlen=strlen(ModelInstName);
|
|
fwrite(&nlen, sizeof(uint32), 1, pDirfile);
|
|
fwrite(ModelInstName, sizeof(char), nlen, pDirfile);
|
|
|
|
/* int realx1 = (int) ((float) pos.x / 533.333333f);
|
|
int realy1 = (int) ((float) pos.z / 533.333333f);
|
|
int realx2 = (int) ((float) pos.x / 533.333333f);
|
|
int realy2 = (int) ((float) pos.z / 533.333333f);
|
|
fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n",
|
|
MapName,
|
|
ModelInstName,
|
|
(float) pos.x, (float) pos.y, (float) pos.z,
|
|
(float) rot.x, (float) rot.y, (float) rot.z,
|
|
sc,
|
|
nVertices,
|
|
realx1, realy1,
|
|
realx2, realy2
|
|
); */
|
|
}
|