void V_GetChasePos(int target, float * cl_angles, float * origin, float * angles) { cl_entity_t * ent = NULL; if ( target ) { ent = gEngfuncs.GetEntityByIndex( target ); }; if (!ent) { // just copy a save in-map position VectorCopy ( vJumpAngles, angles ); VectorCopy ( vJumpOrigin, origin ); return; } if ( gHUD.m_Spectator.m_autoDirector->value ) { if ( g_iUser3 ) V_GetDirectedChasePosition( ent, gEngfuncs.GetEntityByIndex( g_iUser3 ), angles, origin ); else V_GetDirectedChasePosition( ent, ( cl_entity_t*)0xFFFFFFFF, angles, origin ); } else { if ( cl_angles == NULL ) // no mouse angles given, use entity angles ( locked mode ) { VectorCopy ( ent->angles, angles); angles[0]*=-1; } else VectorCopy ( cl_angles, angles); VectorCopy ( ent->origin, origin); origin[2]+= 28; // DEFAULT_VIEWHEIGHT - some offset V_GetChaseOrigin( angles, origin, cl_chasedist->value, origin ); } v_resetCamera = false; }
void V_GetDeathCam(cl_entity_t * ent1, cl_entity_t * ent2, float * angle, float * origin) { float newAngle[3]; float newOrigin[3]; static vec3_t nonDestructedOrigin; float distance = 168.0f; v_lastDistance += v_frametime * 96.0f; // move unit per seconds back if ( v_resetCamera ) v_lastDistance = 64.0f; if ( distance > v_lastDistance ) distance = v_lastDistance; if (ent1->origin.x == 0 && ent1->origin.y == 0 && ent1->origin.z == 0) nonDestructedOrigin.CopyToArray(newOrigin); else { nonDestructedOrigin = ent1->origin; VectorCopy(ent1->origin, newOrigin); } if ( ent1->player ) newOrigin[2]+= 17; // head level of living player // get new angle towards second target if ( ent2 ) { VectorSubtract(ent2->origin, nonDestructedOrigin, newAngle); VectorAngles( newAngle, newAngle ); newAngle[0] = -newAngle[0]; } else { // if no second target is given, look down to dead player newAngle[0] = 90.0f; newAngle[1] = 0.0f; newAngle[2] = 0; } // and smooth view V_SmoothInterpolateAngles( v_lastAngles, newAngle, angle, 120.0f ); V_GetChaseOrigin( angle, newOrigin, distance, origin ); VectorCopy(angle, v_lastAngles); }
void V_GetChasePos(int target, const Vector* cl_angles, Vector& origin, Vector& angles) { cl_entity_t * ent = NULL; if ( target ) { ent = gEngfuncs.GetEntityByIndex( target ); }; if (!ent) { // just copy a save in-map position angles = vJumpAngles; origin = vJumpOrigin; return; } if ( gHUD.m_Spectator.m_autoDirector->value ) { if ( g_iUser3 ) V_GetDirectedChasePosition( ent, gEngfuncs.GetEntityByIndex( g_iUser3 ), angles, origin ); else V_GetDirectedChasePosition( ent, ( cl_entity_t*)0xFFFFFFFF, angles, origin ); } else { if ( cl_angles == nullptr ) // no mouse angles given, use entity angles ( locked mode ) { angles = ent->angles; angles[0]*=-1; } else angles = *cl_angles; origin = ent->origin; origin[2]+= DEFAULT_VIEWHEIGHT; // - some offset V_GetChaseOrigin( angles, origin, cl_chasedist->value, origin ); } v_resetCamera = false; }
void V_GetSingleTargetCam(cl_entity_t * ent1, float * angle, float * origin) { float newAngle[3]; float newOrigin[3]; int flags = gHUD.m_Spectator.m_iObserverFlags; // see is target is a dead player qboolean deadPlayer = ent1->player && (ent1->curstate.solid == SOLID_NOT); float dfactor = ( flags & DRC_FLAG_DRAMATIC )? -1.0f : 1.0f; float distance = 112.0f + ( 16.0f * dfactor ); // get close if dramatic; // go away in final scenes or if player just died if ( flags & DRC_FLAG_FINAL ) distance*=2.0f; else if ( deadPlayer ) distance*=1.5f; // let v_lastDistance float smoothly away v_lastDistance+= v_frametime * 32.0f; // move unit per seconds back if ( distance > v_lastDistance ) distance = v_lastDistance; VectorCopy(ent1->origin, newOrigin); if ( ent1->player ) { if ( deadPlayer ) newOrigin[2]+= 2; //laying on ground else newOrigin[2]+= 17; // head level of living player } else newOrigin[2]+= 8; // object, tricky, must be above bomb in CS // we have no second target, choose view direction based on // show front of primary target VectorCopy(ent1->angles, newAngle); // show dead players from front, normal players back if ( flags & DRC_FLAG_FACEPLAYER ) newAngle[1]+= 180.0f; newAngle[0]+= 12.5f * dfactor; // lower angle if dramatic // if final scene (bomb), show from real high pos if ( flags & DRC_FLAG_FINAL ) newAngle[0] = 22.5f; // choose side of object/player if ( flags & DRC_FLAG_SIDE ) newAngle[1]+=22.5f; else newAngle[1]-=22.5f; V_SmoothInterpolateAngles( v_lastAngles, newAngle, angle, 120.0f ); // HACK, if player is dead don't clip against his dead body, can't check this V_GetChaseOrigin( angle, newOrigin, distance, origin ); }
void V_GetDoubleTargetsCam(cl_entity_t * ent1, cl_entity_t * ent2,float * angle, float * origin) { float newAngle[3]; float newOrigin[3]; float tempVec[3]; int flags = gHUD.m_Spectator.m_iObserverFlags; float dfactor = ( flags & DRC_FLAG_DRAMATIC )? -1.0f : 1.0f; float distance = 112.0f + ( 16.0f * dfactor ); // get close if dramatic; // go away in final scenes or if player just died if ( flags & DRC_FLAG_FINAL ) distance*=2.0f; // let v_lastDistance float smoothly away v_lastDistance+= v_frametime * 32.0f; // move unit per seconds back if ( distance > v_lastDistance ) distance = v_lastDistance; VectorCopy(ent1->origin, newOrigin); if ( ent1->player ) newOrigin[2]+= 17; // head level of living player else newOrigin[2]+= 8; // object, tricky, must be above bomb in CS // get new angle towards second target VectorSubtract( ent2->origin, ent1->origin, newAngle ); VectorAngles( newAngle, newAngle ); newAngle[0] = -newAngle[0]; // set angle diffrent in Dramtaic scenes newAngle[0]+= 12.5f * dfactor; // lower angle if dramatic if ( flags & DRC_FLAG_SIDE ) newAngle[1]+=22.5f; else newAngle[1]-=22.5f; float d = MaxAngleBetweenAngles( v_lastAngles, newAngle ); if ( ( d < v_cameraFocusAngle) && ( v_cameraMode == CAM_MODE_RELAX ) ) { // difference is to small and we are in relax camera mode, keep viewangles VectorCopy(v_lastAngles, newAngle ); } else if ( (d < v_cameraRelaxAngle) && (v_cameraMode == CAM_MODE_FOCUS) ) { // we catched up with our target, relax again v_cameraMode = CAM_MODE_RELAX; } else { // target move too far away, focus camera again v_cameraMode = CAM_MODE_FOCUS; } // and smooth view, if not a scene cut if ( v_resetCamera || (v_cameraMode == CAM_MODE_RELAX) ) { VectorCopy( newAngle, angle ); } else { V_SmoothInterpolateAngles( v_lastAngles, newAngle, angle, 180.0f ); } V_GetChaseOrigin( newAngle, newOrigin, distance, origin ); // move position up, if very close at target if ( v_lastDistance < 64.0f ) origin[2]+= 16.0f*( 1.0f - (v_lastDistance / 64.0f ) ); // calculate angle to second target VectorSubtract( ent2->origin, origin, tempVec ); VectorAngles( tempVec, tempVec ); tempVec[0] = -tempVec[0]; /* take middle between two viewangles InterpolateAngles( newAngle, tempVec, newAngle, 0.5f); */ }
void V_CalcThirdPersonRefdef( ref_params_t *pparams ) { static float lasttime, oldz = 0; pparams->vieworg = pparams->simorg; pparams->vieworg = pparams->vieworg + pparams->viewheight; pparams->viewangles = pparams->cl_viewangles + pparams->punchangle + ev_punchangle; v_angles = pparams->viewangles; v_lastAngles = pparams->viewangles; // never let view origin sit exactly on a node line, because a water plane can // disappear when viewed with the eye exactly on it. // FIXME, we send origin at 1/128 now, change this? // the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis pparams->vieworg[0] += 1.0f / 32; pparams->vieworg[1] += 1.0f / 32; pparams->vieworg[2] += 1.0f / 32; // this is smooth stair climbing in thirdperson mode but not affected for client model :( if( !pparams->smoothing && pparams->onground && pparams->simorg[2] - oldz > 0.0f ) { float steptime; steptime = pparams->time - lasttime; if( steptime < 0 ) steptime = 0; oldz += steptime * 150.0f; if( oldz > pparams->simorg[2] ) oldz = pparams->simorg[2]; if( pparams->simorg[2] - oldz > pparams->movevars->stepsize ) oldz = pparams->simorg[2] - pparams->movevars->stepsize; pparams->vieworg[2] += oldz - pparams->simorg[2]; } else { oldz = pparams->simorg[2]; } lasttime = pparams->time; V_GetChaseOrigin( pparams->viewangles, pparams->vieworg, cl_chasedist->value, pparams->vieworg ); float pitch = pparams->viewangles[PITCH]; // normalize angles if( pitch > 180.0f ) pitch -= 360.0f; else if( pitch < -180.0f ) pitch += 360.0f; // player pitch is inverted pitch /= -3.0; cl_entity_t *ent = gEngfuncs.GetLocalPlayer(); // slam local player's pitch value ent->angles[PITCH] = pitch; ent->curstate.angles[PITCH] = pitch; ent->prevstate.angles[PITCH] = pitch; ent->latched.prevangles[PITCH] = pitch; }
void V_GetDirectedChasePosition(cl_entity_t * ent1, cl_entity_t * ent2,float * angle, float * origin) { float newAngle[3]; float newOrigin[3]; float tempVec[3]; int flags = gHUD.m_Spectator.m_iObserverFlags; qboolean deadPlayer = ent1->player && (ent1->curstate.solid == SOLID_NOT); float dfactor = ( flags & DRC_FLAG_DRAMATIC )? -1.0f : 1.0f; if ( ent1->player && (ent1->curstate.solid == SOLID_NOT) ) dfactor = 1.5f; // zoom away if player dies float distance = 112.0f + ( 16.0f * dfactor ); // get close if dramatic; // go away in final scenes if (flags & DRC_FLAG_FINAL ) distance*=2.0f; // let v_lastDistance float smoothly away v_lastDistance+= v_frametime * 24.0f; // move unit per seconds back if ( distance > v_lastDistance ) distance = v_lastDistance; VectorCopy(ent1->origin, newOrigin); if ( ent1->player ) { if ( deadPlayer ) newOrigin[2]+= 2; //laying on ground else newOrigin[2]+= 28; // head level of living player } else newOrigin[2]+= 8; // object, tricky, must be above bomb in CS if ( ( ent2 == (cl_entity_t*)0xFFFFFFFF ) || deadPlayer ) // we have no second target or player just died { // we have no second target, choose view direction based on // show front of primary target VectorCopy(ent1->angles, newAngle); newAngle[1]+= 180.0f; newAngle[0]+= 12.5f * dfactor; // lower angle if dramatic // if final scene (bomb), show from real high pos if ( flags & DRC_FLAG_FINAL ) newAngle[0] = 22.5f; // choose side of object/player if ( flags & DRC_FLAG_SIDE ) newAngle[1]+=22.5f; else newAngle[1]-=22.5f; // if ( AngleBetweenVectors( tempVec, newAngle ) > 1.0f ) V_SmoothInterpolateAngles( v_lastAngles, newAngle, angle, 120.0f ); // HACK, if player is dead don't clip against his dead body, can't check this V_GetChaseOrigin( angle, newOrigin, distance, deadPlayer, origin ); } else if ( ent2 ) { // get new angle towards second target VectorSubtract( ent2->origin, ent1->origin, newAngle ); VectorAngles( newAngle, newAngle ); newAngle[0] = -newAngle[0]; // set angle diffrent in Dramtaic scenes newAngle[0]+= 12.5f * dfactor; // lower angle if dramatic if ( flags & DRC_FLAG_SIDE ) newAngle[1]+=22.5f; else newAngle[1]-=22.5f; V_GetChaseOrigin( newAngle, newOrigin, distance, false, origin ); origin[2]+= 16.0f*( 1.0f - (v_lastDistance / distance) ); // calculate angle to second target VectorSubtract( ent2->origin, origin, tempVec ); VectorAngles( tempVec, tempVec ); tempVec[0] = -tempVec[0]; // take middle between two viewangles InterpolateAngles( newAngle, tempVec, angle, 0.5f); } else { // second target disappeard somehow (dead) // keep last good viewangle V_GetChaseOrigin( angle, newOrigin, distance, false, origin ); } VectorCopy(angle, v_lastAngles); }