mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 19:37:02 +00:00
Imported MaNGOS revision 6767 from http://mangos.svn.sourceforge.net/svnroot/mangos/trunk/
This commit is contained in:
parent
d767495d5b
commit
800ee76535
3322 changed files with 903437 additions and 0 deletions
261
contrib/vmap_extractor_v2/vmapextract/model.cpp
Normal file
261
contrib/vmap_extractor_v2/vmapextract/model.cpp
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
//#include "common.h"
|
||||
#include "model.h"
|
||||
//#include "world.h"
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
//int globalTime = 0;
|
||||
|
||||
Model::Model(std::string &filename) : filename(filename)
|
||||
{
|
||||
}
|
||||
|
||||
bool Model::open()
|
||||
{
|
||||
MPQFile f(filename.c_str());
|
||||
|
||||
ok = !f.isEof();
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
f.close();
|
||||
printf("Error loading model %s\n", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
|
||||
if(header.nBoundingTriangles > 0) {
|
||||
|
||||
#if 0
|
||||
animated = isAnimated(f);
|
||||
if(animated)
|
||||
{
|
||||
f.close();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
trans = 1.0f;
|
||||
origVertices = (ModelVertex*)(f.getBuffer() + header.ofsVertices);
|
||||
|
||||
vertices = new Vec3D[header.nVertices];
|
||||
normals = new Vec3D[header.nVertices];
|
||||
|
||||
for (size_t i=0; i<header.nVertices; i++)
|
||||
{
|
||||
origVertices[i].pos = fixCoordSystem(origVertices[i].pos);
|
||||
origVertices[i].normal = fixCoordSystem(origVertices[i].normal);
|
||||
vertices[i] = origVertices[i].pos;
|
||||
normals[i] = origVertices[i].normal.normalize();
|
||||
}
|
||||
|
||||
ModelView *view = (ModelView*)(f.getBuffer() + header.ofsViews);
|
||||
|
||||
uint16 *indexLookup = (uint16*)(f.getBuffer() + view->ofsIndex);
|
||||
uint16 *triangles = (uint16*)(f.getBuffer() + view->ofsTris);
|
||||
|
||||
nIndices = view->nTris;
|
||||
indices = new uint16[nIndices];
|
||||
for (size_t i = 0; i<nIndices; i++)
|
||||
{
|
||||
indices[i] = indexLookup[triangles[i]];
|
||||
}
|
||||
f.close();
|
||||
} else {
|
||||
//printf("not included %s\n", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool Model::isAnimated(MPQFile &f)
|
||||
{
|
||||
// see if we have any animated bones
|
||||
ModelBoneDef *bo = (ModelBoneDef*)(f.getBuffer() + header.ofsBones);
|
||||
|
||||
animGeometry = false;
|
||||
animBones = false;
|
||||
ind = false;
|
||||
|
||||
ModelVertex *verts = (ModelVertex*)(f.getBuffer() + header.ofsVertices);
|
||||
for (size_t i=0; i<header.nVertices && !animGeometry; i++) {
|
||||
for (size_t b=0; b<4; b++) {
|
||||
if (verts[i].weights[b]>0) {
|
||||
ModelBoneDef &bb = bo[verts[i].bones[b]];
|
||||
if (bb.translation.type || bb.rotation.type || bb.scaling.type || (bb.flags&8)) {
|
||||
if (bb.flags&8) {
|
||||
// if we have billboarding, the model will need per-instance animation
|
||||
ind = true;
|
||||
}
|
||||
animGeometry = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (animGeometry) animBones = true;
|
||||
else {
|
||||
for (size_t i=0; i<header.nBones; i++) {
|
||||
ModelBoneDef &bb = bo[i];
|
||||
if (bb.translation.type || bb.rotation.type || bb.scaling.type) {
|
||||
animBones = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
animTextures = header.nTexAnims > 0;
|
||||
|
||||
bool animMisc = header.nCameras>0 || // why waste time, pretty much all models with cameras need animation
|
||||
header.nLights>0 || // same here
|
||||
header.nParticleEmitters>0 ||
|
||||
header.nRibbonEmitters>0;
|
||||
|
||||
if (animMisc) animBones = true;
|
||||
|
||||
// animated colors
|
||||
if (header.nColors) {
|
||||
ModelColorDef *cols = (ModelColorDef*)(f.getBuffer() + header.ofsColors);
|
||||
for (size_t i=0; i<header.nColors; i++) {
|
||||
if (cols[i].color.type!=0 || cols[i].opacity.type!=0) {
|
||||
animMisc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// animated opacity
|
||||
if (header.nTransparency && !animMisc) {
|
||||
ModelTransDef *trs = (ModelTransDef*)(f.getBuffer() + header.ofsTransparency);
|
||||
for (size_t i=0; i<header.nTransparency; i++) {
|
||||
if (trs[i].trans.type!=0) {
|
||||
animMisc = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// guess not...
|
||||
return animGeometry || animTextures || animMisc;
|
||||
}
|
||||
|
||||
bool Model::ConvertToVMAPModel(char * outfilename)
|
||||
{
|
||||
|
||||
int N[] = {0x00000000};
|
||||
FILE * output=fopen(outfilename,"wb");
|
||||
if(!output)
|
||||
{
|
||||
printf("Can't create the output file '%s'\n",outfilename);
|
||||
return false;
|
||||
}
|
||||
fwrite("VMAP002",8,1,output);
|
||||
int nVertices = header.nVertices;
|
||||
fwrite(&nVertices, sizeof(int), 1, output);
|
||||
uint32 nofgroups = 1;
|
||||
fwrite(&nofgroups,sizeof(uint32), 1, output);
|
||||
fwrite(N,4,1,output);
|
||||
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 nIdexes = (uint32) nIndices;
|
||||
fwrite(&nIndices,sizeof(uint32), 1, output);
|
||||
fwrite("INDX",4, 1, output);
|
||||
wsize = sizeof(uint32) + sizeof(unsigned short) * nIdexes;
|
||||
fwrite(&wsize, sizeof(int), 1, output);
|
||||
fwrite(&nIdexes, sizeof(uint32), 1, output);
|
||||
if(nIdexes >0)
|
||||
{
|
||||
fwrite(indices, sizeof(unsigned short), nIdexes, 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(int vpos=0; vpos <nVertices; ++vpos)
|
||||
{
|
||||
float sy = vertices[vpos].y;
|
||||
vertices[vpos].y = vertices[vpos].z;
|
||||
vertices[vpos].z = sy;
|
||||
}
|
||||
fwrite(vertices, sizeof(float)*3, nVertices, output);
|
||||
}
|
||||
|
||||
delete[] vertices;
|
||||
delete[] indices;
|
||||
delete[] normals;
|
||||
|
||||
fclose(output);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Model::~Model()
|
||||
{
|
||||
}
|
||||
|
||||
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,const char* ModelInstName,const char*MapName, FILE *pDirfile)
|
||||
{
|
||||
float ff[3];
|
||||
f.read(&d1, 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(&scale,4);
|
||||
// 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, ".\\buildings\\%s", ModelInstName);
|
||||
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;
|
||||
}
|
||||
|
||||
if(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
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue