mdl and md2 vertices are now stored in a different structure called aliasvertex_t...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 26 Nov 2002 20:49:13 +0000 (20:49 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 26 Nov 2002 20:49:13 +0000 (20:49 +0000)
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
mathlib.h
model_alias.c
model_alias.h
model_shared.h

index d798e37..8a8e3fa 100644 (file)
@@ -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
index fc5d6cd..3080d2e 100644 (file)
--- 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;\
index a704571..ce27427 100644 (file)
@@ -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);
 
index ca9127e..3542495 100644 (file)
@@ -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
 
index cfebccb..bd3c106 100644 (file)
@@ -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