Moving an object with force

batnom

20-10-2008 08:06:41

Basically what I need is how to make certain objects (by going off names?) move around continuously? Where do I need to put the code and how do I access the body so I can apply force?



Now the long winded explanation of what I've tried... I have an object in the world made with the following function:

makeObject("ball1", 1, "ellipsoid.mesh", Ogre::Vector3(10.0,0.0,10.0));

void OgreNewtonApplication::makeObject(Ogre::String name, Ogre::Real mass, Ogre::String model, Ogre::Vector3 thisPos)
{
Entity* ent;
SceneNode* node;

name = "Body "+Ogre::StringConverter::toString( objcount++ );

ent = mSceneMgr->createEntity( name, model );
node = mSceneMgr->getRootSceneNode()->createChildSceneNode( name );
node->attachObject( ent );

ent->setMaterialName( "Simple/dirt01" );
ent->setNormaliseNormals(true);

OgreNewt::Collision* col = new OgreNewt::CollisionPrimitives::Ellipsoid( m_World, Ogre::Vector3(1,1,1) );
OgreNewt::Body* body = new OgreNewt::Body( m_World, col );
delete col;

// something new: moment of inertia for the body. this describes how much the body "resists"
// rotation on each axis. realistic values here make for MUCH more realistic results. luckily
// OgreNewt has some helper functions for calculating these values for many primitive shapes!
Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcSphereSolid( mass, 1.0 );
body->setMassMatrix( mass, inertia );

// attach to scene node
body->attachToNode( node );
// this is a standard callback that simply add a gravitational force (-9.8*mass) to the body.
body->setStandardForceCallback();
body->setPositionOrientation( thisPos, Ogre::Quaternion::IDENTITY );
//mSceneNode->setOrientation(camorient);
//body->setVelocity( (dir * 50.0) );
}


I need the object to move from one point to another, it can be hardcoded as I don't have time to try implement lua/pyogre..

Looking around the forums the only way I can seem to do this is with the body->addForce function.. but I can't seem to find anyway to get the bodies I made in CreateScene in FrameStarted (which runs every frame and where I believe it will need to go).. the only way I can see it happening is adding a custom callback..

add this to the CreateObject function
body->setCustomForceAndTorqueCallback(boost::bind(&OgreNewtonApplication::myCallBackFunction,this,_1));

void OgreNewtonApplication::myCallBackFunction(OgreNewt::Body* body)
{
body->addForce(Ogre::Vector3(0, -1, 0));
}


The force is temporary but it seems to work.. but the trouble is:
1) I need objects to do different things
2) This seems to just work once.. i need it continuous
3) This seems like a very round about way of doing it.. surely there must be an easier way??


So basically what I'm asking is how can I make certain objects (by going off names?) move around continuously? Where do I need to put the code and how do I access the body so I can apply force?

nanolucas

20-10-2008 18:27:55

Is it possible to set the velocity of the object directly?

micken

20-10-2008 18:49:12

It is possible to set the velocity of a body directly but it isn't a good idea because it will yield unpredictable results. It is always easier and more efficient to use addForce from within a CustomForceAndTorqueCallback and let Newton do what it was designed to do. Also don't forget about addImpulse as well as it is very useful for initiating motion.


The idea of moving an object continually by physical means seems to me like it would take way too much time to implement without the possibility of errors. You will need to constrain the motion. This is done with Joints. I'm not sure specifically how you would do it but I'm sure if you looked into it you might find the solution you're looking for, or someone else on the forum can ellaborate. It also depends on exactly the kind of motion you are looking for.

If you just want it to move back and forth then you just need to apply a force each call of the CustomForceAndTorqueCallback and when it reaches a certain velocity change the direction of the force. If you want it to move in a circle, square, or follow a path then it gets a lot more complicated.

Either way you will definitely need to use addForce from inside your CustomForceAndTorqueCallback.

batnom

21-10-2008 08:11:50

Thanks for the reply :D

If you want it to move in a circle, square, or follow a path then it gets a lot more complicated.

That's what I'm wanting, essentially for it to go through a number of waypoints.

I have set up a number of CustomForceAndTorqueCallbacks so that when it reaches the target it drops all callbacks and sets one for the next waypoint. It's quite primitive and messy but it seems to be getting the job done. Is there a better way to do this?