Lerp turning-while-moving mobile actors along an arc.
This commit is contained in:
@@ -292,6 +292,12 @@ namespace OpenRA.Mods.Common.Activities
|
||||
protected readonly Move Move;
|
||||
protected readonly WPos From, To;
|
||||
protected readonly int FromFacing, ToFacing;
|
||||
protected readonly WPos ArcCenter;
|
||||
protected readonly int ArcFromLength;
|
||||
protected readonly WAngle ArcFromAngle;
|
||||
protected readonly int ArcToLength;
|
||||
protected readonly WAngle ArcToAngle;
|
||||
|
||||
protected readonly int MoveFractionTotal;
|
||||
protected int moveFraction;
|
||||
|
||||
@@ -304,6 +310,24 @@ namespace OpenRA.Mods.Common.Activities
|
||||
ToFacing = toFacing;
|
||||
moveFraction = startingFraction;
|
||||
MoveFractionTotal = (to - from).Length;
|
||||
|
||||
// Calculate an elliptical arc that joins from and to
|
||||
if (fromFacing != toFacing)
|
||||
{
|
||||
// The center of rotation is where the normal vectors cross
|
||||
var u = new WVec(1024, 0, 0).Rotate(WRot.FromFacing(fromFacing));
|
||||
var v = new WVec(1024, 0, 0).Rotate(WRot.FromFacing(toFacing));
|
||||
var w = from - to;
|
||||
var s = (v.Y * w.X - v.X * w.Y) * 1024 / (v.X * u.Y - v.Y * u.X);
|
||||
var x = from.X + s * u.X / 1024;
|
||||
var y = from.Y + s * u.Y / 1024;
|
||||
|
||||
ArcCenter = new WPos(x, y, 0);
|
||||
ArcFromLength = (ArcCenter - from).HorizontalLength;
|
||||
ArcFromAngle = (ArcCenter - from).Yaw;
|
||||
ArcToLength = (ArcCenter - to).HorizontalLength;
|
||||
ArcToAngle = (ArcCenter - to).Yaw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Cancel(Actor self)
|
||||
@@ -344,9 +368,22 @@ namespace OpenRA.Mods.Common.Activities
|
||||
|
||||
void UpdateCenterLocation(Actor self, Mobile mobile)
|
||||
{
|
||||
// avoid division through zero
|
||||
// Avoid division through zero
|
||||
if (MoveFractionTotal != 0)
|
||||
mobile.SetVisualPosition(self, WPos.Lerp(From, To, moveFraction, MoveFractionTotal));
|
||||
{
|
||||
WPos pos;
|
||||
if (FromFacing != ToFacing)
|
||||
{
|
||||
var angle = WAngle.Lerp(ArcFromAngle, ArcToAngle, moveFraction, MoveFractionTotal);
|
||||
var length = int2.Lerp(ArcFromLength, ArcToLength, moveFraction, MoveFractionTotal);
|
||||
var height = int2.Lerp(From.Z, To.Z, moveFraction, MoveFractionTotal);
|
||||
pos = ArcCenter + new WVec(0, length, height).Rotate(WRot.FromYaw(angle));
|
||||
}
|
||||
else
|
||||
pos = WPos.Lerp(From, To, moveFraction, MoveFractionTotal);
|
||||
|
||||
mobile.SetVisualPosition(self, pos);
|
||||
}
|
||||
else
|
||||
mobile.SetVisualPosition(self, To);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user