Таки добил я интеграцию угловой скорости. Оказалось, все правильно было, вармстартинг был нужен. С ним все заработало корректно. Позже закину видео столкновения двух кубиков с вармстартингом и без, может кому интересно будет.
MikeNew
не верю. я практически уверен, что оно выглядит нормально, потому что из-за вормстартинга они практически не вращаются, поэтому ошибка практически не накапливается, поэтому ты её просто не видишь.
Suslik
> не верю. я практически уверен, что оно выглядит нормально, потому что из-за
> вормстартинга они практически не вращаются, поэтому ошибка практически не
> накапливается, поэтому ты её просто не видишь.
Сам увидишь. Вся разница в коде будет только в том, что я буду отключать вармстартинг, обнуляя в солвере аккумулированный импульс (фрагмент кода будет). Домой доберусь, закину видео.
Suslik
> не верю. я практически уверен, что оно выглядит нормально, потому что из-за
> вормстартинга они практически не вращаются
Вот, смотри:
1. Вармстартинг отключен:
2. Вармстартинг включен:
Разница только в первой строчке:
//ptrCollisions->at(j).joints[i].accumulatedImpulse = 0; if (dV + ptrCollisions->at(j).joints[i].accumulatedImpulse < 0.0f) dV = -ptrCollisions->at(j).joints[i].accumulatedImpulse; ptrCollisions->at(j).joints[i].accumulatedImpulse += dV;
в первом случае она раскоменчена.
Интеграция скорости и через кватерион и через базис выглядит абсолютно одинаково для этих тестов.
Твое мнение?
MikeNew
оба расчёта должны выглядеть одинаково, если поставить много итераций солвера. warmstarting не может неправильный солвер сделать правильным, он только сходимость ускоряет.
Suslik
> оба расчёта должны выглядеть одинаково, если поставить много итераций солвера.
> warmstarting не может неправильный солвер сделать правильным, он только
> сходимость ускоряет.
Вчера нашел еще одну ошибку с псевдоскоростями у себя, и теперь действительно, оба расчеты выглядят одинаково.
И вообще, все работает отлично - бокс падает с ускорением свободного падения (9.8м/с) на вершину с поворотом (0,10,10) с высоты 10 метров и очень быстро успокаивается, контакты больше не стробят. Стак из четырех боксов ведет себя настолько хорошо, насколько хорошо может себя вести без трения (причем даже с errorReduction = 1.0f, что меня удивило).
Теперь очередь за трением.
Хотел вчера выложить видео похвастаться, но у Нвидии были проблемы с серверами и их shadowplay не работал.
Делаю трение.
Бесконечное трение получилось сразу, а с сухим трением возникли проблемы, причем какие-то странные - работает если отключить вармстартинг, и отключается вообще если вармтстартинг включен. Отладочная информация в обоих случаях одинакова, поэтому решительно непонятно почему не работает (трение решается сразу после решения нормали контактов):
Что здесь может быть не так?
Причем проблема кроется исключительно в normalLimiter.accumulatedImpulse (аккумулированые импульсы для трения не мешают, работают и когда включены и когда отключены)
MikeNew
> ptrCollisions->at(j).joints[i]
блин, как ты это сам-то читаешь? мало того, что у тебя джойнты гвоздями к коллиженами прибиты и почему-то двумя индексами индексуются, у тебя ещё везде эта двойная индирекция.
auto &joint = ptrCollisions->at(j).joints[i];
нельзя написать один раз?
у тебя весь код для limiter'ов дважды дублируется. то есть в нём любая ошибка встречается дважды и её надо дважды исправлять.
бери да руками проверяй трение. ставь коэф.трения 1.0, ставь бокс на площадку под углом 40 градусов и он должен на ней стоять, не съезжая. ставь на площадку под углом 50 градусов и он должен с неё ехать с ускорением.
> отключается вообще если вармтстартинг включен
а ты уверен, что вообще применяешь накопленные импульсы трения в начале работы солвера?
Suslik
> блин, как ты это сам-то читаешь? мало того, что у тебя джойнты гвоздями к
> коллиженами прибиты и почему-то двумя индексами индексуются, у тебя ещё везде
> эта двойная индирекция.
Здесь j - это индекс коллизии, i - индекс джойнта, принадлежащего этой коллизии.
Прибитые гвоздями к колиззии джойнты неплохо так сокращают количество вычислений при передаче накопленных импульсов в джойнты, потому и прибил.
Suslik
> а ты уверен, что вообще применяешь накопленные импульсы трения в начале работы
> солвера?
Да.
Edit: Запостил, и увидел что у меня там ошибка. :D
Suslik
> бери да руками проверяй трение. ставь коэф.трения 1.0, ставь бокс на площадку
> под углом 40 градусов и он должен на ней стоять, не съезжая. ставь на площадку
> под углом 50 градусов и он должен с неё ехать с ускорением.
Спасибо, буду пробовать.
Suslik
> а ты уверен, что вообще применяешь накопленные импульсы трения в начале работы
> солвера?
Пофиксил применение накопленных импульсов перед солвером, все заработало как надо.
MikeNew
> Здесь j - это индекс коллизии, i - индекс джойнта, принадлежащего этой
> коллизии.
чиво? каждому коллижену соответствует один джойнт, откуда у тебя их несколько взялось?
> > а ты уверен, что вообще применяешь накопленные импульсы трения в начале
> > работы
> > солвера?
> Да.
нет
Suslik
> чиво? каждому коллижену соответствует один джойнт, откуда у тебя их несколько
> взялось?
Я под коллижном понимаю столкновения двух тел, под джойнтом - контактную точку. Бокс и бесконечная плоскость - может быть четыре джойнта. Один коллижн - четыре джойнта. Или мы по разному понимаем термины.
MikeNew
то, что ты называешь коллиженом, называется contact manifold. солвер о них ничего знать не должен вообще, потому что чтобы он эффективно работал, необходимо ему дать минимальный объём данных для работы из соображений локальности доступа к данным, а если ему всякий шлак из collision detection'а тащить, то каждое обращение к памяти будет кешмиссом. да и с точки зрения архитектуры лучше системы как можно более независимыми делать.
Suslik
> то, что ты называешь коллиженом, называется contact manifold. солвер о них
> ничего знать не должен вообще, потому что чтобы он эффективно работал,
> необходимо ему дать минимальный объём данных для работы из соображений
> локальности доступа к данным, а если ему всякий шлак из collision detection'а
> тащить, то каждое обращение к памяти будет кешмиссом. да и с точки зрения
> архитектуры лучше системы как можно более независимыми делать.
Ясно, об этом не подумал. Ну вот так точно сделаю:
"auto &joint = ptrCollisions->at(j).joints;"
Результаты моих трудов. Есть вармстартинг, правильные тензоры инерции и сухое трение:
Много еще предстоит сделать, особенно в плане оптимизации, сначала буду делать острова и слипинг.
Да и про катящийся шар вопросы назревают, как и про террайн.
Хрен бы я что без вашей помощи сделал, спасибо всем кто отвечает на вопросы.
Тема в архиве.