walking character tut [solved]

rewb0rn

17-12-2006 22:41:56

Hi, I am currently trying out the walking character tut, but i have problems to create the capsule, its not positioned correctly allthough i dont see any mistake in my code. Ive made a screenshot:

http://img160.imageshack.us/img160/1653 ... ed2nv2.jpg

Maybe this sounds familiar to anyone?

Just in case of interest, here is my code:

double Radius;
Ogre::Vector3 Size;
OgreOde::HingeJoint* Joint;

OgreOde::Body* BodyFeet;
OgreOde::SphereGeometry* GeoFeet;
OgreOde::TransformGeometry* TransFeet;

OgreOde::Body* BodyTorso;
OgreOde::CapsuleGeometry* GeoTorso;
OgreOde::TransformGeometry* TransTorso;


void Player::InitFeetRadius(void)
{
AxisAlignedBox Box = ModelNode->getAttachedObject(PLAYER_NAME)->getBoundingBox();
Ogre::Vector3 Min = Box.getMinimum() * PositionNode->getScale();
Ogre::Vector3 Max = Box.getMaximum()* PositionNode->getScale();
Ogre::Vector3 Center = Box.getCenter() * PositionNode->getScale();

Size.x = fabs(Max.x - Min.x);
Size.y = fabs(Max.y - Min.y);
Size.z = fabs(Max.z - Min.z);
Radius = (Size.x > Size.z) ? Size.z / 2.0 : Size.x / 2.0;
}

void Player::InitODE(OgreOde::Space* Space)
{
InitFeetRadius();

BodyFeet = new OgreOde::Body();
BodyFeet->setMass(OgreOde::SphereMass(70 *2.5, Radius));
GeoFeet = new OgreOde::SphereGeometry(Radius);
TransFeet = new OgreOde::TransformGeometry(Space);
ModelNode->translate(Vector3(0, -Radius/PositionNode->getScale().y, 0));
TransFeet->setBody(BodyFeet);
TransFeet->setEncapsulatedGeometry(GeoFeet);
PositionNode->attachObject(BodyFeet);
GeoFeet->setDebug(true);

BodyTorso = new OgreOde::Body();
BodyTorso->setMass(OgreOde::CapsuleMass(70.0 * 2.5, Radius, Vector3::UNIT_Y, Radius));
BodyTorso->setAffectedByGravity(false);
BodyTorso->setDamping(0.0, 50000.0);
TransTorso = new OgreOde::TransformGeometry(Space);
GeoTorso = new OgreOde::CapsuleGeometry(Radius, Size.y - 4 * Radius, Space);
GeoTorso->setPosition(Ogre::Vector3(0.0, Size.y - ((Size.y - 4 * Radius) / 2 + 2 * Radius), 0.0)); //can't find a good way to explain this
GeoTorso->setOrientation(Ogre::Quaternion(Degree(90.0), Vector3::UNIT_X));
TransTorso->setBody(BodyTorso);
TransTorso->setEncapsulatedGeometry(GeoTorso);
PositionNode->attachObject(BodyTorso);
GeoTorso->setDebug(true);

Joint = new OgreOde::HingeJoint();
Joint->attach(BodyTorso, BodyFeet);
Joint->setAxis(Ogre::Vector3::UNIT_X);

rewb0rn

06-01-2007 00:36:37

Still doesnt work yet, though I didnt spend much time on it in the last few days :)

It seems that the line
TransTorso->setEncapsulatedGeometry(GeoTorso);

changes the position of the capsule, because if I comment it out, it looks like this:


also, if I dont comment it out, GeoTorso->setPosition and GeoTorso->setOrientation dont seem do have an effect anymore.

Anyways, in both cases (with or without the setEncapsulatedGeometry) the character doesnt move when the suggested "move forward" code is executed, but it rotates around itself.

Has anyone made this tutorial to work correctly??? Id be glad to have the complete project code.

skala

06-01-2007 18:15:01

i'm also trying to put this tutorial together with different success

i do get the right position of the ninja on the screen with 2 node principle (and with one node just as it's on the first picture in the tutorial).

i've more or less pasted the code from the "tutorial" to the simplescenes_crash sample, which seems to have some similar code (also made all vars defined in the class to get them later for rotation).

my problem is the error "GeomTransform encapsulated object must not be in a space (..\..\ode\src\collision_transform.cpp:133)" when trying to rotate the node. It seems to start rotating (wrongly!) for a few msecs but then the error drops in..

any ideas?

rewb0rn

06-01-2007 20:24:17

got something similiar when not set the internal collisions of the space to false... pls report if it works because id be glad to take a look at your code.

skala

07-01-2007 09:29:38

heh.. i was using the space created for apache model so that caused the problems. Well i can rotate the ninja with addTorque but when i set the torque once the ninja rotates as crazy and then disappears :)

ok below is the code to position the ninja beside the apache helicopter in the F5 crash demo of simplescenes ode tutorial.

first code goes at the end of the constructor in SimpleScenes_Crash.h


/*Entity* ninja = _mgr->createEntity("ninja","ninja.mesh");
SceneNode* ninjaNode = _mgr->getRootSceneNode()->createChildSceneNode("ninja");
SceneNode* modelNode = ninjaNode->createChildSceneNode("ninja_model");*/
ninja = _mgr->createEntity("ninja","ninja.mesh");
ninjaNode = _mgr->getRootSceneNode()->createChildSceneNode("ninja");
modelNode = ninjaNode->createChildSceneNode("ninja_model");
modelNode->attachObject(ninja);
ninjaNode->setScale(0.01,0.01,0.01);
ninjaNode->setPosition(4,0,0);

AxisAlignedBox aab = modelNode->getAttachedObject("ninja")->getBoundingBox();
Ogre::Vector3 min = aab.getMinimum()*ninjaNode->getScale();
Ogre::Vector3 max = aab.getMaximum()*ninjaNode->getScale();
Ogre::Vector3 center = aab.getCenter()*ninjaNode->getScale();
Ogre::Vector3 size(fabs(max.x-min.x),fabs(max.y-min.y),fabs(max.z-min.z));
float radius = (size.x>size.z)?size.z/2.0f:size.x/2.0f;

//OgreOde::SimpleSpace* dollSpace = new OgreOde::SimpleSpace(_world->getDefaultSpace());
dollSpace = new OgreOde::SimpleSpace(_space);
dollSpace->setInternalCollisions(false);

//OgreOde::Body* dollFeetBody = new OgreOde::Body("feet");
dollFeetBody = new OgreOde::Body("feet");
dollFeetBody->setMass(OgreOde::SphereMass(70*2.5,radius));
OgreOde::SphereGeometry* feetGeom = new OgreOde::SphereGeometry(radius);
OgreOde::TransformGeometry* feetTrans = new OgreOde::TransformGeometry(dollSpace);
modelNode->translate(Vector3(0,-radius/ninjaNode->getScale().y,0));
//modelNode->translate( Ogre::Vector3( 0, -min.y / ninjaNode->getScale().y, 0 ) ); // The bounding box must have its bottom at the height 0 //http://www.ogre3d.org/wiki/index.php/Talk:OgreOde_Walking_Character
feetTrans->setBody(dollFeetBody);
feetTrans->setEncapsulatedGeometry(feetGeom);
ninjaNode->attachObject(dollFeetBody);

//OgreOde::Body* dollTorsoBody = new OgreOde::Body("torso");
dollTorsoBody = new OgreOde::Body("torso");
dollTorsoBody->setMass(OgreOde::CapsuleMass(70*2.5,radius,Vector3::UNIT_Y,radius));
dollTorsoBody->setAffectedByGravity(false);
dollTorsoBody->setDamping(0,50000);
OgreOde::TransformGeometry* torsoTrans = new OgreOde::TransformGeometry(dollSpace);
OgreOde::CapsuleGeometry* torsoGeom = new OgreOde::CapsuleGeometry(radius,size.y-4*radius,dollSpace);
//torsoGeom->setPosition(Ogre::Vector3(0,size.y-((size.y-4*radius)/2+2*radius),0)); //can't find a good way to explain this
torsoGeom->setPosition(Ogre::Vector3(0,size.y/2,0)); //http://www.ogre3d.org/wiki/index.php/Talk:OgreOde_Walking_Character
torsoGeom->setOrientation(Quaternion(Degree(90),Vector3::UNIT_X));
torsoTrans->setBody(dollTorsoBody);
torsoTrans->setEncapsulatedGeometry(torsoGeom);
ninjaNode->attachObject(dollTorsoBody);

//OgreOde::HingeJoint* joint = new OgreOde::HingeJoint();
joint = new OgreOde::HingeJoint();
joint->attach(dollTorsoBody,dollFeetBody);
joint->setAxis(Ogre::Vector3::UNIT_X); //set the rotation axis

//_geoms.push_back(feetGeom);
//_bodies.push_back(dollFeetBody);
//_geoms.push_back(torsoGeom);
//_bodies.push_back(dollTorsoBody);
//_joints.push_back(joint);//*/


this are the protected vars


OgreOde::SimpleSpace* dollSpace;
Entity *ninja;
OgreOde::Body *dollTorsoBody;
OgreOde::Body *dollFeetBody;
SceneNode *ninjaNode, *modelNode;
OgreOde::HingeJoint *joint;


i won't post the rotate/move code as it's all a mess :D

skala

07-01-2007 18:35:45

yeah! i finally made it work..

First i had to remove setDamping line from the setup code. This caused the ninja to rotate and disappear.
Second change was in the torsoGeom creation where i removed the third parameter dollSpace from the function call. This was the cause for the error when the model colided with some other object.
Third change was the added dollTorsoBody->setAngularVelocity to zeros. Before it had some problems with flickering to stay upright.

The control code is below. First part goes to frameEnded (in the crash demo as before):

_ninja_rotate = 0;
if (input->isKeyDown(KC_T))
_ninja_rotate += -1;
if (input->isKeyDown(KC_U))
_ninja_rotate += 1;

_ninja_thrust = 0;
if (input->isKeyDown(KC_6))
_ninja_thrust += -1;
if (input->isKeyDown(KC_Y))
_ninja_thrust += 1;


second part goes to addForcesAndTorques:

if (_ninja_rotate == 0)
{
dollFeetBody->wake();
dollFeetBody->setAngularVelocity(Vector3(dollFeetBody->getAngularVelocity().x,0,0));
}
else
{
dollFeetBody->wake();

Quaternion q1 = dollTorsoBody->getOrientation();
Quaternion q2(Degree(-4*_ninja_rotate),Ogre::Vector3::UNIT_Y);
dollTorsoBody->setOrientation(q1*q2);
}//*/

if (_ninja_thrust == 0)
{
dollFeetBody->wake();
dollFeetBody->setLinearVelocity(Vector3(0,dollFeetBody->getLinearVelocity().y,0));
dollFeetBody->setAngularVelocity(Vector3(0,dollFeetBody->getAngularVelocity().y,0));
}
else
{
dollFeetBody->wake();
Quaternion q = dollTorsoBody->getOrientation();
dollFeetBody->setAngularVelocity(q*Ogre::Vector3(10*_ninja_thrust*cos(1.0),dollFeetBody->getAngularVelocity().y,0));
}

Quaternion q = dollTorsoBody->getOrientation();
Vector3 x = q.xAxis();
Vector3 y = q.yAxis();
Vector3 z = q.zAxis();
dollTorsoBody->wake();
dollTorsoBody->setOrientation(Quaternion(x,Vector3::UNIT_Y,z));
dollTorsoBody->setAngularVelocity(Vector3(0,0,0));


and of course declare the _ninja_rotate and _ninja_thrust as real in the protected section and initialize them to 0.

there are a couple more changes to the original tutorial so you can move and rotate at the same time.

i'll try to rewrite it as an addon to intermediate tutorial 3 tomorow

rewb0rn

08-01-2007 21:09:18

I really want to hit myself right now, Ive set the Geometry visible not the Transform Geometry, damn it lol

I took your walking functions now (seems like those in the tutorial are terribly wrong, and the cos(1) indicates it has never been tested...) but the character doesnt walk and if I set gravity, the character falls through the plane and the mapmodel that I have in my program. I think this has to do something with the Space (setInternalCollision(false) means there are no collisions between all the object in this space, right?), so how can I make the char collide with the environment? At the moment the character doesnt walk when I press the key, guess this is because there is no contact to a floor...

SuperMegaMau

11-01-2007 18:01:58

hi,

I found this thread just now, and as I am the one that made the tutorial, I'm going to look at the problems you described, but the code I posted works great for me. It had some flaws, but do the job.

That dumping function I had to use it because the character slide down the hills. About the use of the set velocity or rotate of the feet sphere, if it doesn't work, probably the characted is to big, and if the ode objects are too big, they do some flexibility problem, like bounce between them on the hinge joint.

rewb0rn

12-01-2007 00:46:41

Besides the problems mentioned before, I think it really would help in that tutorial if you post the complete project code in an extra article, like this has been done in the ogre tut section. Helps much to learn.

rewb0rn

15-01-2007 20:12:12

I made it work now with working and jumping. btw kala I see a problem in your walking method, if the user does not press any key, he will suddenly stop, thats bad if you want the player to be able to jump. Also the player surfs on the surface if he walks and changes direction.

I dont like this player physics so much now that I see how it is, because its not possible to control the player while he is in the air, and besides the physics make the player to jump or fly slightly when colliding with objects. If I find a good solution, I will post it here.