Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
model.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "vmapexport.h"
7#include "model.h"
8#include "wmo.h"
9#include "mpqfile.h"
10#include <cassert>
11#include <algorithm>
12#include <cstdio>
13
14extern HANDLE WorldMpq;
15
17{
18 memset(&header, 0, sizeof(header));
19}
20
22{
23 MPQFile f(WorldMpq, filename.c_str());
24
25 if (f.isEof())
26 {
27 f.close();
28 // Do not show this error on console to avoid confusion, the extractor can continue working even if some models fail to load
29 //printf("Error loading model %s\n", filename.c_str());
30 return false;
31 }
32
33 _unload();
34
35 memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
36 if (header.nBoundingTriangles > 0)
37 {
38 f.seek(0);
39 f.seekRelative(header.ofsBoundingVertices);
40 vertices = new Vec3D[header.nBoundingVertices];
41 f.read(vertices,header.nBoundingVertices*12);
42 for (uint32 i=0; i<header.nBoundingVertices; i++)
44 f.seek(0);
45 f.seekRelative(header.ofsBoundingTriangles);
46 indices = new uint16[header.nBoundingTriangles];
47 f.read(indices,header.nBoundingTriangles*2);
48 f.close();
49 }
50 else
51 {
52 //printf("not included %s\n", filename.c_str());
53 f.close();
54 return false;
55 }
56 return true;
57}
58
59bool Model::ConvertToVMAPModel(const char * outfilename)
60{
61 int N[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
62 FILE* output=fopen(outfilename, "wb");
63 if (!output)
64 {
65 printf("Can't create the output file '%s'\n",outfilename);
66 return false;
67 }
68 fwrite(szRawVMAPMagic, 8, 1, output);
69 uint32 nVertices = header.nBoundingVertices;
70 fwrite(&nVertices, sizeof(int), 1, output);
71 uint32 nofgroups = 1;
72 fwrite(&nofgroups,sizeof(uint32), 1, output);
73 fwrite(N,4*3,1,output);// rootwmoid, flags, groupid
74 fwrite(N,sizeof(float),3*2,output);//bbox, only needed for WMO currently
75 fwrite(N,4,1,output);// liquidflags
76 fwrite("GRP ",4,1,output);
77 uint32 branches = 1;
78 int wsize;
79 wsize = sizeof(branches) + sizeof(uint32) * branches;
80 fwrite(&wsize, sizeof(int), 1, output);
81 fwrite(&branches,sizeof(branches), 1, output);
82 uint32 nIndexes = header.nBoundingTriangles;
83 fwrite(&nIndexes,sizeof(uint32), 1, output);
84 fwrite("INDX",4, 1, output);
85 wsize = sizeof(uint32) + sizeof(unsigned short) * nIndexes;
86 fwrite(&wsize, sizeof(int), 1, output);
87 fwrite(&nIndexes, sizeof(uint32), 1, output);
88 if (nIndexes > 0)
89 {
90 for (uint32 i = 0; i < nIndexes; ++i)
91 {
92 if ((i % 3) - 1 == 0 && i + 1 < nIndexes)
93 {
94 uint16 tmp = indices[i];
95 indices[i] = indices[i + 1];
96 indices[i + 1] = tmp;
97 }
98 }
99 fwrite(indices, sizeof(unsigned short), nIndexes, output);
100 }
101
102 fwrite("VERT", 4, 1, output);
103 wsize = sizeof(int) + sizeof(float) * 3 * nVertices;
104 fwrite(&wsize, sizeof(int), 1, output);
105 fwrite(&nVertices, sizeof(int), 1, output);
106 if (nVertices >0)
107 {
108 for (uint32 vpos = 0; vpos < nVertices; ++vpos)
109 {
110 float tmp = vertices[vpos].y;
111 vertices[vpos].y = -vertices[vpos].z;
112 vertices[vpos].z = tmp;
113 }
114
115 fwrite(vertices, sizeof(float)*3, nVertices, output);
116 }
117
118 fclose(output);
119
120 return true;
121}
122
123
125{
126 return Vec3D(v.x, v.z, -v.y);
127}
128
130{
131 return Vec3D(v.x, v.z, v.y);
132}
133
134ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile) : id(0), scale(0), flags(0)
135{
136 float ff[3];
137 f.read(&id, 4);
138 f.read(ff, 12);
139 pos = fixCoords(Vec3D(ff[0], ff[1], ff[2]));
140 f.read(ff, 12);
141 rot = Vec3D(ff[0], ff[1], ff[2]);
142 f.read(&scale, 2);
143 f.read(&flags, 2);
144 // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
145 sc = scale / 1024.0f;
146
147 char tempname[512];
148 snprintf(tempname, sizeof(tempname), "%s/%s", szWorkDirWmo, ModelInstName);
149 FILE* input = fopen(tempname, "r+b");
150
151 if (!input)
152 {
153 //printf("ModelInstance::ModelInstance couldn't open %s\n", tempname);
154 return;
155 }
156
157 fseek(input, 8, SEEK_SET); // get the correct no of vertices
158 int nVertices;
159 int count = fread(&nVertices, sizeof (int), 1, input);
160 fclose(input);
161
162 if (count != 1 || nVertices == 0)
163 return;
164
165 uint16 adtId = 0;// not used for models
167 if (tileX == 65 && tileY == 65)
169
170 //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, name
171 fwrite(&mapID, sizeof(uint32), 1, pDirfile);
172 fwrite(&tileX, sizeof(uint32), 1, pDirfile);
173 fwrite(&tileY, sizeof(uint32), 1, pDirfile);
174 fwrite(&flags, sizeof(uint32), 1, pDirfile);
175 fwrite(&adtId, sizeof(uint16), 1, pDirfile);
176 fwrite(&id, sizeof(uint32), 1, pDirfile);
177 fwrite(&pos, sizeof(float), 3, pDirfile);
178 fwrite(&rot, sizeof(float), 3, pDirfile);
179 fwrite(&sc, sizeof(float), 1, pDirfile);
180 uint32 nlen=strlen(ModelInstName);
181 fwrite(&nlen, sizeof(uint32), 1, pDirfile);
182 fwrite(ModelInstName, sizeof(char), nlen, pDirfile);
183
184 /* int realx1 = (int) ((float) pos.x / 533.333333f);
185 int realy1 = (int) ((float) pos.z / 533.333333f);
186 int realx2 = (int) ((float) pos.x / 533.333333f);
187 int realy2 = (int) ((float) pos.z / 533.333333f);
188
189 fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n",
190 MapName,
191 ModelInstName,
192 (float) pos.x, (float) pos.y, (float) pos.z,
193 (float) rot.x, (float) rot.y, (float) rot.z,
194 sc,
195 nVertices,
196 realx1, realy1,
197 realx2, realy2
198 ); */
199}
std::uint32_t uint32
Definition Define.h:77
std::uint16_t uint16
Definition Define.h:78
HANDLE WorldMpq
Definition System.cpp:49
size_t read(void *dest, size_t bytes)
Definition mpqfile.cpp:58
bool isEof()
Definition mpqfile.h:69
void close()
Definition mpqfile.cpp:87
void seek(int offset)
Definition mpqfile.cpp:75
void seekRelative(int offset)
Definition mpqfile.cpp:81
char * getBuffer()
Definition mpqfile.h:67
Vec3D * vertices
Definition model.h:30
ModelHeader header
Definition model.h:29
uint16 * indices
Definition model.h:31
std::string filename
Definition model.h:27
bool open()
Definition model.cpp:21
void _unload()
Definition model.h:20
Model(std::string &filename)
Definition model.cpp:16
bool ConvertToVMAPModel(char const *outfilename)
Definition model.cpp:59
uint16 flags
Definition model.h:45
uint16 scale
Definition model.h:45
Vec3D rot
Definition model.h:44
Vec3D pos
Definition model.h:44
float sc
Definition model.h:46
uint32 id
Definition model.h:43
ModelInstance()
Definition model.h:48
Definition vec3d.h:13
float x
Definition vec3d.h:15
float y
Definition vec3d.h:15
float z
Definition vec3d.h:15
Vec3D fixCoordSystem2(Vec3D v)
Definition model.cpp:129
Vec3D fixCoordSystem(Vec3D v)
Definition model.cpp:124
Vec3D fixCoordSystem(Vec3D v)
Definition model.cpp:124
const char * szWorkDirWmo
const char * szRawVMAPMagic
@ MOD_M2
Definition vmapexport.h:13
@ MOD_WORLDSPAWN
Definition vmapexport.h:14
static Vec3D fixCoords(const Vec3D &v)
Definition wmo.h:30