Small change to OgreODE simplified character walk

xyzzy

18-02-2007 05:47:59

I was implementing the suggestion for character walk on the ogre wiki (using the capsule with damping that rests on the sphere). I was having some trouble with it, and discovered that a much simpler implementation can be done by making a small change to ogreode. I have removed the capsule and have added a new flag to the body class. The new flag will indicate whether the body should update the rotation value for the parent object. By decoupling this, it isn't necessary to deal with the rotation in the game code. Essentially, the rotation of the sphere does not impact the parent node, but it's position in the world does. The sphere can roll about and drag the character entity with it without trying to spin the character entity around.

rewb0rn

18-02-2007 12:05:01

I guess you still have to reset the character every frame to ensure that he does not fall onto his side? Sounds like it saves some computation, maybe you should post your code here.

xyzzy

19-02-2007 00:10:48

Character does not need to be reset because the ogrebody object isn't rotating the parent scene node. Effectively the change prevents the ogrebody from updating the parent scene node with it's rotation. the whole point of having the capsule and setting the angular damping and then resetting the character orientation is to deal with the fact that the ogreode body is changing the parent scene node rotation, so why just not update the parent scene node's rotation?

Here is a diff:

Index: OgreOdeBody.cpp
===================================================================
--- OgreOdeBody.cpp (revision 65)
+++ OgreOdeBody.cpp (revision 64)
@@ -114,8 +114,6 @@
// used when getting physical out of Movables.
this->setUserObject (this);

- _modify_parent_orientation = true;
-
}
//-----------------------------------------------------------------------
void Body::_historyResize(const size_t size)
@@ -170,12 +168,6 @@

}

-void Body::setModifyParentOrientation(bool bModify)
-{
- _modify_parent_orientation = bModify;
-}
-
-
//-----------------------------------------------------------------------
void Body::setPosition(const Ogre::Vector3& position)
{
@@ -207,7 +199,7 @@
_state_history->_orientation = orientation;
}

- if (mParentNode && _modify_parent_orientation)
+ if (mParentNode)
mParentNode->setOrientation(orientation);
}

@@ -856,4 +848,4 @@

}
return collided;
-}
+}
\ No newline at end of file

xyzzy

19-02-2007 00:17:46

I just realised the diff is backwards. the - is the new stuff and the + is the old stuff

tuan kuranes

24-02-2007 11:34:54

Is this a bug fix to be integrated or just a hack ?
If it's a fix, does it break something (debug visualisation for instance) ?

xyzzy

25-02-2007 17:11:32

Debug visualization works properly with the change.

At this point it looks to me like a feature enhancement. I have not found any negative implications in my own usage of OgreOde. The "fix" simply makes optional the artificial constraint that OgreOde has requireing that physics geometry control the rotation values of it's parent scene node.

In our project, this has simplified the character walk implementation greatly. I now have the character surrounded by an OgreOde sphere (like a hampster in a ball). Angular momentum is applied along the axis according to the orientation of the parent scene node.

If you compare the code examples below to the character walk tutorial, you will see that it is significantly more simple. No joints are required, no seperate space is required, it is not necessary to compensate in the game code for the rotational force that was imposed.

The character is placed in the hampster ball as such:

OgreOde::Body* pFeetBody = new OgreOde::Body(m_pODEWorld, szbuf);
pFeetBody->setMass(OgreOde::SphereMass(250,radius));
pFeetBody->setDamping( 0.0, 500.0);
OgreOde::SphereGeometry* pFeetGeom = new OgreOde::SphereGeometry(radius, m_pODEWorld, m_pODEWorld->getDefaultSpace());

pFeetBody->setModifyParentOrientation(false);
pFeetGeom->setOrientation(Ogre::Quaternion(Ogre::Degree(-90),Ogre::Vector3::UNIT_X));
pFeetGeom->setBody(pFeetBody);

pEntitySceneNode->translate(-center / pSceneNode->getScale());

pSceneNode->attachObject(pFeetBody);


The angular momentum is applied to the hampster ball as such:

if (pbKeys[NetPlayer::LEFT])
{
bKey = TRUE;
pFeet->wake();

vecVelocity = pFeet->getAngularVelocity() + (qNode * Ogre::Vector3(0,0,PLAYER_MOVEMENT));

pFeet->setAngularVelocity(vecVelocity);

}

if (pbKeys[NetPlayer::RIGHT])
{
bKey = TRUE;
pFeet->wake();
vecVelocity = pFeet->getAngularVelocity() + (qNode * Ogre::Vector3(0,0,-PLAYER_MOVEMENT));
pFeet->setAngularVelocity(vecVelocity);

}

if (pbKeys[NetPlayer::UP] )
{
bKey = TRUE;
pFeet->wake();
vecVelocity = pFeet->getAngularVelocity() + (qNode * Ogre::Vector3(-PLAYER_MOVEMENT,0,0));

pFeet->setAngularVelocity(vecVelocity);
}

if (pbKeys[NetPlayer::DOWN] )
{
bKey = TRUE;
pFeet->wake();
vecVelocity = pFeet->getAngularVelocity() + (qNode * Ogre::Vector3(PLAYER_MOVEMENT,0,0));

pFeet->setAngularVelocity(vecVelocity);
}

tuan kuranes

28-02-2007 14:14:39

It's now in CVS.

A good thing would be to add a simple scenes to demo/show the character walk implementation. Patch welcome ;)

tone

05-03-2007 16:47:30

I have a fundamental question regarding FPS walking around scenes of any complexity. Is it really desirable to solve this in the manner the tutorial shows, of using a rolling ball and a capsule to represent the body?

I had presumed that using little boxes to represent the feet would be the purest, and more friendly method from the computational perspective. That is, previous propjects I had used a box to represent the footfall, and the logic of how it would move forward and then down was the means by which I found stairs leading up or down, and simple normal calculations told me if a slope I was trying to move up was just too steep. I had another box reaching from the belt up to the top of the head which was used to realize when the character might hit his head and to test whether ducking would then permit him to continue forward motion.

Is the tutorial approach taken simply because it emphasizes neat ODE features, or because it is really the way one should approach this problem? I just have this pang of doubt when I attempt to consider the rolling of a ball up or down a set of stairs as the "right way" to model this.

Thanks in advance for any context you can provide.

tone

rewb0rn

05-03-2007 19:39:35

Well as you have only two very simple objects that represent the character (sphere and capsule) there is absolutely not problem with the fps, in fact I think your solution will be a bit more complex. Also you dont need an extra object for the head, therefor you have the capsule that includes the whole body of the player. the only thing i dont like with this concept is that you can not control the player while he is in the air, you have to decide if thats a problem for you, if so you can of couse set an additional force to make the player move while flying.

I use this player model in my game and there is no problem with the fps. you will have to add more geometry objects to detect additional contact information though. in my case (a mortal kombat like game) its about the collision of hands and feet.
All together this will be still less complex than a ragdoll, so it should still be easy to compute in realtime.

xyzzy

07-03-2007 05:45:18

In my case, I have eliminated the capsule all together and simply have a ball that rolls around the terrain with the player inside of it like a hampster.

I have tweaked some parameters to add a little more friction to the thing so that the guy isn't rolling around like a marble.

For my purposes, the hampster ball model is sufficient. It's also nice because the sphere is useful for collision detection too. Missiles can have a certain mass and when they hit the sphere cause the player to be knocked back

skala

11-03-2007 19:07:30

could we see a complete working example of the hamster ball code?

i've updated to the latest ogreode from cvs and also to eihort rc2 with many pains to see that the new setting setModifyParentOrientation is having no effect in my code - the model still gets oriented to the sphere. I'm probably doing something wrong..

i've tried the code posted here but still no effect.. :D

cheesus

30-03-2007 17:57:32

i also tried this and it also had no effect. when i debugged ogreode i found this function to be responsible for updating the parent node:
inline void Body::updateParentNode() (line 317 in OgreOdeBody.h)
so i added
if (_modify_parent_orientation)
right befor the call to
mParentNode->setOrientation(_draw_state._orientation);

now it works fine...