用于地形的XNA 3D碰撞检测

时间:2012-10-07 21:59:51

标签: xna collision-detection terrain

我一直致力于基本的3D XNA游戏。到目前为止,我已经设法将各种角色模型加载到更大的级别/世界模型上。我已经提供了一些基本的控件,允许用户/玩家移动世界各地的一个角色 - 甚至使用BoundingSphere / BoundingBox和其他角色模型实现了一些碰撞检测。

然而,角色模型(此刻)被困在Y轴的固定位置,所以我的世界实际上只是一个平面,让他们滑过。

我现在要做的是实施像力一样的重力,这将允许角色随着地形的流动而上升和下降。我花了几个小时在谷歌搜索(徒劳),以检查我的角色的边界球与世界的实际网格之间的详细碰撞。我发现的文章似乎都解释了如何使用球体和盒子方法,或者实现了一些外部物理引擎(所有这些都看起来非常精心实现我想要实现的目标)。

所以我的问题是双重的 -

  • 首先,我是以最好的方式接近这个吗?我的世界只有一个大型模型?
  • 其次,是否有一种相对简单的方法来检查我需要的碰撞类型,使用XNA库本身,或者其他一些不需要我引入全新物理层的库。

NB。我想检查冲突的模型是:Microsoft.Xna.Framework.Graphics.Model

编辑:

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

4 个答案:

答案 0 :(得分:0)

三维碰撞检测比一眼看上去更复杂,因此使用一种规定的方法(即,BoundingSphere对象可以提供帮助)。查看http://msdn.microsoft.com/en-us/library/bb203906(v=xnagamestudio.10).aspx

具体来说,这个代码块给出了一个想法:

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;
            }
        }
    }
}

答案 1 :(得分:0)

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

答案 2 :(得分:-1)

以下是我曾经适用于2D碰撞检测的球/三角技术的详细说明:

http://www.peroxide.dk/papers/collision/collision.pdf

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

关于是否与整个地形网格碰撞的问题是“正确”的方法......如果它是一个简单的网格而且你没有资源约束,那么肯定。然而,碰撞检测在计算上是昂贵的,并且将其应用于网格中的所有三角形可能很快变得不可能。通常,您可能希望将三角形存储在一些有效的可搜索结构中,如octreek-d tree,然后粗略搜索角色附近的三角形,然后可以更精确地测试碰撞用于测试网格中每个三角形的时间要少得多。

答案 3 :(得分:-1)

你可以假装它。换句话说,我假设,在每次更新通话时,您都可以将玩家的高度设置为玩家碰巧所在的地形高度。我想象不是处理事情最专业的方式,但可能有用。