[8423] Fixed typo in mangos.sql.
[getmangos.git] / contrib / vmap_extractor_v2 / vmapextract / wmo.cpp
blob4817e14c85ba84d7f8a3bcb53c4b1a352e3db99a
1 #define __STORMLIB_SELF__
3 #include "wmo.h"
4 #include "Stormlib.h"
5 #include "mpq.h"
7 using namespace std;
9 WMORoot::WMORoot(std::string &filename) : filename(filename)
13 bool WMORoot::open()
15 MPQFile f(filename.c_str());
16 if(f.isEof ())
18 printf("No such file.\n");
19 return false;
22 size_t size;
23 char fourcc[5];
24 bbcorn1[3] = 0;
25 bbcorn2[3]= 0;
27 while (!f.isEof())
29 f.read(fourcc,4);
30 f.read(&size, 4);
32 flipcc(fourcc);
33 fourcc[4] = 0;
35 size_t nextpos = f.getPos() + size;
37 if (!strcmp(fourcc,"MOHD"))//header
39 f.read(&nTextures, 4);
40 f.read(&nGroups, 4);
41 f.read(&nP, 4);
42 f.read(&nLights, 4);
43 f.read(&nModels, 4);
44 f.read(&nDoodads, 4);
45 f.read(&nDoodadSets, 4);
46 f.read(&col, 4);
47 f.read(&RootID, 4);
48 f.read(bbcorn1,12);
49 f.read(bbcorn2,12);
50 break;
53 else if (!strcmp(fourcc,"MOTX"))
56 else if (!strcmp(fourcc,"MOMT"))
59 else if (!strcmp(fourcc,"MOGN"))
62 else if (!strcmp(fourcc,"MOGI"))
65 else if (!strcmp(fourcc,"MOLT"))
68 else if (!strcmp(fourcc,"MODN"))
71 else if (!strcmp(fourcc,"MODS"))
74 else if (!strcmp(fourcc,"MODD"))
77 else if (!strcmp(fourcc,"MOSB"))
80 else if (!strcmp(fourcc,"MOPV"))
83 else if (!strcmp(fourcc,"MOPT"))
86 else if (!strcmp(fourcc,"MOPR"))
89 else if (!strcmp(fourcc,"MFOG"))
93 f.seek((int)nextpos);
95 f.close ();
96 return true;
99 bool WMORoot::ConvertToVMAPRootWmo(FILE *pOutfile)
101 //printf("Convert RootWmo...\n");
103 fwrite("VMAP002",1,8,pOutfile);
104 unsigned int nVectors = 0;
105 fwrite(&nVectors,sizeof(nVectors),1,pOutfile); // will be filled later
106 fwrite(&nGroups,4,1,pOutfile);
107 return true;
110 WMORoot::~WMORoot()
114 WMOGroup::WMOGroup(std::string &filename) : filename(filename)
118 bool WMOGroup::open()
120 MPQFile f(filename.c_str());
121 if(f.isEof ())
123 printf("No such file.\n");
124 return false;
126 size_t size;
127 char fourcc[5];
128 bbcorn1[3] = 0;
129 bbcorn2[3] = 0;
130 while (!f.isEof())
132 f.read(fourcc,4);
133 f.read(&size, 4);
134 flipcc(fourcc);
135 if (!strcmp(fourcc,"MOGP"))//Fix sizeoff = Data size.
137 size = 68;
139 fourcc[4] = 0;
140 size_t nextpos = f.getPos() + size;
141 LiquEx_size = 0;
142 liquflags = 0;
144 if (!strcmp(fourcc,"MOGP"))//header
146 f.seekRelative(-4);
147 f.read(&offsize, 4);
148 f.read(&flag, 4);
149 f.read(&flag1, 4);
150 f.read(&Xid, 4);
151 f.read(bbcorn1, 12);
152 f.read(bbcorn2, 12);
153 f.read(&Xid2, 4);
154 f.read(&Xid3, 4);
155 f.read(&zero1, 4);
156 f.read(&Xflag, 4);
157 f.read(&nTexture,4);
158 f.read(&GroupID,4);
160 else if (!strcmp(fourcc,"MOPY"))
162 MOPY = new char[size];
163 mopy_size = size;
164 nTriangles = (int)size / 2;
165 f.read(MOPY, size);
167 else if (!strcmp(fourcc,"MOVI"))
169 MOVI = new uint16[size/2];
170 f.read(MOVI, size);
172 else if (!strcmp(fourcc,"MOVT"))
174 MOVT = new float[size/4];
175 f.read(MOVT, size);
176 nVertices = (int)size / 12;
178 else if (!strcmp(fourcc,"MONR"))
181 else if (!strcmp(fourcc,"MOTV"))
184 else if (!strcmp(fourcc,"MOBA"))
186 MOBA = new uint16[size/2];
187 moba_size = size/2;
188 f.read(MOBA, size);
190 else if (!strcmp(fourcc,"MLIQ"))
192 liquflags |= 1;
193 WMOLiquidHeader hlq;
194 f.read(&hlq, 0x1E);
195 float ydir = -1.0f;
196 hlq_xverts = hlq.xverts;
197 hlq_yverts = hlq.yverts;
198 int noVer = hlq.xverts * hlq.yverts;
199 float tilesize = CHUNKSIZE / 8.0f;
200 LiquEx_size = sizeof(float) * 3 * noVer;
201 LiquEx = new float[sizeof(float) * 3 * noVer];
202 int p = 0;
204 for (int j=0; j<hlq.yverts; ++j)
206 for (int i=0; i<hlq.xverts; ++i)
208 LiquEx[p++] = hlq.pos_x + tilesize * i;
209 LiquEx[p++] = hlq.pos_z;
210 LiquEx[p++] = ydir * (hlq.pos_y + tilesize * j);
214 f.seek((int)nextpos);
216 f.close();
217 return true;
220 int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
222 if(pPreciseVectorData)
224 fwrite(&liquflags,sizeof(uint32),1,output);
225 char GRP[] = "GRP ";
226 fwrite(GRP,1,4,output);
228 int k = 0;
229 int moba_batch = moba_size/12;
230 MobaEx = new int[moba_batch*4];
231 for(int i=8; i<moba_size; i+=12)
233 MobaEx[k++] = MOBA[i];
235 delete [] MOBA;
236 int moba_size_grp = moba_batch*4+4;
237 fwrite(&moba_size_grp,4,1,output);
238 fwrite(&moba_batch,4,1,output);
239 fwrite(MobaEx,4,k,output);
240 delete [] MobaEx;
242 uint32 nIdexes = nTriangles * 3;
244 if(fwrite("INDX",4, 1, output) != 1)
246 printf("Error while writing file nbraches ID");
247 exit(0);
249 int wsize = sizeof(uint32) + sizeof(unsigned short) * nIdexes;
250 if(fwrite(&wsize, sizeof(int), 1, output) != 1)
252 printf("Error while writing file wsize");
253 // no need to exit?
255 if(fwrite(&nIdexes, sizeof(uint32), 1, output) != 1)
257 printf("Error while writing file nIndexes");
258 exit(0);
260 if(nIdexes >0)
262 if(fwrite(MOVI, sizeof(unsigned short), nIdexes, output) != nIdexes)
264 printf("Error while writing file indexarray");
265 exit(0);
269 if(fwrite("VERT",4, 1, output) != 1)
271 printf("Error while writing file nbraches ID");
272 exit(0);
274 wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
275 if(fwrite(&wsize, sizeof(int), 1, output) != 1)
277 printf("Error while writing file wsize");
278 // no need to exit?
280 if(fwrite(&nVertices, sizeof(int), 1, output) != 1)
282 printf("Error while writing file nVertices");
283 exit(0);
285 if(nVertices >0)
287 if(fwrite(MOVT, sizeof(float)*3, nVertices, output) != nVertices)
289 printf("Error while writing file vectors");
290 exit(0);
294 if(LiquEx_size != 0)
296 int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU"
297 fwrite(LIQU_h,4,4,output);
298 fwrite(LiquEx,4,LiquEx_size/4,output);
299 delete [] LiquEx;
302 return nTriangles;
304 else
306 //printf("Convert GroupWmo...\n");
307 //-------GRP -------------------------------------
308 fwrite(&liquflags,sizeof(uint32),1,output);
309 char GRP[] = "GRP ";
310 fwrite(GRP,1,4,output);
311 int k = 0;
312 int moba_batch = moba_size/12;
313 MobaEx = new int[moba_batch*4];
314 for(int i=8; i<moba_size; i+=12)
316 MobaEx[k++] = MOBA[i];
318 delete [] MOBA;
319 int moba_size_grp = moba_batch*4+4;
320 fwrite(&moba_size_grp,4,1,output);
321 fwrite(&moba_batch,4,1,output);
322 fwrite(MobaEx,4,k,output);
323 delete [] MobaEx;
325 //-------INDX------------------------------------
326 //-------MOPY--------
327 int n = 0;
328 int j = 0;
329 MopyEx = new char[mopy_size];
330 IndexExTr = new int[mopy_size];
331 for (int i=0; i<mopy_size; i+=2)
333 // Skip no collision triangles
334 if ((int)MOPY[i]&WMO_MATERIAL_NO_COLLISION)
335 continue;
336 // Use only this triangles
337 if ((int)MOPY[i]&(WMO_MATERIAL_HINT|WMO_MATERIAL_COLLIDE_HIT))
339 MopyEx[n] = MOPY[i];
340 MopyEx[(n+1)] = MOPY[(i+1)];
341 IndexExTr[j] = i/2;
342 j+=1;
343 n+=2;
346 MopyEx_size = n;
347 IndexExTr_size = j;
348 delete [] MOPY;
349 delete [] MopyEx;
351 //---------MOVI-----------
352 MoviEx = new uint16[IndexExTr_size*3];
353 int m = 0;
354 for (int i=0; i<IndexExTr_size; ++i)
356 int n = 0;
357 n = IndexExTr[i]*3;
358 for (int x=0; x<3; ++x)
360 MoviEx[m] = MOVI[n];
361 n++;
362 m++;
365 delete [] MOVI;
367 MoviExSort = new uint16[IndexExTr_size*3];
368 for(int y=0; y<IndexExTr_size*3; ++y)
370 MoviExSort[y]=MoviEx[y];
373 uint16 hold;
374 for (int pass = 1; pass < IndexExTr_size*3; ++pass)
376 for (int i=0; i < IndexExTr_size*3-1; ++i)
378 if (MoviExSort[i] > MoviExSort[i+1])
380 hold = MoviExSort[i];
381 MoviExSort[i] = MoviExSort[i+1];
382 MoviExSort[i+1] = hold;
384 //double = 65535
385 else
386 if (MoviExSort[i] == MoviExSort[i+1])
387 MoviExSort[i+1] = 65535;
390 // double delet
391 uint16 s = 0;
392 for (int i=0; i < IndexExTr_size*3; ++i)
394 if (MoviExSort[i]!=65535)
396 MoviExSort[s] = MoviExSort[i];
397 s++;
400 MovtExSort = new uint16[s];
401 for (int i=0; i < s; ++i)
403 MovtExSort[i] = MoviExSort[i];
406 for (int i=0; i < IndexExTr_size*3; ++i)
408 uint16 b = MoviEx[i];
409 for (uint16 x = 0; x < s; ++x)
411 if(MoviExSort[x] == b)
413 MoviEx[i] = x;
414 break;
418 int INDX[] = {0x58444E49,IndexExTr_size*6+4,IndexExTr_size*3};
419 fwrite(INDX,4,3,output);
420 fwrite(MoviEx,2,IndexExTr_size*3,output);
422 delete [] MoviEx;
423 delete [] MoviExSort;
424 delete [] IndexExTr;
426 //----------VERT---------
427 //-----MOVT----------
428 int d = 0;
429 MovtEx = new float[s*3];
430 for (uint16 i=0; i<s; ++i)
432 int c=0;//!!!!data in MovtExSort[i] more uint16 in great group wmo files!!!!
433 c = MovtExSort[i]*3;
434 for (int y=0; y<3; ++y)
436 MovtEx[d] = MOVT[c];
437 c++;
438 d++;
441 int VERT[] = {0x54524556,d*4+4,d*4/12};// "VERT"
442 fwrite(VERT,4,3,output);
443 fwrite(MovtEx,4,d,output);
444 //------LIQU------------------------
445 if(LiquEx_size != 0)
447 int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU"
448 fwrite(LIQU_h,4,4,output);
449 fwrite(LiquEx,4,LiquEx_size/4,output);
450 delete [] LiquEx;
453 delete [] MOVT;
454 delete [] MovtEx;
455 delete [] MovtExSort;
457 //---------------------------------------------
458 return IndexExTr_size;
462 WMOGroup::~WMOGroup()
466 WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName,const char*MapName, FILE *pDirfile)
468 pos = Vec3D(0,0,0);
470 float ff[3];
471 f.read(&id, 4);
472 f.read(ff,12);
473 pos = Vec3D(ff[0],ff[1],ff[2]);
474 f.read(ff,12);
475 rot = Vec3D(ff[0],ff[1],ff[2]);
476 f.read(ff,12);
477 pos2 = Vec3D(ff[0],ff[1],ff[2]);
478 f.read(ff,12);
479 pos3 = Vec3D(ff[0],ff[1],ff[2]);
480 f.read(&d2,4);
481 f.read(&d3,4);
483 doodadset = (d2 & 0xFFFF0000) >> 16;
485 int realx1 = (int) ((float) pos2.x / 533.333333f);
486 int realy1 = (int) ((float) pos2.z / 533.333333f);
487 int realx2 = (int) ((float) pos3.x / 533.333333f);
488 int realy2 = (int) ((float) pos3.z / 533.333333f);
490 if(realx1 < 0)
492 realx1 +=20; realx2+=20;
494 if(realy1 < 0)
496 realy1 +=20; realy2+=20;
497 } // hack to prevent neg. values
499 //-----------add_in _dir_file----------------
501 char tempname[512];
502 // const char dirname[] = "buildings\\dir";
504 sprintf(tempname, "buildings\\%s", WmoInstName);
505 FILE *input;
506 input = fopen(tempname, "r+b");
508 if(!input)
509 return;
511 fseek(input, 8, SEEK_SET); // get the correct no of vertices
512 int nVertices;
513 fread(&nVertices, sizeof (int), 1, input);
514 fclose(input);
516 if(nVertices == 0)
517 return;
519 /* FILE *dirfile;
520 dirfile = fopen(dirname, "ab");
521 if(!dirfile)
523 printf("Can't open dirfile!'%s'\n");
524 return;
527 float x,z;
528 x = pos.x;
529 z = pos.z;
530 if(x==0 && z == 0)
532 x = 533.33333f*32;
533 z = 533.33333f*32;
536 fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n",
537 MapName,
538 WmoInstName,
539 (float) x, (float) pos.y, (float) z,
540 (float) rot.x, (float) rot.y, (float) rot.z,
541 nVertices,
542 realx1, realy1,
543 realx2, realy2
546 // fclose(dirfile);