Add GetSplineSegmentLength to get spline segment length

#1879
This commit is contained in:
Wojtek Figat
2023-11-13 11:38:37 +01:00
parent 930b1b978c
commit 418918920e
2 changed files with 40 additions and 2 deletions

View File

@@ -149,8 +149,8 @@ float Spline::GetSplineDuration() const
float Spline::GetSplineLength() const
{
float sum = 0.0f;
const int32 slices = 20;
const float step = 1.0f / (float)slices;
constexpr int32 slices = 20;
constexpr float step = 1.0f / (float)slices;
Vector3 prevPoint = Vector3::Zero;
if (Curve.GetKeyframes().Count() != 0)
{
@@ -181,6 +181,37 @@ float Spline::GetSplineLength() const
return Math::Sqrt(sum);
}
float Spline::GetSplineSegmentLength(int32 index) const
{
if (index == 0)
return 0.0f;
CHECK_RETURN(index > 0 && index < GetSplinePointsCount(), 0.0f);
float sum = 0.0f;
constexpr int32 slices = 20;
constexpr float step = 1.0f / (float)slices;
const auto& a = Curve[index - 1];
const auto& b = Curve[index];
Vector3 startPoint = a.Value.Translation * _transform.Scale;
{
const float length = Math::Abs(b.Time - a.Time);
Vector3 leftTangent, rightTangent;
AnimationUtils::GetTangent(a.Value.Translation, a.TangentOut.Translation, length, leftTangent);
AnimationUtils::GetTangent(b.Value.Translation, b.TangentIn.Translation, length, rightTangent);
// TODO: implement sth more analytical than brute-force solution
for (int32 slice = 0; slice < slices; slice++)
{
const float t = (float)slice * step;
Vector3 pos;
AnimationUtils::Bezier(a.Value.Translation, leftTangent, rightTangent, b.Value.Translation, t, pos);
pos *= _transform.Scale;
sum += (float)Vector3::DistanceSquared(pos, startPoint);
startPoint = pos;
}
}
return Math::Sqrt(sum);
}
float Spline::GetSplineTime(int32 index) const
{
CHECK_RETURN(index >= 0 && index < GetSplinePointsCount(), 0.0f)

View File

@@ -167,6 +167,13 @@ public:
/// </summary>
API_PROPERTY() float GetSplineLength() const;
/// <summary>
/// Gets the length of the spline segment (distance between pair of two points).
/// </summary>
/// <param name="index">The index of the segment end index. Zero-based, smaller than GetSplinePointsCount().</param>
/// <returns>The spline segment length.</returns>
API_FUNCTION() float GetSplineSegmentLength(int32 index) const;
/// <summary>
/// Gets the time of the spline keyframe.
/// </summary>