I’m trying to do a smooth movement of an actor who orbit a pivot and I’m not found any solution of Slerp function for FVectors.
In Unity Engine I use Vector3.Slerp ( Vector3 is similar to FVector) but in UE i just found the Slerp function in FQuat class and this is not working because is not a rotation.
There is any way to do a SLERP between two FVectors?
I’m not sure what you mean by FQuats aren’t rotations.
In UE4, FVectors, FRotators, and FQuats are closely related and are easily converted from one to the other.
Is the end use case that you have a forward facing vector, and a new direction facing vector, and want to slerp from one to the other?
If so, your best bet is to convert them both to FQuats and use the FQuat’s slerp function. FVector has a function ToOrientationQuat() to do this simply, and if you need more control, FQuat has a constructor that takes an orientation vector and a “twist” angle.
If you really need the output to be back into FVector form, you can pull that back out of the FQuat using GetAxisX(). It does sound an awful lot like you should just be using FQuats directly, though - they’re the basic unit by which UE4 handles rotations. (FRotators are basically human readable wrappers, anything you do to manipulate them is generally better done with FQuats.)
Not that interpolating with a fixed alpha (or near fixed using DeltaTime) will cause the actor to never reach its target, it will slow down exponentially as it gets closer to the target as its only moving a fixed portion of the remaining distance.
When you get the axis from a Quat, the result is a unit vector in the desired direction. (1 unit in Unreal = 1 cm) so you’ll need to multiply the GetAxisX() by the radius of the sphere you’re interpolating around.
For anyone looking around like I was, here is a link to a vector SLerp code sample, that you can easily add to a global header:
// Special Thanks to Johnathan, Shaun and Geof!
Vector3 Slerp(Vector3 start, Vector3 end, float percent)
{
// Dot product - the cosine of the angle between 2 vectors.
float dot = Vector3.Dot(start, end);
// Clamp it to be in the range of Acos()
// This may be unnecessary, but floating point
// precision can be a fickle mistress.
Mathf.Clamp(dot, -1.0f, 1.0f);
// Acos(dot) returns the angle between start and end,
// And multiplying that by percent returns the angle between
// start and the final result.
float theta = Mathf.Acos(dot)*percent;
Vector3 RelativeVec = end - start*dot;
RelativeVec.Normalize(); // Orthonormal basis
// The final result.
return ((start*Mathf.Cos(theta)) + (RelativeVec*Mathf.Sin(theta)));
}
I’m using it to subdivide a spherical mesh and its working well.