Pausing Dynamics For Scene Manipulation

Topics: Developer Forum, Project Management Forum, User Forum
May 26, 2011 at 6:55 PM
Edited May 26, 2011 at 10:37 PM

I'm interested in pausing the world dynamics to allow objects in the scene to be manipulated (moved, rotated, etc.).  While dynamics are disabled, I do want collisions to be active, so that objects can be manipulated without their bodies intersecting in space where they would collide in real-time.

My first instinct was to manually turn off gravity and call ResetDynamics on all bodies in the world.  This does freeze the scene, but does not disable dynamics, and moving objects with the mouse is subject to inertia.  I also considered (based on something I read on Box2D) setting the update timestep to zero.  I have not investigated this route fully, yet; however, it does seem that updating positions/rotations and other properties would not be reflected in the world, because those are affected by the time step, as well.

Since I'm kind of wandering in the dark here, I was hoping someone might be able to provide some insight on how they think this could best be accomplished.  Thanks for any help.

Joseph G.

May 27, 2011 at 3:08 AM
Edited May 27, 2011 at 3:14 AM

Just an update; I'm playing with the idea of implementing a mouse joint that is more like a weld joint than a distance joint, in that the relative inertia of the selected body becomes static.  When the mouse button is released, the previously selected body will call ResetDynamics to prevent additional motion when the user has released the button.  I don't know if this will work, mostly because, as weld joints have two bodies, I would need to construct a arbitrary body for the cursor, which seems likely to cause problems.

Jun 1, 2011 at 1:42 AM

Anyone with any thoughts?  Any input would be most appreciated; as this has proven to be a most difficult task.

 

Thanks

Developer
Jun 1, 2011 at 2:13 AM

To move objects you manually set their velocities. There are a few other threads where I answer this question. I even provided an example once. But here are the basic steps:

  1. Transform the mouse position into Farseer world space.
  2. Find the distance from the grab point to the current mouse position (in Farseer world space). This is called the World Delta Position.
  3. Now divide the World Delta Position by the time step duration and voila you have the linear velocity needed to move the item.

This also can work with rotation but that requires quite a bit more math to find all the right angles.

NOTE: I pulled all this directly from my head so I could be forgetting something. But this should get you on the right path.

Jun 1, 2011 at 7:49 PM
Edited Jun 5, 2011 at 11:22 PM

Thanks, Matt.

This seems like a somewhat cumbersome method to manipulate the scene, using the physics API, rather than explicitly setting the class properties of sprites based on mouse position. Perhaps this is what you're getting at?

Joseph

Developer
Jun 1, 2011 at 9:32 PM

@Bludo: To keep collisions functioning properly you have to move your bodies by changing there velocity. We (the engine developers) could add this to the list of features if you post a detailed suggestion to the Issue Tracker. Make sure you set the type as Feature. If I get some time I might be able to whip up a sample.

Jun 2, 2011 at 10:54 PM
Edited Jun 5, 2011 at 11:22 PM

Okay, now I see.

I don't know if it's worth putting in a full-on feature request for this. However, being able to pause dynamics to manipulate bodies could provide for some very interesting (and testbed-friendly) physics testing.

I'm guessing that I would probably be able to implement this in a fork independently sooner than it would get through the request pipeline (but maybe not).

I'd be open to suggestions for a point of entry. I assume this would take some pretty heavy refactoring of the World class for starters. As well as some reworking of most of the dynamics namespace.

Developer
Jun 3, 2011 at 2:18 AM

There would be no refactoring at all. Just a few methods added to allow users to simply "set" the position/rotation of a body and have that translated into linear/angular velocities for them. All the mouse transforming code would have to stay as part of the sample.

Jul 8, 2011 at 3:16 AM
Edited Jul 8, 2011 at 3:30 AM

So I've implemented a method as you recommended where bodies can be moved by setting the linear velocity manually (I actually found an old demo you made and updated it to work with the latest version of Farseer to see what you were getting at).

I do have a question, however, that may be better off in a new post.  I'm setting the body's linear velocity to move to the cursor position.  But the body isn't always able to keep up with the speed of the cursor.  The velocity appears to have a ceiling if the mouse is moved too quickly.  I dug around the forums, and it appears setting the MaxTranslation value in Settings will allow bodies to be moved at higher velocities.

So my question is: why is the value a constant?  I'm reluctant to modify any hard-coded constraints within the Farseer library, itself.  I assume there is a reason for this value to go unmodified, so are there any caveats we should be aware of before altering the settings values, particularly MaxTranslation?