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

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

Страницы: 1 2 336 37 Следующая »
#0
(Правка: 19:38) 19:37, 25 апр. 2018

В общем, решил я что мой святой долг сделать честную подвеску для авто.
Но перед этим я решил подумать что мне для этого надо.
Мне нужен призматический, вращательный и цилиндрический джоинт.
Если в уравнения могу  (я наивно полагаю), а в то как передавать через них (через джоинты) силы и моменты я уже не могу.

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


#1
22:26, 25 апр. 2018

PhysX ?

#2
(Правка: 23:12) 23:11, 25 апр. 2018

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

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

#3
(Правка: 3:26) 3:25, 26 апр. 2018

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
вообще-то пока вы воете про "каксложна", ОП в соседнем треде уже написал базовую импульсную физику

#4
11:16, 26 апр. 2018

bykabak
> PhysX ?
Свой.
Suslik, то есть все что нужно это корректно учесть импульсы?

#5
11:22, 26 апр. 2018

vindast
> Suslik, то есть все что нужно это корректно учесть импульсы?
я не знаю, что ты этим хотел сказать, но да.

#6
11:24, 26 апр. 2018

kvakvs, я уже и так занимаюсь противоестественными совокуплениями с физикой.

#7
11:30, 26 апр. 2018

Suslik
> но да.
Ну ладно)

#8
(Правка: 11:58) 11:55, 26 апр. 2018

Попытка на мертво связать два тела приводит к их "развалу" при их падении на землю.
Либо я ошибся, либо нужно как-то учитывать силы, поскольку колесо должно создавать реакцию опоры при контакте с землей.

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);
  }

#9
(Правка: 11:57) 11:57, 26 апр. 2018

constJoint должен намертво связать два тела, если я не в чем не ошибаюсь.

#10
(Правка: 12:00) 12:00, 26 апр. 2018

vindast
ты видео на валенок снимал? я ничего не понял из-за качества.

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

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

#11
12:06, 26 апр. 2018

Suslik
> во-первых, у тебя в функции применения импульса никак не учитываются w1/w2.
Это точно косяк.  Как их учесть?

#12
12:07, 26 апр. 2018

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

#13
(Правка: 12:09) 12:08, 26 апр. 2018

vindast
для начала стоит для себя уяснить, что одна ограниченная степень свободы — это одна строка якобиана. и она однозначно определяется через n1, n2, w1, w2. если у тебя в солвере общего типа где-то всплывают величины вроде
> vec3 contactPos
это уже звоночек. в общем случае у джойнта нет понятия точки, к которой он "прикладывается". так что ищи, думай.

#14
12:12, 26 апр. 2018

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

Страницы: 1 2 336 37 Следующая »
ПрограммированиеФорумФизика