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

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

Страницы: 1 2 3 437 Следующая »
#15
12:14, 26 апр. 2018

vindast
ещё один способ, очень полезный для отладки. прими invInerta = 0 для обоих тел. это запретит вращение и позволит отладить хотя бы линейную часть импульса, можно буквально построчно отлаживать, потому что там значения получаются интуитивно понятные. когда это работает, можно вернуть вращение и отлаживать его.


#16
13:58, 26 апр. 2018

Так кажется, это я преодолел.

  float getLambda(TRigidBody* body1, vec3 n1, vec3 w1,
    TRigidBody* body2, vec3 n2, vec3 w2)
  {
    float a = dot(n1, body1->linearVelosity) + dot(w1, body1->angularVelosity) + dot(n2, body2->linearVelosity) + dot(w2, body2->angularVelosity);

    float b = dot(n1, n1) *  body1->invMass + dot(w1, w1) *  body1->invInertia + dot(n2, n2) * body2->invMass + dot(w2, w2) * body2->invInertia;

    return -a / b;
  }

  void solveCarWeelMove(TCar* car, TRigidBody* body2, vec3 axis)
  {
    vec3 n1 = axis;
    vec3 w1 = vec3(0);
    vec3 n2 = -axis;
    vec3 w2 = vec3(0);

    float l = getLambda(car, n1, w1, body2, n2, w2);

    if (l > 0)
    {
      car->linearVelosity += n1 * l * car->invMass;
      body2->linearVelosity += n2 * l * body2->invMass;
    }
       
  }

  void constJoint(TCar* car, TRigidBody* weel, float dT, vec3 contactPos)
  {
    //запрещаем двигаться колесу и машине друг относительно друго по всем трем осям машины
    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);



    /*Убераем расхождение 

    vec3 d = contactPos - weel->_pos;
    float x = length(d);

    if (x > 0)
    {
      vec3 dir = normalize(d);
      float corrcetionLambda = getCorrectionLambda(car, dir, vec3(0), weel, -dir, vec3(0), ERP * x);

      corrcetionLambda = x / (car->invMass + weel->invMass);

      if (corrcetionLambda > 0)
      {
        car->_pos += -dir * corrcetionLambda * car->invMass;
        weel->_pos += dir * corrcetionLambda * weel->invMass;
      }
    }*/

  }

#17
13:59, 26 апр. 2018

vindast
хорошо, теперь чини вращение

#18
18:46, 26 апр. 2018

Ничего не выходит.
Не могу понять как задать n1/2 и w1/2 что бы тела не вращались  друг относительно друга.

Suslik и тела рассоединяются если придать хоть одному вращение.

#19
(Правка: 18:49) 18:48, 26 апр. 2018

vindast
в случае с ball socket joint'ами на самом деле якобиан составить просто — это как три контакта с нормалями под 90 градусов. только они двунаправленные. то есть без условия if(lambda > 0)

#20
18:50, 26 апр. 2018
  float getLambda(TRigidBody* body1, vec3 n1, vec3 w1,
    TRigidBody* body2, vec3 n2, vec3 w2)
  {
    float a = dot(n1, body1->linearVelosity) + dot(w1, body1->angularVelosity) + dot(n2, body2->linearVelosity) + dot(w2, body2->angularVelosity);

    float b = dot(n1, n1) *  body1->invMass + dot(w1, w1) *  body1->invInertia + dot(n2, n2) * body2->invMass + dot(w2, w2) * body2->invInertia;

    return -a / b;
  }

  void solveMove(TRigidBody* body1, TRigidBody* body2, vec3 axis, vec3 pos)
  { 
    ///vec3 w1 = cross(normal, (contactPos - car->weel[i]->_pos));
    vec3 n1 = axis;
    vec3 w1 = vec3(0);
    vec3 n2 = -axis;
    vec3 w2 = vec3(0);

    float l = getLambda(body1, n1, w1, body2, n2, w2);

    if (l > 0)
    {
      body1->linearVelosity += n1 * l * body1->invMass;
      body2->linearVelosity += n2 * l * body2->invMass;

    }
       
  }

  void solveRotation(TRigidBody* body1, TRigidBody* body2, vec3 axis)
  {
 
    vec3 n1 = vec3(0);
    vec3 w1 = axis;
    vec3 n2 = vec3(0);
    vec3 w2 = -axis;  

    float l = getLambda(body1, n1, w1, body2, n2, w2);

    if (l > 0)
    {
      body1->angularVelosity += w1 * l * body1->invInertia;
      body2->angularVelosity += w2 * l * body2->invInertia;

      //body1->linearVelosity += n1 * l * body1->invMass;
      //body2->linearVelosity += n2 * l * body2->invMass;
    }

  }

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


/*
    //Убераем расхождение 

    vec3 d = contactPos - weel->_pos;
    float x = length(d);

    if (x > 0)
    {
      vec3 dir = normalize(d);
       
      float corrcetionLambda = x / (car->invMass + weel->invMass);

      if (corrcetionLambda > 0)
      {
        car->_pos += -dir * corrcetionLambda * car->invMass;
        weel->_pos += dir * corrcetionLambda * weel->invMass;
      }
    }*/

  }

По идее вот эти три строчки и есть бол-сокет

    solveMove(car, weel, car->xVector, contactPos);
    solveMove(car, weel, car->yVector, contactPos);
    solveMove(car, weel, car->zVector, contactPos);

#21
18:51, 26 апр. 2018

contactPos сейчас не используется.

#22
18:53, 26 апр. 2018

Suslik
> if(lambda > 0)
сейчас попробую

#23
18:57, 26 апр. 2018

Suslik
получилось что-то, теперь радиус вектор цм колеса - цм машины = const

void solveMove(TRigidBody* body1, TRigidBody* body2, vec3 axis, vec3 pos)
  { 

    vec3 n1 = axis;
    vec3 w1 = vec3(0);
    vec3 n2 = -axis;
    vec3 w2 = vec3(0);

    float l = getLambda(body1, n1, w1, body2, n2, w2);


    body1->linearVelosity += n1 * l * body1->invMass;
    body2->linearVelosity += n2 * l * body2->invMass;
       
  }

Сейчас попробую прилепить точку контакта в вычисления.

#24
19:04, 26 апр. 2018

Suslik
или задача эта для псевдоимпульса?

#25
2:53, 27 апр. 2018

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

#26
10:54, 27 апр. 2018

Suslik
> псевдоимпульс только разрешает разошедшиеся соединения. задача обычного
> импульсного солвера без псевдоимпульсов — не допустить расходждения.
vindast
> void solveMove(TRigidBody* body1, TRigidBody* body2, vec3 axis, vec3 pos)
> {
> ///vec3 w1 = cross(normal, (contactPos - car->weel[i]->_pos));
> vec3 n1 = axis;
> vec3 w1 = vec3(0);
> vec3 n2 = -axis;
> vec3 w2 = vec3(0);
>
> float l = getLambda(body1, n1, w1, body2, n2, w2);
>
> if (l > 0)
> {
> body1->linearVelosity += n1 * l * body1->invMass;
> body2->linearVelosity += n2 * l * body2->invMass;
>
> }
>
> }
Тогда мне надо перелопатить условие, что бы у них были одинаковые угловые скорости относительно оси.
Становится сложно.

#27
11:14, 27 апр. 2018

vindast
ты пытаешься изобрести const joint, который делается не совсем так. я бы советовал всё-таки сначала попробовать изобрести ball-socket.

#28
11:26, 27 апр. 2018

Suslik
> вообще-то пока вы воете про "каксложна", ОП в соседнем треде уже написал
> базовую импульсную физику
Э, да, не в тему я )
У меня позиция - не сделал продукт - сделали твои конкуренты и ты проиграл, ну или сделал слишком поздно и тоже проиграл. А велосипеды изобретать приходится нечасто.

#29
12:34, 27 апр. 2018

kvakvs
> У меня позиция - не сделал продукт - сделали твои конкуренты и ты проиграл, ну
> или сделал слишком поздно и тоже проиграл. А велосипеды изобретать приходится
> нечасто.
"продукт" в случае тем вроде этой — это инвестиции в собственные знания. написав такой велосипед, автор будет знать, как он работает и получит опыт. а не как принято взять physx и получить очередной match-3 с неумело примотанной физикой.

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