X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=model_alias.c;h=cdf0edeee0928722f85bf5373004f98fd1353929;hb=2107b65205dbec9522df439f7639c6fe08e54a46;hp=100311ebc20495244649fafa7f7fa2d9aef5acdb;hpb=d4cd2cda4a1eb2288f2acc600b823c02715d1e12;p=xonotic%2Fdarkplaces.git diff --git a/model_alias.c b/model_alias.c index 100311eb..cdf0edee 100644 --- a/model_alias.c +++ b/model_alias.c @@ -752,33 +752,46 @@ static void Mod_Alias_MorphMesh_CompileFrames(void) } } -static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask) +static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask) { int i; float segmentmins[3], segmentmaxs[3]; msurface_t *surface; - float vertex3fbuf[1024*3]; + float vertex3fbuf[1024 * 3]; float *vertex3f = vertex3fbuf; + float *freevertex3f = NULL; + // for static cases we can just call CollisionBIH which is much faster + if ((frameblend == NULL || (frameblend[0].subframe == 0 && frameblend[1].lerp == 0)) && (skeleton == NULL || skeleton->relativetransforms == NULL)) + { + Mod_CollisionBIH_TraceLine(model, frameblend, skeleton, trace, start, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask); + return; + } memset(trace, 0, sizeof(*trace)); trace->fraction = 1; trace->hitsupercontentsmask = hitsupercontentsmask; trace->skipsupercontentsmask = skipsupercontentsmask; - if (model->surfmesh.num_vertices > 1024) - vertex3f = (float *)Mem_Alloc(tempmempool, model->surfmesh.num_vertices * sizeof(float[3])); + trace->skipmaterialflagsmask = skipmaterialflagsmask; segmentmins[0] = min(start[0], end[0]) - 1; segmentmins[1] = min(start[1], end[1]) - 1; segmentmins[2] = min(start[2], end[2]) - 1; segmentmaxs[0] = max(start[0], end[0]) + 1; segmentmaxs[1] = max(start[1], end[1]) + 1; segmentmaxs[2] = max(start[2], end[2]) + 1; - model->AnimateVertices(model, frameblend, skeleton, vertex3f, NULL, NULL, NULL); + if (frameblend == NULL || frameblend[0].subframe != 0 || frameblend[0].lerp != 0 || skeleton != NULL) + { + if (model->surfmesh.num_vertices > 1024) + vertex3f = freevertex3f = (float *)Mem_Alloc(tempmempool, model->surfmesh.num_vertices * sizeof(float[3])); + model->AnimateVertices(model, frameblend, skeleton, vertex3f, NULL, NULL, NULL); + } + else + vertex3f = model->surfmesh.data_vertex3f; for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++) Collision_TraceLineTriangleMeshFloat(trace, start, end, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs); - if (vertex3f != vertex3fbuf) - Mem_Free(vertex3f); + if (freevertex3f) + Mem_Free(freevertex3f); } -static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask) +static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask) { int i; vec3_t shiftstart, shiftend; @@ -793,16 +806,24 @@ static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameb { VectorAdd(start, boxmins, shiftstart); VectorAdd(end, boxmins, shiftend); - Mod_MDLMD2MD3_TraceLine(model, frameblend, skeleton, trace, shiftstart, shiftend, hitsupercontentsmask, skipsupercontentsmask); + Mod_MDLMD2MD3_TraceLine(model, frameblend, skeleton, trace, shiftstart, shiftend, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask); VectorSubtract(trace->endpos, boxmins, trace->endpos); return; } + // for static cases we can just call CollisionBIH which is much faster + if ((frameblend == NULL || (frameblend[0].subframe == 0 && frameblend[1].lerp == 0)) && (skeleton == NULL || skeleton->relativetransforms == NULL)) + { + Mod_CollisionBIH_TraceBox(model, frameblend, skeleton, trace, start, boxmins, boxmaxs, end, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask); + return; + } + // box trace, performed as brush trace memset(trace, 0, sizeof(*trace)); trace->fraction = 1; trace->hitsupercontentsmask = hitsupercontentsmask; trace->skipsupercontentsmask = skipsupercontentsmask; + trace->skipmaterialflagsmask = skipmaterialflagsmask; if (model->surfmesh.num_vertices > 1024) vertex3f = (float *)Mem_Alloc(tempmempool, model->surfmesh.num_vertices * sizeof(float[3])); segmentmins[0] = min(start[0], end[0]) + boxmins[0] - 1; @@ -901,45 +922,6 @@ static void Mod_MDL_LoadFrames (unsigned char* datapointer, int inverts, int *ve } } -static void Mod_BuildAliasSkinFromSkinFrame(texture_t *texture, skinframe_t *skinframe) -{ - if (cls.state == ca_dedicated) - return; - // hack - if (!skinframe) - skinframe = R_SkinFrame_LoadMissing(); - memset(texture, 0, sizeof(*texture)); - texture->currentframe = texture; - //texture->animated = false; - texture->materialshaderpass = texture->shaderpasses[0] = Mod_CreateShaderPass(skinframe); - texture->currentskinframe = skinframe; - //texture->backgroundnumskinframes = 0; - //texture->customblendfunc[0] = 0; - //texture->customblendfunc[1] = 0; - //texture->surfaceflags = 0; - //texture->supercontents = 0; - //texture->surfaceparms = 0; - //texture->textureflags = 0; - - texture->basematerialflags = MATERIALFLAG_WALL; - texture->basealpha = 1.0f; - if (texture->currentskinframe->hasalpha) - texture->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; - texture->currentmaterialflags = texture->basematerialflags; - texture->offsetmapping = OFFSETMAPPING_DEFAULT; - texture->offsetscale = 1; - texture->offsetbias = 0; - texture->specularscalemod = 1; - texture->specularpowermod = 1; - texture->surfaceflags = 0; - texture->supercontents = SUPERCONTENTS_SOLID; - if (!(texture->basematerialflags & MATERIALFLAG_BLENDED)) - texture->supercontents |= SUPERCONTENTS_OPAQUE; - texture->transparentsort = TRANSPARENTSORT_DISTANCE; - // WHEN ADDING DEFAULTS HERE, REMEMBER TO PUT DEFAULTS IN ALL LOADERS - // JUST GREP FOR "specularscalemod = 1". -} - void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfile, const char *meshname, const char *shadername) { int i; @@ -962,14 +944,14 @@ void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfile, con Image_StripImageExtension(skinfileitem->replacement, stripbuf, sizeof(stripbuf)); if(developer_extra.integer) Con_DPrintf("--> got %s from skin file\n", stripbuf); - Mod_LoadTextureFromQ3Shader(skin, stripbuf, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS); + Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, skin, stripbuf, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, MATERIALFLAG_WALL); break; } } if (!skinfileitem) { // don't render unmentioned meshes - Mod_BuildAliasSkinFromSkinFrame(skin, NULL); + Mod_LoadCustomMaterial(loadmodel->mempool, skin, meshname, SUPERCONTENTS_SOLID, MATERIALFLAG_WALL, R_SkinFrame_LoadMissing()); if(developer_extra.integer) Con_DPrintf("--> skipping\n"); skin->basematerialflags = skin->currentmaterialflags = MATERIALFLAG_NOSHADOW | MATERIALFLAG_NODRAW; @@ -981,7 +963,7 @@ void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfile, con if(developer_extra.integer) Con_DPrintf("--> using default\n"); Image_StripImageExtension(shadername, stripbuf, sizeof(stripbuf)); - Mod_LoadTextureFromQ3Shader(skin, stripbuf, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS); + Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, skin, stripbuf, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, MATERIALFLAG_WALL); } } @@ -1009,7 +991,6 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend) float *vertst; int *vertonseam, *vertremap; skinfile_t *skinfiles; - char vabuf[1024]; datapointer = (unsigned char *)buffer; pinmodel = (mdl_t *)datapointer; @@ -1278,8 +1259,8 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend) dpsnprintf (name, sizeof(name), "%s_%i_%i", loadmodel->name, i, j); else dpsnprintf (name, sizeof(name), "%s_%i", loadmodel->name, i); - if (!Mod_LoadTextureFromQ3Shader(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, name, false, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS)) - Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, R_SkinFrame_LoadInternalQuake(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight)); + if (!Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, loadmodel->data_textures + totalskins * loadmodel->num_surfaces, name, false, false, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, MATERIALFLAG_WALL)) + Mod_LoadCustomMaterial(loadmodel->mempool, loadmodel->data_textures + totalskins * loadmodel->num_surfaces, name, SUPERCONTENTS_SOLID, MATERIALFLAG_WALL, R_SkinFrame_LoadInternalQuake(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP, true, r_fullbrights.integer, (unsigned char *)datapointer, skinwidth, skinheight)); datapointer += skinwidth * skinheight; totalskins++; } @@ -1287,8 +1268,12 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend) // check for skins that don't exist in the model, but do exist as external images // (this was added because yummyluv kept pestering me about support for it) // TODO: support shaders here? - while ((tempskinframe = R_SkinFrame_LoadExternal(va(vabuf, sizeof(vabuf), "%s_%i", loadmodel->name, loadmodel->numskins), (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, false))) + for (;;) { + dpsnprintf(name, sizeof(name), "%s_%i", loadmodel->name, loadmodel->numskins); + tempskinframe = R_SkinFrame_LoadExternal(name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, false, false); + if (!tempskinframe) + break; // expand the arrays to make room tempskinscenes = loadmodel->skinscenes; loadmodel->skinscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, (loadmodel->numskins + 1) * sizeof(animscene_t)); @@ -1301,7 +1286,7 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend) Mem_Free(tempaliasskins); // store the info about the new skin - Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, tempskinframe); + Mod_LoadCustomMaterial(loadmodel->mempool, loadmodel->data_textures + totalskins * loadmodel->num_surfaces, name, SUPERCONTENTS_SOLID, MATERIALFLAG_WALL, tempskinframe); strlcpy(loadmodel->skinscenes[loadmodel->numskins].name, name, sizeof(loadmodel->skinscenes[loadmodel->numskins].name)); loadmodel->skinscenes[loadmodel->numskins].firstframe = totalskins; loadmodel->skinscenes[loadmodel->numskins].framecount = 1; @@ -1330,9 +1315,10 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend) if(mod_alias_force_animated.string[0]) loadmodel->surfmesh.isanimated = mod_alias_force_animated.integer != 0; + // Always make a BIH for the first frame, we can use it where possible. + Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); if (!loadmodel->surfmesh.isanimated) { - Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); loadmodel->TraceBox = Mod_CollisionBIH_TraceBox; loadmodel->TraceBrush = Mod_CollisionBIH_TraceBrush; loadmodel->TraceLine = Mod_CollisionBIH_TraceLine; @@ -1465,7 +1451,7 @@ void Mod_IDP2_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->num_texturesperskin = loadmodel->num_surfaces; loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t)); for (i = 0;i < loadmodel->numskins;i++, inskin += MD2_SKINNAME) - Mod_LoadTextureFromQ3Shader(loadmodel->data_textures + i * loadmodel->num_surfaces, inskin, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS); + Mod_LoadTextureFromQ3Shader(loadmodel->mempool, loadmodel->name, loadmodel->data_textures + i * loadmodel->num_surfaces, inskin, true, true, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PICMIP | TEXF_COMPRESS, MATERIALFLAG_WALL); } else { @@ -1474,7 +1460,7 @@ void Mod_IDP2_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins; loadmodel->num_texturesperskin = loadmodel->num_surfaces; loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t)); - Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures, NULL); + Mod_LoadCustomMaterial(loadmodel->mempool, loadmodel->data_textures, loadmodel->name, SUPERCONTENTS_SOLID, MATERIALFLAG_WALL, R_SkinFrame_LoadMissing()); } loadmodel->skinscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins); @@ -1601,9 +1587,10 @@ void Mod_IDP2_Load(dp_model_t *mod, void *buffer, void *bufferend) surface->num_firstvertex = 0; surface->num_vertices = loadmodel->surfmesh.num_vertices; + // Always make a BIH for the first frame, we can use it where possible. + Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); if (!loadmodel->surfmesh.isanimated) { - Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); loadmodel->TraceBox = Mod_CollisionBIH_TraceBox; loadmodel->TraceBrush = Mod_CollisionBIH_TraceBrush; loadmodel->TraceLine = Mod_CollisionBIH_TraceLine; @@ -1796,9 +1783,10 @@ void Mod_IDP3_Load(dp_model_t *mod, void *buffer, void *bufferend) if(mod_alias_force_animated.string[0]) loadmodel->surfmesh.isanimated = mod_alias_force_animated.integer != 0; + // Always make a BIH for the first frame, we can use it where possible. + Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); if (!loadmodel->surfmesh.isanimated) { - Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); loadmodel->TraceBox = Mod_CollisionBIH_TraceBox; loadmodel->TraceBrush = Mod_CollisionBIH_TraceBrush; loadmodel->TraceLine = Mod_CollisionBIH_TraceLine; @@ -2196,9 +2184,10 @@ void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) if(mod_alias_force_animated.string[0]) loadmodel->surfmesh.isanimated = mod_alias_force_animated.integer != 0; + // Always make a BIH for the first frame, we can use it where possible. + Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); if (!loadmodel->surfmesh.isanimated) { - Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); loadmodel->TraceBox = Mod_CollisionBIH_TraceBox; loadmodel->TraceBrush = Mod_CollisionBIH_TraceBrush; loadmodel->TraceLine = Mod_CollisionBIH_TraceLine; @@ -2574,9 +2563,10 @@ void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) if(mod_alias_force_animated.string[0]) loadmodel->surfmesh.isanimated = mod_alias_force_animated.integer != 0; + // Always make a BIH for the first frame, we can use it where possible. + Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); if (!loadmodel->surfmesh.isanimated) { - Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); loadmodel->TraceBox = Mod_CollisionBIH_TraceBox; loadmodel->TraceBrush = Mod_CollisionBIH_TraceBrush; loadmodel->TraceLine = Mod_CollisionBIH_TraceLine; @@ -3252,9 +3242,10 @@ void Mod_PSKMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) if(mod_alias_force_animated.string[0]) loadmodel->surfmesh.isanimated = mod_alias_force_animated.integer != 0; + // Always make a BIH for the first frame, we can use it where possible. + Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); if (!loadmodel->surfmesh.isanimated) { - Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); loadmodel->TraceBox = Mod_CollisionBIH_TraceBox; loadmodel->TraceBrush = Mod_CollisionBIH_TraceBrush; loadmodel->TraceLine = Mod_CollisionBIH_TraceLine; @@ -4018,9 +4009,10 @@ void Mod_INTERQUAKEMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend) if (!header.ofs_bounds) Mod_Alias_CalculateBoundingBox(); - if (!loadmodel->surfmesh.isanimated && loadmodel->surfmesh.num_triangles >= 1) + // Always make a BIH for the first frame, we can use it where possible. + Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); + if (!loadmodel->surfmesh.isanimated) { - Mod_MakeCollisionBIH(loadmodel, true, &loadmodel->collision_bih); loadmodel->TraceBox = Mod_CollisionBIH_TraceBox; loadmodel->TraceBrush = Mod_CollisionBIH_TraceBrush; loadmodel->TraceLine = Mod_CollisionBIH_TraceLine;