20 #include "format/md2.h"
21 #include "format/md3.h"
22 #include "format/sp2.h"
24 #if MAX_ALIAS_VERTS > TESS_MAX_VERTICES
25 #error TESS_MAX_VERTICES
28 #if MD2_MAX_TRIANGLES > TESS_MAX_INDICES / 3
29 #error TESS_MAX_INDICES
35 dmd2frame_t *src_frame;
36 dmd2trivertx_t *src_vert;
37 dmd2triangle_t *src_tri;
49 int numverts, numindices;
50 char skinname[MAX_QPATH];
51 vec_t scale_s, scale_t;
55 if (length <
sizeof(header)) {
56 return Q_ERR_FILE_TOO_SMALL;
60 header = *(dmd2header_t *)rawdata;
61 for (i = 0; i <
sizeof(header) / 4; i++) {
62 ((uint32_t *)&header)[i] = LittleLong(((uint32_t *)&header)[i]);
68 if (ret == Q_ERR_TOO_FEW) {
70 model->type = MOD_EMPTY;
78 src_tri = (dmd2triangle_t *)((
byte *)rawdata + header.ofs_tris);
79 for (i = 0; i < header.num_tris; i++) {
80 for (j = 0; j < 3; j++) {
81 uint16_t idx_xyz = LittleShort(src_tri->index_xyz[j]);
82 uint16_t idx_st = LittleShort(src_tri->index_st[j]);
85 if (idx_xyz >= header.num_xyz || idx_st >= header.num_st) {
89 vertIndices[numindices + j] = idx_xyz;
90 tcIndices[numindices + j] = idx_st;
100 return Q_ERR_TOO_FEW;
103 for (i = 0; i < numindices; i++) {
109 src_tc = (dmd2stvert_t *)((
byte *)rawdata + header.ofs_st);
110 for (i = 0; i < numindices; i++) {
111 if (remap[i] != 0xFFFF) {
115 for (j = i + 1; j < numindices; j++) {
116 if (vertIndices[i] == vertIndices[j] &&
117 (src_tc[tcIndices[i]].s == src_tc[tcIndices[j]].s &&
118 src_tc[tcIndices[i]].t == src_tc[tcIndices[j]].t)) {
121 finalIndices[j] = numverts;
127 finalIndices[i] = numverts++;
131 return Q_ERR_TOO_MANY;
135 model->type = MOD_ALIAS;
136 model->nummeshes = 1;
137 model->numframes = header.num_frames;
139 model->frames = MOD_Malloc(header.num_frames *
sizeof(
maliasframe_t));
141 dst_mesh = model->meshes;
142 dst_mesh->
numtris = numindices / 3;
145 dst_mesh->
numskins = header.num_skins;
146 dst_mesh->
verts = MOD_Malloc(numverts * header.num_frames *
sizeof(
maliasvert_t));
150 if (dst_mesh->
numtris != header.num_tris) {
151 Com_DPrintf(
"%s has %d bad triangles\n", model->name, header.num_tris - dst_mesh->
numtris);
155 for (i = 0; i < numindices; i++) {
156 dst_mesh->
indices[i] = finalIndices[i];
160 src_skin = (
char *)rawdata + header.ofs_skins;
161 for (i = 0; i < header.num_skins; i++) {
162 if (!
Q_memccpy(skinname, src_skin, 0,
sizeof(skinname))) {
163 ret = Q_ERR_STRING_TRUNCATED;
168 src_skin += MD2_MAX_SKINNAME;
172 src_tc = (dmd2stvert_t *)((
byte *)rawdata + header.ofs_st);
174 scale_s = 1.0f / header.skinwidth;
175 scale_t = 1.0f / header.skinheight;
176 for (i = 0; i < numindices; i++) {
180 dst_tc[finalIndices[i]].
st[0] =
181 (int16_t)LittleShort(src_tc[tcIndices[i]].s) * scale_s;
182 dst_tc[finalIndices[i]].
st[1] =
183 (int16_t)LittleShort(src_tc[tcIndices[i]].t) * scale_t;
187 src_frame = (dmd2frame_t *)((
byte *)rawdata + header.ofs_frames);
188 dst_frame = model->frames;
189 for (j = 0; j < header.num_frames; j++) {
190 LittleVector(src_frame->scale, dst_frame->
scale);
191 LittleVector(src_frame->translate, dst_frame->
translate);
195 for (i = 0; i < numindices; i++) {
199 src_vert = &src_frame->verts[vertIndices[i]];
200 dst_vert = &dst_mesh->
verts[j * numverts + finalIndices[i]];
202 dst_vert->
pos[0] = src_vert->v[0];
203 dst_vert->
pos[1] = src_vert->v[1];
204 dst_vert->
pos[2] = src_vert->v[2];
206 val = src_vert->lightnormalindex;
207 if (val >= NUMVERTEXNORMALS) {
208 dst_vert->
norm[0] = 0;
209 dst_vert->
norm[1] = 0;
215 for (k = 0; k < 3; k++) {
216 val = dst_vert->
pos[k];
224 VectorVectorScale(mins, dst_frame->
scale, mins);
225 VectorVectorScale(maxs, dst_frame->
scale, maxs);
232 src_frame = (dmd2frame_t *)((
byte *)src_frame + header.framesize);
237 return Q_ERR_SUCCESS;
245 static qerror_t MOD_LoadMD3Mesh(model_t *model,
maliasmesh_t *mesh,
246 const byte *rawdata,
size_t length,
size_t *offset_p)
250 dmd3vertex_t *src_vert;
252 dmd3skin_t *src_skin;
258 char skinname[MAX_QPATH];
261 if (length <
sizeof(header))
262 return Q_ERR_BAD_EXTENT;
265 header = *(dmd3mesh_t *)rawdata;
266 for (i = 0; i <
sizeof(header) / 4; i++)
267 ((uint32_t *)&header)[i] = LittleLong(((uint32_t *)&header)[i]);
269 if (header.meshsize <
sizeof(header) || header.meshsize > length)
270 return Q_ERR_BAD_EXTENT;
271 if (header.num_verts < 3)
272 return Q_ERR_TOO_FEW;
274 return Q_ERR_TOO_MANY;
275 if (header.num_tris < 1)
276 return Q_ERR_TOO_FEW;
278 return Q_ERR_TOO_MANY;
279 if (header.num_skins > MAX_ALIAS_SKINS)
280 return Q_ERR_TOO_MANY;
281 end = header.ofs_skins + header.num_skins *
sizeof(dmd3skin_t);
282 if (end < header.ofs_skins || end > length)
283 return Q_ERR_BAD_EXTENT;
284 end = header.ofs_verts + header.num_verts * model->numframes *
sizeof(dmd3vertex_t);
285 if (end < header.ofs_verts || end > length)
286 return Q_ERR_BAD_EXTENT;
287 end = header.ofs_tcs + header.num_verts *
sizeof(dmd3coord_t);
288 if (end < header.ofs_tcs || end > length)
289 return Q_ERR_BAD_EXTENT;
290 end = header.ofs_indexes + header.num_tris * 3 *
sizeof(uint32_t);
291 if (end < header.ofs_indexes || end > length)
292 return Q_ERR_BAD_EXTENT;
294 mesh->
numtris = header.num_tris;
298 mesh->
verts = MOD_Malloc(
sizeof(
maliasvert_t) * header.num_verts * model->numframes);
303 src_skin = (dmd3skin_t *)(rawdata + header.ofs_skins);
304 for (i = 0; i < header.num_skins; i++) {
305 if (!
Q_memccpy(skinname, src_skin->name, 0,
sizeof(skinname)))
306 return Q_ERR_STRING_TRUNCATED;
312 src_vert = (dmd3vertex_t *)(rawdata + header.ofs_verts);
313 dst_vert = mesh->
verts;
314 for (i = 0; i < header.num_verts * model->numframes; i++) {
315 dst_vert->
pos[0] = (int16_t)LittleShort(src_vert->point[0]);
316 dst_vert->
pos[1] = (int16_t)LittleShort(src_vert->point[1]);
317 dst_vert->
pos[2] = (int16_t)LittleShort(src_vert->point[2]);
319 dst_vert->
norm[0] = src_vert->norm[0];
320 dst_vert->
norm[1] = src_vert->norm[1];
322 src_vert++; dst_vert++;
326 src_tc = (dmd3coord_t *)(rawdata + header.ofs_tcs);
328 for (i = 0; i < header.num_verts; i++) {
329 dst_tc->
st[0] = LittleFloat(src_tc->st[0]);
330 dst_tc->
st[1] = LittleFloat(src_tc->st[1]);
335 src_idx = (uint32_t *)(rawdata + header.ofs_indexes);
337 for (i = 0; i < header.num_tris * 3; i++) {
338 index = LittleLong(*src_idx++);
339 if (index >= header.num_verts)
340 return Q_ERR_BAD_INDEX;
344 *offset_p = header.meshsize;
345 return Q_ERR_SUCCESS;
348 qerror_t
MOD_LoadMD3_GL(model_t *model,
const void *rawdata,
size_t length)
351 size_t end, offset, remaining;
352 dmd3frame_t *src_frame;
354 const byte *src_mesh;
358 if (length <
sizeof(header))
359 return Q_ERR_FILE_TOO_SMALL;
362 header = *(dmd3header_t *)rawdata;
363 for (i = 0; i <
sizeof(header) / 4; i++)
364 ((uint32_t *)&header)[i] = LittleLong(((uint32_t *)&header)[i]);
366 if (header.ident != MD3_IDENT)
367 return Q_ERR_UNKNOWN_FORMAT;
368 if (header.version != MD3_VERSION)
369 return Q_ERR_UNKNOWN_FORMAT;
370 if (header.num_frames < 1)
371 return Q_ERR_TOO_FEW;
372 if (header.num_frames > MD3_MAX_FRAMES)
373 return Q_ERR_TOO_MANY;
374 end = header.ofs_frames +
sizeof(dmd3frame_t) * header.num_frames;
375 if (end < header.ofs_frames || end > length)
376 return Q_ERR_BAD_EXTENT;
377 if (header.num_meshes < 1)
378 return Q_ERR_TOO_FEW;
379 if (header.num_meshes > MD3_MAX_MESHES)
380 return Q_ERR_TOO_MANY;
381 if (header.ofs_meshes > length)
382 return Q_ERR_BAD_EXTENT;
385 model->type = MOD_ALIAS;
386 model->numframes = header.num_frames;
387 model->nummeshes = header.num_meshes;
388 model->meshes = MOD_Malloc(
sizeof(
maliasmesh_t) * header.num_meshes);
389 model->frames = MOD_Malloc(
sizeof(
maliasframe_t) * header.num_frames);
392 src_frame = (dmd3frame_t *)((
byte *)rawdata + header.ofs_frames);
393 dst_frame = model->frames;
394 for (i = 0; i < header.num_frames; i++) {
395 LittleVector(src_frame->translate, dst_frame->
translate);
396 VectorSet(dst_frame->
scale, MD3_XYZ_SCALE, MD3_XYZ_SCALE, MD3_XYZ_SCALE);
398 LittleVector(src_frame->mins, dst_frame->
bounds[0]);
399 LittleVector(src_frame->maxs, dst_frame->
bounds[1]);
400 dst_frame->
radius = LittleFloat(src_frame->radius);
402 src_frame++; dst_frame++;
406 src_mesh = (
const byte *)rawdata + header.ofs_meshes;
407 remaining = length - header.ofs_meshes;
408 for (i = 0; i < header.num_meshes; i++) {
409 ret = MOD_LoadMD3Mesh(model, &model->meshes[i], src_mesh, remaining, &offset);
417 return Q_ERR_SUCCESS;
430 switch (model->type) {
432 for (i = 0; i < model->nummeshes; i++) {
434 for (j = 0; j < mesh->
numskins; j++) {
440 for (i = 0; i < model->numframes; i++) {
447 Com_Error(ERR_FATAL,
"%s: bad model type", __func__);