/* Ghoul2 Insert Start */ void SV_Trace( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask, int capsule, int traceFlags, int useLod ) { /* Ghoul2 Insert End */ moveclip_t clip; int i; if ( !mins ) { mins = vec3_origin; } if ( !maxs ) { maxs = vec3_origin; } Com_Memset ( &clip, 0, sizeof ( moveclip_t ) ); // clip to world CM_BoxTrace( &clip.trace, start, end, mins, maxs, 0, contentmask, capsule ); clip.trace.entityNum = clip.trace.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE; if ( clip.trace.fraction == 0 ) { *results = clip.trace; return; // blocked immediately by the world } clip.contentmask = contentmask; /* Ghoul2 Insert Start */ VectorCopy( start, clip.start ); clip.traceFlags = traceFlags; clip.useLod = useLod; /* Ghoul2 Insert End */ // VectorCopy( clip.trace.endpos, clip.end ); VectorCopy( end, clip.end ); clip.mins = mins; clip.maxs = maxs; clip.passEntityNum = passEntityNum; clip.capsule = capsule; // create the bounding box of the entire move // we can limit it to the part of the move not // already clipped off by the world, which can be // a significant savings for line of sight and shot traces for ( i=0 ; i<3 ; i++ ) { if ( end[i] > start[i] ) { clip.boxmins[i] = clip.start[i] + clip.mins[i] - 1; clip.boxmaxs[i] = clip.end[i] + clip.maxs[i] + 1; } else { clip.boxmins[i] = clip.end[i] + clip.mins[i] - 1; clip.boxmaxs[i] = clip.start[i] + clip.maxs[i] + 1; } } // clip to other solid entities SV_ClipMoveToEntities ( &clip ); *results = clip.trace; }
/* ================== SV_Trace Moves the given mins/maxs volume through the world from start to end. Passedict and edicts owned by passedict are explicitly not checked. ================== */ trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask) { moveclip_t clip; if (!mins) mins = vec3_origin; if (!maxs) maxs = vec3_origin; memset ( &clip, 0, sizeof ( moveclip_t ) ); // clip to world clip.trace = CM_BoxTrace (start, end, mins, maxs, 0, contentmask); clip.trace.ent = ge->edicts; if (clip.trace.fraction == 0) return clip.trace; // blocked by the world clip.contentmask = contentmask; clip.start = start; clip.end = end; clip.mins = mins; clip.maxs = maxs; clip.passedict = passedict; VectorCopy (mins, clip.mins2); VectorCopy (maxs, clip.maxs2); // create the bounding box of the entire move SV_TraceBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); // clip to other solid entities SV_ClipMoveToEntities ( &clip ); return clip.trace; }
/* ================== SV_Trace Moves the given mins/maxs volume through the world from start to end. passEntityNum and entities owned by passEntityNum are explicitly not checked. ================== */ void SV_Trace( trace_t *results, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask, traceType_t type ) { moveclip_t clip; int i; if ( !mins ) { mins = vec3_origin; } if ( !maxs ) { maxs = vec3_origin; } memset( &clip, 0, sizeof( moveclip_t ) ); // clip to world CM_BoxTrace( &clip.trace, start, end, mins, maxs, 0, contentmask, type ); clip.trace.entityNum = clip.trace.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE; if ( clip.trace.fraction == 0 || passEntityNum == -2 ) { *results = clip.trace; return; // blocked immediately by the world } clip.contentmask = contentmask; clip.start = start; // VectorCopy( clip.trace.endpos, clip.end ); VectorCopy( end, clip.end ); clip.mins = mins; clip.maxs = maxs; clip.passEntityNum = passEntityNum; clip.collisionType = type; // create the bounding box of the entire move // we can limit it to the part of the move not // already clipped off by the world, which can be // a significant savings for line of sight and shot traces for ( i = 0; i < 3; i++ ) { if ( end[ i ] > start[ i ] ) { clip.boxmins[ i ] = clip.start[ i ] + clip.mins[ i ] - 1; clip.boxmaxs[ i ] = clip.end[ i ] + clip.maxs[ i ] + 1; } else { clip.boxmins[ i ] = clip.end[ i ] + clip.mins[ i ] - 1; clip.boxmaxs[ i ] = clip.start[ i ] + clip.maxs[ i ] + 1; } } // clip to other solid entities SV_ClipMoveToEntities( &clip ); *results = clip.trace; }
/* * SV_Trace * * Moves the given mins/maxs volume through the world from start to end. * passEntityNum and entities owned by passEntityNum are explicitly not checked. */ void SV_Trace(Trace *results, const Vec3 start, Vec3 mins, Vec3 maxs, const Vec3 end, int passEntityNum, int contentmask, int capsule) { moveclip_t clip; int i; if(!mins) mins = vec3_origin; if(!maxs) maxs = vec3_origin; Q_Memset (&clip, 0, sizeof(moveclip_t)); /* clip to world */ CM_BoxTrace(&clip.trace, start, end, mins, maxs, 0, contentmask, capsule); clip.trace.entityNum = clip.trace.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE; if(clip.trace.fraction == 0){ *results = clip.trace; return; /* blocked immediately by the world */ } clip.contentmask = contentmask; clip.start = start; /* copyv3( clip.trace.endpos, clip.end ); */ copyv3(end, clip.end); clip.mins = mins; clip.maxs = maxs; clip.passEntityNum = passEntityNum; clip.capsule = capsule; /* create the bounding box of the entire move * we can limit it to the part of the move not * already clipped off by the world, which can be * a significant savings for line of sight and shot traces */ for(i=0; i<3; i++){ if(end[i] > start[i]){ clip.boxmins[i] = clip.start[i] + clip.mins[i] - 1; clip.boxmaxs[i] = clip.end[i] + clip.maxs[i] + 1; }else{ clip.boxmins[i] = clip.end[i] + clip.mins[i] - 1; clip.boxmaxs[i] = clip.start[i] + clip.maxs[i] + 1; } } /* clip to other solid entities */ SV_ClipMoveToEntities (&clip); *results = clip.trace; }
// Moves the given mins/maxs volume through the world from start to end. // Passedict and edicts owned by passedict are explicitly not checked. void SV_Trace(trace_t &tr, const CVec3 &start, const CVec3 &end, const CBox &bounds, edict_t *passedict, int contentmask) { guard(SV_Trace); // clip to world CM_BoxTrace(tr, start, end, bounds, 0, contentmask); tr.ent = ge->edicts; // entity[0] if (tr.fraction == 0) return; // blocked by the world CM_ClipTraceToModels(tr, start, end, bounds, contentmask); tr.ent = ge->edicts; // entity[0] if (tr.fraction == 0) return; // blocked by model // clip to other solid entities SV_ClipMoveToEntities(tr, start, end, bounds, passedict, contentmask); unguard; }
/* ================== SV_Trace Moves the given mins/maxs volume through the world from start to end. Passedict and edicts owned by passedict are explicitly not checked. ================== */ trace_t q_gameabi SV_Trace(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask) { trace_t trace; if (!sv.cm.cache) { Com_Error(ERR_DROP, "%s: no map loaded", __func__); } // work around game bugs if (++sv.tracecount > 10000) { Com_EPrintf("%s: runaway loop avoided\n", __func__); memset(&trace, 0, sizeof(trace)); trace.fraction = 1; trace.ent = ge->edicts; VectorCopy(end, trace.endpos); sv.tracecount = 0; return trace; } if (!mins) mins = vec3_origin; if (!maxs) maxs = vec3_origin; // clip to world CM_BoxTrace(&trace, start, end, mins, maxs, sv.cm.cache->nodes, contentmask); trace.ent = ge->edicts; if (trace.fraction == 0) { return trace; // blocked by the world } // clip to other solid entities SV_ClipMoveToEntities(start, mins, maxs, end, passedict, contentmask, &trace); return trace; }