/* * @brief The angles are typically fetched from input, after factoring in client-side * prediction, unless the client is watching a demo or chase camera. */ static void Cl_UpdateAngles(const player_state_t *from, const player_state_t *to) { vec3_t old_angles, new_angles, angles; // start with the predicted angles, or interpolate the server states if (Cl_UsePrediction()) { VectorCopy(cl.predicted_state.view_angles, r_view.angles); } else { UnpackAngles(from->pm_state.view_angles, old_angles); UnpackAngles(to->pm_state.view_angles, new_angles); AngleLerp(old_angles, new_angles, cl.lerp, r_view.angles); } // add in the kick angles UnpackAngles(from->pm_state.kick_angles, old_angles); UnpackAngles(to->pm_state.kick_angles, new_angles); AngleLerp(old_angles, new_angles, cl.lerp, angles); VectorAdd(r_view.angles, angles, r_view.angles); // and lastly the delta angles UnpackAngles(from->pm_state.delta_angles, old_angles); UnpackAngles(to->pm_state.delta_angles, new_angles); VectorCopy(new_angles, angles); // check for small delta angles, and interpolate them if (!VectorCompare(old_angles, new_angles)) { int32_t i; for (i = 0; i < 3; i++) { const vec_t delta = fabs(new_angles[i] - old_angles[i]); if (delta > 5.0 && delta < 355.0) { break; } } if (i == 3) { AngleLerp(old_angles, new_angles, cl.lerp, angles); } } VectorAdd(r_view.angles, angles, r_view.angles); if (cl.frame.ps.pm_state.type == PM_DEAD) { // look only on x axis r_view.angles[0] = 0.0; r_view.angles[2] = 45.0; } // and finally set the view directional vectors AngleVectors(r_view.angles, r_view.forward, r_view.right, r_view.up); }
/* * @brief The angles are typically fetched from input, after factoring in client-side * prediction, unless the client is watching a demo or chase camera. */ static void Cl_UpdateAngles(const player_state_t *ps, const player_state_t *ops) { vec3_t old_angles, new_angles, angles; // start with the predicted angles, or interpolate the server states if (Cl_UsePrediction()) { VectorCopy(cl.predicted_state.view_angles, r_view.angles); } else { UnpackAngles(ops->pm_state.view_angles, old_angles); UnpackAngles(ps->pm_state.view_angles, new_angles); AngleLerp(old_angles, new_angles, cl.lerp, r_view.angles); } // add in the kick angles UnpackAngles(ops->pm_state.kick_angles, old_angles); UnpackAngles(ps->pm_state.kick_angles, new_angles); AngleLerp(old_angles, new_angles, cl.lerp, angles); VectorAdd(r_view.angles, angles, r_view.angles); // and lastly the delta angles UnpackAngles(ops->pm_state.delta_angles, old_angles); UnpackAngles(ps->pm_state.delta_angles, new_angles); VectorCopy(new_angles, angles); // check for small delta angles, and interpolate them if (!VectorCompare(new_angles, new_angles)) { VectorSubtract(old_angles, new_angles, angles); vec_t f = VectorLength(angles); if (f < 15.0) { AngleLerp(old_angles, new_angles, cl.lerp, angles); } } VectorAdd(r_view.angles, angles, r_view.angles); ClampAngles(r_view.angles); if (cl.frame.ps.pm_state.type == PM_DEAD) { // look only on x axis r_view.angles[0] = 0.0; r_view.angles[2] = 45.0; } // and finally set the view directional vectors AngleVectors(r_view.angles, r_view.forward, r_view.right, r_view.up); }