Character jumping without a reason

Dibalo

12-05-2007 16:42:11

Hi.

I got a problem with character movement by addForce. My characer walks and stops walking as I want but the problem is that when I stop the walking, character "jumps" This happens when character is walking in the middle of hill. The bigger angle of the hill the higher jump character makes. If he´s walking on the flat area, jump will not happen when stopping. I hope you could help me with this issue. Here is my current moving callback: void _callback(Body* b)
{
Real speed = 20;

Vector3 vel = b->getVelocity();
vel.y = 0;

mMove = ((mNode->getOrientation() * Vector3::NEGATIVE_UNIT_Z * (isMoving*speed))-vel)/b->getWorld()->getTimeStep();

b->addForce( mMove * mMass );
b->addForce( Vector3(0,-9.81,0) * mMass );

isMoving = false;
}

When the character is moving the variable isMoving is true. I´ll change it to true by pressing keyboard key.


I´m making my character with this code: _Character(const String& mesh)
: mMove(Vector3::ZERO), isMoving(false)
{
System* sys = System::getSingletonPtr();

mNode = sys->SceneManager->getRootSceneNode()->createChildSceneNode();
Entity* ent = sys->SceneManager->createEntity( "__DEV_Character_Ent__", mesh );
mNode->attachObject( ent );
mNode->setScale(0.07,0.07,0.07);

Collision* col = new OgreNewt::CollisionPrimitives::Ellipsoid( sys->PhysXworld, Vector3(1.5,.3,.3) );
mBody = new Body( sys->PhysXworld, col );
OgreNewt::BasicJoints::UpVector* joint = new OgreNewt::BasicJoints::UpVector( sys->PhysXworld, mBody, Vector3::UNIT_Y );
mDirJoint = new OgreNewt::BasicJoints::UpVector(sys->PhysXworld, mBody, Vector3::UNIT_X);
delete col;

mMass = 2;
mInertia = OgreNewt::MomentOfInertia::CalcEllipsoidSolid(mMass,Vector3(1.5,0.3,0.3));

mBody->attachToNode( mNode );
mBody->setCustomForceAndTorqueCallback<_Character>( &_Character::_callback, this );
mBody->setMassMatrix( mMass, mInertia );
mBody->setPositionOrientation( Vector3(-100,150,80), Quaternion() );
mBody->setAutoFreeze(0);


OgreNewt::MaterialID* mat = new OgreNewt::MaterialID( sys->PhysXworld );
OgreNewt::MaterialPair* pair = new OgreNewt::MaterialPair( sys->PhysXworld, mat, sys->PhysXworld->getDefaultMaterialID() );
pair->setDefaultElasticity(0);
pair->setDefaultFriction(0,0);
mBody->setMaterialGroupID( mat );


Keyboard& keys = Keyboard::getSingleton();
keys.registerEvent( KeyData(OIS::KC_U, 1), Keyboard::Event(&_Character::move, this) );

}

Please, if you want more details, I´d tell them happily. :)

Dibalo

12-05-2007 20:33:43

Ok I solved it. :D

I thought that when character is moving up to the hill, he has to have a force directed up because he´s moving up. Because that force, character "jumps" before the gravity takes him down. Leaving the y-component of velocity to its normal value disables the gravity. After trying different methods I found a simply answer. I just changed this line:vel.y = 0;
To this:if( vel.y < 0 ) vel.y = 0;
The idea is simply. If only gravity affects to the character, then we can´t disable it. If the force directs upwards, then we have to disable it to avoid "jumping". Of course the real jumping thing is a little different now, but I believe that it can be handled with some if-expressions. :)

rafaelriedel

13-06-2007 00:22:16

Very interesting!

I'm working in something similar, but my code to make the character walk was different from you.

Given an angle, I'm calculate the character's rotation (0~360), then calculating sin and cos, I have a direction vector.

like this:

(this code was extracted from this forum)

d = ogre.Degree( self.dirAngle );

self.rot = ogre.Vector3( Sin(d.valueRadians()), 0.0, -Cos(d.valueRadians()) );

and then apply to the addForce inside the callback method

body.addForce( self.rot * self.mass )

and set a new pin with this:

dirJoint.setPin( self.rot )

How it works:

I have a Sphere with a upvector to UNIT_Y, and a upvector to UNIT_X (dirJoint), and to make it turn, I set the new pin with the rot vector. It worked well! believe me!! ;)

So, applying the force using rot vector by his mass, it worked too! But to make the character stop immediatly is buggy. It stops, but by his inertia, slowing his velocity.

now tell me. Maybe you should give some light for me.

Everywhere I'm reading, with Newton, everyone is using a sphere as feet, I think this sphere should be rolling to a specific direction, but not been "dragged" to this direction (as everyone is doing). What do you think about this?

Ahn! Sorry for the english!!

See ya!!