X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=world.c;h=a43544770573bc09c3833dc1af5ce3868e3f1d98;hp=7468e1357e5dd2902c9285892d9a820ea96ab95c;hb=b56296db9ed33f65930f20c05af04d2b28289eff;hpb=b56a557d3452d3dc18ed0625db50e2e50946f914 diff --git a/world.c b/world.c index 7468e135..a4354477 100644 --- a/world.c +++ b/world.c @@ -29,8 +29,8 @@ line of sight checks trace->inopen and trace->inwater, but bullets don't */ -cvar_t sv_debugmove = {CVAR_NOTIFY, "sv_debugmove", "0"}; -cvar_t sv_areagrid_mingridsize = {CVAR_NOTIFY, "sv_areagrid_mingridsize", "64"}; +cvar_t sv_debugmove = {CVAR_NOTIFY, "sv_debugmove", "0", "disables collision detection optimizations for debugging purposes"}; +cvar_t sv_areagrid_mingridsize = {CVAR_NOTIFY, "sv_areagrid_mingridsize", "64", "minimum areagrid cell size, smaller values work better for lots of small objects, higher values for large objects"}; void SV_AreaStats_f(void); @@ -38,7 +38,7 @@ void SV_World_Init(void) { Cvar_RegisterVariable(&sv_debugmove); Cvar_RegisterVariable(&sv_areagrid_mingridsize); - Cmd_AddCommand("sv_areastats", SV_AreaStats_f); + Cmd_AddCommand("sv_areastats", SV_AreaStats_f, "prints information on culling grid system"); Collision_Init(); } @@ -168,11 +168,11 @@ int SV_EntitiesInBox(vec3_t mins, vec3_t maxs, int maxlist, prvm_edict_t **list) sv_areagrid_stats_calls++; sv_areagrid_marknumber++; - igridmins[0] = (int) ((mins[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]); - igridmins[1] = (int) ((mins[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]); + igridmins[0] = (int) floor((mins[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]); + igridmins[1] = (int) floor((mins[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]); //igridmins[2] = (int) ((mins[2] + sv_areagrid_bias[2]) * sv_areagrid_scale[2]); - igridmaxs[0] = (int) ((maxs[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]) + 1; - igridmaxs[1] = (int) ((maxs[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]) + 1; + igridmaxs[0] = (int) floor((maxs[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]) + 1; + igridmaxs[1] = (int) floor((maxs[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]) + 1; //igridmaxs[2] = (int) ((maxs[2] + sv_areagrid_bias[2]) * sv_areagrid_scale[2]) + 1; igridmins[0] = max(0, igridmins[0]); igridmins[1] = max(0, igridmins[1]); @@ -222,6 +222,7 @@ int SV_EntitiesInBox(vec3_t mins, vec3_t maxs, int maxlist, prvm_edict_t **list) list[numlist] = ent; numlist++; } + // Con_Printf("%d %f %f %f %f %f %f : %d : %f %f %f %f %f %f\n", BoxesOverlap(mins, maxs, ent->fields.server->absmin, ent->fields.server->absmax), ent->fields.server->absmin[0], ent->fields.server->absmin[1], ent->fields.server->absmin[2], ent->fields.server->absmax[0], ent->fields.server->absmax[1], ent->fields.server->absmax[2], PRVM_NUM_FOR_EDICT(ent), mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); } sv_areagrid_stats_entitychecks++; } @@ -253,9 +254,27 @@ void SV_TouchAreaGrid(prvm_edict_t *ent) touch = touchedicts[i]; if (touch != ent && (int)touch->fields.server->solid == SOLID_TRIGGER && touch->fields.server->touch) { + prvm_eval_t *val; prog->globals.server->self = PRVM_EDICT_TO_PROG(touch); prog->globals.server->other = PRVM_EDICT_TO_PROG(ent); prog->globals.server->time = sv.time; + prog->globals.server->trace_allsolid = false; + prog->globals.server->trace_startsolid = false; + prog->globals.server->trace_fraction = 1; + prog->globals.server->trace_inwater = false; + prog->globals.server->trace_inopen = true; + VectorCopy (touch->fields.server->origin, prog->globals.server->trace_endpos); + VectorSet (prog->globals.server->trace_plane_normal, 0, 0, 1); + prog->globals.server->trace_plane_dist = 0; + prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(ent); + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents))) + val->_float = 0; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents))) + val->_float = 0; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags))) + val->_float = 0; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename))) + val->string = 0; PRVM_ExecuteProgram (touch->fields.server->touch, "QC function self.touch is missing"); } } @@ -274,11 +293,11 @@ void SV_LinkEdict_AreaGrid(prvm_edict_t *ent) return; } - igridmins[0] = (int) ((ent->fields.server->absmin[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]); - igridmins[1] = (int) ((ent->fields.server->absmin[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]); + igridmins[0] = (int) floor((ent->fields.server->absmin[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]); + igridmins[1] = (int) floor((ent->fields.server->absmin[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]); //igridmins[2] = (int) ((ent->fields.server->absmin[2] + sv_areagrid_bias[2]) * sv_areagrid_scale[2]); - igridmaxs[0] = (int) ((ent->fields.server->absmax[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]) + 1; - igridmaxs[1] = (int) ((ent->fields.server->absmax[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]) + 1; + igridmaxs[0] = (int) floor((ent->fields.server->absmax[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]) + 1; + igridmaxs[1] = (int) floor((ent->fields.server->absmax[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]) + 1; //igridmaxs[2] = (int) ((ent->fields.server->absmax[2] + sv_areagrid_bias[2]) * sv_areagrid_scale[2]) + 1; if (igridmins[0] < 0 || igridmaxs[0] > AREA_GRID || igridmins[1] < 0 || igridmaxs[1] > AREA_GRID || ((igridmaxs[0] - igridmins[0]) * (igridmaxs[1] - igridmins[1])) > ENTITYGRIDAREAS) { @@ -385,39 +404,15 @@ void SV_LinkEdict (prvm_edict_t *ent, qboolean touch_triggers) ent->fields.server->absmax[2] += 1; } - if (ent->fields.server->solid == SOLID_NOT) - return; - SV_LinkEdict_AreaGrid(ent); // if touch_triggers, touch all entities at this node and descend for more - if (touch_triggers) + if (touch_triggers && ent->fields.server->solid != SOLID_NOT) SV_TouchAreaGrid(ent); } -/* -=============================================================================== - -POINT TESTING IN HULLS - -=============================================================================== -*/ - -/* -============ -SV_TestEntityPosition - -This could be a lot more efficient... -============ -*/ -int SV_TestEntityPosition (prvm_edict_t *ent) -{ - return SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, ent->fields.server->origin, MOVE_NORMAL, ent).startsolid; -} - - /* =============================================================================== @@ -440,7 +435,6 @@ trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t model_t *model = NULL; matrix4x4_t matrix, imatrix; float tempnormal[3], starttransformed[3], endtransformed[3]; - float starttransformedmins[3], starttransformedmaxs[3], endtransformedmins[3], endtransformedmaxs[3]; memset(&trace, 0, sizeof(trace)); trace.fraction = trace.realfraction = 1; @@ -497,14 +491,10 @@ trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t int frame; frame = (int)ent->fields.server->frame; frame = bound(0, frame, (model->numframes - 1)); - VectorAdd(starttransformed, maxs, starttransformedmaxs); - VectorAdd(endtransformed, maxs, endtransformedmaxs); - VectorAdd(starttransformed, mins, starttransformedmins); - VectorAdd(endtransformed, mins, endtransformedmins); - model->TraceBox(model, frame, &trace, starttransformedmins, starttransformedmaxs, endtransformedmins, endtransformedmaxs, hitsupercontents); + model->TraceBox(model, frame, &trace, starttransformed, mins, maxs, endtransformed, hitsupercontents); } else - Collision_ClipTrace_Box(&trace, ent->fields.server->mins, ent->fields.server->maxs, starttransformed, mins, maxs, endtransformed, hitsupercontents, SUPERCONTENTS_SOLID); + Collision_ClipTrace_Box(&trace, ent->fields.server->mins, ent->fields.server->maxs, starttransformed, mins, maxs, endtransformed, hitsupercontents, ent->fields.server->solid == SOLID_CORPSE ? SUPERCONTENTS_CORPSE : SUPERCONTENTS_BODY, 0, NULL); trace.fraction = bound(0, trace.fraction, 1); trace.realfraction = bound(0, trace.realfraction, 1); @@ -529,14 +519,9 @@ SV_ClipMoveToWorld trace_t SV_ClipMoveToWorld(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int movetype, int hitsupercontents) { trace_t trace; - float starttransformedmins[3], starttransformedmaxs[3], endtransformedmins[3], endtransformedmaxs[3]; memset(&trace, 0, sizeof(trace)); trace.fraction = trace.realfraction = 1; - VectorAdd(start, maxs, starttransformedmaxs); - VectorAdd(end, maxs, endtransformedmaxs); - VectorAdd(start, mins, starttransformedmins); - VectorAdd(end, mins, endtransformedmins); - sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, starttransformedmins, starttransformedmaxs, endtransformedmins, endtransformedmaxs, hitsupercontents); + sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, start, mins, maxs, end, hitsupercontents); trace.fraction = bound(0, trace.fraction, 1); trace.realfraction = bound(0, trace.realfraction, 1); VectorLerp(start, trace.fraction, end, trace.endpos); @@ -562,6 +547,7 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const int passedictprog; qboolean pointtrace; prvm_edict_t *traceowner, *touch; + prvm_eval_t *val; trace_t trace; // bounding box of entire move area vec3_t clipboxmins, clipboxmaxs; @@ -586,17 +572,29 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const Con_Printf("move(%f %f %f,%f %f %f)", clipstart[0], clipstart[1], clipstart[2], clipend[0], clipend[1], clipend[2]); #endif - hitsupercontentsmask = SUPERCONTENTS_SOLID; if (passedict) { - if (passedict->fields.server->solid == SOLID_SLIDEBOX) - hitsupercontentsmask |= SUPERCONTENTS_PLAYERCLIP; - if ((int)passedict->fields.server->flags & FL_MONSTER) - hitsupercontentsmask |= SUPERCONTENTS_MONSTERCLIP; + val = PRVM_GETEDICTFIELDVALUE(passedict, eval_dphitcontentsmask); + if (val && val->_float) + hitsupercontentsmask = (int)val->_float; + else if (passedict->fields.server->solid == SOLID_SLIDEBOX) + { + if ((int)passedict->fields.server->flags & FL_MONSTER) + hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_MONSTERCLIP; + else + hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP; + } + else if (passedict->fields.server->solid == SOLID_CORPSE) + hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY; + else + hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE; } + else + hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE; // clip to world cliptrace = SV_ClipMoveToWorld(clipstart, clipmins, clipmaxs, clipend, type, hitsupercontentsmask); + cliptrace.startsolid = cliptrace.bmodelstartsolid; if (cliptrace.startsolid || cliptrace.fraction < 1) cliptrace.ent = prog->edicts; if (type == MOVE_WORLDONLY) @@ -676,12 +674,6 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const // don't clip points against points (they can't collide) if (pointtrace && VectorCompare(touch->fields.server->mins, touch->fields.server->maxs) && (type != MOVE_MISSILE || !((int)touch->fields.server->flags & FL_MONSTER))) continue; - // don't clip corpse against character - if (passedict->fields.server->solid == SOLID_CORPSE && (touch->fields.server->solid == SOLID_SLIDEBOX || touch->fields.server->solid == SOLID_CORPSE)) - continue; - // don't clip character against corpse - if (passedict->fields.server->solid == SOLID_SLIDEBOX && touch->fields.server->solid == SOLID_CORPSE) - continue; } // might interact, so do an exact clip @@ -694,6 +686,8 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const cliptrace.allsolid = true; if (trace.startsolid) { + if (touch->fields.server->solid == SOLID_BSP) + cliptrace.bmodelstartsolid = true; cliptrace.startsolid = true; if (cliptrace.realfraction == 1) cliptrace.ent = touch; @@ -712,6 +706,9 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const VectorCopy(trace.endpos, cliptrace.endpos); cliptrace.plane = trace.plane; cliptrace.ent = touch; + cliptrace.hitsupercontents = trace.hitsupercontents; + cliptrace.hitq3surfaceflags = trace.hitq3surfaceflags; + cliptrace.hittexture = trace.hittexture; } cliptrace.startsupercontents |= trace.startsupercontents; } @@ -739,14 +736,4 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const } #endif -int SV_PointSuperContents(const vec3_t point) -{ - return SV_Move(point, vec3_origin, vec3_origin, point, sv_gameplayfix_swiminbmodels.integer ? MOVE_NOMONSTERS : MOVE_WORLDONLY, NULL).startsupercontents; -} - -int SV_PointQ1Contents(const vec3_t point) -{ - return Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(point)); -} -