Ruch jednostajnie przyspieszony w OpenGL

0

Implementuję ruch obiektu sterowanego klawiszami w OpenGL.

Co działa: Jazda w przód i w tył bez skręcania
Co się sypie: Samo skręcanie i jazda, gdy obiekt jest skręcony

Po włączeniu programu mogę obracać obiektem bez przeszkód. Problem pojawia się wtedy, gdy:

  1. Pojadę naprzód lub do tyłu, a następnie obrócę - zmienia się jego położenie na osi X i Y
  2. Po obrocie próbuję jechać - obiekt zachowuje się dziwnie, a nawet jeździ jak w ruchu drgającym

Jak poprawnie zaimplementować ruch pojazdu?

#define FPS 30
#define PRZYSPIESZENIE 0.01f

struct obiekt
{
        GLfloat x;
        GLfloat y;
        GLfloat z;
        GLfloat a;
        GLfloat v;
};

// Tu tworzymy obiekt, wszystkie własności są zerami
struct obiekt bat = {0.0f,0.0f,0.0f,0.0f,0.0f};

void rysuj()
{
        glPushMatrix();
        glRotatef(bat.a, 0.0f, 1.0f, 0.0f);
        glTranslatef(bat.x, bat.y, bat.z);
        //dalsze rysowanie pominięto
}

void timer()
{
        if(GetAsyncKeyState('W') & 0x8000)
        {
                bat.v -= PRZYSPIESZENIE; //Jazda w przód
        }
        else if(GetAsyncKeyState('S') & 0x8000)
        {
                bat.v += PRZYSPIESZENIE; //Jazda w tył
        }
        else
        {
                bat.v *= 0.95; // Siła oporu
        }
        if(GetAsyncKeyState('A') & 0x8000)
        {
                bat.a += 0.1f; // Skręcamy w lewo - WAŻNY FRAGMENT
        }
        if(GetAsyncKeyState('D') & 0x8000)
        {
                bat.a -= 0.1f; // Skręcamy w prawo - WAŻNY FRAGMENT
        }
        bat.z += cosf(bat.a) * bat.v;  // Tu pewnie coś jest nie tak
        bat.x += sinf(bat.a) * bat.v;  // Tu pewnie coś jest nie tak
}
0

Aby poprawnie zasymilować skręcanie trzeba przynajmniej uwzględnić takie rzeczy jak masa, prędkość z kierunkiem, siła z kierunkiem, opór środowiska.
Opór - bo jeżeli naciśniesz w samochodzie gaz do dechy to nie będziesz mieć stałego przyspieszenia przez cały czas.

0

Wzory na obliczanie kierunku ruchu wydają się być dobre, więc nie wiem dlaczego tak się dzieje. Możesz nagrać kawałek filmu z tym dziwnym ruchem? Może osie X i Z powinny być na odwrót, nie wiem jak jest w OpenGL, ale w XNA jest jak teraz masz i działa.

A tak w ogóle na początku wspomniałeś...

  1. Pojadę naprzód lub do tyłu, a następnie obrócę - zmienia się jego położenie na osi X i Y

a w kodzie jest wyznaczanie tylko wartości na osiach X i Z, a nie Y, który jak domyślam się jest pionem.

0

Mi się wydaje, że tu: bat.z += cosf(bat.a) * bat.v; // Tu pewnie coś jest nie tak
powinno być bat.y, a nie bat.z, ponieważ powinieneś przesuwać obiekt względem osi y, a nie z

0

Przeanalizowałem sytuację na kartce i powinno być dobrze. Obiekt porusza się po osi Z, a skręca po osi X. Problem leży w funkcjach glRotatef() i glTranslatef() albo coś źle obliczam w funkcji timer(). Może obrót ma wpływ na przesunięcie, może nie zgadzają się jednostki (stopnie, radiany)? Tylko jeśli na początku przesunę obiekt, a potem obrócę, będzie on obrócony względem środka okna, a nie środka obiektu, czyli może wylądować w niepożądane miejsce.

Obiekt porusza się w środowisku wodnym, ale na razie nie implementuję wszystkich sił zgodnie z fizyką.

1 użytkowników online, w tym zalogowanych: 0, gości: 1