Kolizja V2

This commit is contained in:
Pc
2025-01-19 01:35:24 +01:00
parent 1a85de2c23
commit 7d33f8a997
2 changed files with 126 additions and 135 deletions

View File

@@ -1,3 +1,4 @@
#pragma once
#include <iostream>
#include <chrono>
@@ -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;
}

250
main.cpp
View File

@@ -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<double> 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<Plot>& fences) {
static bool CheckAllFencesCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const std::vector<Plot>& 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<Plot>& fences) {
static void UpdateRover(const std::vector<Plot>& fences) {
// Przyspieszanie w przód
if (keyWPressed) {
velocity += acceleration;
@@ -256,23 +259,37 @@ void UpdateRover(const std::vector<Plot>& 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<std::pair<float, float>> 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<Plot>& fences) {
std::vector<Plot> 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<Plot> 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) {
void static RenderScene(void) {
// Ustawienie liczby próbek dla antyaliasingu
glfwWindowHint(GLFW_SAMPLES, 16); // 4x MSAA (Wielokrotne próbkowanie)
//float normal[3]; // Storage for calculated surface normal
// Włączenie antyaliasingu (MSAA)
glEnable(GL_MULTISAMPLE);
// Save the matrix state and do the rotations
// 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
glRotatef(Rotation, 0.0f, 1.0f, 0.0f); // Obrót łazika
glColor3f(1.0, 0.0, 0.0); // Czerwony kolor dla łazika
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();
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ń
glPopMatrix(); // Przywrócenie poprzedniej macierzy
glMatrixMode(GL_MODELVIEW); // Ustawienie trybu modelu-widoku
// Zamiana buforów (double buffering)
// 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