X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=world.c;h=d8d092ff3a745e5cfec99cf500a5a5b6237a8e8e;hb=0fd6ba6decb661516e054a41e796eed450218df0;hp=fe6aba980171840d03542959c30f2705abb4bcd6;hpb=79364be7e78057695411165ed1e3a7119f0d55ff;p=xonotic%2Fdarkplaces.git diff --git a/world.c b/world.c index fe6aba98..d8d092ff 100644 --- a/world.c +++ b/world.c @@ -45,9 +45,9 @@ void InsertLinkAfter (link_t *l, link_t *after); // (type *)STRUCT_FROM_LINK(link_t *link, type, member) // ent = STRUCT_FROM_LINK(link,entity_t,order) // FIXME: remove this mess! -//#define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m))) +//#define STRUCT_FROM_LINK(l,t,m) ((t *)((qbyte *)l - (int)&(((t *)0)->m))) -#define EDICT_FROM_AREA(l) ((edict_t *)((byte *)l - (int)&(((edict_t *)0)->area))) +#define EDICT_FROM_AREA(l) ((edict_t *)((qbyte *)l - (int)&(((edict_t *)0)->area))) //============================================================================ @@ -125,19 +125,18 @@ void SV_InitBoxHull (void) for (i=0 ; i<6 ; i++) { box_clipnodes[i].planenum = i; - + side = i&1; - + box_clipnodes[i].children[side] = CONTENTS_EMPTY; if (i != 5) box_clipnodes[i].children[side^1] = i + 1; else box_clipnodes[i].children[side^1] = CONTENTS_SOLID; - + box_planes[i].type = i>>1; box_planes[i].normal[i>>1] = 1; } - } @@ -418,7 +417,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) if (ent->area.prev) SV_UnlinkEdict (ent); // unlink from old position - + if (ent == sv.edicts) return; // don't add the world @@ -554,7 +553,7 @@ edict_t *SV_TestEntityPosition (edict_t *ent) if (trace.startsolid) return sv.edicts; - + return NULL; } @@ -742,44 +741,36 @@ eventually rotation) of the end points trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) { trace_t trace; - vec3_t offset, start_l, end_l; - double startd[3], endd[3]; + vec3_t offset, forward, left, up; + double startd[3], endd[3], tempd[3]; hull_t *hull; // fill in a default trace memset (&trace, 0, sizeof(trace_t)); trace.fraction = 1; trace.allsolid = true; - VectorCopy (end, trace.endpos); // get the clipping hull hull = SV_HullForEntity (ent, mins, maxs, offset); - VectorSubtract (start, offset, start_l); - VectorSubtract (end, offset, end_l); + VectorSubtract(start, offset, startd); + VectorSubtract(end, offset, endd); -// LordHavoc: enabling rotating bmodels // rotate start and end into the models frame of reference if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2])) { - vec3_t forward, right, up; - vec3_t temp; - - AngleVectors (ent->v.angles, forward, right, up); - - VectorCopy (start_l, temp); - start_l[0] = DotProduct (temp, forward); - start_l[1] = -DotProduct (temp, right); - start_l[2] = DotProduct (temp, up); - - VectorCopy (end_l, temp); - end_l[0] = DotProduct (temp, forward); - end_l[1] = -DotProduct (temp, right); - end_l[2] = DotProduct (temp, up); + AngleVectorsFLU (ent->v.angles, forward, left, up); + VectorCopy(startd, tempd); + startd[0] = DotProduct (tempd, forward); + startd[1] = DotProduct (tempd, left); + startd[2] = DotProduct (tempd, up); + VectorCopy(endd, tempd); + endd[0] = DotProduct (tempd, forward); + endd[1] = DotProduct (tempd, left); + endd[2] = DotProduct (tempd, up); } - VectorCopy(start_l, startd); - VectorCopy(end_l, endd); + VectorCopy(end, trace.endpos); // trace a line through the appropriate clipping hull VectorCopy(startd, RecursiveHullCheckInfo.start); @@ -788,37 +779,30 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max RecursiveHullCheckInfo.trace = &trace; SV_RecursiveHullCheck (hull->firstclipnode, 0, 1, startd, endd); -// LordHavoc: enabling rotating bmodels - // rotate endpos back to world frame of reference - if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2])) + // if we hit, unrotate endpos and normal, and store the entity we hit + if (trace.fraction != 1) { - vec3_t a; - vec3_t forward, right, up; - vec3_t temp; - - if (trace.fraction != 1) + // rotate endpos back to world frame of reference + if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2])) { - VectorNegate (ent->v.angles, a); - AngleVectors (a, forward, right, up); - - VectorCopy (trace.endpos, temp); - trace.endpos[0] = DotProduct (temp, forward); - trace.endpos[1] = -DotProduct (temp, right); - trace.endpos[2] = DotProduct (temp, up); - - VectorCopy (trace.plane.normal, temp); - trace.plane.normal[0] = DotProduct (temp, forward); - trace.plane.normal[1] = -DotProduct (temp, right); - trace.plane.normal[2] = DotProduct (temp, up); + VectorNegate (ent->v.angles, offset); + AngleVectorsFLU (offset, forward, left, up); + + VectorCopy (trace.endpos, tempd); + trace.endpos[0] = DotProduct (tempd, forward); + trace.endpos[1] = DotProduct (tempd, left); + trace.endpos[2] = DotProduct (tempd, up); + + VectorCopy (trace.plane.normal, tempd); + trace.plane.normal[0] = DotProduct (tempd, forward); + trace.plane.normal[1] = DotProduct (tempd, left); + trace.plane.normal[2] = DotProduct (tempd, up); } - } - -// fix trace up by the offset - if (trace.fraction != 1) + // fix offset VectorAdd (trace.endpos, offset, trace.endpos); - -// did we clip the move? - if (trace.fraction < 1 || trace.startsolid ) + trace.ent = ent; + } + else if (trace.allsolid || trace.startsolid) trace.ent = ent; return trace; @@ -840,6 +824,8 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) trace_t trace; loc0: + if (clip->trace.allsolid) + return; // touch linked edicts for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next) { @@ -850,46 +836,69 @@ loc0: if (touch == clip->passedict) continue; if (touch->v.solid == SOLID_TRIGGER) - Sys_Error ("Trigger in clipping list"); + Host_Error ("Trigger in clipping list"); if (clip->type == MOVE_NOMONSTERS && touch->v.solid != SOLID_BSP) continue; if (clip->boxmins[0] > touch->v.absmax[0] - || clip->boxmins[1] > touch->v.absmax[1] - || clip->boxmins[2] > touch->v.absmax[2] || clip->boxmaxs[0] < touch->v.absmin[0] + || clip->boxmins[1] > touch->v.absmax[1] || clip->boxmaxs[1] < touch->v.absmin[1] + || clip->boxmins[2] > touch->v.absmax[2] || clip->boxmaxs[2] < touch->v.absmin[2]) continue; - if (clip->passedict != NULL && clip->passedict->v.size[0] && !touch->v.size[0]) - continue; // points never interact - - // might intersect, so do an exact clip - if (clip->trace.allsolid) - return; if (clip->passedict) { + if (clip->passedict->v.size[0] && !touch->v.size[0]) + continue; // points never interact if (PROG_TO_EDICT(touch->v.owner) == clip->passedict) continue; // don't clip against own missiles if (PROG_TO_EDICT(clip->passedict->v.owner) == touch) continue; // don't clip against owner // LordHavoc: corpse code - if (clip->passedict->v.solid == SOLID_CORPSE && touch->v.solid == SOLID_SLIDEBOX) + if (clip->passedict->v.solid == SOLID_CORPSE && (touch->v.solid == SOLID_SLIDEBOX || touch->v.solid == SOLID_CORPSE)) continue; if (clip->passedict->v.solid == SOLID_SLIDEBOX && touch->v.solid == SOLID_CORPSE) continue; } + // might interact, so do an exact clip if ((int)touch->v.flags & FL_MONSTER) trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end); else trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end); - if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction) + // LordHavoc: take the 'best' answers from the new trace and combine with existing data + if (trace.allsolid) + clip->trace.allsolid = true; + if (trace.startsolid) + { + clip->trace.startsolid = true; + if (!clip->trace.ent) + clip->trace.ent = trace.ent; + } + if (trace.inopen) + clip->trace.inopen = true; + if (trace.inwater) + clip->trace.inwater = true; + if (trace.fraction < clip->trace.fraction) + { + clip->trace.fraction = trace.fraction; + VectorCopy(trace.endpos, clip->trace.endpos); + clip->trace.plane = trace.plane; + clip->trace.endcontents = trace.endcontents; + clip->trace.ent = trace.ent; + } + /* + if (trace.allsolid) { - trace.ent = touch; - if (clip->trace.startsolid) + clip->trace = trace; + return; + } + if (trace.startsolid || trace.fraction < clip->trace.fraction) + { + if (clip->trace.startsolid) { clip->trace = trace; clip->trace.startsolid = true; @@ -897,8 +906,7 @@ loc0: else clip->trace = trace; } - else if (trace.startsolid) - clip->trace.startsolid = true; + */ } // recurse down both sides @@ -965,9 +973,6 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e memset ( &clip, 0, sizeof ( moveclip_t ) ); -// clip to world - clip.trace = SV_ClipMoveToEntity ( sv.edicts, start, mins, maxs, end ); - clip.start = start; clip.end = end; clip.mins = mins; @@ -985,15 +990,21 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e } else { - VectorCopy (mins, clip.mins2); - VectorCopy (maxs, clip.maxs2); + VectorCopy (clip.mins, clip.mins2); + VectorCopy (clip.maxs, clip.maxs2); } -// create the bounding box of the entire move - SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); + // clip to world + clip.trace = SV_ClipMoveToEntity (sv.edicts, start, mins, maxs, end); -// clip to entities - SV_ClipToLinks ( sv_areanodes, &clip ); + // clip to entities + //if (!clip.trace.allsolid) + { + // create the bounding box of the entire move + SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); + + SV_ClipToLinks ( sv_areanodes, &clip ); + } return clip.trace; }