X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=world.c;h=cf2b2d00e69ab4c4017b9dcbf5b9dabb27c745fd;hb=8d6e18bf98b2cdd0bc5edd08b131312d81bf1a06;hp=0a9a58618c600d49105384988246abffe0925f4a;hpb=80bf4ebf5beea6eba76f5dd4f13c41d28241688c;p=xonotic%2Fdarkplaces.git diff --git a/world.c b/world.c index 0a9a5861..cf2b2d00 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(); } @@ -254,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"); } } @@ -320,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)); @@ -386,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; -} - - /* =============================================================================== @@ -441,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; @@ -449,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) { @@ -498,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); @@ -530,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); @@ -563,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; @@ -587,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.bmodelstartsolid = cliptrace.startsolid; if (cliptrace.startsolid || cliptrace.fraction < 1) cliptrace.ent = prog->edicts; if (type == MOVE_WORLDONLY) @@ -677,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 @@ -695,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; @@ -713,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; } @@ -734,7 +730,7 @@ 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 ? 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; }