I have read the source code of USplineComponent
and found that for a curve in Unreal, the result is calculated via FMath::CubicInterp
:
/**
* Performs a cubic interpolation
*
* @param P - end points
* @param T - tangent directions at end points
* @param Alpha - distance along spline
*
* @return Interpolated value
*/
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);
}
You can follow the logic in USplineComponent::Draw to be convinced.
And the calculation approach above is the same as the cubic hermite spline:
$$ \boldsymbol{p}(t) = (2t^3-3t^2+1)\boldsymbol{p}_0 + (t^3-2t^2+t)\boldsymbol{m}_0 + (-2t^3+3t^2)\boldsymbol{p}_1 +(t^3-t^2)\boldsymbol{m}_1 $$
Then the problem becomes how to convert a cubic hermite spline to a bezier curve.
I have tried several conversion methods on SO:
https://stackoverflow.com/a/1099357/3427520
https://stackoverflow.com/a/42587252/3427520
https://stackoverflow.com/a/42590480/3427520
But all failed to get a correct bezier curve as USD that can be correctly rendered by Houdini.
But what I have been worrying most is that USplineComponet
is not a cubic hermite spline. I'm not sure since I knew few about curve math, even after reading some introduction of curve wiki, PDFs and articles.
The bezier curve data to USD bezier-basis curve procedure may also fail, I don't have a solution to verify converted bezier curve is correct (can generate the same shape in UE4) or not.