Per-Entity Gravity

Post and discuss features you'd like to see in the BEPUphysics library.
Post Reply
mcmonkey
Posts: 92
Joined: Fri Apr 17, 2015 11:42 pm

Per-Entity Gravity

Post by mcmonkey »

It'd be pretty neat if we could specify a gravity vector on each entity rather than in the Space.

A simple way to accomplish this in a non-changing manner would be to use something along the lines of a Nullable<Vector3> -> if it's null, use Space.Gravity, otherwise, use the value input.

In theory, this should be a relatively simple addition, just use Entity.Gravity rather than Space.Gravity.

This would allow all sorts of fun tricks - entities that are floating (EG in water or a zero-grav chamber or whatever) and thus have no gravity pull. Or perhaps a very very large space consisting of multiple planets, and each entity's gravity is the sum of all planet's gravity's adjusted for distance between the entity and the planet. Or even allowed mcmonkey to go mad with power as he does in the Quake3 Engine:: http://social.xfire.com/videos/4f99e4

Who has per-entity gravity?
Bullet does.
Even Quake (not even a physics engine) has it available.

Is this workaround-able?
Yes. Somewhat. Every tick, apply an impulse that counters the standard effect of gravity, then a second one that applies the new gravity. But this is, of course... excessive. Three forces are applied to every entity involved every tick, that's too much. And it's not even perfect, as the internal code isn't exactly the same as Impulse(gravity * TimeStep) every tick. (or at least I think it's more than that. Acceleration in the real world doesn't actually work like that, that's merely a fair estimate of how it works.)
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Per-Entity Gravity

Post by Norbo »

I went ahead and replaced Entity.IsAffectedByGravity with a nullable Entity.Gravity since it's low impact and just a feature superset: https://bepuphysics.codeplex.com/Source ... changesets

However, I should mention that this type of thing is probably not going to survive into the core of BEPUphysics 2.0. The engine is heading for a major rewrite that focuses on maximum performance and a minimal API. Anything which isn't really a part of core physics simulation will likely be punted to the user or to convenience layers built outside of the core API. The API just makes sure it's possible to build such layers. (Philosophically, it's a bit like the OpenGL/DX11->Vulkan/DX12 move.)

Some examples of other likely victims of this redesign:
-Internal timestepping. There is really nothing special about internal timestepping- it's just one possible (and very simple) implementation of fixed timesteps that could, and probably should, be implemented externally.
-Space-resident state buffers and state interpolation. Users who need these things (for asynchronous updates or internal timestepping) have to opt in anyway, and there's no reason to have them baked into the engine proper.
-All deferred collision events, and many immediate collision events. The important degrees of access will be retained, but the engine will do far less.
-"Prefab" entity types like Box, Sphere, and so on are totally redundant and only exist for legacy reasons. Related complicated inheritance hierarchies and generics to expose typed fields in collidables will also likely go away.
-Fat collision rules. Some games can get by with no filtering, or just bitfields. The engine and API shouldn't be hauling around a bunch of pointless dictionaries for such use cases.
And so on.
This would allow all sorts of fun tricks - entities that are floating (EG in water or a zero-grav chamber or whatever) and thus have no gravity pull. Or perhaps a very very large space consisting of multiple planets, and each entity's gravity is the sum of all planet's gravity's adjusted for distance between the entity and the planet. Or even allowed mcmonkey to go mad with power as he does in the Quake3 Engine:: http://social.xfire.com/videos/4f99e4
This sort of stuff was already pretty darn easy; check out the PlanetDemo in the BEPUphysicsDemos. (Note that none of the 'gravity field' stuff is a part of the physics engine itself, just demos-side sample code.)
Yes. Somewhat. Every tick, apply an impulse that counters the standard effect of gravity, then a second one that applies the new gravity. But this is, of course... excessive. Three forces are applied to every entity involved every tick, that's too much.
In the previous version, setting entity.IsAffectedByGravity to false and applying your own gravity impulse would suffice. Also, note that the application of an impulse is trivially cheap; even if you needed to apply three impulses per object per tick, it wouldn't even show up on a profiler. The engine is doing way more complicated stuff.
And it's not even perfect, as the internal code isn't exactly the same as Impulse(gravity * TimeStep) every tick. (or at least I think it's more than that. Acceleration in the real world doesn't actually work like that, that's merely a fair estimate of how it works.)
That's actually exactly how gravity works. From Entity.UpdateForForces:

Code: Select all

Vector3.Add(ref forceUpdater.gravityDt, ref linearVelocity, out linearVelocity);
Game physics are all about fair estimates :)
JusTiCe8
Posts: 52
Joined: Mon Jun 01, 2015 9:02 am

Re: Per-Entity Gravity

Post by JusTiCe8 »

As 1.4.0 include now this feature, how it is suppose to be use ? Is there any new demo of it ?

Does this mean the gravity is applied to anything near the entity (quite like the forcefield in planet demo) or something else ?

As entity's gravity is defined as a vector, first we need to create the vector pointing toward the "center of mass" (either mesh barycenter or a user defined point, even outside the mesh) I guess. Or does this work in a completely different way ?

Thanks.

PS: @Norbo, I take the opportunity here to thank you for the new update, it's just unbelievable how long you have keep up the will to improve BEPU.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Per-Entity Gravity

Post by Norbo »

There is no demo of it; it just changes the specific entity's linear velocity by gravity * dt each time step. If it's set, it overrides the ForceUpdater.Gravity for that entity. It doesn't affect any nearby entities.
As entity's gravity is defined as a vector, first we need to create the vector pointing toward the "center of mass" (either mesh barycenter or a user defined point, even outside the mesh) I guess. Or does this work in a completely different way ?
If you want to make an entity orbit some other object's center of mass, you would indeed need to change the gravity each timestep to compensate for the change in position.
it's just unbelievable how long you have keep up the will to improve BEPU.
I wonder how many more times I'm going to rewrite it...
Post Reply