Which algorithm is used for spline components in UE4?

In the pursuit of solving my bigger problem with UE4 splines, I decided to do some math computation myself. I quickly realized, that I don’t know which algorithm is actually being used by the engine to draw the splines.

A quick search showed me the exactly this question being posted on the UE forums:

to which TheJamsh reports that they are using Cubic Bezier by default.
However, through experimentation this cannot be true!

Consider the following simple experiment: put control points p0, p1, p2, p3 in a square and draw a Cubic Bezier spline S. Using a simple DeCasteljau algorithm you can conclude that the curve will reach 75% height of the square, exactly at S(0.5).

65996-paint.png

The built-in spline tool of Paint also agrees with it :slight_smile:

In UE4 you don’t specify points p1 and p2, but use tangents t0, t3 at points p0, p3 respectively. I assume that t0 = p1-2 and t3 = p3-p2. However, in UE4 (using the Unreal Tournament version), I get a different result:

65997-spline+square+ue4.png

The resulting spline is much shorter, as if the tangents were dampened somehow.
Which brings me back to the original question - what is the math driving the splines in UE4?
Or maybe it is intended to be a cubic bezier but there is some bug lurking in the formula?

Try checking code for yourself:

https://github.com/EpicGames/UnrealEngine/blob/a27ad66f0a075f3b74ef8f68a4b2b0da4882425e/Engine/Source/Runtime/Engine/Private/Components/SplineComponent.cpp

Unfortunately, I have problems accessing that code. I added my git unsername to the profile setting, but I still get error 404 as if the file never even existed.

I stumbled across this question because I had the same and looked it up myself. I know this question is kind of outdated, but I want to post the answer anyway in case someone else needs this to know.

I looked into the source code (4.14) of the spline component and saw that the interpolation is done by the template function CubicInterp() in the header UnrealMathUtility.h . This function looks like this:

template< class T, class U > 
static FORCEINLINE_DEBUGGABLE T CubicInterp( const T& P0, const T& T0, const T& P1, const T& T1, const U& A )
{
	const float A2 = A  * A;
	const float A3 = A2 * A;

	return (T)(((2*A3)-(3*A2)+1) * P0) + ((A3-(2*A2)+A) * T0) + ((A3-A2) * T1) + (((-2*A3)+(3*A2)) * P1);
}

where P0 and P1 are start and end point and T0 and T1 are their tangents.

I looked this formula up at Bézier curve - Wikipedia . There you don’t find the formula with tangents, but with two intermediate points, which can be converted into P0+T0 and P1-T1. After simplifying the formula and comparing it to the function above from the source code, the tangents need to be multiplied by 3 to match the formula from wikipedia. You can see this by multiplying your tangents manually by 3 and then you get the expected result for the original tangents.

I don’t know if this is really a bug or done on purpose, but nevertheless, now you know it :slight_smile: