Skip to content

Commit 46c4ffc

Browse files
authored
Add files via upload
1 parent 3855e16 commit 46c4ffc

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

ProjectileUtil.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//All in world space! Gets point you have to aim to
2+
//NOTE: this will break with infinite speed projectiles!
3+
//https://gamedev.stackexchange.com/questions/149327/projectile-aim-prediction-with-acceleration
4+
public static Vector3 GetTargetLeadingPositionQuadratic(Vector3 launchPosition, Vector3 launcherVelocity, Vector3 projectileAcceleration, Vector3 targetPosition, Vector3 targetVelocity, Vector3 targetAcceleration, float distance, float projectileSpeed, int iterations)
5+
{
6+
Vector3 pT = targetPosition - launchPosition;
7+
Vector3 vT = targetVelocity - launcherVelocity;
8+
Vector3 aT = targetAcceleration;
9+
float s = projectileSpeed;
10+
Vector3 aP = projectileAcceleration;
11+
12+
Vector3 accel = aT - aP;
13+
14+
//time to target guess
15+
float guess = distance / s;
16+
17+
if (iterations > 0)
18+
{
19+
//quartic coefficients
20+
float a = Vector3.Dot(accel, accel) * 0.25f;
21+
float b = Vector3.Dot(accel, vT);
22+
float c = Vector3.Dot(accel, pT) + Vector3.Dot(vT, vT) - s * s;
23+
float d = 2f * Vector3.Dot(vT, pT);
24+
float e = Vector3.Dot(pT, pT);
25+
26+
//solve with newton
27+
float finalGuess = SolveQuarticNewton(guess, iterations, a, b, c, d, e);
28+
29+
//use first guess if negative or zero
30+
if (finalGuess > 0f)
31+
{
32+
guess = finalGuess;
33+
}
34+
}
35+
36+
Vector3 travel = pT + vT * guess + 0.5f * aT * guess * guess;
37+
38+
return launchPosition + travel;
39+
}
40+
41+
//All in world space! Gets launch velocity you have to aim to
42+
//NOTE: this will break with infinite speed projectiles!
43+
//https://gamedev.stackexchange.com/questions/149327/projectile-aim-prediction-with-acceleration
44+
public static Vector3 GetTargetLeadingVelocityQuadratic(Vector3 launchPosition, Vector3 launcherVelocity, Vector3 projectileAcceleration, Vector3 targetPosition, Vector3 targetVelocity, Vector3 targetAcceleration, float distance, float projectileSpeed, int iterations)
45+
{
46+
Vector3 pT = targetPosition - launchPosition;
47+
Vector3 vT = targetVelocity - launcherVelocity;
48+
Vector3 aT = targetAcceleration;
49+
float s = projectileSpeed;
50+
Vector3 aP = projectileAcceleration;
51+
52+
Vector3 accel = aT - aP;
53+
54+
//time to target guess
55+
float guess = distance / s;
56+
57+
if (iterations > 0)
58+
{
59+
//quartic coefficients
60+
float a = Vector3.Dot(accel, accel) * 0.25f;
61+
float b = Vector3.Dot(accel, vT);
62+
float c = Vector3.Dot(accel, pT) + Vector3.Dot(vT, vT) - s * s;
63+
float d = 2f * Vector3.Dot(vT, pT);
64+
float e = Vector3.Dot(pT, pT);
65+
66+
//solve with newton
67+
float finalGuess = SolveQuarticNewton(guess, iterations, a, b, c, d, e);
68+
69+
//use first guess if negative or zero
70+
if (finalGuess > 0f)
71+
{
72+
guess = finalGuess;
73+
}
74+
}
75+
76+
Vector3 travel = pT + vT * guess + 0.5f * aT * guess * guess;
77+
78+
Vector3 launchVelocity = travel / guess - 0.5f * aP * guess;
79+
80+
return launchVelocity;
81+
}
82+
83+
static float SolveQuarticNewton(float guess, int iterations, float a, float b, float c, float d, float e)
84+
{
85+
for (int i = 0; i < iterations; i++)
86+
{
87+
guess = guess - EvalQuartic(guess, a, b, c, d, e) / EvalQuarticDerivative(guess, a, b, c, d);
88+
}
89+
return guess;
90+
}
91+
92+
static float EvalQuartic(float t, float a, float b, float c, float d, float e)
93+
{
94+
return a * t * t * t * t + b * t * t * t + c * t * t + d * t + e;
95+
}
96+
97+
static float EvalQuarticDerivative(float t, float a, float b, float c, float d)
98+
{
99+
return 4f * a * t * t * t + 3f * b * t * t + 2f * c * t + d;
100+
}

0 commit comments

Comments
 (0)