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

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

Страницы: 1 2 3 414 Следующая »
SuslikМодераторwww26 апр. 201812:14#15
vindast
ещё один способ, очень полезный для отладки. прими invInerta = 0 для обоих тел. это запретит вращение и позволит отладить хотя бы линейную часть импульса, можно буквально построчно отлаживать, потому что там значения получаются интуитивно понятные. когда это работает, можно вернуть вращение и отлаживать его.
vindastПостоялецwww26 апр. 201813:58#16
Так кажется, это я преодолел.
  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;
      }
    }*/

  }
SuslikМодераторwww26 апр. 201813:59#17
vindast
хорошо, теперь чини вращение
vindastПостоялецwww26 апр. 201818:46#18
Ничего не выходит.
Не могу понять как задать n1/2 и w1/2 что бы тела не вращались  друг относительно друга.

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

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

Правка: 26 апр. 2018 18:49

vindastПостоялецwww26 апр. 201818:50#20
  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);

vindastПостоялецwww26 апр. 201818:51#21
contactPos сейчас не используется.
vindastПостоялецwww26 апр. 201818:53#22
Suslik
> if(lambda > 0)
сейчас попробую
vindastПостоялецwww26 апр. 201818:57#23
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;
       
  }

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

vindastПостоялецwww26 апр. 201819:04#24
Suslik
или задача эта для псевдоимпульса?
SuslikМодераторwww27 апр. 20182:53#25
vindast
псевдоимпульс только разрешает разошедшиеся соединения. задача обычного импульсного солвера без псевдоимпульсов — не допустить расходждения.
vindastПостоялецwww27 апр. 201810:54#26
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;
>
> }
>
> }
Тогда мне надо перелопатить условие, что бы у них были одинаковые угловые скорости относительно оси.
Становится сложно.
SuslikМодераторwww27 апр. 201811:14#27
vindast
ты пытаешься изобрести const joint, который делается не совсем так. я бы советовал всё-таки сначала попробовать изобрести ball-socket.
kvakvsПостоялецwww27 апр. 201811:26#28
Suslik
> вообще-то пока вы воете про "каксложна", ОП в соседнем треде уже написал
> базовую импульсную физику
Э, да, не в тему я )
У меня позиция - не сделал продукт - сделали твои конкуренты и ты проиграл, ну или сделал слишком поздно и тоже проиграл. А велосипеды изобретать приходится нечасто.
SuslikМодераторwww27 апр. 201812:34#29
kvakvs
> У меня позиция - не сделал продукт - сделали твои конкуренты и ты проиграл, ну
> или сделал слишком поздно и тоже проиграл. А велосипеды изобретать приходится
> нечасто.
"продукт" в случае тем вроде этой — это инвестиции в собственные знания. написав такой велосипед, автор будет знать, как он работает и получит опыт. а не как принято взять physx и получить очередной match-3 с неумело примотанной физикой.
Страницы: 1 2 3 414 Следующая »

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

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