Для каждой контактирующей пары мы уже вычислили точки соприкосновения, нормаль и глубину. Суммарный импульс складывается из массы тел и их скоростей. Импульс считается относительно точки контакта, учитывается угловое вращение. Представьте себе палку, которая быстро крутится в воздухе и удаляется концом обо что-то. Импульст такого удара явно зависит от скорости вращения, ведь центр может быть недвижим. Формул не будет, это скучно, и они есть в статьях выше. А здесь у нас легкое чтиво
Попробуем применить эти импульсы к каждой паре тел. В общем, если это сделать так, то в какой-то степени это даже будет работать. Тела будут отлетать друг от друга и весте себя правдоподобно... без гравитации и длительных взаимодействий друг с другом. Такая физика подойдет может быть для простого бильярда
Попробуем применить эти импульсы к каждой паре тел. В общем, если это сделать так, то в какой-то степени это даже будет работать. Тела будут отлетать друг от друга и весте себя правдоподобно... без гравитации и длительных взаимодействий друг с другом. Такая физика подойдет может быть для простого бильярда
Большие проблемы начинаются при длительном воздействии. Самый простой пример, и самый распространенный, как назло - это лежащее на полу твердое тело. Если тупо применять импульс, то оно в лучше случае остановится и немного залезет в пол. Но если сверху на него надавит другое тело, или даже стопка тел - они начнуть разъезжаться, проникать друг в друга и все разлетится к чертям
Тут две проблемы: точность рассчета импульсов в сложных противоречащих системах и проблема проникновения при интегрировании
Тут две проблемы: точность рассчета импульсов в сложных противоречащих системах и проблема проникновения при интегрировании
И тут выплывает факт, что 1/60 секунды - это довольно много в мире физики. Импульс может оказаться очень большой. А в сложных системах где на одно тело действуют противоположные импульсы, итоговый импульс может оказаться далек от реальности. Представьте ту самую кучу твердых тел, там ведь полны бардак в импульсах, они действуют в разные стороны
Плюс начинает проявляться эффект дрожания (jittering) - тела начинают дрожать, тк за 1/60 успевают перелететь нужно положение, из-за чего считается слишком большой импульс, что приводит снова к перелету в другую сторону, в итоге система не стабильна и вот так вот дрожит. Или вовсе взрывается, когда за 2-3 кадра импульсы нарастают в геометрической прогрессии и тела улетают в nan
Если вы вспомните старые игры, до массового распространения движков типа havok, physX, то вы вспомните все эти эффекты - физика в играх была либо любо глючная, либо никакая. Все из-за вот этой проблемы дискретности и применения импульсов. Это было еще где-то в начале 2000х годов. Но потом пришел Эрин Катто
Плюс начинает проявляться эффект дрожания (jittering) - тела начинают дрожать, тк за 1/60 успевают перелететь нужно положение, из-за чего считается слишком большой импульс, что приводит снова к перелету в другую сторону, в итоге система не стабильна и вот так вот дрожит. Или вовсе взрывается, когда за 2-3 кадра импульсы нарастают в геометрической прогрессии и тела улетают в nan
Если вы вспомните старые игры, до массового распространения движков типа havok, physX, то вы вспомните все эти эффекты - физика в играх была либо любо глючная, либо никакая. Все из-за вот этой проблемы дискретности и применения импульсов. Это было еще где-то в начале 2000х годов. Но потом пришел Эрин Катто
это чувак, который написал Box2D. Забавно, ведь это изначально была просто демка на GDC (Game Dev Conference), где она показывал свой подход к решению проблемы. Кстати вот его канал на ютубе.
Что же такого он привнес? Численные методы в решение проблемы сложных систем контактов в физических движках. По сути, коллизии в физдвижке - это система условий. Ее можно решить классически, загнав в огромные матрицы и посчитать. Но это весьма дорого в плане ресурсов - матрицы огромные и очень разреженные, в итоге умножаешь нули на нули.
Эрин Катто придумал применил простой способ - считать все контакты в несколько итераций. То есть не один раз, а раз так 6-8 за кадр. При этом тела все еще не движутся, просто на каждой итерации импульсы в контактах уточняются и приближаются к более правильному решению системы. Собственно, так и работают разные численные методы - вместо решения системы уравнений аналитически, мы решаем их итерационно, приближая ответ к верному все ближе и ближе.
На 6-8 итерации работы алгоритма точность схождения уже достаточная чтобы корректно симулировать физику. Пропадает эффект дрожания, стопка тел становится стабильной, куча не разъезжается. Остается еще одна проблема - тела проникают друг в друга
Что же такого он привнес? Численные методы в решение проблемы сложных систем контактов в физических движках. По сути, коллизии в физдвижке - это система условий. Ее можно решить классически, загнав в огромные матрицы и посчитать. Но это весьма дорого в плане ресурсов - матрицы огромные и очень разреженные, в итоге умножаешь нули на нули.
Эрин Катто придумал применил простой способ - считать все контакты в несколько итераций. То есть не один раз, а раз так 6-8 за кадр. При этом тела все еще не движутся, просто на каждой итерации импульсы в контактах уточняются и приближаются к более правильному решению системы. Собственно, так и работают разные численные методы - вместо решения системы уравнений аналитически, мы решаем их итерационно, приближая ответ к верному все ближе и ближе.
На 6-8 итерации работы алгоритма точность схождения уже достаточная чтобы корректно симулировать физику. Пропадает эффект дрожания, стопка тел становится стабильной, куча не разъезжается. Остается еще одна проблема - тела проникают друг в друга
Это можно решить наивно - придать телам чуть больший импульс, чтобы они как бы вылетели друг из друга. Ну, это работает окей в части случаев, когда глубина проникновения не большая. Ну а если большая, то импульс прикладывается неадекватно большой, и тело не вылазит, а вылетает с лютой скоростью в противоположном направлении. Думаю такой эффект вы тоже видели в некоторых играх
Эрин подошел к проблеме по-другому. Окей, нам нужно как-то вытащить тела друг из друга. При этом не разогнав их до скорости света. Окей, давайте сделаем отдельные импульсы, направленные чисто на расталкивание объектов, скорости которых будем обнуять каждый кадр. Ииии... это работает. Мы точно так же считаем дополнительный импульс, направленный на расталкивание тел, но он как бы действует только один кадр. Тела расталкиваются, но при этом не уетают - профит
Здесь стоит вспомнить про идентификацию точек контакта. Они должны быть одни и те же между разными кадрами симуляции. Это нужно для поддержания работы численного метода рассчета импульса. Начинать уточнения гораздо эффективнее не с нуля, а он предыдущего рассчитанного импульса, ведь он, вероятно будет такой же. Например, в стопке тел, которые стоят и не двигаются, импульсы между ними будут интуитивно одинаковые от кадра к кадру. Поэтому мы идентифицируем точки контакта от кадра к кадру
Эрин подошел к проблеме по-другому. Окей, нам нужно как-то вытащить тела друг из друга. При этом не разогнав их до скорости света. Окей, давайте сделаем отдельные импульсы, направленные чисто на расталкивание объектов, скорости которых будем обнуять каждый кадр. Ииии... это работает. Мы точно так же считаем дополнительный импульс, направленный на расталкивание тел, но он как бы действует только один кадр. Тела расталкиваются, но при этом не уетают - профит
Здесь стоит вспомнить про идентификацию точек контакта. Они должны быть одни и те же между разными кадрами симуляции. Это нужно для поддержания работы численного метода рассчета импульса. Начинать уточнения гораздо эффективнее не с нуля, а он предыдущего рассчитанного импульса, ведь он, вероятно будет такой же. Например, в стопке тел, которые стоят и не двигаются, импульсы между ними будут интуитивно одинаковые от кадра к кадру. Поэтому мы идентифицируем точки контакта от кадра к кадру
Теперь вкратце о трении. В целом, это те же импульсы, направленные перпендикулярно нормали контакта. А дальше все просто - коэф. трения, скольжения итп
итак, соберем все в кучу. У нас есть тела, они занимают какое-то положение в мире. У них есть параметры - масса, инерция и тп. У тел есть оболочка, или коллайдеры, с помощью которых мы понимаем как они сталкиваются.
Всю эту систему мы обновляем раз в какой-то промежуток времени, обычно это 1/60 секунды. Сначала двигаем тела в соответствии с их скоростями. Затем смотрим кто с кем столкнулся - отсеиваем очевидные НЕ пересечения в широкой фазе и уточняем точки контакта в узкой фазе. После этого в несколько итераций считаем импульсы между парами тел. Повторяем на следующем кадре
Всю эту систему мы обновляем раз в какой-то промежуток времени, обычно это 1/60 секунды. Сначала двигаем тела в соответствии с их скоростями. Затем смотрим кто с кем столкнулся - отсеиваем очевидные НЕ пересечения в широкой фазе и уточняем точки контакта в узкой фазе. После этого в несколько итераций считаем импульсы между парами тел. Повторяем на следующем кадре
движимые тела и недвижимые. Есть ящик, который ведет себя динамически, а есть земля, которая статична. Ее подвинуть нельзя. По сути это просто типы твердых тел, что отражается в рассчете импульсов. К статическим телам не применяется импульс, весь импульс уходит в динамическое тело
ограничения или джоинты. Применяется в физике авто для подвески, например. Или для ragdoll (трупаки), для симуляции суставов тела. Задают какие-то органичения для двух тел, как они могут двигаться друг относительно друг друга. По сути, история точно такая же что и в контактах, но немного по-другому. Решается теми же численными методами внутри солвера
Собственно, все это было придумано в начале 2000х, и по сути нифига не поменялось. Физдвижки уже пршли стадию борьбы и устаканились. Все юзают PhysX для трехмерной физики, и Box2D для 2D. Мир физики затух и не развивается, что меня печалит. Потому что я правда считаю что эта зона может дать сильный толчок в развитии картинки в игре, как бы странно это ни звучало
иии здесь на сцену выходят снова численные метолы (полезная штука, да?). В это раз мой герой это Томас Якобсен, работавший над физикой первого Hitman. О дааа, бородатые года, а можно было таскать гибкие трупаки по локации, растения огибали персонажа, шторы вели себя физично, и галстук (карл!) физично болтался на груди 47го. Такого и нынче то не часто встретишь
Вот его оригинальная статья про физику в хитмане
Вот его оригинальная статья про физику в хитмане
ориентация тел в пространстве, их вращение осуществляется через линейные движения вершин. По сути они крутятся друг от друга, удерживаются между собой связями.
самый интересный момент - это связи. Как их решать? Попробуем снова пойти от наивного решения проблемы, представим что это просто пружины. Но пружины пружинят, и тело из пружин скорее похоже на желе. А если сделать их очень твердыми пружинами? Тогда в рассчете получаются огромные скорости которые при интегрировании 1/60 секунды превращаются в огромные расстояния, и тела взрываются
самый интересный момент - это связи. Как их решать? Попробуем снова пойти от наивного решения проблемы, представим что это просто пружины. Но пружины пружинят, и тело из пружин скорее похоже на желе. А если сделать их очень твердыми пружинами? Тогда в рассчете получаются огромные скорости которые при интегрировании 1/60 секунды превращаются в огромные расстояния, и тела взрываются
Окей, есть еще второй подход, физика мягких тел, если вы еще не забыли. Мне лично он нравится даже больше чем физика твердых тел, потому что он просто прикольнее и в какой-то мере изящнее
где он применяется? Для всяких тканей или деформируемых тел. Например beamng - это физика магких тел. Выглядит круто и сложно, но на самом деле это все ппц просто до усрачки
где он применяется? Для всяких тканей или деформируемых тел. Например beamng - это физика магких тел. Выглядит круто и сложно, но на самом деле это все ппц просто до усрачки
Немного поподробнее про сами частицы. В версии Томаса используется интеграция Верле. В таком подходе у частиц нет скорости, вместо этого хранится предыдущая позиция на прошлом кадре. Следующая позиция на новом кадре рассчитывается как текущая позиция + дельта от предыдущей. Предыдущая перезаписывается. Таким образом каждая вершина представлена 2мя векторами - текущая и предыдущая позиции.
Здесь солвер обновляет текущие позиции вершин, что обновляет дельту от предыдущей позиции, и фактически влияет на скорость и направление движения. В сумме вся эта система работает так, что тела движутся довольно правдоподобно. Но, честно говоря, это нечестные расчеты, они не соответствуют реальности.
Трение и взаимопроникновения решаются просто сдвигом точки в нужном направлении. К сожалению, это дает порой плохие результаты, при сильном проникновении тела могут вылетать друг из друга с невероятно большой скоростью. В отличие от физики твердного тела это не так плохо выглядит, тк большая скорость "проникшей" точки уравновешивается другими точками, которые находятся снаружи
Здесь солвер обновляет текущие позиции вершин, что обновляет дельту от предыдущей позиции, и фактически влияет на скорость и направление движения. В сумме вся эта система работает так, что тела движутся довольно правдоподобно. Но, честно говоря, это нечестные расчеты, они не соответствуют реальности.
Трение и взаимопроникновения решаются просто сдвигом точки в нужном направлении. К сожалению, это дает порой плохие результаты, при сильном проникновении тела могут вылетать друг из друга с невероятно большой скоростью. В отличие от физики твердного тела это не так плохо выглядит, тк большая скорость "проникшей" точки уравновешивается другими точками, которые находятся снаружи
Что ж, подход удивительно похож на солвер их физики тведых тел - решаем систему связей не один раз, а раз 6-8 за кадр. Однако, тут все гораздо проще. Томас представил систему связей как систему бесконечно упругих пружин. И пришел к выводу, что с такими пружинами, две частицы мгновенно приходят в стабильное состояние и расстояние между ними равно целевому. Повторить 8 раз. Все.
Это безумно простая идея, безумно простой код, дающие огромнй потенциал для реализации всяких штук
Это безумно простая идея, безумно простой код, дающие огромнй потенциал для реализации всяких штук
здесь чуть сложнее проверка столкновений, тк сложно описать гибкое тело негибкой формой. Для кубов еще можно использовать примитивы, но для тряпок уже не получится. Здесь отлично ложится подход разбиения на сферы. Обычно можно каждую точку описать сферой и проверка столкновений выглядит весьма правдоподобной
Физика твердого тела - наиболее распространенный вид физики в играх. Это всякие ящики, машины, регдоллы и др. Можно делать разрушаемые или гибкие тела с помощью джоинтов. Пример с besiege выше - это физика твердого тела. Просто тел много, они маленькие и соединены множеством джоинтов. Джоинты могут разрушаться при достижении определенного порога импульса
итак, отличие от физики твердых тел в том, что физическое тело не описыается единой матрицей трансформации и оболочкой. Тело описывается набором точек и связей между ними. Например квадрат - это 4 точки и 2 треугольника. Каждая точка ведет себя как отдельное упрощенное твердое тело - у нее есть позиция, скорость, масса. Но нет вращения. Точки соединены связами, или балками (beam -> beam.ng). Цель связей проста - сохранять расстояние между точками. Ну или вести себя как пружина, или как эластичная связь - сокращаться под действием силы
В общем, все тела они похожи на такие балочные конструкции, а-ля металлические мосты из треугольнико или эйфелева башня. Три точки, соединенные связями в треугольник образуют твердое тело - треугольник нельзя сжать или деформировать при абсолютно упругих связях. Из треугольников можно делать жесткие формы, например квадрат - это 2 треугольник. А так же и деформируемые - тряпки, джоинты и тп.
в остальном это очень похоже на физику твердых тел:
- интегрируем положения точек
- ищем столкновения
- решаем ограничения связей
- применяем силы
- повторяем
В общем, все тела они похожи на такие балочные конструкции, а-ля металлические мосты из треугольнико или эйфелева башня. Три точки, соединенные связями в треугольник образуют твердое тело - треугольник нельзя сжать или деформировать при абсолютно упругих связях. Из треугольников можно делать жесткие формы, например квадрат - это 2 треугольник. А так же и деформируемые - тряпки, джоинты и тп.
в остальном это очень похоже на физику твердых тел:
- интегрируем положения точек
- ищем столкновения
- решаем ограничения связей
- применяем силы
- повторяем
Вот и разобрали оба подхода в физике. В реальности эти оба подхода комбинируются в одном движке, частицы мягких тел могут влиять на твердые тела посредством импульсов и наоборот. В итоге мы может делать весьма интересные комбинации