Calculating trajectory with PhysX drag

Between posts at
and more from stackoverflow which I cannot manage to locate again, I’ve been working on creating a toolset for calculating trajectory to match PhysX’s systems. To that end, I have the calculations completed without drag factored in.

In short, I calculate the velocity to launch from point A to point B in X seconds with

HorizontalVelocity = HorizontalDistance * TimeInFlight;
VerticalVelocity = (VerticalDistance + ((0.5f * GravityMagnitude) * (TimeInFlight * TimeInFlight))) / TimeInFlight;

and then calculate resultant positions along that curve by multiplying that initial velocity vector (per direction) by a chosen timestep and any applicable gravitational influence.

HorizontalPoint = HorizontalVelocity * TimeStep;
VerticalPoint = (VerticalVelocity * TimeStep) - ((0.5f * GravityMagnitude) * (TimeStep * TimeStep));

From the aforementioned post, Physx is very definitely defining motion which can be recreated with:

void FixedUpdate()
	velocity = velocity + (Physics.gravity * Time.fixedDeltaTime);
	velocity = velocity * (1 - (GetComponent<Rigidbody>().drag * Time.fixedDeltaTime));
	transform.position += (velocity * Time.fixedDeltaTime);

What I have been unable to manage to do, however, is implement that drag into the trajectory calculations. I would presume that drag should be able to be simplified into something like

Mathf.Clamp01(Mathf.Pow(1.0f - (drag * Time.fixedDeltaTime), targetTime / Time.fixedDeltaTime))

in order to simulate the effects of drag over time, but I have had no success in joining it together with either of the initial velocity calculation or the stepped calculations (to create preview lines, for example) in a way which matches up with the actual physics calculations.

In general, I’ve been aiming for a single formula for these calculations (represented by essentially only using starting point and velocity vector, then getting points at specific times) rather than working incrementally (for example, calculate each physics step one at a time to catch up to the destination point). Am I overlooking something in how I’m attempting to factor in drag ahead of time, or is it even more complicated than I’m realizing?

Your mentioned Math.Pow would work for your HorizontalPoint but not for VerticalPoint. The problem is that the calculations involved are addition and multiplication each step. An addition is a “fix-amount-change” while the multiplication is a “percentage-change”. Since those things happen each step they are alternating.

So drag isn’t a factor of the whole progression but of each step since each step is based on the last value plus the gravity vector the whole thing scaled down by drag. You can write it as endless progression like that:

((((initialVel + g)*d+g)*d+g)*d+g)*d...

// btw d = 1 - drag * Time.fixedDeltaTime

Just look at the result after 1, 2, 3 iterations:

// i = initialVel

0 iterations   i
1 iterations   i*d     + g*d
2 iterations   i*d*d   + g*d*d   + g*d
3 iterations   i*d*d*d + g*d*d*d + g*d*d + g*d
4 iterations   i*d^4   + g*d^4   + g*d^3 + g*d^2 + g*d
5 iterations   i*d^5   + g*d^5   + g*d^4 + g*d^3 + g*d^2 + g*d

This progression can’t be liniarized. So i see no way beside iterating it.

Floating point math nowadays is extremely fast. You can do thousands or millions of those calculations without much problems.

Also keep in mind that this doesn’t even consider friction or collisions (which of course can’t be predicted without iterating).