Updated Copyright year to 2013
[getmangos.git] / contrib / vmap_extractor / vmapextract / model.cpp
blobe13dc424a0068cc7028b396a9935724413d1a5bc
1 /*
2 * Copyright (C) 2005-2013 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #define _CRT_SECURE_NO_WARNINGS
21 #include "vmapexport.h"
22 #include "model.h"
23 #include "wmo.h"
24 #include "mpqfile.h"
25 #include <cassert>
26 #include <algorithm>
27 #include <cstdio>
29 extern HANDLE WorldMpq;
31 Model::Model(std::string& filename) : filename(filename), vertices(0), indices(0)
35 bool Model::open()
37 MPQFile f(WorldMpq, filename.c_str());
39 ok = !f.isEof();
41 if (!ok)
43 f.close();
44 // Do not show this error on console to avoid confusion, the extractor can continue working even if some models fail to load
45 //printf("Error loading model %s\n", filename.c_str());
46 return false;
49 _unload();
51 memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
52 if (header.nBoundingTriangles > 0)
54 f.seek(0);
55 f.seekRelative(header.ofsBoundingVertices);
56 vertices = new Vec3D[header.nBoundingVertices];
57 f.read(vertices, header.nBoundingVertices * 12);
58 for (uint32 i = 0; i < header.nBoundingVertices; i++)
60 vertices[i] = fixCoordSystem(vertices[i]);
62 f.seek(0);
63 f.seekRelative(header.ofsBoundingTriangles);
64 indices = new uint16[header.nBoundingTriangles];
65 f.read(indices, header.nBoundingTriangles * 2);
66 f.close();
68 else
70 //printf("not included %s\n", filename.c_str());
71 f.close();
72 return false;
74 return true;
77 bool Model::ConvertToVMAPModel(const char* outfilename)
79 int N[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
80 FILE* output = fopen(outfilename, "wb");
81 if (!output)
83 printf("Can't create the output file '%s'\n", outfilename);
84 return false;
86 fwrite(szRawVMAPMagic, 8, 1, output);
87 uint32 nVertices = 0;
88 nVertices = header.nBoundingVertices;
89 fwrite(&nVertices, sizeof(int), 1, output);
90 uint32 nofgroups = 1;
91 fwrite(&nofgroups, sizeof(uint32), 1, output);
92 fwrite(N, 4 * 3, 1, output); // rootwmoid, flags, groupid
93 fwrite(N, sizeof(float), 3 * 2, output); //bbox, only needed for WMO currently
94 fwrite(N, 4, 1, output); // liquidflags
95 fwrite("GRP ", 4, 1, output);
96 uint32 branches = 1;
97 int wsize;
98 wsize = sizeof(branches) + sizeof(uint32) * branches;
99 fwrite(&wsize, sizeof(int), 1, output);
100 fwrite(&branches, sizeof(branches), 1, output);
101 uint32 nIndexes = 0;
102 nIndexes = header.nBoundingTriangles;
103 fwrite(&nIndexes, sizeof(uint32), 1, output);
104 fwrite("INDX", 4, 1, output);
105 wsize = sizeof(uint32) + sizeof(unsigned short) * nIndexes;
106 fwrite(&wsize, sizeof(int), 1, output);
107 fwrite(&nIndexes, sizeof(uint32), 1, output);
108 if (nIndexes > 0)
110 fwrite(indices, sizeof(unsigned short), nIndexes, output);
112 fwrite("VERT", 4, 1, output);
113 wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
114 fwrite(&wsize, sizeof(int), 1, output);
115 fwrite(&nVertices, sizeof(int), 1, output);
116 if (nVertices > 0)
118 for (uint32 vpos = 0; vpos < nVertices; ++vpos)
120 std::swap(vertices[vpos].y, vertices[vpos].z);
122 fwrite(vertices, sizeof(float) * 3, nVertices, output);
125 fclose(output);
127 return true;
131 Vec3D fixCoordSystem(Vec3D v)
133 return Vec3D(v.x, v.z, -v.y);
136 Vec3D fixCoordSystem2(Vec3D v)
138 return Vec3D(v.x, v.z, v.y);
141 ModelInstance::ModelInstance(MPQFile& f, const char* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile)
143 float ff[3];
144 f.read(&id, 4);
145 f.read(ff, 12);
146 pos = fixCoords(Vec3D(ff[0], ff[1], ff[2]));
147 f.read(ff, 12);
148 rot = Vec3D(ff[0], ff[1], ff[2]);
149 f.read(&scale, 4);
150 // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
151 sc = scale / 1024.0f;
153 char tempname[512];
154 sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName);
155 FILE* input;
156 input = fopen(tempname, "r+b");
158 if (!input)
160 //printf("ModelInstance::ModelInstance couldn't open %s\n", tempname);
161 return;
164 fseek(input, 8, SEEK_SET); // get the correct no of vertices
165 int nVertices;
166 fread(&nVertices, sizeof(int), 1, input);
167 fclose(input);
169 if (nVertices == 0)
170 return;
172 uint16 adtId = 0;// not used for models
173 uint32 flags = MOD_M2;
174 if (tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN;
175 //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, name
176 fwrite(&mapID, sizeof(uint32), 1, pDirfile);
177 fwrite(&tileX, sizeof(uint32), 1, pDirfile);
178 fwrite(&tileY, sizeof(uint32), 1, pDirfile);
179 fwrite(&flags, sizeof(uint32), 1, pDirfile);
180 fwrite(&adtId, sizeof(uint16), 1, pDirfile);
181 fwrite(&id, sizeof(uint32), 1, pDirfile);
182 fwrite(&pos, sizeof(float), 3, pDirfile);
183 fwrite(&rot, sizeof(float), 3, pDirfile);
184 fwrite(&sc, sizeof(float), 1, pDirfile);
185 uint32 nlen = strlen(ModelInstName);
186 fwrite(&nlen, sizeof(uint32), 1, pDirfile);
187 fwrite(ModelInstName, sizeof(char), nlen, pDirfile);
189 /* int realx1 = (int) ((float) pos.x / 533.333333f);
190 int realy1 = (int) ((float) pos.z / 533.333333f);
191 int realx2 = (int) ((float) pos.x / 533.333333f);
192 int realy2 = (int) ((float) pos.z / 533.333333f);
194 fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n",
195 MapName,
196 ModelInstName,
197 (float) pos.x, (float) pos.y, (float) pos.z,
198 (float) rot.x, (float) rot.y, (float) rot.z,
200 nVertices,
201 realx1, realy1,
202 realx2, realy2
203 ); */