Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Box2D: проблема с определением контакта с землёй для колеса

Box2D: проблема с определением контакта с землёй для колеса

Поделиться
DEN 3DПостоялецwww16 сен. 201714:24#0
Приветствую.

Решил создать игру с машинкой, используя Box2D.

Созал при помощи множества Edge-Shape объектов дорогу, создал саму
машинку из бокса и пары колёс и соединил всё это Wheel-джоинтами.

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

Создал класс Contact Listener с таким вот кодом внутри:

class MyContactListener : public b2ContactListener
{
   public:
     void BeginContact(b2Contact* contact)
   {
    b2Fixture* fixtureA = contact->GetFixtureA();
                b2Fixture* fixtureB = contact->GetFixtureB();
    b2Body* bodyA = fixtureA->GetBody();
                b2Body* bodyB = fixtureB->GetBody();

    if ((bodyA == groundBody && bodyB == Wheel1Body) || (bodyA == Wheel1Body && bodyB == groundBody))
    {
      wheel1Contacted = true;
    }

    if ((bodyA == groundBody && bodyB == Wheel2Body) || (bodyA == Wheel2Body && bodyB == groundBody))
    {
      wheel2Contacted = true;
    }

   };
  
     void EndContact(b2Contact* contact)
   {
    b2Fixture* fixtureA = contact->GetFixtureA();
                b2Fixture* fixtureB = contact->GetFixtureB();
    b2Body* bodyA = fixtureA->GetBody();
                b2Body* bodyB = fixtureB->GetBody();

    if ((bodyA == groundBody && bodyB == Wheel1Body) || (bodyA == Wheel1Body && bodyB == groundBody))
    {
      wheel1Contacted = false;
    }

    if ((bodyA == groundBody && bodyB == Wheel2Body) || (bodyA == Wheel2Body && bodyB == groundBody))
    {
      wheel2Contacted = false;
    }
   };
  
     void PreSolve(b2Contact* contact,const b2Manifold* oldManifold)
     {
    
     };

     void PostSolve(b2Contact* contact,const b2ContactImpulse* Impulse)
   {
   };
};

Ну и установил его экземпляр в качетсве листенера (world.SetContactListener()).

И получается такой неприятный эффект, что во время езды машинки по дороге - то есть контакт, то нет
контакта (и так быстро меняется с интервалом 0.5 - 0.7 сек.), хотя визуально в это время контакт с землёй
у обеих колёс есть.

От чего возникает такая проблема с нестабильностью контакта и как её решить?

Спасибо.

andrew911Постоялецwww16 сен. 201715:43#1
Возможно машина немного подпрыгивает, можно сделать сенсор чуть больше размера колеса и определять по нему
DEN 3DПостоялецwww16 сен. 201716:12#2
Меня осенило. У меня же дорога состоит из множества fixture-сегментов.
И поэтому, действительно, машина едет и переходит с сегмента на сегмент
и соответственно, с одним сегментом контакт прекращается, а со следующим - начинается.

Теперь думаю, как организовать проверку контакта с землёй при таком раскладе?

DEN 3DПостоялецwww16 сен. 201716:14#3
Пока на ум приходит - хранить массив состояний всех сегментов и обновлять его. И далее проверять -
если хоть с одним сегментом есть контакт - значит общий контакт есть.

Но блин, как-то громоздко выходит. Может, можно проще как-то?

SuperInoyПостоялецwww17 сен. 20172:45#4
DEN 3D
> Может, можно проще как-то?
Подсовывай для физики свой меш, вручную сделанный из окружающих машинку. :)

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

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