mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
547 lines
14 KiB
C++
547 lines
14 KiB
C++
#define __STORMLIB_SELF__
|
|
|
|
#include "wmo.h"
|
|
#include "Stormlib.h"
|
|
#include "mpq.h"
|
|
|
|
using namespace std;
|
|
|
|
WMORoot::WMORoot(std::string &filename) : filename(filename)
|
|
{
|
|
}
|
|
|
|
bool WMORoot::open()
|
|
{
|
|
MPQFile f(filename.c_str());
|
|
if(f.isEof ())
|
|
{
|
|
printf("No such file.\n");
|
|
return false;
|
|
}
|
|
|
|
size_t size;
|
|
char fourcc[5];
|
|
bbcorn1[3] = 0;
|
|
bbcorn2[3]= 0;
|
|
|
|
while (!f.isEof())
|
|
{
|
|
f.read(fourcc,4);
|
|
f.read(&size, 4);
|
|
|
|
flipcc(fourcc);
|
|
fourcc[4] = 0;
|
|
|
|
size_t nextpos = f.getPos() + size;
|
|
|
|
if (!strcmp(fourcc,"MOHD"))//header
|
|
{
|
|
f.read(&nTextures, 4);
|
|
f.read(&nGroups, 4);
|
|
f.read(&nP, 4);
|
|
f.read(&nLights, 4);
|
|
f.read(&nModels, 4);
|
|
f.read(&nDoodads, 4);
|
|
f.read(&nDoodadSets, 4);
|
|
f.read(&col, 4);
|
|
f.read(&RootID, 4);
|
|
f.read(bbcorn1,12);
|
|
f.read(bbcorn2,12);
|
|
break;
|
|
}
|
|
/*
|
|
else if (!strcmp(fourcc,"MOTX"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MOMT"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MOGN"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MOGI"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MOLT"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MODN"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MODS"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MODD"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MOSB"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MOPV"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MOPT"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MOPR"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MFOG"))
|
|
{
|
|
}
|
|
*/
|
|
f.seek((int)nextpos);
|
|
}
|
|
f.close ();
|
|
return true;
|
|
}
|
|
|
|
bool WMORoot::ConvertToVMAPRootWmo(FILE *pOutfile)
|
|
{
|
|
//printf("Convert RootWmo...\n");
|
|
|
|
fwrite("VMAP002",1,8,pOutfile);
|
|
unsigned int nVectors = 0;
|
|
fwrite(&nVectors,sizeof(nVectors),1,pOutfile); // will be filled later
|
|
fwrite(&nGroups,4,1,pOutfile);
|
|
return true;
|
|
}
|
|
|
|
WMORoot::~WMORoot()
|
|
{
|
|
}
|
|
|
|
WMOGroup::WMOGroup(std::string &filename) : filename(filename)
|
|
{
|
|
}
|
|
|
|
bool WMOGroup::open()
|
|
{
|
|
MPQFile f(filename.c_str());
|
|
if(f.isEof ())
|
|
{
|
|
printf("No such file.\n");
|
|
return false;
|
|
}
|
|
size_t size;
|
|
char fourcc[5];
|
|
bbcorn1[3] = 0;
|
|
bbcorn2[3] = 0;
|
|
while (!f.isEof())
|
|
{
|
|
f.read(fourcc,4);
|
|
f.read(&size, 4);
|
|
flipcc(fourcc);
|
|
if (!strcmp(fourcc,"MOGP"))//Fix sizeoff = Data size.
|
|
{
|
|
size = 68;
|
|
}
|
|
fourcc[4] = 0;
|
|
size_t nextpos = f.getPos() + size;
|
|
LiquEx_size = 0;
|
|
liquflags = 0;
|
|
|
|
if (!strcmp(fourcc,"MOGP"))//header
|
|
{
|
|
f.seekRelative(-4);
|
|
f.read(&offsize, 4);
|
|
f.read(&flag, 4);
|
|
f.read(&flag1, 4);
|
|
f.read(&Xid, 4);
|
|
f.read(bbcorn1, 12);
|
|
f.read(bbcorn2, 12);
|
|
f.read(&Xid2, 4);
|
|
f.read(&Xid3, 4);
|
|
f.read(&zero1, 4);
|
|
f.read(&Xflag, 4);
|
|
f.read(&nTexture,4);
|
|
f.read(&GroupID,4);
|
|
}
|
|
else if (!strcmp(fourcc,"MOPY"))
|
|
{
|
|
MOPY = new char[size];
|
|
mopy_size = size;
|
|
nTriangles = (int)size / 2;
|
|
f.read(MOPY, size);
|
|
}
|
|
else if (!strcmp(fourcc,"MOVI"))
|
|
{
|
|
MOVI = new uint16[size/2];
|
|
f.read(MOVI, size);
|
|
}
|
|
else if (!strcmp(fourcc,"MOVT"))
|
|
{
|
|
MOVT = new float[size/4];
|
|
f.read(MOVT, size);
|
|
nVertices = (int)size / 12;
|
|
}
|
|
else if (!strcmp(fourcc,"MONR"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MOTV"))
|
|
{
|
|
}
|
|
else if (!strcmp(fourcc,"MOBA"))
|
|
{
|
|
MOBA = new uint16[size/2];
|
|
moba_size = size/2;
|
|
f.read(MOBA, size);
|
|
}
|
|
else if (!strcmp(fourcc,"MLIQ"))
|
|
{
|
|
liquflags |= 1;
|
|
WMOLiquidHeader hlq;
|
|
f.read(&hlq, 0x1E);
|
|
float ydir = -1.0f;
|
|
hlq_xverts = hlq.xverts;
|
|
hlq_yverts = hlq.yverts;
|
|
int noVer = hlq.xverts * hlq.yverts;
|
|
float tilesize = CHUNKSIZE / 8.0f;
|
|
LiquEx_size = sizeof(float) * 3 * noVer;
|
|
LiquEx = new float[sizeof(float) * 3 * noVer];
|
|
int p = 0;
|
|
|
|
for (int j=0; j<hlq.yverts; ++j)
|
|
{
|
|
for (int i=0; i<hlq.xverts; ++i)
|
|
{
|
|
LiquEx[p++] = hlq.pos_x + tilesize * i;
|
|
LiquEx[p++] = hlq.pos_z;
|
|
LiquEx[p++] = ydir * (hlq.pos_y + tilesize * j);
|
|
}
|
|
}
|
|
}
|
|
f.seek((int)nextpos);
|
|
}
|
|
f.close();
|
|
return true;
|
|
}
|
|
|
|
int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
|
|
{
|
|
if(pPreciseVectorData)
|
|
{
|
|
fwrite(&liquflags,sizeof(uint32),1,output);
|
|
char GRP[] = "GRP ";
|
|
fwrite(GRP,1,4,output);
|
|
|
|
int k = 0;
|
|
int moba_batch = moba_size/12;
|
|
MobaEx = new int[moba_batch*4];
|
|
for(int i=8; i<moba_size; i+=12)
|
|
{
|
|
MobaEx[k++] = MOBA[i];
|
|
}
|
|
delete [] MOBA;
|
|
int moba_size_grp = moba_batch*4+4;
|
|
fwrite(&moba_size_grp,4,1,output);
|
|
fwrite(&moba_batch,4,1,output);
|
|
fwrite(MobaEx,4,k,output);
|
|
delete [] MobaEx;
|
|
|
|
uint32 nIdexes = nTriangles * 3;
|
|
|
|
if(fwrite("INDX",4, 1, output) != 1)
|
|
{
|
|
printf("Error while writing file nbraches ID");
|
|
exit(0);
|
|
}
|
|
int wsize = sizeof(uint32) + sizeof(unsigned short) * nIdexes;
|
|
if(fwrite(&wsize, sizeof(int), 1, output) != 1)
|
|
{
|
|
printf("Error while writing file wsize");
|
|
// no need to exit?
|
|
}
|
|
if(fwrite(&nIdexes, sizeof(uint32), 1, output) != 1)
|
|
{
|
|
printf("Error while writing file nIndexes");
|
|
exit(0);
|
|
}
|
|
if(nIdexes >0)
|
|
{
|
|
if(fwrite(MOVI, sizeof(unsigned short), nIdexes, output) != nIdexes)
|
|
{
|
|
printf("Error while writing file indexarray");
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
if(fwrite("VERT",4, 1, output) != 1)
|
|
{
|
|
printf("Error while writing file nbraches ID");
|
|
exit(0);
|
|
}
|
|
wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
|
|
if(fwrite(&wsize, sizeof(int), 1, output) != 1)
|
|
{
|
|
printf("Error while writing file wsize");
|
|
// no need to exit?
|
|
}
|
|
if(fwrite(&nVertices, sizeof(int), 1, output) != 1)
|
|
{
|
|
printf("Error while writing file nVertices");
|
|
exit(0);
|
|
}
|
|
if(nVertices >0)
|
|
{
|
|
if(fwrite(MOVT, sizeof(float)*3, nVertices, output) != nVertices)
|
|
{
|
|
printf("Error while writing file vectors");
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
if(LiquEx_size != 0)
|
|
{
|
|
int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU"
|
|
fwrite(LIQU_h,4,4,output);
|
|
fwrite(LiquEx,4,LiquEx_size/4,output);
|
|
delete [] LiquEx;
|
|
}
|
|
|
|
return nTriangles;
|
|
}
|
|
else
|
|
{
|
|
//printf("Convert GroupWmo...\n");
|
|
//-------GRP -------------------------------------
|
|
fwrite(&liquflags,sizeof(uint32),1,output);
|
|
char GRP[] = "GRP ";
|
|
fwrite(GRP,1,4,output);
|
|
int k = 0;
|
|
int moba_batch = moba_size/12;
|
|
MobaEx = new int[moba_batch*4];
|
|
for(int i=8; i<moba_size; i+=12)
|
|
{
|
|
MobaEx[k++] = MOBA[i];
|
|
}
|
|
delete [] MOBA;
|
|
int moba_size_grp = moba_batch*4+4;
|
|
fwrite(&moba_size_grp,4,1,output);
|
|
fwrite(&moba_batch,4,1,output);
|
|
fwrite(MobaEx,4,k,output);
|
|
delete [] MobaEx;
|
|
|
|
//-------INDX------------------------------------
|
|
//-------MOPY--------
|
|
int n = 0;
|
|
int j = 0;
|
|
MopyEx = new char[mopy_size];
|
|
IndexExTr = new int[mopy_size];
|
|
for (int i=0; i<mopy_size; i+=2)
|
|
{
|
|
// Skip no collision triangles
|
|
if ((int)MOPY[i]&WMO_MATERIAL_NO_COLLISION)
|
|
continue;
|
|
// Use only this triangles
|
|
if ((int)MOPY[i]&(WMO_MATERIAL_HINT|WMO_MATERIAL_COLLIDE_HIT))
|
|
{
|
|
MopyEx[n] = MOPY[i];
|
|
MopyEx[(n+1)] = MOPY[(i+1)];
|
|
IndexExTr[j] = i/2;
|
|
j+=1;
|
|
n+=2;
|
|
}
|
|
}
|
|
MopyEx_size = n;
|
|
IndexExTr_size = j;
|
|
delete [] MOPY;
|
|
delete [] MopyEx;
|
|
|
|
//---------MOVI-----------
|
|
MoviEx = new uint16[IndexExTr_size*3];
|
|
int m = 0;
|
|
for (int i=0; i<IndexExTr_size; ++i)
|
|
{
|
|
int n = 0;
|
|
n = IndexExTr[i]*3;
|
|
for (int x=0; x<3; ++x)
|
|
{
|
|
MoviEx[m] = MOVI[n];
|
|
n++;
|
|
m++;
|
|
}
|
|
}
|
|
delete [] MOVI;
|
|
|
|
MoviExSort = new uint16[IndexExTr_size*3];
|
|
for(int y=0; y<IndexExTr_size*3; ++y)
|
|
{
|
|
MoviExSort[y]=MoviEx[y];
|
|
}
|
|
|
|
uint16 hold;
|
|
for (int pass = 1; pass < IndexExTr_size*3; ++pass)
|
|
{
|
|
for (int i=0; i < IndexExTr_size*3-1; ++i)
|
|
{
|
|
if (MoviExSort[i] > MoviExSort[i+1])
|
|
{
|
|
hold = MoviExSort[i];
|
|
MoviExSort[i] = MoviExSort[i+1];
|
|
MoviExSort[i+1] = hold;
|
|
}
|
|
//double = 65535
|
|
else
|
|
if (MoviExSort[i] == MoviExSort[i+1])
|
|
MoviExSort[i+1] = 65535;
|
|
}
|
|
}
|
|
// double delet
|
|
uint16 s = 0;
|
|
for (int i=0; i < IndexExTr_size*3; ++i)
|
|
{
|
|
if (MoviExSort[i]!=65535)
|
|
{
|
|
MoviExSort[s] = MoviExSort[i];
|
|
s++;
|
|
}
|
|
}
|
|
MovtExSort = new uint16[s];
|
|
for (int i=0; i < s; ++i)
|
|
{
|
|
MovtExSort[i] = MoviExSort[i];
|
|
}
|
|
|
|
for (int i=0; i < IndexExTr_size*3; ++i)
|
|
{
|
|
uint16 b = MoviEx[i];
|
|
for (uint16 x = 0; x < s; ++x)
|
|
{
|
|
if(MoviExSort[x] == b)
|
|
{
|
|
MoviEx[i] = x;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
int INDX[] = {0x58444E49,IndexExTr_size*6+4,IndexExTr_size*3};
|
|
fwrite(INDX,4,3,output);
|
|
fwrite(MoviEx,2,IndexExTr_size*3,output);
|
|
|
|
delete [] MoviEx;
|
|
delete [] MoviExSort;
|
|
delete [] IndexExTr;
|
|
|
|
//----------VERT---------
|
|
//-----MOVT----------
|
|
int d = 0;
|
|
MovtEx = new float[s*3];
|
|
for (uint16 i=0; i<s; ++i)
|
|
{
|
|
int c=0;//!!!!data in MovtExSort[i] more uint16 in great group wmo files!!!!
|
|
c = MovtExSort[i]*3;
|
|
for (int y=0; y<3; ++y)
|
|
{
|
|
MovtEx[d] = MOVT[c];
|
|
c++;
|
|
d++;
|
|
}
|
|
}
|
|
int VERT[] = {0x54524556,d*4+4,d*4/12};// "VERT"
|
|
fwrite(VERT,4,3,output);
|
|
fwrite(MovtEx,4,d,output);
|
|
//------LIQU------------------------
|
|
if(LiquEx_size != 0)
|
|
{
|
|
int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU"
|
|
fwrite(LIQU_h,4,4,output);
|
|
fwrite(LiquEx,4,LiquEx_size/4,output);
|
|
delete [] LiquEx;
|
|
}
|
|
|
|
delete [] MOVT;
|
|
delete [] MovtEx;
|
|
delete [] MovtExSort;
|
|
|
|
//---------------------------------------------
|
|
return IndexExTr_size;
|
|
}
|
|
}
|
|
|
|
WMOGroup::~WMOGroup()
|
|
{
|
|
}
|
|
|
|
WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName,const char*MapName, FILE *pDirfile)
|
|
{
|
|
pos = Vec3D(0,0,0);
|
|
|
|
float ff[3];
|
|
f.read(&id, 4);
|
|
f.read(ff,12);
|
|
pos = Vec3D(ff[0],ff[1],ff[2]);
|
|
f.read(ff,12);
|
|
rot = Vec3D(ff[0],ff[1],ff[2]);
|
|
f.read(ff,12);
|
|
pos2 = Vec3D(ff[0],ff[1],ff[2]);
|
|
f.read(ff,12);
|
|
pos3 = Vec3D(ff[0],ff[1],ff[2]);
|
|
f.read(&d2,4);
|
|
f.read(&d3,4);
|
|
|
|
doodadset = (d2 & 0xFFFF0000) >> 16;
|
|
|
|
int realx1 = (int) ((float) pos2.x / 533.333333f);
|
|
int realy1 = (int) ((float) pos2.z / 533.333333f);
|
|
int realx2 = (int) ((float) pos3.x / 533.333333f);
|
|
int realy2 = (int) ((float) pos3.z / 533.333333f);
|
|
|
|
if(realx1 < 0)
|
|
{
|
|
realx1 +=20; realx2+=20;
|
|
}
|
|
if(realy1 < 0)
|
|
{
|
|
realy1 +=20; realy2+=20;
|
|
} // hack to prevent neg. values
|
|
|
|
//-----------add_in _dir_file----------------
|
|
|
|
char tempname[512];
|
|
// const char dirname[] = "buildings\\dir";
|
|
|
|
sprintf(tempname, "buildings\\%s", WmoInstName);
|
|
FILE *input;
|
|
input = fopen(tempname, "r+b");
|
|
|
|
if(!input)
|
|
return;
|
|
|
|
fseek(input, 8, SEEK_SET); // get the correct no of vertices
|
|
int nVertices;
|
|
fread(&nVertices, sizeof (int), 1, input);
|
|
fclose(input);
|
|
|
|
if(nVertices == 0)
|
|
return;
|
|
|
|
/* FILE *dirfile;
|
|
dirfile = fopen(dirname, "ab");
|
|
if(!dirfile)
|
|
{
|
|
printf("Can't open dirfile!'%s'\n");
|
|
return;
|
|
}
|
|
*/
|
|
float x,z;
|
|
x = pos.x;
|
|
z = pos.z;
|
|
if(x==0 && z == 0)
|
|
{
|
|
x = 533.33333f*32;
|
|
z = 533.33333f*32;
|
|
}
|
|
|
|
fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n",
|
|
MapName,
|
|
WmoInstName,
|
|
(float) x, (float) pos.y, (float) z,
|
|
(float) rot.x, (float) rot.y, (float) rot.z,
|
|
nVertices,
|
|
realx1, realy1,
|
|
realx2, realy2
|
|
);
|
|
|
|
// fclose(dirfile);
|
|
}
|