From 2c0685947301364c356aa2234ff363f8a406162b Mon Sep 17 00:00:00 2001 From: Sheldon Lee Date: Thu, 20 Apr 2023 00:28:17 +0100 Subject: [PATCH] Refactor storing of ray-casted distances. The ray-casting is done when camera_update() is called, and distances are stored in the Camera struct. --- camera.cpp | 43 ++++++++++++++++++++- camera.h | 10 +++++ level.cpp | 63 ++---------------------------- level.h | 2 +- minimap.cpp | 108 +++++++++++++++++++++++++++++++++++++--------------- minimap.h | 1 + view.cpp | 18 +++++---- 7 files changed, 145 insertions(+), 100 deletions(-) diff --git a/camera.cpp b/camera.cpp index 4af2a26..c52904a 100644 --- a/camera.cpp +++ b/camera.cpp @@ -7,12 +7,24 @@ #define TRANSLATIONAL_SPEED 1.f static void move(Camera* camera, float t); +static void castRays(Camera* camera); + +int camera_init(Camera* camera, sf::Vector2f pos, float direction, unsigned int resolution, float fov) +{ + camera->pos = pos; + camera->direction = direction; + camera->resolution = resolution; + camera->fov = fov; + + camera->rays = (CameraRay*)malloc(sizeof(CameraRay)*resolution); + return 1; +} void camera_update(Camera* camera, float t) { if (!camera) return; - move(camera, t); + castRays(camera); } static void move(Camera* camera, float t) @@ -29,8 +41,35 @@ static void move(Camera* camera, float t) rotation -=1; float magnitude = forward * t * TRANSLATIONAL_SPEED; - sf::Vector2f offset(magnitude * cos(camera->direction), magnitude *sin(camera->direction)); + sf::Vector2f offset(magnitude * cos(camera->direction), magnitude * sin(camera->direction)); camera->pos += offset; camera->direction += rotation * t * ROTATION_SPEED; } + +void camera_destroy(Camera *camera) +{ + free(camera->rays); +} + +static void castRays(Camera* camera) +{ + float rayDirection = 0; + float rayDirectionStep = camera->fov / (float)camera->resolution; + bool isOddResolution = (camera->resolution % 2); + float rayDirectionOffset = isOddResolution? 0 : rayDirectionStep / 2.f; + + for (unsigned int i = 0; i < camera->resolution; i++) { + if (isOddResolution && i == 0) + rayDirection = camera->direction; + else if (i % 2) + rayDirection = camera->direction - rayDirectionOffset; + else + rayDirection = camera->direction + rayDirectionOffset; + + camera->rays[i].direction = rayDirection; + camera->rays[i].distance = level_rayCastDistance(camera->pos, rayDirection); + + if ((i + isOddResolution) % 2) rayDirectionOffset += rayDirectionStep; + } +} diff --git a/camera.h b/camera.h index 158cc04..78bf997 100644 --- a/camera.h +++ b/camera.h @@ -3,14 +3,24 @@ #include +typedef struct +{ + float direction; + float distance; +} CameraRay; + typedef struct { sf::Vector2f pos; float direction; unsigned int resolution; float fov; + + CameraRay* rays; } Camera; +int camera_init(Camera* camera, sf::Vector2f pos, float direction, unsigned int resolution, float fov); void camera_update(Camera* camera, float t); +void camera_destroy(Camera* camera); #endif diff --git a/level.cpp b/level.cpp index 24d5ce0..dc86da3 100644 --- a/level.cpp +++ b/level.cpp @@ -1,15 +1,10 @@ #include "level.h" -#include #include "maths.h" #define WIDTH 5 #define HEIGHT 5 -static void drawGrid(sf::RenderTarget* renderTarget, unsigned int tileSize); -static void drawGridLine(sf::RenderTarget* renderTarget, float step, bool isHorizontal); -static sf::Vertex getGridLineVertex(float n, float maxDimension, bool isStart, bool isHorizontal); - static float castRay(sf::Vector2f point, float direction); static void getGridIndex(sf::Vector2f point, int* x, int* y); @@ -23,20 +18,16 @@ static unsigned int level[WIDTH * HEIGHT] = { int level_init() { - printf("level_init()\n"); return 1; } void level_update(sf::RenderTarget* renderTarget, unsigned int drawSize) { if (!renderTarget) return; - - drawGrid(renderTarget, drawSize/WIDTH); } void level_end() { - printf("level_end()\n"); return; } @@ -51,58 +42,12 @@ void level_getDimensions(unsigned int* width, unsigned int* height) *height = HEIGHT; } -static void drawGrid(sf::RenderTarget* renderTarget, unsigned int tileSize) +unsigned int level_getGridValue(unsigned int x, unsigned int y) { - for (unsigned int x = 0; x < WIDTH; x++) { - for (unsigned int y = 0; y < HEIGHT; y++) { - if (!level[y * HEIGHT + x]) continue; + if (x < 0 || WIDTH <= x) return 0; + if (y < 0 || HEIGHT <= y) return 0; - sf::RectangleShape rectangle(sf::Vector2f(tileSize, tileSize)); - rectangle.setPosition((float)x * tileSize, (float)y * tileSize); - renderTarget->draw(rectangle); - } - } - - drawGridLine(renderTarget, tileSize, true); - drawGridLine(renderTarget, tileSize, false); -} - -static void drawGridLine(sf::RenderTarget* renderTarget, float step, bool isHorizontal) -{ - unsigned int lines = isHorizontal? WIDTH : HEIGHT; - - for (unsigned int n = 0; n < lines; n++) { - if (n == 0) continue; - float offset = (float)n * step; - float maxDimension = (float)lines * step; - sf::Vertex line[] = - { - getGridLineVertex(offset, maxDimension, true, isHorizontal), - getGridLineVertex(offset, maxDimension, false, isHorizontal) - }; - - renderTarget->draw(line, 2, sf::Lines); - } -} - -static sf::Vertex getGridLineVertex(float offset, float maxDimension, bool isStart, bool isHorizontal) -{ - sf::Vertex start; - sf::Vertex end; - - if (isHorizontal) { - start = sf::Vertex(sf::Vector2f(offset, 0)); - end = sf::Vertex(sf::Vector2f(offset, maxDimension)); - } - else { - start = sf::Vertex(sf::Vector2f(0, offset)); - end = sf::Vertex(sf::Vector2f(maxDimension, offset)); - } - - sf::Color color(100, 100, 100); - start.color = color; - end.color = color; - return isStart? start : end; + return level[y * HEIGHT + x]; } static float castRay(sf::Vector2f point, float direction) diff --git a/level.h b/level.h index 7b97746..856a65e 100644 --- a/level.h +++ b/level.h @@ -4,9 +4,9 @@ #include int level_init(); -void level_update(sf::RenderTarget* renderTarget, unsigned int drawSize); void level_end(); float level_rayCastDistance(sf::Vector2f point, float direction); void level_getDimensions(unsigned int* width, unsigned int* height); +unsigned int level_getGridValue(unsigned int x, unsigned int y); #endif diff --git a/minimap.cpp b/minimap.cpp index ce10320..cfb51b0 100644 --- a/minimap.cpp +++ b/minimap.cpp @@ -3,28 +3,31 @@ #include "maths.h" #include "level.h" - +// Camera drawing static void drawCamera(sf::RenderTarget* renderTarget, Camera* camera); static void drawRays(sf::RenderTarget* renderTarget, Camera* camera); static void drawLine(sf::RenderTarget* renderTarget, sf::Vector2f pos, float angle, float length, sf::Color color); +// Grid drawing +static void drawGrid(sf::RenderTarget* renderTarget, unsigned int tileSize); +static void drawGridLine(sf::RenderTarget* renderTarget, float step, bool isHorizontal); +static sf::Vertex getGridLineVertex(float n, float maxDimension, bool isStart, bool isHorizontal); -static sf::RenderTexture minimap; +static sf::RenderTexture renderTexture; +static sf::Vector2f renderTexturePosition; static bool init = false; static unsigned int minimapSize; +static unsigned int gridWidth, gridHeight; static float drawScale; int minimap_init(unsigned int size) { printf("minimap_init()\n"); - if (!minimap.create(size, size)) return 0; - level_init(); - - unsigned int width, height; - level_getDimensions(&width, &height); + if (!renderTexture.create(size, size)) return 0; minimapSize = size; - drawScale = (float)size/(float)width; + level_getDimensions(&gridWidth, &gridHeight); + drawScale = (float)size/(float)gridWidth; init = true; return 1; @@ -34,15 +37,22 @@ void minimap_update(sf::RenderTarget* renderTarget, Camera* camera) { if (!init) return; if (!renderTarget || !camera) return; - minimap.clear(); - level_update(&minimap, minimapSize); - drawCamera(&minimap, camera); - minimap.display(); - sf::Sprite sprite(minimap.getTexture()); + renderTexture.clear(); + drawGrid(&renderTexture, minimapSize/gridWidth); + drawCamera(&renderTexture, camera); + renderTexture.display(); + + sf::Sprite sprite(renderTexture.getTexture()); renderTarget->draw(sprite); } +void minimap_setTexturePosition(float x, float y) +{ + renderTexturePosition.x = x; + renderTexturePosition.y = y; +} + static void drawCamera(sf::RenderTarget* renderTarget, Camera* camera) { const sf::Vector2f scaledPos = camera->pos * drawScale; @@ -61,24 +71,9 @@ static void drawRays(sf::RenderTarget* renderTarget, Camera* camera) { const sf::Vector2f scaledPos = camera->pos * drawScale; - float rayDirection = 0; - float rayDirectionStep = camera->fov / (float)camera->resolution; - bool isOddResolution = (camera->resolution % 2); - float rayDirectionOffset = isOddResolution? 0 : rayDirectionStep / 2.f; - for (unsigned int i = 0; i < camera->resolution; i++) { - if (isOddResolution && i == 0) - rayDirection = camera->direction; - else if (i % 2) - rayDirection = camera->direction - rayDirectionOffset; - else - rayDirection = camera->direction + rayDirectionOffset; - - float distance = level_rayCastDistance(camera->pos, rayDirection) * drawScale; - - drawLine(renderTarget, scaledPos, rayDirection, distance, sf::Color(150, 150, 100)); - - if ((i + isOddResolution) % 2) rayDirectionOffset += rayDirectionStep; + CameraRay* ray = &camera->rays[i]; + drawLine(renderTarget, scaledPos, ray->direction, ray->distance * drawScale, sf::Color(150, 150, 100)); } } @@ -98,3 +93,56 @@ static void drawLine(sf::RenderTarget* renderTarget, sf::Vector2f pos, float ang renderTarget->draw(line, 2, sf::Lines); } +static void drawGrid(sf::RenderTarget* renderTarget, unsigned int tileSize) +{ + for (unsigned int x = 0; x < gridWidth; x++) { + for (unsigned int y = 0; y < gridHeight; y++) { + if (!level_getGridValue(x, y)) continue; + + sf::RectangleShape rectangle(sf::Vector2f(tileSize, tileSize)); + rectangle.setPosition((float)x * tileSize, (float)y * tileSize); + renderTarget->draw(rectangle); + } + } + + drawGridLine(renderTarget, tileSize, true); + drawGridLine(renderTarget, tileSize, false); +} + +static void drawGridLine(sf::RenderTarget* renderTarget, float step, bool isHorizontal) +{ + unsigned int lines = isHorizontal? gridWidth : gridHeight; + + for (unsigned int n = 0; n < lines; n++) { + if (n == 0) continue; + float offset = (float)n * step; + float maxDimension = (float)lines * step; + sf::Vertex line[] = + { + getGridLineVertex(offset, maxDimension, true, isHorizontal), + getGridLineVertex(offset, maxDimension, false, isHorizontal) + }; + + renderTarget->draw(line, 2, sf::Lines); + } +} + +static sf::Vertex getGridLineVertex(float offset, float maxDimension, bool isStart, bool isHorizontal) +{ + sf::Vertex start; + sf::Vertex end; + + if (isHorizontal) { + start = sf::Vertex(sf::Vector2f(offset, 0)); + end = sf::Vertex(sf::Vector2f(offset, maxDimension)); + } + else { + start = sf::Vertex(sf::Vector2f(0, offset)); + end = sf::Vertex(sf::Vector2f(maxDimension, offset)); + } + + sf::Color color(100, 100, 100); + start.color = color; + end.color = color; + return isStart? start : end; +} diff --git a/minimap.h b/minimap.h index 4c50837..3309369 100644 --- a/minimap.h +++ b/minimap.h @@ -6,5 +6,6 @@ int minimap_init(unsigned int size); void minimap_update(sf::RenderTarget* renderTarget, Camera* camera); +void minimap_setTexturePosition(float x, float y); #endif diff --git a/view.cpp b/view.cpp index 2bf6472..5ba2115 100644 --- a/view.cpp +++ b/view.cpp @@ -6,22 +6,24 @@ #include "camera.h" #include "minimap.h" -#define MINIMAP_SIZE 250 -#define HALF_MINIMAP_SIZE MINIMAP_SIZE/2.f -#define DRAW_SCALE MINIMAP_SIZE/5.f +#define MINIMAP_SIZE 460 +#define VIEW_SIZE MINIMAP_SIZE*2 static int handleKeyCode(sf::Keyboard::Key key); -static Camera camera = { sf::Vector2f(5.f/2.f, 5.f/2.f), 0.f, 300, 0.5f*PI }; +static Camera camera; static sf::Uint32 style = sf::Style::Titlebar; -static sf::RenderWindow window(sf::VideoMode(MINIMAP_SIZE + camera.resolution, MINIMAP_SIZE), "Raycasting", style); +static sf::RenderWindow window(sf::VideoMode(MINIMAP_SIZE + VIEW_SIZE, MINIMAP_SIZE), "Raycasting", style); static sf::Clock timer; int view_init() { printf("view_init()\n"); - minimap_init(MINIMAP_SIZE); + if (!camera_init(&camera, sf::Vector2f(5.f/2.f, 5.f/2.f), 0.f, 100, 0.5f*PI)) return 0; + if (!minimap_init(MINIMAP_SIZE)) return 0; + + minimap_setTexturePosition(0.f, 0.f); return 1; } @@ -55,9 +57,9 @@ int view_update() void view_end() { - printf("view_end()\n"); - + camera_destroy(&camera); window.close(); + printf("view_end()\n"); } static int handleKeyCode(sf::Keyboard::Key key)