From 384e311e7918416b4b72b05935b1343dd62fa8ed Mon Sep 17 00:00:00 2001 From: havoc Date: Tue, 26 Nov 2002 20:49:13 +0000 Subject: [PATCH] mdl and md2 vertices are now stored in a different structure called aliasvertex_t, it has all the features of mdl, md2 and md3 formats and simplifies interpolation, it also has precomputed texture vectors for faster realtime lighting. normals are no longer interpolated if not needed (fake shadows and shadow volumes do not need them) added VectorM, VectorMAM, VectorMAMAM and VectorMAMAMAM macros to make aliasvertex_t interpolation code more readable git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2652 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_models.c | 226 +++++++++++++++++++++++-------------------------- mathlib.h | 4 + model_alias.c | 90 +++++++++++--------- model_alias.h | 9 ++ model_shared.h | 2 +- 5 files changed, 171 insertions(+), 160 deletions(-) diff --git a/gl_models.c b/gl_models.c index d798e378..8a8e3fab 100644 --- a/gl_models.c +++ b/gl_models.c @@ -49,131 +49,137 @@ void GL_Models_Init(void) R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap); } -void R_AliasLerpVerts(int vertcount, float *vertices, float *normals, - float lerp1, const trivertx_t *verts1, const vec3_t fscale1, const vec3_t translate1, - float lerp2, const trivertx_t *verts2, const vec3_t fscale2, const vec3_t translate2, - float lerp3, const trivertx_t *verts3, const vec3_t fscale3, const vec3_t translate3, - float lerp4, const trivertx_t *verts4, const vec3_t fscale4, const vec3_t translate4) +void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float *normals, float *svectors, float *tvectors) { - int i; - vec3_t scale1, scale2, scale3, scale4, translate; - const float *n1, *n2, *n3, *n4; - float *av, *avn; - av = vertices; - avn = normals; - VectorScale(fscale1, lerp1, scale1); - if (lerp2) + int i, vertcount; + float vlerp1, nlerp1, vlerp2, nlerp2, vlerp3, nlerp3, vlerp4, nlerp4; + const aliasvertex_t *verts1, *verts2, *verts3, *verts4; + + if (vertices == NULL) + Host_Error("R_Model_Alias_GetVerts: vertices == NULL.\n"); + if (svectors != NULL && (tvectors == NULL || normals == NULL)) + Host_Error("R_Model_Alias_GetVerts: svectors requires tvectors and normals.\n"); + if (tvectors != NULL && (svectors == NULL || normals == NULL)) + Host_Error("R_Model_Alias_GetVerts: tvectors requires svectors and normals.\n"); + + vertcount = ent->model->numverts; + verts1 = ent->model->mdlmd2data_pose + ent->frameblend[0].frame * vertcount; + vlerp1 = ent->frameblend[0].lerp * (1.0f / 16.0f); + nlerp1 = ent->frameblend[0].lerp * (1.0f / 127.0f); + if (ent->frameblend[1].lerp) { - VectorScale(fscale2, lerp2, scale2); - if (lerp3) + verts2 = ent->model->mdlmd2data_pose + ent->frameblend[1].frame * vertcount; + vlerp2 = ent->frameblend[1].lerp * (1.0f / 16.0f); + nlerp2 = ent->frameblend[1].lerp * (1.0f / 127.0f); + if (ent->frameblend[2].lerp) { - VectorScale(fscale3, lerp3, scale3); - if (lerp4) + verts3 = ent->model->mdlmd2data_pose + ent->frameblend[2].frame * vertcount; + vlerp3 = ent->frameblend[2].lerp * (1.0f / 16.0f); + nlerp3 = ent->frameblend[2].lerp * (1.0f / 127.0f); + if (ent->frameblend[3].lerp) { - VectorScale(fscale4, lerp4, scale4); - translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3 + translate4[0] * lerp4; - translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3 + translate4[1] * lerp4; - translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3 + translate4[2] * lerp4; + verts4 = ent->model->mdlmd2data_pose + ent->frameblend[3].frame * vertcount; + vlerp4 = ent->frameblend[3].lerp * (1.0f / 16.0f); + nlerp4 = ent->frameblend[3].lerp * (1.0f / 127.0f); // generate vertices - for (i = 0;i < vertcount;i++) + if (svectors != NULL) + { + for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++, verts3++, verts4++) + { + VectorMAMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vlerp4, verts4->origin, vertices); + VectorMAMAMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, nlerp3, verts3->normal, nlerp4, verts4->normal, normals); + VectorMAMAMAM(nlerp1, verts1->svector, nlerp2, verts2->svector, nlerp3, verts3->svector, nlerp4, verts4->svector, svectors); + CrossProduct(svectors, normals, tvectors); + } + } + else if (normals != NULL) { - av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + verts3->v[0] * scale3[0] + verts4->v[0] * scale4[0] + translate[0]; - av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + verts3->v[1] * scale3[1] + verts4->v[1] * scale4[1] + translate[1]; - av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + verts3->v[2] * scale3[2] + verts4->v[2] * scale4[2] + translate[2]; - n1 = m_bytenormals[verts1->lightnormalindex]; - n2 = m_bytenormals[verts2->lightnormalindex]; - n3 = m_bytenormals[verts3->lightnormalindex]; - n4 = m_bytenormals[verts4->lightnormalindex]; - avn[0] = n1[0] * lerp1 + n2[0] * lerp2 + n3[0] * lerp3 + n4[0] * lerp4; - avn[1] = n1[1] * lerp1 + n2[1] * lerp2 + n3[1] * lerp3 + n4[1] * lerp4; - avn[2] = n1[2] * lerp1 + n2[2] * lerp2 + n3[2] * lerp3 + n4[2] * lerp4; - av += 4; - avn += 4; - verts1++;verts2++;verts3++;verts4++; + for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++, verts3++, verts4++) + { + VectorMAMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vlerp4, verts4->origin, vertices); + VectorMAMAMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, nlerp3, verts3->normal, nlerp4, verts4->normal, normals); + } } + else + for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++, verts3++, verts4++) + VectorMAMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vlerp4, verts4->origin, vertices); } else { - translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3; - translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3; - translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3; // generate vertices - for (i = 0;i < vertcount;i++) + if (svectors != NULL) + { + for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++, verts3++) + { + VectorMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vertices); + VectorMAMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, nlerp3, verts3->normal, normals); + VectorMAMAM(nlerp1, verts1->svector, nlerp2, verts2->svector, nlerp3, verts3->svector, svectors); + CrossProduct(svectors, normals, tvectors); + } + } + else if (normals != NULL) { - av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + verts3->v[0] * scale3[0] + translate[0]; - av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + verts3->v[1] * scale3[1] + translate[1]; - av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + verts3->v[2] * scale3[2] + translate[2]; - n1 = m_bytenormals[verts1->lightnormalindex]; - n2 = m_bytenormals[verts2->lightnormalindex]; - n3 = m_bytenormals[verts3->lightnormalindex]; - avn[0] = n1[0] * lerp1 + n2[0] * lerp2 + n3[0] * lerp3; - avn[1] = n1[1] * lerp1 + n2[1] * lerp2 + n3[1] * lerp3; - avn[2] = n1[2] * lerp1 + n2[2] * lerp2 + n3[2] * lerp3; - av += 4; - avn += 4; - verts1++;verts2++;verts3++; + for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++, verts3++) + { + VectorMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vertices); + VectorMAMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, nlerp3, verts3->normal, normals); + } } + else + for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++, verts3++) + VectorMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vertices); } } else { - translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2; - translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2; - translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2; // generate vertices - for (i = 0;i < vertcount;i++) + if (svectors != NULL) + { + for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++) + { + VectorMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vertices); + VectorMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, normals); + VectorMAM(nlerp1, verts1->svector, nlerp2, verts2->svector, svectors); + CrossProduct(svectors, normals, tvectors); + } + } + else if (normals != NULL) { - av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + translate[0]; - av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + translate[1]; - av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + translate[2]; - n1 = m_bytenormals[verts1->lightnormalindex]; - n2 = m_bytenormals[verts2->lightnormalindex]; - avn[0] = n1[0] * lerp1 + n2[0] * lerp2; - avn[1] = n1[1] * lerp1 + n2[1] * lerp2; - avn[2] = n1[2] * lerp1 + n2[2] * lerp2; - av += 4; - avn += 4; - verts1++;verts2++; + for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++) + { + VectorMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vertices); + VectorMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, normals); + } } + else + for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++) + VectorMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vertices); } } else { - translate[0] = translate1[0] * lerp1; - translate[1] = translate1[1] * lerp1; - translate[2] = translate1[2] * lerp1; // generate vertices - if (lerp1 != 1) + if (svectors != NULL) { - // general but almost never used case - for (i = 0;i < vertcount;i++) + for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++) { - av[0] = verts1->v[0] * scale1[0] + translate[0]; - av[1] = verts1->v[1] * scale1[1] + translate[1]; - av[2] = verts1->v[2] * scale1[2] + translate[2]; - n1 = m_bytenormals[verts1->lightnormalindex]; - avn[0] = n1[0] * lerp1; - avn[1] = n1[1] * lerp1; - avn[2] = n1[2] * lerp1; - av += 4; - avn += 4; - verts1++; + VectorM(vlerp1, verts1->origin, vertices); + VectorM(nlerp1, verts1->normal, normals); + VectorM(nlerp1, verts1->svector, svectors); + CrossProduct(svectors, normals, tvectors); } } - else + else if (normals != NULL) { - // fast normal case - for (i = 0;i < vertcount;i++) + for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++) { - av[0] = verts1->v[0] * scale1[0] + translate[0]; - av[1] = verts1->v[1] * scale1[1] + translate[1]; - av[2] = verts1->v[2] * scale1[2] + translate[2]; - VectorCopy(m_bytenormals[verts1->lightnormalindex], avn); - av += 4; - avn += 4; - verts1++; + VectorM(vlerp1, verts1->origin, vertices); + VectorM(nlerp1, verts1->normal, normals); } } + else + for (i = 0;i < vertcount;i++, vertices += 4, verts1++) + VectorM(vlerp1, verts1->origin, vertices); } } @@ -189,28 +195,7 @@ skinframe_t *R_FetchSkinFrame(const entity_render_t *ent) return &model->skinframes[model->skinscenes[s].firstframe]; } -void R_LerpMDLMD2Vertices(const entity_render_t *ent, float *vertices, float *normals) -{ - const md2frame_t *frame1, *frame2, *frame3, *frame4; - const trivertx_t *frame1verts, *frame2verts, *frame3verts, *frame4verts; - const model_t *model = ent->model; - - frame1 = &model->mdlmd2data_frames[ent->frameblend[0].frame]; - frame2 = &model->mdlmd2data_frames[ent->frameblend[1].frame]; - frame3 = &model->mdlmd2data_frames[ent->frameblend[2].frame]; - frame4 = &model->mdlmd2data_frames[ent->frameblend[3].frame]; - frame1verts = &model->mdlmd2data_pose[ent->frameblend[0].frame * model->numverts]; - frame2verts = &model->mdlmd2data_pose[ent->frameblend[1].frame * model->numverts]; - frame3verts = &model->mdlmd2data_pose[ent->frameblend[2].frame * model->numverts]; - frame4verts = &model->mdlmd2data_pose[ent->frameblend[3].frame * model->numverts]; - R_AliasLerpVerts(model->numverts, vertices, normals, - ent->frameblend[0].lerp, frame1verts, frame1->scale, frame1->translate, - ent->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate, - ent->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate, - ent->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate); -} - -void R_DrawQ1Q2AliasModelCallback (const void *calldata1, int calldata2) +void R_DrawAliasModelCallback (const void *calldata1, int calldata2) { int i, c, fullbright, pantsfullbright, shirtfullbright, colormapped, tex; float pantscolor[3], shirtcolor[3]; @@ -266,7 +251,7 @@ void R_DrawQ1Q2AliasModelCallback (const void *calldata1, int calldata2) blendfunc2 = GL_ZERO; } - R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals); + R_Model_Alias_GetVerts(ent, varray_vertex, aliasvert_normals, NULL, NULL); memcpy(varray_texcoord[0], model->mdlmd2data_texcoords, model->numverts * sizeof(float[4])); if (!skinframe->base && !skinframe->pants && !skinframe->shirt && !skinframe->glow) { @@ -431,9 +416,9 @@ void R_Model_Alias_Draw(entity_render_t *ent) c_models++; if (ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || R_FetchSkinFrame(ent)->fog != NULL) - R_MeshQueue_AddTransparent(ent->origin, R_DrawQ1Q2AliasModelCallback, ent, 0); + R_MeshQueue_AddTransparent(ent->origin, R_DrawAliasModelCallback, ent, 0); else - R_DrawQ1Q2AliasModelCallback(ent, 0); + R_DrawAliasModelCallback(ent, 0); } void R_Model_Alias_DrawFakeShadow (entity_render_t *ent) @@ -463,7 +448,7 @@ void R_Model_Alias_DrawFakeShadow (entity_render_t *ent) R_Mesh_State(&m); c_alias_polys += model->numtris; - R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals); + R_Model_Alias_GetVerts(ent, varray_vertex, NULL, NULL, NULL); // put a light direction in the entity's coordinate space Matrix4x4_Transform3x3(&ent->inversematrix, lightdirection, projection); @@ -498,7 +483,7 @@ void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightor { R_Mesh_Matrix(&ent->matrix); R_Mesh_ResizeCheck(ent->model->numverts * 2); - R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals); + R_Model_Alias_GetVerts(ent, varray_vertex, NULL, NULL, NULL); R_Shadow_Volume(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices, ent->model->mdlmd2data_triangleneighbors, relativelightorigin, lightradius, projectdistance); } } @@ -511,8 +496,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v skinframe_t *skinframe; R_Mesh_Matrix(&ent->matrix); R_Mesh_ResizeCheck(ent->model->numverts); - R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals); - Mod_BuildTextureVectorsAndNormals(ent->model->numverts, ent->model->numtris, varray_vertex, ent->model->mdlmd2data_texcoords, ent->model->mdlmd2data_indices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals); + R_Model_Alias_GetVerts(ent, varray_vertex, aliasvert_normals, aliasvert_svectors, aliasvert_tvectors); skinframe = R_FetchSkinFrame(ent); // note: to properly handle fog this should scale the lightcolor into lightcolor2 according to 1-fog scaling diff --git a/mathlib.h b/mathlib.h index fc5d6cd0..3080d2ec 100644 --- a/mathlib.h +++ b/mathlib.h @@ -72,6 +72,10 @@ extern vec3_t vec3_origin; #define VectorScale(in, scale, out) ((out)[0] = (in)[0] * (scale),(out)[1] = (in)[1] * (scale),(out)[2] = (in)[2] * (scale)) #define VectorCompare(a,b) (((a)[0]==(b)[0])&&((a)[1]==(b)[1])&&((a)[2]==(b)[2])) #define VectorMA(a, scale, b, c) ((c)[0] = (a)[0] + (scale) * (b)[0],(c)[1] = (a)[1] + (scale) * (b)[1],(c)[2] = (a)[2] + (scale) * (b)[2]) +#define VectorM(scale1, b1, c) ((c)[0] = (scale1) * (b1)[0],(c)[1] = (scale1) * (b1)[1],(c)[2] = (scale1) * (b1)[2]) +#define VectorMAM(scale1, b1, scale2, b2, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2]) +#define VectorMAMAM(scale1, b1, scale2, b2, scale3, b3, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2]) +#define VectorMAMAMAM(scale1, b1, scale2, b2, scale3, b3, scale4, b4, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0] + (scale4) * (b4)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1] + (scale4) * (b4)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2] + (scale4) * (b4)[2]) #define VectorNormalizeFast(_v)\ {\ float _y, _number;\ diff --git a/model_alias.c b/model_alias.c index a704571e..ce274274 100644 --- a/model_alias.c +++ b/model_alias.c @@ -37,9 +37,9 @@ static int vertonseam[MAXALIASVERTS]; static int vertremap[MAXALIASVERTS]; static int temptris[MAXALIASTRIS][3]; -static void Mod_ConvertAliasVerts (int inverts, vec3_t scale, vec3_t translate, trivertx_t *v, trivertx_t *out) +static void Mod_ConvertAliasVerts (int inverts, vec3_t scale, vec3_t translate, trivertx_t *v, aliasvertex_t *out) { - int i, j, invalidnormals = 0; + int i, j; float dist; vec3_t temp; for (i = 0;i < inverts;i++) @@ -64,34 +64,38 @@ static void Mod_ConvertAliasVerts (int inverts, vec3_t scale, vec3_t translate, if (modelradius < dist) modelradius = dist; + VectorScale(temp, 16.0f, temp); + temp[0] = bound(-32768, temp[0], 32767); + temp[1] = bound(-32768, temp[1], 32767); + temp[2] = bound(-32768, temp[2], 32767); + j = vertremap[i]; // not onseam if (j >= 0) - { - VectorCopy(v[i].v, out[j].v); - out[j].lightnormalindex = v[i].lightnormalindex; - if (out[j].lightnormalindex >= NUMVERTEXNORMALS) - { - invalidnormals++; - out[j].lightnormalindex = 0; - } - } + VectorCopy(temp, out[j].origin); j = vertremap[i+inverts]; // onseam if (j >= 0) - { - VectorCopy(v[i].v, out[j].v); - out[j].lightnormalindex = v[i].lightnormalindex; - if (out[j].lightnormalindex >= NUMVERTEXNORMALS) - { - invalidnormals++; - out[j].lightnormalindex = 0; - } - } + VectorCopy(temp, out[j].origin); + } +} + +static void Mod_BuildAliasVertexTextureVectors(int numtriangles, const int *elements, int numverts, aliasvertex_t *vertices, const float *texcoords, float *vertexbuffer, float *svectorsbuffer, float *tvectorsbuffer, float *normalsbuffer) +{ + int i; + for (i = 0;i < numverts;i++) + VectorScale(vertices[i].origin, (1.0f / 16.0f), &vertexbuffer[i * 4]); + Mod_BuildTextureVectorsAndNormals(numverts, numtriangles, vertexbuffer, texcoords, elements, svectorsbuffer, tvectorsbuffer, normalsbuffer); + for (i = 0;i < numverts;i++) + { + vertices[i].normal[0] = normalsbuffer[i * 4 + 0] * 127.0f; + vertices[i].normal[1] = normalsbuffer[i * 4 + 1] * 127.0f; + vertices[i].normal[2] = normalsbuffer[i * 4 + 2] * 127.0f; + vertices[i].svector[0] = svectorsbuffer[i * 4 + 0] * 127.0f; + vertices[i].svector[1] = svectorsbuffer[i * 4 + 1] * 127.0f; + vertices[i].svector[2] = svectorsbuffer[i * 4 + 2] * 127.0f; } - if (invalidnormals) - Con_Printf("Mod_ConvertAliasVerts: \"%s\", %i invalid normal indices found\n", loadmodel->name, invalidnormals); } -static void Mod_MDL_LoadFrames (qbyte * datapointer, int inverts, int outverts, vec3_t scale, vec3_t translate) +static void Mod_MDL_LoadFrames (qbyte* datapointer, int inverts, vec3_t scale, vec3_t translate) { daliasframetype_t *pframetype; daliasframe_t *pinframe; @@ -100,8 +104,13 @@ static void Mod_MDL_LoadFrames (qbyte * datapointer, int inverts, int outverts, int i, f, pose, groupframes; float interval; animscene_t *scene; + float *vertexbuffer, *svectorsbuffer, *tvectorsbuffer, *normalsbuffer; pose = 0; scene = loadmodel->animscenes; + vertexbuffer = Mem_Alloc(tempmempool, loadmodel->numverts * sizeof(float[4]) * 4); + svectorsbuffer = vertexbuffer + loadmodel->numverts * 4; + tvectorsbuffer = svectorsbuffer + loadmodel->numverts * 4; + normalsbuffer = tvectorsbuffer + loadmodel->numverts * 4; for (f = 0;f < loadmodel->numframes;f++) { pframetype = (daliasframetype_t *)datapointer; @@ -149,11 +158,13 @@ static void Mod_MDL_LoadFrames (qbyte * datapointer, int inverts, int outverts, VectorCopy(scale, loadmodel->mdlmd2data_frames[pose].scale); VectorCopy(translate, loadmodel->mdlmd2data_frames[pose].translate); - Mod_ConvertAliasVerts(inverts, scale, translate, (trivertx_t *)datapointer, loadmodel->mdlmd2data_pose + pose * outverts); + Mod_ConvertAliasVerts(inverts, scale, translate, (trivertx_t *)datapointer, loadmodel->mdlmd2data_pose + pose * loadmodel->numverts); + Mod_BuildAliasVertexTextureVectors(loadmodel->numtris, loadmodel->mdlmd2data_indices, loadmodel->numverts, loadmodel->mdlmd2data_pose + pose * loadmodel->numverts, loadmodel->mdlmd2data_texcoords, vertexbuffer, svectorsbuffer, tvectorsbuffer, normalsbuffer); datapointer += sizeof(trivertx_t) * inverts; pose++; } } + Mem_Free(vertexbuffer); } static rtexture_t *GL_TextureForSkinLayer(const qbyte *in, int width, int height, const char *name, const unsigned int *palette, int precache) @@ -471,13 +482,13 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) // load the frames loadmodel->animscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numframes); loadmodel->mdlmd2data_frames = Mem_Alloc(loadmodel->mempool, sizeof(md2frame_t) * totalposes); - loadmodel->mdlmd2data_pose = Mem_Alloc(loadmodel->mempool, sizeof(trivertx_t) * totalposes * totalverts); + loadmodel->mdlmd2data_pose = Mem_Alloc(loadmodel->mempool, sizeof(aliasvertex_t) * totalposes * totalverts); // LordHavoc: doing proper bbox for model aliasbboxmin[0] = aliasbboxmin[1] = aliasbboxmin[2] = 1000000000; aliasbboxmax[0] = aliasbboxmax[1] = aliasbboxmax[2] = -1000000000; - Mod_MDL_LoadFrames (startframes, numverts, totalverts, scale, translate); + Mod_MDL_LoadFrames (startframes, numverts, scale, translate); modelyawradius = sqrt(modelyawradius); modelradius = sqrt(modelradius); @@ -499,16 +510,15 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) Mod_BuildTriangleNeighbors(loadmodel->mdlmd2data_triangleneighbors, loadmodel->mdlmd2data_indices, loadmodel->numtris); } -static void Mod_MD2_ConvertVerts (vec3_t scale, vec3_t translate, trivertx_t *v, trivertx_t *out, int *vertremap) +static void Mod_MD2_ConvertVerts (vec3_t scale, vec3_t translate, trivertx_t *v, aliasvertex_t *out, int *vertremap) { - int i, invalidnormals = 0; + int i; float dist; trivertx_t *in; vec3_t temp; for (i = 0;i < loadmodel->numverts;i++) { in = v + vertremap[i]; - VectorCopy(in->v, out[i].v); temp[0] = in->v[0] * scale[0] + translate[0]; temp[1] = in->v[1] * scale[1] + translate[1]; temp[2] = in->v[2] * scale[2] + translate[2]; @@ -525,15 +535,12 @@ static void Mod_MD2_ConvertVerts (vec3_t scale, vec3_t translate, trivertx_t *v, dist += temp[2]*temp[2]; if (modelradius < dist) modelradius = dist; - out[i].lightnormalindex = in->lightnormalindex; - if (out[i].lightnormalindex >= NUMVERTEXNORMALS) - { - invalidnormals++; - out[i].lightnormalindex = 0; - } + VectorScale(temp, 16.0f, temp); + temp[0] = bound(-32768, temp[0], 32767); + temp[1] = bound(-32768, temp[1], 32767); + temp[2] = bound(-32768, temp[2], 32767); + VectorCopy(temp, out[i].origin); } - if (invalidnormals) - Con_Printf("Mod_MD2_ConvertVerts: \"%s\", %i invalid normal indices found\n", loadmodel->name, invalidnormals); } void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) @@ -557,6 +564,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) md2triangle_t *intri; unsigned short *inst; int skinwidth, skinheight; + float *vertexbuffer, *svectorsbuffer, *tvectorsbuffer, *normalsbuffer; pinmodel = buffer; base = buffer; @@ -719,6 +727,10 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) loadmodel->mdlmd2data_frames = Mem_Alloc(loadmodel->mempool, loadmodel->numframes * sizeof(md2frame_t)); loadmodel->mdlmd2data_pose = Mem_Alloc(loadmodel->mempool, loadmodel->numverts * loadmodel->numframes * sizeof(trivertx_t)); + vertexbuffer = Mem_Alloc(tempmempool, loadmodel->numverts * sizeof(float[4]) * 4); + svectorsbuffer = vertexbuffer + loadmodel->numverts * 4; + tvectorsbuffer = svectorsbuffer + loadmodel->numverts * 4; + normalsbuffer = tvectorsbuffer + loadmodel->numverts * 4; for (i = 0;i < loadmodel->numframes;i++) { pinframe = (md2frame_t *)datapointer; @@ -729,7 +741,8 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) loadmodel->mdlmd2data_frames[i].scale[j] = LittleFloat(pinframe->scale[j]); loadmodel->mdlmd2data_frames[i].translate[j] = LittleFloat(pinframe->translate[j]); } - Mod_MD2_ConvertVerts (loadmodel->mdlmd2data_frames[i].scale, loadmodel->mdlmd2data_frames[i].translate, (void *)datapointer, &loadmodel->mdlmd2data_pose[i * loadmodel->numverts], vertremap); + Mod_MD2_ConvertVerts(loadmodel->mdlmd2data_frames[i].scale, loadmodel->mdlmd2data_frames[i].translate, (void *)datapointer, loadmodel->mdlmd2data_pose + i * loadmodel->numverts, vertremap); + Mod_BuildAliasVertexTextureVectors(loadmodel->numtris, loadmodel->mdlmd2data_indices, loadmodel->numverts, loadmodel->mdlmd2data_pose + i * loadmodel->numverts, loadmodel->mdlmd2data_texcoords, vertexbuffer, svectorsbuffer, tvectorsbuffer, normalsbuffer); datapointer += numxyz * sizeof(trivertx_t); strcpy(loadmodel->animscenes[i].name, loadmodel->mdlmd2data_frames[i].name); @@ -738,6 +751,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) loadmodel->animscenes[i].framerate = 10; loadmodel->animscenes[i].loop = true; } + Mem_Free(vertexbuffer); Mem_Free(vertremap); diff --git a/model_alias.h b/model_alias.h index ca9127e8..3542495f 100644 --- a/model_alias.h +++ b/model_alias.h @@ -230,5 +230,14 @@ typedef struct md3modelheader_s } md3modelheader_t; +// LordHavoc: all quake series 'alias' models (mdl, md2, md3) are converted to this vertex format +typedef struct aliasvertex_s +{ + short origin[3]; + signed char normal[3]; + signed char svector[3]; +} +aliasvertex_t; + #endif diff --git a/model_shared.h b/model_shared.h index cfebccbe..bd3c106f 100644 --- a/model_shared.h +++ b/model_shared.h @@ -234,7 +234,7 @@ typedef struct model_s int *mdlmd2data_indices; float *mdlmd2data_texcoords; md2frame_t *mdlmd2data_frames; - trivertx_t *mdlmd2data_pose; + aliasvertex_t *mdlmd2data_pose; int *mdlmd2data_triangleneighbors; // for Zymotic models -- 2.39.2