Войти
ПрограммированиеФорумФизика

Физика "на пальцах" (комментарии) (22 стр)

Страницы: 118 19 20 21 22 23 Следующая »
#315
2:32, 2 окт. 2014

есть там такой параметр
            initialVelocityProjection = -(sphere2.velocity.mul(normal)-sphere1.velocity.mul(normal))*bounce-dampingScaled;
            initialVelocityProjection = initialVelocityProjection<0f?0f:initialVelocityProjection;
Спасибо за советы, буду думать дальше :)

#316
11:46, 21 окт. 2014

Вопрос про warmstarting. При небольшом стеке боксов все работает хорошо. Система довольно быстро сходится (несколько кадров), далее применяется warmstarting и в солвере используется одна итериация - применение вормстартинга заранее компенсирует действие силы тяжести и в солвере импульсы получаются близкими к нулю, поэтому выход. Если же количество боксов увеличить (например, 30 боксов, ровно стоящих друг на друге), то ситуация ухудшается... Тут несколько вопросов.
1. Наблюдаю картину, когда в течение нескольких кадров подряд количество точек контакта не меняется (для большей устойчивости использую Persistent Contact Manifold). При этом количество итераций в солвере очень странное (ставлю выход из солвера только по малости применямых импульсов). То они потихоньку уменьшаются, а потом происходит резкий скачок. Почему? Ведь точки сохраняются, вармстартинг для них всех применяется.
2. И потом, даже когда система вроде как сходится (число итераций начинает не превышать 10), но все равно после вормстартинга считается не одна итерация (как по идее должно быть при получении точного решения на прошлом шаге моделирования), а несколько (от 3 до 10). Почему это происходит? Включение/отключение стабилизации на сходимость почти не влияет. Обнуление коэффициента восстановления тоже.

#317
16:44, 21 окт. 2014

gammaray
warmstarting может вносить свои артефакты сходимости. если поставить слишком мало итераций для сходимости и warmstarting, то импульс в системе будет рассчитываться как бы с задержкой, что вызовет осцилляции. стек будет немного колебаться, будто резиновый. если увеличивать количество итераций, он будет жёстче. самый плохой для вормстартинга случай(на самом деле для любого солвера) - это если взять стек касающихся друг друга боксов и уронить с небольшой высоты.

также проверь, сохраняется ли количество контактных точек - если CD не достаточно чёткий, то контакты могут появляться/исчезать и точность солвера сильно упадёт.

#318
12:24, 22 окт. 2014

Suslik
Тут скорее второй случай. Количество их не меняется, т.к. я использую реализацию PCM из Bullet. Но может меняться (незначительно) их положение между кадрами. На линейной скорости при использовании вормстартинга это не сказывается, но сказывается (незначительно, но все же), на угловой. Не помню где, но по моему ты писал, что для большей устойчивости надо разрешать телам проникать на некоторую разрешенную глубину depthSkin. То есть псевдоскорости должны выталкивать только в случае deep > depthSkin. Но если в солвере ставить больше итераций, то обычные импульсы не дают проникать телам друг в друга. Как действовать в этом случае? Может коллизию не добавлять, пока глубина ее проникновения меньше depthSkin?

#319
16:58, 22 окт. 2014

gammaray
делай так:

dstVelocity = -bounce * currVelocity;
if(depth < skinDepth) dstVelocity -= skinVelocity; //константа
дело в том, что если ты будешь просто игнорить коллизии, пока у них глубина меньше порога, то и разницы никакой не будет.
#320
12:33, 23 окт. 2014

Suslik
Интересная идея, спасибо. Этот вычет skinVelocity надо делать всегда или только при контакте? Дело в том, что тогда при ударе это приведет к откачке энергии. Да и понятно, что после удара объекты разлетятся. То есть может здесь лучше действовать так?

dstVelocity = -bounce * currVelocity;
if(dstVelocity < contactVelocity) //случай перехода к контакту
    if(depth < skinDepth) dstVelocity = -skinVelocity
    else dstVelocity = 0
#321
16:34, 27 окт. 2014

Реализовал и потестировал. Возникло несколько вопросов.
1. Правильно я понимаю, что по сути skinVelocity - это та скорость, с которой объекты будут продолжать проникать друг в друга, пока не проникнут на глубину skinDepth?
2. Условие if(depth < skinDepth) означает, что эту скорость объекты будут иметь, пока не проникнут глубже skinDepth. Но в этом случае начинает работать стабилизация (псевдоскорости) и объекты начинают выталкиваться друг из друга. Это приводит к дрожанию. Потому что вначале объекты выталкиваются до глубины skinDepth. Условие if(depth < skinDepth) срабатывает снова (в идеале в этот момент после применения псевдоскоростей на предыдущем шаге моделирования depth = skinDepth), и объекты снова начинают проникать. И так до бесконечности. Может здесь ставить что-то типа условия if(depth < skinDepth*0.9) например?

#322
18:35, 27 окт. 2014

gammaray
> 1. Правильно я понимаю, что по сути skinVelocity - это та скорость, с которой
> объекты будут продолжать проникать друг в друга, пока не проникнут на глубину
> skinDepth?
да

gammaray
> 2. Условие if(depth < skinDepth) означает, что эту скорость объекты будут
> иметь, пока не проникнут глубже skinDepth. Но в этом случае начинает работать
> стабилизация (псевдоскорости) и объекты начинают выталкиваться друг из друга.
> Это приводит к дрожанию. Потому что вначале объекты выталкиваются до глубины
> skinDepth. Условие if(depth < skinDepth) срабатывает снова (в идеале в этот
> момент после применения псевдоскоростей на предыдущем шаге моделирования depth
> = skinDepth), и объекты снова начинают проникать. И так до бесконечности. Может
> здесь ставить что-то типа условия if(depth < skinDepth*0.9) например?
составляй уравнение на псевдоскорость вида
dstPseudovelocity = max(0.0f, depth - skinWidth) * erp;

#323
18:46, 27 окт. 2014

Suslik
> составляй уравнение на псевдоскорость вида
> dstPseudovelocity = max(0.0f, depth - skinWidth) * erp;
Так я точно так же и работаю с псевдоскоростями) И тогда возникает ситуация, что я описал выше

#324
18:51, 27 окт. 2014

можешь псевдоскоростями выталкивать на половину глубины контакта

#325
7:53, 22 мар. 2015

добавил в конец статьи пример с кодом

#326
12:48, 22 мар. 2015

Suslik
Круто!

Прошло более 1 года
#327
10:58, 28 сен. 2016

В прилигаемом коде сделал bouncy = 0.6 после этого появились постоянные колебания больших стеков ящиков. Как это побороть?

Скажу сразу, что мне необходим движек для 2d боксов выровненных по осям. Вращение из данного кода убрал. Но может для этого частного случая есть более лучший подход, чем адаптация кода из статьи, к примеру может лучше будет использовать position-based подход?

#328
11:11, 28 сен. 2016

Parfen Rogozhin
> В прилигаемом коде сделал bouncy = 0.6 после этого появились постоянные
> колебания больших стеков ящиков. Как это побороть?
можно сделать так: считать, что тела всегда теряют некоторую константную скорость при соударении, то есть вместо bounce * initialVelocityProjection считать примерно так: bounce * std::min(initialVelocityProjection - deltaVelocity, 0.0f), (знак и min/max выбирается в зависимости от того, как выбрана нормаль контакта).

Parfen Rogozhin
> Скажу сразу, что мне необходим движек для 2d боксов выровненных по осям.
если точность не слишком важна, гораздо проще было бы сделать http://www.gamedev.ru/code/articles/PositionBasedPhysics но если ты уже написал физику на импульсах, то это круче, потому что точнее и лучше контролируется. если тебе когда-то захочется использовать вращение, то кроме импульсов особо вариантов нету. если только частицы без вращения, то и position-based сойдёт.

#329
17:01, 28 сен. 2016
можно сделать так: считать, что тела всегда теряют некоторую константную скорость при соударении, то есть вместо bounce * initialVelocityProjection считать примерно так: bounce * std::min(initialVelocityProjection - deltaVelocity, 0.0f), (знак и min/max выбирается в зависимости от того, как выбрана нормаль контакта).

Ага, нашел это в коде и подкрутил - помогло. Тем не менее таки думаю position-based пилить, мне главное как проще и быстрее в работе - делаю онлайн 2d стрелялку.
Страницы: 118 19 20 21 22 23 Следующая »
ПрограммированиеФорумФизика

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