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"
29 extern HANDLE WorldMpq
;
31 Model::Model(std::string
& filename
) : filename(filename
), vertices(0), indices(0)
37 MPQFile
f(WorldMpq
, filename
.c_str());
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());
51 memcpy(&header
, f
.getBuffer(), sizeof(ModelHeader
));
52 if (header
.nBoundingTriangles
> 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
]);
63 f
.seekRelative(header
.ofsBoundingTriangles
);
64 indices
= new uint16
[header
.nBoundingTriangles
];
65 f
.read(indices
, header
.nBoundingTriangles
* 2);
70 //printf("not included %s\n", filename.c_str());
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");
83 printf("Can't create the output file '%s'\n", outfilename
);
86 fwrite(szRawVMAPMagic
, 8, 1, output
);
88 nVertices
= header
.nBoundingVertices
;
89 fwrite(&nVertices
, sizeof(int), 1, output
);
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
);
98 wsize
= sizeof(branches
) + sizeof(uint32
) * branches
;
99 fwrite(&wsize
, sizeof(int), 1, output
);
100 fwrite(&branches
, sizeof(branches
), 1, output
);
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
);
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
);
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
);
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
)
146 pos
= fixCoords(Vec3D(ff
[0], ff
[1], ff
[2]));
148 rot
= Vec3D(ff
[0], ff
[1], ff
[2]);
150 // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
151 sc
= scale
/ 1024.0f
;
154 sprintf(tempname
, "%s/%s", szWorkDirWmo
, ModelInstName
);
156 input
= fopen(tempname
, "r+b");
160 //printf("ModelInstance::ModelInstance couldn't open %s\n", tempname);
164 fseek(input
, 8, SEEK_SET
); // get the correct no of vertices
166 fread(&nVertices
, sizeof(int), 1, input
);
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",
197 (float) pos.x, (float) pos.y, (float) pos.z,
198 (float) rot.x, (float) rot.y, (float) rot.z,