[SOLVED] btKinematicCharController: Behavior on slopes

Post Reply
Waschmaschine
Posts: 10
Joined: Wed Apr 15, 2015 9:50 pm

[SOLVED] btKinematicCharController: Behavior on slopes

Post by Waschmaschine »

Hello everyone,
I am using a btKinematicCharacterController to control my player. I've put together a quick video of two small clips:
https://www.youtube.com/watch?v=2GH1YI5B5lU

Edit: I do not care about issue #1 right now.
Clip #1 is an issue I face when I land or stop on seams. The player gets pushed a little bit. Even though the grassy plane is one object in Bullet.
I think it has to do with how I create this object because I am using a btBvhTriangleMeshShape for the plane (and BtOgre, of course). Any advice? It's a small annoyance, but still.

Code: Select all

   Ogre::Plane plane;
	plane.normal = Ogre::Vector3::UNIT_Y;
	plane.d = 0;
 
	Ogre::MeshManager::getSingleton().createPlane("floor", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 70.0f, 70.0f, 10, 10, true, 1, 50.0f, 50.0f, Ogre::Vector3::UNIT_Z);
	Ogre::Entity* planeEnt = _sceneManager->createEntity("plane", "floor");
	planeEnt->setMaterialName("GrassMaterial");
	planeEnt->setCastShadows(false);
	_sceneManager->getRootSceneNode()->createChildSceneNode()->attachObject(planeEnt);
	// physics for plane
	BtOgre::StaticMeshToShapeConverter converter3(planeEnt);
	_planeShape = converter3.createTrimesh();
	_planeMotionState = new btDefaultMotionState();
	_planeBody = new btRigidBody(0, _planeMotionState, _planeShape);
	_planeBody->setCollisionFlags(COL_STATIC_ENVIRONMENT);

	_phyWorld->addRigidBody(_planeBody, COL_STATIC_ENVIRONMENT, CollisionGroups::environmentCollidesWith);
Clip #2 is that the player slides on any slope, even though he can walk them up. How can I avoid that? I want the player to stay at this position if the angle is not too steep.

Any advice?
Last edited by Waschmaschine on Sun Aug 16, 2015 4:39 pm, edited 1 time in total.
Waschmaschine
Posts: 10
Joined: Wed Apr 15, 2015 9:50 pm

Re: btKinematicCharController: Behavior on slopes and on sea

Post by Waschmaschine »

After some experimenting and dissecting I've found out why the sliding on slopes occurs:

In btKinematicCharacterController you basically apply gravity and in the method stepDown you check whether you hit the floor and calculate your new height for drops. After that in the next loop iteration we first call recoverFromPenetration(), which pushes the character position on slopes in the direction of the normal of the hit, which is up (positive y) and some xz direction. So, I think this happens:

1. recoverFromPenetration() detects a hit, pushes your character in normal direction.
2. stepDown() pushes you in gravity direction, so that a penetration is detected again in the next loop (or very soon).
3. repeat

A fix or hack for small slopes is to overwrite btKinematicCharacterController with your own and limit recoverFromPenetration(), when you are on the ground. So in btCharacterController::recoverFromPenetration change the code where you detect a penetration to the following:

Code: Select all

btVector3 offset = pt.m_normalWorldOnB * directionSign * dist * btScalar(0.2);
if (onGround()){ // CHANGE: Prevent sliding when on slopes
    offset.setX(0);
    offset.setZ(0);
}
m_currentPosition += offset;					
penetration = true;
This works for me right now. Too steep slopes (> ca. 60°) do not work with movement, because onGround() begins to flip for some frames. So you might want to change the onGround detection if you want to climb those steep slopes.
Post Reply