Feature Request: A callback on velocity change

Mar 30, 2010 at 7:11 PM

Much like the callback on update. I've added it locally but it would be nice to get it in Farseer proper. This would be useful for safely capping the velocity of bodies. If you do it outside the farseer update you can easily exceed your maximum velocity whenever a force or impulse is applied. ie:

Body.ApplyForce(new Vector2(10000, 0));

// Cap Velocity in X direction, but body will still move far more than 10 units in that direction on the next frame
Body.Velocity = new Vector2(Max(10, Body.Velocity.X), Body.Velocity.Y);

The velocity at ten units but on the next frame, when the applied force is resolved, the actual velocity will far exceed that. So if you're going to cap the speed it needs to be done following the update to velocity from any new forces but before the position is set.

I realize using LinearDrag would be preferable but these kinds of hacks are needed for character controls and such.

 

 

Developer
Mar 30, 2010 at 11:27 PM

Are you requesting this feature for 3.x or 2.1.3 version of the engine?

As an alternative you could create your own class inheriting from Body and override ApplyForce and even the set method of Velocity.

 

Mar 31, 2010 at 3:14 AM
I'm using 2.1.3 right now but would like to move to 3.0 when it's ready! So, ideally, first one and then the other? =D I considered overriding Body but it looks like LinearVelocity is just a public Vector2 and the class is sealed anyways. I'm new to C# so forgive me if I'm overlooking something obvious.
Developer
Mar 31, 2010 at 3:28 AM

OK, well I will add this on our list of features, but for 2.1.3 I will just give you a method to replace what is in the engine right now. Just to be clear you want an event fired whenever the velocity of a Body is changed? Please realize I have no idea how many times per iteration the velocity is changed so your event could get fired several times in one time step. Are you comfortable recompiling Farseer?

Also do you realize that your code -

Body.ApplyForce(new Vector2(10000, 0));

// Cap Velocity in X direction, but body will still move far more than 10 units in that direction on the next frame
Body.Velocity = new Vector2(Max(10, Body.Velocity.X), Body.Velocity.Y);

doesn't 'cap' the velocity. It sets its minimum to 10 with no maximum. To limit the velocity you should change Max to Min and use a constant variable where 10 is to define the maximum allowable velocity. Like this -

const int
maxVelocity = 100;

Body.ApplyForce(new Vector2(10000, 0));

// Cap Velocity in X direction, but body will still move far more than 10 units in that direction on the next frame
Body.Velocity = new Vector2(Math.Min(maxVelocity, Body.Velocity.X), Body.Velocity.Y);

Mar 31, 2010 at 4:09 AM
Edited Mar 31, 2010 at 4:09 AM
Woops! You're right, of course. I grabbed and simplified some old code that was capping velocity along the negative x axis. I already have some changes here that seem to work for my purposes (I just added a delegate to Body and invoke it at the end of Body::IntegrateVelocity) so I don't have any immediate need, I'd just hate to have to forever rely on unofficial modifications to Farseer =) Thanks a lot for considering my request.