[4057] added: Line of sight (vmaps) [part 2] (last part)
[mangos-git.git] / contrib / vmap_extractor_v2 / vmapextract / model.cpp
blob90459f6ac9f0dc202fd79ecd67f5fee2f221548d
1 //#include "common.h"
2 #include "model.h"
3 //#include "world.h"
4 #include <cassert>
5 #include <algorithm>
7 //int globalTime = 0;
9 Model::Model(std::string &filename) : filename(filename)
13 bool Model::open()
15 MPQFile f(filename.c_str());
17 ok = !f.isEof();
19 if (!ok)
21 f.close();
22 printf("Error loading model %s\n", filename.c_str());
23 return false;
26 memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
27 if(header.nBoundingTriangles > 0) {
29 animated = isAnimated(f);
30 #if 0
31 if(animated)
33 f.close();
34 return false;
36 #endif
37 trans = 1.0f;
38 origVertices = (ModelVertex*)(f.getBuffer() + header.ofsVertices);
40 vertices = new Vec3D[header.nVertices];
41 normals = new Vec3D[header.nVertices];
43 for (size_t i=0; i<header.nVertices; i++)
45 origVertices[i].pos = fixCoordSystem(origVertices[i].pos);
46 origVertices[i].normal = fixCoordSystem(origVertices[i].normal);
47 vertices[i] = origVertices[i].pos;
48 normals[i] = origVertices[i].normal.normalize();
51 ModelView *view = (ModelView*)(f.getBuffer() + header.ofsViews);
53 uint16 *indexLookup = (uint16*)(f.getBuffer() + view->ofsIndex);
54 uint16 *triangles = (uint16*)(f.getBuffer() + view->ofsTris);
56 nIndices = view->nTris;
57 indices = new uint16[nIndices];
58 for (size_t i = 0; i<nIndices; i++)
60 indices[i] = indexLookup[triangles[i]];
62 f.close();
63 } else {
64 //printf("not included %s\n", filename.c_str());
65 return false;
67 return true;
71 bool Model::isAnimated(MPQFile &f)
73 // see if we have any animated bones
74 ModelBoneDef *bo = (ModelBoneDef*)(f.getBuffer() + header.ofsBones);
76 animGeometry = false;
77 animBones = false;
78 ind = false;
80 ModelVertex *verts = (ModelVertex*)(f.getBuffer() + header.ofsVertices);
81 for (size_t i=0; i<header.nVertices && !animGeometry; i++) {
82 for (size_t b=0; b<4; b++) {
83 if (verts[i].weights[b]>0) {
84 ModelBoneDef &bb = bo[verts[i].bones[b]];
85 if (bb.translation.type || bb.rotation.type || bb.scaling.type || (bb.flags&8)) {
86 if (bb.flags&8) {
87 // if we have billboarding, the model will need per-instance animation
88 ind = true;
90 animGeometry = true;
91 break;
97 if (animGeometry) animBones = true;
98 else {
99 for (size_t i=0; i<header.nBones; i++) {
100 ModelBoneDef &bb = bo[i];
101 if (bb.translation.type || bb.rotation.type || bb.scaling.type) {
102 animBones = true;
103 break;
108 animTextures = header.nTexAnims > 0;
110 bool animMisc = header.nCameras>0 || // why waste time, pretty much all models with cameras need animation
111 header.nLights>0 || // same here
112 header.nParticleEmitters>0 ||
113 header.nRibbonEmitters>0;
115 if (animMisc) animBones = true;
117 // animated colors
118 if (header.nColors) {
119 ModelColorDef *cols = (ModelColorDef*)(f.getBuffer() + header.ofsColors);
120 for (size_t i=0; i<header.nColors; i++) {
121 if (cols[i].color.type!=0 || cols[i].opacity.type!=0) {
122 animMisc = true;
123 break;
128 // animated opacity
129 if (header.nTransparency && !animMisc) {
130 ModelTransDef *trs = (ModelTransDef*)(f.getBuffer() + header.ofsTransparency);
131 for (size_t i=0; i<header.nTransparency; i++) {
132 if (trs[i].trans.type!=0) {
133 animMisc = true;
134 break;
139 // guess not...
140 return animGeometry || animTextures || animMisc;
143 bool Model::ConvertToVMAPModel(char * outfilename)
146 int N[] = {0x00000000};
147 FILE * output=fopen(outfilename,"wb");
148 if(!output)
150 printf("Can't create the output file '%s'\n",outfilename);
151 return false;
153 fwrite("VMAP002",8,1,output);
154 int nVertices = header.nVertices;
155 fwrite(&nVertices, sizeof(int), 1, output);
156 uint32 nofgroups = 1;
157 fwrite(&nofgroups,sizeof(uint32), 1, output);
158 fwrite(N,4,1,output);
159 fwrite("GRP ",4,1,output);
160 uint32 branches = 1;
161 int wsize;
162 wsize = sizeof(branches) + sizeof(uint32) * branches;
163 fwrite(&wsize, sizeof(int), 1, output);
164 fwrite(&branches,sizeof(branches), 1, output);
165 uint32 nIdexes = (uint32) nIndices;
166 fwrite(&nIndices,sizeof(uint32), 1, output);
167 fwrite("INDX",4, 1, output);
168 wsize = sizeof(uint32) + sizeof(unsigned short) * nIdexes;
169 fwrite(&wsize, sizeof(int), 1, output);
170 fwrite(&nIdexes, sizeof(uint32), 1, output);
171 if(nIdexes >0)
173 fwrite(indices, sizeof(unsigned short), nIdexes, output);
175 fwrite("VERT",4, 1, output);
176 wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
177 fwrite(&wsize, sizeof(int), 1, output);
178 fwrite(&nVertices, sizeof(int), 1, output);
179 if(nVertices >0)
181 for(int vpos=0; vpos <nVertices; ++vpos)
183 float sy = vertices[vpos].y;
184 vertices[vpos].y = vertices[vpos].z;
185 vertices[vpos].z = sy;
187 fwrite(vertices, sizeof(float)*3, nVertices, output);
190 delete[] vertices;
191 delete[] indices;
192 delete[] normals;
194 fclose(output);
196 return true;
199 Model::~Model()
203 Vec3D fixCoordSystem(Vec3D v)
205 return Vec3D(v.x, v.z, -v.y);
208 Vec3D fixCoordSystem2(Vec3D v)
210 return Vec3D(v.x, v.z, v.y);
213 ModelInstance::ModelInstance(MPQFile &f,const char* ModelInstName,const char*MapName, FILE *pDirfile)
215 float ff[3];
216 f.read(&d1, 4);
217 f.read(ff,12);
218 pos = Vec3D(ff[0],ff[1],ff[2]);
219 f.read(ff,12);
220 rot = Vec3D(ff[0],ff[1],ff[2]);
221 f.read(&scale,4);
222 // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
223 sc = scale / 1024.0f;
225 char tempname[512];
226 sprintf(tempname, ".\\buildings\\%s", ModelInstName);
227 FILE *input;
228 input = fopen(tempname, "r+b");
229 if(!input)
231 return;
233 fseek(input, 8, SEEK_SET); // get the correct no of vertices
234 int nVertices;
235 fread(&nVertices, sizeof (int), 1, input);
236 fclose(input);
237 if(nVertices == 0)
239 return;
242 if(pDirfile)
244 int realx1 = (int) ((float) pos.x / 533.333333f);
245 int realy1 = (int) ((float) pos.z / 533.333333f);
246 int realx2 = (int) ((float) pos.x / 533.333333f);
247 int realy2 = (int) ((float) pos.z / 533.333333f);
250 fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n",
251 MapName,
252 ModelInstName,
253 (float) pos.x, (float) pos.y, (float) pos.z,
254 (float) rot.x, (float) rot.y, (float) rot.z,
256 nVertices,
257 realx1, realy1,
258 realx2, realy2