ace/Source/ACE.Server/Physics/Trajectory2.cs

64 lines
1.8 KiB
C#

using System;
using System.Numerics;
using ACE.Server.Physics.Common;
namespace ACE.Server.Physics
{
public static class Trajectory2
{
public static Vector3 CalculateTrajectory(Vector3 startPos, Vector3 endPos, Vector3 targetVelocity, float speed, bool gravity)
{
var targetOffset = endPos - startPos;
Vector3 result;
float t = 0.0f;
if (targetVelocity == Vector3.Zero)
{
var targetDist = targetOffset.Length();
t = targetDist / speed;
result = targetOffset / t;
}
else
{
var p0 = targetOffset;
var p1 = Vector3.Zero;
var v0 = targetVelocity;
if (Vec.NormalizeCheckSmall(ref v0))
v0 = Vector3.Zero;
var s1 = speed;
var a = (v0.X * v0.X) + (v0.Y * v0.Y) - (s1 * s1);
var b = 2 * ((p0.X * v0.X) + (p0.Y * v0.Y) - (p1.X * v0.X) - (p1.Y * v0.Y));
var c = (p0.X * p0.X) + (p0.Y * p0.Y) + (p1.X * p1.X) + (p1.Y * p1.Y) - (2 * p1.X * p0.X) - (2 * p1.Y * p0.Y);
var t0 = Math.Sqrt((b * b) - (4 * a * c));
var t1 = (-b + t0) / (2 * a);
var t2 = (-b - t0) / (2 * a);
if (t1 < 0)
t1 = float.MaxValue;
if (t2 < 0)
t2 = float.MaxValue;
t = (float)Math.Min(t1, t2);
if (t >= 100)
return CalculateTrajectory(startPos, endPos, Vector3.Zero, speed, gravity);
var s0 = targetVelocity.Length();
result = (p0 + t * s0 * v0) / t;
}
if (gravity)
result.Z -= PhysicsGlobals.Gravity * t * 0.5f;
return result;
}
}
}