[4057] added: Line of sight (vmaps) [part 2] (last part)
[mangos-git.git] / contrib / vmap_extractor_v2 / vmapextract / wmo.cpp
blob144da74caf09ad4751ca3066a88f05bdf88b1db3
1 #define __STORMLIB_SELF__
3 #include "wmo.h"
4 #include "Stormlib.h"
5 #include "mpq.h"
7 using namespace std;
10 WMORoot::WMORoot(std::string &filename) : filename(filename)
13 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
15 bool WMORoot::open()
18 MPQFile f(filename.c_str());
19 if(f.isEof ())
21 printf("No such file.\n");
22 return false;
25 size_t size;
26 char fourcc[5];
27 bbcorn1[3] = 0;
28 bbcorn2[3]= 0;
30 while (!f.isEof ())
32 f.read(fourcc,4);
33 f.read(&size, 4);
35 flipcc(fourcc);
36 fourcc[4] = 0;
38 size_t nextpos = f.getPos() + size;
40 if (!strcmp(fourcc,"MOHD"))//header
43 f.read(&nTextures, 4);
44 f.read(&nGroups, 4);
45 f.read(&nP, 4);
46 f.read(&nLights, 4);
47 f.read(&nModels, 4);
48 f.read(&nDoodads, 4);
49 f.read(&nDoodadSets, 4);
50 f.read(&col, 4);
51 f.read(&RootID, 4);
52 f.read(bbcorn1,12);
53 f.read(bbcorn2,12);
54 break;
57 else if (!strcmp(fourcc,"MOTX"))
61 else if (!strcmp(fourcc,"MOMT"))
65 else if (!strcmp(fourcc,"MOGN"))
69 else if (!strcmp(fourcc,"MOGI"))
73 else if (!strcmp(fourcc,"MOLT"))
77 else if (!strcmp(fourcc,"MODN"))
81 else if (!strcmp(fourcc,"MODS"))
85 else if (!strcmp(fourcc,"MODD"))
89 else if (!strcmp(fourcc,"MOSB"))
93 else if (!strcmp(fourcc,"MOPV"))
97 else if (!strcmp(fourcc,"MOPT"))
101 else if (!strcmp(fourcc,"MOPR"))
105 else if (!strcmp(fourcc,"MFOG"))
110 f.seek((int)nextpos);
112 f.close ();
113 return true;
115 //---------------------------------------------------------------------------
117 bool WMORoot::ConvertToVMAPRootWmo(FILE *pOutfile)
119 //printf("Convert RootWmo...\n");
121 fwrite("VMAP002",1,8,pOutfile);
122 unsigned int nVectors = 0;
123 fwrite(&nVectors,sizeof(nVectors),1,pOutfile); // will be filled later
124 fwrite(&nGroups,4,1,pOutfile);
125 return true;
128 //----------------------------------------------------------------------------
129 WMORoot::~WMORoot()
132 //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
134 WMOGroup::WMOGroup(std::string &filename) : filename(filename)
137 //---------------------------------------------------------------------------
138 bool WMOGroup::open()
140 MPQFile f(filename.c_str());
141 if(f.isEof ())
143 printf("No such file.\n");
144 return false;
146 size_t size;
147 char fourcc[5];
148 bbcorn1[3] = 0;
149 bbcorn2[3] = 0;
150 while (!f.isEof ())
152 f.read(fourcc,4);
153 f.read(&size, 4);
154 flipcc(fourcc);
155 if (!strcmp(fourcc,"MOGP"))//Fix sizeoff = Data size.
157 size = 68;
159 fourcc[4] = 0;
160 size_t nextpos = f.getPos() + size;
161 LiquEx_size = 0;
162 liquflags = 0;
164 if (!strcmp(fourcc,"MOGP"))//header
166 f.seekRelative(-4);
167 f.read(&offsize, 4);
168 f.read(&flag, 4);
169 f.read(&flag1, 4);
170 f.read(&Xid, 4);
171 f.read(bbcorn1, 12);
172 f.read(bbcorn2, 12);
173 f.read(&Xid2, 4);
174 f.read(&Xid3, 4);
175 f.read(&zero1, 4);
176 f.read(&Xflag, 4);
177 f.read(&nTexture,4);
178 f.read(&GroupID,4);
180 else if (!strcmp(fourcc,"MOPY"))
182 MOPY = new char[size];
183 mopy_size = size;
184 nTriangles = (int)size / 2;
185 f.read(MOPY, size);
187 else if (!strcmp(fourcc,"MOVI"))
189 MOVI = new uint16[size/2];
190 f.read(MOVI, size);
193 else if (!strcmp(fourcc,"MOVT"))
195 MOVT = new float[size/4];
196 f.read(MOVT, size);
197 nVertices = (int)size / 12;
199 else if (!strcmp(fourcc,"MONR"))
202 else if (!strcmp(fourcc,"MOTV"))
205 else if (!strcmp(fourcc,"MOBA"))
207 MOBA = new uint16[size/2];
208 moba_size = size/2;
209 f.read(MOBA, size);
211 else if (!strcmp(fourcc,"MLIQ"))
213 liquflags |= 1;
214 WMOLiquidHeader hlq;
215 f.read(&hlq, 0x1E);
216 float ydir = -1.0f;
217 hlq_xverts = hlq.xverts;
218 hlq_yverts = hlq.yverts;
219 int noVer = hlq.xverts * hlq.yverts;
220 float tilesize = CHUNKSIZE / 8.0f;
221 LiquEx_size = sizeof(float) * 3 * noVer;
222 LiquEx = new float[sizeof(float) * 3 * noVer];
223 int p = 0;
225 for (int j=0; j<hlq.yverts; j++)
227 for (int i=0; i<hlq.xverts; i++)
229 LiquEx[p++] = hlq.pos_x + tilesize * i;
230 LiquEx[p++] = hlq.pos_z;
231 LiquEx[p++] = ydir * (hlq.pos_y + tilesize * j);
236 f.seek((int)nextpos);
238 f.close ();
239 return true;
241 //----------------------------------------------------------------------------
242 int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, bool pPreciseVectorData)
244 if(pPreciseVectorData) {
245 fwrite(&liquflags,sizeof(uint32),1,output);
246 char GRP[] = "GRP ";
247 fwrite(GRP,1,4,output);
249 int k = 0;
250 int moba_batch = moba_size/12;
251 MobaEx = new int[moba_batch*4];
252 for(int i=8; i<moba_size; i+=12)
254 MobaEx[k++] = MOBA[i];
256 delete [] MOBA;
257 int moba_size_grp = moba_batch*4+4;
258 fwrite(&moba_size_grp,4,1,output);
259 fwrite(&moba_batch,4,1,output);
260 fwrite(MobaEx,4,k,output);
261 delete [] MobaEx;
263 uint32 nIdexes = nTriangles * 3;
265 if(fwrite("INDX",4, 1, output) != 1) { printf("Error while writing file nbraches ID"); exit(0); }
266 int wsize = sizeof(uint32) + sizeof(unsigned short) * nIdexes;
267 if(fwrite(&wsize, sizeof(int), 1, output) != 1) { printf("Error while writing file wsize"); }
268 if(fwrite(&nIdexes, sizeof(uint32), 1, output) != 1) { printf("Error while writing file nIndexes"); exit(0); }
269 if(nIdexes >0) {
270 if(fwrite(MOVI, sizeof(unsigned short), nIdexes, output) != nIdexes) { printf("Error while writing file indexarray"); exit(0); }
273 if(fwrite("VERT",4, 1, output) != 1) { printf("Error while writing file nbraches ID"); exit(0); }
274 wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
275 if(fwrite(&wsize, sizeof(int), 1, output) != 1) { printf("Error while writing file wsize"); }
276 if(fwrite(&nVertices, sizeof(int), 1, output) != 1) { printf("Error while writing file nVertices"); exit(0); }
277 if(nVertices >0) {
278 if(fwrite(MOVT, sizeof(float)*3, nVertices, output) != nVertices) { printf("Error while writing file vectors"); exit(0); }
281 if(LiquEx_size != 0)
283 int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU"
284 fwrite(LIQU_h,4,4,output);
285 fwrite(LiquEx,4,LiquEx_size/4,output);
286 delete [] LiquEx;
289 return nTriangles;
290 } else {
291 //printf("Convert GroupWmo...\n");
292 //-------GRP -------------------------------------
293 fwrite(&liquflags,sizeof(uint32),1,output);
294 char GRP[] = "GRP ";
295 fwrite(GRP,1,4,output);
296 int k = 0;
297 int moba_batch = moba_size/12;
298 MobaEx = new int[moba_batch*4];
299 for(int i=8; i<moba_size; i+=12)
301 MobaEx[k++] = MOBA[i];
303 delete [] MOBA;
304 int moba_size_grp = moba_batch*4+4;
305 fwrite(&moba_size_grp,4,1,output);
306 fwrite(&moba_batch,4,1,output);
307 fwrite(MobaEx,4,k,output);
308 delete [] MobaEx;
310 //-------INDX------------------------------------
311 //-------MOPY--------
312 int n = 0;
313 int j = 0;
314 MopyEx = new char[mopy_size];
315 IndexExTr = new int[mopy_size];
316 for (int i=0; i<mopy_size; i+=2)
318 if ((int)MOPY[i]==0x00000008 ||(int)MOPY[i]==0x00000009 ||(int)MOPY[i]==0x00000020 ||(int)MOPY[i]==0x00000021 ||(int)MOPY[i]==0x00000022 ||(int)MOPY[i]==0x00000048 ||(int)MOPY[i]==0x00000049 ||(int)MOPY[i]==0x00000060 ||(int)MOPY[i]==0x00000061 ||(int)MOPY[i]==0x00000062 ||(int)MOPY[i]==0x0000000A ||(int)MOPY[i]==0x0000004A)
320 MopyEx[n] = MOPY[i];
321 MopyEx[(n+1)] = MOPY[(i+1)];
322 IndexExTr[j] = i/2;
323 j+=1;
324 n+=2;
327 MopyEx_size = n;
328 IndexExTr_size = j;
329 delete [] MOPY;
330 delete [] MopyEx;
332 //---------MOVI-----------
333 MoviEx = new uint16[IndexExTr_size*3];
334 int m = 0;
335 for (int i=0; i<IndexExTr_size; i++)
337 int n = 0;
338 n = IndexExTr[i]*3;
339 for (int x=0; x<3; x++)
341 MoviEx[m] = MOVI[n];
342 n++;
343 m++;
346 delete [] MOVI;
348 MoviExSort = new uint16[IndexExTr_size*3];
349 for(int y=0; y<IndexExTr_size*3; y++)
351 MoviExSort[y]=MoviEx[y];
354 uint16 hold;
355 for (int pass = 1; pass < IndexExTr_size*3; pass++)
357 for (int i=0; i < IndexExTr_size*3-1; i++)
359 if (MoviExSort[i] > MoviExSort[i+1])
361 hold = MoviExSort[i];
362 MoviExSort[i] = MoviExSort[i+1];
363 MoviExSort[i+1] = hold;
365 //double = 65535
366 else
367 if (MoviExSort[i] == MoviExSort[i+1])
368 MoviExSort[i+1] = 65535;
371 // double delet
372 uint16 s = 0;
373 for (int i=0; i < IndexExTr_size*3; i++)
375 if (MoviExSort[i]!=65535)
377 MoviExSort[s] = MoviExSort[i];
378 s++;
381 MovtExSort = new uint16[s];
382 for (int i=0; i < s; i++)
384 MovtExSort[i] = MoviExSort[i];
387 for (int i=0; i < IndexExTr_size*3; i++)
389 uint16 b = MoviEx[i];
390 for (uint16 x = 0; x < s; x++)
392 if(MoviExSort[x] == b)
395 MoviEx[i] = x;
396 break;
401 int INDX[] = {0x58444E49,IndexExTr_size*6+4,IndexExTr_size*3};
402 fwrite(INDX,4,3,output);
403 fwrite(MoviEx,2,IndexExTr_size*3,output);
405 delete [] MoviEx;
406 delete [] MoviExSort;
407 delete [] IndexExTr;
409 //----------VERT---------
410 //-----MOVT----------
411 int d = 0;
412 MovtEx = new float[s*3];
413 for (uint16 i=0; i<s; i++)
415 int c=0;//!!!!data in MovtExSort[i] more uint16 in great group wmo files!!!!
416 c = MovtExSort[i]*3;
417 for (int y=0; y<3; y++)
419 MovtEx[d] = MOVT[c];
420 c++;
421 d++;
424 int VERT[] = {0x54524556,d*4+4,d*4/12};// "VERT"
425 fwrite(VERT,4,3,output);
426 fwrite(MovtEx,4,d,output);
427 //------LIQU------------------------
428 if(LiquEx_size != 0)
430 int LIQU_h[] = {0x5551494C,LiquEx_size+8,hlq_xverts,hlq_yverts};// "LIQU"
431 fwrite(LIQU_h,4,4,output);
432 fwrite(LiquEx,4,LiquEx_size/4,output);
433 delete [] LiquEx;
436 delete [] MOVT;
437 delete [] MovtEx;
438 delete [] MovtExSort;
440 //---------------------------------------------
441 return IndexExTr_size;
445 WMOGroup::~WMOGroup()
449 WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName,const char*MapName, FILE *pDirfile)
451 pos = Vec3D(0,0,0);
453 float ff[3];
454 f.read(&id, 4);
455 f.read(ff,12);
456 pos = Vec3D(ff[0],ff[1],ff[2]);
457 f.read(ff,12);
458 rot = Vec3D(ff[0],ff[1],ff[2]);
459 f.read(ff,12);
460 pos2 = Vec3D(ff[0],ff[1],ff[2]);
461 f.read(ff,12);
462 pos3 = Vec3D(ff[0],ff[1],ff[2]);
463 f.read(&d2,4);
464 f.read(&d3,4);
466 doodadset = (d2 & 0xFFFF0000) >> 16;
468 int realx1 = (int) ((float) pos2.x / 533.333333f);
469 int realy1 = (int) ((float) pos2.z / 533.333333f);
470 int realx2 = (int) ((float) pos3.x / 533.333333f);
471 int realy2 = (int) ((float) pos3.z / 533.333333f);
473 if(realx1 < 0)
475 realx1 +=20; realx2+=20;
477 if(realy1 < 0)
479 realy1 +=20; realy2+=20;
480 } // hack to prevent neg. values
482 //-----------add_in _dir_file----------------
484 char tempname[512];
485 // const char dirname[] = "buildings\\dir";
487 sprintf(tempname, "buildings\\%s", WmoInstName);
488 FILE *input;
489 input = fopen(tempname, "r+b");
490 if(!input)
492 return;
494 fseek(input, 8, SEEK_SET); // get the correct no of vertices
495 int nVertices;
496 fread(&nVertices, sizeof (int), 1, input);
497 fclose(input);
498 if(nVertices == 0)
500 return;
503 /* FILE *dirfile;
504 dirfile = fopen(dirname, "ab");
505 if(!dirfile)
507 printf("Can't open dirfile!'%s'\n");
508 return;
511 float x,z;
512 x = pos.x;
513 z = pos.z;
514 if(x==0 && z == 0)
515 { x = 533.33333f*32; z = 533.33333f*32; }
516 fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n",
517 MapName,
518 WmoInstName,
519 (float) x, (float) pos.y, (float) z,
520 (float) rot.x, (float) rot.y, (float) rot.z,
521 nVertices,
522 realx1, realy1,
523 realx2, realy2
526 // fclose(dirfile);