Description

Note: This is possibly related to [Link Removed].

For some inputs, function UE::Curves::WeightedEvalForTwoKeys() inside file "CurveEvaluation.cpp" can incorrectly return the value of the first key, when the expected result was something very close to the second key. This has been noticed, for example, when calling UCurveFloat::GetFloatValue(), which can result in popping artifacts as the input value is slowly interpolated from one key to the next.

A UDN user pointed out that adding "UE_DISABLE_OPTIMIZATION" at the top of file "CurveEvaluation.cpp" fixes the behavior. An alternative fix is to add "#pragma float_control(precise,on,push)" and "#pragma float_control(pop)" to either side of the WeightedEvalForTwoKeys() function.

A preliminary investigation revealed a problem in the following snippet from UE::Curves::WeightedEvalForTwoKeys() in "CurveEvaluation.cpp":

[:158] const int32 NumResults = SolveCubic(Coeff, Results);
[:165]

{ [:166] NewInterp = TNumericLimits<double>::Lowest(); [:167] for (double Result : Results) [:169] if ((Result >= 0.0) && (Result <= 1.0)) [:171] if (NewInterp < 0.0 || Result > NewInterp) [:173] NewInterp = Result; [:178] if (NewInterp == TNumericLimits<double>::Lowest()) [:180] NewInterp = 0.0; [:183] }

In the code above, when the sampled time is very close to the second key of an interval, function SolveCubic() is expected to return at least one result very close to 1 in the interval [0,1]. However, for some inputs and because of floating-point precision issues, that calculated output can be slightly above 1 instead. As a consequence, the test in line 169 fails and we end up executing line 180, which brings the final interpolation result to the first key instead of the second.

Steps to Reproduce

1. Download, unzip and open the attached repro project.
2. From the Content Browser:
2.1. Open asset "MyFloatCurve" and keep it open for future reference.
2.2. Run the Editor Utility Widget "EUW_CurveInspector"
3. On the editor utility widget tab:
3.1. Select asset "MyFloatCurve"
3.2. Spin around the input values to see the behavior output matching the curve.
3.3. Type in -0.00004 for the input. The output is close to zero, as expected.
3.4. Type in -0.00003 for the input. The output is 200, close to the first curve key, which is completely wrong.
3.5. Type in 0.00000 for the input. The output is zero, as expected.

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-229247 in the post.

0
Login to Vote

Unresolved
ComponentUE - Anim - Runtime
Affects Versions5.4.4
Target Fix5.6
CreatedOct 31, 2024
UpdatedDec 2, 2024
View Jira Issue