This project has moved. For the latest updates, please go here.

Moving bodies to follow a mouse directly

Oct 15, 2009 at 4:01 PM

I'm using WPF, and have played with the SimpleSamples and enjoyed the spring attached to the mouse location used to manipulate objects with the mouse. Now I'd like to move them directly, and I'm attempting to do so by setting the object's Position whenever the mouse moves, and applying a force of the last delta when the mouse is released. This isn't working very well, I'm guessing because setting the position directly does not update the body's other properties, and so collisions cannot be calculated properly. 

What is the best way to accomplish this? I've thought of figuring the force to apply based on the mouse movement, so the object keeps up with the mouse, but I don't think that is feasible to track. Could I make a joint, with one end attached to the body and the other attached to a temporary body that tracks with the mouse? I'm not sure if that would have the same result as what I'm doing now, or if the body's properties would be set properly.

I'm sure there must be a nice way to do this. Thanks a lot for any help.

Oct 15, 2009 at 7:30 PM

Update:  I checked out FreeGoo, which rocks, and found the MouseSpring he created. It does basically exactly what I'm looking to do (apply a force to the Body to keep up with the mouse), but I can't seem to get it working correctly. Maybe I'm missing something, or maybe I just need to play with the constants?

Oct 15, 2009 at 10:04 PM

I have also been trying to figure out this.
At the moment I have just been trying to apply a force worked out by an algoritum to move the object... but it doesnt work that well.

If anyone knows how to do this let us know.
(And if you figure it out rhythm could you post how?)

Oct 16, 2009 at 1:07 PM

Object dragging is simply setting Body.Position to desired value. Example:


private void MouseMove(MouseState oldMouseState, MouseState newMouseState) { Vector2 Offset = new Vector2((newMouseState.X - oldMouseState.X), (newMouseState.Y - oldMouseState.Y)); if (Operation.Peek() == eOperationState.World) // Record mouse position when editing world geometry { Mouse = new Vector2(newMouseState.X, newMouseState.Y); Mouse = Vector2.Transform(Mouse, Global.Instance.Camera.Matrix); } if (Operation.Peek() == eOperationState.Translate) { if (newMouseState.LeftButton == ButtonState.Pressed) { if (bDragging) { if (Selector.Count != 0) { foreach (Entity Object in Selector) { // If static and selected if (Object.Body.IsStatic && Selector.State(Object)) Object.Position += Offset; } } } else Selector.DeselectAll(); if (!bDragging) // Moving mouse and not holding right mouse button SelectionRectangle = new RubberbandRectangle(0, 0, 0, 0); } } if (SelectionRectangle != null) { SelectionRectangle.Rect = new Rectangle(iXDown, iYDown, newMouseState.X - iXDown, newMouseState.Y - iYDown); global::Miner.Editor.Utilities.Normalize(ref SelectionRectangle.Rect); } }

Oct 16, 2009 at 1:31 PM

That code does not actually drag an object.
It simply moves it each frame to a new location. This means that nothing in the physics simulator can react to it and it just penatrates everything too.

We are trying to figure out how to move a object so that it follows a cursor 1 to 1 and also has fully working collision.
If you have any idea on how to do this that would be great.

(also if i have misunderstood your code then let me know but as far as i can see it just moves the position each frame.)

Genbox? Got any ideas you are good with math right... :)

Oct 16, 2009 at 2:50 PM

Dan, did you check out the MouseSpring from FreeGoo? It seems to be exactly what we are looking for, but I couldn't get it working correctly. FreeGoo is really cool in general, but unfortunately I was stumped by getting the MouseSpring working in my project (it works pretty nicely in FreeGoo). I'll play with it more when I have time, let me know if you have any luck.

Oct 16, 2009 at 4:19 PM

Yeah, it's generally a bad idea to set 'position' itselt.  It should only be done when the body is first created, and even then you need to be careful.  The mouse spring thingy is done simply with a FixedLinearSpring controller.  One point set to a body's 0,0 point, and the other set to some world coorinate (the spot where the mouse is pointing).  I'd imagine you should be able to simply apply force manually each frame as well.  Just make sure you take mass into account, and avoid using ApplyImpulse.