Walking Character tutorial (not moving)[solved]

shanefarris

24-02-2010 19:26:21

I am running through the tutorial, and when I try and move the character, the sphere (feet) stay in place even though the sphere rolls. The capsule moves as if it is falling back as the sphere rolls, so that's weird. Here is my code to initialize the physics:

// Getting AABB
AxisAlignedBox aab = mEntity->getBoundingBox();
reVector3Df min = aab.getMinimum() * m_PlayerNode->getScale();
reVector3Df max = aab.getMaximum() * m_PlayerNode->getScale();
reVector3Df center = aab.getCenter() * m_PlayerNode->getScale();
reVector3Df 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;

// Create a new space
OgreOde::SimpleSpace* dollSpace = new OgreOde::SimpleSpace(world, world->getDefaultSpace());
dollSpace->setInternalCollisions(false);

// create sphere
dollFeetBody = new OgreOde::Body(world, "feet");
dollFeetBody->setMass(OgreOde::SphereMass(70 * 2.5, radius));
OgreOde::SphereGeometry* feetGeom = new OgreOde::SphereGeometry(radius, world, 0);
OgreOde::TransformGeometry* feetTrans = new OgreOde::TransformGeometry(world, dollSpace);
modelNode->translate(reVector3Df(0,-radius / m_PlayerNode->getScale().y, 0));
feetTrans->setBody(dollFeetBody);
feetTrans->setEncapsulatedGeometry(feetGeom);
m_PlayerNode->attachObject(dollFeetBody);

// Create the Capsule (torso)
dollTorsoBody = new OgreOde::Body(world, "torso");
dollTorsoBody->setMass(OgreOde::CapsuleMass(70 * 2.5, radius, reVector3Df::UNIT_Y, radius));
dollTorsoBody->setAffectedByGravity(false);
dollTorsoBody->setDamping(0, 50000);
OgreOde::TransformGeometry* torsoTrans = new OgreOde::TransformGeometry(world, dollSpace);
OgreOde::CapsuleGeometry* torsoGeom = new OgreOde::CapsuleGeometry(
radius, size.y - 4 * radius, world, dollSpace);
torsoGeom->setPosition(reVector3Df(0, size.y - ((size.y - 4 * radius) / 2 + 2 * radius), 0));
torsoGeom->setOrientation(Quaternion(Degree(90), reVector3Df::UNIT_X));
torsoTrans->setBody(dollTorsoBody);
torsoTrans->setEncapsulatedGeometry(torsoGeom);
m_PlayerNode->attachObject(dollTorsoBody);

// Create the Joint
OgreOde::HingeJoint* joint = new OgreOde::HingeJoint(world);
joint->attach(dollTorsoBody, dollFeetBody);
joint->setAxis(reVector3Df::UNIT_X); //set the rotation axis



Here is the code I am using to just move the model (in this case the robot) forward:

if(Keyboard->isKeyDown(OIS::KC_W))
{
Quaternion q = dollTorsoBody->getOrientation();
dollFeetBody->wake();
dollFeetBody->setAngularVelocity(q * reVector3Df(10 * cos(1.0f), 0, 10 * sin(1.0f)));
}
else if(Keyboard->isKeyDown(OIS::KC_A))
{
Quaternion q1 = dollTorsoBody->getOrientation();
Quaternion q2(Degree(-4), reVector3Df::UNIT_Y);
dollTorsoBody->setOrientation(q1 * q2);
}
else
{
dollFeetBody->setAngularVelocity(reVector3Df(0, 0, 0));
dollFeetBody->setLinearVelocity(Vector3(0, dollFeetBody->getLinearVelocity().y, 0));
}

Quaternion q = dollTorsoBody->getOrientation();
Vector3 x = q.xAxis();
Vector3 y = q.yAxis();
Vector3 z = q.zAxis();

dollTorsoBody->wake();
dollTorsoBody->setOrientation(Quaternion(x, reVector3Df::UNIT_Y, z));


So again, the sphere rolls, but stays in place, any ideas?

shanefarris

26-02-2010 16:44:05

Anyone have any feed back on this, or have experienced this before?

Master004

20-03-2010 15:43:32

Yes, I have the same problem.. I believe the tutorial is out of date. I doesnt work on any laptop/computer for all my teammates. The code only does what it should do on my very fast computer. On slower machines, the torso spins like crazy and give a bNormalizeResult error.

I think somebody with more knowledge has to redo the tutorial!

SFCBias

03-04-2010 15:17:49

Following this code will get your character moving http://www.ogre3d.org/wiki/index.php/Ninja_Walking_Character

shanefarris

25-04-2010 18:19:27

I am using the new code now and it is still not working. The top capsule is not moving around all crazy like, but nothing is moving. The feet sphere is rotating but its not moving the entire model and the capsule. Any ideas on that?

The only difference between the wiki and the new code is it doesn't set dampening for the capsule and thats all I could find, what else is different?

Thanks.

SFCBias

25-04-2010 19:18:56

Well I'm not sure if you're doing this but the actual entity should be attached to a child node of the first node you created, then the body and geoms etc are attached to the parent node

This is my code so i can show you what I mean. Here pNode = parentNode and cNode = child of pNode.
Also, to make things easier, i Named the Parent node with the same name as the entity as you can see on line 2 and 3

SceneNode *cNode = pNode ->createChildSceneNode();
cNode->attachObject(mSceneManager->getEntity(pNode->getName()));
AxisAlignedBox aab =
cNode->getAttachedObject(pNode->getName())->getBoundingBox();

Ogre::Vector3 min = aab.getMinimum() * pNode->getScale();
Ogre::Vector3 max = aab.getMaximum() * pNode->getScale();
Ogre::Vector3 center = aab.getCenter() * pNode->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::Body* dollFeetBody = new OgreOde::Body(mWorld);
OgreOde::SphereMass mMass(weight * 2.5, radius);
//mMass.setDensity(weight,radius);

dollFeetBody->setMass(mMass);

OgreOde::SphereGeometry* feetGeom = new OgreOde::SphereGeometry(radius,
mWorld);
OgreOde::TransformGeometry* feetTrans = new OgreOde::TransformGeometry(
mWorld, mSpace);

feetTrans->setBody(dollFeetBody);
feetTrans->setEncapsulatedGeometry(feetGeom);
pNode->attachObject(dollFeetBody);

cNode->translate(Vector3(0, -radius / pNode->getScale().y, 0));

OgreOde::Body* dollTorsoBody = new OgreOde::Body(mWorld);
dollTorsoBody->setMass(OgreOde::CapsuleMass(weight * 2.5, radius,
Vector3::UNIT_Y, radius));
dollTorsoBody->setAffectedByGravity(false);
OgreOde::TransformGeometry* torsoTrans = new OgreOde::TransformGeometry(
mWorld, mSpace);
OgreOde::CapsuleGeometry* torsoGeom = new OgreOde::CapsuleGeometry(radius,
size.y - 4 * radius, mWorld);
torsoGeom->setPosition(Ogre::Vector3(0, size.y - ((size.y - 4 * radius) / 2
+ 2 * radius), 0));
torsoGeom->setOrientation(Quaternion(Degree(90), Vector3::UNIT_X));
torsoTrans->setBody(dollTorsoBody);
torsoTrans->setEncapsulatedGeometry(torsoGeom);
pNode->attachObject(dollTorsoBody);

OgreOde::HingeJoint* joint = new OgreOde::HingeJoint(mWorld);
joint->attach(dollTorsoBody, dollFeetBody);
joint->setAxis(Ogre::Vector3::UNIT_X);



And here is the code for movement.

where _torso = torsoBody and _feet = feetBody


if (input->isKeyDown(KC_J))
_ninja_rotate += -1;
if (input->isKeyDown(KC_L))
_ninja_rotate += 1;

_ninja_thrust = 0;
if (input->isKeyDown(KC_I))
_ninja_thrust += -1;
if (input->isKeyDown(KC_K))
_ninja_thrust += 1;

if (_ninja_rotate == 0)
{
_feet->wake();
_feet->setAngularVelocity(Vector3(_feet->getAngularVelocity().x,0,0));
}
else
{
_feet->wake();
Quaternion q1 = _torso->getOrientation();
Quaternion q2(Degree(-4*_ninja_rotate),Ogre::Vector3::UNIT_Y);
_torso->setOrientation(q1*q2);
}

if (_ninja_thrust == 0)
{
_feet->wake();
_feet->setLinearVelocity(Vector3(0,_feet->getLinearVelocity().y,0));
_feet->setAngularVelocity(Vector3(0,_feet->getAngularVelocity().y,0));
}
else
{
float speed = 30;
_feet->wake();
Quaternion q = _torso->getOrientation();
_feet->setAngularVelocity(q*Ogre::Vector3(speed*_ninja_thrust*cos(1.0),_feet->getAngularVelocity().y,0));
}

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

shanefarris

27-04-2010 00:14:22

My bad, I didn't have a collision listener set. How is it that i will have boxes fall and a plane and they collide, but the sphere needed a collision listener set before it would move? Obviously there's collision being found with the boxes, I thought there would be a default listener already setup when you setup OgreOde. This I guess is not the case, so what call back is being called for the boxes?

SFCBias

28-04-2010 19:32:20

Thats intresting, may i see the code you used to create the box

shanefarris

02-05-2010 02:09:50


s32 CPhysicsStrategy_Ode::AddCube(SceneNode* Node, Entity* entity, const f32 bodyRestitution,
const f32 bodyFriction, const f32 bodyMass, Space* space)
{
// Create a body associated with the node we created
OgreOde::Body* body = new OgreOde::Body(m_World);
Node->attachObject(body);

reVector3Df size = GetBoundingBox(Node, entity);
OgreOde::BoxMass mass(bodyMass, size);
mass.setDensity(5.0, size);

if(!space)
space = m_Space;

OgreOde::Geometry* geom = new OgreOde::BoxGeometry(size, m_World, space);
body->setMass(mass);

// Tie the collision geometry to the physical body
geom->setBody(body);
//entity->setUserAny(Any(geom));

// Keep track of the body
m_Bodies.push_back(body);
m_Geometries.push_back(geom);
return m_Geometries.size() - 1;
}

SFCBias

04-05-2010 16:17:09

well in the class you want to be the collision listener , you should be calling mWorld->setCollisionListener(this); and that should make that class a collision listener for ALL collisions