我可以使用一些帮助来确定碰撞响应。我正在尝试在幻灯片 4 到 10 上实现本文中介绍的内容。碰撞检测有效,碰撞实体确实沿着碰撞平面滑动,但速度严重降低。我不确定我是否正确地将剩余速度投影在碰撞平面上。
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;
}
在从v中减去 v之后,我将v和newVelocity都可视化了,它们看起来应该是这样的:v垂直于碰撞平面,newVelocity在我们移动的方向上平行于它。
如果我将newVelocity直接添加到newPosition而不是进行递归,如下所示:
...
// 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)
实体正在滑动,没有减速,所以我很确定向量是好的。
然而,maxIterations总是跑到零,所以总是有冲突。也许这会减慢速度?
对基础数学有更好理解的人会看看吗?
谢谢!
编辑:
第一次迭代后的向量说明:
盒子与墙壁发生碰撞(由于背面剔除,此屏幕截图中不可见)