Этап 1: копия beamNG
Сначала мне стало интересно, можно ли сделать физику аналогичную beamNG? Вкратце расскажу как она работает:
Вся физическая модель состоит из свободно двигающихся в пространстве вершин (точек), соединенных балками (beam) с определенной жесткостью. Из них можно построить как жесткую структуру, например треугольник, так и подвижную - например лист из треугольников, будет вести себя как ткань. Каждая балка по сути пружина, стягивающая или расталкивающая пару вершин. Кузов авто можно смоделировать как множество соединенных точек в жесткую структуру. Толкаешь одну вершину - например ступицу колеса - она тянет за собой другие, те в свою очередь следующие и так далее, в следсвтие чего весь кузов приобретает импульс

Самое главное в этой системе - малый шаг интегрирования, всего 5 миллисекунд. Это делает физику стабильной, множество пружин не успевают "взорваться" за столь малый шаг, и вся система работает довольно хорошо.
Такую систему воспроизвести достаточно легко. Особенно учитывая что предок beamNG - rigs of rods - лежит в открытом доступе. Нет, я не копировал вслепую, но ИИ явно в курсе этого проекта, ведь он обучен на открытых исходников различных проектов
Но у такой системы есть недостаток - разрывы моделируются плохо. Балку можно разорвать при достижении порога силы. Но она удаляется целиком и фактически пропадает кусок физической модели. И что делать с графикой? Обычно в таком варианте в beamNG полигоны улетают в рандомную сторону, из-за чего графика треугольниками растягивается по экрану
Этап 2: shell материалы

Тут я вспомнил свою старую идею - моделировать материал не балками, а треугольниками. Их можно решать точно так же как и балки, только вместо двух точек будет три. К этому можно добавить усилия между двумя соседствующими через общее ребро два треугольника, не давать им сгибаться друг относительно друга, тем самым моделировать упругость листа материала. А так же отрывать треугольники друг от друга вдоль соседствующих ребер.
Таким образом мы можем получить изгибы и разрывы, без потери геометрии: изначальная площадь треугольников будет равна площади после разрыва.
Плюс к этому, для треугольников испытывающих значимое воздействие, можно делать тесселяцию: разделять один треугольник на несколько, чтобы детализировать модель в конкретном месте, что может делать разрывы еще реалистичнее, без потери производительности
А еще, к разрывам можно применять паттерны. Например, для стекла или пластика при контакте сразу делать "надрезы" в виде трещин и круговых повреждений вокруг точки контакта. Для дерева, например, делать разрыв вдоль волокон легче, чем поперек

В целом такой подход позволяет неплохо моделировать листы из материала. То что нужно для физики авто, ведь по сути кузов автомобиля - это формированный листовой материал
Но у такой системы есть нюанс, она очень неточная и податливая. В beamNG для жесткости кузова делается множество хаков, добавляются балки дающие нужную жесткость тем или иным частям, нивелирую не очень точную физику. Здесь же точность становится еще меньше, и с ней просто не получается смоделировать жесткий кузов автомобиля.
Но есть еще одна старая идеа
Этап 3: FEM
Вообще-то реалистичные повреждения кузова уже умеют моделировать давно, их применяют в проектировании реальных автомобилей. Называется это finite element method (FEM), в которой подход фактически такой же как в beamNG, однако применяется совершенно другой решатель системы.

В beamNG он тупой и простой - решаем каждую балку как пружину, считаем силы, применяем их к точкам. Но точек много и связей тоже, на одну вершину может влиять множество пружин, и в какую сторону ее двигать? Ну, в какую-то подвинется, на следующем кадре еще, а так как шаг интегрирований всего 5 миллисекунд, система более-менее уравновешивается и работает правдоподобно
Более правильно, а точнее "точно", решать такие сложные системы - через системы уравнений, то есть через матрицы (атеншн, могут быть флешбеки из школы или института). В таком подходе вершина уже движется не "куда-то", а туда куда приводит решение системы уравнений.
Фактически, метод beamNG - это численный метод решения все тех же систем уравнений (каждая балка - уравнение). А численные методы фактически решают систему итерациями, и чем больше итераций, тем ближе решение к реальному. То есть в этот подход фактически заложена неточность
Подход FEM гораздо точнее, но и гораздо медленнее. Инженерное моделирование деформации кузова авто считается не один час. Это довольно точно получается, но явно не подходит под геймдев.
Но что если разительно уменьшить количество элементов кузова, и решить через систему уравнений (матрицы)? Кузов можно упростить и сделать что-то вроде трубчатой рамы, на который навешать рычаги подвески и гибкие, менее точные shell-листы
Этап 4: ээээксеприменты

Честно говоря, получилось плохо. По отдельности все отлично:
трубчатый каркас ведет себя реалистично, в том числе моделирование многорычажной подвески авто
shell-листы выглядят реалистично на изгиб и разрыв
Но все вместе выглядит как трубчатый каркас покрытый мокрыми салфетками. Прикрепленные листы легко разрушаются от перегрузок, очень заметно болтаются, и самая большая проблема: селф-колижн
Все друг в друга проникает, это выглядит не правдоподобно, а решить эту проблему очень дорого. Коллизии из мешей - самый сложный кейс поиска столкновений, ведь мы должны проверить пересечение каждой пары треугольников, а это огромное количество. Есть множество оптимизаций широкой фазы, оптимизирубющие проверки, но так как все треугольники очень близки - фактически мы делаем уйму проверок и это убивает перфоманс. При этом они все равно очень легко проникают друг в друга, ведь каждый треугольник рассматривается отдельно.
Хотя, в этом есть один неожиданный плюс - отрывать эты куски от авто получилось довольно залипательно. Есть в этом какая-то сатисфакция, прям как будто отрываешь клеенку от нового телевизора
Этап 5: еще пара идей
Я посмотрел на перфоманс FEM решателя, и подумал "а что если так моделировать и панели автомобиля"? Кроме балок так же добавить конечный элемент - треугольник. Да, это супер-тяжелые рассчеты, но их получилось распараллелить. Здесь круто что ИИ довольно хорошо это может оптимизировать и улучшить.
По сути мой подход был такой: профилируй сам, ищи узкие места сам, нужно вписаться в стабильные 60FPS. Черт, я конечно умею в оптимизации и смог бы сделать это сам, но как будто бы это не особо и нужно - ИИ отлично справился. Окей, это было не совсем так просто, и я ставил более сложные условия, типа утилизации кеша процессора и уменьшение взаимных блокировок, но я думаю мистер клод это все знает и без меня
Так или иначе, получилось смоделировать кузов, подвеску, панели и бампера автомобиля полностью в FEM системе, при стабильных 60 FPS.
Для селф-колижена я применил тупой хак: добавил обьемные выпуклые внутренние формы кузова для коллизий. Подкапотное пространство, салон, багажник - просто не дают точкам полигонов проинкать в них, и распределяют усилие на опорные точки этого объема. Так как форма выпуклая, а проверяем только точки (три вершины и один центр) - это работает супер-быстро и простое. Таким образом отвалившийся бампер не проваливается внутрь под днище, а открывшийся капот не падает прокручиваясь внутрь салона.
Ну и самое главное: это работает довольно точно и может моделировать разрывы. Здесь все так же применяется детализация при столкновении:
балки делятся на несколько, тем самым могут более реалистично гнуться
треугольники делятся на несколько, давая более точную форму разрыва
Поверх физической модели можно по аналогии beamNG натянуть графическую модель. Работает довольно просто, аналогично костным анимациям: вершины по расстояниям привязываются к ближайшим вершинам физической модели, учитывая позицию и вращение. Разрыв можно моделировать либо через исчезновение полигонов, либо через их тесселяцию
Отличный тест работы системы - разрубить машину огромным топором. Такого точно нет в beamNG!
Финальный результат
Стало ли это лучше физики beamNG? Честно скажу, и да и нет. Тест топора - показательный. А еще физика шасси немного точнее beamNG, тут я даже сделал отдельный элемент симулцяии колеса и шины авто. Думаю, это немного лучше физики колеса beamNG, где оно фактически моделируется как множество вершин с некоторыми хаками для коллизий и устойчивости.
С другой стороны, перфоманс на грани: физика столкновения двух автомобилей занимает 15-20 миллисекунд, что нормально для демки, но недопустимо много для реальной игры, где нужно обсчитывать еще кучу всего в игровом мире
Ну и самое главное - визуально два метода не отличить, и подход даже во многих ситуациях выглядит реалистичнее. Учитывая бюджеты кадра, это гораздо более лучший подход
Здесь лежит демо под mac os:
https://drive.google.com/file/d/16SjBebgNcFKsUPTdfPY67K0w-n1XX8GM/view?usp=sharing
Больше о разработке игр, движков и о разработке в целом в моем телеграм‑канале.