Hi guys,
So I’m trying to use spline components for a system I’m making. I’m trying to add 2 points along the curve, either side of another point, but have those points in no way distort the existing spline. I found the following answer on stack overflow:
Unfortunately, following this logic, neither the position of the point, nor the tangents of that point, come out correct. This leads me to believe (perhaps mistakenly) that the algorithm for splines in UE4 may be a different implementation. Below are images of the current implementation I have.
As you can see, the external tangents on both points seem to be a lot closer to the intended values than the ones facing the point about which they are placed.
Here’s the logic for what I have now:
FVector newSplinePoint = GetLocationAtDistanceAlongSpline(Distance, ESplineCoordinateSpace::Local);
//Before we insert it, the next key is the key at the index we're inserting at
FInterpCurvePoint<FVector> nextKey = SplineCurves.Position.Points[Index];
FInterpCurvePoint<FVector> prevKey = SplineCurves.Position.Points[Index - 1];
//Get t
const float alpha = SplineCurves.ReparamTable.Eval(Distance, 0.0f);
float t = (alpha - prevKey.InVal) / (nextKey.InVal - prevKey.InVal);
FVector prevPointOutTan = (1 - t) * prevKey.OutVal + t * prevKey.LeaveTangent;
FVector betweenTansTan = (1 - t) * nextKey.LeaveTangent + t * nextKey.ArriveTangent;
FVector nextPointInTan = (1 - t) * nextKey.ArriveTangent + t * nextKey.OutVal;
FVector newPointInTan = (1 - t) * prevPointOutTan + t * betweenTansTan;
FVector newPointOutTan = (1 - t) * betweenTansTan + t * nextPointInTan;
//Update points to have new tangents, to fit this new point in
SplineCurves.Position.Points[Index - 1] = FInterpCurvePoint<FVector>(prevKey.InVal, prevKey.OutVal, prevKey.ArriveTangent, prevPointOutTan, CIM_CurveBreak);
SplineCurves.Position.Points[Index] = FInterpCurvePoint<FVector>(nextKey.InVal, nextKey.OutVal, nextPointInTan, nextKey.LeaveTangent, CIM_CurveBreak);
int32 NumPoints = SplineCurves.Position.Points.Num();
//UE_LOG(LogTemp, Log, TEXT("InTan: %s - OutTan: %s"), *P01_12.ToString(), *P12_23.ToString);
if (Index >= 0 && Index <= NumPoints)
{
const float InKey = (Index == 0) ? 0.0f : SplineCurves.Position.Points[Index - 1].InVal + 1.0f;
SplineCurves.Position.Points.Insert(FInterpCurvePoint<FVector>(InKey, newSplinePoint, newPointInTan, newPointInTan, CIM_CurveBreak), Index);
//SplineCurves.Position.Points.Insert(FInterpCurvePoint<FVector>(InKey, newSplinePoint, FVector::ZeroVector, FVector::ZeroVector, CIM_CurveAuto), Index);
SplineCurves.Rotation.Points.Insert(FInterpCurvePoint<FQuat>(InKey, FQuat::Identity, FQuat::Identity, FQuat::Identity, CIM_CurveAuto), Index);
SplineCurves.Scale.Points.Insert(FInterpCurvePoint<FVector>(InKey, FVector(1.0f), FVector::ZeroVector, FVector::ZeroVector, CIM_CurveAuto), Index);
NumPoints++;
// Adjust subsequent points' input keys to make room for the value just added
for (int I = Index + 1; I < NumPoints; ++I)
{
SplineCurves.Position.Points[I].InVal += 1.0f;
SplineCurves.Rotation.Points[I].InVal += 1.0f;
SplineCurves.Scale.Points[I].InVal += 1.0f;
}
}
UpdateSpline();
Just curious if anyone has had to deal with anything similar to this, or has any thoughts/suggestions about how I might deal with this issue?