diff --git a/OpenRA.FileFormats/WPos.cs b/OpenRA.FileFormats/WPos.cs index 25f76bef65..32ec012970 100644 --- a/OpenRA.FileFormats/WPos.cs +++ b/OpenRA.FileFormats/WPos.cs @@ -36,6 +36,20 @@ namespace OpenRA public static WPos Lerp(WPos a, WPos b, int mul, int div) { return a + (b - a) * mul / div; } + public static WPos LerpQuadratic(WPos a, WPos b, WAngle pitch, int mul, int div) + { + // Start with a linear lerp between the points + var ret = Lerp(a, b, mul, div); + + if (pitch.Angle == 0) + return ret; + + // Add an additional quadratic variation to height + // Uses fp to avoid integer overflow + var offset = (int)((float)((float)(b - a).Length*pitch.Tan()*mul*(div - mul)) / (float)(1024*div*div)); + return new WPos(ret.X, ret.Y, ret.Z + offset); + } + public static WPos Average(params WPos[] list) { if (list == null || list.Length == 0) diff --git a/OpenRA.FileFormats/WVec.cs b/OpenRA.FileFormats/WVec.cs index 4eab6e15d1..7b450d9d57 100644 --- a/OpenRA.FileFormats/WVec.cs +++ b/OpenRA.FileFormats/WVec.cs @@ -53,6 +53,20 @@ namespace OpenRA public static WVec Lerp(WVec a, WVec b, int mul, int div) { return a + (b - a) * mul / div; } + public static WVec LerpQuadratic(WVec a, WVec b, WAngle pitch, int mul, int div) + { + // Start with a linear lerp between the points + var ret = Lerp(a, b, mul, div); + + if (pitch.Angle == 0) + return ret; + + // Add an additional quadratic variation to height + // Uses fp to avoid integer overflow + var offset = (int)((float)((float)(b - a).Length*pitch.Tan()*mul*(div - mul)) / (float)(1024*div*div)); + return new WVec(ret.X, ret.Y, ret.Z + offset); + } + public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); } public override bool Equals(object obj)