]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
precalculate texture vectors on mdl/md2/md3 models, this improves
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 28 Nov 2007 11:19:00 +0000 (11:19 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 28 Nov 2007 11:19:00 +0000 (11:19 +0000)
rendering performance with rtlights or q3bsp lightgrid

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7732 d7cf8633-e32d-0410-b094-e92efae38249

model_alias.c
model_shared.h

index 0179e821152368da394d24272cb4b483f7c79fff..ad5b030c30798e7625ded95150e637a13467e3b1 100644 (file)
@@ -276,11 +276,28 @@ void Mod_Alias_GetMesh_Vertices(const model_t *model, const frameblend_t *frameb
                                        }
                                }
                        }
-               }
-               // md3 model vertices do not include tangents, so we have to generate them (extremely slow)
-               if (normal3f)
                        if (svector3f)
-                               Mod_BuildTextureVectorsFromNormals(0, model->surfmesh.num_vertices, model->surfmesh.num_triangles, vertex3f, model->surfmesh.data_texcoordtexture2f, normal3f, model->surfmesh.data_element3i, svector3f, tvector3f, r_smoothnormals_areaweighting.integer);
+                       {
+                               const texvecvertex_t *texvecvert = model->surfmesh.data_morphtexvecvertex + numverts * frameblend[blendnum].frame;
+                               float f = frameblend[blendnum].lerp * (1.0f / 127.0f);
+                               if (blendnum == 0)
+                               {
+                                       for (i = 0;i < numverts;i++, texvecvert++)
+                                       {
+                                               VectorScale(texvecvert->svec, f, svector3f + i*3);
+                                               VectorScale(texvecvert->tvec, f, tvector3f + i*3);
+                                       }
+                               }
+                               else
+                               {
+                                       for (i = 0;i < numverts;i++, texvecvert++)
+                                       {
+                                               VectorMA(svector3f + i*3, f, texvecvert->svec, svector3f + i*3);
+                                               VectorMA(tvector3f + i*3, f, texvecvert->tvec, tvector3f + i*3);
+                                       }
+                               }
+                       }
+               }
        }
        else if (model->surfmesh.data_morphmdlvertex)
        {
@@ -352,10 +369,28 @@ void Mod_Alias_GetMesh_Vertices(const model_t *model, const frameblend_t *frameb
                                        }
                                }
                        }
-               }
-               if (normal3f)
                        if (svector3f)
-                               Mod_BuildTextureVectorsFromNormals(0, model->surfmesh.num_vertices, model->surfmesh.num_triangles, vertex3f, model->surfmesh.data_texcoordtexture2f, normal3f, model->surfmesh.data_element3i, svector3f, tvector3f, r_smoothnormals_areaweighting.integer);
+                       {
+                               const texvecvertex_t *texvecvert = model->surfmesh.data_morphtexvecvertex + numverts * frameblend[blendnum].frame;
+                               float f = frameblend[blendnum].lerp * (1.0f / 127.0f);
+                               if (blendnum == 0)
+                               {
+                                       for (i = 0;i < numverts;i++, texvecvert++)
+                                       {
+                                               VectorScale(texvecvert->svec, f, svector3f + i*3);
+                                               VectorScale(texvecvert->tvec, f, tvector3f + i*3);
+                                       }
+                               }
+                               else
+                               {
+                                       for (i = 0;i < numverts;i++, texvecvert++)
+                                       {
+                                               VectorMA(svector3f + i*3, f, texvecvert->svec, svector3f + i*3);
+                                               VectorMA(tvector3f + i*3, f, texvecvert->tvec, tvector3f + i*3);
+                                       }
+                               }
+                       }
+               }
        }
        else
                Host_Error("model %s has no skeletal or vertex morph animation data", model->name);
@@ -515,14 +550,30 @@ static void Mod_Alias_CalculateBoundingBox(void)
        loadmodel->radius2 = radius * radius;
 }
 
-static void Mod_Alias_Mesh_CompileFrameZero(void)
+static void Mod_Alias_MorphMesh_CompileFrames(void)
 {
+       int i, j;
        frameblend_t frameblend[4] = {{0, 1}, {0, 0}, {0, 0}, {0, 0}};
-       loadmodel->surfmesh.data_vertex3f = (float *)Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * sizeof(float[3][4]));
-       loadmodel->surfmesh.data_svector3f = loadmodel->surfmesh.data_vertex3f + loadmodel->surfmesh.num_vertices * 3;
-       loadmodel->surfmesh.data_tvector3f = loadmodel->surfmesh.data_vertex3f + loadmodel->surfmesh.num_vertices * 6;
-       loadmodel->surfmesh.data_normal3f = loadmodel->surfmesh.data_vertex3f + loadmodel->surfmesh.num_vertices * 9;
-       Mod_Alias_GetMesh_Vertices(loadmodel, frameblend, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f);
+       unsigned char *datapointer;
+       datapointer = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * (sizeof(float[3]) * 4 + loadmodel->surfmesh.num_morphframes * sizeof(texvecvertex_t)));
+       loadmodel->surfmesh.data_vertex3f = (float *)datapointer;datapointer += loadmodel->surfmesh.num_vertices * sizeof(float[3]);
+       loadmodel->surfmesh.data_svector3f = (float *)datapointer;datapointer += loadmodel->surfmesh.num_vertices * sizeof(float[3]);
+       loadmodel->surfmesh.data_tvector3f = (float *)datapointer;datapointer += loadmodel->surfmesh.num_vertices * sizeof(float[3]);
+       loadmodel->surfmesh.data_normal3f = (float *)datapointer;datapointer += loadmodel->surfmesh.num_vertices * sizeof(float[3]);
+       loadmodel->surfmesh.data_morphtexvecvertex = (texvecvertex_t *)datapointer;datapointer += loadmodel->surfmesh.num_morphframes * loadmodel->surfmesh.num_vertices * sizeof(texvecvertex_t);
+       // this counts down from the last frame to the first so that the final data in surfmesh is for frame zero (which is what the renderer expects to be there)
+       for (i = loadmodel->surfmesh.num_morphframes-1;i >= 0;i--)
+       {
+               frameblend[0].frame = i;
+               Mod_Alias_GetMesh_Vertices(loadmodel, frameblend, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_normal3f, NULL, NULL);
+               Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, r_smoothnormals_areaweighting.integer);
+               // encode the svector and tvector in 3 byte format for permanent storage
+               for (j = 0;j < loadmodel->surfmesh.num_vertices;j++)
+               {
+                       VectorScale(loadmodel->surfmesh.data_svector3f + j * 3, 127.0f, loadmodel->surfmesh.data_morphtexvecvertex[i*loadmodel->surfmesh.num_vertices+j].svec);
+                       VectorScale(loadmodel->surfmesh.data_tvector3f + j * 3, 127.0f, loadmodel->surfmesh.data_morphtexvecvertex[i*loadmodel->surfmesh.num_vertices+j].tvec);
+               }
+       }
 }
 
 static void Mod_MDLMD2MD3_TraceBox(model_t *model, int frame, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask)
@@ -951,7 +1002,7 @@ void Mod_IDP0_Load(model_t *mod, void *buffer, void *bufferend)
        Mod_MDL_LoadFrames (startframes, numverts, vertremap);
        Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
        Mod_Alias_CalculateBoundingBox();
-       Mod_Alias_Mesh_CompileFrameZero();
+       Mod_Alias_MorphMesh_CompileFrames();
 
        Mem_Free(vertst);
        Mem_Free(vertremap);
@@ -1305,7 +1356,7 @@ void Mod_IDP2_Load(model_t *mod, void *buffer, void *bufferend)
 
        Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
        Mod_Alias_CalculateBoundingBox();
-       Mod_Alias_Mesh_CompileFrameZero();
+       Mod_Alias_MorphMesh_CompileFrames();
 
        surface = loadmodel->data_surfaces;
        surface->texture = loadmodel->data_textures;
@@ -1471,7 +1522,7 @@ void Mod_IDP3_Load(model_t *mod, void *buffer, void *bufferend)
                Mod_ValidateElements(loadmodel->surfmesh.data_element3i + surface->num_firsttriangle * 3, surface->num_triangles, surface->num_firstvertex, surface->num_vertices, __FILE__, __LINE__);
        }
        Mod_BuildTriangleNeighbors(loadmodel->surfmesh.data_neighbor3i, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles);
-       Mod_Alias_Mesh_CompileFrameZero();
+       Mod_Alias_MorphMesh_CompileFrames();
        Mod_Alias_CalculateBoundingBox();
        Mod_FreeSkinFiles(skinfiles);
 
index b49bdd068c31880b4aeea766822510407dce9d45..89d3b2b9a9a4c8b27dee5da8a6e54b03c9fa100b 100644 (file)
@@ -90,7 +90,13 @@ typedef struct overridetagnameset_s
 overridetagnameset_t;
 
 struct md3vertex_s;
-struct trivertex_s;
+struct trivertx_s;
+typedef struct texvecvertex_s
+{
+       signed char svec[3];
+       signed char tvec[3];
+}
+texvecvertex_t;
 
 // used for mesh lists in q1bsp/q3bsp map models
 // (the surfaces reference portions of these meshes)
@@ -125,6 +131,7 @@ typedef struct surfmesh_s
        int num_morphframes;
        struct md3vertex_s *data_morphmd3vertex;
        struct trivertx_s *data_morphmdlvertex;
+       struct texvecvertex_s *data_morphtexvecvertex;
        float *data_morphmd2framesize6f;
        float num_morphmdlframescale[3];
        float num_morphmdlframetranslate[3];