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

Помогите написать физический движок :) (33 стр)

Страницы: 132 33 34 3537 Следующая »
#480
(Правка: 18:48) 18:46, 7 янв. 2019

Добавил а / 2 и все заработало. Только теперь выходит что одно из колес может двигаться вдвое быстрее чем должно.
Я так понимаю что степень свободы дифференциала это отдельный джоинт, как я выше описывал.


#481
2:38, 8 янв. 2019

vindast
> Добавил а / 2 и все заработало
можно /2 добавить для удобства, да

> Только теперь выходит что одно из колес может двигаться вдвое быстрее чем должно.
лол а что дифференциал по-твоему должен делать?

#482
(Правка: 7:11) 7:08, 8 янв. 2019

Suslik
> лол а что дифференциал по-твоему должен делать?
А я и не знаю) Кроме того что он позволяет вращаться с разной скоростью. Я думал что колесо вращаться быстрее чем ось редуктора не может )

Я правильно все подсчитал?

#483
8:15, 8 янв. 2019

Вармстатинг с тренимем дружит или нет?

#484
9:33, 8 янв. 2019

vindast
> Вармстатинг с тренимем дружит или нет?
конечно

#485
(Правка: 10:04) 9:44, 8 янв. 2019

Suslik,  у меня возникла логическая проблема. На каждой итерации солвера просчитывается джоинт, который не дает телам дальше проваливаться друг в друга. Как аккумулировать тут лямбду вы расписывали в своей статье. Если эта лямбда > 0, то просчитывается джоинт трения.

Само решение джоинта трения сейчас выглядит так:

void solve(const float& normalImp)
  {
    solveFriction(normalImp, nFr11, wFr11, nFr12, wFr12);
    solveFriction(normalImp, nFr21, wFr21, nFr22, wFr22);
  }

__forceinline void solveFriction(const float& normalImp, const vec3& nFr1, const vec3& wFr1, const vec3& nFr2, const vec3& wFr2)
  {
    float a = dot(nFr1, _body1->_linearVelosity) + dot(wFr1, _body1->_angularVelosity) + dot(nFr2, _body2->_linearVelosity) + dot(wFr2, _body2->_angularVelosity);
    float b = dot(nFr1, nFr1) * _body1->_invMass + dot(wFr1, wFr1) * _body1->_invInertia + dot(nFr2, nFr2) * _body2->_invMass + dot(wFr2, wFr2) * _body2->_invInertia;
    float l = -a / b;

    l = min(abs(l) * _frictionKoef, normalImp * _frictionKoef) * sign(l);

    _body1->_linearVelosity  += nFr1 * l * _body1->_invMass;
    _body1->_angularVelosity += wFr1 * l * _body1->_invInertia;

    _body2->_linearVelosity  += nFr2 * l * _body2->_invMass;
    _body2->_angularVelosity += wFr2 * l * _body2->_invInertia;

  }
normalImp - не что иное как лямбда из джоинта, который не дает телам пролетать сквозь друга. Проблема в том, что он меняется от итерации к итерации. И не понятно как задать условие ограничителя трения, по тому что normalImp * _frictionKoef величина не постоянная и может сильно меняться от итерации к итерации.

ps: статью сейчас перечитал, и понял что я так в трении ошибся. Буду переделывать, но все равно вопрос про то как правильно тут аккумулировать лямбду остался.

#486
10:21, 8 янв. 2019

vindast
> normalImp - не что иное как лямбда из джоинта, который не дает телам пролетать
> сквозь друга. Проблема в том, что он меняется от итерации к итерации. И не
> понятно как задать условие ограничителя трения, по тому что normalImp *
> _frictionKoef величина не постоянная и может сильно меняться от итерации к
> итерации.
опять же, с вормстартингом всё просто — сравнивать надо с аккумулированным нормальным импульсом, потому что когда система сходится, он меняться перестаёт.

#487
8:10, 9 янв. 2019

У меня тут вопрос возник.
Допустим есть джоинт, у которого лямбда никак не ограничивается (на пример бол-сокет).
Как к нему вармстатинг прикрутить? так же как обычно, но никак не контролировать накопленный импульс?

#488
8:14, 9 янв. 2019

vindast
> так же как обычно, но никак не контролировать накопленный импульс?
да

#489
11:08, 10 янв. 2019

у меня снова проблема)

Не могу понять как ограничивать силу трения, если по двум направлениям разные коэффициенты трения.
(при моделировании шины)

Хелп.
Матиматический затык.

#490
11:24, 10 янв. 2019

vindast
брать больший, нет? Вот реально, ты уже 33 страницы брутфорсишь задачи. У тебя хоть какая-то логика есть? Ты за год не осилил ни миртича, ни бараффа? Ты задаешь вопрос. Суслик отвечает. Ты его брутфорсишь, а потом спрашиваешь дальше?

#491
(Правка: 12:23) 12:21, 10 янв. 2019

lookid
> брать больший, нет?
нет

vindast
> Не могу понять как ограничивать силу трения, если по двум направлениям разные
> коэффициенты трения.
если коэф. трения разный, то надо строить анизотропную модель трения. грубо говоря, если трение изотропное, то вектор силы трения ограничивается окружностью. если коэф.трения разные, то ограничиваться вектор будет эллипсом. проще всего перейти в систему координат(масштабированием двух осей трения), где ограничивающая кривая — опять же, окружность, пусть единичного радиуса. в этой системе координат ограничить трение и потом перевести обратно в мировую. аналогичным образом можно работать с тензором инерции в 3д, у которого известны собственные оси и моменты инерции относительно них в 3д: https://en.wikipedia.org/wiki/Moment_of_inertia#Principal_axes. для практики можешь сначала это реализовать.

хотя, если честно, то едва ли это особо важно при моделировании шин. но в качестве упражнения — полезно.

#492
(Правка: 13:09) 13:08, 10 янв. 2019

lookid, ну и зачем ты это высказал? Сам покажи что сделал. Машинку на джоинтах, которая хоть как-то едет я сделал. Да и статьи суслика вообще единственный полезный материал по теме.
За то что он от меня, такого нуба, не отвернулся отдельное спасибо, только вот зачем ты тут? Не хочешь помочь - иди мимо. Таких как ты здесь толпы, все эксперты просто во всем, а как показать результат - так его нет.
Suslik, буду думать. Ассиметричную инерцию надо делать все равно.

#493
15:23, 10 янв. 2019

трение тут насчитал.
Для обычного случая:

void solve(const float& normalImp) // normalImp > 0, _frictionKoef > 0
  {
    float l1, l2;

    computeLambda(l1, nFr11, wFr11, nFr12, wFr12);
    computeLambda(l2, nFr21, wFr21, nFr22, wFr22);
 
    float x = sqrt(l1 * l1 + l2 * l2) / _frictionKoef;

    if (x > normalImp)
    {
      float c = normalImp / x / _frictionKoef;

      l1 *= c;
      l2 *= c;
    }

    aplyLambda(l1, nFr11, wFr11, nFr12, wFr12);
    aplyLambda(l2, nFr21, wFr21, nFr22, wFr22);
  }

Для шин:

float x = sqrt(l1 * l1 / (kLong * kLong) + l2 * l2 / (kLateral * kLateral));

    if (x > NormalImp)
    {
      float c = NormalImp / x;
      l1 *= c / kLong;
      l2 *= c / kLateral;
    }

#494
16:41, 10 янв. 2019

vindast
примерно так должно быть, но более точно мне проверять лень. попробуй сам поподставляй крайние случаи вроде k1 = 0, k2 = inf и тому подобные.

Страницы: 132 33 34 3537 Следующая »
ПрограммированиеФорумФизика