From 41437cd25927741522aa2ab2f5d1733e009d9eee Mon Sep 17 00:00:00 2001 From: Teo-CD Date: Sun, 28 Jan 2024 22:08:35 +0000 Subject: [PATCH] Clean-up: Change indentation to tabs --- CMakeLists.txt | 24 ++-- Player.cpp | 26 ++-- Player.h | 32 ++--- World.cpp | 368 ++++++++++++++++++++++++------------------------- World.h | 66 ++++----- main.cpp | 86 ++++++------ 6 files changed, 301 insertions(+), 301 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90b4bb5..0845878 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,31 +8,31 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) find_package(SFML COMPONENTS system window graphics network audio REQUIRED) if(NOT SFML_FOUND) - message(FATAL_ERROR "SFML could not be found") + message(FATAL_ERROR "SFML could not be found") endif() set(LIBS - sfml-window - sfml-graphics) + sfml-window + sfml-graphics) find_package(ImGui QUIET) find_package(ImGui-SFML QUIET) if(NOT ImGui_FOUND OR NOT ImGui-SFML_FOUND OR NO_IMGUI) - message("*Not* building with ImGui") + message("*Not* building with ImGui") else () - message("Building with ImGui") - add_compile_definitions(IMGUI) - set(LIBS ${LIBS} - ImGui-SFML::ImGui-SFML) + message("Building with ImGui") + add_compile_definitions(IMGUI) + set(LIBS ${LIBS} + ImGui-SFML::ImGui-SFML) endif() add_compile_options(-Wall -Wextra) add_executable(raycasting - main.cpp - Player.cpp - World.cpp - ) + main.cpp + Player.cpp + World.cpp + ) target_link_libraries(raycasting ${LIBS}) diff --git a/Player.cpp b/Player.cpp index b6fa26c..694636e 100644 --- a/Player.cpp +++ b/Player.cpp @@ -10,21 +10,21 @@ Player::Player(float x, float y, float alpha) : x(x), y(y), orientation(alpha) void Player::move(float dx, float dy) { - x += dx; - y += dy; + x += dx; + y += dy; } void Player::rotate(float alpha) { - orientation += fmodf(alpha, 360); - if(orientation > 360) - { - orientation -= 360; - } - else if(orientation < 0) - { - orientation += 360; - } + orientation += fmodf(alpha, 360); + if(orientation > 360) + { + orientation -= 360; + } + else if(orientation < 0) + { + orientation += 360; + } /* * Rotate the movement vector along the new angle, assumes that the only @@ -33,9 +33,9 @@ void Player::rotate(float alpha) float prevSpeedX = currentMoveSpeedX; float prevSpeedY = currentMoveSpeedY; currentMoveSpeedX = cosf(-alpha * deg_to_rad) * prevSpeedX - - sinf(-alpha * deg_to_rad) * prevSpeedY; + - sinf(-alpha * deg_to_rad) * prevSpeedY; currentMoveSpeedY = sinf(-alpha * deg_to_rad) * prevSpeedX - + cosf(-alpha * deg_to_rad) * prevSpeedY; + + cosf(-alpha * deg_to_rad) * prevSpeedY; } void Player::updateSpeed(float localX, float localY) { diff --git a/Player.h b/Player.h index eab2795..294e669 100644 --- a/Player.h +++ b/Player.h @@ -11,28 +11,28 @@ static constexpr float deg_to_rad = 3.14159265/180; class Player { public: - Player(float x, float y, float alpha); + Player(float x, float y, float alpha); - float x; - float y; - float orientation; + float x; + float y; + float orientation; - float moveSpeed = 5; - float rotationSpeed = 180; + float moveSpeed = 5; + float rotationSpeed = 180; - float currentMoveSpeedX = 0; - float currentMoveSpeedY = 0; + float currentMoveSpeedX = 0; + float currentMoveSpeedY = 0; - float currentRotationSpeed = 0; + float currentRotationSpeed = 0; - /* View properties. */ - float fov = 70; - float sensorSize = 0.035; /* 35mm, about equivalent to human eye ? */ - float focalLength = sensorSize / (2*tanf((fov*deg_to_rad)/2)); + /* View properties. */ + float fov = 70; + float sensorSize = 0.035; /* 35mm, about equivalent to human eye ? */ + float focalLength = sensorSize / (2*tanf((fov*deg_to_rad)/2)); - void move(float dx, float dy); - void rotate(float alpha); - void updateSpeed(float localX, float localY); + void move(float dx, float dy); + void rotate(float alpha); + void updateSpeed(float localX, float localY); }; diff --git a/World.cpp b/World.cpp index 7880148..b8a8eb6 100644 --- a/World.cpp +++ b/World.cpp @@ -14,22 +14,22 @@ World::World(int w, int h, sf::Color groundColor, sf::Color ceilingColor, std::v player(0,0,0), w(w), h(h), map(std::move(worldMap)), groundColor(groundColor), ceilingColor(ceilingColor) { - map.resize(w*h,BlockType::WALL); + map.resize(w*h,BlockType::WALL); } int World::getW() const { - return w; + return w; } int World::getH() const { - return h; + return h; } BlockType World::getBlock(int x, int y) const { - return map[x + w*y]; + return map[x + w*y]; } BlockType World::getBlock(float x, float y) const @@ -39,176 +39,176 @@ BlockType World::getBlock(float x, float y) const void World::setBlock(BlockType block, int x, int y, int width, int height) { - for(int i = 0;i(world.player.x) == i%world.w && static_cast(world.player.y) == i/world.h) - { - ostream << "P"; - } - else - { - ostream << " "; - } - break; - } - case BlockType::WALL: - { - ostream << "W"; - break; - } - case BlockType::DOOR: - { - ostream << "D"; - break; - } - case BlockType::WINDOW: - { - ostream << "W"; - break; - } - } - } - return(ostream); + for(int i = 0;i(world.player.x) == i%world.w && static_cast(world.player.y) == i/world.h) + { + ostream << "P"; + } + else + { + ostream << " "; + } + break; + } + case BlockType::WALL: + { + ostream << "W"; + break; + } + case BlockType::DOOR: + { + ostream << "D"; + break; + } + case BlockType::WINDOW: + { + ostream << "W"; + break; + } + } + } + return(ostream); } float World::castRay(float originX, float originY, float orientation) const { - /* - * Reference used for ray intersection computations : - * https://web.archive.org/web/20220628034315/https://yunes.informatique.univ-paris-diderot.fr/wp-content/uploads/cours/INFOGRAPHIE/08-Raycasting.pdf - * The logic is as follows : - * - This computes one set of point per edge crossings (horizontal/vertical) - * - The origin not being confined to the grid, offsets are computed to - * align the intersections properly - * - The intersections are at multiples of the tangent of the relevant - * angle for the axis of interest, and simply on successive edges of - * the grid for the other one - * - Depending on the orientation, signs must be taken into account - * to work 360° - * - Those formulas consider regular axes (x→,y↑), however the world is - * built around left-handed axes (x→,y↓), so the rendered world is - * mirrored. This also explains some weird signs for rotations. - */ - /* Offsets to get back on the grid from the ray's origin. */ - float hOffsetX; - float hOffsetY; - float vOffsetX; - float vOffsetY; + /* + * Reference used for ray intersection computations : + * https://web.archive.org/web/20220628034315/https://yunes.informatique.univ-paris-diderot.fr/wp-content/uploads/cours/INFOGRAPHIE/08-Raycasting.pdf + * The logic is as follows : + * - This computes one set of point per edge crossings (horizontal/vertical) + * - The origin not being confined to the grid, offsets are computed to + * align the intersections properly + * - The intersections are at multiples of the tangent of the relevant + * angle for the axis of interest, and simply on successive edges of + * the grid for the other one + * - Depending on the orientation, signs must be taken into account + * to work 360° + * - Those formulas consider regular axes (x→,y↑), however the world is + * built around left-handed axes (x→,y↓), so the rendered world is + * mirrored. This also explains some weird signs for rotations. + */ + /* Offsets to get back on the grid from the ray's origin. */ + float hOffsetX; + float hOffsetY; + float vOffsetX; + float vOffsetY; - /* Signs controlling the direction of travel. */ - float hDir; - float vDir; - /* Need offset for rounding in the right direction ? */ - float hRound; - float vRound; + /* Signs controlling the direction of travel. */ + float hDir; + float vDir; + /* Need offset for rounding in the right direction ? */ + float hRound; + float vRound; - float rads = orientation * deg_to_rad; - /* Used for vertical intersections. */ - float rads_offset = (90 - orientation) * deg_to_rad; + float rads = orientation * deg_to_rad; + /* Used for vertical intersections. */ + float rads_offset = (90 - orientation) * deg_to_rad; - /* Tangents used for the different axes. */ - float hTan = tanf(rads); - float vTan = tanf(rads_offset); + /* Tangents used for the different axes. */ + float hTan = tanf(rads); + float vTan = tanf(rads_offset); - /* Check if cos > 0 for horizontal hits formulas. */ - if (orientation < 90 || orientation > 270) { - hOffsetX = ceilf(originY) - originY; - hOffsetY = ceilf(originY); - hDir = +1; - hRound = 0; - } else { - hOffsetX = originY - floorf(originY); - hOffsetY = floorf(originY); - hDir = -1; - hRound = -1; - } - hTan *= hDir; - hOffsetX *= hTan; + /* Check if cos > 0 for horizontal hits formulas. */ + if (orientation < 90 || orientation > 270) { + hOffsetX = ceilf(originY) - originY; + hOffsetY = ceilf(originY); + hDir = +1; + hRound = 0; + } else { + hOffsetX = originY - floorf(originY); + hOffsetY = floorf(originY); + hDir = -1; + hRound = -1; + } + hTan *= hDir; + hOffsetX *= hTan; - /* Check if sin > 0 for vertical hits formulas. */ - if (orientation < 180) { - vOffsetX = ceilf(originX); - vOffsetY = ceilf(originX) - originX; - vDir = 1; - vRound = 0; - } else { - vOffsetX = floorf(originX); - vOffsetY = originX - floorf(originX); - vDir = -1; - vRound = -1; - } - vTan *= vDir; - vOffsetY *= vTan; + /* Check if sin > 0 for vertical hits formulas. */ + if (orientation < 180) { + vOffsetX = ceilf(originX); + vOffsetY = ceilf(originX) - originX; + vDir = 1; + vRound = 0; + } else { + vOffsetX = floorf(originX); + vOffsetY = originX - floorf(originX); + vDir = -1; + vRound = -1; + } + vTan *= vDir; + vOffsetY *= vTan; - /* - * Now we have all the constants and deltas to work with, cast the ray. - * Generated points follow the formulas : - * - h-intersect : (originX + hOffsetX + hTan*i, hOffsetY + hDir*i) - * - v-intersect : (vOffsetX + vDir*i, originY + vOffsetY + vTan*i) - */ - int i = 0; - float hCheckX = originX + hOffsetX; - float hCheckY = hOffsetY; - /* Bounds + sanity check. */ - while (hCheckX >= 0 && hCheckX <= static_cast(w) && + /* + * Now we have all the constants and deltas to work with, cast the ray. + * Generated points follow the formulas : + * - h-intersect : (originX + hOffsetX + hTan*i, hOffsetY + hDir*i) + * - v-intersect : (vOffsetX + vDir*i, originY + vOffsetY + vTan*i) + */ + int i = 0; + float hCheckX = originX + hOffsetX; + float hCheckY = hOffsetY; + /* Bounds + sanity check. */ + while (hCheckX >= 0 && hCheckX <= static_cast(w) && hCheckY >= 0 && hCheckY <= static_cast(h) && i < h) { - if (getBlock(floorf(hCheckX), floorf(hCheckY) + hRound) == BlockType::WALL) { - break; - } + if (getBlock(floorf(hCheckX), floorf(hCheckY) + hRound) == BlockType::WALL) { + break; + } - hCheckX += hTan; - hCheckY += hDir; - i++; - } + hCheckX += hTan; + hCheckY += hDir; + i++; + } - i = 0; - float vCheckX = vOffsetX; - float vCheckY = originY + vOffsetY; + i = 0; + float vCheckX = vOffsetX; + float vCheckY = originY + vOffsetY; - /* Bounds + sanity check. */ - while (vCheckX >= 0 && vCheckX < static_cast(w) && + /* Bounds + sanity check. */ + while (vCheckX >= 0 && vCheckX < static_cast(w) && vCheckY >= 0 && vCheckY < static_cast(h) && i < w) { - if (getBlock(floorf(vCheckX) + vRound, floorf(vCheckY)) == BlockType::WALL) { - break; - } + if (getBlock(floorf(vCheckX) + vRound, floorf(vCheckY)) == BlockType::WALL) { + break; + } - vCheckX += vDir; - vCheckY += vTan; - i++; - } + vCheckX += vDir; + vCheckY += vTan; + i++; + } - /* - * We may or may not have hit something. Check which coordinates are closest - * and use those for computing the apparent size on screen. - */ - float hDist = sqrtf((originX - hCheckX)*(originX - hCheckX) + - (originY - hCheckY)*(originY - hCheckY)); - float vDist = sqrtf((originX - vCheckX)*(originX - vCheckX) + - (originY - vCheckY)*(originY - vCheckY)); + /* + * We may or may not have hit something. Check which coordinates are closest + * and use those for computing the apparent size on screen. + */ + float hDist = sqrtf((originX - hCheckX)*(originX - hCheckX) + + (originY - hCheckY)*(originY - hCheckY)); + float vDist = sqrtf((originX - vCheckX)*(originX - vCheckX) + + (originY - vCheckY)*(originY - vCheckY)); - return hDist > vDist ? vDist : hDist; + return hDist > vDist ? vDist : hDist; } void World::fillColumn(sf::RenderWindow& window, unsigned int column, @@ -227,51 +227,51 @@ void World::render(sf::RenderWindow& window) const { float windowX = static_cast(window.getSize().x); float windowY = static_cast(window.getSize().y); - /* - * Draw ground and sky planes through half of the screen, as the walls - * will get drawn over them. - * This doesn't work if we support textures/levels. - */ - sf::RectangleShape ground = sf::RectangleShape(sf::Vector2f(windowX,windowY/2.0f)); - ground.setFillColor(groundColor); - ground.setPosition(0,windowY/2.0f); + /* + * Draw ground and sky planes through half of the screen, as the walls + * will get drawn over them. + * This doesn't work if we support textures/levels. + */ + sf::RectangleShape ground = sf::RectangleShape(sf::Vector2f(windowX,windowY/2.0f)); + ground.setFillColor(groundColor); + ground.setPosition(0,windowY/2.0f); - sf::RectangleShape ceiling = sf::RectangleShape(sf::Vector2f(windowX,windowY/2.0f)); - ceiling.setFillColor(ceilingColor); + sf::RectangleShape ceiling = sf::RectangleShape(sf::Vector2f(windowX,windowY/2.0f)); + ceiling.setFillColor(ceilingColor); - window.draw(ground); - window.draw(ceiling); + window.draw(ground); + window.draw(ceiling); const float worldToCamera = (player.focalLength*2)/player.sensorSize; - /* - * Throw rays and draw walls over the ceiling and ground. - * Only throws in the plane, which doesn't work for levels/3D. - */ - for(unsigned int i = 0 ; i < window.getSize().x ; i++) - { - float deltaAngle = (player.fov/windowX) * (static_cast(i)-windowX/2.0f); - float rayAngle = player.orientation + deltaAngle; - if (rayAngle < 0) { - rayAngle += 360; - } else if (rayAngle > 360) { - rayAngle -= 360; - } - float obstacleScale = worldToCamera / castRay(player.x, player.y, rayAngle); - /* 2 Is wall height in meters. */ - fillColumn(window, i, obstacleScale); - } + /* + * Throw rays and draw walls over the ceiling and ground. + * Only throws in the plane, which doesn't work for levels/3D. + */ + for(unsigned int i = 0 ; i < window.getSize().x ; i++) + { + float deltaAngle = (player.fov/windowX) * (static_cast(i)-windowX/2.0f); + float rayAngle = player.orientation + deltaAngle; + if (rayAngle < 0) { + rayAngle += 360; + } else if (rayAngle > 360) { + rayAngle -= 360; + } + float obstacleScale = worldToCamera / castRay(player.x, player.y, rayAngle); + /* 2 Is wall height in meters. */ + fillColumn(window, i, obstacleScale); + } } void World::step(const float& stepTime) { - player.move(player.currentMoveSpeedX*stepTime, - player.currentMoveSpeedY*stepTime); + player.move(player.currentMoveSpeedX*stepTime, + player.currentMoveSpeedY*stepTime); /* Undo last move if the player would end up in a wall. */ if (getBlock(player.x, player.y) != BlockType::AIR) { player.move(-player.currentMoveSpeedX*stepTime, -player.currentMoveSpeedY*stepTime); } - player.rotate(player.currentRotationSpeed*stepTime); + player.rotate(player.currentRotationSpeed*stepTime); #ifdef IMGUI if (ImGui::Begin("MapEdit")) { diff --git a/World.h b/World.h index 19c503a..43b4b1e 100644 --- a/World.h +++ b/World.h @@ -14,54 +14,54 @@ #include "Player.h" enum class BlockType { - AIR, - WALL, - DOOR, - WINDOW, + AIR, + WALL, + DOOR, + WINDOW, }; class World { public: - Player player; + Player player; - World(int w, int h, - sf::Color groundColor = Colors::Ground, - sf::Color ceilingColor = Colors::Ceiling, - std::vector worldMap = {}); - int getW() const; - int getH() const; + World(int w, int h, + sf::Color groundColor = Colors::Ground, + sf::Color ceilingColor = Colors::Ceiling, + std::vector worldMap = {}); + int getW() const; + int getH() const; inline BlockType getBlock(int x, int y) const; inline BlockType getBlock(float x, float y) const; void setBlock(BlockType block, int x, int y, int width = 1, int height = 1); - void render(sf::RenderWindow&) const; + void render(sf::RenderWindow&) const; - /** - * Move the world one step forward. - * @param stepTime delta time since last step, in seconds - */ - void step(const float& stepTime); + /** + * Move the world one step forward. + * @param stepTime delta time since last step, in seconds + */ + void step(const float& stepTime); - friend std::ostream& operator<<(std::ostream& ostream, World const & world); + friend std::ostream& operator<<(std::ostream& ostream, World const & world); private: - int w; - int h; - std::vector map; + int w; + int h; + std::vector map; - sf::Color groundColor; - sf::Color ceilingColor; + sf::Color groundColor; + sf::Color ceilingColor; - void fillColumn(sf::RenderWindow&, unsigned int column, float scale, - sf::Color fillColor = Colors::Wall) const; - /** - * Cast a ray from a given position and return its distance to the origin. - * @param originX Ray X origin, strictly positive - * @param originY Ray Y origin, strictly positive - * @param orientation Angle to cast to, in degrees between 0 and 360 - * @return Distance of the hit to the origin. - */ - float castRay(float originX, float originY, float orientation) const; + void fillColumn(sf::RenderWindow&, unsigned int column, float scale, + sf::Color fillColor = Colors::Wall) const; + /** + * Cast a ray from a given position and return its distance to the origin. + * @param originX Ray X origin, strictly positive + * @param originY Ray Y origin, strictly positive + * @param orientation Angle to cast to, in degrees between 0 and 360 + * @return Distance of the hit to the origin. + */ + float castRay(float originX, float originY, float orientation) const; }; diff --git a/main.cpp b/main.cpp index af75df6..3f91470 100644 --- a/main.cpp +++ b/main.cpp @@ -12,13 +12,13 @@ int main() { - World world(32,32); - world.setBlock(BlockType::AIR,1,1,30,30); - world.setBlock(BlockType::WALL,4,4,2,2); - world.player.move(2,2); - std::cout << world << std::endl; + World world(32,32); + world.setBlock(BlockType::AIR,1,1,30,30); + world.setBlock(BlockType::WALL,4,4,2,2); + world.player.move(2,2); + std::cout << world << std::endl; - sf::RenderWindow window(sf::VideoMode(1000,1000),"Da raycasting"); + sf::RenderWindow window(sf::VideoMode(1000,1000),"Da raycasting"); #ifdef IMGUI if (!ImGui::SFML::Init(window)) { std::cout << "Failed to init Dear ImGui SFML" << std::endl; @@ -31,12 +31,12 @@ int main() // window.setFramerateLimit(60); - sf::Event event{}; - sf::Clock frameTime; - while (window.isOpen()) - { - while (window.pollEvent(event)) - { + sf::Event event{}; + sf::Clock frameTime; + while (window.isOpen()) + { + while (window.pollEvent(event)) + { if (event.type == sf::Event::Closed) { window.close(); continue; @@ -56,43 +56,43 @@ int main() if (io.WantCaptureMouse || io.WantCaptureKeyboard) continue; #endif - if (event.type == sf::Event::KeyPressed) { - switch (event.key.code) { - case sf::Keyboard::Key::Escape: - window.close(); - break; - case sf::Keyboard::Key::Left: - world.player.currentRotationSpeed = -world.player.rotationSpeed; - break; - case sf::Keyboard::Key::Right: - world.player.currentRotationSpeed = world.player.rotationSpeed; - break; + if (event.type == sf::Event::KeyPressed) { + switch (event.key.code) { + case sf::Keyboard::Key::Escape: + window.close(); + break; + case sf::Keyboard::Key::Left: + world.player.currentRotationSpeed = -world.player.rotationSpeed; + break; + case sf::Keyboard::Key::Right: + world.player.currentRotationSpeed = world.player.rotationSpeed; + break; case sf::Keyboard::Key::Up: world.player.updateSpeed(1, 0); break; case sf::Keyboard::Key::Down: world.player.updateSpeed(-1, 0); break; - default: - break; - } - } - else if (event.type == sf::Event::KeyReleased) { - switch (event.key.code) { - case sf::Keyboard::Key::Left: - case sf::Keyboard::Key::Right: - world.player.currentRotationSpeed = 0; - break; + default: + break; + } + } + else if (event.type == sf::Event::KeyReleased) { + switch (event.key.code) { + case sf::Keyboard::Key::Left: + case sf::Keyboard::Key::Right: + world.player.currentRotationSpeed = 0; + break; case sf::Keyboard::Key::Up: case sf::Keyboard::Key::Down: world.player.updateSpeed(0, 0); break; - default: - break; - } - } - } - window.clear(); + default: + break; + } + } + } + window.clear(); const sf::Time& deltaT = frameTime.restart(); #ifdef IMGUI @@ -100,7 +100,7 @@ int main() #endif world.step(deltaT.asSeconds()); - world.render(window); + world.render(window); #ifdef IMGUI // ImGui::ShowDemoWindow(); @@ -126,11 +126,11 @@ int main() ImGui::SFML::Render(window); #endif - window.display(); - } + window.display(); + } #ifdef IMGUI ImGui::SFML::Shutdown(); #endif - return 0; + return 0; }