From f59a48ed512bd542e96f6e999fc1adac7df96397 Mon Sep 17 00:00:00 2001 From: Floriansylvain Date: Sun, 28 Dec 2025 16:42:47 +0100 Subject: [PATCH] feat: raycasting part 2 (working great!) --- src/Game.cpp | 64 ++++++++++++++++++++++++++++++++++++---------------- src/Game.hpp | 15 ++++-------- 2 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/Game.cpp b/src/Game.cpp index 25d9afd..79dfb8b 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -2,11 +2,12 @@ #include #include #include +#include #include Game::Game() : gridLines(WIDTH, HEIGHT, 20.f), player(15.f, sf::Color::Green), - rayVertices(sf::PrimitiveType::Lines) { + rayVertices(sf::PrimitiveType::TriangleFan) { window.create(sf::VideoMode({WIDTH, HEIGHT}), "SFML Game"); window.setVerticalSyncEnabled(VSYNC); @@ -16,6 +17,8 @@ Game::Game() worldView.setSize({(float)WIDTH, (float)HEIGHT}); worldView.setCenter({(float)WIDTH / 2.f, (float)HEIGHT / 2.f}); + + lightColor = sf::Color(255, 255, 150, 50); } void Game::run() { @@ -64,7 +67,7 @@ float Game::intersects(Ray ray, Wall wall) { (ray.direction.x * wallVector.y) - (ray.direction.y * wallVector.x); if (determinator == 0) - return false; + return INFINITY; auto rayDist = ((wall.start.x - ray.origin.x) * wallVector.y - (wall.start.y - ray.origin.y) * wallVector.x); @@ -81,34 +84,57 @@ float Game::intersects(Ray ray, Wall wall) { return INFINITY; }; +sf::Vector2f Game::updateRay(sf::Vector2f &origin, sf::Vector2f &targetPoint, + float offset) { + auto closestDist = 1.0f; + auto maxDist = 3000.0f; + + float angle = + std::atan2(targetPoint.y - origin.y, targetPoint.x - origin.x) + offset; + + sf::Vector2f direction = {std::cos(angle) * maxDist, + std::sin(angle) * maxDist}; + Ray ray = {origin, direction}; + + for (Wall wall : walls.get()) { + auto rayDist = intersects(ray, wall); + if (rayDist < closestDist) { + closestDist = rayDist; + }; + } + + return ray.origin + (ray.direction * closestDist); +} + void Game::update(double dt) { debug.update(dt); player.update(dt, window, worldView); - // INIT/UPDATE RAYS ------- + // INIT/UPDATE RAYS ------------------------------------------ auto mousePos = sf::Mouse::getPosition(window); auto mousePosWorld = window.mapPixelToCoords(mousePos, worldView); rayVertices.clear(); + hitPoints.clear(); + for (sf::Vector2 targetPoint : walls.getPoints()) { - auto ray = Ray(mousePosWorld, targetPoint); - auto closestDist = 1.0f; - - for (Wall wall : walls.get()) { - auto rayDist = intersects(ray, wall); - if (rayDist < closestDist) { - closestDist = rayDist; - }; - } - - sf::Vector2f hitPoint = ray.origin + (ray.direction * closestDist); - - rayVertices.append({ray.origin, sf::Color::Blue}); - rayVertices.append({hitPoint, sf::Color::Blue}); + hitPoints.emplace_back(updateRay(mousePosWorld, targetPoint, 0.f)); + hitPoints.emplace_back(updateRay(mousePosWorld, targetPoint, 0.001f)); + hitPoints.emplace_back(updateRay(mousePosWorld, targetPoint, -0.001f)); } + std::sort(hitPoints.begin(), hitPoints.end(), + [mousePosWorld](sf::Vector2f a, sf::Vector2f b) -> bool { + auto angleA = atan2(mousePosWorld.y - a.y, mousePosWorld.x - a.x); + auto angleB = atan2(mousePosWorld.y - b.y, mousePosWorld.x - b.x); + return angleA < angleB; + }); - // TODO: implement 3-rays trick to have softer angles - // ----------------- + rayVertices.append({mousePosWorld, lightColor}); + for (auto hitPoint : hitPoints) { + rayVertices.append({hitPoint, lightColor}); + } + rayVertices.append({hitPoints[0], lightColor}); + // ----------------------------------------------------------- }; void Game::render() { diff --git a/src/Game.hpp b/src/Game.hpp index 5bef1d1..05f742b 100644 --- a/src/Game.hpp +++ b/src/Game.hpp @@ -12,7 +12,7 @@ #include "Player.hpp" #include "Walls.hpp" -constexpr bool VSYNC = true; +constexpr bool VSYNC = false; constexpr int WIDTH = 1920; constexpr int HEIGHT = 1080; constexpr int DEBUG_REFRESH_RATE_IN_MS = 250; @@ -21,15 +21,6 @@ constexpr float ASPECT = 16.f / 9.f; struct Ray { sf::Vector2f origin; sf::Vector2f direction; - float angle; - - Ray(sf::Vector2f origin, sf::Vector2f target) { - this->origin = origin; - this->direction = target - origin; - angle = direction.angleTo(origin).asDegrees(); - }; - - Ray(float angle, float length) {}; // TODO }; class Game { @@ -47,8 +38,12 @@ private: Walls walls; sf::VertexArray rayVertices; + std::vector hitPoints; + sf::Color lightColor; float intersects(Ray ray, Wall wall); + sf::Vector2f updateRay(sf::Vector2f &origin, sf::Vector2f &targetPoint, + float offset); void onResize(); void processEvents();