总是检测到碰撞,即使它们不应该是碰撞

发布于 2024-11-27 09:33:10 字数 3344 浏览 1 评论 0原文

好吧,我肯定忽略了一些非常明显的事情,但问题是:

在我的项目中,我使用两种类型的碰撞:球体到球体和盒子到盒子。 两人都遇到了同样的问题;它们总是检测到两个物体之间的碰撞。

在我的 baseGameObject 类中,我声明了边界框:

       BoundingBox bb;

我还有为模型创建边界框并使用它来定义 bb 的方法:

      public void Initialize()
      {
          bb = CreateBoundingBox();
      }


    protected BoundingBox CalculateBoundingBox()
    {

        Vector3 modelMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
        Vector3 modelMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
        transforms = new Matrix[model.Bones.Count];

        foreach (ModelMesh mesh in model.Meshes)
        {
            Vector3 meshMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
            Vector3 meshMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

            foreach (ModelMeshPart part in mesh.MeshParts)
            {
                int stride = part.VertexBuffer.VertexDeclaration.VertexStride;

                byte[] vertexData = new byte[stride * part.NumVertices];
                part.VertexBuffer.GetData(part.VertexOffset * stride, vertexData, 0, part.NumVertices, 1); // fixed 13/4/11

                Vector3 vertPosition = new Vector3();
                for (int ndx = 0; ndx < vertexData.Length; ndx += stride)
                {
                    vertPosition.X = BitConverter.ToSingle(vertexData, ndx);
                    vertPosition.Y = BitConverter.ToSingle(vertexData, ndx + sizeof(float));
                    vertPosition.Z = BitConverter.ToSingle(vertexData, ndx + sizeof(float) * 2);

                    meshMin = Vector3.Min(meshMin, vertPosition);
                    meshMax = Vector3.Max(meshMax, vertPosition);
                }
            }

            meshMin = Vector3.Transform(meshMin, transforms[mesh.ParentBone.Index]);
            meshMax = Vector3.Transform(meshMax, transforms[mesh.ParentBone.Index]);

            modelMin = Vector3.Min(modelMin, meshMin);
            modelMax = Vector3.Max(modelMax, meshMax);
        }

        return new BoundingBox(modelMin, modelMax);

    }

然后我创建了一个方法来使用 bb 进行碰撞。

    public bool BoxCollision(BoundingBox secondBox)
    {
        if (bb.Intersects(secondBox))
            return true;
        else            
            return false;
    }

最后我使用该方法来确定碰撞检测。

    public void CollisionCheck()
    {
        foreach (NonPlayerChar npc in npcList)
        {
            if(player.SphereCollision(npc.model, npc.getWorldRotation()))
            { npc.position = vector3.Zero; }

            if (player.BoxCollision(npc.bb))
            { npc.position = vector3.Zero; }                 
        }

    }

位置问题是为了测试它们是否发生碰撞。我可以将对象位置设置为任何位置,并且仍然会检测到碰撞。 我对于边界球体碰撞也有同样的问题。

   public bool SphereCollision(Model secondModel, Matrix secondWorld)
    {
        foreach (ModelMesh modelMeshes in model.Meshes)
        {
            foreach (ModelMesh secondModelMesh in secondModel.Meshes)
            {
                if(modelMeshes.BoundingSphere.Transform(getWorldRotation()).Intersects(secondModelMesh.BoundingSphere.Transform(secondWorld)))
                    return true;
            }
        }
        return false;
    }

有谁知道我做错了什么?

OK I'm definitely overlooking something painfully obvious but here's the problem:

In my project I'm using two types of collision: sphere to sphere and box to box.
Both are experiencing the same problem; they always detect a collision between the two objects.

in my baseGameObject class I declare the bounding box:

       BoundingBox bb;

I also have the method that creates a boundingbox for a model and use that to define bb:

      public void Initialize()
      {
          bb = CreateBoundingBox();
      }


    protected BoundingBox CalculateBoundingBox()
    {

        Vector3 modelMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
        Vector3 modelMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
        transforms = new Matrix[model.Bones.Count];

        foreach (ModelMesh mesh in model.Meshes)
        {
            Vector3 meshMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
            Vector3 meshMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

            foreach (ModelMeshPart part in mesh.MeshParts)
            {
                int stride = part.VertexBuffer.VertexDeclaration.VertexStride;

                byte[] vertexData = new byte[stride * part.NumVertices];
                part.VertexBuffer.GetData(part.VertexOffset * stride, vertexData, 0, part.NumVertices, 1); // fixed 13/4/11

                Vector3 vertPosition = new Vector3();
                for (int ndx = 0; ndx < vertexData.Length; ndx += stride)
                {
                    vertPosition.X = BitConverter.ToSingle(vertexData, ndx);
                    vertPosition.Y = BitConverter.ToSingle(vertexData, ndx + sizeof(float));
                    vertPosition.Z = BitConverter.ToSingle(vertexData, ndx + sizeof(float) * 2);

                    meshMin = Vector3.Min(meshMin, vertPosition);
                    meshMax = Vector3.Max(meshMax, vertPosition);
                }
            }

            meshMin = Vector3.Transform(meshMin, transforms[mesh.ParentBone.Index]);
            meshMax = Vector3.Transform(meshMax, transforms[mesh.ParentBone.Index]);

            modelMin = Vector3.Min(modelMin, meshMin);
            modelMax = Vector3.Max(modelMax, meshMax);
        }

        return new BoundingBox(modelMin, modelMax);

    }

I then made a method to use bb for my collision.

    public bool BoxCollision(BoundingBox secondBox)
    {
        if (bb.Intersects(secondBox))
            return true;
        else            
            return false;
    }

And finally I use the method to determine collision detection.

    public void CollisionCheck()
    {
        foreach (NonPlayerChar npc in npcList)
        {
            if(player.SphereCollision(npc.model, npc.getWorldRotation()))
            { npc.position = vector3.Zero; }

            if (player.BoxCollision(npc.bb))
            { npc.position = vector3.Zero; }                 
        }

    }

the position thing was a test to see if they collide. I can set the objects position to any position and the collision is still detected.
I have the same problem for the bounding sphere collision.

   public bool SphereCollision(Model secondModel, Matrix secondWorld)
    {
        foreach (ModelMesh modelMeshes in model.Meshes)
        {
            foreach (ModelMesh secondModelMesh in secondModel.Meshes)
            {
                if(modelMeshes.BoundingSphere.Transform(getWorldRotation()).Intersects(secondModelMesh.BoundingSphere.Transform(secondWorld)))
                    return true;
            }
        }
        return false;
    }

Does anyone know what I'm doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

飘逸的'云 2024-12-04 09:33:10

最简单的事情之一就是抓住两个球体并比较它们的坐标..

例如

sphere1_x = sphere.x;
sphere2_x = sphere2.x;
width of sphere = 2 for example;

if ((sphere1_x + width/2) > (sphere2_x + width/2))
system.out.writeline("collison");
else if (sphere1_x (check for other ways of connecting between the coordinate system x>x2, x<x2, y>y2, y<y2 etc)
else
system.out.writeline("no collision")

,然后如果您真的想要,您可以将代码重构为上面的方式。
在球体之前先处理边界框可能更容易。

One of the easiest things to do is to grab both your spheres and compare there coordinates..

e.g.

sphere1_x = sphere.x;
sphere2_x = sphere2.x;
width of sphere = 2 for example;

if ((sphere1_x + width/2) > (sphere2_x + width/2))
system.out.writeline("collison");
else if (sphere1_x (check for other ways of connecting between the coordinate system x>x2, x<x2, y>y2, y<y2 etc)
else
system.out.writeline("no collision")

Then if you really want you can refactor your code to how youve got it above.
Probably easier to do the bounding boxes first before the spheres.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文