public static float LerpAngle(float a, float b, float t) { float num = MathR.Repeat(b - a, 360f); if ((double)num > 180.0) { num -= 360f; } return(a + num * MathR.Clamp01(t)); }
public static float Lerp(float value1, float value2, float ammount) { return(value1 + (value2 - value1) * MathR.Clamp01(ammount)); }
public override void updateCamera() { base.updateCamera(); updateCameraCommon(); var camExtraHeightV3 = Vector3.WorldUp * extraCamHeight; var posCenter = veh.Position + fullHeightOffset; float rotSpeed = rotationSpeed; if(useVariableRotSpeed) { var desiredRootSpeed = MathR.SmoothStep(minRotSpeed, maxRotSpeed, MathR.Clamp01(AngleInDeg(veh.ForwardVector, veh.Velocity) / 90)); currentRootSpeed = MathR.Lerp(currentRootSpeed, desiredRootSpeed, 2f * Time.getDeltaTime()); } if (veh.Speed > 1f) { //velQuat = MathR.LookRotation(veh.Velocity, Vector3.WorldUp); velocityQuat = MathR.XLookRotation(smoothVelocity); } Quaternion vehQuat; if(isCycleOrByke) { // Bykes / cycles (avoid unwanted cam rotations during wheelies/stoppies) if (veh.Speed < 3f) { if(veh.IsOnAllWheels) vehQuat = getRotationFromAverageWheelPosBike(); else vehQuat = getSurfaceNormalRotation(); // Possibly unperformant (using it only for wheelie/stoppie al low speeds) } else vehQuat = velocityQuat; } else // cars { if(avoidCameraBouncinessCar && veh.IsOnAllWheels) { vehQuat = getRotationFromAverageWheelPosCar(); // Avoid camera movements caused by car suspension movement (wheels are on the floor) } else { vehQuat = veh.Quaternion; } } //smoothQuat = MathR.QuatNlerp(smoothQuat, veh.Quaternion, MathR.Clamp01(rotationSpeed * Time.getDeltaTime())); smoothQuat = Quaternion.SlerpUnclamped(smoothQuat, vehQuat, rotationSpeed * Time.getDeltaTime()); smoothVelQuat = Quaternion.Lerp(smoothVelQuat, velocityQuat, 2f * Time.getDeltaTime()); finalQuat = Quaternion.Lerp(smoothQuat, velocityQuat, script.smoothIsInAir); float finalDistMult = 1f; if (veh.Speed > 0.15f) { // TODO Optimize? finalDistMult = Vector3.Angle(finalQuat * Vector3.RelativeFront, veh.Velocity) / 180f; finalDistMult = MathR.Lerp(1f, -1f, finalDistMult); } if(script.isMouseLooking) { finalQuat = Quaternion.Lerp(finalQuat, getFreelookQuaternion(), script.smoothIsFreeLooking); } targetCamera.Position = posCenter + camExtraHeightV3 + (finalQuat * Vector3.RelativeBack * (fullLongitudeOffset + ( currentDistanceIncrement * finalDistMult ))); var pointAt = posCenter - finalQuat * Vector3.RelativeBack * (currentDistanceIncrement + 2f); targetCamera.PointAt(pointAt); }
// Cheaper than Slerp public static Quaternion EulerNlerp(Quaternion start, Quaternion end, float ammount) { return(QuaternionFromEuler(Vector3.Lerp(start.ToEulerAngles(), end.ToEulerAngles(), MathR.Clamp01(ammount)).Normalized)); }
private Transform UpdateCameraRear() { // smooth out current rotation and position currentRotation = MathR.EulerNlerp(currentRotation, rearCamCurrentTransform.quaternion, (responsivenessMultiplier * generalMovementSpeed) * Time.getDeltaTime()); currentPos = Vector3.Lerp(currentPos, rearCamCurrentTransform.position, MathR.Clamp01((responsivenessMultiplier * generalMovementSpeed) * Time.getDeltaTime())); Quaternion look; var wantedPos = veh.Position + (veh.ForwardVector * finalDummyOffset); // If veh has towed vehicle, increase camera distance by towed vehicle longitude // should camera be attached to vehicle's back or back his velocity var fixedVsVelocity = getFixedVsVelocityFactor(speedCoeff); Quaternion vehQuat = veh.Quaternion; // Compute camera position rear the vechicle var wantedPosFixed = wantedPos - veh.Quaternion * Vector3.RelativeFront * fullLongitudeOffset; // smooth out velocity // Compute camera postition rear the direction of the vehcle if (speedCoeff >= stoppedSpeed) { wantedPosVelocity = wantedPos + MathR.QuaternionLookRotation(smoothVelocity) * Vector3.RelativeBottom * fullLongitudeOffset; } // Smooth factor between two above cam positions smoothFixedVsVelocity = MathR.Lerp(smoothFixedVsVelocity, fixedVsVelocity, (fixedVsVelocitySpeed) * Time.getDeltaTime()); if (!isCycleOrByke) { tempSmoothVsVl = MathR.Lerp(tempSmoothVsVl, MathR.Clamp(speedCoeff * 0.4347826f, 0.025f, 1f), (fixedVsVelocitySpeed * 0.05f)); smoothFixedVsVelocity = MathR.Lerp(0f, smoothFixedVsVelocity, tempSmoothVsVl); } wantedPos = Vector3.Lerp(wantedPosFixed, wantedPosVelocity, MathR.Clamp01(smoothFixedVsVelocity)); //currentPos = Vector3.Lerp(currentPos, wantedPos, Mathr.Clamp01((responsivenessMultiplier * cameraStickiness) * Time.getDeltaTime())); currentPos = Vector3.Lerp(currentPos, wantedPos, MathR.Clamp01((responsivenessMultiplier * cameraStickiness) * Time.getDeltaTime())); //rearCamCurrentTransform.position = currentPos; targetCamera.PointAt(pointAt); look = Quaternion.Euler(targetCamera.Rotation); // Rotate the camera towards the velocity vector. var finalCamRotationSpeed = MathR.Lerp(cameraRotationSpeedLowSpeed, cameraRotationSpeed, ((speedCoeff / lowSpeedLimit) * 1.32f) * Time.getDeltaTime() * 51f); look = MathR.EulerNlerp(currentRotation, look, (1.8f * finalCamRotationSpeed) * Time.getDeltaTime()); // Fix stuttering (mantain camera distance fixed in local space) Transform fixedDistanceTr = new Transform(currentPos + fullHeightOffset + (Vector3.WorldUp * extraCamHeight), Quaternion.Identity); fixedDistanceTr.PointAt(pointAt); Quaternion finalQuat = fixedDistanceTr.quaternion; if (script.isMouseLooking) { finalQuat = Quaternion.Lerp(finalQuat, getFreelookQuaternion(), script.smoothIsFreeLooking); } fixedDistanceTr.position = veh.Position + fullHeightOffset + (Vector3.WorldUp * extraCamHeight) + (finalQuat * Vector3.RelativeBack * (fullLongitudeOffset + currentDistanceIncrement)); //fixedDistanceTr.position = fixedDistanceTr.position + fullHeightOffset; var transform = new Transform(); transform.position = fixedDistanceTr.position; //transform.position = currentPos + fullHeightOffset; transform.rotation = look.ToEulerAngles(); transform.quaternion = look; rearCamCurrentTransform = transform; return(transform); }