]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_alias.c
implemented PointSuperContents model function as a lower-overhead
[xonotic/darkplaces.git] / model_alias.c
index ec808b7060624e1dca68cff9e964b8a556f98bf0..b117fec37fb359ed142addce4c3d8f7931c9a5b2 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)
@@ -722,7 +773,7 @@ static void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfi
                                                tempskinframe = R_SkinFrame_LoadExternal(skinfileitem->replacement, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP | TEXF_COMPRESS, false);
                                                if (!tempskinframe)
                                                        if (cls.state != ca_dedicated)
-                                                               Con_DPrintf("mesh \"%s\": failed to load skin #%i \"%s\"\n", meshname, i, skinfileitem->replacement);
+                                                               Con_Printf("mesh \"%s\": failed to load skin #%i \"%s\"\n", meshname, i, skinfileitem->replacement);
                                                Mod_BuildAliasSkinFromSkinFrame(skin, tempskinframe);
                                        }
                                        break;
@@ -787,12 +838,15 @@ void Mod_IDP0_Load(model_t *mod, void *buffer, void *bufferend)
 
        loadmodel->type = mod_alias;
        loadmodel->DrawSky = NULL;
+       loadmodel->DrawAddWaterPlanes = NULL;
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
+       loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->PointSuperContents = NULL;
 
        loadmodel->num_surfaces = 1;
        loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
@@ -949,7 +1003,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);
@@ -1020,7 +1074,7 @@ void Mod_IDP0_Load(model_t *mod, void *buffer, void *bufferend)
                                {
                                        tempskinframe = R_SkinFrame_LoadExternal(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, false);
                                        if (!tempskinframe)
-                                               tempskinframe = R_SkinFrame_LoadInternal(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight, 8, NULL, NULL);
+                                               tempskinframe = R_SkinFrame_LoadInternalQuake(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight);
                                        Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, tempskinframe);
                                }
                                datapointer += skinwidth * skinheight;
@@ -1103,15 +1157,18 @@ void Mod_IDP2_Load(model_t *mod, void *buffer, void *bufferend)
                        loadmodel->name, version, MD2ALIAS_VERSION);
 
        loadmodel->modeldatatypestring = "MD2";
-       
+
        loadmodel->type = mod_alias;
        loadmodel->DrawSky = NULL;
+       loadmodel->DrawAddWaterPlanes = NULL;
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
+       loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->PointSuperContents = NULL;
 
        if (LittleLong(pinmodel->num_tris) < 1 || LittleLong(pinmodel->num_tris) > 65536)
                Host_Error ("%s has invalid number of triangles: %i", loadmodel->name, LittleLong(pinmodel->num_tris));
@@ -1301,7 +1358,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;
@@ -1341,12 +1398,15 @@ void Mod_IDP3_Load(model_t *mod, void *buffer, void *bufferend)
 
        loadmodel->type = mod_alias;
        loadmodel->DrawSky = NULL;
+       loadmodel->DrawAddWaterPlanes = NULL;
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
+       loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->PointSuperContents = NULL;
        loadmodel->synctype = ST_RAND;
        // convert model flags to EF flags (MF_ROCKET becomes EF_ROCKET, etc)
        i = LittleLong (pinmodel->flags);
@@ -1465,7 +1525,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);
 
@@ -1545,12 +1605,15 @@ void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        }
 
        loadmodel->DrawSky = NULL;
+       loadmodel->DrawAddWaterPlanes = NULL;
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
+       loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->PointSuperContents = NULL;
 
        loadmodel->numframes = pheader->numscenes;
        loadmodel->num_surfaces = pheader->numshaders;
@@ -1806,7 +1869,7 @@ void Mod_DARKPLACESMODEL_Load(model_t *mod, void *buffer, void *bufferend)
                Host_Error ("Mod_DARKPLACESMODEL_Load: only type 2 (hierarchical skeletal pose) models are currently supported (name = %s)", loadmodel->name);
 
        loadmodel->modeldatatypestring = "DPM";
-       
+
        loadmodel->type = mod_alias;
        loadmodel->synctype = ST_RAND;
 
@@ -1840,12 +1903,15 @@ void Mod_DARKPLACESMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        }
 
        loadmodel->DrawSky = NULL;
+       loadmodel->DrawAddWaterPlanes = NULL;
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
+       loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->PointSuperContents = NULL;
 
        // model bbox
        for (i = 0;i < 3;i++)
@@ -2108,15 +2174,18 @@ void Mod_PSKMODEL_Load(model_t *mod, void *buffer, void *bufferend)
                Host_Error ("Mod_PSKMODEL_Load: %s is not an Unreal Engine ActorX (.psk + .psa) model", loadmodel->name);
 
        loadmodel->modeldatatypestring = "PSK";
-       
+
        loadmodel->type = mod_alias;
        loadmodel->DrawSky = NULL;
+       loadmodel->DrawAddWaterPlanes = NULL;
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
+       loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->PointSuperContents = NULL;
        loadmodel->synctype = ST_RAND;
 
        FS_StripExtension(loadmodel->name, animname, sizeof(animname));