Столкновения в САТ работают только в двух направлениях

Я пытаюсь разрешить коллизии через SAT в XNA, но это работает только в двух направлениях внизу и справа). Я полагаю, что эта проблема вызвана тем, что перекрытие не проходит проверку длины, если ось имеет отрицательные компоненты.

Метод разрешения столкновений:

public Vector2 Collides(Rect other, float selfr, float otherr)
        {
            Vector2 minTranslationVector = new Vector2(Single.PositiveInfinity, Single.PositiveInfinity);
            foreach (Vector2 v in GetRotatedNormals(selfr))
            {
                float[] minMaxA = ProjectRotatedAlongAxis(selfr, v);
                float[] minMaxB = other.ProjectRotatedAlongAxis(otherr, v);
                float minA = minMaxA[0];
                float maxA = minMaxA[1];
                float minB = minMaxB[0];
                float maxB = minMaxB[1];
                if (!(maxA > minB && maxB > minA))
                    return new Vector2(0, 0);
                float overlap = Math.Min(maxA - minB, maxB - minA);
                if (Math.Pow(overlap, 2) < minTranslationVector.LengthSquared())
                {
                    minTranslationVector = v * overlap;

                }
            }
            foreach (Vector2 v in other.GetRotatedNormals(otherr))
            {
                float[] minMaxA = ProjectRotatedAlongAxis(selfr, v);
                float[] minMaxB = other.ProjectRotatedAlongAxis(otherr, v);
                float minA = minMaxA[0];
                float maxA = minMaxA[1];
                float minB = minMaxB[0];
                float maxB = minMaxB[1];
                if (!(maxA > minB && maxB > minA))
                    return new Vector2(0, 0);
                float overlap = Math.Min(maxA - minB, maxB - minA);

                if (Math.Pow(overlap, 2) < minTranslationVector.LengthSquared())
                {
                    minTranslationVector = v * overlap;

                }
            }
            return minTranslationVector;
        }

Разрешение столкновений игроков (фрагмент из метода обновления)

foreach (GameObject obj in room.Objects)
            {
                if (!obj.HasCollisions)
                    continue;
                Rect playerRect = new Rect(BoundingBox);
                Vector2 minTranslationVector = playerRect.Collides(new Rect(obj.BoundingBox), 0, 0);
                playerRect.topLeft += minTranslationVector;

                toDraw += playerRect.isNegative;

                Position = playerRect.topLeft;
                BoundingBox = playerRect.ToRectangle();
            }

0 ответов

Другие вопросы по тегам