-
Notifications
You must be signed in to change notification settings - Fork 0
Physics RU
🌐 English · Русский
В Nova реализован настоящий движок физики твёрдых тел — единый решатель на импульсах со связями (последовательные импульсы / PGS по манифолду контактов, с прогревом, трением, трением качения, упругостью, позиционной коррекцией split-impulse и засыпанием островов). Даёт правдоподобную гравитацию с углом падения, инерцией, качением, отскоком, вращением, устойчивыми стопками и естественным кувырканием — а не скриптовое падение.
Два главных переключателя уровня мира, оба задаются при создании мира (и редактируются в JSON — см. Формат мира):
Главный выключатель твёрдых объектов.
- Игрок — вертикальная капсула с реальным ростом тела: его выталкивает из пола и любого коллайдера, так что сквозь них нельзя пройти или пролететь, нельзя проскользнуть под низкий навес и нельзя проткнуть головой перекладину на уровне головы (точечный пузырь раньше проскакивал). Вдоль стен по-прежнему скользит без зацепа.
- Каждый меш может использовать быстрый AABB (бокс по мировым осям) или OBB — ориентированный бокс, плотно облегающий наклонённую форму (контакты бокс-бокс считаются полным 3D-тестом разделяющих осей).
- У каждого объекта свой флаг Collide; когда переключатель мира выключен, Collide у всех объектов принудительно выключается и блокируется.
Включает симуляцию:
- Игрок становится ходячим персонажем: гравитация тянет камеру вниз, она стоит на поверхностях, Space — прыжок, F1 переключает режим свободного полёта для постройки.
- Любой объект может включить Gravity — меши, примитивы, сферы, даже свет или платформа падают и ложатся на то, что под ними.
- Падающий шар сталкивается с реальной поверхностью, на которую падает — с настоящими треугольниками пирамиды / рампы / меша, а не с габаритным боксом — поэтому он скатывается по склону с настоящим импульсом (быстрее на крутом), доезжает до остановки на ровном и отскакивает по своей упругости. Падающий меш так же ложится на реальную поверхность под ним.
- Ящики лежат, скользят или опрокидываются на реальной поверхности — их не выбрасывает. Ящик, брошенный на рампу, ложится плашмя на склон и съезжает или скатывается по нему; его не выкидывает вбок (он сталкивается с настоящими треугольниками меша, а не с боксом). Скользит он или кувыркается — зависит от крутизны склона и трения: на пологом просто скользит, на крутой грани / будучи неустойчивым — переваливается через грань и катится с грани на грань — всё естественно из решателя.
- Всё сталкивается со всем, и ящики СТОПКУЮТСЯ. Ящики и шары сталкиваются в любых сочетаниях (ящик-ящик, шар-ящик, шар-шар), с учётом массы, так что башня из ящиков стоит устойчиво (без дрожи, крена и проваливания), а шар, влетевший в неё, разбрасывает башню — и затем вся куча успокаивается и засыпает вместе (как один остров).
- Произвольный меш падает как его НАСТОЯЩАЯ форма. Меш-объект с Gravity + Collide симулируется как его выпуклая оболочка — ложится и лежит на своих гранях, кувыркается и стопкуется как его реальный силуэт, а не как габаритный бокс, и ложится на реальные треугольники наклонного меша под ним. (Примитивы-«коробки» — куб, рампа, пирамида… — сохраняют более быстрый бокс-коллайдер, который и так совпадает с их формой. Вогнутый меш сталкивается как его выпуклая огибающая.)
- Трение качения — катящийся шар и кувыркающийся ящик замедляются и останавливаются, а не катятся вечно, при этом всё ещё скатываясь вниз по склону (гравитация сильнее малого сопротивления качению). Настраивается на каждый объект.
-
Упругость (Bounce / restitution) задаётся на весь мир (диалог создания) и на каждый объект:
0= мёртвая остановка,1= идеально упруго. На контакте упругости двух поверхностей комбинируются (среднее геометрическое), поэтому прыгучий шар на «мёртвом» полу ведёт себя иначе, чем на стене-«батуте». - Трение, масса и 3D-вращение — объекты теряют скорость на трении (Кулона + качения), тяжёлый объект сдвигается меньше (пер-объектная Mass), а удар не по центру заставляет тело кувыркаться — полное 3D-вращение с настоящим тензором инерции и кватернионной ориентацией без дрейфа.
- Симуляция дробится на под-шаги внутри, поэтому ведёт себя одинаково, рендерит ли терминал на 60 FPS или на нескольких, и имеет предохранители, чтобы ничего не улетало.
Шарниры связывают два объекта физической связью, решаемой в том же решателе, что и контакты, — поэтому связь держит под гравитацией, столкновениями и в стопках, без отдельного физ-пути. Заспавнить из редактора: пролистай тип спавна до joint и поставь (B); он появляется как линия-маркер между двумя точками-якорями, окрашенная по типу. Выбери его и листай Kind (N / M) — инспектор покажет поля этого типа:
- Ball-socket (голубой) — соединяет две точки-якоря вместе, оставляя вращение свободным (шар в гнезде). Хорош для маятников, цепей, звеньев рэгдолла.
-
Hinge (оранжевый, со штырьком оси) — дверь / люк: тела могут вращаться только вокруг одной общей оси (берётся в системе тела A, поэтому два по-разному повёрнутых тела всё равно вращаются вокруг одной чистой оси). Необязательные лимиты угла — диапазон-упор, показываемый в инспекторе как радианы с градусами (напр.
-1.57 (-90°)) — и мотор (тяга с ограничением момента к целевой скорости) вместе дают сервопривод. - Distance (зелёный) — держит два якоря на фиксированном rest length: жёсткий стержень по умолчанию или мягкая пружина (задай частоту + демпфирование), колеблющаяся к длине покоя.
Стороной шарнира может быть любой объект. Конец связи может быть динамическим телом, неподвижным миром (статическая точка-якорь, bodyId -1) или любым другим объектом — светом, камерой, статичным предметом или платформой. Нефизическая или статичная сторона работает как фиксированный/кинематический якорь: подвинь её в редакторе, и то, что на ней висит, поедет следом. Шарнир, у которого обе стороны статичны, неактивен (двигать нечего), и инспектор показывает статус каждого шарнира — active или inactive — <причина> (гравитация мира выключена, тело удалено или обе стороны статичны) — так что мёртвый шарнир никогда не загадка.
Collide (на каждый шарнир, по умолчанию выкл). Два тела шарнира по умолчанию не сталкиваются друг с другом, чтобы пара с якорями в центрах могла перекрываться, а связь и контакт не боролись. Включи JCollide для шарниров с якорями на гранях/рёбрах — например, настоящей цепи, звенья которой должны упираться, а не проходить друг сквозь друга.
Шарниры защёлкиваются вместе в момент авторинга (или при загрузке сохранённого мира), так что стартуют собранными; более поздняя правка в рантайме (пере-включение гравитации, смена тела, правка поля) вместо этого сходится динамически. Они интегрированы со сном (тело, которое тянет шарнир, не замирает в воздухе, а висящее в покое тело всё равно засыпает и просыпается при возмущении), принимают живые правки полей и сохраняют мировую позицию якоря при перепривязке на другое тело.
Шарниры сохраняются в мире (JSON) и синхронизируются в мультиплеере — подключившийся клиент их видит, а живые правки (спавн / изменение / удаление) едут пирам.
По задумке (не баги): сталкивающаяся пара шарнира может немного перекрыться при резком махе — решатель исправляет это за несколько шагов. А если растащить статические якоря так, что цепь на distance-связях не дотягивается (якоря дальше, чем сумма длин покоя стержней), стержни заметно растягиваются, пока не вернёшь достижимую расстановку — длина покоя это цель, а не предел прочности.
Попробуй всё это в сгенерированном мире Test Lab (maketestworld — см. Начало работы): маятник, стержень, пружина, дверь, мельница с мотором, сталкивающаяся цепь, качели на двух стержнях и люк.
Каждый объект несёт свои настройки (редактируйте их вживую в инспекторе или в JSON мира):
- Collide — является ли объект твёрдым (действует только при включённой коллизии мира).
- Gravity — притягивается ли объект вниз (действует только при включённой гравитации мира; по умолчанию выкл).
- Collider — форма коллайдера меша: AABB (быстрый бокс по мировым осям) или OBB (ориентированный бокс, поворачивается вместе с объектом, лучше для наклонённых/вытянутых форм).
-
Mass — масса в импульсном солвере (деф
1); тяжёлый объект меньше сдвигается при столкновении. -
Bounce (restitution) — 0–1;
-1наследует значение мира. На контакте упругости двух поверхностей комбинируются. -
Friction — коэффициент трения Кулона (μ, деф
0.5). -
RollFric — сопротивление трения качения (деф
0.05), чтобы катящийся шар / кувыркающийся ящик успокаивался.
Физика объектов считается у authority/solo, а полное состояние каждого сдвинутого тела — позиция, ориентация и скорость — транслируется клиентам, которые экстраполируют и плавно подводят к нему, поэтому падение, качение и кувыркание объектов синхронно видят все (а не «замороженными» между обновлениями); гравитация самого игрока считается локально у каждого участника, поэтому ничего не рассинхронизируется. См. Мультиплеер.