Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

bg_slidemove.c File Reference

#include "q_shared.h"
#include "bg_public.h"
#include "bg_local.h"

Include dependency graph for bg_slidemove.c:

Include dependency graph

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)


Define Documentation

#define MAX_CLIP_PLANES   5
 

Definition at line 44 of file bg_slidemove.c.


Function Documentation

qboolean PM_SlideMove qboolean  gravity  ) 
 

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:

void PM_StepSlideMove qboolean  gravity  ) 
 

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:


Generated on Thu Aug 25 13:47:03 2005 for Quake III Arena by  doxygen 1.3.9.1