Каков наилучший способ обработки одновременных столкновений в физическом движке?

13

Я пишу 2D физический движок в javascript, чтобы я мог больше узнать о физике в видеоиграх. Он работает правильно для столкновений с твердым телом, за исключением случаев, когда любое тело сталкивается с двумя или более другими телами одновременно.

В настоящее время для каждой пары сталкивающихся тел (A, B) я изменяю их скорости и угловые скорости, основываясь на импульсе столкновения, и выталкиваю их друг от друга, чтобы они не проникали. Но тогда обнаружение столкновений и расчеты импульсов для других столкновений с участием A будут неправильными.

Какие подходы я могу исследовать, чтобы заставить мой двигатель работать на 3+ объектах, сталкивающихся друг с другом?

кулачок
источник
2
Связанные: gamedev.stackexchange.com/questions/15836/… и gamedev.stackexchange.com/questions/26181/… и я уверен, что это еще не все, я просто не могу найти прямо сейчас.
MichaelHouse

Ответы:

11

Я использую следующий подход (похожий на алгоритм массового расщепления Тонге http://www.richardtonge.com/ ):

  • обнаружить все сталкивающиеся пары в вашей сцене / контексте. Пусть (A, B) такая пара. Примените идею расщепления призрака / массы: если A контактирует с телами M, а B контактирует с N другими телами, тогда временно установите массу A на, m_A/Mа массу B наm_B/N
  • вычислить вклады силы реакции / восстановления для каждой пары (A, B) и сохранить эти вклады в собственных аккумуляторах A и B
  • Вычислите скорости восстановления из импульсов (как вы указали) и сохраните их таким же образом (как остатки скорости deltaV в их собственных аккумуляторах для каждой пары (A, B))
  • вычислять штрафные перемещения (опять же, накапливать перемещения, не применять их мгновенно!)
    • сбросить массы всех тел, ранее обозначенных как стороны в парах столкновений ( m_A = m_A * Mи m_B = m_B * N)

Этот подход аналогичен тому, как итерационный алгоритм Якоби работает с линейными одновременными системами уравнений. И не гарантируется сходство, но в моем симуляторе это делает работу довольно плавно ... в 3D (да, дополнительное измерение увеличивает вдвое сложность!).

Предостережение : исправляйте положения и скорости только после завершения фазы обнаружения / обработки столкновений! Таким образом вы одновременно обновляете своих сталкивающихся актеров. Кроме того, силы восстановления должны быть приняты во внимание в следующий раз, когда вы интегрируете позиции и скорости.

РЕДАКТИРОВАТЬ: Ну, я думаю, что вы используете уже используемый метод интеграции Verlet (этот стал нарицательным среди энтузиастов Gamedev). В этом спектре обработки столкновений и интеграции вы можете посмотреть здесь .

ОБНОВЛЕНИЕ: Некоторая информация о том, как приблизиться к столкновению (и собственно столкновению в этом отношении), может быть найдена в этих статьях:

Предложенный мною подход далеко не является оригинальным вкладом, многие игры используют его с правдоподобными результатами, и его лучше всего использовал Якобсен в своем игровом движке Hitman.

Исходя из некоторого практического опыта, штрафные силы (аналогичные линейным или экспоненциальным пружинам, получающим свои входные данные от расстояния проникновения) не могут должным образом разрешить проникновения, когда другие силы от сталкивающихся тел могут быть больше, чем они. Вот почему я решил объединить три (почти избыточных) подхода: ньютоновские силы реакции (вы толкаете стену, стена отодвигается назад), полученные из импульса скорости (столкновение шаров для снукера) и неестественное «геометрически отодвигают тела друг от друга» " решение. Вместе они, кажется, обеспечивают все: избавиться от большинстваУжасные артефакты взаимопроникновения, сталкивающиеся тела имеют тенденцию взаимодействовать друг с другом в долгосрочной перспективе (из-за скоростей и сил восстановления - по крайней мере, силы, которые имели тенденцию тянуть тела в сценарии столкновения, устраняются, и тела отскакивают друг от друга) , Наконец, для дальнейшего понимания этих простых, но общих концепций, я предлагаю проанализировать эти слайды .

Мой эпитет «метод злоупотребления», описывающий шаги интеграции Verlet, нацелен на убеждение популярной культуры, что это Святой Грааль методов интеграции. Это просто немного лучше, чем его кузен Симплектический Эйлер (также называемый некоторым неявным Эйлером). Существуют более сложные методы интеграции (и все они имеют неявное имя в них). Их используют мощные игровые движки, но у независимых разработчиков нет времени экспериментировать с ними, поскольку Verlet, настроенный на конкретный сценарий, действительно творит чудеса. Кроме того, нет абсолютно никакого метода интеграции, который мог бы справиться с жесткими ограничениями без небольшого обмана (не могу найти ссылку, но документ, на который я ссылаюсь, должен называться «X.Provot -» Деформационные ограничения в массе модель для описания поведения жесткой ткани "

teodron
источник
Спасибо (+1)! Что такое «скорость восстановления» и «смещение штрафа»? Кроме того, почему вы говорите, что интеграция верлетов «злоупотреблена»? Как вы думаете, это плохой метод для использования?
Cam
Скорости восстановления - это именно те скорости, которые вы получаете от импульсов, единственное отличие состоит в том, что я вычисляю их как остатки (т.е. я сохраняю разницу между этой скоростью на основе импульса и текущей скоростью, сохраняя текущую скорость нетронутой для дальнейших вычислений). Смещения штрафа - это векторы, длина которых определяется тем, насколько проникают два объекта, и именно вектор минимальной длины может полностью перевести один объект за пределы другого. Я обычно добавляю такое смещение к каждому объекту, деля длину на 2).
Теодрон
1
Блестящий ответ! У меня есть еще один вопрос. Скажем, я накапливаю скорости восстановления, разве они не составят очень нереалистичное число? Если я рассмотрю каждое столкновение с объектом А отдельно и просто добавлю эффекты на каждый объект, разве у А не будет свой импульс распространяться между объектами? Вместо этого полный импульс будет применен к каждому, что кажется мне интуитивно неправильным
Cam
Это очень хороший вопрос ... с одной точки зрения, кажется, что импульсы вносят дополнительный вклад в результирующую скорость. Вот мое (возможно, ошибочное!) Рассуждение: представьте, как сталкиваются три шара пула / снукера. Один из них должен получать взносы от двух других таким аддитивным способом. Первоначально я думал взвешивать эти вклады и вычислять средневзвешенное значение для конечной скорости, но так как я хотел быстрых результатов, я пропустил эту идею. В общем, сталкивающийся шар должен получить вклады в скорость от оставшихся двух. Возможно, учебник для старших классов может помочь.
Теодрон
3
Возможно, я не понимаю, что вы объяснили, потому что следующий пример все еще касается меня: представьте, что прямоугольник по горизонтали падает прямо вниз, и предположим, что пол неровный (так что состоит из нескольких соседних треугольников). Если есть n треугольников, используя ваш метод накопления, прямоугольник отскочит назад на n раз быстрее, чем должен! Как можно исправить эту ситуацию?
Cam
1

Я полагаю, что вместо изменения скоростей вы изменяете силы, действующие на объект. Не «подталкивайте» их, скорее делайте это плавно и используя уже существующий код. Делая это, тела не будут немедленно (и, я полагаю, быстро) изменять свои скорости.

Проверьте Box2DJS для примера: http://box2d-js.sourceforge.net/index2.html .

jcora
источник
-1

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

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

Изменить: Вероятно, я придумал что-то вроде этого /physics/296767/multiple-colliding-balls

Георгий Виноходов
источник