streamingle-unity-utilities/Tests/Editor/Gaze/GazeProfileAuthoringTests.cs

228 lines
8.8 KiB
C#

using System.Reflection;
using NUnit.Framework;
using UnityEngine;
namespace Streamingle.Gaze.Tests
{
public sealed class GazeProfileAuthoringTests
{
private static readonly string[] StandardChannels =
{
"eyeLookUpLeft",
"eyeLookUpRight",
"eyeLookDownLeft",
"eyeLookDownRight",
"eyeLookInLeft",
"eyeLookInRight",
"eyeLookOutLeft",
"eyeLookOutRight"
};
[Test]
public void SeedStandardEyeLook_CreatesFivePointsAndFourCorners()
{
var profile = CreateStandardProfile();
try
{
Assert.That(profile.SeedStandardEyeLook(80f), Is.True);
for (var index = 0; index < 9; index++)
Assert.That(profile.IsSampleCaptured((GazeCalibrationPoint)index), Is.True);
Assert.That(
profile.GetSampleWeightsCopy(GazeCalibrationPoint.Center),
Is.EqualTo(new[] { 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f }));
Assert.That(
profile.GetSampleWeightsCopy(GazeCalibrationPoint.CenterLeft),
Is.EqualTo(new[] { 0f, 0f, 0f, 0f, 0f, 80f, 80f, 0f }));
Assert.That(
profile.GetSampleWeightsCopy(GazeCalibrationPoint.UpRight),
Is.EqualTo(new[] { 80f, 80f, 0f, 0f, 80f, 0f, 0f, 80f }));
}
finally
{
Object.DestroyImmediate(profile);
}
}
[Test]
public void GenerateCorners_CombinesCardinalDeltasAndClampsByUsage()
{
var profile = ScriptableObject.CreateInstance<BlendshapeGazeProfile>();
try
{
profile.ReplaceChannels(new[]
{
new GazeBlendShapeChannel("eyeLookUpLeft"),
new GazeBlendShapeChannel("eyeLidCorrective", GazeChannelUsage.Corrective)
});
profile.SetSample(GazeCalibrationPoint.Center, new[] { 80f, 0f });
profile.SetSample(GazeCalibrationPoint.CenterLeft, new[] { 100f, 100f });
profile.SetSample(GazeCalibrationPoint.CenterRight, new[] { 0f, -100f });
profile.SetSample(GazeCalibrationPoint.UpCenter, new[] { 100f, 100f });
profile.SetSample(GazeCalibrationPoint.DownCenter, new[] { 0f, -100f });
Assert.That(profile.CanGenerateCorners, Is.True);
Assert.That(profile.GenerateCornersFromCardinals(), Is.True);
Assert.That(
profile.GetSampleWeightsCopy(GazeCalibrationPoint.UpLeft),
Is.EqualTo(new[] { 100f, 100f }));
Assert.That(
profile.GetSampleWeightsCopy(GazeCalibrationPoint.DownRight),
Is.EqualTo(new[] { 0f, -100f }));
}
finally
{
Object.DestroyImmediate(profile);
}
}
[Test]
public void GenerateCorners_UsesCardinalDeltasRelativeToCenter()
{
var profile = ScriptableObject.CreateInstance<BlendshapeGazeProfile>();
try
{
profile.ReplaceChannels(new[]
{
new GazeBlendShapeChannel("eyeLookTest")
});
profile.SetSample(GazeCalibrationPoint.Center, new[] { 10f });
profile.SetSample(GazeCalibrationPoint.CenterLeft, new[] { 30f });
profile.SetSample(GazeCalibrationPoint.CenterRight, new[] { 10f });
profile.SetSample(GazeCalibrationPoint.UpCenter, new[] { 40f });
profile.SetSample(GazeCalibrationPoint.DownCenter, new[] { 10f });
Assert.That(profile.GenerateCornersFromCardinals(), Is.True);
Assert.That(
profile.GetSampleWeight(GazeCalibrationPoint.UpLeft, 0),
Is.EqualTo(60f));
}
finally
{
Object.DestroyImmediate(profile);
}
}
[Test]
public void DirectionLimits_SanitizeNonFiniteValuesAndClampToSupportedRanges()
{
var profile = ScriptableObject.CreateInstance<BlendshapeGazeProfile>();
try
{
profile.SetDirectionLimits(
float.NaN,
float.PositiveInfinity,
float.NegativeInfinity,
float.NaN);
Assert.That(profile.MinYaw, Is.EqualTo(-35f));
Assert.That(profile.MaxYaw, Is.EqualTo(35f));
Assert.That(profile.MinPitch, Is.EqualTo(-25f));
Assert.That(profile.MaxPitch, Is.EqualTo(20f));
profile.SetDirectionLimits(-180f, -5f, 10f, 180f);
Assert.That(profile.MinYaw, Is.EqualTo(-90f));
Assert.That(profile.MaxYaw, Is.EqualTo(0.1f));
Assert.That(profile.MinPitch, Is.EqualTo(-0.1f));
Assert.That(profile.MaxPitch, Is.EqualTo(90f));
SetPrivateField(profile, "minYaw", float.PositiveInfinity);
SetPrivateField(profile, "maxYaw", float.NegativeInfinity);
SetPrivateField(profile, "minPitch", float.NaN);
SetPrivateField(profile, "maxPitch", float.NaN);
InvokeOnValidate(profile);
Assert.That(profile.MinYaw, Is.EqualTo(-35f));
Assert.That(profile.MaxYaw, Is.EqualTo(35f));
Assert.That(profile.MinPitch, Is.EqualTo(-25f));
Assert.That(profile.MaxPitch, Is.EqualTo(20f));
}
finally
{
Object.DestroyImmediate(profile);
}
}
[Test]
public void CopySample_WithMirrorSwapsLeftAndRightChannels()
{
var profile = CreateStandardProfile();
try
{
profile.SetSample(
GazeCalibrationPoint.CenterLeft,
new[] { 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f });
Assert.That(
profile.CopySample(
GazeCalibrationPoint.CenterLeft,
GazeCalibrationPoint.CenterRight,
true),
Is.True);
Assert.That(
profile.GetSampleWeightsCopy(GazeCalibrationPoint.CenterRight),
Is.EqualTo(new[] { 2f, 1f, 4f, 3f, 6f, 5f, 8f, 7f }));
}
finally
{
Object.DestroyImmediate(profile);
}
}
[Test]
public void SetSample_RejectsNonFiniteWeights()
{
var profile = ScriptableObject.CreateInstance<BlendshapeGazeProfile>();
try
{
profile.ReplaceChannels(new[]
{
new GazeBlendShapeChannel("eyeLookUpLeft")
});
Assert.Throws<System.ArgumentException>(() =>
profile.SetSample(GazeCalibrationPoint.Center, new[] { float.NaN }));
Assert.Throws<System.ArgumentException>(() =>
profile.SetSample(GazeCalibrationPoint.Center, new[] { float.PositiveInfinity }));
Assert.That(profile.IsSampleCaptured(GazeCalibrationPoint.Center), Is.False);
}
finally
{
Object.DestroyImmediate(profile);
}
}
private static BlendshapeGazeProfile CreateStandardProfile()
{
var profile = ScriptableObject.CreateInstance<BlendshapeGazeProfile>();
var channels = new GazeBlendShapeChannel[StandardChannels.Length];
for (var index = 0; index < channels.Length; index++)
channels[index] = new GazeBlendShapeChannel(StandardChannels[index]);
profile.ReplaceChannels(channels);
return profile;
}
private static void SetPrivateField(
BlendshapeGazeProfile profile,
string fieldName,
float value)
{
var field = typeof(BlendshapeGazeProfile).GetField(
fieldName,
BindingFlags.Instance | BindingFlags.NonPublic);
Assert.That(field, Is.Not.Null, $"Expected private field '{fieldName}'.");
field.SetValue(profile, value);
}
private static void InvokeOnValidate(BlendshapeGazeProfile profile)
{
var method = typeof(BlendshapeGazeProfile).GetMethod(
"OnValidate",
BindingFlags.Instance | BindingFlags.NonPublic);
Assert.That(method, Is.Not.Null, "Expected private OnValidate method.");
method.Invoke(profile, null);
}
}
}