I could use some help figuring out collision response. I'm trying to implement what is presented in this paper on slides 4 to 10. Collision detection works, and the colliding entity does slide along the collision plane but with severely reduced speed. I'm not sure whether I'm properly projecting the leftover velocity on collision plane.
class CollisionPacket {
// INPUT:
colliderRadius: vec3;
colliderPosition: vec3;
colliderVelocity: vec3;
// OUTPUT:
collisionFound: bool;
collisionTime: number; // how far can we travel before we collide?
collisionPoint: vec3; // point on triangle where collision ocurred
collisionNormal: vec3; // normal of nearest collided triangle
}
collideAndSlide(position: vec3, velocity: vec3, radius: number): vec3 {
var packet = new CollisionPacket();
packet.colliderRadius = radius;
packet.colliderPosition = position;
packet.colliderVelocity = velocity;
packet.collisionTime = 0.0;
packet.collisionFound = false;
var maxIterations = 5;
do {
// check nearby triangles for collisions
this.collideWorld(packet);
var newPosition = packet.colliderPosition.copy();
var newVelocity = packet.colliderVelocity.copy();
if (packet.collisionFound) {
// scale velocity vector to collide with nearest triangle
var scaledVelocity = packet.colliderVelocity.copy().scale(packet.collisionTime);
// move a tiny bit away from collision along collision normal
scaledVelocity.add(packet.collisionNormal.copy().scale(0.001));
// add scaled velocity to position
newPosition.add(scaledVelocity);
// and remove it from leftover velocity
newVelocity.subtract(scaledVelocity);
// extract part of velocity vector which is perpendicular to collision plane (CORRECT?)
var v = packet.collisionNormal.copy().scale(vec3.dot(newVelocity, packet.collisionNormal));
// remove that part from velocity vector
newVelocity = vec3.difference(newVelocity, v);
// update values for next iteration
packet.colliderPosition = newPosition;
packet.colliderVelocity = newVelocity;
}
else {
// no collision, move as requested
newPosition.add(packet.colliderVelocity);
}
} while (--maxIterations > 0 && packet.collisionFound)
return newPosition;
}
I visualized both v and newVelocity after v has been subtracted from it and they look how they're supposed to: v is perpendicular to the collision plane, newVelocity runs parallel to it in the direction we're moving.
If I add newVelocity directly to newPosition instead of doing the recursion, like this:
...
// remove that part from velocity vector
newVelocity = vec3.difference(newVelocity, v);
newPosition.add(newVelocity);
}
else {
// no collision, move as requested
newPosition.add(packet.colliderVelocity);
}
} while (false)
the entity is sliding as it should, without being slowed down, so I'm quite sure the vectors are ok.
However, maxIterations always runs down to zero, so there's always collisions. maybe that's slowing it down?
Would someone with a better understanding of the underlying math have a look?
Thank you!
EDIT:
Illustration of the vectors after the first iteration:
The box is colliding against the wall (invisible on this screenshot due to backface culling)