Suslik
Насколько я понимаю, задача псевдо скоростей растолкать объекты не изменяя их скорости. Но ты в статье пишешь:
"интегрируем движение каждого тела для псевдоскоростей по закону pos += pseudoVelocity * timeStep;"
и хоть убей, но не понимаю как это растолкает объекты, т.к. timeStep значительно меньше 1 и в расчёте псевдо-скоростей никоим образом не участвует.
Аналогичные сомнения относительно расчётов lambda, она ведь также не учитывает шаг времени... или оно там как-то неявно учитывается исходя из глубины? %)
Про глубину спрашивал, т.к. в примере к статье увидел такое "float depth = (point2 - point1) * normal;" и вообще, пример мало общего со статьёй имеет %)
XProger
(point2 - point1) — расстояние между контактными точками, скалярно умножается на нормаль контакта, получается глубина
timeStep действительно значительно меньше единицы, но они и не должны за одну итерацию растолкаться. им как бы присваивается временная скорость, пропорциональная глубине, которая автоматически обнуляется, когда они расталкиваются. то есть они расталкиваются с вполне конечной скоростью, которую ты сам определяешь и результат такого интегрирования с измельчением шага по времени будет просто точнее, но быстрее они от этого расталкиваться не будут. если угодно, можно в правой части поставить величину не просто пропорциональную глубине, а ещё обратно пропорциональную шагу по времени, тогда они за один шаг по времени разъедутся, например на половину глубины проникновения и чем меньше шаг по времени, тем они это быстрее сделают. можно делать хоть так, хоть так, разницы особой нет.
Попробовал с псевдо-скоростями (по 10 раздельных иттераций для скорсоти и псевдо-скорости), в моей реализации вышло не намного лучше чем Baumgarte, стек разваливается. возможно виноват MPR т.к. при столкновении плашмёй там точка приложения сил явно скачет относительно центра фейса (бокса). Возможно я что-то не то делаю, возможно нужно прикладывать какие-то внешние силы типа сопротивления воздуха или типа того чтобы это раскачивание гасить. В данный момент вижу, как боксы выталкиваясь одним углом разворачиваются и влетают противоположным в землю, снова выталкиваются, так и прыгают с угла на угол.
Собрал небольшую демку того что у меня сейчас выходит
управление: поворот - мышь, перемещение - WASD, 1 - бокс, 2 - цилиндр, 3 - сфера, 4 - конус, 5 - капсула.
Существуют ли грязные хаки, чтобы это дрожание как-то убрать?
XProger
> при столкновении плашмёй там точка приложения сил явно скачет относительно
> центра фейса (бокса)
что значит точка? их должно быть как минимум 3. проблема, когда бокс выталкивается то одним углом, то другим, возникает, либо когда генерится слишком мало контактов, либо когда стоит слишком большой erp(то есть тела выталкиваются слишком резко). основной хак, которым это убирают — это ограничение сверху на скорость расталкивания, но прежде, чем его вводить, надо остальные параметры нормально выставить.
Suslik
> что значит точка? их должно быть как минимум 3. проблема, когда бокс
> выталкивается то одним углом, то другим, возникает, либо когда генерится
> слишком мало контактов,
Я кстати где-то читал пейпер, что можно на одном контакте. Но там как-то хитро через объемы пересечений нужно было модифицировать импульс. К сожалению я тогда не смог в ту математику, а сейчас тот пейпер тоже найти не могу.
Suslik
А как эти контакты собирать если MPR возвращает по минимальному расстоянию? Как описано в статье брать несколько саппорт-поинтов по кругу вокруг минимального?
XProger
много алгоритмов есть, чтобы сгенерировать contact manifold. я делаю так: http://www.gamedev.ru/code/articles/convex_collisions . bullet поворачивает сами геометрии и кастует gjk. есть persistent manifold, который накапливает контактные точки.
Реализовал кеширование точек контакта, рву их когда расстояние между ними становится больше какой-то эмпирической величины. Частично проблему решило, но остался лёгкий дрейф угловой скорости, который рвёт контактные точки со временем :)

Тема в архиве.