159 lines
7.4 KiB
C#
159 lines
7.4 KiB
C#
using T3.Core.Animation;
|
|
using T3.Core.DataTypes;
|
|
using Xunit;
|
|
|
|
namespace Core.Tests;
|
|
|
|
public class BezierInterpolatorTests
|
|
{
|
|
[Fact]
|
|
public void DefaultTension_MatchesHermite()
|
|
{
|
|
// At tension=1.0, Bezier should produce identical results to Hermite
|
|
var curve = new Curve();
|
|
curve.AddOrUpdateV(0.0, new VDefinition
|
|
{
|
|
Value = 0.0,
|
|
InInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutTangentAngle = 0.6,
|
|
TensionOut = 1.0f,
|
|
Weighted = false, // Not weighted → Hermite path
|
|
});
|
|
curve.AddOrUpdateV(1.0, new VDefinition
|
|
{
|
|
Value = 1.0,
|
|
InInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
InTangentAngle = 0.3,
|
|
TensionIn = 1.0f,
|
|
Weighted = false,
|
|
});
|
|
|
|
// Enable Bezier on a copy and compare
|
|
var curveBezier = new Curve();
|
|
curveBezier.AddOrUpdateV(0.0, new VDefinition
|
|
{
|
|
Value = 0.0,
|
|
InInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutTangentAngle = 0.6,
|
|
TensionOut = 1.0f,
|
|
Weighted = true, // Weighted → Bezier path
|
|
});
|
|
curveBezier.AddOrUpdateV(1.0, new VDefinition
|
|
{
|
|
Value = 1.0,
|
|
InInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
InTangentAngle = 0.3,
|
|
TensionIn = 1.0f,
|
|
Weighted = true,
|
|
});
|
|
|
|
for (double u = 0.0; u <= 1.0; u += 0.05)
|
|
{
|
|
var hermite = curve.GetSampledValue(u);
|
|
var bezier = curveBezier.GetSampledValue(u);
|
|
Assert.Equal(hermite, bezier, 5);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void LowTension_ProducesDifferentCurve()
|
|
{
|
|
var curve = new Curve();
|
|
curve.AddOrUpdateV(0.0, new VDefinition
|
|
{
|
|
Value = 0.0,
|
|
InInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutTangentAngle = 0.7854,
|
|
TensionOut = 0.3f,
|
|
Weighted = true,
|
|
});
|
|
curve.AddOrUpdateV(1.0, new VDefinition
|
|
{
|
|
Value = 1.0,
|
|
InInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
InTangentAngle = 0.7854,
|
|
TensionIn = 0.3f,
|
|
Weighted = true,
|
|
});
|
|
|
|
// Endpoints must be exact
|
|
Assert.Equal(0.0, curve.GetSampledValue(0.0), 4);
|
|
Assert.Equal(1.0, curve.GetSampledValue(1.0), 4);
|
|
|
|
// Midpoint should differ from tension=1.0 Hermite
|
|
var mid = curve.GetSampledValue(0.5);
|
|
Assert.True(mid > 0 && mid < 1, $"Value should be in (0,1), got {mid}");
|
|
}
|
|
|
|
[Fact]
|
|
public void SegmentNeedsBezier_OnlyWhenWeightedAndNonDefaultTension()
|
|
{
|
|
var defaultKey = new VDefinition
|
|
{
|
|
InInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
TensionIn = 1.0f,
|
|
TensionOut = 1.0f,
|
|
Weighted = false,
|
|
};
|
|
|
|
var weightedKey = new VDefinition
|
|
{
|
|
InInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
TensionIn = 0.5f,
|
|
TensionOut = 0.5f,
|
|
Weighted = true,
|
|
};
|
|
|
|
var smoothKey = new VDefinition
|
|
{
|
|
InInterpolation = VDefinition.KeyInterpolation.Smooth,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Smooth,
|
|
};
|
|
|
|
// Default tangent keys → Hermite
|
|
Assert.False(BezierInterpolator.SegmentNeedsBezier(defaultKey, defaultKey));
|
|
|
|
// Smooth keys → Hermite
|
|
Assert.False(BezierInterpolator.SegmentNeedsBezier(smoothKey, smoothKey));
|
|
|
|
// Weighted tangent with non-default tension → Bezier
|
|
Assert.True(BezierInterpolator.SegmentNeedsBezier(weightedKey, defaultKey));
|
|
Assert.True(BezierInterpolator.SegmentNeedsBezier(defaultKey, weightedKey));
|
|
}
|
|
|
|
[Fact]
|
|
public void BezierEndpointsAreExact()
|
|
{
|
|
var curve = new Curve();
|
|
curve.AddOrUpdateV(2.0, new VDefinition
|
|
{
|
|
Value = 10.0,
|
|
InInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutTangentAngle = 0.5,
|
|
TensionOut = 0.7f,
|
|
Weighted = true,
|
|
});
|
|
curve.AddOrUpdateV(5.0, new VDefinition
|
|
{
|
|
Value = 20.0,
|
|
InInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
OutInterpolation = VDefinition.KeyInterpolation.Tangent,
|
|
InTangentAngle = 0.3,
|
|
TensionIn = 1.5f,
|
|
Weighted = true,
|
|
});
|
|
|
|
Assert.Equal(10.0, curve.GetSampledValue(2.0), 4);
|
|
Assert.Equal(20.0, curve.GetSampledValue(5.0), 4);
|
|
}
|
|
}
|