XNA三维地形碰撞检测

XNA三维地形碰撞检测,xna,collision-detection,terrain,Xna,Collision Detection,Terrain,我一直在做一个基本的3D XNA游戏。到目前为止,我已经成功地将各种角色模型加载到一个更大的级别/世界模型中。我加入了一些基本控件,允许用户/玩家在世界各地移动其中一个角色,甚至使用BoundingSphere/BoundingBox与其他角色模型实现了一些碰撞检测 然而,角色模型(目前)被固定在Y轴上的一个固定位置,因此我的世界实际上只是一个平面,它们可以在上面滑动 我现在想做的是实现一种类似重力的力,它允许角色随着地形的流动而升降。我花了几个小时在谷歌上搜索(徒劳无功),寻找某种方法来检查我

我一直在做一个基本的3D XNA游戏。到目前为止,我已经成功地将各种角色模型加载到一个更大的级别/世界模型中。我加入了一些基本控件,允许用户/玩家在世界各地移动其中一个角色,甚至使用BoundingSphere/BoundingBox与其他角色模型实现了一些碰撞检测

然而,角色模型(目前)被固定在Y轴上的一个固定位置,因此我的世界实际上只是一个平面,它们可以在上面滑动

我现在想做的是实现一种类似重力的力,它允许角色随着地形的流动而升降。我花了几个小时在谷歌上搜索(徒劳无功),寻找某种方法来检查我角色的边界球体与世界实际网格之间的详细碰撞。我找到的所有文章似乎都解释了如何使用球体和长方体方法,或者如何实现一些外部物理引擎(所有这些似乎都非常详细地说明了我想要实现的目标)

所以我的问题是双重的-

  • 首先,我是否以最好的方式处理这件事?我的世界只有一个大的ish模型
  • 其次,是否有一种相对简单的方法来检查我需要的碰撞类型,使用XNA库本身,或者其他不需要我引入全新物理层的库
注意。我要检查冲突的模型是:Microsoft.Xna.Framework.Graphics.Model

编辑:


我还应该提到的是,我不是在创建一个关卡,而是一个游戏引擎,它可以处理从数据库加载的各个关卡。因此,我不想单独/手动定义级别的约束。理想情况下,我希望从数据库加载我的单个网格,并能够按原样检测碰撞,或者从网格数据自动计算出约束/边界区域。

三维碰撞检测比乍一看似乎更复杂,因此使用其中一种规定的方法(即BoundingSphere对象可以帮助)。检查

具体而言,此代码块给出了一个想法:

static void CheckForCollisions( ref WorldObject c1, ref WorldObject c2 )
{
    for (int i = 0; i < c1.model.Meshes.Count; i++)
    {
        // Check whether the bounding boxes of the two cubes intersect.
        BoundingSphere c1BoundingSphere = c1.model.Meshes[i].BoundingSphere;
        c1BoundingSphere.Center += c1.position;

        for (int j = 0; j < c2.model.Meshes.Count; j++)
        {
            BoundingSphere c2BoundingSphere = c2.model.Meshes[j].BoundingSphere;
            c2BoundingSphere.Center += c2.position;

            if (c1BoundingSphere.Intersects( c2BoundingSphere ))
            {
                c2.ReverseVelocity();
                c1.Backup();
                c1.ReverseVelocity();
                return;
            }
        }
    }
}
静态无效检查碰撞(参考WorldObject c1,参考WorldObject c2)
{
对于(int i=0;i
三维碰撞检测比乍一看要复杂得多,因此使用规定的方法之一(即BoundingSphere对象可以提供帮助)。检查

具体而言,此代码块给出了一个想法:

static void CheckForCollisions( ref WorldObject c1, ref WorldObject c2 )
{
    for (int i = 0; i < c1.model.Meshes.Count; i++)
    {
        // Check whether the bounding boxes of the two cubes intersect.
        BoundingSphere c1BoundingSphere = c1.model.Meshes[i].BoundingSphere;
        c1BoundingSphere.Center += c1.position;

        for (int j = 0; j < c2.model.Meshes.Count; j++)
        {
            BoundingSphere c2BoundingSphere = c2.model.Meshes[j].BoundingSphere;
            c2BoundingSphere.Center += c2.position;

            if (c1BoundingSphere.Intersects( c2BoundingSphere ))
            {
                c2.ReverseVelocity();
                c1.Backup();
                c1.ReverseVelocity();
                return;
            }
        }
    }
}
静态无效检查碰撞(参考WorldObject c1,参考WorldObject c2)
{
对于(int i=0;i
第一个答案为您提供了详细碰撞检测的第一次通过测试。您可以优化第一次通过并使用AABB测试。第二次通过将需要光线三角形相交测试。请小心,因为当光线击中三角形边或顶点时,其中一些测试将失败-因此请确保测试仪代码/算法符合您的要求选择考虑了这些因素。还可以使用四叉树或其他空间分区方案进行进一步修改,以提高碰撞检测的速度。

第一个答案为您提供了详细碰撞检测的第一次通过测试。您可以优化第一次通过并使用AABB测试。第二次通过将需要一个光线三角形横断面测试。小心,因为当光线击中三角形边或顶点时,其中一些会失败-因此,请确保您选择的测试仪代码/算法考虑到这些。还可以使用四叉树或其他空间分区方案进行进一步修改,以提高碰撞检测的速度。

以下是对碰撞检测的详细描述球体/三角形技术I曾经适用于2D碰撞检测:

我不能肯定它会对你有帮助,但它可能对与地形网格和重力的碰撞有用。结合与其他“角色”的碰撞这可能很有挑战性,具体取决于你想做什么。但是,它确实具体描述了如何实现重力,总的来说,这是3D中碰撞检测和角色物理可能采用的最简单的方法之一

至于与整个地形网格碰撞是否“正确”如果是一个简单的网格,并且您没有资源限制,那么请确定。但是,碰撞检测在计算上非常昂贵,并且将其应用于网格中的所有三角形可能很快变得不可能。通常,您可能希望将三角形存储在一些有效搜索的结构中,如a或a,然后执行rough搜索