using UnityEngine.Scripting;
////REVIEW: handle values dropping below min and above max?
namespace UnityEngine.InputSystem.Processors
{
///
/// Normalizes input values in the range and to
/// unsigned normalized form [0..1] if is placed at (or below)
/// or to signed normalized form [-1..1] if is placed in-between
/// and .
///
///
/// This processor is registered (see ) under the name "normalize".
///
/// Note that this processor does not clamp the incoming value to and .
/// To achieve this, either add a or use
/// which combines clamping and normalizing.
///
///
///
///
/// // Bind to right trigger on gamepad such that the value values below 0.3 and above 0.7 get normalized
/// // to values between [0..1].
/// new InputAction(binding: "<Gamepad>/rightTrigger", processors: "normalize(min=0.3,max=0.7)");
///
///
///
///
public class NormalizeProcessor : InputProcessor
{
///
/// Input value (inclusive) that corresponds to 0 or -1 (depending on ), the lower bound.
///
///
/// If the input value drops below min, the result is undefined.
///
public float min;
///
/// Input value (inclusive) that corresponds to 1, the upper bound.
///
///
/// If the input value goes beyond max, the result is undefined.
///
public float max;
///
/// Input value that corresponds to 0. If this is placed at or below , the resulting normalization
/// returns a [0..1] value. If this is placed in-between and , the resulting
/// normalization returns a [-1..1] value.
///
public float zero;
///
/// Normalize with respect to and .
///
/// Input value.
/// Ignored.
/// Normalized value.
public override float Process(float value, InputControl control)
{
return Normalize(value, min, max, zero);
}
///
/// Normalize with respect to and .
///
/// Input value.
/// Lower bound. See .
/// Upper bound. See .
/// Zero point. See .
/// Normalized value.
///
/// This method performs the same function as .
///
///
/// // Normalize 2 against a [1..5] range. Returns 0.25.
/// NormalizeProcessor.Normalize(2, 1, 5, 1)
///
///
///
public static float Normalize(float value, float min, float max, float zero)
{
if (zero < min)
zero = min;
// Prevent NaN/Inf from dividing 0 by something.
if (Mathf.Approximately(value, min))
{
if (min < zero)
return -1f;
return 0f;
}
var percentage = (value - min) / (max - min);
if (min < zero)
return 2 * percentage - 1;
return percentage;
}
internal static float Denormalize(float value, float min, float max, float zero)
{
if (zero < min)
zero = min;
if (min < zero)
{
if (value < 0)
return min + (zero - min) * (value * -1f);
return zero + (max - zero) * value;
}
return min + (max - min) * value;
}
///
public override string ToString()
{
return $"Normalize(min={min},max={max},zero={zero})";
}
}
}