#include "cm_local.h"
Include dependency graph for cm_trace.c:

Go to the source code of this file.
|
|
Definition at line 410 of file cm_trace.c. |
|
|
Definition at line 720 of file cm_trace.c. Referenced by CM_TraceCapsuleThroughCapsule(). |
|
||||||||||||||||||||||||||||||||||||
|
Definition at line 1367 of file cm_trace.c. References CM_Trace(), NULL, and vec3_origin. Referenced by BotImport_Trace(), CL_CgameSystemCalls(), and SV_Trace(). 01369 {
01370 CM_Trace( results, start, end, mins, maxs, model, vec3_origin, brushmask, capsule, NULL );
01371 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 96 of file cm_trace.c. References CM_ProjectPointOntoVector(), fabs(), j, p, t, vec3_t, VectorLengthSquared(), and VectorSubtract. Referenced by CM_TraceThroughSphere(), and CM_TraceThroughVerticalCylinder(). 00096 {
00097 vec3_t proj, t;
00098 int j;
00099
00100 CM_ProjectPointOntoVector(p, lp1, dir, proj);
00101 for (j = 0; j < 3; j++)
00102 if ((proj[j] > lp1[j] && proj[j] > lp2[j]) ||
00103 (proj[j] < lp1[j] && proj[j] < lp2[j]))
00104 break;
00105 if (j < 3) {
00106 if (fabs(proj[j] - lp1[j]) < fabs(proj[j] - lp2[j]))
00107 VectorSubtract(p, lp1, t);
00108 else
00109 VectorSubtract(p, lp2, t);
00110 return VectorLengthSquared(t);
00111 }
00112 VectorSubtract(p, proj, t);
00113 return VectorLengthSquared(t);
00114 }
|
Here is the call graph for this function:

|
|
Definition at line 411 of file cm_trace.c. References trace_t::allsolid, leafList_s::bounds, clipMap_t::checkcount, cm, CM_BoxLeafnums_r(), CM_TestInLeaf(), leafList_s::count, i, leafList_s::lastLeaf, leafList_t, clipMap_t::leafs, leafs, leafList_s::list, leafList_s::maxcount, leafList_s::overflowed, traceWork_t::size, traceWork_t::start, leafList_s::storeLeafs, traceWork_t::trace, and VectorAdd. Referenced by CM_Trace(). 00411 {
00412 int leafs[MAX_POSITION_LEAFS];
00413 int i;
00414 leafList_t ll;
00415
00416 // identify the leafs we are touching
00417 VectorAdd( tw->start, tw->size[0], ll.bounds[0] );
00418 VectorAdd( tw->start, tw->size[1], ll.bounds[1] );
00419
00420 for (i=0 ; i<3 ; i++) {
00421 ll.bounds[0][i] -= 1;
00422 ll.bounds[1][i] += 1;
00423 }
00424
00425 ll.count = 0;
00426 ll.maxcount = MAX_POSITION_LEAFS;
00427 ll.list = leafs;
00428 ll.storeLeafs = CM_StoreLeafs;
00429 ll.lastLeaf = 0;
00430 ll.overflowed = qfalse;
00431
00432 cm.checkcount++;
00433
00434 CM_BoxLeafnums_r( &ll, 0 );
00435
00436
00437 cm.checkcount++;
00438
00439 // test the contents of the leafs
00440 for (i=0 ; i < ll.count ; i++) {
00441 CM_TestInLeaf( tw, &cm.leafs[leafs[i]] );
00442 if ( tw->trace.allsolid ) {
00443 break;
00444 }
00445 }
00446 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 82 of file cm_trace.c. References DotProduct, point, vec3_t, VectorMA, and VectorSubtract. Referenced by CM_DistanceFromLineSquared(). 00083 {
00084 vec3_t pVec;
00085
00086 VectorSubtract( point, vStart, pVec );
00087 // project onto the directional vector for this segment
00088 VectorMA( vStart, DotProduct( pVec, vDir ), vDir, vProj );
00089 }
|
|
||||||||||||
|
Definition at line 374 of file cm_trace.c. References clipHandle_t, CM_ClipHandleToModel(), CM_ModelBounds(), CM_TempBoxModel(), CM_TestInLeaf(), cmodel_t, traceWork_t::end, h(), sphere_t::halfheight, i, cmodel_s::leaf, sphere_t::offset, offset, qfalse, sphere_t::radius, traceWork_t::size, traceWork_t::sphere, traceWork_t::start, sphere_t::use, vec3_t, and VectorSet. Referenced by CM_Trace(). 00374 {
00375 vec3_t mins, maxs, offset, size[2];
00376 clipHandle_t h;
00377 cmodel_t *cmod;
00378 int i;
00379
00380 // mins maxs of the capsule
00381 CM_ModelBounds(model, mins, maxs);
00382
00383 // offset for capsule center
00384 for ( i = 0 ; i < 3 ; i++ ) {
00385 offset[i] = ( mins[i] + maxs[i] ) * 0.5;
00386 size[0][i] = mins[i] - offset[i];
00387 size[1][i] = maxs[i] - offset[i];
00388 tw->start[i] -= offset[i];
00389 tw->end[i] -= offset[i];
00390 }
00391
00392 // replace the bounding box with the capsule
00393 tw->sphere.use = qtrue;
00394 tw->sphere.radius = ( size[1][0] > size[1][2] ) ? size[1][2]: size[1][0];
00395 tw->sphere.halfheight = size[1][2];
00396 VectorSet( tw->sphere.offset, 0, 0, size[1][2] - tw->sphere.radius );
00397
00398 // replace the capsule with the bounding box
00399 h = CM_TempBoxModel(tw->size[0], tw->size[1], qfalse);
00400 // calculate collision
00401 cmod = CM_ClipHandleToModel( h );
00402 CM_TestInLeaf( tw, &cmod->leaf );
00403 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 162 of file cm_trace.c. References trace_t::allsolid, cbrush_t::bounds, traceWork_t::bounds, cbrush_t::contents, trace_t::contents, cplane_t, cplane_s::dist, DotProduct, trace_t::fraction, i, cplane_s::normal, cbrush_t::numsides, sphere_t::offset, traceWork_t::offsets, cbrushside_t::plane, sphere_t::radius, cbrush_t::sides, cplane_s::signbits, traceWork_t::sphere, traceWork_t::start, trace_t::startsolid, t, traceWork_t::trace, sphere_t::use, vec3_t, VectorAdd, and VectorSubtract. Referenced by CM_TestInLeaf(). 00162 {
00163 int i;
00164 cplane_t *plane;
00165 float dist;
00166 float d1;
00167 cbrushside_t *side;
00168 float t;
00169 vec3_t startp;
00170
00171 if (!brush->numsides) {
00172 return;
00173 }
00174
00175 // special test for axial
00176 if ( tw->bounds[0][0] > brush->bounds[1][0]
00177 || tw->bounds[0][1] > brush->bounds[1][1]
00178 || tw->bounds[0][2] > brush->bounds[1][2]
00179 || tw->bounds[1][0] < brush->bounds[0][0]
00180 || tw->bounds[1][1] < brush->bounds[0][1]
00181 || tw->bounds[1][2] < brush->bounds[0][2]
00182 ) {
00183 return;
00184 }
00185
00186 if ( tw->sphere.use ) {
00187 // the first six planes are the axial planes, so we only
00188 // need to test the remainder
00189 for ( i = 6 ; i < brush->numsides ; i++ ) {
00190 side = brush->sides + i;
00191 plane = side->plane;
00192
00193 // adjust the plane distance apropriately for radius
00194 dist = plane->dist + tw->sphere.radius;
00195 // find the closest point on the capsule to the plane
00196 t = DotProduct( plane->normal, tw->sphere.offset );
00197 if ( t > 0 )
00198 {
00199 VectorSubtract( tw->start, tw->sphere.offset, startp );
00200 }
00201 else
00202 {
00203 VectorAdd( tw->start, tw->sphere.offset, startp );
00204 }
00205 d1 = DotProduct( startp, plane->normal ) - dist;
00206 // if completely in front of face, no intersection
00207 if ( d1 > 0 ) {
00208 return;
00209 }
00210 }
00211 } else {
00212 // the first six planes are the axial planes, so we only
00213 // need to test the remainder
00214 for ( i = 6 ; i < brush->numsides ; i++ ) {
00215 side = brush->sides + i;
00216 plane = side->plane;
00217
00218 // adjust the plane distance apropriately for mins/maxs
00219 dist = plane->dist - DotProduct( tw->offsets[ plane->signbits ], plane->normal );
00220
00221 d1 = DotProduct( tw->start, plane->normal ) - dist;
00222
00223 // if completely in front of face, no intersection
00224 if ( d1 > 0 ) {
00225 return;
00226 }
00227 }
00228 }
00229
00230 // inside this brush
00231 tw->trace.startsolid = tw->trace.allsolid = qtrue;
00232 tw->trace.fraction = 0;
00233 tw->trace.contents = brush->contents;
00234 }
|
|
||||||||||||
|
Definition at line 305 of file cm_trace.c. References trace_t::allsolid, bottom, CM_ModelBounds(), trace_t::fraction, i, offset, sphere_t::offset, p2, r, sphere_t::radius, traceWork_t::sphere, Square, traceWork_t::start, trace_t::startsolid, top, traceWork_t::trace, vec3_t, VectorAdd, VectorCopy, VectorLengthSquared(), and VectorSubtract. Referenced by CM_Trace(). 00305 {
00306 int i;
00307 vec3_t mins, maxs;
00308 vec3_t top, bottom;
00309 vec3_t p1, p2, tmp;
00310 vec3_t offset, symetricSize[2];
00311 float radius, halfwidth, halfheight, offs, r;
00312
00313 CM_ModelBounds(model, mins, maxs);
00314
00315 VectorAdd(tw->start, tw->sphere.offset, top);
00316 VectorSubtract(tw->start, tw->sphere.offset, bottom);
00317 for ( i = 0 ; i < 3 ; i++ ) {
00318 offset[i] = ( mins[i] + maxs[i] ) * 0.5;
00319 symetricSize[0][i] = mins[i] - offset[i];
00320 symetricSize[1][i] = maxs[i] - offset[i];
00321 }
00322 halfwidth = symetricSize[ 1 ][ 0 ];
00323 halfheight = symetricSize[ 1 ][ 2 ];
00324 radius = ( halfwidth > halfheight ) ? halfheight : halfwidth;
00325 offs = halfheight - radius;
00326
00327 r = Square(tw->sphere.radius + radius);
00328 // check if any of the spheres overlap
00329 VectorCopy(offset, p1);
00330 p1[2] += offs;
00331 VectorSubtract(p1, top, tmp);
00332 if ( VectorLengthSquared(tmp) < r ) {
00333 tw->trace.startsolid = tw->trace.allsolid = qtrue;
00334 tw->trace.fraction = 0;
00335 }
00336 VectorSubtract(p1, bottom, tmp);
00337 if ( VectorLengthSquared(tmp) < r ) {
00338 tw->trace.startsolid = tw->trace.allsolid = qtrue;
00339 tw->trace.fraction = 0;
00340 }
00341 VectorCopy(offset, p2);
00342 p2[2] -= offs;
00343 VectorSubtract(p2, top, tmp);
00344 if ( VectorLengthSquared(tmp) < r ) {
00345 tw->trace.startsolid = tw->trace.allsolid = qtrue;
00346 tw->trace.fraction = 0;
00347 }
00348 VectorSubtract(p2, bottom, tmp);
00349 if ( VectorLengthSquared(tmp) < r ) {
00350 tw->trace.startsolid = tw->trace.allsolid = qtrue;
00351 tw->trace.fraction = 0;
00352 }
00353 // if between cylinder up and lower bounds
00354 if ( (top[2] >= p1[2] && top[2] <= p2[2]) ||
00355 (bottom[2] >= p1[2] && bottom[2] <= p2[2]) ) {
00356 // 2d coordinates
00357 top[2] = p1[2] = 0;
00358 // if the cylinders overlap
00359 VectorSubtract(top, p1, tmp);
00360 if ( VectorLengthSquared(tmp) < r ) {
00361 tw->trace.startsolid = tw->trace.allsolid = qtrue;
00362 tw->trace.fraction = 0;
00363 }
00364 }
00365 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 243 of file cm_trace.c. References trace_t::allsolid, b, clipMap_t::brushes, cPatch_t::checkcount, clipMap_t::checkcount, cbrush_t::checkcount, cm, cm_noCurves, CM_PositionTestInPatchCollide(), CM_TestBoxInBrush(), trace_t::contents, cPatch_t::contents, traceWork_t::contents, cbrush_t::contents, cLeaf_t::firstLeafBrush, cLeaf_t::firstLeafSurface, trace_t::fraction, cvar_s::integer, k, clipMap_t::leafbrushes, clipMap_t::leafsurfaces, cLeaf_t::numLeafBrushes, cLeaf_t::numLeafSurfaces, cPatch_t::pc, trace_t::startsolid, clipMap_t::surfaces, and traceWork_t::trace. Referenced by CM_PositionTest(), CM_TestBoundingBoxInCapsule(), and CM_Trace(). 00243 {
00244 int k;
00245 int brushnum;
00246 cbrush_t *b;
00247 cPatch_t *patch;
00248
00249 // test box position against all brushes in the leaf
00250 for (k=0 ; k<leaf->numLeafBrushes ; k++) {
00251 brushnum = cm.leafbrushes[leaf->firstLeafBrush+k];
00252 b = &cm.brushes[brushnum];
00253 if (b->checkcount == cm.checkcount) {
00254 continue; // already checked this brush in another leaf
00255 }
00256 b->checkcount = cm.checkcount;
00257
00258 if ( !(b->contents & tw->contents)) {
00259 continue;
00260 }
00261
00262 CM_TestBoxInBrush( tw, b );
00263 if ( tw->trace.allsolid ) {
00264 return;
00265 }
00266 }
00267
00268 // test against all patches
00269 #ifdef BSPC
00270 if (1) {
00271 #else
00272 if ( !cm_noCurves->integer ) {
00273 #endif //BSPC
00274 for ( k = 0 ; k < leaf->numLeafSurfaces ; k++ ) {
00275 patch = cm.surfaces[ cm.leafsurfaces[ leaf->firstLeafSurface + k ] ];
00276 if ( !patch ) {
00277 continue;
00278 }
00279 if ( patch->checkcount == cm.checkcount ) {
00280 continue; // already checked this brush in another leaf
00281 }
00282 patch->checkcount = cm.checkcount;
00283
00284 if ( !(patch->contents & tw->contents)) {
00285 continue;
00286 }
00287
00288 if ( CM_PositionTestInPatchCollide( tw, patch->pc ) ) {
00289 tw->trace.startsolid = tw->trace.allsolid = qtrue;
00290 tw->trace.fraction = 0;
00291 tw->trace.contents = patch->contents;
00292 return;
00293 }
00294 }
00295 }
00296 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||||||||||||||
|
Definition at line 1149 of file cm_trace.c. References assert, BOX_MODEL_HANDLE, c_traces, clipMap_t::checkcount, cm, CM_ClipHandleToModel(), CM_PositionTest(), CM_TestBoundingBoxInCapsule(), CM_TestCapsuleInCapsule(), CM_TestInLeaf(), CM_TraceBoundingBoxThroughCapsule(), CM_TraceCapsuleThroughCapsule(), CM_TraceThroughLeaf(), CM_TraceThroughTree(), cmodel_t, Com_Memset(), trace_t::contents, fabs(), sphere_t::halfheight, i, cmodel_s::leaf, clipMap_t::numNodes, offset, sphere_t::radius, sphere_t::use, vec3_t, VectorClear, VectorCopy, VectorLengthSquared(), and VectorSet. Referenced by CM_BoxTrace(), and CM_TransformedBoxTrace(). 01150 {
01151 int i;
01152 traceWork_t tw;
01153 vec3_t offset;
01154 cmodel_t *cmod;
01155
01156 cmod = CM_ClipHandleToModel( model );
01157
01158 cm.checkcount++; // for multi-check avoidance
01159
01160 c_traces++; // for statistics, may be zeroed
01161
01162 // fill in a default trace
01163 Com_Memset( &tw, 0, sizeof(tw) );
01164 tw.trace.fraction = 1; // assume it goes the entire distance until shown otherwise
01165 VectorCopy(origin, tw.modelOrigin);
01166
01167 if (!cm.numNodes) {
01168 *results = tw.trace;
01169
01170 return; // map not loaded, shouldn't happen
01171 }
01172
01173 // allow NULL to be passed in for 0,0,0
01174 if ( !mins ) {
01175 mins = vec3_origin;
01176 }
01177 if ( !maxs ) {
01178 maxs = vec3_origin;
01179 }
01180
01181 // set basic parms
01182 tw.contents = brushmask;
01183
01184 // adjust so that mins and maxs are always symetric, which
01185 // avoids some complications with plane expanding of rotated
01186 // bmodels
01187 for ( i = 0 ; i < 3 ; i++ ) {
01188 offset[i] = ( mins[i] + maxs[i] ) * 0.5;
01189 tw.size[0][i] = mins[i] - offset[i];
01190 tw.size[1][i] = maxs[i] - offset[i];
01191 tw.start[i] = start[i] + offset[i];
01192 tw.end[i] = end[i] + offset[i];
01193 }
01194
01195 // if a sphere is already specified
01196 if ( sphere ) {
01197 tw.sphere = *sphere;
01198 }
01199 else {
01200 tw.sphere.use = capsule;
01201 tw.sphere.radius = ( tw.size[1][0] > tw.size[1][2] ) ? tw.size[1][2]: tw.size[1][0];
01202 tw.sphere.halfheight = tw.size[1][2];
01203 VectorSet( tw.sphere.offset, 0, 0, tw.size[1][2] - tw.sphere.radius );
01204 }
01205
01206 tw.maxOffset = tw.size[1][0] + tw.size[1][1] + tw.size[1][2];
01207
01208 // tw.offsets[signbits] = vector to apropriate corner from origin
01209 tw.offsets[0][0] = tw.size[0][0];
01210 tw.offsets[0][1] = tw.size[0][1];
01211 tw.offsets[0][2] = tw.size[0][2];
01212
01213 tw.offsets[1][0] = tw.size[1][0];
01214 tw.offsets[1][1] = tw.size[0][1];
01215 tw.offsets[1][2] = tw.size[0][2];
01216
01217 tw.offsets[2][0] = tw.size[0][0];
01218 tw.offsets[2][1] = tw.size[1][1];
01219 tw.offsets[2][2] = tw.size[0][2];
01220
01221 tw.offsets[3][0] = tw.size[1][0];
01222 tw.offsets[3][1] = tw.size[1][1];
01223 tw.offsets[3][2] = tw.size[0][2];
01224
01225 tw.offsets[4][0] = tw.size[0][0];
01226 tw.offsets[4][1] = tw.size[0][1];
01227 tw.offsets[4][2] = tw.size[1][2];
01228
01229 tw.offsets[5][0] = tw.size[1][0];
01230 tw.offsets[5][1] = tw.size[0][1];
01231 tw.offsets[5][2] = tw.size[1][2];
01232
01233 tw.offsets[6][0] = tw.size[0][0];
01234 tw.offsets[6][1] = tw.size[1][1];
01235 tw.offsets[6][2] = tw.size[1][2];
01236
01237 tw.offsets[7][0] = tw.size[1][0];
01238 tw.offsets[7][1] = tw.size[1][1];
01239 tw.offsets[7][2] = tw.size[1][2];
01240
01241 //
01242 // calculate bounds
01243 //
01244 if ( tw.sphere.use ) {
01245 for ( i = 0 ; i < 3 ; i++ ) {
01246 if ( tw.start[i] < tw.end[i] ) {
01247 tw.bounds[0][i] = tw.start[i] - fabs(tw.sphere.offset[i]) - tw.sphere.radius;
01248 tw.bounds[1][i] = tw.end[i] + fabs(tw.sphere.offset[i]) + tw.sphere.radius;
01249 } else {
01250 tw.bounds[0][i] = tw.end[i] - fabs(tw.sphere.offset[i]) - tw.sphere.radius;
01251 tw.bounds[1][i] = tw.start[i] + fabs(tw.sphere.offset[i]) + tw.sphere.radius;
01252 }
01253 }
01254 }
01255 else {
01256 for ( i = 0 ; i < 3 ; i++ ) {
01257 if ( tw.start[i] < tw.end[i] ) {
01258 tw.bounds[0][i] = tw.start[i] + tw.size[0][i];
01259 tw.bounds[1][i] = tw.end[i] + tw.size[1][i];
01260 } else {
01261 tw.bounds[0][i] = tw.end[i] + tw.size[0][i];
01262 tw.bounds[1][i] = tw.start[i] + tw.size[1][i];
01263 }
01264 }
01265 }
01266
01267 //
01268 // check for position test special case
01269 //
01270 if (start[0] == end[0] && start[1] == end[1] && start[2] == end[2]) {
01271 if ( model ) {
01272 #ifdef ALWAYS_BBOX_VS_BBOX // bk010201 - FIXME - compile time flag?
01273 if ( model == BOX_MODEL_HANDLE || model == CAPSULE_MODEL_HANDLE) {
01274 tw.sphere.use = qfalse;
01275 CM_TestInLeaf( &tw, &cmod->leaf );
01276 }
01277 else
01278 #elif defined(ALWAYS_CAPSULE_VS_CAPSULE)
01279 if ( model == BOX_MODEL_HANDLE || model == CAPSULE_MODEL_HANDLE) {
01280 CM_TestCapsuleInCapsule( &tw, model );
01281 }
01282 else
01283 #endif
01284 if ( model == CAPSULE_MODEL_HANDLE ) {
01285 if ( tw.sphere.use ) {
01286 CM_TestCapsuleInCapsule( &tw, model );
01287 }
01288 else {
01289 CM_TestBoundingBoxInCapsule( &tw, model );
01290 }
01291 }
01292 else {
01293 CM_TestInLeaf( &tw, &cmod->leaf );
01294 }
01295 } else {
01296 CM_PositionTest( &tw );
01297 }
01298 } else {
01299 //
01300 // check for point special case
01301 //
01302 if ( tw.size[0][0] == 0 && tw.size[0][1] == 0 && tw.size[0][2] == 0 ) {
01303 tw.isPoint = qtrue;
01304 VectorClear( tw.extents );
01305 } else {
01306 tw.isPoint = qfalse;
01307 tw.extents[0] = tw.size[1][0];
01308 tw.extents[1] = tw.size[1][1];
01309 tw.extents[2] = tw.size[1][2];
01310 }
01311
01312 //
01313 // general sweeping through world
01314 //
01315 if ( model ) {
01316 #ifdef ALWAYS_BBOX_VS_BBOX
01317 if ( model == BOX_MODEL_HANDLE || model == CAPSULE_MODEL_HANDLE) {
01318 tw.sphere.use = qfalse;
01319 CM_TraceThroughLeaf( &tw, &cmod->leaf );
01320 }
01321 else
01322 #elif defined(ALWAYS_CAPSULE_VS_CAPSULE)
01323 if ( model == BOX_MODEL_HANDLE || model == CAPSULE_MODEL_HANDLE) {
01324 CM_TraceCapsuleThroughCapsule( &tw, model );
01325 }
01326 else
01327 #endif
01328 if ( model == CAPSULE_MODEL_HANDLE ) {
01329 if ( tw.sphere.use ) {
01330 CM_TraceCapsuleThroughCapsule( &tw, model );
01331 }
01332 else {
01333 CM_TraceBoundingBoxThroughCapsule( &tw, model );
01334 }
01335 }
01336 else {
01337 CM_TraceThroughLeaf( &tw, &cmod->leaf );
01338 }
01339 } else {
01340 CM_TraceThroughTree( &tw, 0, 0, 1, tw.start, tw.end );
01341 }
01342 }
01343
01344 // generate endpos from the original, unmodified start/end
01345 if ( tw.trace.fraction == 1 ) {
01346 VectorCopy (end, tw.trace.endpos);
01347 } else {
01348 for ( i=0 ; i<3 ; i++ ) {
01349 tw.trace.endpos[i] = start[i] + tw.trace.fraction * (end[i] - start[i]);
01350 }
01351 }
01352
01353 // If allsolid is set (was entirely inside something solid), the plane is not valid.
01354 // If fraction == 1.0, we never hit anything, and thus the plane is not valid.
01355 // Otherwise, the normal on the plane should have unit length
01356 assert(tw.trace.allsolid ||
01357 tw.trace.fraction == 1.0 ||
01358 VectorLengthSquared(tw.trace.plane.normal) > 0.9999);
01359 *results = tw.trace;
01360 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 982 of file cm_trace.c. References clipHandle_t, CM_ClipHandleToModel(), CM_ModelBounds(), CM_TempBoxModel(), CM_TraceThroughLeaf(), cmodel_t, traceWork_t::end, h(), sphere_t::halfheight, i, cmodel_s::leaf, sphere_t::offset, offset, qfalse, sphere_t::radius, traceWork_t::size, traceWork_t::sphere, traceWork_t::start, sphere_t::use, vec3_t, and VectorSet. Referenced by CM_Trace(). 00982 {
00983 vec3_t mins, maxs, offset, size[2];
00984 clipHandle_t h;
00985 cmodel_t *cmod;
00986 int i;
00987
00988 // mins maxs of the capsule
00989 CM_ModelBounds(model, mins, maxs);
00990
00991 // offset for capsule center
00992 for ( i = 0 ; i < 3 ; i++ ) {
00993 offset[i] = ( mins[i] + maxs[i] ) * 0.5;
00994 size[0][i] = mins[i] - offset[i];
00995 size[1][i] = maxs[i] - offset[i];
00996 tw->start[i] -= offset[i];
00997 tw->end[i] -= offset[i];
00998 }
00999
01000 // replace the bounding box with the capsule
01001 tw->sphere.use = qtrue;
01002 tw->sphere.radius = ( size[1][0] > size[1][2] ) ? size[1][2]: size[1][0];
01003 tw->sphere.halfheight = size[1][2];
01004 VectorSet( tw->sphere.offset, 0, 0, size[1][2] - tw->sphere.radius );
01005
01006 // replace the capsule with the bounding box
01007 h = CM_TempBoxModel(tw->size[0], tw->size[1], qfalse);
01008 // calculate collision
01009 cmod = CM_ClipHandleToModel( h );
01010 CM_TraceThroughLeaf( tw, &cmod->leaf );
01011 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 920 of file cm_trace.c. References bottom, traceWork_t::bounds, CM_ModelBounds(), CM_TraceThroughSphere(), CM_TraceThroughVerticalCylinder(), traceWork_t::end, h(), sphere_t::halfheight, i, offset, sphere_t::offset, sphere_t::radius, RADIUS_EPSILON, traceWork_t::sphere, traceWork_t::start, top, vec3_t, VectorAdd, VectorCopy, and VectorSubtract. Referenced by CM_Trace(). 00920 {
00921 int i;
00922 vec3_t mins, maxs;
00923 vec3_t top, bottom, starttop, startbottom, endtop, endbottom;
00924 vec3_t offset, symetricSize[2];
00925 float radius, halfwidth, halfheight, offs, h;
00926
00927 CM_ModelBounds(model, mins, maxs);
00928 // test trace bounds vs. capsule bounds
00929 if ( tw->bounds[0][0] > maxs[0] + RADIUS_EPSILON
00930 || tw->bounds[0][1] > maxs[1] + RADIUS_EPSILON
00931 || tw->bounds[0][2] > maxs[2] + RADIUS_EPSILON
00932 || tw->bounds[1][0] < mins[0] - RADIUS_EPSILON
00933 || tw->bounds[1][1] < mins[1] - RADIUS_EPSILON
00934 || tw->bounds[1][2] < mins[2] - RADIUS_EPSILON
00935 ) {
00936 return;
00937 }
00938 // top origin and bottom origin of each sphere at start and end of trace
00939 VectorAdd(tw->start, tw->sphere.offset, starttop);
00940 VectorSubtract(tw->start, tw->sphere.offset, startbottom);
00941 VectorAdd(tw->end, tw->sphere.offset, endtop);
00942 VectorSubtract(tw->end, tw->sphere.offset, endbottom);
00943
00944 // calculate top and bottom of the capsule spheres to collide with
00945 for ( i = 0 ; i < 3 ; i++ ) {
00946 offset[i] = ( mins[i] + maxs[i] ) * 0.5;
00947 symetricSize[0][i] = mins[i] - offset[i];
00948 symetricSize[1][i] = maxs[i] - offset[i];
00949 }
00950 halfwidth = symetricSize[ 1 ][ 0 ];
00951 halfheight = symetricSize[ 1 ][ 2 ];
00952 radius = ( halfwidth > halfheight ) ? halfheight : halfwidth;
00953 offs = halfheight - radius;
00954 VectorCopy(offset, top);
00955 top[2] += offs;
00956 VectorCopy(offset, bottom);
00957 bottom[2] -= offs;
00958 // expand radius of spheres
00959 radius += tw->sphere.radius;
00960 // if there is horizontal movement
00961 if ( tw->start[0] != tw->end[0] || tw->start[1] != tw->end[1] ) {
00962 // height of the expanded cylinder is the height of both cylinders minus the radius of both spheres
00963 h = halfheight + tw->sphere.halfheight - radius;
00964 // if the cylinder has a height
00965 if ( h > 0 ) {
00966 // test for collisions between the cylinders
00967 CM_TraceThroughVerticalCylinder(tw, offset, radius, h, tw->start, tw->end);
00968 }
00969 }
00970 // test for collision between the spheres
00971 CM_TraceThroughSphere(tw, top, radius, startbottom, endbottom);
00972 CM_TraceThroughSphere(tw, bottom, radius, starttop, endtop);
00973 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 483 of file cm_trace.c. References trace_t::allsolid, c_brush_traces, cbrush_t::contents, trace_t::contents, cplane_t, cplane_s::dist, DotProduct, traceWork_t::end, f, trace_t::fraction, i, cplane_s::normal, cbrush_t::numsides, sphere_t::offset, traceWork_t::offsets, trace_t::plane, cbrushside_t::plane, qboolean, sphere_t::radius, cbrush_t::sides, cplane_s::signbits, traceWork_t::sphere, traceWork_t::start, trace_t::startsolid, SURFACE_CLIP_EPSILON, cbrushside_t::surfaceFlags, trace_t::surfaceFlags, t, traceWork_t::trace, sphere_t::use, vec3_t, VectorAdd, and VectorSubtract. Referenced by CM_TraceThroughLeaf(). 00483 {
00484 int i;
00485 cplane_t *plane, *clipplane;
00486 float dist;
00487 float enterFrac, leaveFrac;
00488 float d1, d2;
00489 qboolean getout, startout;
00490 float f;
00491 cbrushside_t *side, *leadside;
00492 float t;
00493 vec3_t startp;
00494 vec3_t endp;
00495
00496 enterFrac = -1.0;
00497 leaveFrac = 1.0;
00498 clipplane = NULL;
00499
00500 if ( !brush->numsides ) {
00501 return;
00502 }
00503
00504 c_brush_traces++;
00505
00506 getout = qfalse;
00507 startout = qfalse;
00508
00509 leadside = NULL;
00510
00511 if ( tw->sphere.use ) {
00512 //
00513 // compare the trace against all planes of the brush
00514 // find the latest time the trace crosses a plane towards the interior
00515 // and the earliest time the trace crosses a plane towards the exterior
00516 //
00517 for (i = 0; i < brush->numsides; i++) {
00518 side = brush->sides + i;
00519 plane = side->plane;
00520
00521 // adjust the plane distance apropriately for radius
00522 dist = plane->dist + tw->sphere.radius;
00523
00524 // find the closest point on the capsule to the plane
00525 t = DotProduct( plane->normal, tw->sphere.offset );
00526 if ( t > 0 )
00527 {
00528 VectorSubtract( tw->start, tw->sphere.offset, startp );
00529 VectorSubtract( tw->end, tw->sphere.offset, endp );
00530 }
00531 else
00532 {
00533 VectorAdd( tw->start, tw->sphere.offset, startp );
00534 VectorAdd( tw->end, tw->sphere.offset, endp );
00535 }
00536
00537 d1 = DotProduct( startp, plane->normal ) - dist;
00538 d2 = DotProduct( endp, plane->normal ) - dist;
00539
00540 if (d2 > 0) {
00541 getout = q |