moving objects with the mouse.

cal

29-07-2009 08:57:14

Hi guys, wondering if you's could give me a quick touch of help, Im not a physics man, so apologies if Im missing something blatently obvious here.

OVERVIEW:

I have a scene, viewed from above by a camera looking straight down along the normal of a plane, that plane is the "floor" of my scene. Scattered on the floor are a number of boxes (width and length around 400, height considerably shorter, think of them like square hocky pucks). Im trying to interact with these objects with the mouse, by casting down a physical object from above the scene which represents the "mouse" in world space. This object is a long cylinder taller than any objects in the scene, locked from rotating with an upvector. I initially poisition this object above the height of the boxes, and what I want is for it to fall (due to gravity) onto the anything below it, and then have that object be moved by the "mouse".

This piece of code is most likely irrelevant, but for background its the setup of the mouse objects.


// this is all a bit hack and slash at the minute, will be refactoring once I get my head round everything
Ogre::Quaternion rot = Ogre::Quaternion(Ogre::Radian(Ogre::Math::PI/2), Ogre::Vector3::UNIT_Z);
OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::Cylinder(world, 25, 2000, rot);
m_body = new OgreNewt::Body(world, col);
m_body->setContinuousCollisionMode(1);
delete col;

Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcCylinderSolid( 1500000.0, 25, 2000);
m_body->setMassMatrix( 1500000.0, inertia );
m_body->setAutoFreeze(false);
m_body->setCenterOfMass(Ogre::Vector3(0,-300,0));
m_body->setLinearDamping(0);
m_body->setAngularDamping(Ogre::Vector3(0,0,0));
m_body->attachToNode(m_sceneNode);
m_upVector = new OgreNewt::BasicJoints::UpVector(m_world, m_body, Ogre::Vector3(Ogre::Vector3::UNIT_Y) );
m_body->setUserData(this);
//m_body->setStandardForceCallback();
m_body->setCustomForceAndTorqueCallback<FeedbackObject>(&FeedbackObject::movement, this);
m_body->setPositionOrientation(Ogre::Vector3(m_lastMouse.x, 1200, m_lastMouse.z), Ogre::Quaternion::IDENTITY);


PROBLEM:

My problem is, I currently dont know how to move the "mouse" object with forces, and am instead setting its velocity, which I have working fine and the mouse object follows the mouse as it should. This however means I cant add a force for gravity, since the two dont play well. I know F=MA, and with constant velocity, A = 0, so there's no net force. Basically, I want to either a) calculate the force to take an object from one position to another in the time it took the mouse to move there, or b) add gravity as a velocity, but this pushes my objects through the floor when the mouse is on top of them.

Actually there's a c) too, which is if anyone tells me theres a better way to do this whole thing. The mouse objects interact fine when they hit the boxes from the sides, but i specifically need them to move objects from on top too (like if I were setting the velocity of the box, but need it to rotate naturally too, say it was moved from one side it would rotate slightly as its moved)

here's the code for my force feedback


void FeedbackObject::movement(OgreNewt::Body *body)
{
Ogre::Vector3 pos;
Ogre::Quaternion rot;
m_body->getPositionOrientation(pos, rot);

// time is updated each frame so I can measure how long has passed since last movement
if(m_time > 0)
{
// the distance I need to move the "mouse" object to place it under the current mouse pos
Ogre::Vector3 dist(m_currentMouse.x-pos.x, 0, m_currentMouse.z-pos.z);
// the velocity to move the mouse with
Ogre::Vector3 vel = dist/m_time;
m_body->setVelocity(Ogre::Vector3(vel.x, 0, vel.z));

// this sets the current mouse position, this makes it so the next frame if the mouse has stopped, vel will be 0
// there's a check done on this in another piece of code, which doesnt affect anything else.
set_current_mouse(m_currentMouse);
m_time = 0;
}

// this code doesnt work, its supposed to add gravity
Ogre::Real mass;
Ogre::Vector3 inertia;
m_body->getMassMatrix(mass, inertia);
Ogre::Vector3 force(0,-9.8,0);
force *= mass;

m_body->addForce( force );
}

deadvirus

29-07-2009 17:10:49

See if this helps: http://www.ogre3d.org/wiki/index.php/OgreNewt_Picking

cal

29-07-2009 20:10:09

Thanks for the link deadvirus, unfortunately that code is from the Raycasting demo, and applies a spring force to the picked object, where as Im wanting the object to move with the mouse in the exact position, rather than bouncing around it. At the minute I do this by setting its velocity, based on the distance it has to travel, and the time since the last update. What I need though is the force needed to move the object from its original position, to the new location.

I thought I could do it with the suvats, and F=MA, but clearly Im missing something (im not a physics man), I think Im just not implementing the equation correctly.

Imagine its the first movement of the mouse, the distance travelled on the 2d "floor" plane is 100, and the mass of the object is 20. I want to calculate the force needed to move the object from 0 to 100. F = MA, so I need the acceleration:

v^2 = u^2 + 2as , so

a = (v^2 - u^2) / 2s

Where a = accel, v = final velocity, u = starting velocity, s=displacement.

This is giving me erratic behaviour though, well, a pendulum effect around the desired position, which gets more verocious the further the mouse is moved.

deadvirus

30-07-2009 01:03:10

Oh I see... sorry...
But, if you want it to move exactly like the mouse, why do you need it to have gravity?

cal

30-07-2009 01:39:34

Because I want it to interact with objects its below, through friction which needs a force going down from the "mouse" object onto the object below, ie, gravity. The idea is the mouse becomes a physical object in the scene, that interacts like any other physical object naturally.

I've created a similar effect by attaching a joint to the object below, but thats really now what I want.

deadvirus

30-07-2009 12:21:29

You're right, the F = m*a should work...
What do you mean by pendulum efect? The object moves in circles? Or just in one line?

cal

30-07-2009 12:35:07

The pendulum effect is in a straight line (providing I've moved the mouse in a straight line). I've figured out its because Im not applying a counter force to the object to stop it when it reaches its destination. So the code Im using is always creating force until it goes past the destination point, at which time it thinks the destination is in the opposite direction and does the same again. Meaning the object pendulums around the destination (I should have said oscillating).

I think I now just need to apply this counter force to stop it, and it should work as intended. Will let you know.