From cfb3f12ef455073e4d3723e1a78190f74510bc75 Mon Sep 17 00:00:00 2001 From: Pc Date: Thu, 16 Jan 2025 23:46:42 +0100 Subject: [PATCH] Kolizja z plotem --- Rover.cpp | 0 grafikaKBT.vcxproj | 1 + grafikaKBT.vcxproj.filters | 11 ++- main.cpp | 160 ++++++++++++++++++++++++++++--------- 4 files changed, 134 insertions(+), 38 deletions(-) create mode 100644 Rover.cpp diff --git a/Rover.cpp b/Rover.cpp new file mode 100644 index 0000000..e69de29 diff --git a/grafikaKBT.vcxproj b/grafikaKBT.vcxproj index 28784d3..8d5ad99 100644 --- a/grafikaKBT.vcxproj +++ b/grafikaKBT.vcxproj @@ -123,6 +123,7 @@ + diff --git a/grafikaKBT.vcxproj.filters b/grafikaKBT.vcxproj.filters index 2f91739..3bbb550 100644 --- a/grafikaKBT.vcxproj.filters +++ b/grafikaKBT.vcxproj.filters @@ -36,6 +36,15 @@ Source Files + + Source Files + + + Source Files + + + Source Files + @@ -65,4 +74,4 @@ Source Files - + \ No newline at end of file diff --git a/main.cpp b/main.cpp index 5ccf6ae..6f94d21 100644 --- a/main.cpp +++ b/main.cpp @@ -98,6 +98,7 @@ void LimitFPS(int targetFPS) { lastTime = std::chrono::high_resolution_clock::now(); } +bool Kolizja = false; bool keyWPressed = false; bool keySPressed = false; bool keyAPressed = false; @@ -112,46 +113,67 @@ float MoveSpeed = 1.0f; // Prędkość poruszania się float velocity = 0.0f; // Aktualna prędkość łazika -const float friction = 0.1f; // Współczynnik tarcia (μ) +const float friction = 0.05f; // Współczynnik tarcia (μ) const float maxSpeed = 3.0f; // Maksymalna prędkość łazika const float acceleration = 0.2f; + float rotationVelocity = 0.0f; // Prędkość obrotu łazika + const float rotationAcceleration = 0.1f; // Przyspieszenie obrotu const float rotationFriction = 0.05f; // Współczynnik tarcia obrotu const float maxRotationSpeed = 3.0f; // Maksymalna prędkość obrotu +// Struktura do reprezentacji płotu +struct Plot { + GLfloat xc; // Środek płotu w osi X + GLfloat yc; // Środek płotu w osi Y (nieużywane w kolizji, ale może być pomocne) + GLfloat zc; // Środek płotu w osi Z + GLfloat length; // Długość płotu + GLfloat gruboscY; // Grubość płotu + bool mod_x; // 0 - płot pionowy, 1 - płot poziomy +}; +// Funkcja sprawdzająca kolizję z płotem +// Funkcja sprawdzająca kolizję z płotem, uwzględniając wymiary łazika +bool CheckFenceCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const Plot& plot) { + if (plot.mod_x == 0) { // Płot pionowy (równoległy do osi Z) + float xMin = plot.xc - plot.gruboscY / 2.0f; + float xMax = plot.xc + plot.gruboscY / 2.0f; + float zMin = plot.zc - plot.length / 2.0f; + float zMax = plot.zc + plot.length / 2.0f; - -// Funkcja do poruszania łazikiem -void MoveRover(bool forward) { - // Zamieniamy kąt na radiany - float radRotation = Rotation * GL_PI / 180.0f; - - // Wektor ruchu w kierunku przód/tył (kierunek łazika) - float moveX = cos(radRotation); - float moveZ = sin(radRotation); - - // Ruch w przód - if (forward) { - Sides -= MoveSpeed * moveX; - Foward -= MoveSpeed * moveZ; + // Sprawdzenie, czy którykolwiek fragment łazika wchodzi w obszar płotu + if (roverXMax >= xMin && roverXMin <= xMax && // Kolizja w osi X + roverZMax >= zMin && roverZMin <= zMax) { // Kolizja w osi Z + return true; + } } - // Ruch w tył - else { - Sides += MoveSpeed * moveX; - Foward += MoveSpeed * moveZ; + else { // Płot poziomy (równoległy do osi X) + float xMin = plot.xc - plot.length / 2.0f; + float xMax = plot.xc + plot.length / 2.0f; + float zMin = plot.zc - plot.gruboscY / 2.0f; + float zMax = plot.zc + plot.gruboscY / 2.0f; + + // Sprawdzenie, czy którykolwiek fragment łazika wchodzi w obszar płotu + if (roverXMax >= xMin && roverXMin <= xMax && // Kolizja w osi X + roverZMax >= zMin && roverZMin <= zMax) { // Kolizja w osi Z + return true; + } } + return false; } -// Funkcja do obracania łazika wokół osi Y -void RotateRoverAndCamera(float angle) { - Rotation += angle; - if (Rotation >= 360.0f) Rotation -= 360.0f; - if (Rotation < 0.0f) Rotation += 360.0f; +// Funkcja ogólna do sprawdzania kolizji ze wszystkimi płotami +bool CheckAllFencesCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const std::vector& fences) { + for (const auto& fence : fences) { + if (CheckFenceCollision(roverXMin, roverXMax, roverZMin, roverZMax, fence)) { + return true; // Kolizja wykryta z którymś płotem + } + } + return false; // Brak kolizji } -void UpdateRover() { +void UpdateRover(const std::vector& fences) { // Przyspieszanie w przód if (keyWPressed) { velocity += acceleration; @@ -195,17 +217,77 @@ void UpdateRover() { } } - // Aktualizacja pozycji na podstawie prędkości - float radRotation = Rotation * GL_PI / 180.0f; - Sides -= velocity * cos(radRotation); - Foward -= velocity * sin(radRotation); + // Wyliczenie nowej pozycji na podstawie prędkości + float radRotation = Rotation * GL_PI / 180.0f; // Przeliczamy rotację na radiany + float newSides = Sides - velocity * cos(radRotation); // Nowa pozycja w osi X + float newFoward = Foward - velocity * sin(radRotation); // Nowa pozycja w osi Z - // Aktualizacja kąta obrotu - Rotation += rotationVelocity; - if (Rotation >= 360.0f) Rotation -= 360.0f; - if (Rotation < 0.0f) Rotation += 360.0f; + // Wyliczenie obszaru zajmowanego przez łazik + float roverXMin = newSides - 15.0f; + float roverXMax = newSides + 15.0f; + float roverZMin = newFoward - 15.0f; + float roverZMax = newFoward + 15.0f; + + // Sprawdzanie kolizji przed aktualizacją pozycji + if (Kolizja == true) { + if (CheckAllFencesCollision(roverXMin, roverXMax, roverZMin, roverZMax, fences)) { + // Jeśli jest kolizja, zatrzymujemy łazik + velocity = 0.0f; + cout << "Kolizja podczas ruchu\n"; + } + else { + // Jeśli brak kolizji, aktualizujemy pozycję + Sides = newSides; + Foward = newFoward; + } + + // Sprawdzanie kolizji podczas obrotu + if (rotationVelocity != 0.0f) { + // Wyliczamy narożniki łazika po obrocie + float newRotation = Rotation + rotationVelocity; + float radNewRotation = newRotation * GL_PI / 180.0f; + + // Wyliczamy offsety narożników w nowych współrzędnych + float offsetX = 15.0f * cos(radNewRotation); + float offsetZ = 15.0f * sin(radNewRotation); + + // Wyznaczamy nowe granice łazika + float rotatedXMin = Sides - offsetX; + float rotatedXMax = Sides + offsetX; + float rotatedZMin = Foward - offsetZ; + float rotatedZMax = Foward + offsetZ; + + // Sprawdzamy kolizję dla granic po obrocie + if (CheckAllFencesCollision(rotatedXMin, rotatedXMax, rotatedZMin, rotatedZMax, fences)) { + rotationVelocity = 0.0f; // Zatrzymujemy obrót w przypadku kolizji + cout << "Kolizja podczas obrotu\n"; + } + else { + // Aktualizujemy rotację tylko, jeśli nie ma kolizji + Rotation = newRotation; + if (Rotation >= 360.0f) Rotation -= 360.0f; + if (Rotation < 0.0f) Rotation += 360.0f; + } + } + } + else { + // Jeśli kolizje są wyłączone, aktualizujemy wszystko bez sprawdzania + Sides = newSides; + Foward = newFoward; + Rotation += rotationVelocity; + if (Rotation >= 360.0f) Rotation -= 360.0f; + if (Rotation < 0.0f) Rotation += 360.0f; + } } + +std::vector fences = { + {-10.0f, 3.0f, 45.0f, 130.0f, 4.0f, 0}, + { 50.0f, 3.0f, -20.0f, 120.0f, 4.0f, 1}, + {110.0f, 3.0f, 45.0f, 130.0f, 4.0f, 0}, + { 50.0f, 3.0f, 110.0f, 120.0f, 4.0f, 1} +}; + // Change viewing volume and viewport. Called when window is resized void ChangeSize(GLsizei w, GLsizei h) { GLfloat nRange = 100.0f; @@ -683,7 +765,7 @@ void plot(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat length, GLfloat gruboscY, //GLuint programID, VertexArrayID, MatrixID; lazik user(10.0f, 0.0f, 0.0f, "res/models/lazik4.obj"); // obiekty eksportujemy z Forward Axis Z, Up Axis Y. -plane mapa( 0.0f, 0.0f, 0.0f, "res/models/mapka3"); +plane mapa( 0.0f, 0.0f, 0.0f, "res/models/mapka3_nofence_noplatform.obj"); void SetupRC() { // Light values and coordinates @@ -817,7 +899,7 @@ void RenderScene(void) { Foward, 0.0f, Sides, // Punkt, na który patrzy kamera (łazik) 0.0f, 1.0f, 0.0f // Wektor "góry" ); - + // Rysowanie mapy (nie porusza się) glPushMatrix(); glColor3f(0.0, 1.0, 0.0); // Zielony kolor dla mapy @@ -827,12 +909,13 @@ void RenderScene(void) { // Rysowanie łazika (porusza się i obraca) glPushMatrix(); - + glTranslatef(Foward, 0.0f, Sides); // Translacja łazika na jego pozycję glRotatef(Rotation, 0.0f, 1.0f, 0.0f); // Obrót łazika wokół własnej osi glColor3f(1.0, 0.0, 0.0); // Czerwony kolor dla łazika + user.draw(); - UpdateRover(); + UpdateRover(fences); glPopMatrix(); //skrzynka(50); @@ -1266,6 +1349,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) polygonmode = !polygonmode; if (polygonmode) timestampedCout("Uwaga! Tryb wireframe jest niewydajny i powinien sluzyc tylko do debugowania!"); break; + case 'K': + Kolizja = !Kolizja; + break; case 'W': keyWPressed = true;