Столкновение всегда обнаруживается, даже если оно не должно быть столкновением. - PullRequest
1 голос
/ 02 августа 2011

ОК. Я определенно пропускаю что-то до боли очевидное, но вот проблема:

В моем проекте я использую два типа столкновений: сфера в сферу и коробка в коробку. Оба испытывают одну и ту же проблему; они всегда обнаруживают столкновение между двумя объектами.

в моем классе 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;
    }

Кто-нибудь знает, что я делаю не так?

1 Ответ

1 голос
/ 02 августа 2011

Одна из самых простых вещей - это взять обе ваши сферы и сравнить там их координаты.

например,

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")

Тогда, если вы действительно хотите, вы можете реорганизовать свой код так, как:Вы получили это выше.Вероятно, проще сделать ограничивающие рамки сначала перед сферами.

...