Atmospheric flight model 2.0

In this blog post, I will explain changes to the atmospheric flight model that was introduced in patch 0.1.4.0. Warning: it’s going to get long and technical, so if you don’t like talks about physics, this is your last chance to preserve your brain from a headache !


Basic flight theory

Before I go explaining what the new version does, one needs to understand how the previous version ( prior to patch 0.1.4.0 ) was working.

First of all, thrust and gravity should be pretty self-explainatory, so I won’t speak of those here. There has been no change in the atmospheric flight model for these two forces.

In atmospheric flight, the dominant force is drag. Drag is the reason why you reach a terminal velocity either when falling, or when flying at max speed in air. Drag opposes to the movement of the object. As for lift, it comes from the wing profile and difference of air pressure between under and above the wing. A good airplane maximizes lift while minimizes drag.

The old atmospheric model used two equations for drag and lift. Both are kind of similar, but let’s have a look at drag first:

  • Fd is the drag force
  • p is the atmospheric density ( 1,225 kg/m^3 at sea level on Earth, decreases with altitude exponentially )
  • A is the wing area
  • Cd is the drag coefficient ( more on that later )
  • v is the speed

The most important thing to understand is that drag grows with the square of the size ( aka wing area ) and speed. When drag reaches thrust capacity, your object cannot accelerate any further and you hit terminal velocity.

The drag coefficient is a factor that determines how aerodynamic your object is. The closer to a bulky box, the higher it is. For an airplane seen from the front, Cd is minimal. That’s why planes do not behave like bricks, heh. Cd is usually found experimentally.

Lift is a very similar formula:

… except that this time it uses a lift coefficient, instead of a drag coefficient. The lift coefficient is interesting, because it changes ( for wings ) based on the angle of attack. In other words, depending on the inclination of the wing compared to the travel direction, you get different values for Cl.


Old atmospheric flight model ( 1.0 )

In the old flight model, the two equations were implemented directly. To determine the lift and drag coefficients Cd and Cl, based on the angle of attack, I used the following curves:

http://www.aerospaceweb.org/question/airfoils/q0150b.shtml

As you can see, those simplify the object as an airfoil. Our ships aren’t wings, they’re actually more like bricks. So, in many ways, the old atmospheric flight model was incorrect. More importantly, the overall shape of the ship in the travel directory ( the “flow vector” ) wasn’t a factor.

In order to make everything work well in the game prototype, I had to add arbitrary coefficients both in the drag and lift equations.


New atmospheric flight model ( 2 .0 )

To better determine the drag coefficient, my idea was very practical. Every single frame, cast a bunch of rays in the direction of the flow movement vector, and determine which percentage of those hit the surface of the object and at which angle. Each ray simulates air molecules hitting the object and resulting in a force that causes linear and rotational acceleration. The idea is similar to doing an integral over the flow surface.

For performance reasons, the number of rays is quite limited. I settled for a value of 25,but I experimented lower values ( 10 ) or higher ( up to 500 ). I haven’t noticed much of a difference in the quality or stability of the simulation based on the number of rays. Keep in mind those are rays per frame ( for a given flying object ), so at 100 fps, if you have a hundred objects and cast 500 rays, that’s a total of 100 * 100 * 500 = 5 million rays. This shouldn’t be a problem with 25 rays though, especially as the code can be optimized later.

The shape of the object is approximated with a bounding box. Later on we can refine the shape with a set of convex volumes if needed, but I think a box is a good first approximation of our flying bricks, err… ships.

So, what the algorithm does for each ray is to cast a ray, determine if it hits that box, and if it does, generate a feedback force along the normal of the box surface. This will naturally generate drag and lift.

To explain this better, let’s have a look at a simple scenario, in a standalone testbed app which I developped just for that purpose:

Ouch ! Lots of vectors all over the place. They’re color coded and represent the following:

  • The dark blue vector ( pointing downwards outside the screen ) is the gravity vector
  • the yellow vector ( pointing downwards and right outside the screen ) is the velocity vector
  • The brown vectors represent flow-casts that missed the object
  • The green vectors represent flow-casts that hit the object
  • Finallt, the important ones: the purple/pink vectors represent the output forces acting upon the object as a result of the flow-cast

The object is obviously represented by the box ( seen from the sides ). This approximates our ship. The “front” ( nose ) is actually pointing to the right of the screen, slightly pitched downwards.

In this scenario, the ship is falling through the atmosphere and generates a good amount of drag due to it. It’s pretty close to hitting its fall terminal velocity. The simulated ship is the fighter, and weights 26 tons. Its dimensions ( the box’s ) are 12m x 4.5m x 15m.

If you pitch the ship even more so that it’s nose matches the velocity / air flow, it minimizes drag since the “profile area” is now much smaller. The terminal velocity increases to 150 m/s or even higher…

Inversely, if you counter-pitch the ship to maximize its area, like it was free-falling like a sky diver in a belly position, the terminal velocity diminishes to less than 100 m/s:



As you can see, this model seems to work out pretty well for drag. The way your object / ship is oriented changes the amount of drag, which changes the maximum speed you can reach. In this testbed, the atmospheric density is a constant, but in the game prototype it varies with altitude ( not per planet though; all planets use 1,225 kg/m3 at ground level. I’ll probably change that in a later patch to give more variety to planets ).

The most interesting part of this new model is that I was able to get ride of the arbitrary coefficients of the old model. And when I did that, I was very curious to see what results I would obtain if I simulated a sky-diving human in free-fall. According to wikipedia, a sky-diver in belly position would hit terminal velocity at around 50 m/s, 90 m/s in head-diving and up to 120 m/s with special equipment to minimize drag.

Well, I tested these 3 scenarios, and surprise surprise… without any arbitrary factors, my 90 Kg man-sized box did hit pretty close to these terminal velocities. Not bad, not bad. At least as far as linear accelerations are concerned.

One thing I still haven’t solved are torque ( rotational accelerations ). Without introducing an arbitrary factor in the equation, I found that the amount of torque is very high. In fact, it makes a sky-diving human quickly lose its stability and start to rotate in all directions. I do not know if I’m missing something in the physics or if I can simply blame it on the method ( a low amount of ray casts means every frame, the flow vectors hit the object at random positions. It’s no problem for the linear acceleration, but this randomization in the surface positions causes a random amount of torque ). For the game prototype, I had to introduce a scalar factor in the torque ( linear accelerations are left 100% realistic though ) otherwise it quickly became unplayable during re-entry, or even flying above 100 m/s in the atmospheres.

Last thing: more factors can easily be introduced into the atmospheric flight model. Such is wind, the cyan vector in the following picture:

In this scenario, the wind force blows from the back of the ship and helps flying in the direction of movement. Of course, if the wind was coming from the front of the ship, it’d slow it down a little bit. In the old atmospheric flight model 1.0, I didn’t know how to correctly generate an acceleration force out of a wind velocity, which results in awkyard behavior. In the new model, wind is simply added to the flow vector, and is naturally taken into account in the simulation. It behaves a lot better / more realistically.

Also note the big red vector on the right, slighly upwards. This is is thrust. As you can see, this scenario shows a ship flying in an atmosphere with a low amount of thrust ( 10% of what it’s capable of ). It hits maximum air speed ( drag = thrust ) at around 160 m/s. Of course, that’s only for 10% of its maximum thrust. At 100%, it can fly much, muuuch faster. Let’s see how fast exactly:

In this picture, the fighter is flying at 100% of its thrust capabilities ( according to my doc, that’d be around 5.7 g’s ). It hits maximum air speed at around 445 m/s. The view is zoomed out a bit, but as you can see, the big pink vector pointing to the left has become huge compared to the object’s size. There’s a small amount of lift too ( pointing upwards ) but it’s not enough to maintain the ship in air due to the gravity. This is probably a good example of the lack of insufficient lift, since our ships are more like bricks than wings.

Another factor that can be taken into account is the sound speed barrier ( mach 1.0 ). For the implementation details, see this forum thread:

https://forums.inovaestudios.com/t/0-1-3-0-drag-tests-and-approximations/3464/27

I implemented it with constant sound speed ( around 340 m/s ), which causes the drag coefficient to rise up to x5 of its normal value. Let’s see if our ship at 100% thrust can still reach 445 m/s…

… nope, no way. At around 320 to 330 m/s, the ship becomes unable to speed up more. The mach barrier is definitely here. I’d need a lot more power / thrust to breach it. Or a lower drag coefficient. The conclusion here is that if you’re flying a brick, you really need a lot of power if you want to breach the sound limit.


Feedback & conclusion

For those of you who have tested the new atmospheric flight model in game, feel free to post your feedback.

I believe the sound barrier is a problem, as flying at 340 m/s is actually pretty slow. The good thing is that it will probably make combat better, and give a better sense of scale to the planets. The bad thing however is that it can now take forever to fly anywhere, or to escape from a planet to get into warp. 4-5 minutes is not unexpected, and is much longer than what I’d personally like to see.

It seems likely that, moving forward, we’ll re-introduce a per-ship aerodynamic coefficient which will be used as a multiplier to nerf the drag coefficient. It should allow ships to fly faster in atmospheres, and take off into warp more quickly. The downside is that it might make re-entry harder ( atmosphere will slow you down slower ) so it might get more tricky if you don’t control your entry speed.

As for lift, it is possible to introduce a new lift model, or to increase some coefficients to artificially introduce a higher amount of lift. As this point we enter the realism versus gameplay discussion. What do you think is best ? Do you want your “bricks” to have a decent amount of lift in atmospheres ? Did you like the roll-then-pitch approach of the old versions ? Let us know !

21 Likes

On the one hand, I can certainly appreciate the practical approach to the new flight model, however it does feel somewhat less enjoyable than the old model (as is usually the case when realism is sacrificed). I liked that ships could power through the atmosphere during entry without sliding to the side or tumbling out of control (there almost seems to be more lift during entry with the new model). I also enjoyed the more conventional flying style of rolling and pitching which does still seem to work well, but I feel I’m having to pitch up more and often.

In terms of speed, I’m sure you’ve done all your calculations correctly, but somehow 340m/s just doesn’t feel right (in terms of how fast I expect it to be). Of course, I’m not a fighter pilot, but I’ve played my fair share of flying sims and transonic flight feels like it should be a bit faster. I tried comparing to a couple in-cockpit videos, and the kind of speed we get at the sound barrier seems more like ~240m/s.

1 Like

I just want to note what was discussed on Discord, once you implement shields you can change the brick model to a squeezed sphere. The shield would act in place of the ship hull while it’s powered and should provide a more airplane like lift and drag values, allowing greater speed and some interesting gameplay mechanics.

6 Likes

Prolate spheroid. :blush:

3 Likes

FLYING SAUCER!

3 Likes

Very interesting read.
I’m completely ignorant about this stuff but given the simple shape of the ship (box) couldn’t the drag be analytically calculated in some way without the need of simulation?

I don’t have access to that topic. Is that expected?

Keep up the great work!

Sweet. There’s been a lot back and forth when 0.1.3.0 hit and the other extreme … ships with a terminal velocity of 16km/s happened.

This solution is a very interesting approach and really does work ingame, which is kinda amazing considering aerodynamics is something that can be as complex as you let it be.

I find it fun that the randomness is visible to the player. The minimal velocity fluctuations when flying are a nice addition to the feel of the atmosphere.

How well would the system do with other, more complex shapes? Probably if we had angles, the probability of one ray hitting that angle is less then if it was part of the bigger surface. Thus not representing the full shape correctly.

How about taking a mean value over several frames. You let the simulation run every frame but the output means the last 10 or so frames. Wouldn’t that solve some of the problems with the rotational forces?

Wouldn’t something like that become more inaccurate at lower frame rates?

The atmosphere certainly now feels a lot more substantial and I really like the way shaking and subtle handling changes reflect dangerous speed. It feels intuitive, at least to someone who is familiar with flight simulators!

So does the current system, which is also bound to farmerate. Probably the reason why most games have a separate tickrate for physics.

And yeah, I would find modifying the ships aerodynamic shape, trough something like a shield or the main shield, more elegant than just a modifier going into the now so nicely realistic simulation.
Loosing the shield would mean whole different aerodynamic behaviour. That’s one of the ideas that was floating around in the dev-access forums.

1 Like

[quote=“Lomsor, post:9, topic:3484”]
So does the current system, which is also bound to farmerate. Probably the reason why most games have a separate tickrate for physics.[/quote]

Physics tick rate is already separated from rendering rate. That’s why even if you play on a laptop your ship won’t turn slower than if you play on a 980 Ti :wink:

2 Likes

I might be missing something obvious here, but there are some things i really do not understand.

When you take the bounding box to cast the rays again, will the shape of the ship not play zero role, only the x:y:z relations? Why do you need to cast rays anyways when you use the bounding box? Given the normal of each of the 6 quads, you can always exactly calculate what effective area the quad is “showing” ( or not showing ) towards the wind / flow vector, and at what angle. This gives you an exact deflection force for an equal distribution of air molecules over the whole quad. No randomness introduced by spawning raycasts. I would understand raycasts against the complex body of a ship where you can not always get the exact value for each quad and/or triangle, especially when some may be hidden by others ( both pointing towards the flow vector but one being behind the other ), but i fail to understand the need of raycasts for a box shape.

I like the old roll and pitch approach in atmospheres.

About the slow speeds in atmot…
I am for giving engines more power, so that ships can breach sound barrier easily.
Not immediate power! But power that can be achieved if constant acceleration is applied for bit of time in straight vector.
With downside of ships being progressively less and less controllable as you gain speed.
A cruise mode if you will or atmospheric warp…

1 Like

[quote=“Wargrim, post:11, topic:3484”]
Why do you need to cast rays anyways when you use the bounding box? Given the normal of each of the 6 quads, you can always exactly calculate what effective area the quad is “showing” ( or not showing ) towards the wind / flow vector, and at what angle.[/quote]

Yeah, I guess you could do that too. Although you’d have to calculate the size / area of the projected 2D quad for every single of these 6 faces, and also would have to take back-facing into account. Overall it might be easier ( or even faster ) to do it through a few ray casts. In any case, the ray cast method was done in anticipation of using more complex shapes in the future, but if performance becomes a problem, I agree I’ll probably fall back on the projected quads method. You’re right that there should be less instability though, so I might do that anyways.

Keep the rays if you can, we want Prolate spheroids in some future patch. :slight_smile:

I’m pleasantly surprised by the new complexity, yet its still more simple than doing an entire vector flow field. I like it.

If you’re using a box shape based on the bounding box for all ships aerodynamic models, then that’s probably the best path to take. Though if you want, perhaps you can test different shapes. Maybe make a wedge from the ship bounds instead?

On a related note: With the low surface area-to-weight ratio (i.e. a brick), the atmosphere will have less effect on maneuvering as it does now. In this case, I think I like everyone else’s idea of having the shields with their own geometric model that alters aerodynamics while it’s active. It could introduce some very unique dynamics to the game.

As a single on/off mechanism it could make engagements more precarious, or add an interesting combat option for daring pilots.

If it’s a modifiable parameter, then you might be able to get better turning rates at the expense of making your shields large and easy to hit.

On a side note, I think I personally could stand a higher thrust-to-weight ratio on the interceptor. I’d like it to feel significantly more agile.

On a parallel note, higher over-all thrust values may be necessary to counter problems with very thick atmospheres, or at least make them playable.

On a tangent note, purple vectors are more important than green ones. #purpleftw

2 Likes

I like the raycast method.

Yeah, way too slow for me, definitely needs to be faster - much, at least while flying in straighter lines. Also wondering if a solution to balancing could be adding heat that can destroy a ship during reentry. Personally I would love this realistic, challenging aspect of reentry, while overlooking some of the more mathematically challenging atmospheric flight mechanics.

you are amazing

1 Like

Quick note: using raycasts is, at hypersonic speeds, surprisingly accurate. At subsonic speeds, it looses accuracy.

1 Like

I’d be rather interested in the difference between the aerodynamics of the box, and of a convex manifold of the ship. Especially considering that the ship’s area tends to be quite a bit less than the bounding box, even if it is a bit boxy in general.