Как предотвратить новые столкновения в обход старых? (2D) - PullRequest
1 голос
/ 24 марта 2020

Я хотел бы создать свою собственную систему столкновений с полигонами в C ++. Есть статические c коллайдеры (никогда не двигаются, не могут быть нажаты) и динамические c (могут двигаться, могут ли никогда находиться внутри статических c коллайдеров.). Мой текущий подход:

for (auto &dyn : dynamicColliders) {
    for (auto &stat : staticColliders) {
        // "how deep" is any vertex of dyn inside of stat? Store that in t.
        //    Is dyn inside stat (0 <= t <= 1)? -> push dyn outside by t
        // not inside? -> next 2 lines
        // "how deep" is any vertex of stat inside of dyn? Store that in r.
        //    Is stat inside dyn (0 <= r <= 1)? -> push dyn outside by r.
    }
}

Вот пример того, что произошло:

https://youtu.be/XeGga98ZtUY

В основном, квадраты являются c объекты. Шестигранник динамический c. Теперь, когда шестиугольник сталкивается с нижним квадратом, он выталкивается в верхний квадрат. Однако верхний квадрат толкает шестиугольник обратно в нижний квадрат. (Теперь шаг физики завершен. Ложное нижнее столкновение больше не имеет смысла. Этот порядок происходит, потому что верхний квадрат является «самым новым» объектом столкновения)

Что я пробовал:

  1. Суммирование всех векторов "Pu sh" и добавление их в конце
  2. Полностью отмените движение на текущем шаге физики, если после столкновения с квадратом произошло столкновение.
  3. (Выше подход)

Результаты:

  1. Не сработало: шестигранник втолкнулся в нижний квадрат, с которым он не сталкивался раньше.
  2. На самом деле работает, но очень глючно. Я не могу скользить по квадрату, потому что он отменен.
  3. (см. Видео выше)

Как можно избежать обхода этого типа столкновения? Большое спасибо!

1 Ответ

1 голос
/ 24 марта 2020

Этот единый подход к обнаружению коллизий (к сожалению) не сработает. Поскольку он моделирует каждый объект в одной точке, где происходит столкновение, он не учитывает тот факт, что объект мог также столкнуться где-то еще, поэтому он не может двигаться или отскакивать в направлении, которое он пытается вытолкнуть sh.

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

Если вы также строите систему обнаружения (как это звучит из вашего вопроса), то вам понадобится эффективный алгоритм для картирования возможных точек столкновения в 2-мерном пространстве, вы, вероятно, хотите реализовать Поиск ближайших соседей с кд-дерево . Вы можете найти много библиотек C ++, чтобы сделать это для вас.

(Обратите внимание, что дерево kd теряет баланс при каждой вставке и удалении, поэтому у вас должно быть динамическое c дерево для ваших движущихся точек, которое периодически перебалансируется, и дерево c для ваших состояний c баллов, которые можно оставить в покое)

...