X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=world.c;h=0ff5a6fc7dd6e79f2d022fb93d1abcc1195f9330;hb=8659703a56a752a24a84b9208a38055512ce2736;hp=ff129dfd5165647d41a00bba78d14f8b84cd3211;hpb=0cc298d3c03cc31166905b782f9f6545f8eee742;p=xonotic%2Fdarkplaces.git diff --git a/world.c b/world.c index ff129dfd..0ff5a6fc 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) { @@ -319,7 +338,7 @@ void SV_LinkEdict (prvm_edict_t *ent, qboolean touch_triggers) if (ent->fields.server->solid == SOLID_BSP) { - int modelindex = ent->fields.server->modelindex; + int modelindex = (int)ent->fields.server->modelindex; if (modelindex < 0 || modelindex > MAX_MODELS) { Con_Printf("edict %i: SOLID_BSP with invalid modelindex!\n", PRVM_NUM_FOR_EDICT(ent)); @@ -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; @@ -448,7 +442,7 @@ trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t if ((int) ent->fields.server->solid == SOLID_BSP || movetype == MOVE_HITMODEL) { - unsigned int modelindex = ent->fields.server->modelindex; + unsigned int modelindex = (unsigned int)ent->fields.server->modelindex; // if the modelindex is 0, it shouldn't be SOLID_BSP! if (modelindex == 0) { @@ -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); @@ -521,6 +511,23 @@ trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t return trace; } +/* +================== +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; + memset(&trace, 0, sizeof(trace)); + trace.fraction = trace.realfraction = 1; + 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); + return trace; +} + //=========================================================================== /* @@ -540,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; @@ -564,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_ClipMoveToEntity(prog->edicts, clipstart, clipmins, clipmaxs, clipend, type, hitsupercontentsmask); + cliptrace = SV_ClipMoveToWorld(clipstart, clipmins, clipmaxs, clipend, type, hitsupercontentsmask); + cliptrace.bmodelstartsolid = cliptrace.startsolid; if (cliptrace.startsolid || cliptrace.fraction < 1) cliptrace.ent = prog->edicts; if (type == MOVE_WORLDONLY) @@ -623,7 +643,7 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const // precalculate passedict's owner edict pointer for comparisons traceowner = passedict ? PRVM_PROG_TO_EDICT(passedict->fields.server->owner) : 0; - // clip to enttiies + // clip to entities numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts); if (numtouchedicts > MAX_EDICTS) { @@ -654,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 @@ -672,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; @@ -690,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; } @@ -711,20 +730,10 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const #if COLLISIONPARANOID < 3 if (trace.startsolid || endstuck) #endif - Con_Printf("%s{e%i:%f %f %f:%f %f %f:%f:%f %f %f%s%s}\n", (trace.startsolid || endstuck) ? "\002" : "", passedict ? passedict - prog->edicts : -1, passedict->fields.server->origin[0], passedict->fields.server->origin[1], passedict->fields.server->origin[2], end[0] - passedict->fields.server->origin[0], end[1] - passedict->fields.server->origin[1], end[2] - passedict->fields.server->origin[2], trace.fraction, trace.endpos[0] - passedict->fields.server->origin[0], trace.endpos[1] - passedict->fields.server->origin[1], trace.endpos[2] - passedict->fields.server->origin[2], trace.startsolid ? " startstuck" : "", endstuck ? " endstuck" : ""); + Con_Printf("%s{e%i:%f %f %f:%f %f %f:%f:%f %f %f%s%s}\n", (trace.startsolid || endstuck) ? "^3" : "", passedict ? (int)(passedict - prog->edicts) : -1, passedict->fields.server->origin[0], passedict->fields.server->origin[1], passedict->fields.server->origin[2], end[0] - passedict->fields.server->origin[0], end[1] - passedict->fields.server->origin[1], end[2] - passedict->fields.server->origin[2], trace.fraction, trace.endpos[0] - passedict->fields.server->origin[0], trace.endpos[1] - passedict->fields.server->origin[1], trace.endpos[2] - passedict->fields.server->origin[2], trace.startsolid ? " startstuck" : "", endstuck ? " endstuck" : ""); } return trace; } #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)); -} -