9 Model::Model(std::string
&filename
) : filename(filename
)
15 MPQFile
f(filename
.c_str());
22 printf("Error loading model %s\n", filename
.c_str());
26 memcpy(&header
, f
.getBuffer(), sizeof(ModelHeader
));
27 if(header
.nBoundingTriangles
> 0) {
29 animated
= isAnimated(f
);
38 origVertices
= (ModelVertex
*)(f
.getBuffer() + header
.ofsVertices
);
40 vertices
= new Vec3D
[header
.nVertices
];
41 normals
= new Vec3D
[header
.nVertices
];
43 for (size_t i
=0; i
<header
.nVertices
; i
++)
45 origVertices
[i
].pos
= fixCoordSystem(origVertices
[i
].pos
);
46 origVertices
[i
].normal
= fixCoordSystem(origVertices
[i
].normal
);
47 vertices
[i
] = origVertices
[i
].pos
;
48 normals
[i
] = origVertices
[i
].normal
.normalize();
51 ModelView
*view
= (ModelView
*)(f
.getBuffer() + header
.ofsViews
);
53 uint16
*indexLookup
= (uint16
*)(f
.getBuffer() + view
->ofsIndex
);
54 uint16
*triangles
= (uint16
*)(f
.getBuffer() + view
->ofsTris
);
56 nIndices
= view
->nTris
;
57 indices
= new uint16
[nIndices
];
58 for (size_t i
= 0; i
<nIndices
; i
++)
60 indices
[i
] = indexLookup
[triangles
[i
]];
64 //printf("not included %s\n", filename.c_str());
71 bool Model::isAnimated(MPQFile
&f
)
73 // see if we have any animated bones
74 ModelBoneDef
*bo
= (ModelBoneDef
*)(f
.getBuffer() + header
.ofsBones
);
80 ModelVertex
*verts
= (ModelVertex
*)(f
.getBuffer() + header
.ofsVertices
);
81 for (size_t i
=0; i
<header
.nVertices
&& !animGeometry
; i
++) {
82 for (size_t b
=0; b
<4; b
++) {
83 if (verts
[i
].weights
[b
]>0) {
84 ModelBoneDef
&bb
= bo
[verts
[i
].bones
[b
]];
85 if (bb
.translation
.type
|| bb
.rotation
.type
|| bb
.scaling
.type
|| (bb
.flags
&8)) {
87 // if we have billboarding, the model will need per-instance animation
97 if (animGeometry
) animBones
= true;
99 for (size_t i
=0; i
<header
.nBones
; i
++) {
100 ModelBoneDef
&bb
= bo
[i
];
101 if (bb
.translation
.type
|| bb
.rotation
.type
|| bb
.scaling
.type
) {
108 animTextures
= header
.nTexAnims
> 0;
110 bool animMisc
= header
.nCameras
>0 || // why waste time, pretty much all models with cameras need animation
111 header
.nLights
>0 || // same here
112 header
.nParticleEmitters
>0 ||
113 header
.nRibbonEmitters
>0;
115 if (animMisc
) animBones
= true;
118 if (header
.nColors
) {
119 ModelColorDef
*cols
= (ModelColorDef
*)(f
.getBuffer() + header
.ofsColors
);
120 for (size_t i
=0; i
<header
.nColors
; i
++) {
121 if (cols
[i
].color
.type
!=0 || cols
[i
].opacity
.type
!=0) {
129 if (header
.nTransparency
&& !animMisc
) {
130 ModelTransDef
*trs
= (ModelTransDef
*)(f
.getBuffer() + header
.ofsTransparency
);
131 for (size_t i
=0; i
<header
.nTransparency
; i
++) {
132 if (trs
[i
].trans
.type
!=0) {
140 return animGeometry
|| animTextures
|| animMisc
;
143 bool Model::ConvertToVMAPModel(char * outfilename
)
146 int N
[] = {0x00000000};
147 FILE * output
=fopen(outfilename
,"wb");
150 printf("Can't create the output file '%s'\n",outfilename
);
153 fwrite("VMAP002",8,1,output
);
154 int nVertices
= header
.nVertices
;
155 fwrite(&nVertices
, sizeof(int), 1, output
);
156 uint32 nofgroups
= 1;
157 fwrite(&nofgroups
,sizeof(uint32
), 1, output
);
158 fwrite(N
,4,1,output
);
159 fwrite("GRP ",4,1,output
);
162 wsize
= sizeof(branches
) + sizeof(uint32
) * branches
;
163 fwrite(&wsize
, sizeof(int), 1, output
);
164 fwrite(&branches
,sizeof(branches
), 1, output
);
165 uint32 nIdexes
= (uint32
) nIndices
;
166 fwrite(&nIndices
,sizeof(uint32
), 1, output
);
167 fwrite("INDX",4, 1, output
);
168 wsize
= sizeof(uint32
) + sizeof(unsigned short) * nIdexes
;
169 fwrite(&wsize
, sizeof(int), 1, output
);
170 fwrite(&nIdexes
, sizeof(uint32
), 1, output
);
173 fwrite(indices
, sizeof(unsigned short), nIdexes
, output
);
175 fwrite("VERT",4, 1, output
);
176 wsize
= sizeof(int) + sizeof(float) * 3 * nVertices
;
177 fwrite(&wsize
, sizeof(int), 1, output
);
178 fwrite(&nVertices
, sizeof(int), 1, output
);
181 for(int vpos
=0; vpos
<nVertices
; ++vpos
)
183 float sy
= vertices
[vpos
].y
;
184 vertices
[vpos
].y
= vertices
[vpos
].z
;
185 vertices
[vpos
].z
= sy
;
187 fwrite(vertices
, sizeof(float)*3, nVertices
, output
);
203 Vec3D
fixCoordSystem(Vec3D v
)
205 return Vec3D(v
.x
, v
.z
, -v
.y
);
208 Vec3D
fixCoordSystem2(Vec3D v
)
210 return Vec3D(v
.x
, v
.z
, v
.y
);
213 ModelInstance::ModelInstance(MPQFile
&f
,const char* ModelInstName
,const char*MapName
, FILE *pDirfile
)
218 pos
= Vec3D(ff
[0],ff
[1],ff
[2]);
220 rot
= Vec3D(ff
[0],ff
[1],ff
[2]);
222 // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
223 sc
= scale
/ 1024.0f
;
226 sprintf(tempname
, ".\\buildings\\%s", ModelInstName
);
228 input
= fopen(tempname
, "r+b");
233 fseek(input
, 8, SEEK_SET
); // get the correct no of vertices
235 fread(&nVertices
, sizeof (int), 1, input
);
244 int realx1
= (int) ((float) pos
.x
/ 533.333333f
);
245 int realy1
= (int) ((float) pos
.z
/ 533.333333f
);
246 int realx2
= (int) ((float) pos
.x
/ 533.333333f
);
247 int realy2
= (int) ((float) pos
.z
/ 533.333333f
);
250 fprintf(pDirfile
,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n",
253 (float) pos
.x
, (float) pos
.y
, (float) pos
.z
,
254 (float) rot
.x
, (float) rot
.y
, (float) rot
.z
,