#include "q_shared.h"
#include "bg_public.h"
#include "bg_local.h"
Include dependency graph for bg_slidemove.c:

Go to the source code of this file.
Defines | |
| #define | MAX_CLIP_PLANES 5 |
Functions | |
| qboolean | PM_SlideMove (qboolean gravity) |
| void | PM_StepSlideMove (qboolean gravity) |
|
|
Definition at line 44 of file bg_slidemove.c. |
|
|
Definition at line 45 of file bg_slidemove.c. References trace_t::allsolid, playerState_s::clientNum, CrossProduct(), d, DotProduct, trace_t::endpos, trace_t::entityNum, trace_t::fraction, pml_t::frametime, playerState_s::gravity, pml_t::groundPlane, pml_t::groundTrace, i, pml_t::impactSpeed, j, k, pmove_t::maxs, pmove_t::mins, cplane_s::normal, numplanes, playerState_s::origin, OVERCLIP, trace_t::plane, pm, PM_AddTouchEnt(), PM_ClipVelocity(), playerState_s::pm_time, pml, pmove_t::ps, qboolean, pmove_t::trace, pmove_t::tracemask, vec3_t, VectorAdd, VectorClear, VectorCopy, VectorMA, VectorNormalize(), VectorNormalize2(), VectorScale, and playerState_s::velocity. Referenced by PM_AirMove(), PM_StepSlideMove(), and PM_WaterMove(). 00045 {
00046 int bumpcount, numbumps;
00047 vec3_t dir;
00048 float d;
00049 int numplanes;
00050 vec3_t planes[MAX_CLIP_PLANES];
00051 vec3_t primal_velocity;
00052 vec3_t clipVelocity;
00053 int i, j, k;
00054 trace_t trace;
00055 vec3_t end;
00056 float time_left;
00057 float into;
00058 vec3_t endVelocity;
00059 vec3_t endClipVelocity;
00060
00061 numbumps = 4;
00062
00063 VectorCopy (pm->ps->velocity, primal_velocity);
00064
00065 if ( gravity ) {
00066 VectorCopy( pm->ps->velocity, endVelocity );
00067 endVelocity[2] -= pm->ps->gravity * pml.frametime;
00068 pm->ps->velocity[2] = ( pm->ps->velocity[2] + endVelocity[2] ) * 0.5;
00069 primal_velocity[2] = endVelocity[2];
00070 if ( pml.groundPlane ) {
00071 // slide along the ground plane
00072 PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal,
00073 pm->ps->velocity, OVERCLIP );
00074 }
00075 }
00076
00077 time_left = pml.frametime;
00078
00079 // never turn against the ground plane
00080 if ( pml.groundPlane ) {
00081 numplanes = 1;
00082 VectorCopy( pml.groundTrace.plane.normal, planes[0] );
00083 } else {
00084 numplanes = 0;
00085 }
00086
00087 // never turn against original velocity
00088 VectorNormalize2( pm->ps->velocity, planes[numplanes] );
00089 numplanes++;
00090
00091 for ( bumpcount=0 ; bumpcount < numbumps ; bumpcount++ ) {
00092
00093 // calculate position we are trying to move to
00094 VectorMA( pm->ps->origin, time_left, pm->ps->velocity, end );
00095
00096 // see if we can make it there
00097 pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask);
00098
00099 if (trace.allsolid) {
00100 // entity is completely trapped in another solid
00101 pm->ps->velocity[2] = 0; // don't build up falling damage, but allow sideways acceleration
00102 return qtrue;
00103 }
00104
00105 if (trace.fraction > 0) {
00106 // actually covered some distance
00107 VectorCopy (trace.endpos, pm->ps->origin);
00108 }
00109
00110 if (trace.fraction == 1) {
00111 break; // moved the entire distance
00112 }
00113
00114 // save entity for contact
00115 PM_AddTouchEnt( trace.entityNum );
00116
00117 time_left -= time_left * trace.fraction;
00118
00119 if (numplanes >= MAX_CLIP_PLANES) {
00120 // this shouldn't really happen
00121 VectorClear( pm->ps->velocity );
00122 return qtrue;
00123 }
00124
00125 //
00126 // if this is the same plane we hit before, nudge velocity
00127 // out along it, which fixes some epsilon issues with
00128 // non-axial planes
00129 //
00130 for ( i = 0 ; i < numplanes ; i++ ) {
00131 if ( DotProduct( trace.plane.normal, planes[i] ) > 0.99 ) {
00132 VectorAdd( trace.plane.normal, pm->ps->velocity, pm->ps->velocity );
00133 break;
00134 }
00135 }
00136 if ( i < numplanes ) {
00137 continue;
00138 }
00139 VectorCopy (trace.plane.normal, planes[numplanes]);
00140 numplanes++;
00141
00142 //
00143 // modify velocity so it parallels all of the clip planes
00144 //
00145
00146 // find a plane that it enters
00147 for ( i = 0 ; i < numplanes ; i++ ) {
00148 into = DotProduct( pm->ps->velocity, planes[i] );
00149 if ( into >= 0.1 ) {
00150 continue; // move doesn't interact with the plane
00151 }
00152
00153 // see how hard we are hitting things
00154 if ( -into > pml.impactSpeed ) {
00155 pml.impactSpeed = -into;
00156 }
00157
00158 // slide along the plane
00159 PM_ClipVelocity (pm->ps->velocity, planes[i], clipVelocity, OVERCLIP );
00160
00161 // slide along the plane
00162 PM_ClipVelocity (endVelocity, planes[i], endClipVelocity, OVERCLIP );
00163
00164 // see if there is a second plane that the new move enters
00165 for ( j = 0 ; j < numplanes ; j++ ) {
00166 if ( j == i ) {
00167 continue;
00168 }
00169 if ( DotProduct( clipVelocity, planes[j] ) >= 0.1 ) {
00170 continue; // move doesn't interact with the plane
00171 }
00172
00173 // try clipping the move to the plane
00174 PM_ClipVelocity( clipVelocity, planes[j], clipVelocity, OVERCLIP );
00175 PM_ClipVelocity( endClipVelocity, planes[j], endClipVelocity, OVERCLIP );
00176
00177 // see if it goes back into the first clip plane
00178 if ( DotProduct( clipVelocity, planes[i] ) >= 0 ) {
00179 continue;
00180 }
00181
00182 // slide the original velocity along the crease
00183 CrossProduct (planes[i], planes[j], dir);
00184 VectorNormalize( dir );
00185 d = DotProduct( dir, pm->ps->velocity );
00186 VectorScale( dir, d, clipVelocity );
00187
00188 CrossProduct (planes[i], planes[j], dir);
00189 VectorNormalize( dir );
00190 d = DotProduct( dir, endVelocity );
00191 VectorScale( dir, d, endClipVelocity );
00192
00193 // see if there is a third plane the the new move enters
00194 for ( k = 0 ; k < numplanes ; k++ ) {
00195 if ( k == i || k == j ) {
00196 continue;
00197 }
00198 if ( DotProduct( clipVelocity, planes[k] ) >= 0.1 ) {
00199 continue; // move doesn't interact with the plane
00200 }
00201
00202 // stop dead at a tripple plane interaction
00203 VectorClear( pm->ps->velocity );
00204 return qtrue;
00205 }
00206 }
00207
00208 // if we have fixed all interactions, try another move
00209 VectorCopy( clipVelocity, pm->ps->velocity );
00210 VectorCopy( endClipVelocity, endVelocity );
00211 break;
00212 }
00213 }
00214
00215 if ( gravity ) {
00216 VectorCopy( endVelocity, pm->ps->velocity );
00217 }
00218
00219 // don't change velocity if in a timer (FIXME: is this correct?)
00220 if ( pm->ps->pm_time ) {
00221 VectorCopy( primal_velocity, pm->ps->velocity );
00222 }
00223
00224 return ( bumpcount != 0 );
00225 }
|
Here is the call graph for this function:

|
|
Definition at line 233 of file bg_slidemove.c. References trace_t::allsolid, c_pmove, playerState_s::clientNum, Com_Printf(), pmove_t::debugLevel, DotProduct, down, trace_t::endpos, EV_STEP_12, EV_STEP_16, EV_STEP_4, EV_STEP_8, trace_t::fraction, pmove_t::maxs, pmove_t::mins, cplane_s::normal, playerState_s::origin, OVERCLIP, trace_t::plane, pm, PM_AddEvent(), PM_ClipVelocity(), PM_SlideMove(), pmove_t::ps, pmove_t::trace, pmove_t::tracemask, up, vec3_t, VectorCopy, VectorSet, and playerState_s::velocity. Referenced by PM_AirMove(), PM_FlyMove(), PM_WalkMove(), and PM_WaterJumpMove(). 00233 {
00234 vec3_t start_o, start_v;
00235 vec3_t down_o, down_v;
00236 trace_t trace;
00237 // float down_dist, up_dist;
00238 // vec3_t delta, delta2;
00239 vec3_t up, down;
00240 float stepSize;
00241
00242 VectorCopy (pm->ps->origin, start_o);
00243 VectorCopy (pm->ps->velocity, start_v);
00244
00245 if ( PM_SlideMove( gravity ) == 0 ) {
00246 return; // we got exactly where we wanted to go first try
00247 }
00248
00249 VectorCopy(start_o, down);
00250 down[2] -= STEPSIZE;
00251 pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
00252 VectorSet(up, 0, 0, 1);
00253 // never step up when you still have up velocity
00254 if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
00255 DotProduct(trace.plane.normal, up) < 0.7)) {
00256 return;
00257 }
00258
00259 VectorCopy (pm->ps->origin, down_o);
00260 VectorCopy (pm->ps->velocity, down_v);
00261
00262 VectorCopy (start_o, up);
00263 up[2] += STEPSIZE;
00264
00265 // test the player position if they were a stepheight higher
00266 pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
00267 if ( trace.allsolid ) {
00268 if ( pm->debugLevel ) {
00269 Com_Printf("%i:bend can't step\n", c_pmove);
00270 }
00271 return; // can't step up
00272 }
00273
00274 stepSize = trace.endpos[2] - start_o[2];
00275 // try slidemove from this position
00276 VectorCopy (trace.endpos, pm->ps->origin);
00277 VectorCopy (start_v, pm->ps->velocity);
00278
00279 PM_SlideMove( gravity );
00280
00281 // push down the final amount
00282 VectorCopy (pm->ps->origin, down);
00283 down[2] -= stepSize;
00284 pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
00285 if ( !trace.allsolid ) {
00286 VectorCopy (trace.endpos, pm->ps->origin);
00287 }
00288 if ( trace.fraction < 1.0 ) {
00289 PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
00290 }
00291
00292 #if 0
00293 // if the down trace can trace back to the original position directly, don't step
00294 pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
00295 if ( trace.fraction == 1.0 ) {
00296 // use the original move
00297 VectorCopy (down_o, pm->ps->origin);
00298 VectorCopy (down_v, pm->ps->velocity);
00299 if ( pm->debugLevel ) {
00300 Com_Printf("%i:bend\n", c_pmove);
00301 }
00302 } else
00303 #endif
00304 {
00305 // use the step move
00306 float delta;
00307
00308 delta = pm->ps->origin[2] - start_o[2];
00309 if ( delta > 2 ) {
00310 if ( delta < 7 ) {
00311 PM_AddEvent( EV_STEP_4 );
00312 } else if ( delta < 11 ) {
00313 PM_AddEvent( EV_STEP_8 );
00314 } else if ( delta < 15 ) {
00315 PM_AddEvent( EV_STEP_12 );
00316 } else {
00317 PM_AddEvent( EV_STEP_16 );
00318 }
00319 }
00320 if ( pm->debugLevel ) {
00321 Com_Printf("%i:stepped\n", c_pmove);
00322 }
00323 }
00324 }
|
Here is the call graph for this function:

1.3.9.1