Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Помогите написать физический движок :)

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

Страницы: 1 2 313 14 Следующая »
vindastПостоялецwww25 апр. 201819:37#0
В общем, решил я что мой святой долг сделать честную подвеску для авто.
Но перед этим я решил подумать что мне для этого надо.
Мне нужен призматический, вращательный и цилиндрический джоинт.
Если в уравнения могу  (я наивно полагаю), а в то как передавать через них (через джоинты) силы и моменты я уже не могу.

Помогите мне понять как я должен передавать силы через них?  И что делать с моментами?

Правка: 25 апр. 2018 19:38

bykabakПостоялецwww25 апр. 201822:26#1
PhysX ?
kvakvsПостоялецwww25 апр. 201823:11#2
Этот твой святой долг выльется в несколько дней честной траханины с физикой, с улётами автомобиля в космос и проваливанием в землю.
А так то одобряю, замечательное дело когда честная физика.

В физдвижке джойнт передаёт силы приложенные к подключенных к нему телам автоматически.
Ничего не нужно делать кроме как задать веса корректно всем частям модели и добавить вращение или силу нужным частям.

Правка: 25 апр. 2018 23:12

SuslikМодераторwww26 апр. 20183:25#3
vindast
> А как передавать силы через джоинт?
ты уже сам написал:
      body->angularVelosity = body->angularVelosity + cross(n * lambda, contactPos - body->_pos) * body->invInertia;
      body->linearVelosity = body->linearVelosity + n * lambda * body->invMass;

это и есть передача импульса lambda через джойнт. вопрос лишь в том, как корректно спроектировать нужный тебе джойнт(как построить для него n1, n2, w1, w2), чтобы он делал то, что тебе нужно.

bykabak
kvakvs
вообще-то пока вы воете про "каксложна", ОП в соседнем треде уже написал базовую импульсную физику

Правка: 26 апр. 2018 3:26

vindastПостоялецwww26 апр. 201811:16#4
bykabak
> PhysX ?
Свой.
Suslik, то есть все что нужно это корректно учесть импульсы?
SuslikМодераторwww26 апр. 201811:22#5
vindast
> Suslik, то есть все что нужно это корректно учесть импульсы?
я не знаю, что ты этим хотел сказать, но да.
vindastПостоялецwww26 апр. 201811:24#6
kvakvs, я уже и так занимаюсь противоестественными совокуплениями с физикой.
vindastПостоялецwww26 апр. 201811:30#7
Suslik
> но да.
Ну ладно)
vindastПостоялецwww26 апр. 201811:55#8
Попытка на мертво связать два тела приводит к их "развалу" при их падении на землю.
Либо я ошибся, либо нужно как-то учитывать силы, поскольку колесо должно создавать реакцию опоры при контакте с землей.

float solve(vec3 n1, vec3 w1, vec3 linearVelosity1, vec3 angularVelosity1, float invMass1, float invInertia1,
    vec3 n2, vec3 w2, vec3 linearVelosity2, vec3 angularVelosity2, float invMass2, float invInertia2,
    float erpXdepth = 0.0f)
  {
    float a = dot(n1, linearVelosity1) + dot(w1, angularVelosity1) + dot(n2, linearVelosity2) + dot(w2, angularVelosity2);

    float b = dot(n1, n1) * invMass1 + dot(w1, w1) * invInertia1 + dot(n2, n2) * invMass2 + dot(w2, w2) * invInertia2;

    return (erpXdepth - a) / b;
  }

  void solve(TRigidBody* body1, vec3 n1, vec3 w1, TRigidBody* body2, vec3 n2, vec3 w2, vec3 contactPos)
  {
    float lambda = solve(n1, w1, body1->linearVelosity, body1->angularVelosity, body1->invMass, body1->invInertia,
      n2, w2, body2->linearVelosity, body2->angularVelosity, body2->invMass, body2->invInertia);

    if (lambda > 0)
    {
      body1->angularVelosity = body1->angularVelosity + cross(n1 * lambda, contactPos - body1->_pos) * body1->invInertia;
      body1->linearVelosity = body1->linearVelosity + n1 * lambda * body1->invMass;

      body2->angularVelosity = body2->angularVelosity + cross(n2 * lambda, contactPos - body2->_pos) * body2->invInertia;
      body2->linearVelosity = body2->linearVelosity + n2 * lambda * body2->invMass;
    }

  }

  void solveCarWeelMove(TCar* car, TRigidBody* body2, vec3 axis)
  {
    vec3 n1 = axis;
    vec3 w1 = cross(n1, (car->weelContactPos - car->_pos));
    vec3 n2 = -axis;
    vec3 w2 = cross(n2, (car->weelContactPos - car->weel->_pos));

    solve(car, n1, w1, body2, n2, w2, car->weelContactPos);
  }

  void constJoint(TCar* car, TRigidBody* weel)
  {
    //запрещаем двигаться колесу и машине друг относительно друго по всем трем осям машины
    solveCarWeelMove(car, weel, car->xVector);
    solveCarWeelMove(car, weel, car->yVector);
    solveCarWeelMove(car, weel, car->zVector);
     
    //Запрещаем вращаться колесу и машине друг относительно друга по всем трем осям машины
    solve(car, vec3(0), car->yVector, weel, vec3(0),  -car->yVector, car->weelContactPos);
    solve(car, vec3(0), car->zVector, weel, vec3(0),  -car->zVector, car->weelContactPos);
    solve(car, vec3(0), car->xVector, weel, vec3(0), -car->xVector, car->weelContactPos);
  }

Правка: 26 апр. 2018 11:58

vindastПостоялецwww26 апр. 201811:57#9
constJoint должен намертво связать два тела, если я не в чем не ошибаюсь.

Правка: 26 апр. 2018 11:57

SuslikМодераторwww26 апр. 201812:00#10
vindast
ты видео на валенок снимал? я ничего не понял из-за качества.

во-первых, у тебя в функции применения импульса никак не учитываются w1/w2. во-вторых, рекомендую сперва сделать обыкновенный ball-socket joint, то есть сцепить тела за одну точку, не запрещая им вращаться. когда заработает, ограничивай больше степеней свободы.

вообще для начала стоит убедиться, что у тебя тела хотя бы независимо друг от друга нормально с землёй взаимодействуют.

Правка: 26 апр. 2018 12:00

vindastПостоялецwww26 апр. 201812:06#11
Suslik
> во-первых, у тебя в функции применения импульса никак не учитываются w1/w2.
Это точно косяк.  Как их учесть?
vindastПостоялецwww26 апр. 201812:07#12
Suslik
> вообще для начала стоит убедиться, что у тебя тела хотя бы независимо друг от
> друга нормально с землёй взаимодействуют.
Эта часть работает нормально, проверено, проблемы начинаются при попытке их соединить.
SuslikМодераторwww26 апр. 201812:08#13
vindast
для начала стоит для себя уяснить, что одна ограниченная степень свободы — это одна строка якобиана. и она однозначно определяется через n1, n2, w1, w2. если у тебя в солвере общего типа где-то всплывают величины вроде
> vec3 contactPos
это уже звоночек. в общем случае у джойнта нет понятия точки, к которой он "прикладывается". так что ищи, думай.

Правка: 26 апр. 2018 12:09

vindastПостоялецwww26 апр. 201812:12#14
На сколько я могу судить, лямбда вычисляется корректно, она не применяется как должна.
Страницы: 1 2 313 14 Следующая »

/ Форум / Программирование игр / Физика

2001—2018 © GameDev.ru — Разработка игр