feat: new type of camera
fix: movement works like it should
This commit is contained in:
319
main.cpp
319
main.cpp
@@ -1,4 +1,4 @@
|
|||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#ifdef _MSC_VER // Check if MS Visual C compiler
|
#ifdef _MSC_VER // Check if MS Visual C compiler
|
||||||
# pragma comment(lib, "opengl32.lib") // Compiler-specific directive to avoid manually configuration
|
# pragma comment(lib, "opengl32.lib") // Compiler-specific directive to avoid manually configuration
|
||||||
# pragma comment(lib, "glu32.lib") // Link libraries
|
# pragma comment(lib, "glu32.lib") // Link libraries
|
||||||
@@ -115,6 +115,10 @@ float Foward = 45.0f; // Pozycja łazika w przód/tył
|
|||||||
float Sides = -45.0f; // Pozycja łazika w lewo/prawo
|
float Sides = -45.0f; // Pozycja łazika w lewo/prawo
|
||||||
float Rotation = 270.0f; // Rotacja łazika (w stopniach)
|
float Rotation = 270.0f; // Rotacja łazika (w stopniach)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const float MinDistance = 20.0f;
|
||||||
|
const float MaxDistance = 1000.0f;
|
||||||
float CameraHeight = 50.0f; // Wysokość kamery
|
float CameraHeight = 50.0f; // Wysokość kamery
|
||||||
float MoveSpeed = 0.5f; // Prędkość poruszania się
|
float MoveSpeed = 0.5f; // Prędkość poruszania się
|
||||||
|
|
||||||
@@ -134,202 +138,168 @@ float maxRotationSpeed = 0.5f; // Maksymalna prędkość obrotu
|
|||||||
|
|
||||||
// Struktura do reprezentacji płotu
|
// Struktura do reprezentacji płotu
|
||||||
struct Plot {
|
struct Plot {
|
||||||
GLfloat xc; // Środek płotu w osi X
|
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 yc; // Środek (nieużywany w 2D)
|
||||||
GLfloat zc; // Środek płotu w osi Z
|
GLfloat zc; // Środek płotu w osi Z
|
||||||
GLfloat length; // Długość płotu
|
GLfloat length; // Długość (dłuższy wymiar)
|
||||||
GLfloat gruboscY; // Grubość płotu
|
GLfloat grubosc; // Szerokość/Grubość (krótszy wymiar)
|
||||||
bool mod_x; // 0 - płot pionowy, 1 - płot poziomy
|
bool mod_x; // 0 - płot wzdłuż osi Z (pionowy), 1 - płot wzdłuż osi X (poziomy)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Funkcja sprawdzająca kolizję z płotem, uwzględniając wymiary łazika
|
static bool CheckFenceCollision(float rXMin, float rXMax, float rZMin, float rZMax, const Plot& plot) {
|
||||||
static bool CheckFenceCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const Plot& plot) {
|
float fXMin, fXMax, fZMin, fZMax;
|
||||||
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;
|
|
||||||
|
|
||||||
// Sprawdzenie, czy którykolwiek fragment łazika wchodzi w obszar płotu
|
if (plot.mod_x == 0) { // Płot pionowy (rozciąga się w osi Z)
|
||||||
if (roverXMax >= xMin && roverXMin <= xMax && // Kolizja w osi X
|
fXMin = plot.xc - plot.grubosc / 2.0f;
|
||||||
roverZMax >= zMin && roverZMin <= zMax) { // Kolizja w osi Z
|
fXMax = plot.xc + plot.grubosc / 2.0f;
|
||||||
return true;
|
fZMin = plot.zc - plot.length / 2.0f;
|
||||||
}
|
fZMax = plot.zc + plot.length / 2.0f;
|
||||||
} else {
|
} else { // Płot poziomy (rozciąga się w osi X)
|
||||||
|
fXMin = plot.xc - plot.length / 2.0f;
|
||||||
|
fXMax = plot.xc + plot.length / 2.0f;
|
||||||
|
fZMin = plot.zc - plot.grubosc / 2.0f;
|
||||||
|
fZMax = plot.zc + plot.grubosc / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// Płot poziomy (równoległy do osi X)
|
// Standardowy test nakładania się prostokątów (AABB vs AABB)
|
||||||
float xMin = plot.xc - plot.length / 2.0f;
|
return (rXMax >= fXMin && rXMin <= fXMax &&
|
||||||
float xMax = plot.xc + plot.length / 2.0f;
|
rZMax >= fZMin && rZMin <= fZMax);
|
||||||
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 ogólna do sprawdzania kolizji ze wszystkimi płotami
|
static bool CheckAllFencesCollision(float rXMin, float rXMax, float rZMin, float rZMax, 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) {
|
||||||
for (const auto& fence: fences) {
|
if (CheckFenceCollision(rXMin, rXMax, rZMin, rZMax, fence)) {
|
||||||
if (CheckFenceCollision(roverXMin, roverXMax, roverZMin, roverZMax, fence)) {
|
return true;
|
||||||
// Kolizja wykryta z którymś płotem
|
}
|
||||||
return true;
|
}
|
||||||
}
|
return false;
|
||||||
}
|
|
||||||
return false; // Brak kolizji
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateRover(const std::vector<Plot>& fences) {
|
static void UpdateRover(const std::vector<Plot>& fences) {
|
||||||
|
// --- 1. OBSŁUGA PRZYSPIESZENIA (W / S) ---
|
||||||
if (keyWPressed) {
|
if (keyWPressed) {
|
||||||
|
|
||||||
// Przyspieszanie w przód
|
|
||||||
velocity += acceleration;
|
velocity += acceleration;
|
||||||
if (velocity > maxSpeed) velocity = maxSpeed;
|
if (velocity > maxSpeed) velocity = maxSpeed;
|
||||||
|
}
|
||||||
} else if (keySPressed) {
|
else if (keySPressed) {
|
||||||
|
|
||||||
// Przyspieszanie w tył
|
|
||||||
velocity -= acceleration;
|
velocity -= acceleration;
|
||||||
if (velocity < -maxSpeed) velocity = -maxSpeed;
|
if (velocity < -maxSpeed) velocity = -maxSpeed;
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
|
// Hamowanie (tarcie)
|
||||||
// Hamowanie (wytracanie prędkości z powodu tarcia)
|
|
||||||
if (velocity > 0) {
|
if (velocity > 0) {
|
||||||
|
|
||||||
velocity -= friction;
|
velocity -= friction;
|
||||||
if (velocity < 0) velocity = 0;
|
if (velocity < 0) velocity = 0;
|
||||||
|
}
|
||||||
} else if (velocity < 0) {
|
else if (velocity < 0) {
|
||||||
|
|
||||||
velocity += friction;
|
velocity += friction;
|
||||||
if (velocity > 0) velocity = 0;
|
if (velocity > 0) velocity = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obracanie (rotacja z driftowaniem)
|
// --- 2. OBSŁUGA OBROTU (A / D) ---
|
||||||
if (keyAPressed) {
|
if (keyAPressed) {
|
||||||
|
|
||||||
rotationVelocity += rotationAcceleration;
|
rotationVelocity += rotationAcceleration;
|
||||||
if (rotationVelocity > maxRotationSpeed) rotationVelocity = maxRotationSpeed;
|
if (rotationVelocity > maxRotationSpeed) rotationVelocity = maxRotationSpeed;
|
||||||
|
}
|
||||||
} else if (keyDPressed) {
|
else if (keyDPressed) {
|
||||||
|
|
||||||
rotationVelocity -= rotationAcceleration;
|
rotationVelocity -= rotationAcceleration;
|
||||||
if (rotationVelocity < -maxRotationSpeed) rotationVelocity = -maxRotationSpeed;
|
if (rotationVelocity < -maxRotationSpeed) rotationVelocity = -maxRotationSpeed;
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
|
// Driftowanie (wytracanie rotacji)
|
||||||
// Jeśli żaden z klawiszy A/D nie jest wciśnięty,
|
float driftFactor = 0.1f;
|
||||||
// to stopniowo spowalniamy rotację (drift)
|
|
||||||
|
|
||||||
// Mniejsza wartość = dłuższy drift
|
|
||||||
float driftFactor = 0.1f;
|
|
||||||
|
|
||||||
if (rotationVelocity > 0) {
|
if (rotationVelocity > 0) {
|
||||||
|
|
||||||
rotationVelocity -= rotationFriction * driftFactor;
|
rotationVelocity -= rotationFriction * driftFactor;
|
||||||
if (rotationVelocity < 0) rotationVelocity = 0;
|
if (rotationVelocity < 0) rotationVelocity = 0;
|
||||||
|
}
|
||||||
} else if (rotationVelocity < 0) {
|
else if (rotationVelocity < 0) {
|
||||||
|
|
||||||
rotationVelocity += rotationFriction * driftFactor;
|
rotationVelocity += rotationFriction * driftFactor;
|
||||||
if (rotationVelocity > 0) rotationVelocity = 0;
|
if (rotationVelocity > 0) rotationVelocity = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wyliczenie nowej pozycji na podstawie prędkości
|
// --- 3. LOGIKA ODWRÓCENIA SKRĘTU PRZY COFANIU ---
|
||||||
float radRotation = Rotation * GL_PI / 180.0f; // Przeliczamy rotację na radiany
|
// Jeśli prędkość jest ujemna, odwracamy wpływ rotationVelocity na kąt,
|
||||||
float newSides = Sides - velocity * cos(radRotation); // Nowa pozycja w osi X
|
// aby klawisz D zawsze kierował pojazd w prawo względem kamery.
|
||||||
float newFoward = Foward - velocity * sin(radRotation); // Nowa pozycja w osi Z
|
float actualRotationStep = rotationVelocity;
|
||||||
|
if (velocity < 0.0f) {
|
||||||
|
actualRotationStep = -rotationVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
// Wymiary łazika (połówki w osi X i Z)
|
// --- 4. WYLICZENIE NOWEJ POZYCJI ---
|
||||||
const float roverHalfWidthX = 19.0f; // 38/2
|
float radRotation = Rotation * GL_PI / 180.0f;
|
||||||
const float roverHalfLengthZ = 12.0f; // 24/2
|
float newSides = Sides - velocity * cos(radRotation);
|
||||||
|
float newFoward = Foward - velocity * sin(radRotation);
|
||||||
|
|
||||||
// Wyliczenie obszaru zajmowanego przez łazik
|
// Wymiary łazika
|
||||||
float roverXMin = newSides - roverHalfWidthX;
|
const float roverHalfWidthX = 19.0f;
|
||||||
float roverXMax = newSides + roverHalfWidthX;
|
const float roverHalfLengthZ = 12.0f;
|
||||||
|
|
||||||
|
// Obszar zajmowany przez łazik (AABB dla ruchu prostoliniowego)
|
||||||
|
float roverXMin = newSides - roverHalfWidthX;
|
||||||
|
float roverXMax = newSides + roverHalfWidthX;
|
||||||
float roverZMin = newFoward - roverHalfLengthZ;
|
float roverZMin = newFoward - roverHalfLengthZ;
|
||||||
float roverZMax = newFoward + roverHalfLengthZ;
|
float roverZMax = newFoward + roverHalfLengthZ;
|
||||||
|
|
||||||
// Sprawdzanie kolizji przed aktualizacją pozycji
|
// --- 5. KOLIZJE I AKTUALIZACJA ---
|
||||||
if (!Kolizja) {
|
if (!Kolizja) {
|
||||||
|
// Kolizja przy ruchu przód/tył
|
||||||
if (CheckAllFencesCollision(roverZMin, roverZMax, roverXMin, roverXMax, fences)) {
|
if (CheckAllFencesCollision(roverZMin, roverZMax, roverXMin, roverXMax, fences)) {
|
||||||
// Jeśli jest kolizja, zatrzymujemy łazik
|
|
||||||
// cout << "Kolizja podczas ruchu!\n";
|
|
||||||
velocity = 0.0f;
|
velocity = 0.0f;
|
||||||
} else {
|
}
|
||||||
// Jeśli brak kolizji, aktualizujemy pozycję
|
else {
|
||||||
Sides = newSides;
|
Sides = newSides;
|
||||||
Foward = newFoward;
|
Foward = newFoward;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sprawdzanie kolizji podczas obrotu
|
// Kolizja przy obrocie
|
||||||
if (rotationVelocity != 0.0f) {
|
if (actualRotationStep != 0.0f) {
|
||||||
// Wyliczamy nową rotację
|
float newRotation = Rotation + actualRotationStep;
|
||||||
float newRotation = Rotation + rotationVelocity;
|
|
||||||
float radNewRotation = newRotation * GL_PI / 180.0f;
|
float radNewRotation = newRotation * GL_PI / 180.0f;
|
||||||
|
|
||||||
// Obracamy narożniki łazika
|
// Punkty narożne do sprawdzenia po obrocie (OBB)
|
||||||
std::vector<std::pair<float, float>> corners(4);
|
std::vector<std::pair<float, float>> corners = {
|
||||||
corners[0] = {Sides - roverHalfWidthX, Foward - roverHalfLengthZ}; // Lewy dolny
|
{Sides - roverHalfWidthX, Foward - roverHalfLengthZ},
|
||||||
corners[1] = {Sides + roverHalfWidthX, Foward - roverHalfLengthZ}; // Prawy dolny
|
{Sides + roverHalfWidthX, Foward - roverHalfLengthZ},
|
||||||
corners[2] = {Sides - roverHalfWidthX, Foward + roverHalfLengthZ}; // Lewy górny
|
{Sides - roverHalfWidthX, Foward + roverHalfLengthZ},
|
||||||
corners[3] = {Sides + roverHalfWidthX, Foward + roverHalfLengthZ}; // Prawy górny
|
{Sides + roverHalfWidthX, Foward + roverHalfLengthZ}
|
||||||
bool collisionDetected = false;
|
};
|
||||||
|
|
||||||
// Obracamy wszystkie narożniki
|
bool collisionDetected = false;
|
||||||
for (auto& corner: corners) {
|
for (auto& corner : corners) {
|
||||||
float x = corner.first;
|
float x = corner.first;
|
||||||
float z = corner.second;
|
float z = corner.second;
|
||||||
|
|
||||||
corner.first = Sides + (x - Sides) * cos(radNewRotation) - (z - Foward) * sin(radNewRotation);
|
// Rotacja punktów wokół środka łazika
|
||||||
corner.second = Foward + (x - Sides) * sin(radNewRotation) + (z - Foward) * cos(radNewRotation);
|
float rotatedX = Sides + (x - Sides) * cos(radNewRotation) - (z - Foward) * sin(radNewRotation);
|
||||||
|
float rotatedZ = Foward + (x - Sides) * sin(radNewRotation) + (z - Foward) * cos(radNewRotation);
|
||||||
|
|
||||||
// Sprawdzamy kolizję na podstawie obróconych narożników
|
if (CheckAllFencesCollision(rotatedX, rotatedX, rotatedZ, rotatedZ, fences)) {
|
||||||
if (CheckAllFencesCollision( corner.first, corner.first, corner.second, corner.second, fences)) {
|
|
||||||
collisionDetected = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (CheckAllFencesCollision(corner.second, corner.second, corner.first, corner.first, fences)) {
|
|
||||||
collisionDetected = true;
|
collisionDetected = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collisionDetected) {
|
if (collisionDetected) {
|
||||||
//cout << "Kolizja podczas obrotu!\n";
|
rotationVelocity = 0.0f; // Blokujemy obrót
|
||||||
rotationVelocity = 0.0f; // Zatrzymujemy obrót
|
}
|
||||||
} else {
|
else {
|
||||||
// Aktualizujemy rotację, jeśli nie ma kolizji
|
Rotation = newRotation;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
// Kolizje wyłączone - aktualizuj bez pytań
|
||||||
|
Sides = newSides;
|
||||||
|
Foward = newFoward;
|
||||||
|
Rotation += actualRotationStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalizacja kąta do zakresu 0-360
|
||||||
|
if (Rotation >= 360.0f) Rotation -= 360.0f;
|
||||||
|
if (Rotation < 0.0f) Rotation += 360.0f;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Plot> fences = {
|
std::vector<Plot> fences = {
|
||||||
{ 450.0f, 3.0f, -90.0f, 900.0f, 4.0f, 1}, // 1 - poziomo
|
{ 450.0f, 3.0f, -90.0f, 900.0f, 4.0f, 1}, // 1 - poziomo
|
||||||
@@ -340,35 +310,28 @@ std::vector<Plot> fences = {
|
|||||||
|
|
||||||
// Change viewing volume and viewport. Called when window is resized
|
// Change viewing volume and viewport. Called when window is resized
|
||||||
void static ChangeSize(GLsizei w, GLsizei h) {
|
void static ChangeSize(GLsizei w, GLsizei h) {
|
||||||
GLfloat nRange = 100.0f;
|
// Zabezpieczenie przed dzieleniem przez zero
|
||||||
//GLfloat fAspect;
|
|
||||||
// Prevent a divide by zero
|
|
||||||
if (h == 0) h = 1;
|
if (h == 0) h = 1;
|
||||||
|
|
||||||
lastWidth = w;
|
lastWidth = w;
|
||||||
lastHeight = h;
|
lastHeight = h;
|
||||||
|
|
||||||
//fAspect = (GLfloat)w / (GLfloat)h;
|
// Obliczenie proporcji okna (Aspect Ratio)
|
||||||
// Set Viewport to window dimensions
|
GLfloat fAspect = (GLfloat)w / (GLfloat)h;
|
||||||
|
|
||||||
|
// Ustawienie obszaru renderowania
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
|
|
||||||
// Reset coordinate system
|
// Reset macierzy projekcji
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
// // Establish clipping volume (left, right, bottom, top, near, far)
|
// USTAWIENIE PERSPEKTYWY
|
||||||
// if (w <= h) glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -nRange, nRange);
|
// Parametry: (Kąt widzenia w stopniach, Proporcje okna, Bliska płaszczyzna, Daleka płaszczyzna)
|
||||||
// else glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -nRange, nRange);
|
// UWAGA: Bliska płaszczyzna (near) w perspektywie MUSI być większa od 0 (np. 1.0f)
|
||||||
|
gluPerspective(45.0f, fAspect, 1.0f, 2000.0f);
|
||||||
// Establish clipping volume (left, right, bottom, top, near, far)
|
|
||||||
if (w <= h) glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -20 * nRange, 20 * nRange);
|
|
||||||
else glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -20 * nRange, 20 * nRange);
|
|
||||||
|
|
||||||
// Establish perspective:
|
|
||||||
/*
|
|
||||||
gluPerspective(60.0f, fAspect, 1.0, 400);
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// Powrót do macierzy widoku modelu
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
}
|
}
|
||||||
@@ -584,27 +547,38 @@ void static RenderScene(void) {
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
// Widok panoramiczny (SHIFT/F5)
|
// Widok panoramiczny (SHIFT/F5)
|
||||||
|
// Pomocnicza konwersja na radiany
|
||||||
|
float rad = Rotation * GL_PI / 180.0f;
|
||||||
|
|
||||||
if (panoramic_view) {
|
if (panoramic_view) {
|
||||||
// Zwiększ prędkość obrotu oraz tarcie
|
// --- WIDOK Z GÓRY (STRATEGICZNY) ---
|
||||||
maxRotationSpeed = 1.0f;
|
maxRotationSpeed = 1.0f;
|
||||||
rotationFriction = 0.5f;
|
rotationFriction = 0.5f;
|
||||||
|
|
||||||
|
float mapZoom = 400.0f; // Wysokość, z której patrzymy
|
||||||
gluLookAt(
|
gluLookAt(
|
||||||
Foward, // Pozycja kamery
|
Foward, mapZoom, Sides, // Kamera wysoko nad łazikiem
|
||||||
123, // Wysokość kamery, nie ma znaczenia bo nie mamy perspektywy
|
Foward, 0.0f, Sides, // Patrzymy prosto na łazik
|
||||||
Sides - 1.0f, // Kamera wzdłuż osi X i Z, z jakiegoś powodu działa po "- 1.0f"
|
1.0f, 0.0f, 0.0f // ZMIANA: Wektor góry to oś X (bo patrzymy w dół osi Y)
|
||||||
Foward, 0.0f, Sides, // Punkt patrzenia (łazik)
|
|
||||||
0.0f, 1.0f, 0.0f // Wektor "góry"
|
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
// Ustaw tarcie i prędkość obrotu na domyślną wartość
|
else {
|
||||||
maxRotationSpeed = 0.5f;
|
maxRotationSpeed = 0.5f;
|
||||||
rotationFriction = 0.1f;
|
rotationFriction = 0.1f;
|
||||||
|
|
||||||
|
float rad = Rotation * GL_PI / 180.0f;
|
||||||
|
|
||||||
|
// Obliczamy pozycję kamery korzystając z dynamicznego CameraDistance
|
||||||
|
float camX = Foward + CameraHeight * sin(rad);
|
||||||
|
float camZ = Sides + CameraHeight * cos(rad);
|
||||||
|
|
||||||
|
// Wysokość kamery też może się skalować z dystansem (opcjonalnie)
|
||||||
|
float dynamicHeight = CameraHeight * 0.4f;
|
||||||
|
|
||||||
gluLookAt(
|
gluLookAt(
|
||||||
Foward - 50.0f * sin((Rotation + 180.0f) * GL_PI / 180.0f), // Pozycja kamery
|
camX, dynamicHeight, camZ, // Pozycja kamery
|
||||||
CameraHeight / 4, // Wysokość kamery
|
Foward, 10.0f, Sides, // Patrzymy na łazik
|
||||||
Sides - 50.0f * cos((Rotation + 180.0f) * GL_PI / 180.0f), // Kamera wzdłuż osi X i Z
|
0.0f, 1.0f, 0.0f // Góra
|
||||||
Foward, 0.0f, Sides, // Punkt patrzenia (łazik)
|
|
||||||
0.0f, 1.0f, 0.0f // Wektor "góry"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -993,6 +967,23 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
{
|
||||||
|
// Pobieramy informację o tym, jak mocno obrócono kółko
|
||||||
|
int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
|
||||||
|
|
||||||
|
// Zmieniamy dystans kamery (podzielone przez 120, bo tyle wynosi jeden "skok" scrolla)
|
||||||
|
CameraHeight -= (float)zDelta * 0.1f;
|
||||||
|
|
||||||
|
// Ograniczamy zoom, żeby nie wejść kamerą "w łazik" ani nie odlecieć w kosmos
|
||||||
|
if (CameraHeight < MinDistance) CameraHeight = MinDistance;
|
||||||
|
if (CameraHeight > MaxDistance) CameraHeight = MaxDistance;
|
||||||
|
|
||||||
|
// Odświeżamy okno
|
||||||
|
InvalidateRect(hWnd, NULL, FALSE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user