Гайд по динамичной деформации мешей в Godot
Если вы хотите, чтобы ваш меш при столкновении или при касании руками игрока вминался, гнулся или, проще говоря, деформировался, — этот гайд поможет это реализовать. Но прежде чем начать познавать магию Godot, прошу обратить внимание на игру Fullitro — разрабатываемую мною игру про гонки в открытом мире. Рекомендую посетить канал в ТГ и поддержать разработку:
Итак, предположим, есть точка столкновения/взаимодействия и импульс. Для удобства создадим функцию:
Для того, чтобы взаимодействовать с мешем нам понадобится специальный инструмент MeshDataTool, или сокращенно MDT. С помощью него можно редактировать вершины меша, цвет, положение, нормали и так далее. Создадим MDT:
Далее мы будем загружать в него surfaces, деформировать и загружать их в меш.
Изучите меш: если он содержит несколько поверхностей, то необходимо создать дополнительную ноду, в которой будет содержаться дубликат деформируемого меша. (Это необходимо из-за отсутствия в текущей версии функции удаления конкретных поверхностей меша). В нашем случае для усложнения задачи будет несколько поверхностей.
Дальнейший план работы программы:
- очищаем старые данные
- проходимся по каждой surface
- загружаем surface и редактируем вертексы
- отправляем изменения в наш меш-дубликат
- очищаем изначальный меш и загружаем меш из меша-дубликата
В случае, если у вас только одна поверхность, можете пропустить 2 и 4 пункты и сразу записывать изменения в исходный меш
Итак, назовем наш второй меш mdt_result. Перед началом деформации, нужно очистить данные этого меша:
Теперь будем проходить по каждой поверхности, загружать её в наш магический MDT и редактировать его там:
mdt.create_from_surface загружает поверхность меша в редактор MDT
Теперь проходимся по каждой вершине и вычитаем из неё импульс:
mdt.get_vertex(i) возвращает локальную позицию вершины в пространстве, impulse_coef - переменная, отвечающая на силу деформации, умножение на дистанцию до точки столкновения - смягчение деформации.
Также вы можете изменить цвет вертексов, нормали и прочие параметры (см. док. MDT Годота).
После редактирования необходимо отправить новый меш на исходный (если у вас одна surface) или на наш mdt_result (если у вас несколько surfaces):
Мы создали новый меш на основе исходного, "помяли" его, и теперь его нужно загрузить его вместо старого, "немятого":
Полный код функции выглядит так:
Для вызова функции рекомендую использовать мониторинг столкновений у RigidBody тел (Solver->Contact Monitor = true) и функции _integrate_forces.
Также, если потребуется добавить деформируемому мешу форму столкновений, используйте:
Удачи в воспроизведении этой магии!
Не судите строго, это мой первый пост на DTF.