From 7d33f8a997198dd723d32906b27b042d31f57e2b Mon Sep 17 00:00:00 2001 From: Pc Date: Sun, 19 Jan 2025 01:35:24 +0100 Subject: [PATCH] Kolizja V2 --- FPSCounter.cpp | 3 +- main.cpp | 258 ++++++++++++++++++++++++------------------------- 2 files changed, 126 insertions(+), 135 deletions(-) diff --git a/FPSCounter.cpp b/FPSCounter.cpp index 5fd25eb..3c9baa7 100644 --- a/FPSCounter.cpp +++ b/FPSCounter.cpp @@ -1,3 +1,4 @@ +#pragma once #include #include @@ -13,7 +14,7 @@ public: // Aktualizujemy FPS co 1 sekundê if (elapsed.count() >= 1.0) { double fps = frameCount / elapsed.count(); - std::cout << "FPS: " << fps << std::endl; + std::cout << "FPS: " << fps << "\n"; frameCount = 0; lastTime = currentTime; } diff --git a/main.cpp b/main.cpp index 06b66e3..c2abc90 100644 --- a/main.cpp +++ b/main.cpp @@ -83,9 +83,10 @@ std::time_t monitormodehelper; //Zmienne do ruchu ##############################################^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FPSCounter fpsCounter; + static const int targetFPS = 144; // Celowany FPS //Fps counter -void LimitFPS(int targetFPS) { +static void LimitFPS(int targetFPS) { static auto lastTime = std::chrono::high_resolution_clock::now(); auto currentTime = std::chrono::high_resolution_clock::now(); std::chrono::duration elapsed = currentTime - lastTime; @@ -117,15 +118,17 @@ float MoveSpeed = 1.0f; // PrÄ™dkość poruszania siÄ™ float velocity = 0.0f; // Aktualna prÄ™dkość Å‚azika +float rotationVelocity = 0.0f; // PrÄ™dkość obrotu Å‚azika + + const float friction = 0.01f; // Współczynnik tarcia (μ) -const float maxSpeed = 3.0f; // Maksymalna prÄ™dkość Å‚azika +const float maxSpeed = 5.0f; // Maksymalna prÄ™dkość Å‚azika const float acceleration = 0.2f; -float rotationVelocity = 0.0f; // PrÄ™dkość obrotu Å‚azika const float rotationAcceleration = 0.075f; // Przyspieszenie obrotu const float rotationFriction = 0.1f; // Współczynnik tarcia obrotu -const float maxRotationSpeed = 1.5f; // Maksymalna prÄ™dkość obrotu +const float maxRotationSpeed = 1.0f; // Maksymalna prÄ™dkość obrotu // Struktura do reprezentacji pÅ‚otu struct Plot { @@ -139,7 +142,7 @@ struct Plot { // 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) { +static 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; @@ -168,7 +171,7 @@ bool CheckFenceCollision(float roverXMin, float roverXMax, float roverZMin, floa } // Funkcja ogólna do sprawdzania kolizji ze wszystkimi pÅ‚otami -bool CheckAllFencesCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const std::vector& fences) { +static 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 @@ -177,7 +180,7 @@ bool CheckAllFencesCollision(float roverXMin, float roverXMax, float roverZMin, return false; // Brak kolizji } -void UpdateRover(const std::vector& fences) { +static void UpdateRover(const std::vector& fences) { // Przyspieszanie w przód if (keyWPressed) { velocity += acceleration; @@ -256,23 +259,37 @@ void UpdateRover(const std::vector& fences) { float newRotation = Rotation + rotationVelocity; float radNewRotation = newRotation * GL_PI / 180.0f; - // Wyliczamy narożniki Å‚azika po obrocie - float offsetX = roverHalfWidthX * cos(radNewRotation) + roverHalfLengthZ * sin(radNewRotation); - float offsetZ = roverHalfLengthZ * cos(radNewRotation) + roverHalfWidthX * sin(radNewRotation); + // Obracamy narożniki Å‚azika + std::vector> corners(4); + corners[0] = { Sides - roverHalfWidthX, Foward - roverHalfLengthZ }; // Lewy dolny + corners[1] = { Sides + roverHalfWidthX, Foward - roverHalfLengthZ }; // Prawy dolny + corners[2] = { Sides - roverHalfWidthX, Foward + roverHalfLengthZ }; // Lewy górny + corners[3] = { Sides + roverHalfWidthX, Foward + roverHalfLengthZ }; // Prawy górny - // Wyznaczamy nowe granice Å‚azika - float rotatedXMin = Sides - offsetX; - float rotatedXMax = Sides + offsetX; - float rotatedZMin = Foward - offsetZ; - float rotatedZMax = Foward + offsetZ; + // Obracamy wszystkie narożniki + for (auto& corner : corners) { + float x = corner.first; + float z = corner.second; - // Sprawdzamy kolizjÄ™ dla granic po obrocie - if (CheckAllFencesCollision(rotatedXMin, rotatedXMax, rotatedZMin, rotatedZMax, fences)) { - rotationVelocity = 0.0f; // Zatrzymujemy obrót w przypadku kolizji + corner.first = Sides + (x - Sides) * cos(radNewRotation) - (z - Foward) * sin(radNewRotation); + corner.second = Foward + (x - Sides) * sin(radNewRotation) + (z - Foward) * cos(radNewRotation); + } + + // Sprawdzamy kolizjÄ™ na podstawie obróconych narożników + bool collisionDetected = false; + for (const auto& corner : corners) { + if (CheckAllFencesCollision(corner.first, corner.first, corner.second, corner.second, fences)) { + collisionDetected = true; + break; + } + } + + if (collisionDetected) { + rotationVelocity = 0.0f; // Zatrzymujemy obrót cout << "Kolizja podczas obrotu\n"; } else { - // Aktualizujemy rotacjÄ™ tylko, jeÅ›li nie ma kolizji + // Aktualizujemy rotacjÄ™, jeÅ›li nie ma kolizji Rotation = newRotation; if (Rotation >= 360.0f) Rotation -= 360.0f; if (Rotation < 0.0f) Rotation += 360.0f; @@ -293,6 +310,7 @@ void UpdateRover(const std::vector& fences) { + std::vector fences = { {-550.0f, 3.0f, 50.0f, 1310.0f, 4.0f, 0}, // 0 - pionowo { 50.0f, 3.0f, -600.0f, 1200.0f, 4.0f, 1}, // 1 - poziomo @@ -301,7 +319,7 @@ std::vector fences = { }; // Change viewing volume and viewport. Called when window is resized -void ChangeSize(GLsizei w, GLsizei h) { +void static ChangeSize(GLsizei w, GLsizei h) { GLfloat nRange = 100.0f; //GLfloat fAspect; // Prevent a divide by zero @@ -339,7 +357,7 @@ void ChangeSize(GLsizei w, GLsizei h) { // opis: Å‚aduje mapÄ™ bitowÄ… z pliku i zwraca jej adres. // WypeÅ‚nia strukturÄ™ nagłówka. // Nie obsÅ‚uguje map 8-bitowych. -unsigned char* LoadBitmapFile(char* filename, BITMAPINFOHEADER* bitmapInfoHeader) { +static unsigned char* LoadBitmapFile(char* filename, BITMAPINFOHEADER* bitmapInfoHeader) { FILE* filePtr; // wskaźnik pozycji pliku BITMAPFILEHEADER bitmapFileHeader; // nagłówek pliku unsigned char* bitmapImage; // dane obrazu @@ -396,7 +414,7 @@ unsigned char* LoadBitmapFile(char* filename, BITMAPINFOHEADER* bitmapInfoHeader return bitmapImage; } -void SetDCPixelFormat(HDC hDC) { +static void SetDCPixelFormat(HDC hDC) { int nPixelFormat; static PIXELFORMATDESCRIPTOR pfd = { @@ -424,7 +442,7 @@ void SetDCPixelFormat(HDC hDC) { SetPixelFormat(hDC, nPixelFormat, &pfd); } -void skrzynka(GLfloat k) { +static void skrzynka(GLfloat k) { glColor3d(0.8, 0.7, 0.3); @@ -477,7 +495,7 @@ void skrzynka(GLfloat k) { glEnd(); } -void platforma(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat xlen, GLfloat zlen) { +static void platforma(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat xlen, GLfloat zlen) { glColor3d(0.729, 0.91, 0.51); // jasnozielony, dla grass02.bmp glEnable(GL_TEXTURE_2D); @@ -499,7 +517,7 @@ void platforma(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat xlen, GLfloat zlen) { } -void stodola(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat krawedz) { +static void stodola(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat krawedz) { glEnable(GL_TEXTURE_2D); @@ -562,7 +580,7 @@ void stodola(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat krawedz) { } -void plot(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat length, GLfloat gruboscY, bool mod_x) +static void plot(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat length, GLfloat gruboscY, bool mod_x) { GLfloat grubosc = 1.0f; @@ -785,18 +803,21 @@ void plot(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat length, GLfloat gruboscY, 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_nofence_noplatform.obj"); -void SetupRC() { +static void SetupRC() { // Light values and coordinates - GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f}; - GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f}; - GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f}; - GLfloat lightPos[] = {50.0f, -100.0f, 50.0f, 1.0f}; - GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f}; + GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f }; + GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f }; + GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + // Multiple light positions (for light coming from all sides) + GLfloat lightPos1[] = { 50.0f, -100.0f, 50.0f, 1.0f }; // Light 0 position + GLfloat lightPos2[] = { -50.0f, -100.0f, 50.0f, 1.0f }; // Light 1 position + GLfloat lightPos3[] = { 50.0f, -100.0f, -50.0f, 1.0f }; // Light 2 position + GLfloat lightPos4[] = { -50.0f, -100.0f, -50.0f, 1.0f }; // Light 3 position glEnable(GL_DEPTH_TEST); // Hidden surface removal - glFrontFace(GL_CCW); // Counter clock-wise polygons face out - //glEnable(GL_CULL_FACE); // Do not calculate inside of jet // !!! znaczÄ…co poprawia wydajność + glFrontFace(GL_CCW); // Counter clockwise polygons face out glDepthFunc(GL_LESS); // Enable lighting @@ -806,9 +827,30 @@ void SetupRC() { glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); glLightfv(GL_LIGHT0, GL_SPECULAR, specular); - glLightfv(GL_LIGHT0, GL_POSITION, lightPos); + glLightfv(GL_LIGHT0, GL_POSITION, lightPos1); glEnable(GL_LIGHT0); + // Setup and enable light 1 + glLightfv(GL_LIGHT1, GL_AMBIENT, ambientLight); + glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuseLight); + glLightfv(GL_LIGHT1, GL_SPECULAR, specular); + glLightfv(GL_LIGHT1, GL_POSITION, lightPos2); + glEnable(GL_LIGHT1); + + // Setup and enable light 2 + glLightfv(GL_LIGHT2, GL_AMBIENT, ambientLight); + glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuseLight); + glLightfv(GL_LIGHT2, GL_SPECULAR, specular); + glLightfv(GL_LIGHT2, GL_POSITION, lightPos3); + glEnable(GL_LIGHT2); + + // Setup and enable light 3 + glLightfv(GL_LIGHT3, GL_AMBIENT, ambientLight); + glLightfv(GL_LIGHT3, GL_DIFFUSE, diffuseLight); + glLightfv(GL_LIGHT3, GL_SPECULAR, specular); + glLightfv(GL_LIGHT3, GL_POSITION, lightPos4); + glEnable(GL_LIGHT3); + // Enable color tracking glEnable(GL_COLOR_MATERIAL); @@ -820,11 +862,8 @@ void SetupRC() { glMaterialfv(GL_FRONT, GL_SPECULAR, specref); glMateriali(GL_FRONT, GL_SHININESS, 128); - // White background glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - // Black brush - //glColor3f(0.0, 0.0, 0.0); // Initialize GLEW timestampedCout("Inicjalizowanie GLEW..."); @@ -836,145 +875,95 @@ void SetupRC() { timestampedCout("Zainicjalizowano GLEW."); - // glfw3 jest w teorii niepotrzebny, ale może siÄ™ przydać - // do przepisania kodu na podobny do tego stÄ…d: - // https://github.com/opengl-tutorials/ogl/blob/master/tutorial07_model_loading/tutorial07.cpp + // Initialize GLFW3 timestampedCout("Inicjalizowanie GLFW3..."); if (!glfwInit()) { timestampedCout("Failed to initialize GLFW"); } timestampedCout("Zainicjalizowano GLFW3."); - // glGenVertexArrays(1, &VertexArrayID); - // glBindVertexArray(VertexArrayID); - - // ZaÅ‚aduj shadery - - // programID = LoadShaders("res/shaders/TransformVertexShader.vertexshader", "res/shaders/TextureFragmentShader.fragmentshader"); - // MatrixID = glGetUniformLocation(programID, "MVP"); - // user.passProgramID(programID); - - // ZaÅ‚aduj model z pliku .obj - + // Load models timestampedCout("Ladowanie modelu lazika..."); user.loadModel(); timestampedCout("Ladowanie modelu mapki..."); mapa.loadModel(); glfwSwapInterval(1); - - //glClearColor(0.0f, 0.0f, 0.4f, 0.0f); - } -void RenderScene(void) { - - - //float normal[3]; // Storage for calculated surface normal - // Save the matrix state and do the rotations +void static RenderScene(void) { + // Ustawienie liczby próbek dla antyaliasingu + glfwWindowHint(GLFW_SAMPLES, 16); // 4x MSAA (Wielokrotne próbkowanie) + + // Włączenie antyaliasingu (MSAA) + glEnable(GL_MULTISAMPLE); + + // Przywrócenie macierzy modelu i ustawienie obrotów glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glRotatef(zRot, 0.0f, 0.0f, 1.0f); - // gluLookAt( - // 0, 0, 0, // the position of your camera, in world space - // 0, 0, 0, // where you want to look at, in world space - // 0, 1, 0 // probably glm::vec3(0,1,0), but (0,-1,0) would make you looking upside-down, which can be great too - // ); - + // Ustawienie trybu rysowania wielokÄ…tów switch (polygonmode) { - case 1: - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - break; - default: - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + case 1: + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Rysowanie linii + break; + default: + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // WypeÅ‚nianie poligonów } - - - // Clear the screen + // Czyszczenie ekranu przed rysowaniem glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - // Use our shader - //timestampedCout("programID wynosi " << programID); - //glUseProgram(programID); - - // // Bind our texture in Texture Unit 0 - // glActiveTexture(GL_TEXTURE0); - // glBindTexture(GL_TEXTURE_2D, Texture); - // // Set our "myTextureSampler" sampler to use Texture Unit 0 - // glUniform1i(TextureID, 0); - //glLoadIdentity(); // Zresetowanie macierzy widoku - // - //############################################################################################ - //Sterowanie - //############################################################################################ + // Przywrócenie macierzy widoku gluLookAt( - Foward - 100.0f * sin((Rotation + 180.0f) * GL_PI / 180.0f), // Pozycja kamery wokół Å‚azika (w poziomie) - CameraHeight, // Wysokość kamery - Sides - 100.0f * cos((Rotation + 180.0f) * GL_PI / 180.0f), // Kamera wzdÅ‚uż osi X i Z - Foward, 0.0f, Sides, // Punkt, na który patrzy kamera (Å‚azik) - 0.0f, 1.0f, 0.0f // Wektor "góry" + Foward - 50.0f * sin((Rotation + 180.0f) * GL_PI / 180.0f), // Pozycja kamery + CameraHeight/4, // Wysokość kamery + Sides - 50.0f * cos((Rotation + 180.0f) * GL_PI / 180.0f), // Kamera wzdÅ‚uż osi X i Z + Foward, 0.0f, Sides, // Punkt patrzenia (Å‚azik) + 0.0f, 1.0f, 0.0f // Wektor "góry" ); - - // Rysowanie mapy (nie porusza siÄ™) + + // Rysowanie mapy glPushMatrix(); - glColor3f(0.0, 1.0, 0.0); // Zielony kolor dla mapy + glColor3f(0.0, 1.0, 0.0); // Zielony kolor platforma(50.0f, 0.0f, 45.0f, 600.0f, 650.0f); - //mapa.draw(); glPopMatrix(); - // Rysowanie Å‚azika (porusza siÄ™ i obraca) + // Rysowanie Å‚azika 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 - fpsCounter.update(); + glTranslatef(Foward, 0.0f, Sides); // Translacja Å‚azika + glRotatef(Rotation, 0.0f, 1.0f, 0.0f); // Obrót Å‚azika + glColor3f(1.0, 0.0, 0.0); // Czerwony kolor dla Å‚azika + user.draw(); UpdateRover(fences); + fpsCounter.update(); glPopMatrix(); - //skrzynka(50); - plot(-550.0f, 3.0f, 50.0f, 1310.0f, 4.0f, 0); // 0 - pionowo - plot(50.0f, 3.0f, -600.0f, 1200.0f, 4.0f, 1); // 1 - poziomo + // Rysowanie innych obiektów + plot(-550.0f, 3.0f, 50.0f, 1310.0f, 4.0f, 0); + plot(50.0f, 3.0f, -600.0f, 1200.0f, 4.0f, 1); plot(650.0f, 3.0f, 50.0f, 1310.0f, 4.0f, 0); plot(50.0f, 3.0f, 695.0f, 1200.0f, 4.0f, 1); - - - - // stodola(2.0f, 0.0f, -7.5f, 20.0f); stodola(10.0f, 0.0f, 2.0f, 40.0f); // Zamiana buforów (double buffering) - //glColor3f(1.0, 0.0, 0.0); - //user.draw(); - //glColor3f(0.0, 1.0, 0.0); - //mapa.draw(); - //glColor3f(0.0, 0.0, 0.0); - + // glfwSwapBuffers(window); // Przełączenie buforów + // glfwPollEvents(); // ObsÅ‚uga zdarzeÅ„ - // Zamiana buforów (double buffering) + glPopMatrix(); // Przywrócenie poprzedniej macierzy + glMatrixMode(GL_MODELVIEW); // Ustawienie trybu modelu-widoku - - // Swap buffers - //glfwSwapBuffers(window); - //glfwPollEvents(); - - //Wyrysowanie prostokata: - //glRectd(-10.0,-10.0,20.0,20.0); - - glPopMatrix(); // wymagane - glMatrixMode(GL_MODELVIEW); // zmniejsza zużycie GPU - - // Flush drawing commands - //glFlush(); + // Wymuszenie wykonania wszystkich rysunków + glFlush(); } + // If necessary, creates a 3-3-2 palette for the device context listed. -HPALETTE GetOpenGLPalette(HDC hDC) { +HPALETTE static GetOpenGLPalette(HDC hDC) { HPALETTE hRetPal = NULL; // Handle to palette to be created PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor LOGPALETTE* pPal; // Pointer to memory for logical palette @@ -1044,7 +1033,7 @@ HPALETTE GetOpenGLPalette(HDC hDC) { // Return the handle to the new palette return hRetPal; } -void CreateConsole() { +void static CreateConsole() { // Tworzenie nowej konsoli if (AllocConsole()) { // Przekierowanie standardowych strumieni do konsoli @@ -1062,7 +1051,7 @@ void CreateConsole() { int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { CreateConsole(); MSG msg; // Windows message structure - WNDCLASS wc; // Windows class structure + WNDCLASS wc{}; // Windows class structure HWND hWnd; // Storeage for window handle @@ -1253,6 +1242,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) // The painting function. This message sent by Windows // whenever the screen needs updating. case WM_PAINT: + LimitFPS(targetFPS); // Call OpenGL drawing code RenderScene(); @@ -1265,7 +1255,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) // Limit FPS // Uaktualniaj FPS - LimitFPS(targetFPS); // Ogranicz FPS + // Ogranicz FPS