}
}
-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)
+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;
- if (model->surfmesh.num_vertices > 1024)
- vertex3f = (float *)Mem_Alloc(tempmempool, model->surfmesh.num_vertices * sizeof(float[3]));
+ trace->skipsupercontentsmask = skipsupercontentsmask;
+ 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)
+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;
{
VectorAdd(start, boxmins, shiftstart);
VectorAdd(end, boxmins, shiftend);
- Mod_MDLMD2MD3_TraceLine(model, frameblend, skeleton, trace, shiftstart, shiftend, hitsupercontentsmask);
+ 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;
}
}
-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;
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;
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);
}
}
float *vertst;
int *vertonseam, *vertremap;
skinfile_t *skinfiles;
- char vabuf[1024];
datapointer = (unsigned char *)buffer;
pinmodel = (mdl_t *)datapointer;
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++;
}
// 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));
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;
loadmodel->skinscenes[loadmodel->numskins].loop = true;
//increase skin counts
+ loadmodel->num_textures++;
loadmodel->numskins++;
totalskins++;
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;
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
{
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);
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;
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;
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;
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;
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;
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;