平面实体上的立方体实体碰撞

时间:2013-08-01 01:55:48

标签: xna xna-4.0

如何在立方体和平面之间进行碰撞,我可以在平面上做一个球体,但我不能在平面上找出立方体,我知道我必须找到立方体的x,y,z并且做在飞机上检测但我无法弄明白。

这是我的碰撞测试代码。

public static bool sphereAndSphere(Sphere a, Sphere b, ref Contact contact)
    {
        // Get the vector from the centre of particle B to the centre of particle A
        Vector3 separationVector = b.Position - a.Position;
        float sumOfRadii = a.Radius + b.Radius;
        float distance = separationVector.Length();

        if (distance < sumOfRadii)
        {
            contact.contactPoint = a.Position + separationVector / 2f;
            separationVector.Normalize();
            contact.contactNormal = separationVector;
            contact.penetrationDepth = sumOfRadii - distance;

            return true;
        }

        return false;
    }

    // This assumes that the Origin is in the centre of world 
    // and that the planes are the boundaries of the world and that all rigid-bodies are within the boundaries
    public static bool sphereAndPlane(Sphere a, PlaneEntity b, ref Contact contact)
    {
        // Depth of sphere into plane (if negative, no collision)
        float depth = Vector3.Dot(a.Position, b.DirectionFromOrigin) + a.Radius + b.OffsetFromOrigin;

        if (depth > 0)
        {
            contact.contactPoint = a.Position + (a.Radius - depth) * b.DirectionFromOrigin;
            contact.contactNormal = -b.DirectionFromOrigin;
            contact.penetrationDepth = depth;

            return true;
        }

        return false;
    }

这里对盒子上的立方体进行测试

public static bool sphereAndBox(Sphere a, Cube b, ref Contact contact)
    {
        Vector3 relativePoint = Vector3.Transform(a.Position, Matrix.Invert(b.WorldTransform));

        // Early out check, based on separation axis theorem
        if (Math.Abs(relativePoint.X) - a.Radius > b.halfSize.X
            || Math.Abs(relativePoint.Y) - a.Radius > b.halfSize.Y
            || Math.Abs(relativePoint.Z) - a.Radius > b.halfSize.Z)
            return false;

        Vector3 closestPoint = Vector3.Zero;

        closestPoint.X = MathHelper.Clamp(relativePoint.X, -b.halfSize.X, b.halfSize.X);
        closestPoint.Y = MathHelper.Clamp(relativePoint.Y, -b.halfSize.Y, b.halfSize.Z);
        closestPoint.Z = MathHelper.Clamp(relativePoint.Z, -b.halfSize.Z, b.halfSize.Z);

        float distance = (closestPoint - relativePoint).LengthSquared();

        if (distance < a.Radius * a.Radius)
        {
            contact.contactPoint = Vector3.Transform(closestPoint, b.WorldTransform);
            contact.contactNormal = a.Position - contact.contactPoint;
            contact.contactNormal.Normalize();
            contact.penetrationDepth = a.Radius - (float)Math.Sqrt(distance);
            return true;
        }

        return false;
}

1 个答案:

答案 0 :(得分:0)

如果平面或立方体不是轴对齐 - 或者 - 立方体(宽度,长度,高度)不相等,您会发现最简单的方法是对立方体而不是立方体单独测试立方体的每个角落位置作为一个整体。然后当第一个角穿过平面时,记录碰撞。

但是如果平面和立方体都是轴对齐 AND 立方体是对称的(WLH),那么将立方体视为半径为立方体宽度一半的球体。