q1bsp traceline code now hits surfaces, this comes at a performance cost
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 1 Mar 2011 18:16:44 +0000 (18:16 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 1 Mar 2011 18:16:44 +0000 (18:16 +0000)
but was necessary for bouncegrid to acquire color of surfaces, it also
means that quakec code can now use trace_dphittexture on q1bsp maps
disabled bouncegrid on fullbright surfaces (fixes bright coronas bug)
tweaked bouncegrid settings again now that texture color works

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

15 files changed:
cl_collision.c
cl_collision.h
cl_input.c
cl_main.c
cl_particles.c
clvm_cmds.c
collision.c
collision.h
gl_rmain.c
model_brush.c
model_shared.h
r_explosion.c
r_shadow.c
sv_phys.c
view.c

index 513aa13..57b6b4b 100644 (file)
@@ -435,9 +435,9 @@ CL_TraceLine
 ==================
 */
 #ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
-trace_t CL_TraceLine(const vec3_t start, const vec3_t pEnd, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
+trace_t CL_TraceLine(const vec3_t start, const vec3_t pEnd, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces)
 #else
-trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities)
+trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces)
 #endif
 {
        int i, bodysupercontents;
@@ -492,7 +492,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
 #endif
 
        // clip to world
-       Collision_ClipLineToWorld(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask);
+       Collision_ClipLineToWorld(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask, hitsurfaces);
        cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog ? prog->edicts : NULL;
@@ -541,7 +541,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                        entity_render_t *ent = &cl.entities[cl.brushmodel_entities[i]].render;
                        if (!BoxesOverlap(clipboxmins, clipboxmaxs, ent->mins, ent->maxs))
                                continue;
-                       Collision_ClipLineToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask);
+                       Collision_ClipLineToGenericEntity(&trace, ent->model, ent->frameblend, ent->skeleton, vec3_origin, vec3_origin, 0, &ent->matrix, &ent->inversematrix, start, end, hitsupercontentsmask, hitsurfaces);
                        if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
                                *hitnetworkentity = cl.brushmodel_entities[i];
                        Collision_CombineTraces(&cliptrace, &trace, NULL, true);
@@ -587,7 +587,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                                continue;
                        Matrix4x4_CreateTranslate(&entmatrix, origin[0], origin[1], origin[2]);
                        Matrix4x4_CreateTranslate(&entinversematrix, -origin[0], -origin[1], -origin[2]);
-                       Collision_ClipLineToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, end, hitsupercontentsmask);
+                       Collision_ClipLineToGenericEntity(&trace, NULL, NULL, NULL, cl.playerstandmins, cl.playerstandmaxs, SUPERCONTENTS_BODY, &entmatrix, &entinversematrix, start, end, hitsupercontentsmask, hitsurfaces);
                        if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
                                *hitnetworkentity = i;
                        Collision_CombineTraces(&cliptrace, &trace, NULL, false);
@@ -651,7 +651,7 @@ skipnetworkplayers:
                if (type == MOVE_MISSILE && (int)touch->fields.client->flags & FL_MONSTER)
                        Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.client->mins, touch->fields.client->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
                else
-                       Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.client->mins, touch->fields.client->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask);
+                       Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.client->mins, touch->fields.client->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, hitsurfaces);
 
                if (cliptrace.realfraction > trace.realfraction && hitnetworkentity)
                        *hitnetworkentity = 0;
@@ -712,7 +712,7 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
                if (VectorCompare(start, pEnd))
                        trace = CL_TracePoint(shiftstart, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
                else
-                       trace = CL_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities);
+                       trace = CL_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities, false);
                VectorSubtract(trace.endpos, mins, trace.endpos);
                return trace;
        }
index dbf3dd7..27ce51b 100644 (file)
@@ -11,7 +11,7 @@ dp_model_t *CL_GetModelFromEdict(prvm_edict_t *ed);
 void CL_LinkEdict(prvm_edict_t *ent);
 int CL_GenericHitSuperContentsMask(const prvm_edict_t *edict);
 trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
-trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
+trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces);
 trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
 #define CL_PointSuperContents(point) (CL_TracePoint((point), sv_gameplayfix_swiminbmodels.integer ? MOVE_NOMONSTERS : MOVE_WORLDONLY, NULL, 0, true, false, NULL, false).startsupercontents)
 
index 256a2f7..1a0704d 100644 (file)
@@ -1349,7 +1349,7 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
                                if (cls.protocol == PROTOCOL_QUAKEWORLD)
                                        trace = CL_TraceBox(neworigin2, s->mins, s->maxs, neworigin3, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false);
                                else
-                                       trace = CL_TraceLine(neworigin2, neworigin3, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false);
+                                       trace = CL_TraceLine(neworigin2, neworigin3, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false, false);
                                if (trace.fraction == 1 && !trace.startsolid)
                                        friction *= cl.movevars_edgefriction;
                        }
index 0d340a8..0963ce9 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -1462,7 +1462,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                trace_t trace;
                matrix4x4_t tempmatrix;
                Matrix4x4_Transform(&e->render.matrix, muzzleflashorigin, v2);
-               trace = CL_TraceLine(origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, NULL, false);
+               trace = CL_TraceLine(origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, NULL, false, false);
                Matrix4x4_Normalize(&tempmatrix, &e->render.matrix);
                Matrix4x4_SetOrigin(&tempmatrix, trace.endpos[0], trace.endpos[1], trace.endpos[2]);
                Matrix4x4_Scale(&tempmatrix, 150, 1);
index 187934c..328ab48 100644 (file)
@@ -682,7 +682,7 @@ particle_t *CL_NewParticle(const vec3_t sortorigin, unsigned short ptypeindex, i
                part->typeindex = pt_spark;
                part->bounce = 0;
                VectorMA(part->org, lifetime, part->vel, endvec);
-               trace = CL_TraceLine(part->org, endvec, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_LIQUIDSMASK, true, false, NULL, false);
+               trace = CL_TraceLine(part->org, endvec, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_LIQUIDSMASK, true, false, NULL, false, false);
                part->die = cl.time + lifetime * trace.fraction;
                part2 = CL_NewParticle(endvec, pt_raindecal, pcolor1, pcolor2, tex_rainsplash, part->size, part->size * 20, part->alpha, part->alpha / 0.4, 0, 0, trace.endpos[0] + trace.plane.normal[0], trace.endpos[1] + trace.plane.normal[1], trace.endpos[2] + trace.plane.normal[2], trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2], 0, 0, 0, 0, pqualityreduction, 0, 1, PBLEND_ADD, PARTICLE_ORIENTED_DOUBLESIDED, -1, -1, -1, 1, 1, 0, 0, NULL);
                if (part2)
@@ -812,7 +812,7 @@ void CL_SpawnDecalParticleForPoint(const vec3_t org, float maxdist, float size,
        {
                VectorRandom(org2);
                VectorMA(org, maxdist, org2, org2);
-               trace = CL_TraceLine(org, org2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, &hitent, false);
+               trace = CL_TraceLine(org, org2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, &hitent, false, true);
                // take the closest trace result that doesn't end up hitting a NOMARKS
                // surface (sky for example)
                if (bestfrac > trace.fraction && !(trace.hitq3surfaceflags & Q3SURFACEFLAG_NOMARKS))
@@ -1693,7 +1693,7 @@ void CL_ParticleExplosion (const vec3_t org)
                                        {
                                                VectorRandom(v2);
                                                VectorMA(org, 128, v2, v);
-                                               trace = CL_TraceLine(org, v, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
+                                               trace = CL_TraceLine(org, v, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, false);
                                        }
                                        while (k < 16 && trace.fraction < 0.1f);
                                        VectorSubtract(trace.endpos, org, v2);
@@ -2797,7 +2797,7 @@ void R_DrawParticles (void)
 //                             if (p->bounce && cl.time >= p->delayedcollisions)
                                if (p->bounce && cl_particles_collisions.integer && VectorLength(p->vel))
                                {
-                                       trace = CL_TraceLine(oldorg, p->org, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | ((p->typeindex == pt_rain || p->typeindex == pt_snow) ? SUPERCONTENTS_LIQUIDSMASK : 0), true, false, &hitent, false);
+                                       trace = CL_TraceLine(oldorg, p->org, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | ((p->typeindex == pt_rain || p->typeindex == pt_snow) ? SUPERCONTENTS_LIQUIDSMASK : 0), true, false, &hitent, false, false);
                                        // if the trace started in or hit something of SUPERCONTENTS_NODROP
                                        // or if the trace hit something flagged as NOIMPACT
                                        // then remove the particle
index 74326a4..2beea3c 100644 (file)
@@ -265,7 +265,7 @@ static void VM_CL_traceline (void)
        if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
                PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
-       trace = CL_TraceLine(v1, v2, move, ent, CL_GenericHitSuperContentsMask(ent), CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true);
+       trace = CL_TraceLine(v1, v2, move, ent, CL_GenericHitSuperContentsMask(ent), CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true, false);
 
        CL_VM_SetTraceGlobals(&trace, svent);
 //     R_TimeReport("traceline");
@@ -608,7 +608,7 @@ realcheck:
        start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
        start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
        stop[2] = start[2] - 2*sv_stepheight.value;
-       trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+       trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true, false);
 
        if (trace.fraction == 1.0)
                return;
@@ -622,7 +622,7 @@ realcheck:
                        start[0] = stop[0] = x ? maxs[0] : mins[0];
                        start[1] = stop[1] = y ? maxs[1] : mins[1];
 
-                       trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+                       trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true, false);
 
                        if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
                                bottom = trace.endpos[2];
@@ -3394,7 +3394,7 @@ realcheck:
        start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
        start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
        stop[2] = start[2] - 2*sv_stepheight.value;
-       trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), true, false, NULL, true);
+       trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), true, false, NULL, true, false);
 
        if (trace.fraction == 1.0)
                return false;
@@ -3407,7 +3407,7 @@ realcheck:
                        start[0] = stop[0] = x ? maxs[0] : mins[0];
                        start[1] = stop[1] = y ? maxs[1] : mins[1];
 
-                       trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), true, false, NULL, true);
+                       trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), true, false, NULL, true, false);
 
                        if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
                                bottom = trace.endpos[2];
index 3c069ca..5e0e017 100644 (file)
@@ -1717,7 +1717,7 @@ void Collision_ClipToWorld(trace_t *trace, dp_model_t *model, const vec3_t start
        VectorLerp(start, trace->fraction, end, trace->endpos);
 }
 
-void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
+void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask, qboolean hitsurfaces)
 {
        float starttransformed[3], endtransformed[3];
 
@@ -1730,7 +1730,9 @@ void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const
        Con_Printf("trans(%f %f %f -> %f %f %f, %f %f %f -> %f %f %f)", start[0], start[1], start[2], starttransformed[0], starttransformed[1], starttransformed[2], end[0], end[1], end[2], endtransformed[0], endtransformed[1], endtransformed[2]);
 #endif
 
-       if (model && model->TraceLine)
+       if (model && model->TraceLineAgainstSurfaces && hitsurfaces)
+               model->TraceLineAgainstSurfaces(model, frameblend, skeleton, trace, starttransformed, endtransformed, hitsupercontentsmask);
+       else if (model && model->TraceLine)
                model->TraceLine(model, frameblend, skeleton, trace, starttransformed, endtransformed, hitsupercontentsmask);
        else
                Collision_ClipTrace_Box(trace, bodymins, bodymaxs, starttransformed, vec3_origin, vec3_origin, endtransformed, hitsupercontentsmask, bodysupercontents, 0, NULL);
@@ -1743,11 +1745,13 @@ void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const
        Matrix4x4_TransformPositivePlane(matrix, trace->plane.normal[0], trace->plane.normal[1], trace->plane.normal[2], trace->plane.dist, trace->plane.normal);
 }
 
-void Collision_ClipLineToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontents)
+void Collision_ClipLineToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontents, qboolean hitsurfaces)
 {
        memset(trace, 0, sizeof(*trace));
        trace->fraction = trace->realfraction = 1;
-       if (model && model->TraceLine)
+       if (model && model->TraceLineAgainstSurfaces && hitsurfaces)
+               model->TraceLineAgainstSurfaces(model, NULL, NULL, trace, start, end, hitsupercontents);
+       else if (model && model->TraceLine)
                model->TraceLine(model, NULL, NULL, trace, start, end, hitsupercontents);
        trace->fraction = bound(0, trace->fraction, 1);
        trace->realfraction = bound(0, trace->realfraction, 1);
index f541de4..1b41f05 100644 (file)
@@ -150,11 +150,11 @@ void Collision_TraceBrushTriangleFloat(trace_t *trace, const colbrushf_t *thisbr
 struct frameblend_s;
 struct skeleton_s;
 void Collision_ClipToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask);
-void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask);
+void Collision_ClipLineToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, const vec3_t end, int hitsupercontentsmask, qboolean hitsurfaces);
 void Collision_ClipPointToGenericEntity(trace_t *trace, dp_model_t *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, const vec3_t bodymins, const vec3_t bodymaxs, int bodysupercontents, matrix4x4_t *matrix, matrix4x4_t *inversematrix, const vec3_t start, int hitsupercontentsmask);
 // like above but does not do a transform and does nothing if model is NULL
 void Collision_ClipToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontents);
-void Collision_ClipLineToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontents);
+void Collision_ClipLineToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, const vec3_t end, int hitsupercontents, qboolean hitsurfaces);
 void Collision_ClipPointToWorld(trace_t *trace, dp_model_t *model, const vec3_t start, int hitsupercontents);
 // combines data from two traces:
 // merges contents flags, startsolid, allsolid, inwater
index 5d6cf2c..8c5fc54 100644 (file)
@@ -5005,8 +5005,6 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_REFLECTION;
                if (rsurface.texture->reflectmasktexture)
                        permutation |= SHADERPERMUTATION_REFLECTCUBE;
-               if (r_shadow_bouncegridtexture)
-                       permutation |= SHADERPERMUTATION_BOUNCEGRID;
                GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
                allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
        }
index df58532..16d1c74 100644 (file)
@@ -1293,6 +1293,189 @@ void Mod_Q1BSP_LightPoint(dp_model_t *model, const vec3_t p, vec3_t ambientcolor
        Mod_Q1BSP_LightPoint_RecursiveBSPNode(model, ambientcolor, diffusecolor, diffusenormal, model->brush.data_nodes + model->brushq1.hulls[0].firstclipnode, p[0], p[1], p[2] + 0.125, p[2] - 65536);
 }
 
+static texture_t *Mod_Q1BSP_TraceLineAgainstSurfacesFindTextureOnNode(RecursiveHullCheckTraceInfo_t *t, const dp_model_t *model, const mnode_t *node, double mid[3])
+{
+       int i;
+       int j;
+       int k;
+       int axis = node->plane->type;
+       const msurface_t *surface;
+       float normal[3];
+       float v0[3];
+       float v1[3];
+       float edgedir[3];
+       float edgenormal[3];
+       float p[3];
+       VectorCopy(mid, p);
+       surface = model->data_surfaces + node->firstsurface;
+       for (i = 0;i < node->numsurfaces;i++, surface++)
+       {
+               if (axis < 3)
+               {
+                       if (mid[axis] < surface->mins[axis] || mid[axis] > surface->maxs[axis])
+                               continue;
+               }
+               else
+               {
+                       if (!BoxesOverlap(mid, mid, surface->mins, surface->maxs))
+                               continue;
+               }
+               if (!(t->trace->hitsupercontentsmask & surface->texture->supercontents))
+                       continue;
+               VectorCopy(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex, normal);
+               for (j = 0, k = surface->num_vertices - 1;j < surface->num_vertices;k = j, j++)
+               {
+                       VectorCopy(model->surfmesh.data_vertex3f + 3 * (surface->num_firstvertex + k), v0);
+                       VectorCopy(model->surfmesh.data_vertex3f + 3 * (surface->num_firstvertex + j), v1);
+                       VectorSubtract(v0, v1, edgedir);
+                       CrossProduct(edgedir, normal, edgenormal);
+                       if (DotProduct(edgenormal, p) > DotProduct(edgenormal, v0))
+                               break;
+               }
+               if (j == surface->num_vertices)
+               {
+                       // hit this surface
+                       return surface->texture->currentframe;
+               }
+       }
+       return NULL;
+}
+
+static int Mod_Q1BSP_TraceLineAgainstSurfacesRecursiveBSPNode(RecursiveHullCheckTraceInfo_t *t, const dp_model_t *model, const mnode_t *node, const double p1[3], const double p2[3])
+{
+       const mplane_t *plane;
+       double t1, t2;
+       int side;
+       double midf, mid[3];
+       const mleaf_t *leaf;
+
+       while (node->plane)
+       {
+               plane = node->plane;
+               if (plane->type < 3)
+               {
+                       t1 = p1[plane->type] - plane->dist;
+                       t2 = p2[plane->type] - plane->dist;
+               }
+               else
+               {
+                       t1 = DotProduct (plane->normal, p1) - plane->dist;
+                       t2 = DotProduct (plane->normal, p2) - plane->dist;
+               }
+               if (t1 < 0)
+               {
+                       if (t2 < 0)
+                       {
+                               node = node->children[1];
+                               continue;
+                       }
+                       side = 1;
+               }
+               else
+               {
+                       if (t2 >= 0)
+                       {
+                               node = node->children[0];
+                               continue;
+                       }
+                       side = 0;
+               }
+
+               // the line intersects, find intersection point
+               // LordHavoc: this uses the original trace for maximum accuracy
+               if (plane->type < 3)
+               {
+                       t1 = t->start[plane->type] - plane->dist;
+                       t2 = t->end[plane->type] - plane->dist;
+               }
+               else
+               {
+                       t1 = DotProduct (plane->normal, t->start) - plane->dist;
+                       t2 = DotProduct (plane->normal, t->end) - plane->dist;
+               }
+       
+               midf = t1 / (t1 - t2);
+               VectorMA(t->start, midf, t->dist, mid);
+
+               // recurse both sides, front side first, return if we hit a surface
+               if (Mod_Q1BSP_TraceLineAgainstSurfacesRecursiveBSPNode(t, model, node->children[side], p1, mid) == HULLCHECKSTATE_DONE)
+                       return HULLCHECKSTATE_DONE;
+
+               t->trace->hittexture = Mod_Q1BSP_TraceLineAgainstSurfacesFindTextureOnNode(t, model, node, mid);
+               if (!t->trace->hittexture)
+                       return Mod_Q1BSP_TraceLineAgainstSurfacesRecursiveBSPNode(t, model, node->children[side ^ 1], mid, p2);
+
+               // we hit a surface, this is the impact point...
+               if (side)
+               {
+                       t->trace->plane.dist = -plane->dist;
+                       VectorNegate (plane->normal, t->trace->plane.normal);
+               }
+               else
+               {
+                       t->trace->plane.dist = plane->dist;
+                       VectorCopy (plane->normal, t->trace->plane.normal);
+               }
+       
+               // calculate the true fraction
+               t->trace->realfraction = midf;
+       
+               // calculate the return fraction which is nudged off the surface a bit
+               midf = (t1 - DIST_EPSILON) / (t1 - t2);
+               t->trace->fraction = bound(0, midf, 1);
+       
+               if (collision_prefernudgedfraction.integer)
+                       t->trace->realfraction = t->trace->fraction;
+
+               t->trace->hitq3surfaceflags = t->trace->hittexture->surfaceflags;
+               t->trace->hitsupercontents = t->trace->hittexture->supercontents;
+
+               return HULLCHECKSTATE_DONE;
+       }
+       leaf = (const mleaf_t *)node;
+       side = Mod_Q1BSP_SuperContentsFromNativeContents(NULL, leaf->contents);
+       if (!t->trace->startfound)
+       {
+               t->trace->startfound = true;
+               t->trace->startsupercontents |= side;
+       }
+       if (side & SUPERCONTENTS_LIQUIDSMASK)
+               t->trace->inwater = true;
+       if (side == 0)
+               t->trace->inopen = true;
+       if (side & t->trace->hitsupercontentsmask)
+       {
+               // if the first leaf is solid, set startsolid
+               if (t->trace->allsolid)
+                       t->trace->startsolid = true;
+               return HULLCHECKSTATE_SOLID;
+       }
+       else
+       {
+               t->trace->allsolid = false;
+               return HULLCHECKSTATE_EMPTY;
+       }
+}
+
+static void Mod_Q1BSP_TraceLineAgainstSurfaces(struct model_s *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
+{
+       RecursiveHullCheckTraceInfo_t rhc;
+
+       memset(&rhc, 0, sizeof(rhc));
+       memset(trace, 0, sizeof(trace_t));
+       rhc.trace = trace;
+       rhc.trace->hitsupercontentsmask = hitsupercontentsmask;
+       rhc.trace->fraction = 1;
+       rhc.trace->realfraction = 1;
+       rhc.trace->allsolid = true;
+       rhc.hull = &model->brushq1.hulls[0]; // 0x0x0
+       VectorCopy(start, rhc.start);
+       VectorCopy(end, rhc.end);
+       VectorSubtract(rhc.end, rhc.start, rhc.dist);
+       Mod_Q1BSP_TraceLineAgainstSurfacesRecursiveBSPNode(&rhc, model, model->brush.data_nodes + rhc.hull->firstclipnode, rhc.start, rhc.end);
+       VectorMA(rhc.start, rhc.trace->fraction, rhc.dist, rhc.trace->endpos);
+}
+
 static void Mod_Q1BSP_DecompressVis(const unsigned char *in, const unsigned char *inend, unsigned char *out, unsigned char *outend)
 {
        int c;
@@ -3449,6 +3632,8 @@ static int Mod_Q1BSP_CreateShadowMesh(dp_model_t *mod)
        return numshadowmeshtriangles;
 }
 
+void Mod_CollisionBIH_TraceLineAgainstSurfaces(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);
+
 void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
 {
        int i, j, k;
@@ -3506,9 +3691,10 @@ void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
 
        mod->soundfromcenter = true;
        mod->TraceBox = Mod_Q1BSP_TraceBox;
-       mod->TraceLine = Mod_Q1BSP_TraceLine;
+       mod->TraceLine = Mod_Q1BSP_TraceLineAgainstSurfaces; // LordHavoc: use the surface-hitting version of TraceLine in all cases
        mod->TracePoint = Mod_Q1BSP_TracePoint;
        mod->PointSuperContents = Mod_Q1BSP_PointSuperContents;
+       mod->TraceLineAgainstSurfaces = Mod_Q1BSP_TraceLineAgainstSurfaces;
        mod->brush.TraceLineOfSight = Mod_Q1BSP_TraceLineOfSight;
        mod->brush.SuperContentsFromNativeContents = Mod_Q1BSP_SuperContentsFromNativeContents;
        mod->brush.NativeContentsFromSuperContents = Mod_Q1BSP_NativeContentsFromSuperContents;
@@ -3770,6 +3956,7 @@ void Mod_Q1BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
                        mod->TraceLine = Mod_CollisionBIH_TraceLine;
                        mod->TraceBox = Mod_CollisionBIH_TraceBox;
                        mod->TraceBrush = Mod_CollisionBIH_TraceBrush;
+                       mod->TraceLineAgainstSurfaces = Mod_CollisionBIH_TraceLineAgainstSurfaces;
                }
 
                // generate VBOs and other shared data before cloning submodels
@@ -5822,7 +6009,7 @@ static void Mod_CollisionBIH_TracePoint_RecursiveBIHNode(trace_t *trace, dp_mode
        }
 }
 
-static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model_t *model, int nodenum, const vec3_t start, const vec3_t end, const vec3_t linestart, const vec3_t lineend)
+static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model_t *model, bih_t *bih, int nodenum, const vec3_t start, const vec3_t end, const vec3_t linestart, const vec3_t lineend)
 {
        const bih_leaf_t *leaf;
        const bih_node_t *node;
@@ -5851,7 +6038,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
        segmentmaxs[2] = max(start[2], end[2]);
        while (nodenum >= 0)
        {
-               node = model->collision_bih.nodes + nodenum;
+               node = bih->nodes + nodenum;
 #if 0
                if (!BoxesOverlap(segmentmins, segmentmaxs, node->mins, node->maxs))
                        return;
@@ -5861,7 +6048,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
                if (segmentmins[axis] <= node->backmax)
                {
                        if (segmentmaxs[axis] >= node->frontmin)
-                               Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                               Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
                        nodenum = node->back;
                }
                else if (segmentmaxs[axis] >= node->frontmin)
@@ -5886,7 +6073,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
                if (sideflags & 12)
                {
                        if ((sideflags & 3) != 3)
-                               Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                               Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
                        nodenum = node->back;
                }
                else if ((sideflags & 3) != 3)
@@ -5933,7 +6120,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
                        return; // line falls in gap between children
                case 4:
                        // start end start END
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
 #ifdef BIHLINECLIP
                        backfrac = backdist1 / (backdist1 - backdist2);
                        VectorLerp(start, backfrac, end, newend); end = newend;
@@ -5951,7 +6138,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
 #ifdef BIHLINECLIP
                        frontfrac = frontdist1 / (frontdist1 - frontdist2);
                        VectorLerp(start, frontfrac, end, clipped);
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, clipped, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, clipped, end, linestart, lineend);
                        backfrac = backdist1 / (backdist1 - backdist2);
                        VectorLerp(start, backfrac, end, newend); end = newend;
                        segmentmins[0] = min(start[0], end[0]);
@@ -5961,7 +6148,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
                        segmentmaxs[1] = max(start[1], end[1]);
                        segmentmaxs[2] = max(start[2], end[2]);
 #else
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
 #endif
                        nodenum = node->back;
                        break;
@@ -5970,7 +6157,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
 #ifdef BIHLINECLIP
                        frontfrac = frontdist1 / (frontdist1 - frontdist2);
                        VectorLerp(start, frontfrac, end, clipped);
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, clipped, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, clipped, linestart, lineend);
                        backfrac = backdist1 / (backdist1 - backdist2);
                        VectorLerp(start, backfrac, end, newend); end = newend;
                        segmentmins[0] = min(start[0], end[0]);
@@ -5980,7 +6167,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
                        segmentmaxs[1] = max(start[1], end[1]);
                        segmentmaxs[2] = max(start[2], end[2]);
 #else
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
 #endif
                        nodenum = node->back;
                        break;
@@ -6000,7 +6187,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
                        break;
                case 8:
                        // start end START end
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
 #ifdef BIHLINECLIP
                        backfrac = backdist1 / (backdist1 - backdist2);
                        VectorLerp(start, backfrac, end, newstart); start = newstart;
@@ -6018,7 +6205,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
 #ifdef BIHLINECLIP
                        frontfrac = frontdist1 / (frontdist1 - frontdist2);
                        VectorLerp(start, frontfrac, end, clipped);
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, clipped, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, clipped, end, linestart, lineend);
                        backfrac = backdist1 / (backdist1 - backdist2);
                        VectorLerp(start, backfrac, end, newstart); start = newstart;
                        segmentmins[0] = min(start[0], end[0]);
@@ -6028,7 +6215,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
                        segmentmaxs[1] = max(start[1], end[1]);
                        segmentmaxs[2] = max(start[2], end[2]);
 #else
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
 #endif
                        nodenum = node->back;
                        break;
@@ -6037,7 +6224,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
 #ifdef BIHLINECLIP
                        frontfrac = frontdist1 / (frontdist1 - frontdist2);
                        VectorLerp(start, frontfrac, end, clipped);
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, clipped, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, clipped, linestart, lineend);
                        backfrac = backdist1 / (backdist1 - backdist2);
                        VectorLerp(start, backfrac, end, newstart); start = newstart;
                        segmentmins[0] = min(start[0], end[0]);
@@ -6047,7 +6234,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
                        segmentmaxs[1] = max(start[1], end[1]);
                        segmentmaxs[2] = max(start[2], end[2]);
 #else
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
 #endif
                        nodenum = node->back;
                        break;
@@ -6067,7 +6254,7 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
                        break;
                case 12:
                        // start end start end
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
                        nodenum = node->back;
                        break;
                case 13:
@@ -6075,9 +6262,9 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
 #ifdef BIHLINECLIP
                        frontfrac = frontdist1 / (frontdist1 - frontdist2);
                        VectorLerp(start, frontfrac, end, clipped);
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, clipped, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, clipped, end, linestart, lineend);
 #else
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
 #endif
                        nodenum = node->back;
                        break;
@@ -6086,9 +6273,9 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
 #ifdef BIHLINECLIP
                        frontfrac = frontdist1 / (frontdist1 - frontdist2);
                        VectorLerp(start, frontfrac, end, clipped);
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, clipped, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, clipped, linestart, lineend);
 #else
-                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, node->front, start, end, linestart, lineend);
+                       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, bih, node->front, start, end, linestart, lineend);
 #endif
                        nodenum = node->back;
                        break;
@@ -6100,9 +6287,9 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model
 #endif
 #endif
        }
-       if (!model->collision_bih.leafs)
+       if (!bih->leafs)
                return;
-       leaf = model->collision_bih.leafs + (-1-nodenum);
+       leaf = bih->leafs + (-1-nodenum);
 #if 1
        if (!BoxesOverlap(segmentmins, segmentmaxs, leaf->mins, leaf->maxs))
                return;
@@ -6209,7 +6396,7 @@ void Mod_CollisionBIH_TraceLine(dp_model_t *model, const frameblend_t *frameblen
        trace->fraction = 1;
        trace->realfraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
-       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, model->collision_bih.rootnode, start, end, start, end);
+       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, &model->collision_bih, model->collision_bih.rootnode, start, end, start, end);
 }
 
 void Mod_CollisionBIH_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)
@@ -6584,7 +6771,7 @@ static void Mod_Q3BSP_TraceLine(dp_model_t *model, const frameblend_t *frameblen
        segmentmaxs[1] = max(start[1], end[1]) + 1;
        segmentmaxs[2] = max(start[2], end[2]) + 1;
        if (mod_collision_bih.integer)
-               Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, model->collision_bih.rootnode, start, end, start, end);
+               Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, &model->collision_bih, model->collision_bih.rootnode, start, end, start, end);
        else if (model->brush.submodel)
        {
                for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
@@ -6734,6 +6921,16 @@ static int Mod_Q3BSP_PointSuperContents(struct model_s *model, int frame, const
        return supercontents;
 }
 
+void Mod_CollisionBIH_TraceLineAgainstSurfaces(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)
+{
+       memset(trace, 0, sizeof(*trace));
+       trace->fraction = 1;
+       trace->realfraction = 1;
+       trace->hitsupercontentsmask = hitsupercontentsmask;
+       Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace, model, &model->render_bih, model->render_bih.rootnode, start, end, start, end);
+}
+
+
 bih_t *Mod_MakeCollisionBIH(dp_model_t *model, qboolean userendersurfaces, bih_t *out)
 {
        int j;
@@ -6968,6 +7165,7 @@ void Mod_Q3BSP_Load(dp_model_t *mod, void *buffer, void *bufferend)
        mod->TraceLine = Mod_Q3BSP_TraceLine;
        mod->TracePoint = Mod_Q3BSP_TracePoint;
        mod->PointSuperContents = Mod_Q3BSP_PointSuperContents;
+       mod->TraceLineAgainstSurfaces = Mod_CollisionBIH_TraceLineAgainstSurfaces;
        mod->brush.TraceLineOfSight = Mod_Q3BSP_TraceLineOfSight;
        mod->brush.SuperContentsFromNativeContents = Mod_Q3BSP_SuperContentsFromNativeContents;
        mod->brush.NativeContentsFromSuperContents = Mod_Q3BSP_NativeContentsFromSuperContents;
@@ -7266,6 +7464,7 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->TraceBrush = Mod_CollisionBIH_TraceBrush;
        loadmodel->TraceLine = Mod_CollisionBIH_TraceLine;
        loadmodel->TracePoint = Mod_CollisionBIH_TracePoint_Mesh;
+       loadmodel->TraceLineAgainstSurfaces = Mod_CollisionBIH_TraceLineAgainstSurfaces;
        loadmodel->PointSuperContents = Mod_CollisionBIH_PointSuperContents_Mesh;
        loadmodel->brush.TraceLineOfSight = NULL;
        loadmodel->brush.SuperContentsFromNativeContents = NULL;
@@ -8256,6 +8455,7 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->TraceLine = Mod_OBJ_TraceLine;
        loadmodel->TracePoint = Mod_OBJ_TracePoint;
        loadmodel->PointSuperContents = Mod_OBJ_PointSuperContents;
+       loadmodel->TraceLineAgainstSurfaces = Mod_OBJ_TraceLineAgainstSurfaces;
        loadmodel->brush.TraceLineOfSight = Mod_OBJ_TraceLineOfSight;
        loadmodel->brush.SuperContentsFromNativeContents = Mod_OBJ_SuperContentsFromNativeContents;
        loadmodel->brush.NativeContentsFromSuperContents = Mod_OBJ_NativeContentsFromSuperContents;
index 3247d0f..02c237f 100644 (file)
@@ -1022,6 +1022,8 @@ typedef struct model_s
        void (*TracePoint)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, int hitsupercontentsmask);
        // find the supercontents value at a point in this model
        int (*PointSuperContents)(struct model_s *model, int frame, const vec3_t point);
+       // trace a line against geometry in this model and report correct texture (used by r_shadow_bouncegrid)
+       void (*TraceLineAgainstSurfaces)(struct model_s *model, const struct frameblend_s *frameblend, const struct skeleton_s *skeleton, struct trace_s *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask);
        // fields belonging to some types of model
        model_sprite_t  sprite;
        model_brush_t   brush;
index 5ed5110..727f847 100644 (file)
@@ -189,7 +189,7 @@ void R_NewExplosion(const vec3_t org)
                                // clip start origin
                                if (e->clipping)
                                {
-                                       trace = CL_TraceLine(e->origin, e->vert[j], MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
+                                       trace = CL_TraceLine(e->origin, e->vert[j], MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, false);
                                        VectorCopy(trace.endpos, e->vert[i]);
                                }
                        }
@@ -245,7 +245,7 @@ static void R_MoveExplosion(explosion_t *e)
                        VectorMA(e->vert[i], frametime, e->vertvel[i], end);
                        if (e->clipping)
                        {
-                               trace = CL_TraceLine(e->vert[i], end, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
+                               trace = CL_TraceLine(e->vert[i], end, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, false);
                                if (trace.fraction < 1)
                                {
                                        // clip velocity against the wall
index 4dbdb53..35082a2 100644 (file)
@@ -323,11 +323,11 @@ cvar_t r_shadow_bouncegrid = {CVAR_SAVE, "r_shadow_bouncegrid", "0", "perform pa
 cvar_t r_shadow_bouncegrid_bounceanglediffuse = {CVAR_SAVE, "r_shadow_bouncegrid_bounceanglediffuse", "0", "use random bounce direction rather than true reflection, makes some corner areas dark"};
 cvar_t r_shadow_bouncegrid_dlightparticlemultiplier = {CVAR_SAVE, "r_shadow_bouncegrid_dlightparticlemultiplier", "0", "if set to a high value like 16 this can make dlights look great, but 0 is recommended for performance reasons"};
 cvar_t r_shadow_bouncegrid_hitmodels = {CVAR_SAVE, "r_shadow_bouncegrid_hitmodels", "0", "enables hitting character model geometry (SLOW)"};
-cvar_t r_shadow_bouncegrid_intensity = {CVAR_SAVE, "r_shadow_bouncegrid_intensity", "1", "overall brightness of bouncegrid texture"};
+cvar_t r_shadow_bouncegrid_intensity = {CVAR_SAVE, "r_shadow_bouncegrid_intensity", "4", "overall brightness of bouncegrid texture"};
 cvar_t r_shadow_bouncegrid_lightradiusscale = {CVAR_SAVE, "r_shadow_bouncegrid_lightradiusscale", "2", "particles stop at this fraction of light radius (can be more than 1)"};
 cvar_t r_shadow_bouncegrid_maxbounce = {CVAR_SAVE, "r_shadow_bouncegrid_maxbounce", "3", "maximum number of bounces for a particle (minimum is 1)"};
-cvar_t r_shadow_bouncegrid_particlebounceintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particlebounceintensity", "1", "amount of energy carried over after each bounce"};
-cvar_t r_shadow_bouncegrid_particleintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particleintensity", "4", "brightness of particles contributing to bouncegrid texture"};
+cvar_t r_shadow_bouncegrid_particlebounceintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particlebounceintensity", "4", "amount of energy carried over after each bounce, this is a multiplier of texture color and the result is clamped to 1 or less, to prevent adding energy on each bounce"};
+cvar_t r_shadow_bouncegrid_particleintensity = {CVAR_SAVE, "r_shadow_bouncegrid_particleintensity", "2", "brightness of particles contributing to bouncegrid texture"};
 cvar_t r_shadow_bouncegrid_particlespacing = {CVAR_SAVE, "r_shadow_bouncegrid_particlespacing", "32", "emit one particle per this many units (squared) of radius (squared)"};
 cvar_t r_shadow_bouncegrid_spacingx = {CVAR_SAVE, "r_shadow_bouncegrid_spacingx", "64", "unit size of bouncegrid pixel on X axis"};
 cvar_t r_shadow_bouncegrid_spacingy = {CVAR_SAVE, "r_shadow_bouncegrid_spacingy", "64", "unit size of bouncegrid pixel on Y axis"};
@@ -2293,6 +2293,8 @@ static void R_Shadow_UpdateBounceGridTexture(void)
        int shotparticles;
        int tex[3];
        trace_t cliptrace;
+       //trace_t cliptrace2;
+       //trace_t cliptrace3;
        unsigned char *pixel;
        unsigned char *pixels;
        unsigned short *highpixel;
@@ -2304,6 +2306,7 @@ static void R_Shadow_UpdateBounceGridTexture(void)
        unsigned int seed = (unsigned int)(realtime * 1000.0f);
        vec3_t shotcolor;
        vec3_t baseshotcolor;
+       vec3_t surfcolor;
        vec3_t clipend;
        vec3_t clipstart;
        vec3_t clipdiff;
@@ -2464,7 +2467,9 @@ static void R_Shadow_UpdateBounceGridTexture(void)
                        for (bouncecount = 0;;bouncecount++)
                        {
                                r_refdef.stats.bouncegrid_traces++;
-                               cliptrace = CL_TraceLine(clipstart, clipend, r_shadow_bouncegrid_hitmodels.integer ? MOVE_HITMODEL : MOVE_NOMONSTERS, NULL, hitsupercontentsmask, true, false, NULL, true);
+                               //r_refdef.scene.worldmodel->TraceLineAgainstSurfaces(r_refdef.scene.worldmodel, NULL, NULL, &cliptrace, clipstart, clipend, hitsupercontentsmask);
+                               //r_refdef.scene.worldmodel->TraceLine(r_refdef.scene.worldmodel, NULL, NULL, &cliptrace2, clipstart, clipend, hitsupercontentsmask);
+                               cliptrace = CL_TraceLine(clipstart, clipend, r_shadow_bouncegrid_hitmodels.integer ? MOVE_HITMODEL : MOVE_NOMONSTERS, NULL, hitsupercontentsmask, true, false, NULL, true, true);
                                //Collision_ClipLineToWorld(&cliptrace, cl.worldmodel, clipstart, clipend, hitsupercontentsmask);
                                if (cliptrace.fraction >= 1.0f)
                                        break;
@@ -2499,11 +2504,16 @@ static void R_Shadow_UpdateBounceGridTexture(void)
                                if (bouncecount >= maxbounce)
                                        break;
                                // scale down shot color by bounce intensity and texture color (or 50% if no texture reported)
-                               VectorScale(shotcolor, r_shadow_bouncegrid_particlebounceintensity.value, shotcolor);
+                               // also clamp the resulting color to never add energy, even if the user requests extreme values
                                if (cliptrace.hittexture && cliptrace.hittexture->currentskinframe)
-                                       VectorMultiply(shotcolor, cliptrace.hittexture->currentskinframe->avgcolor, shotcolor);
+                                       VectorCopy(cliptrace.hittexture->currentskinframe->avgcolor, surfcolor);
                                else
-                                       VectorScale(shotcolor, 0.5f, shotcolor);
+                                       VectorSet(surfcolor, 0.5f, 0.5f, 0.5f);
+                               VectorScale(surfcolor, r_shadow_bouncegrid_particlebounceintensity.value, surfcolor);
+                               surfcolor[0] = min(surfcolor[0], 1.0f);
+                               surfcolor[1] = min(surfcolor[1], 1.0f);
+                               surfcolor[2] = min(surfcolor[2], 1.0f);
+                               VectorMultiply(shotcolor, surfcolor, shotcolor);
                                if (VectorLength2(shotcolor) < 3.0f)
                                        break;
                                r_refdef.stats.bouncegrid_bounces++;
@@ -4869,7 +4879,7 @@ void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
        else
        {
                // FIXME: these traces should scan all render entities instead of cl.world
-               if (CL_TraceLine(r_refdef.view.origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
+               if (CL_TraceLine(r_refdef.view.origin, rtlight->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, true).fraction < 1)
                        return;
        }
        VectorScale(rtlight->currentcolor, cscale, color);
@@ -5247,7 +5257,7 @@ void R_Shadow_SelectLightInView(void)
                if (rating >= 0.95)
                {
                        rating /= (1 + 0.0625f * sqrt(DotProduct(temp, temp)));
-                       if (bestrating < rating && CL_TraceLine(light->origin, r_refdef.view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction == 1.0f)
+                       if (bestrating < rating && CL_TraceLine(light->origin, r_refdef.view.origin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, true).fraction == 1.0f)
                        {
                                bestrating = rating;
                                best = light;
@@ -5696,7 +5706,7 @@ void R_Shadow_SetCursorLocationForView(void)
        vec3_t dest, endpos;
        trace_t trace;
        VectorMA(r_refdef.view.origin, r_editlights_cursordistance.value, r_refdef.view.forward, dest);
-       trace = CL_TraceLine(r_refdef.view.origin, dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false);
+       trace = CL_TraceLine(r_refdef.view.origin, dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, true);
        if (trace.fraction < 1)
        {
                dist = trace.fraction * r_editlights_cursordistance.value;
@@ -6448,7 +6458,7 @@ void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const
                        intensity = min(1.0f, (1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) * r_shadow_lightintensityscale.value;
                        if (intensity <= 0.0f)
                                continue;
-                       if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
+                       if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, true).fraction < 1)
                                continue;
                        // scale down intensity to add to both ambient and diffuse
                        //intensity *= 0.5f;
@@ -6480,7 +6490,7 @@ void R_CompleteLightPoint(vec3_t ambient, vec3_t diffuse, vec3_t lightdir, const
                        intensity = (1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist) * r_shadow_lightintensityscale.value;
                        if (intensity <= 0.0f)
                                continue;
-                       if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false).fraction < 1)
+                       if (light->shadow && CL_TraceLine(p, light->shadoworigin, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, true, false, NULL, false, true).fraction < 1)
                                continue;
                        // scale down intensity to add to both ambient and diffuse
                        //intensity *= 0.5f;
index e55ae81..7558be8 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -299,7 +299,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
 #endif
 
        // clip to world
-       Collision_ClipLineToWorld(&cliptrace, sv.worldmodel, clipstart, clipend, hitsupercontentsmask);
+       Collision_ClipLineToWorld(&cliptrace, sv.worldmodel, clipstart, clipend, hitsupercontentsmask, false);
        cliptrace.bmodelstartsolid = cliptrace.startsolid;
        if (cliptrace.startsolid || cliptrace.fraction < 1)
                cliptrace.ent = prog->edicts;
@@ -393,7 +393,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
                if (type == MOVE_MISSILE && (int)touch->fields.server->flags & FL_MONSTER)
                        Collision_ClipToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
                else
-                       Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask);
+                       Collision_ClipLineToGenericEntity(&trace, model, touch->priv.server->frameblend, &touch->priv.server->skeleton, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipend, hitsupercontentsmask, false);
 
                Collision_CombineTraces(&cliptrace, &trace, (void *)touch, touch->fields.server->solid == SOLID_BSP);
        }
diff --git a/view.c b/view.c
index 3066ef9..86902ad 100644 (file)
--- a/view.c
+++ b/view.c
@@ -535,7 +535,7 @@ void V_CalcRefdef (void)
 #else
                                        // trace from first person view location to our chosen third person view location
 #if 1
-                                       trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false);
+                                       trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false, true);
 #else
                                        trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false);
 #endif
@@ -550,7 +550,7 @@ void V_CalcRefdef (void)
                                                        chase_dest[1] = vieworg[1] - forward[1] * camback + up[1] * camup + offset[1];
                                                        chase_dest[2] = vieworg[2] - forward[2] * camback + up[2] * camup + offset[2];
 #if 1
-                                                       trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false);
+                                                       trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false, true);
 #else
                                                        trace = CL_TraceBox(vieworg, camboxmins, camboxmaxs, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false);
 #endif
@@ -578,7 +578,7 @@ void V_CalcRefdef (void)
                                        chase_dest[0] = vieworg[0] + forward[0] * dist;
                                        chase_dest[1] = vieworg[1] + forward[1] * dist;
                                        chase_dest[2] = vieworg[2] + forward[2] * dist + camup;
-                                       trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false);
+                                       trace = CL_TraceLine(vieworg, chase_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, true, false, NULL, false, true);
                                        VectorMAMAM(1, trace.endpos, 8, forward, 4, trace.plane.normal, vieworg);
                                }
                        }