189 dmd2frame_t *src_frame;
190 dmd2trivertx_t *src_vert;
191 dmd2triangle_t *src_tri;
192 dmd2stvert_t *src_tc;
201 int numverts, numindices;
202 char skinname[MAX_QPATH];
203 vec_t scale_s, scale_t;
207 if (length <
sizeof(header)) {
208 return Q_ERR_FILE_TOO_SMALL;
212 header = *(dmd2header_t *)rawdata;
213 for (
int i = 0; i <
sizeof(header) / 4; i++) {
214 ((uint32_t *)&header)[i] = LittleLong(((uint32_t *)&header)[i]);
220 if (ret == Q_ERR_TOO_FEW) {
222 model->type = MOD_EMPTY;
223 return Q_ERR_SUCCESS;
230 src_tri = (dmd2triangle_t *)((
byte *)rawdata + header.ofs_tris);
231 for (
int i = 0; i < header.num_tris; i++) {
233 for (
int j = 0; j < 3; j++) {
234 uint16_t idx_xyz = LittleShort(src_tri->index_xyz[j]);
235 uint16_t idx_st = LittleShort(src_tri->index_st[j]);
238 if (idx_xyz >= header.num_xyz || idx_st >= header.num_st) {
243 vertIndices[numindices + j] = idx_xyz;
244 tcIndices[numindices + j] = idx_st;
253 if (numindices < 3) {
254 return Q_ERR_TOO_FEW;
257 qboolean all_normals_same = qtrue;
258 int same_normal = -1;
260 src_frame = (dmd2frame_t *)((
byte *)rawdata + header.ofs_frames);
261 for (
int i = 0; i < numindices; i++)
263 int v = vertIndices[i];
264 int normal = src_frame->verts[v].lightnormalindex;
269 same_normal = normal;
270 else if (normal != same_normal)
271 all_normals_same = qfalse;
274 for (
int i = 0; i < numindices; i++) {
280 src_tc = (dmd2stvert_t *)((
byte *)rawdata + header.ofs_st);
281 for (
int i = 0; i < numindices; i++) {
282 if (remap[i] != 0xFFFF) {
287 if (!all_normals_same)
289 for (
int j = i + 1; j < numindices; j++) {
290 if (vertIndices[i] == vertIndices[j] &&
291 (src_tc[tcIndices[i]].s == src_tc[tcIndices[j]].s &&
292 src_tc[tcIndices[i]].t == src_tc[tcIndices[j]].t)) {
295 finalIndices[j] = numverts;
302 finalIndices[i] = numverts++;
306 model->type = MOD_ALIAS;
307 model->nummeshes = 1;
308 model->numframes = header.num_frames;
310 model->frames = MOD_Malloc(header.num_frames *
sizeof(
maliasframe_t));
312 dst_mesh = model->meshes;
313 dst_mesh->
numtris = numindices / 3;
316 dst_mesh->
numskins = header.num_skins;
317 dst_mesh->
positions = MOD_Malloc(numverts * header.num_frames *
sizeof(vec3_t));
318 dst_mesh->
normals = MOD_Malloc(numverts * header.num_frames *
sizeof(vec3_t));
319 dst_mesh->
tex_coords = MOD_Malloc(numverts * header.num_frames *
sizeof(vec2_t));
320 dst_mesh->
tangents = MOD_Malloc(numverts * header.num_frames *
sizeof(vec4_t));
321 dst_mesh->
indices = MOD_Malloc(numindices *
sizeof(
int));
323 if (dst_mesh->
numtris != header.num_tris) {
324 Com_DPrintf(
"%s has %d bad triangles\n", model->name, header.num_tris - dst_mesh->
numtris);
328 for (
int i = 0; i < numindices; i++) {
329 dst_mesh->
indices[i] = finalIndices[i];
333 src_skin = (
char *)rawdata + header.ofs_skins;
334 for (
int i = 0; i < header.num_skins; i++) {
335 if (!
Q_memccpy(skinname, src_skin, 0,
sizeof(skinname))) {
336 ret = Q_ERR_STRING_TRUNCATED;
343 Com_EPrintf(
"error finding material '%s'\n", skinname);
347 image_t* image_emissive = NULL;
349 if (image_diffuse != R_NOTEXTURE)
352 if (!
Q_strlcpy(skinname, src_skin, strlen(src_skin) - 3))
353 return Q_ERR_STRING_TRUNCATED;
355 Q_concat(skinname,
sizeof(skinname), skinname,
"_n.tga", NULL);
357 image_normals =
IMG_Find(skinname, IT_SKIN, IF_NONE);
358 if (image_normals == R_NOTEXTURE) image_normals = NULL;
361 if (!
Q_strlcpy(skinname, src_skin, strlen(src_skin) - 3))
362 return Q_ERR_STRING_TRUNCATED;
364 Q_concat(skinname,
sizeof(skinname), skinname,
"_light.tga", NULL);
366 image_emissive =
IMG_Find(skinname, IT_SKIN, IF_SRGB);
367 if (image_emissive == R_NOTEXTURE) image_emissive = NULL;
374 src_skin += MD2_MAX_SKINNAME;
378 src_tc = (dmd2stvert_t *)((
byte *)rawdata + header.ofs_st);
379 scale_s = 1.0f / header.skinwidth;
380 scale_t = 1.0f / header.skinheight;
383 src_frame = (dmd2frame_t *)((
byte *)rawdata + header.ofs_frames);
384 dst_frame = model->frames;
385 for (
int j = 0; j < header.num_frames; j++) {
386 LittleVector(src_frame->scale, dst_frame->
scale);
387 LittleVector(src_frame->translate, dst_frame->
translate);
392 for (
int i = 0; i < numindices; i++) {
396 src_vert = &src_frame->verts[vertIndices[i]];
397 vec3_t *dst_pos = &dst_mesh->
positions [j * numverts + finalIndices[i]];
398 vec3_t *dst_nrm = &dst_mesh->
normals [j * numverts + finalIndices[i]];
399 vec2_t *dst_tc = &dst_mesh->
tex_coords[j * numverts + finalIndices[i]];
401 (*dst_tc)[0] = scale_s * src_tc[tcIndices[i]].s;
402 (*dst_tc)[1] = scale_t * src_tc[tcIndices[i]].t;
404 (*dst_pos)[0] = src_vert->v[0] * dst_frame->
scale[0] + dst_frame->
translate[0];
405 (*dst_pos)[1] = src_vert->v[1] * dst_frame->
scale[1] + dst_frame->
translate[1];
406 (*dst_pos)[2] = src_vert->v[2] * dst_frame->
scale[2] + dst_frame->
translate[2];
408 (*dst_nrm)[0] = 0.0f;
409 (*dst_nrm)[1] = 0.0f;
410 (*dst_nrm)[2] = 0.0f;
412 val = src_vert->lightnormalindex;
414 if (val < NUMVERTEXNORMALS) {
420 for (
int k = 0; k < 3; k++) {
430 if (all_normals_same)
432 for (
int tri = 0; tri < numindices / 3; tri++)
434 int i0 = j * numverts + finalIndices[tri * 3 + 0];
435 int i1 = j * numverts + finalIndices[tri * 3 + 1];
436 int i2 = j * numverts + finalIndices[tri * 3 + 2];
443 VectorSubtract(*p1, *p0, e1);
444 VectorSubtract(*p2, *p0, e2);
445 CrossProduct(e2, e1, n);
448 VectorCopy(n, dst_mesh->
normals[i0]);
449 VectorCopy(n, dst_mesh->
normals[i1]);
450 VectorCopy(n, dst_mesh->
normals[i2]);
454 VectorVectorScale(mins, dst_frame->
scale, mins);
455 VectorVectorScale(maxs, dst_frame->
scale, maxs);
462 src_frame = (dmd2frame_t *)((
byte *)src_frame + header.framesize);
467 for (
int i = 0; i < dst_mesh->
numindices; i += 3) {
468 int tmp = dst_mesh->
indices[i + 1];
470 dst_mesh->
indices[i + 2] = tmp;
476 return Q_ERR_SUCCESS;