与复杂几何体碰撞和滑动球体
Posted
技术标签:
【中文标题】与复杂几何体碰撞和滑动球体【英文标题】:Collide and slide a sphere against complex geometry 【发布时间】:2012-10-09 09:41:43 【问题描述】:我可以使用一些帮助来确定碰撞响应。我正在尝试实现在幻灯片 4 到 10 上呈现的 in this paper。碰撞检测有效,并且碰撞实体 确实 沿着碰撞平面滑动,但速度严重降低。我不确定我是否正确地将剩余速度投影到碰撞平面上。
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 总是跑到零,所以总是有冲突。也许这会减慢速度?
对基础数学有更好理解的人可以看看吗?
谢谢!
编辑:
第一次迭代后的向量说明:
盒子与墙壁发生碰撞(由于背面剔除,此屏幕截图中不可见)
【问题讨论】:
【参考方案1】:发现问题:我忘记在每次迭代开始时重置 packet.collisionTime,这是它减慢了速度的原因。它现在按预期工作。也许代码对其他人有帮助。
【讨论】:
以上是关于与复杂几何体碰撞和滑动球体的主要内容,如果未能解决你的问题,请参考以下文章