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

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

Страницы: 124 25 26 2737 Следующая »
#360
(Правка: 9:01) 9:00, 28 сен. 2018

vindast
> 2)Далее разрешить поворот еще вокруг оси аморта. Но есть вопрос как сделать сам
> рулевой механизм, по тому что просто поворот всего в лоб приведет к
> нестабильности.
Эту проблему я решил просто вращая ступицу, все ведет стабильно.

Пока буду переделывать силы трения в покрышке.


#361
18:20, 30 сен. 2018

vindast
у меня сейчас период очень бурного отдыха, отвечать быстро не смогу

#362
18:51, 30 сен. 2018

Suslik, я уже забеспокоился, вдруг случилось что. Я почти сделал все что планировал пока Вас не было, сам ))))))) Осталось только трение. Я его почти сделал, остался только боковой случай.

#363
(Правка: 19:33) 19:33, 30 сен. 2018

Suslik

у меня сейчас период очень бурного отдыха

Опять ловишь жуков ? :)
#364
11:28, 1 окт. 2018

Вроде все сделал кроме передней подвески.

Как видно хорошо передние колеса сходят с ума. Я сейчас просто снял ограничение кручения аморта спереди вокруг его оси.
Мне нужна подсказка, как бы правильно сделать поворот передних колес.

Чисто теоретически, уже можно сделать спереди макферсон с рулевой рейкой, а сзади "рессора" в виде простого аморта. Но думаю это нужно отложить до того момента когда все будет отлажено.
#365
(Правка: 17:02) 15:52, 1 окт. 2018

Починил переднюю подвеску, отбой ) Сделал поворот как глубина - угол поворота для псевдоскорости.

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

Сейчас такой вопрос.
Как сделать по уму систему коллизий?
Я так понимаю нужно курить сапортмапинг для обычных обычных объектов. Я вроде понял как с этим быть и пока буду пробовать сам сделать
систему коллизий на нем основанную. (пока только для бокса - для начала). Но как быть с дорогами? Сплайнами соответственно.

#366
(Правка: 18:39) 18:33, 3 окт. 2018

Не смог заимплементить gjk. Алгоритм никогда не выдает, что было найдено пересечение (почти никогда).
Делал по этой статье: https://gamedev.ru/pages/kesha/articles/gjk

Основной код:

void gjk(TOrientedBoundingBox* b1, TOrientedBoundingBox* b2, vector<vec3>& positions)
  {
    //Инициализирую точки симплекса какими-то значениями
    vec3 Simplex[4];

    Simplex[0] = getMinkovskyDifferens(b1, b2, vec3(0.0f, 1.0f, 0.0f));
    Simplex[1] = getMinkovskyDifferens(b1, b2, vec3(1.0f, 0.1f, 0.1f));
    Simplex[2] = getMinkovskyDifferens(b1, b2, vec3(0.4f, 0.0f, 1.0f));
    Simplex[3] = getMinkovskyDifferens(b1, b2, vec3(-1.0f, -1.0f, 0.4f));

    int IterationCount = 0;

    int id1, id2;  //Id вершин грани, на которой лежит ближняя к нулю точка. 
    vec3 MinPoint; //Содержит ближнюю к нулю точку симплекса

    while (true)
    {
      //Если симплекс содержит ноль то поиск закончен.
      if (isSipmlexContainsZeroPoint(Simplex))
      {
        cout << "Collision" << endl;
        break;
      }

//Ищу ближнюю к нулю точку симплекса.
      findClousestSimplexPointToZero(MinPoint, Simplex, id1, id2);

      vec3 v = getMinkovskyDifferens(b1, b2, -MinPoint);

      //Условие что экстремум в направелнии MinPoint (радиус-вектор) нарастает
      if (dot(v, MinPoint) <= 1.0f)
      {
        cout << "Not match" << endl;
        break;
      }
 
      //Ищу куда воткнуть новую точку из CSO
      for (int i = 0; i < 4; i++)
      {
        if (i != id1 && i != id2)
        {
          Simplex[i] = v;
          break;
        }
      }

      //Защита от переполнения. Почти всегда дает именно этот результат.
      IterationCount++;
      if (IterationCount > 10)
      {
        cout << "IterationCount overload" << endl;
        break;
      }
    }

  }
Код разности Минковского:
vec3 getMinkovskyDifferens(TOrientedBoundingBox* b1, TOrientedBoundingBox* b2, const vec3& dir)
  {
    return b1->getSupportPoint(dir) - b2->getSupportPoint(-dir);
  }
Ближняя к нулю точка в симплексе:
vec3 getNearToZeroPoint(const vec3& p1, const vec3& p2)
  {
    vec3 d = p2 - p1;
    vec3 r = vec3(0.0f) - p1;
    float t = clamp(dot(r, d) , 0.0f, 1.0f);

    return p1 + d * t;
  }

void computeMinPos(
    vec3& MinPoint,
    int& FirstPoint, 
    int& SecondPoint, 
    const vec3* Simplex3D,
    const int& id1,
    const int& id2
  )
  {
     vec3 tmpPos = getNearToZeroPoint(Simplex3D[id1], Simplex3D[id2]);

     if (length(MinPoint) > length(tmpPos))
     {
       MinPoint = tmpPos;
       FirstPoint = id1;
       SecondPoint = id2;
     }
  }

  void findClousestSimplexPointToZero(vec3& MinPoint, const vec3* Simplex3D, int& FirstPoint, int& SekondPoint)
  {
    MinPoint = getNearToZeroPoint(Simplex3D[0], Simplex3D[1]);
    FirstPoint = 0;
    SekondPoint = 1;

    computeMinPos(MinPoint, FirstPoint, SekondPoint, Simplex3D, 0, 2);
    computeMinPos(MinPoint, FirstPoint, SekondPoint, Simplex3D, 0, 3);
    computeMinPos(MinPoint, FirstPoint, SekondPoint, Simplex3D, 1, 2);
    computeMinPos(MinPoint, FirstPoint, SekondPoint, Simplex3D, 1, 3);
    computeMinPos(MinPoint, FirstPoint, SekondPoint, Simplex3D, 2, 3);

  }

Проверка на принадлежность точки (0) тетраэдру (симплексу) (есть подозрение что она не всегда правильно работает - на пример в случае складывания тетраэдра в плоскостную фигуру) :

bool isSipmlexContainsZeroPoint(vec3* Simplex)
  {
 
    vec3 Point = vec3(0.0f) - Simplex[0];

    float x = dot(Simplex[1] - Simplex[0], Point);
    float y = dot(Simplex[2] - Simplex[0], Point);
    float z = dot(Simplex[3] - Simplex[0], Point);

    return x >= 0.0f && x <= 1.0f &&
      y >= 0.0f && y <= 1.0f &&
      z >= 0.0f && z <= 1.0f;

  }

Сапортпоинты работают как должны.
Я думаю могу ошибаться во вставке новой точки в симплекс, нахождении ближний к нулю точки или же в проверке принадлежности нуля к тетраэдру симплекса.

Что я делаю не так?
Если есть годная статья на тему, то скиньте пожалуйста.
Третий день пошел как я с этим не могу разобраться.

#367
18:41, 3 окт. 2018

vindast
бери да отлаживай, в чём проблема-то. для многоугольников алгоритм сходится за 2-3 итерации, проведи эти итерации на листочке бумаги и сравни со своей программой.

#368
18:44, 3 окт. 2018

Suslik, есть вопрос с которым на бумажке не разобраться. По какому принципу нужно удалять точку из симплекса? Я оставляю ребро, к которому принадлежит точка с минимальной дистанцией до центра координат. Остаются две точки. Так вот какую откинуть и почему?

#369
20:18, 3 окт. 2018

vindast
В gjk надо на каждой новой итерации ты должен строить новый симплекс путьом взятия самой дальней точки с всех возможных направлений текущего симплекса.  Другими словами ты должен найти ближайшый симплекс с разницы минковского к началу координат , а потом с етого конечного симплекса берешь информацию о двух ближайшых симплексах с первого и второго тела и уже поним выщитиваешь две ближайшые точки по бариоцентрическими координатами !


vindast
> Остаются две точки. Так вот какую откинуть и почему?
Любую точку можеш удалять, видь одна и вторая точка лежать в плоскости относительно нормали ребра.  Только вот зачем?
Видь gjk должен найти два ближайшых симплекса с первого и второго тела , вереней ближайшый симплекс к началу координат с разницы минковского, а там уже есть информация про двух ближайшых  сисимплексах  и нормали . gjk сам по себе не даст две ближайшые точки от двух тел , то бишь минемальное  расстояние относительно двух тел , ну верней даст но далеко не во всех случаях . "Почти никогда" .
Так что надо так gjk+baryocentric !

P.S:  Конченое ребро это тоже симплекс , но просто у него какие-то две точки совпадают , это надо учитивать в бариоцентрических расчётах . И на всякий случай скажу правильный gjk работает только с наружы , так что придётся делать GJK-SAP или GJK-EPA ну или просто MPR

#370
(Правка: 11:33) 11:15, 4 окт. 2018

vindast
>По какому принципу нужно удалять точку из симплекса?
в симплексе остаются только те точки, которые образуют ближайшую к началу координат фичу: треугольник, ребро или точка. это для классического gjk, который понимает только не пересекающиеся геометрии. чтобы искать пересечение, нужен gjk-epa и там точки из симплекса удалять вообще не получится. либо можешь попробовать мой алгоритм (не знаю, может быть, его уже кто-то до меня придумывал, но я не нашёл).
так работает gjk в моих обозначениях, выжимка из диссера:
Изображение
самое главное в GJK — это критерий останова. я использовал такой:
Изображение
Изображение
так работает мой sgjk — расширение gjk на случай пресекающихся геометрий:
Изображение

werasaimon
опять лекарства забыл принять

#371
11:46, 4 окт. 2018

Suslik, спасибо. Сейчас буду читать.

#372
12:16, 4 окт. 2018

Кажется я вкурил что я не так делал. Надо не только по ребрам искать ближайшее расстояние, но и по самой грани.
Позже сяду, переделаю.

#373
12:36, 4 окт. 2018

Suslik
> который понимает только не пересекающиеся геометрии
А вот это не понятно. По идее он должен что-то найти если они пересекаются. То есть, если найдет симплекс к которому принадлежит начало координат, то пересечение есть, иначе нет.

gjk-epa (я чуть-чуть про него почитал) начинается с симплекса, которым закончился gjk, и должен вернуть область пересечения - контактную площадку.

Так же есть вопрос по оператору "+" - который возвращает выпуклую оболочку для множества. Так ведь симплекс должен быть из 4-х точек для трехмерного пространства. О какой выпуклой оболочке тогда идет речь? По идее даже если он сжался в одну точку, он должен оставаться вырожденным тетраэдром. Или я что-то не понимаю?

#374
13:54, 4 окт. 2018

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

Страницы: 124 25 26 2737 Следующая »
ПрограммированиеФорумФизика