void V_Move( int mx, int my ) { float fov; float fx, fy; float dx, dy; float c_x, c_y; float dX, dY; vec3_t forward, up, right; vec3_t newangles; vec3_t farpoint; pmtrace_t tr; fov = CalcFov( in_fov, (float)ScreenWidth, (float)ScreenHeight ); c_x = (float)ScreenWidth / 2.0; c_y = (float)ScreenHeight / 2.0; dx = (float)mx - c_x; dy = (float)my - c_y; // Proportion we moved in each direction fx = dx / c_x; fy = dy / c_y; dX = fx * in_fov / 2.0 ; dY = fy * fov / 2.0; newangles = v_angles; newangles[ YAW ] -= dX; newangles[ PITCH ] += dY; // Now rotate v_forward around that point AngleVectors ( newangles, forward, right, up ); farpoint = v_origin + 8192 * forward; // Trace tr = *(gEngfuncs.PM_TraceLine( (float *)&v_origin, (float *)&farpoint, PM_TRACELINE_PHYSENTSONLY, 2 /*point sized hull*/, -1 )); if ( tr.fraction != 1.0 && tr.ent != 0 ) { hitent = PM_GetPhysEntInfo( tr.ent ); PM_ParticleLine( (float *)&v_origin, (float *)&tr.endpos, 5, 1.0, 0.0 ); } else { hitent = -1; } }
// Get the origin of the Observer based around the target's position and angles void V_GetChaseOrigin( float * angles, float * origin, float distance, float * returnvec ) { Vector vecStart, vecEnd; pmtrace_t *trace; int maxLoops = 8; Vector forward, right, up; // trace back from the target using the player's view angles AngleVectors( angles, forward, right, up ); forward = -forward; vecStart = origin; vecEnd = vecStart + forward * distance; int ignoreent = -1; // first, ignore no entity cl_entity_t *ent = NULL; while( maxLoops > 0 ) { trace = gEngfuncs.PM_TraceLine( vecStart, vecEnd, PM_TRACELINE_PHYSENTSONLY, 2, ignoreent ); if( trace->ent <= 0 ) break; // we hit the world or nothing, stop trace ent = gEngfuncs.GetEntityByIndex( PM_GetPhysEntInfo( trace->ent )); if( ent == NULL ) break; // hit non-player solid BSP, stop here if( ent->curstate.solid == SOLID_BSP && !ent->player ) break; // if close enought to end pos, stop, otherwise continue trace if( trace->fraction < 1.0f ) { break; } else { ignoreent = trace->ent; // ignore last hit entity vecStart = trace->endpos; } maxLoops--; } VectorMA( trace->endpos, 8, trace->plane.normal, returnvec ); v_lastDistance = (trace->endpos - Vector(origin)).Length(); // real distance without offset }
//========================== // V_GetChaseOrigin //========================== void V_GetChaseOrigin( const Vector &angles, const Vector &origin, float distance, Vector &returnvec ) { Vector vecStart, vecEnd; pmtrace_t *trace; int maxLoops = 8; Vector forward, right, up; // trace back from the target using the player's view angles AngleVectors( angles, forward, right, up ); forward = -forward; vecStart = origin; vecEnd = vecStart + forward * distance; int ignoreent = -1; // first, ignore no entity cl_entity_t *ent = NULL; while( maxLoops > 0 ) { trace = gEngfuncs.PM_TraceLine( vecStart, vecEnd, PM_TRACELINE_PHYSENTSONLY, 2, ignoreent ); if( trace->ent <= 0 ) break; // we hit the world or nothing, stop trace ent = GET_ENTITY( PM_GetPhysEntInfo( trace->ent )); if( ent == NULL ) break; // hit non-player solid BSP, stop here if( ent->curstate.solid == SOLID_BSP && !ent->player ) break; // if close enought to end pos, stop, otherwise continue trace if(( vecEnd - trace->endpos ).Length() < 1.0f ) { break; } else { ignoreent = trace->ent; // ignore last hit entity vecStart = trace->endpos; } maxLoops--; } returnvec = trace->endpos + trace->plane.normal * 8; }
// Get the origin of the Observer based around the target's position and angles void V_GetChaseOrigin( float * angles, float * origin, float distance, float * returnvec ) { vec3_t vecEnd; vec3_t forward; vec3_t vecStart; pmtrace_t * trace; int maxLoops = 8; int ignoreent = -1; // first, ignore no entity cl_entity_t * ent = NULL; // Trace back from the target using the player's view angles AngleVectors(angles, forward, NULL, NULL); VectorScale(forward,-1,forward); VectorCopy( origin, vecStart ); VectorMA(vecStart, distance , forward, vecEnd); while ( maxLoops > 0) { trace = gEngfuncs.PM_TraceLine( vecStart, vecEnd, PM_TRACELINE_PHYSENTSONLY, 2, ignoreent ); // WARNING! trace->ent is is the number in physent list not the normal entity number if ( trace->ent <= 0) break; // we hit the world or nothing, stop trace ent = gEngfuncs.GetEntityByIndex( PM_GetPhysEntInfo( trace->ent ) ); if ( ent == NULL ) break; // hit non-player solid BSP , stop here if ( ent->curstate.solid == SOLID_BSP && !ent->player ) break; // if close enought to end pos, stop, otherwise continue trace if( Distance(trace->endpos, vecEnd ) < 1.0f ) { break; } else { ignoreent = trace->ent; // ignore last hit entity VectorCopy( trace->endpos, vecStart); } maxLoops--; } /* if ( ent ) { gEngfuncs.Con_Printf("Trace loops %i , entity %i, model %s, solid %i\n",(8-maxLoops),ent->curstate.number, ent->model->name , ent->curstate.solid ); } */ VectorMA( trace->endpos, 4, trace->plane.normal, returnvec ); v_lastDistance = Distance(trace->endpos, origin); // real distance without offset }