2

我可以使用一些帮助来确定碰撞响应。我正在尝试在幻灯片 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之后,我将vnewVelocity都可视化了,它们看起来应该是这样的: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总是跑到零,所以总是有冲突。也许这会减慢速度?

对基础数学有更好理解的人会看看吗?

谢谢!

编辑:

第一次迭代后的向量说明:

在此处输入图像描述

盒子与墙壁发生碰撞(由于背面剔除,此屏幕截图中不可见)

4

1 回答 1

0

发现问题:我忘记在每次迭代开始时重置 packet.collisionTime,这让一切都变慢了。它现在按预期工作。也许代码对其他人有帮助。

于 2012-10-19T16:15:25.450 回答