00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "q_shared.h"
00026 #include "bg_public.h"
00027 #include "bg_local.h"
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #define MAX_CLIP_PLANES 5
00045 qboolean PM_SlideMove( qboolean gravity ) {
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
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
00080 if ( pml.groundPlane ) {
00081 numplanes = 1;
00082 VectorCopy( pml.groundTrace.plane.normal, planes[0] );
00083 } else {
00084 numplanes = 0;
00085 }
00086
00087
00088 VectorNormalize2( pm->ps->velocity, planes[numplanes] );
00089 numplanes++;
00090
00091 for ( bumpcount=0 ; bumpcount < numbumps ; bumpcount++ ) {
00092
00093
00094 VectorMA( pm->ps->origin, time_left, pm->ps->velocity, end );
00095
00096
00097 pm->trace ( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, pm->tracemask);
00098
00099 if (trace.allsolid) {
00100
00101 pm->ps->velocity[2] = 0;
00102 return qtrue;
00103 }
00104
00105 if (trace.fraction > 0) {
00106
00107 VectorCopy (trace.endpos, pm->ps->origin);
00108 }
00109
00110 if (trace.fraction == 1) {
00111 break;
00112 }
00113
00114
00115 PM_AddTouchEnt( trace.entityNum );
00116
00117 time_left -= time_left * trace.fraction;
00118
00119 if (numplanes >= MAX_CLIP_PLANES) {
00120
00121 VectorClear( pm->ps->velocity );
00122 return qtrue;
00123 }
00124
00125
00126
00127
00128
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
00144
00145
00146
00147 for ( i = 0 ; i < numplanes ; i++ ) {
00148 into = DotProduct( pm->ps->velocity, planes[i] );
00149 if ( into >= 0.1 ) {
00150 continue;
00151 }
00152
00153
00154 if ( -into > pml.impactSpeed ) {
00155 pml.impactSpeed = -into;
00156 }
00157
00158
00159 PM_ClipVelocity (pm->ps->velocity, planes[i], clipVelocity, OVERCLIP );
00160
00161
00162 PM_ClipVelocity (endVelocity, planes[i], endClipVelocity, OVERCLIP );
00163
00164
00165 for ( j = 0 ; j < numplanes ; j++ ) {
00166 if ( j == i ) {
00167 continue;
00168 }
00169 if ( DotProduct( clipVelocity, planes[j] ) >= 0.1 ) {
00170 continue;
00171 }
00172
00173
00174 PM_ClipVelocity( clipVelocity, planes[j], clipVelocity, OVERCLIP );
00175 PM_ClipVelocity( endClipVelocity, planes[j], endClipVelocity, OVERCLIP );
00176
00177
00178 if ( DotProduct( clipVelocity, planes[i] ) >= 0 ) {
00179 continue;
00180 }
00181
00182
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
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;
00200 }
00201
00202
00203 VectorClear( pm->ps->velocity );
00204 return qtrue;
00205 }
00206 }
00207
00208
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
00220 if ( pm->ps->pm_time ) {
00221 VectorCopy( primal_velocity, pm->ps->velocity );
00222 }
00223
00224 return ( bumpcount != 0 );
00225 }
00226
00227
00228
00229
00230
00231
00232
00233 void PM_StepSlideMove( qboolean gravity ) {
00234 vec3_t start_o, start_v;
00235 vec3_t down_o, down_v;
00236 trace_t trace;
00237
00238
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;
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
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
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;
00272 }
00273
00274 stepSize = trace.endpos[2] - start_o[2];
00275
00276 VectorCopy (trace.endpos, pm->ps->origin);
00277 VectorCopy (start_v, pm->ps->velocity);
00278
00279 PM_SlideMove( gravity );
00280
00281
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
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
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
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 }
00325