   Sliding character controller using Bullet
  I'm trying to implement my own sliding character controller to have more control over it and also to get the most out of speed. I'm running into a few issues though, and i was hoping if someone could help in clarifying some things up. First of all, here's how my algorithm works(i'm using only the collision library): i do a convex sweep and retain only the first intersection point p and normal n. If there is indeed a collision then i decompose the velocity of the object(which is a sphere) into a parallel component pa, and normal component pn, with respect to n. I then reiterate the algorithm with new parameters: velocityNew = pn * (pn.dot(velocityOld));startPoint = collisionPoint;endPoint = startPoint + velocityNew,until a number of iterations have passed or velocityNew has a small enough magnitude.The code is very short and can explain better what am i doing:   bool collision = false;   int i;   for (i=0; i<10; i++)   {    if (vel.length() < 0.00001f)    break; float radius = 150.0f; e = s+vel;  btCollisionWorld::ClosestConvexResultCallback cb(s, e);   btSphereShape sphere(radius); btTransform from(btMatrix3x3().getIdentity(), s); btTransform to(btMatrix3x3().getIdentity(), e); collisionWorld->convexSweepTest(&sphere, from, to, cb);   if (cb.hasHit()) { point = cb.m_hitPointWorld;    normal = cb.m_hitNormalWorld;    btVector3 n = normal;    n.normalize();    btVector3 newPos = point + n * radius;    s = newPos;   btVector3 dir = e - s;    btVector3 parallel = btDot(n, dir)*n;    btVector3 perpendicular = dir - parallel;    perpendicular.normalize();    vel = perpendicular*((vel).dot(perpendicular));    collision = true;  }elsebreak;    }   if (!collision)    s = e;The problem is that i sometimes run through walls, and at corners the sphere trembles back and forth. What can i do to improve this? I also notice that the character controller provided also has this issue and besides it's rather slow sometimes.[Edited by - Deliverance on May 22, 2010 3:10:02 PM]
  At some point you're going to need to ensure that you're moving towards the contact point before you correct the velocity. It is possible that you are in contact and moving away. Trying to correct the velocity in this case would cause ping pong like behavior. Check the sign of one of your dot products to ensure you're only doing things to prevent penetration not also to prevent separation.Also i'm pretty sure you can do this without a single square root call. You have 3.Actually, i swear i've seen this code, major deja vu.   ;  Thanks for the feedback! You are correct, i have to assume for velocity turning around the initial velocity and cause the object to jump back. Althogh, i discovered that this isn't the only issue. Bullet does no account for objects ALREADY in collision when doing the swept collision test so i had to include a discrete collision test first and then do the swept test. These two corrections do improve the ping-pong behaviour,by minimizing it, but i'm not fully satisfied yet. There's still ping-pong behaviour there and i wonder what can i do to minimize it more (can't see a solution that completely gets rid of it now). Here's the new code:for (i=0; i<10; i++){if (vel.length() < 0.00001f)break;float radius = 150.0f;e = s+vel;    btCollisionWorld::ClosestConvexResultCallback cb(s, e);  btSphereShape sphere(radius);btCollisionObject sco;btTransform worldTrans;worldTrans.setIdentity();worldTrans.setOrigin(s);sco.setWorldTransform(worldTrans);sco.setCollisionShape(&sphere);btTransform from(btMatrix3x3().getIdentity(), s);btTransform to(btMatrix3x3().getIdentity(), e);btDrawingResultLocal dr(&sco);collisionWorld->contactTest(&sco, dr);btVector3 point;btVector3 normal;bool okay = false;if (dr.minimumDistance < 0.0f){okay = true;if ((dr.pt2 - dr.pt1).length() > 0.001f)point = dr.pt2 + (dr.pt2 - dr.pt1).normalized() * -dr.minimumDistance;elsepoint = dr.pt1;normal = dr.normal;}else{collisionWorld->convexSweepTest(&sphere, from, to, cb);if (cb.hasHit()){okay = true;point = cb.m_hitPointWorld;normal = cb.m_hitNormalWorld;}}if (okay){btVector3 n = normal;n.normalize();btVector3 newPos = point + n * radius;s = newPos;btVector3 dir = e - s;btVector3 parallel = btDot(n, dir)*n;btVector3 perpendicular = dir - parallel;perpendicular.normalize();if (initialVel.dot((perpendicular*((vel).dot(perpendicular)))) < 0.0f)break;vel = perpendicular*((vel).dot(perpendicular));collision = true; }else break; }if (!collision)s = e;EDIT: i know the code is not optimized and kind of messy but i'm trying to make it work first and optimize later.   