Problem with custom forceCallback Function [Solved]

jtpsoft

24-08-2009 09:57:39

Hi^^
Here's my problem:
Why my program doesn't enter into my custom forceCallBack fuction)?

MainChar::MainChar(Ogre::SceneNode *Node,OgreNewt::World *World)
{
mWorld=World;
mNode=Node;
OgreNewt::Collision *col= new OgreNewt::CollisionPrimitives::ConvexHull(mWorld,mNode);
mBody = new OgreNewt::Body( mWorld, col );

mBody->attachToNode( mNode );
mBody->setPositionOrientation( mNode->getPosition(), mNode->getOrientation() );
mBody->setCustomForceAndTorqueCallback<MainChar>( &MainChar::forceCallback, this );
//DivanoBod->setMaterialGroupID(mMatDefault);
delete col;
}
void MainChar::forceCallback(OgreNewt::Body *Body)
{
Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcBoxSolid(500,Vector3(11,3,7));
mBody->setMassMatrix( 500.0, inertia );
Body->addLocalForce(Vector3(0,-910 * 80,0),Vector3::ZERO);
}

Am I call setCustomForceAndTorqueCallback in a wrong way?
Edit:
I've also tried this solution ,but with the same result..The standardForceCallback works,the overridden one don't.
mBody->setCustomForceAndTorqueCallback( boost::bind( &MainChar::forceCallback,this, _1 ) );


Regards in advance,
Jimmy

deadvirus

24-08-2009 12:58:30

You need to set that body's mass. If you don't set the mass, it's considered infinit and so it does not call any force callbacks.

jtpsoft

24-08-2009 13:16:09

mmm i guess i don't explain well my problem..
Anyway I partially solved in this way:
MainChar::MainChar(Ogre::SceneNode *Node,OgreNewt::World *World)
{
mWorld=World;
mNode=Node;
OgreNewt::Collision *col= new OgreNewt::CollisionPrimitives::ConvexHull(mWorld,mNode);
mBody = new OgreNewt::Body( mWorld, col );
Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcBoxSolid(500,Vector3(11,3,7));
mBody->setMassMatrix( 500.0, inertia );
mBody->attachToNode( mNode );
mBody->setPositionOrientation( mNode->getPosition(), mNode->getOrientation() );
[size=150]mBody->removeAutoactiveCallback();[/size]
mBody->setCustomForceAndTorqueCallback<MainChar>( &MainChar::forceCallback, this );
delete col;
}


In that way the program enter into my custom forcecallback..I never seen this line before,but it seems to work!!

Thx anyway of course^^

deadvirus

24-08-2009 14:24:11

mmm i guess i don't explain well my problem..
Anyway I partially solved in this way:
MainChar::MainChar(Ogre::SceneNode *Node,OgreNewt::World *World)
{
mWorld=World;
mNode=Node;
OgreNewt::Collision *col= new OgreNewt::CollisionPrimitives::ConvexHull(mWorld,mNode);
mBody = new OgreNewt::Body( mWorld, col );
Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcBoxSolid(500,Vector3(11,3,7));
mBody->setMassMatrix( 500.0, inertia );
mBody->attachToNode( mNode );
mBody->setPositionOrientation( mNode->getPosition(), mNode->getOrientation() );
[size=150]mBody->removeAutoactiveCallback();[/size]
mBody->setCustomForceAndTorqueCallback<MainChar>( &MainChar::forceCallback, this );
delete col;
}


In that way the program enter into my custom forcecallback..I never seen this line before,but it seems to work!!

Thx anyway of course^^


That's what I've said, you need to set that body's mass, when you create it (I have not seen that you were setting the mass in the force callback).
Because you were not setting the mass when you create the body, it would never call the force and torque callback.
By the way, I think there are some tutorials that explain that, on the wiki.

jtpsoft

25-08-2009 13:48:50

Here we are again..

After solving the previous problem(thx deadvirus!) I have a new, logical ,problem:
MainChar::MainChar(Ogre::SceneNode *Node,OgreNewt::World *World)
{
mKUP=mKDW=false;
mCharVel=160;
mCharVel2=60;
mWorld=World;
mNode=Node;
OgreNewt::Collision *col= new OgreNewt::CollisionPrimitives::ConvexHull(mWorld,Node);
mBody = new OgreNewt::Body( mWorld, col );
mBody->setAutoFreeze(0);
Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcCylinderSolid(50,10,50);
mBody->setMassMatrix( 500.0, inertia );
mBody->attachToNode( mNode );
OgreNewt::Joint* joint;
joint = new OgreNewt::BasicJoints::UpVector( mWorld, mBody, Vector3(Vector3::UNIT_Y));
mBody->setPositionOrientation( mNode->getPosition(), mNode->getOrientation() );
mBody->removeForceAndTorqueCallback();
mBody->setCustomForceAndTorqueCallback<MainChar>( &MainChar::forceCallback, this );
delete col;
}
void MainChar::forceCallback(OgreNewt::Body *Body)
{

Ogre::Real mass,movex,movez,rotateVal;
movex=movez=rotateVal=0;
Ogre::Vector3 inertia,pos;
Ogre::Quaternion rot;

if (mKUP)
{
movex =mCharVel;
}
else if (mKDW)
{
movex =-mCharVel2;
}
else
{

if(Body->getVelocity().x !=0)
{
movex=-Body->getVelocity().x*15;
}
else
movex=0;

}

if (mKRIGHT)
{
rotateVal =-1.8;
}
else if (mKLEFT)
{
rotateVal =1.8;
}
else
{
rotateVal=0;
}


Vector3 r = Vector3(0,rotateVal,0);
Body->setOmega(r);

Body->getMassMatrix(mass, inertia);
Ogre::Vector3 force(movex-Body->getVelocity().x, 0, movez);
force *= mass;
Body->getPositionOrientation(pos,rot);
force=rot*force;
Body->setForce(force);


}


With this code when I use the combination of up/down and right/left arrows the body "escape" from scene.How can I Fix this problem?My purpose is to move a character in a very simple way(i only need very simple collisions e contactcallbacks to create triggerzones)..

Thx again in advance.

deadvirus

25-08-2009 15:10:45

I don't understand what do you mean by escape... if you could show a video it'll be better...
There's some stuff that I think its not right on your code... try this:

void MainChar::forceCallback(OgreNewt::Body *Body)
{

Ogre::Real mass,movex,movez,rotateVal;
movex=movez=rotateVal=0;
Ogre::Vector3 inertia,pos;
Ogre::Quaternion rot;

if (mKUP)
{
movex =mCharVel;
}
else if (mKDW)
{
movex =-mCharVel2;
}
else
{

if(Body->getVelocity().x !=0)
{
movex=-Body->getVelocity().x*15;
}
else
movex=0;

}

if (mKRIGHT)
{
rotateVal =-1.8;
}
else if (mKLEFT)
{
rotateVal =1.8;
}
else
{
rotateVal=0;
}


Vector3 r = Vector3(0,rotateVal,0);
Body->setOmega(r);

Body->addLocalForce(force, Vector3(0,0,0));

}


Or something like that... I think you should not multiply by the mass, because that way you are applying a force that's neglecting the mass of the body, like gravity.

jtpsoft

26-08-2009 04:22:22

http://www.youtube.com/watch?v=VfL35hQi30c
Meaning of "Escape" :P

Code used:

Vector3 r = Vector3(0,rotateVal,0);
Body->setOmega(r);

Ogre::Vector3 force(movex-Body->getVelocity().x, 0, movez);
force *= 250;
/*Body->getPositionOrientation(pos,rot);
force=rot*force;
Body->setForce(force);*/

Body->addLocalForce(force, Vector3(0,0,0));


I've also used this code(with the same result):
Vector3 r = Vector3(0,rotateVal,0);
Body->setOmega(r);

Ogre::Vector3 force(movex-Body->getVelocity().x, 0, movez);
force *= 250;
Body->getPositionOrientation(pos,rot);
force=rot*force;
Body->setForce(force);

/*Body->addLocalForce(force, Vector3(0,0,0));*/

jtpsoft

26-08-2009 08:14:05

And finally the solution^^:
void MainChar::forceCallback(OgreNewt::Body *Body)
{

Ogre::Real mass,movex,movez,rotateVal;
movex=movez=rotateVal=0;
Ogre::Vector3 inertia,pos;
Ogre::Quaternion rot;

if (mKUP)
{
movex =mCharVel;
}
else if (mKDW)
{
movex =mCharVel2;
}
else
{
movex=0;
Body->setVelocity(Vector3::ZERO);

}

if (mKRIGHT)
{
rotateVal =-3.8;
Body->setVelocity(Vector3::ZERO);
}
else if (mKLEFT)
{
rotateVal =3.8;
Body->setVelocity(Vector3::ZERO);
}

else
{
rotateVal=0;
Body->setTorque(Vector3::ZERO);
}


Vector3 r = Vector3(0,rotateVal,0);
Body->setOmega(r);

Ogre::Vector3 force(movex-Body->getVelocity().x, 0, movez);
force *= 250;

Body->addLocalForce(force, Vector3(0,0,0));
}