Dynamic entity, LinMomentum=0, still moving !

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
JusTiCe8
Posts: 52
Joined: Mon Jun 01, 2015 9:02 am

Dynamic entity, LinMomentum=0, still moving !

Post by JusTiCe8 »

Hi,

when trying to go back to the "source" (ie: forces), I encounter something odd:

a dynamic entity (m=50) is put in the air (y=500), space has "standard" gravity (y=-9.81), no entity's personal gravity defined.

I have add a "hovering mode" (called levitation in the code), which either before and after or just after a space.Update call, nullify the linear momentum of the entity. Before update call let the gravity do its job for the last dt elapsed, also after update call remove the gravity action. I got both LM and LV = 0 (only y component is considered).
But, y position of the entity still slowly decrease (between -0.1 and -0.2 unit/s), with isFixedTimeStep = true or false and these engine settings only:

Space.Solver.IterationLimit = 100;
CollisionDetectionSettings.AllowedPenetration = 0.002f;

and BEPU binaries release from 15/06/2015 (1.4.0), using a snapshot from the 11/12/2015 gives the same result.
Entity is initially a capsule (build with CapsuleShape), I have also used a CylinderShape just to check, same result (for these two, if any angular velocity exists, it would be on the symmetry axis, Y), also with SphereShape and a BoxShape, not angular velocity observed.

Seen this thread, but can't get a dynamic entity, with a zero LM, to stay where it is.

Also, if I replace this line:

Code: Select all

demo.LinearMomentum -= demo.LinearMomentum;
by these:

Code: Select all

demo.LinearMomentum = BEPUutilities.Vector3.Zero;
                demo.AngularMomentum = BEPUutilities.Vector3.Zero;
"ghost force" still drag the object down.

I just wish to understand what's happening there, is this an issue with my code or somewhere in BEPU or did I do something wrong ?

My entire solution is provided (not in demo format, sorry).


bonus question: in EntityBase code, I see LM is calculated with

Code: Select all

Vector3.Multiply(ref linearVelocity, mass, out momentum);
why doing it "backward" ?

Should not be the LV be a result of LM. I'm pretty sure LV is quite easy to get when only gravity is applied to an entity, but with more complicated system like a rocket/plane engine, you can't get LV directly, at least if you have choose some accuracy.

Thanks.
Attachments
ForcesCalcTest.zip
test code
(33 KiB) Downloaded 247 times
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Dynamic entity, LinMomentum=0, still moving !

Post by Norbo »

Gravity is applied near the start of the time step. Position integration is performed at the end. So, setting velocities to zero outside of the timestep will allow a single frame's worth of gravity to be integrated into displacement.

Either use the built in per-entity gravity, or hook the Space.ForceUpdater.Finishing event so that your modification can counteract built in gravity.
why doing it "backward" ?

Should not be the LV be a result of LM. I'm pretty sure LV is quite easy to get when only gravity is applied to an entity, but with more complicated system like a rocket/plane engine, you can't get LV directly, at least if you have choose some accuracy.
Linear velocity and momentum differ only by a scale, so there's no reason to store both. Linear velocity was chosen as the in-memory value because it is the more commonly accessed value.

Angular velocity and momentum work similarly, though there are a few more approximations happening there for speed and stability.
JusTiCe8
Posts: 52
Joined: Mon Jun 01, 2015 9:02 am

Re: Dynamic entity, LinMomentum=0, still moving !

Post by JusTiCe8 »

ok ,thanks.

(you may have already guess this: ) it would be great to add some piece of documentation about what happened inside BEPU during a single big time step (of the game), like a down arrow from game.update call start to finish, including what is actually hooked by default, what we can hook ourselves, etc + where gravity calculation is done, where apply*impulse call are in the flow.

It may look like:

Broadphase
|
something
|
Narrowphase
|
something 2
|
Space.ForceUpdater.Starting (if there is any starting :) )
| ...
some calculations
|
Space.ForceUpdater.Finishing
|
V end
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Dynamic entity, LinMomentum=0, still moving !

Post by Norbo »

The "Overview of changes from v0.14.3 to v0.15.0" has some relevant information in it:
http://download.codeplex.com/download?P ... dId=217294

It's still mostly accurate, for now. I'll probably have to make another one when v2.0 comes out.

All update stages have the starting/finishing events.
JusTiCe8
Posts: 52
Joined: Mon Jun 01, 2015 9:02 am

Re: Dynamic entity, LinMomentum=0, still moving !

Post by JusTiCe8 »

Hi Ross, don't want to bother you with this but
Norbo wrote: Either use the built in per-entity gravity, or hook the Space.ForceUpdater.Finishing event so that your modification can counteract built in gravity.
bugs me.

It would work in any "faked physics" style game, but suppose I would like to make a not-so-arcadish drone game for instance, if I'm willing to create an hovering auto-pilot, I shouldn't "cheat", instead I would add a lift force as equal as possible as drone weight (to keep things simple without considering a full areo physic model).

Is there any way, as it is now, to add our own forces so BEPU integration phase mix them as expected, or it would need to move gravity management as it is out ?

Thanks.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Dynamic entity, LinMomentum=0, still moving !

Post by Norbo »

If you express the forces as explicit changes in momentum per frame, there is no need to worry about the order of force application. You only need to work within the execution of the engine if what you want to do is set the momentum to zero directly without any attempt at predicting and nullifying the influence of gravity from outside the execution of the engine.

For example, if you do this:

Code: Select all

entity.LinearVelocity -= gravity * dt;
in any context that is synchronized with the stepping of the engine (as in, it is applied at every individual space time step and dt is the same as the engine's time step- watch out if using internal time stepping with Space.Update(dt)), it will exactly counteract the influence of gravity and the result will be floating in the air as expected. Basically, when combined with the built in gravity integration, this results in:

Code: Select all

entity.LinearVelocity -= x;
entity.LinearVelocity += x;
which of course results in no net change.

This makes physical sense- gravity is a force, and to counteract it, you have to apply an equal and opposite force. So, there's no need for any special techniques to get the forces to 'mix' properly- it just works.
Post Reply