[Solved] Help with Custom Callbacks

zass

10-09-2008 18:05:11

Hi,
I'm not usually one to post questions on forums, but I have searched everywhere and I'm sure I cant find an answer to my problem, although I'm sure there is some simple solution that I'm somehow missing.

I have created a character class which in theory creates and moves a character around the world. To do the movement the class has a forceCallback method which I assign to the character's body like so:
body->setCustomForceAndTorqueCallback<Character>(&Character::forceCallback, this);
I have also tried it this way (but it shouldn't make a difference):
body->setCustomForceAndTorqueCallback(boost::bind(&Character::forceCallback, this, _1));
In the forceCallback method I want to add the force mMovementForce (which is a character instance variable) to the body. mMovementForce is calculated elsewhere based on input. So my forceCallback method looks something like this:

void Character::forceCallback(OgreNewt::Body *bod)
{
Ogre::Real mass;
bod->getMassMatrix(mass, Ogre::Vector3());
bod->addForce(Ogre::Vector3::UNIT_Y * -98.1 * mass);

bod->addLocalForce(mMovementForce, Ogre::Vector3::ZERO);
mMovementForce = Ogre::Vector3::ZERO;
}


The problem is that mMovementForce doesnt have the right value, in fact it has very weird values like (1.07374e+008, 0, 2.10195e-044), however if I make the mMovementForce variable static and reference it like Character::mMovementForce then it works fine (but I need mMovementForce to not be static). So I'm thinking that the instanced mMovementForce isnt defined somehow for the forceCallback method and its just pulling some random undefined memory or something, but I cant for the life of me figure out why or how to fix it. I've been searching the forums for hours and I havent found a solution, although i've found other peoples code that does exactly this and apparently works, so I guess there must be some simple solution that I am missing.
Any help would be greatly appreciated.

micken

10-09-2008 20:56:08

Hi zass.

Can you explain in more depth why you need mMovementForce to be private? Is this value being changed constantly by another function of the class?

You might want to try this instead:


bod->addLocalForce(this->getMovementForce(), Ogre::Vector3::ZERO);
this->setMovementForce(Ogre::Vector3::ZERO);


using public functions to modify and access the data may solve this problem.

I think somehow even though you may not set it as such, your forceandtorquecallback is being treated like a static function which means it cannot access private data.

zass

11-09-2008 05:14:22

Hi, thanks for the reply. I don't particularly need mMovementForce to be private, I just need it too be a instance var. I had already tried making it a public var and it didnt change a thing. I tried using public functions to access/modify as you suggested it and still it made no difference.
I think you're right about my callback being treated as a static function, meaning it wont be able to access any variables/functions in the class instance. So how do I make the callback be treated like a class method not a static function?

micken

11-09-2008 14:58:50

I had a look at my code and figured out that I just stopped trying to use private member data. You might want to try another strategy:

Create a singleton class to hold your mMovementForce and access that from your callback.

Also check the places where you are setting mMovementForce. You could be trying to set it improperly somewhere else.

zass

11-09-2008 16:42:23

Yeah i've checked the setting of mMovementForce so many times :p and its always right even when I throw debug messages and stuff (other than from within the callback function obviously)
As for using a singleton, that works fine if there is only one character object, but if there is more than one then I'd need a singleton for each one.
I'd really like to get this working correctly, I assume it is supposed to work so that the callback can be a class method. Although in the mean time I can get by with a static var or a singleton I guess

micken

11-09-2008 23:58:08

Yeah i've checked the setting of mMovementForce so many times :p and its always right even when I throw debug messages and stuff (other than from within the callback function obviously)
As for using a singleton, that works fine if there is only one character object, but if there is more than one then I'd need a singleton for each one.
I'd really like to get this working correctly, I assume it is supposed to work so that the callback can be a class method. Although in the mean time I can get by with a static var or a singleton I guess


Well you won't really need a singleton for each class you would just need a data structure in your singleton to hold all the variables of that type (i.e. a std::map)

But there must be a way! Is there anyone out there who knows the answer to this?

zass

12-09-2008 12:42:04

Aha! I found the solution, everything works correctly and how it should now. I can access instance variables from the forceCallback. After much frustration I figured out it was all simply due to the fact that I had not allocated memory for the character class, which was dumb of me. All I needed to do to fix it was add 'new' to my declaration. i.e. change this line:
Character char1 = Character();
to this:
Character* char1 = new Character();
Thanks for your help micken, and I hope this helps with your project as well.

micken

12-09-2008 17:51:08

Ag! That was it! I knew I was looking in the wrong place > <

That's how I solved it when I came across it too.