Legends-of-Azeroth-Pandaria-5.4.8

Форк
0
269 строк · 9.2 Кб
1
/*
2
 * Copyright (C) 2011-2016 Project SkyFire <http://www.projectskyfire.org/>
3
 * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
4
 * Copyright (C) 2005-2016 MaNGOS <http://getmangos.com/>
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License as published by the
8
 * Free Software Foundation; either version 3 of the License, or (at your
9
 * option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
 * more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along
17
 * with this program. If not, see <http://www.gnu.org/licenses/>.
18
 */
19

20
#include "vmapexport.h"
21
#include "model.h"
22
#include "wmo.h"
23
#include "adtfile.h"
24
#include "mpqfile.h"
25
#include "VMapDefinitions.h"
26
#include "Errors.h"
27
#include <G3D/Quat.h>
28
#include <cassert>
29
#include <algorithm>
30
#include <cstdio>
31

32
extern HANDLE WorldMpq;
33

34
Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0)
35
{
36
    memset(&header, 0, sizeof(header));
37
}
38

39
bool Model::open()
40
{
41
    MPQFile f(WorldMpq, filename.c_str());
42

43
    if (f.isEof())
44
    {
45
        f.close();
46
        // Do not show this error on console to avoid confusion, the extractor can continue working even if some models fail to load
47
        //printf("Error loading model %s\n", filename.c_str());
48
        return false;
49
    }
50

51
    _unload();
52

53
    memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
54
    if (header.nBoundingTriangles > 0)
55
    {
56
        f.seek(0);
57
        f.seekRelative(header.ofsBoundingVertices);
58
        vertices = new Vec3D[header.nBoundingVertices];
59
        f.read(vertices,header.nBoundingVertices*12);
60
        for (uint32 i=0; i<header.nBoundingVertices; i++)
61
            vertices[i] = fixCoordSystem(vertices[i]);
62
        f.seek(0);
63
        f.seekRelative(header.ofsBoundingTriangles);
64
        indices = new uint16[header.nBoundingTriangles];
65
        f.read(indices,header.nBoundingTriangles*2);
66
        f.close();
67
    }
68
    else
69
    {
70
        //printf("not included %s\n", filename.c_str());
71
        f.close();
72
        return false;
73
    }
74
    return true;
75
}
76

77
bool Model::ConvertToVMAPModel(const char * outfilename)
78
{
79
    int N[12] = { };
80
    FILE* output = fopen(outfilename, "wb");
81
    if (!output)
82
    {
83
        printf("Can't create the output file '%s'\n", outfilename);
84
        return false;
85
    }
86
    fwrite(VMAP::RAW_VMAP_MAGIC, 8, 1, output);
87
    uint32 nVertices = header.nBoundingVertices;
88
    fwrite(&nVertices, sizeof(int), 1, output);
89
    uint32 nofgroups = 1;
90
    fwrite(&nofgroups, sizeof(uint32), 1, output);
91
    fwrite(N, 4 * 3, 1, output);// rootwmoid, flags, groupid
92
    fwrite(N, sizeof(float), 3 * 2, output);//bbox, only needed for WMO currently
93
    fwrite(N, 4, 1, output);// liquidflags
94
    fwrite("GRP ", 4, 1, output);
95
    uint32 branches = 1;
96
    int wsize;
97
    wsize = sizeof(branches) + sizeof(uint32) * branches;
98
    fwrite(&wsize, sizeof(int), 1, output);
99
    fwrite(&branches, sizeof(branches), 1, output);
100
    uint32 nIndexes = header.nBoundingTriangles;
101
    fwrite(&nIndexes, sizeof(uint32), 1, output);
102
    fwrite("INDX", 4, 1, output);
103
    wsize = sizeof(uint32) + sizeof(unsigned short) * nIndexes;
104
    fwrite(&wsize, sizeof(int), 1, output);
105
    fwrite(&nIndexes, sizeof(uint32), 1, output);
106
    if (nIndexes > 0)
107
    {
108
        for (uint32 i = 0; i < nIndexes; ++i)
109
        {
110
            if ((i % 3) - 1 == 0 && i + 1 < nIndexes)
111
            {
112
                uint16 tmp = indices[i];
113
                indices[i] = indices[i + 1];
114
                indices[i + 1] = tmp;
115
            }
116
        }
117
        fwrite(indices, sizeof(unsigned short), nIndexes, output);
118
    }
119

120
    fwrite("VERT", 4, 1, output);
121
    wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
122
    fwrite(&wsize, sizeof(int), 1, output);
123
    fwrite(&nVertices, sizeof(int), 1, output);
124
    if (nVertices > 0)
125
    {
126
        for (uint32 vpos = 0; vpos < nVertices; ++vpos)
127
        {
128
            float tmp = vertices[vpos].y;
129
            vertices[vpos].y = -vertices[vpos].z;
130
            vertices[vpos].z = tmp;
131
        }
132

133
        fwrite(vertices, sizeof(float) * 3, nVertices, output);
134
    }
135

136
    fclose(output);
137

138
    return true;
139
}
140

141
Vec3D fixCoordSystem(Vec3D const& v)
142
{
143
    return Vec3D(v.x, v.z, -v.y);
144
}
145

146
void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile)
147
{
148
    char tempname[1036];
149
    sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName);
150
    FILE* input = fopen(tempname, "r+b");
151

152
    if (!input)
153
        return;
154

155
    fseek(input, 8, SEEK_SET); // get the correct no of vertices
156
    int nVertices;
157
    int count = fread(&nVertices, sizeof(int), 1, input);
158
    fclose(input);
159

160
    if (count != 1 || nVertices == 0)
161
        return;
162

163
    // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
164
    float sc = doodadDef.Scale / 1024.0f;
165

166
    Vec3D position = fixCoords(doodadDef.Position);
167

168
    uint16 nameSet = 0;// not used for models
169
    uint32 uniqueId = GenerateUniqueObjectId(doodadDef.UniqueId, 0);
170
    uint32 tcflags = MOD_M2;
171
    if (tileX == 65 && tileY == 65)
172
        tcflags |= MOD_WORLDSPAWN;
173

174
    //write mapID, tileX, tileY, Flags, NameSet, UniqueId, Pos, Rot, Scale, name
175
    fwrite(&mapID, sizeof(uint32), 1, pDirfile);
176
    fwrite(&tileX, sizeof(uint32), 1, pDirfile);
177
    fwrite(&tileY, sizeof(uint32), 1, pDirfile);
178
    fwrite(&tcflags, sizeof(uint32), 1, pDirfile);
179
    fwrite(&nameSet, sizeof(uint16), 1, pDirfile);
180
    fwrite(&uniqueId, sizeof(uint32), 1, pDirfile);
181
    fwrite(&position, sizeof(Vec3D), 1, pDirfile);
182
    fwrite(&doodadDef.Rotation, sizeof(Vec3D), 1, pDirfile);
183
    fwrite(&sc, sizeof(float), 1, pDirfile);
184
    uint32 nlen = strlen(ModelInstName);
185
    fwrite(&nlen, sizeof(uint32), 1, pDirfile);
186
    fwrite(ModelInstName, sizeof(char), nlen, pDirfile);
187
}
188

189
void Doodad::ExtractSet(WMODoodadData const& doodadData, ADT::MODF const& wmo, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile)
190
{
191
    if (wmo.DoodadSet >= doodadData.Sets.size())
192
        return;
193

194
    G3D::Vector3 wmoPosition(wmo.Position.z, wmo.Position.x, wmo.Position.y);
195
    G3D::Matrix3 wmoRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::toRadians(wmo.Rotation.y), G3D::toRadians(wmo.Rotation.x), G3D::toRadians(wmo.Rotation.z));
196

197
    uint16 doodadId = 0;
198
    WMO::MODS const& doodadSetData = doodadData.Sets[wmo.DoodadSet];
199
    for (uint16 doodadIndex : doodadData.References)
200
    {
201
        if (doodadIndex < doodadSetData.StartIndex ||
202
            doodadIndex >= doodadSetData.StartIndex + doodadSetData.Count)
203
            continue;
204

205
        WMO::MODD const& doodad = doodadData.Spawns[doodadIndex];
206

207
        char ModelInstName[1024];
208
        sprintf(ModelInstName, "%s", GetPlainName(&doodadData.Paths[doodad.NameIndex]));
209
        uint32 nlen = strlen(ModelInstName);
210
        fixnamen(ModelInstName, nlen);
211
        fixname2(ModelInstName, nlen);
212
        if (nlen > 3)
213
        {
214
            char const* extension = &ModelInstName[nlen - 4];
215
            if (!strcmp(extension, ".mdx") || !strcmp(extension, ".mdl"))
216
            {
217
                ModelInstName[nlen - 2] = '2';
218
                ModelInstName[nlen - 1] = '\0';
219
            }
220
        }
221

222
        char tempname[1036];
223
        sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName);
224
        FILE* input = fopen(tempname, "r+b");
225
        if (!input)
226
            continue;
227

228
        fseek(input, 8, SEEK_SET); // get the correct no of vertices
229
        int nVertices;
230
        int count = fread(&nVertices, sizeof(int), 1, input);
231
        fclose(input);
232

233
        if (count != 1 || nVertices == 0)
234
            continue;
235

236
        ASSERT(doodadId < std::numeric_limits<uint16>::max());
237
        ++doodadId;
238

239
        G3D::Vector3 position = wmoPosition + (wmoRotation * G3D::Vector3(doodad.Position.x, doodad.Position.y, doodad.Position.z));
240

241
        Vec3D rotation;
242
        (G3D::Quat(doodad.Rotation.X, doodad.Rotation.Y, doodad.Rotation.Z, doodad.Rotation.W)
243
            .toRotationMatrix() * wmoRotation)
244
            .toEulerAnglesXYZ(rotation.z, rotation.x, rotation.y);
245

246
        rotation.z = G3D::toDegrees(rotation.z);
247
        rotation.x = G3D::toDegrees(rotation.x);
248
        rotation.y = G3D::toDegrees(rotation.y);
249

250
        uint16 nameSet = 0;     // not used for models
251
        uint32 uniqueId = GenerateUniqueObjectId(wmo.UniqueId, doodadId);
252
        uint32 tcflags = MOD_M2;
253
        if (tileX == 65 && tileY == 65)
254
            tcflags |= MOD_WORLDSPAWN;
255

256
        //write mapID, tileX, tileY, Flags, NameSet, UniqueId, Pos, Rot, Scale, name
257
        fwrite(&mapID, sizeof(uint32), 1, pDirfile);
258
        fwrite(&tileX, sizeof(uint32), 1, pDirfile);
259
        fwrite(&tileY, sizeof(uint32), 1, pDirfile);
260
        fwrite(&tcflags, sizeof(uint32), 1, pDirfile);
261
        fwrite(&nameSet, sizeof(uint16), 1, pDirfile);
262
        fwrite(&uniqueId, sizeof(uint32), 1, pDirfile);
263
        fwrite(&position, sizeof(Vec3D), 1, pDirfile);
264
        fwrite(&rotation, sizeof(Vec3D), 1, pDirfile);
265
        fwrite(&doodad.Scale, sizeof(float), 1, pDirfile);
266
        fwrite(&nlen, sizeof(uint32), 1, pDirfile);
267
        fwrite(ModelInstName, sizeof(char), nlen, pDirfile);
268
    }
269
}
270

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.