root/trunk/contrib/vmap_extractor_v2/vmapextract/model.cpp

Revision 2, 7.0 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1//#include "common.h"
2#include "model.h"
3//#include "world.h"
4#include <cassert>
5#include <algorithm>
6
7//int globalTime = 0;
8
9Model::Model(std::string &filename) : filename(filename)
10{
11}
12
13bool Model::open()
14{
15    MPQFile f(filename.c_str());
16
17    ok = !f.isEof();
18
19    if (!ok) 
20    {
21        f.close();
22        printf("Error loading model %s\n", filename.c_str());
23        return false;
24    }
25
26    memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
27    if(header.nBoundingTriangles > 0) {
28
29#if 0
30        animated = isAnimated(f);
31        if(animated)
32        {
33            f.close();
34            return false;
35        }
36#endif
37        trans = 1.0f;
38        origVertices = (ModelVertex*)(f.getBuffer() + header.ofsVertices);
39
40        vertices = new Vec3D[header.nVertices];
41        normals = new Vec3D[header.nVertices];
42
43        for (size_t i=0; i<header.nVertices; i++) 
44        {
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();   
49        }
50
51        ModelView *view = (ModelView*)(f.getBuffer() + header.ofsViews);
52
53        uint16 *indexLookup = (uint16*)(f.getBuffer() + view->ofsIndex);
54        uint16 *triangles = (uint16*)(f.getBuffer() + view->ofsTris);
55
56        nIndices = view->nTris;
57        indices = new uint16[nIndices];
58        for (size_t i = 0; i<nIndices; i++) 
59        {
60            indices[i] = indexLookup[triangles[i]];
61        }
62        f.close();
63    } else {
64        //printf("not included %s\n", filename.c_str());
65        return false;
66    }
67    return true;
68
69}
70
71bool Model::isAnimated(MPQFile &f)
72{
73    // see if we have any animated bones
74    ModelBoneDef *bo = (ModelBoneDef*)(f.getBuffer() + header.ofsBones);
75
76    animGeometry = false;
77    animBones = false;
78    ind = false;
79
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;
89                    }
90                    animGeometry = true;
91                    break;
92                }
93            }
94        }
95    }
96
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;
104            }
105        }
106    }
107
108    animTextures = header.nTexAnims > 0;
109
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;
114
115    if (animMisc) animBones = true;
116
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;
124            }
125        }
126    }
127
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;
135            }
136        }
137    }
138
139    // guess not...
140    return animGeometry || animTextures || animMisc;
141}
142
143bool Model::ConvertToVMAPModel(char * outfilename)
144{
145
146    int N[] = {0x00000000};
147    FILE * output=fopen(outfilename,"wb");
148    if(!output)
149    {
150        printf("Can't create the output file '%s'\n",outfilename);
151        return false;
152    }
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) 
172    {
173        fwrite(indices, sizeof(unsigned short), nIdexes, output);
174    }
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) 
180    {
181        for(int vpos=0; vpos <nVertices; ++vpos) 
182        {
183            float sy = vertices[vpos].y;
184            vertices[vpos].y = vertices[vpos].z;
185            vertices[vpos].z = sy;
186        }
187        fwrite(vertices, sizeof(float)*3, nVertices, output);
188    }
189
190    delete[] vertices;
191    delete[] indices;
192    delete[] normals;
193
194    fclose(output);
195
196    return true;
197}
198
199Model::~Model()
200{
201}
202
203Vec3D fixCoordSystem(Vec3D v)
204{
205    return Vec3D(v.x, v.z, -v.y);
206}
207
208Vec3D fixCoordSystem2(Vec3D v)
209{
210    return Vec3D(v.x, v.z, v.y);
211}
212
213ModelInstance::ModelInstance(MPQFile &f,const char* ModelInstName,const char*MapName,  FILE *pDirfile)
214{
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;
224
225    char tempname[512];
226    sprintf(tempname, ".\\buildings\\%s", ModelInstName);
227    FILE *input;
228    input = fopen(tempname, "r+b");
229    if(!input)
230    {
231        return;
232    }
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)
238    {
239        return;
240    }
241
242    if(pDirfile) 
243    {
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);
248
249
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,
255            sc,
256            nVertices,
257            realx1, realy1,
258            realx2, realy2
259            );                         
260    }
261}
Note: See TracBrowser for help on using the browser.