minor code update

-Ray.cpp and Ray.h have been removed from the project
-added constructVertexArray() which can take any object that inherits from sf::Shape and create a vertex array with the same shape with approriate transforms taken into account
This commit is contained in:
Joseph Aquino 2025-04-22 14:25:35 -04:00
parent 5d3df8e1b9
commit d50487f484
8 changed files with 38 additions and 261 deletions

View File

@ -93,6 +93,7 @@ void Light::createAndSortRays(const std::vector<sf::VertexArray>& polygons)
} }
sf::Angle angle; sf::Angle angle;
const float infiniteLength = 5000.f * hasFlags(Flags::infiniteLength);
for (auto& poly : polygons) for (auto& poly : polygons)
{ {
@ -103,8 +104,8 @@ void Light::createAndSortRays(const std::vector<sf::VertexArray>& polygons)
angle = sf::radians(std::atan2f(poly[i].position.y - m_origin.y, poly[i].position.x - m_origin.x)); angle = sf::radians(std::atan2f(poly[i].position.y - m_origin.y, poly[i].position.x - m_origin.x));
m_rays.emplace_back(sf::Vertex{ poly[i].position, m_lightColor }); m_rays.emplace_back(sf::Vertex{ poly[i].position, m_lightColor });
m_rays.emplace_back(sf::Vertex{ constructVector( m_origin, angle + sf::radians(.00001f), m_rayLength + (5000.f * hasFlags(Flags::infiniteLength)) ), m_lightColor }); m_rays.emplace_back(sf::Vertex{ constructVector( m_origin, angle + sf::radians(.00001f), m_rayLength + infiniteLength), m_lightColor });
m_rays.emplace_back(sf::Vertex{ constructVector( m_origin, angle - sf::radians(.00001f), m_rayLength + (5000.f * hasFlags(Flags::infiniteLength)) ), m_lightColor }); m_rays.emplace_back(sf::Vertex{ constructVector( m_origin, angle - sf::radians(.00001f), m_rayLength + infiniteLength), m_lightColor });
} }
} }
@ -114,9 +115,9 @@ void Light::createAndSortRays(const std::vector<sf::VertexArray>& polygons)
// overload for bounded light // overload for bounded light
void Light::createAndSortRays(const std::vector<sf::VertexArray>& polygons, sf::Angle lowerAngleBounds, sf::Angle upperAngleBounds) void Light::createAndSortRays(const std::vector<sf::VertexArray>& polygons, sf::Angle lowerAngleBounds, sf::Angle upperAngleBounds)
{ {
const float infiniteLength = 5000.f * hasFlags(Flags::infiniteLength);
sf::Vertex lowerBound{ constructVector( m_origin, lowerAngleBounds, m_rayLength + (5000.f * hasFlags(Flags::infiniteLength)) ), m_lightColor }; sf::Vertex lowerBound{ constructVector( m_origin, lowerAngleBounds, m_rayLength + infiniteLength), m_lightColor };
sf::Vertex upperBound{ constructVector( m_origin, upperAngleBounds, m_rayLength + (5000.f * hasFlags(Flags::infiniteLength)) ), m_lightColor }; sf::Vertex upperBound{ constructVector( m_origin, upperAngleBounds, m_rayLength + infiniteLength), m_lightColor };
auto lowerBoundVector = lowerBound.position - m_origin; auto lowerBoundVector = lowerBound.position - m_origin;
auto upperBoundVector = upperBound.position - m_origin; auto upperBoundVector = upperBound.position - m_origin;
@ -132,7 +133,6 @@ void Light::createAndSortRays(const std::vector<sf::VertexArray>& polygons, sf::
} }
} }
constexpr float infiniteLength = 5000.f;
sf::Angle angle; sf::Angle angle;
for (auto& poly : polygons) for (auto& poly : polygons)
@ -148,8 +148,8 @@ void Light::createAndSortRays(const std::vector<sf::VertexArray>& polygons, sf::
angle = sf::radians(std::atan2f(poly[i].position.y - m_origin.y, poly[i].position.x - m_origin.x)); angle = sf::radians(std::atan2f(poly[i].position.y - m_origin.y, poly[i].position.x - m_origin.x));
m_rays.emplace_back(sf::Vertex{ poly[i].position, m_lightColor }); m_rays.emplace_back(sf::Vertex{ poly[i].position, m_lightColor });
m_rays.emplace_back(sf::Vertex{ constructVector( m_origin, angle + sf::radians(.00001f), m_rayLength + (infiniteLength * hasFlags(Flags::infiniteLength)) ), m_lightColor }); m_rays.emplace_back(sf::Vertex{ constructVector( m_origin, angle + sf::radians(.00001f), m_rayLength + infiniteLength), m_lightColor });
m_rays.emplace_back(sf::Vertex{ constructVector( m_origin, angle - sf::radians(.00001f), m_rayLength + (infiniteLength * hasFlags(Flags::infiniteLength)) ), m_lightColor }); m_rays.emplace_back(sf::Vertex{ constructVector( m_origin, angle - sf::radians(.00001f), m_rayLength + infiniteLength), m_lightColor });
} }
} }
@ -190,4 +190,3 @@ bool Light::withinBounds(sf::Vector2f point, sf::Vector2f lower, sf::Vector2f up
{ {
return point.angleTo(upper).wrapUnsigned().asRadians() < (lower).angleTo(upper).wrapUnsigned().asRadians(); return point.angleTo(upper).wrapUnsigned().asRadians() < (lower).angleTo(upper).wrapUnsigned().asRadians();
} }

View File

@ -32,6 +32,7 @@ public:
visible ? setFlags(Flags::visibility) : unsetFlags(Flags::visibility); visible ? setFlags(Flags::visibility) : unsetFlags(Flags::visibility);
} }
public:
enum class Flags enum class Flags
{ {
visibility = 1 << 0, visibility = 1 << 0,
@ -96,7 +97,6 @@ private:
int m_rayCount{ 500 }; int m_rayCount{ 500 };
int m_flags{}; int m_flags{};
enum enum
{ {
start, start,

189
Ray.cpp
View File

@ -1,189 +0,0 @@
#include "Ray.h"
Ray::Ray(sf::Vector2f startPoint, sf::Vector2f endPoint, sf::Color color)
{
m_points[start].position = startPoint;
m_points[start].color = color;
m_points[end].position = endPoint;
m_points[end].color = color;
if (m_points[start].position - m_points[end].position == sf::Vector2f{ 0.f, 0.f })
{
m_angle = sf::Angle::Zero;
}
else
{
m_angle = sf::radians(std::atan2f(m_points[end].position.y - m_points[start].position.y, m_points[end].position.x - m_points[start].position.x));
}
}
Ray::Ray(sf::Vector2f startPoint, float length, sf::Angle angle, sf::Color color)
{
m_points[start].position = startPoint;
m_points[start].color = color;
m_points[end].position = constructVector(startPoint, angle, length);
m_points[end].color = color;
m_angle = angle;
}
Ray::Ray(const Ray& ray)
{
auto& newPoints = ray.points();
m_points[start].position = newPoints[start].position;
m_points[start].color = newPoints[start].color;
m_points[end].position = newPoints[end].position;
m_points[end].color = newPoints[end].color;
m_angle = ray.angle();
}
void Ray::change(const Ray& ray, bool copyColor)
{
auto& newPoints = ray.points();
m_points[start].position = newPoints[start].position;
m_points[end].position = newPoints[end].position;
if (copyColor)
{
m_points[start].color = newPoints[start].color;
m_points[end].color = newPoints[0].color;
}
m_angle = ray.angle();
}
void Ray::change(sf::Vector2f startPoint, sf::Vector2f endPoint)
{
m_points[start].position = startPoint;
m_points[end].position = endPoint;
if (m_points[start].position - m_points[end].position == sf::Vector2f{ 0.f, 0.f })
{
m_angle = sf::Angle::Zero;
}
else
{
m_angle = sf::radians(std::atan2f(m_points[end].position.y - m_points[start].position.y, m_points[end].position.x - m_points[start].position.x));
}
}
void Ray::change(sf::Vector2f startPoint, sf::Vector2f endPoint, sf::Color color)
{
m_points[start].position = startPoint;
m_points[start].color = color;
m_points[end].position = endPoint;
m_points[end].color = color;
if (m_points[start].position - m_points[end].position == sf::Vector2f{ 0.f, 0.f })
{
m_angle = sf::Angle::Zero;
}
else
{
m_angle = sf::radians(std::atan2f(m_points[end].position.y - m_points[start].position.y, m_points[end].position.x - m_points[start].position.x));
}
}
void Ray::changeStart(sf::Vector2f startPoint, sf::Color color)
{
m_points[start].position = startPoint;
m_points[start].color = color;
if (m_points[start].position - m_points[end].position == sf::Vector2f{ 0.f, 0.f })
{
m_angle = sf::Angle::Zero;
}
else
{
m_angle = sf::radians(std::atan2f(m_points[end].position.y - m_points[start].position.y, m_points[end].position.x - m_points[start].position.x));
}
}
void Ray::changeStart(sf::Vector2f startPoint)
{
m_points[start].position = startPoint;
if (m_points[start].position - m_points[end].position == sf::Vector2f{ 0.f, 0.f })
{
m_angle = sf::Angle::Zero;
}
else
{
m_angle = sf::radians(std::atan2f(m_points[end].position.y - m_points[start].position.y, m_points[end].position.x - m_points[start].position.x));
}
}
void Ray::changeStart(const Ray& ray, bool copyColor)
{
auto& newStart = ray.points()[0];
m_points[start].position = newStart.position;
if (copyColor) m_points[start].color = newStart.color;
if (m_points[start].position - m_points[end].position == sf::Vector2f{ 0.f, 0.f })
{
m_angle = sf::Angle::Zero;
}
else
{
m_angle = sf::radians(std::atan2f(m_points[end].position.y - m_points[start].position.y, m_points[end].position.x - m_points[start].position.x));
}
}
void Ray::changeEnd(sf::Vector2f endPoint, sf::Color color)
{
m_points[end].position = endPoint;
m_points[end].color = color;
if (m_points[start].position - m_points[end].position == sf::Vector2f{ 0.f, 0.f })
{
m_angle = sf::Angle::Zero;
}
else
{
m_angle = sf::radians(std::atan2f(m_points[end].position.y - m_points[start].position.y, m_points[end].position.x - m_points[start].position.x));
}
}
void Ray::changeEnd(sf::Vector2f endPoint)
{
m_points[end].position = endPoint;
if (m_points[start].position - m_points[end].position == sf::Vector2f{ 0.f, 0.f })
{
m_angle = sf::Angle::Zero;
}
else
{
m_angle = sf::radians(std::atan2f(m_points[end].position.y - m_points[start].position.y, m_points[end].position.x - m_points[start].position.x));
}
}
void Ray::changeEnd(const Ray& ray, bool copyColor)
{
auto& newEnd = ray.points()[end];
m_points[end].position = newEnd.position;
if (copyColor) m_points[end].color = newEnd.color;
if (m_points[start].position - m_points[end].position == sf::Vector2f{ 0.f, 0.f })
{
m_angle = sf::Angle::Zero;
}
else
{
m_angle = sf::radians(std::atan2f(m_points[end].position.y - m_points[start].position.y, m_points[end].position.x - m_points[start].position.x));
}
}
void Ray::changeColor(sf::Color color)
{
m_points[start].color = color;
m_points[end].color = color;
}
void Ray::calculateIntersect(const std::vector<sf::VertexArray>& polygons)
{
sf::Vector2f closestIntersection = m_points[end].position;
std::optional<sf::Vector2f> currentIntersect{};
for (auto& poly : polygons)
{
for (int i = 1; i <= poly.getVertexCount() - 1; i++) {
currentIntersect = lineIntersect({ m_points[start].position, m_points[end].position }, { poly[i - 1].position , poly[i].position });
if (currentIntersect)
{
if ((closestIntersection - m_points[start].position).length() > (currentIntersect.value() - m_points[start].position).length())
{
closestIntersection = currentIntersect.value();
}
}
}
}
changeEnd(closestIntersection);
}

54
Ray.h
View File

@ -1,54 +0,0 @@
#pragma once
#include <cmath>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstddef>
#include <SFML/Graphics.hpp>
#include <imgui-SFML.h>
#include <imgui.h>
#include "Utility.hpp"
//used for sf::VertexArray index
enum
{
start,
end
};
class Ray
{
public:
Ray(sf::Vector2f startPoint, sf::Vector2f endPoint, sf::Color color = sf::Color::Red);
Ray(sf::Vector2f startPoint, float length, sf::Angle angle, sf::Color color = sf::Color::Red);
Ray(const Ray& ray);
~Ray() = default;
const sf::Angle& angle() const { return m_angle; }
const sf::VertexArray& points() const { return m_points; }
void change(const Ray& ray, bool copyColor = false);
void change(sf::Vector2f startPoint, sf::Vector2f endPoint);
void change(sf::Vector2f startPoint, sf::Vector2f endPoint, sf::Color color);
void changeStart(sf::Vector2f startPoint, sf::Color color);
void changeStart(sf::Vector2f startPoint);
void changeStart(const Ray& ray, bool copyColor = false);
void changeEnd(sf::Vector2f endPoint, sf::Color color);
void changeEnd(sf::Vector2f endPoint);
void changeEnd(const Ray& ray, bool copyColor = false);
void changeColor(sf::Color color);
void calculateIntersect(const std::vector<sf::VertexArray>& polygons);
private:
sf::VertexArray m_points{ sf::PrimitiveType::Lines, 2 };//points[0] = origin of ray, points[1] = end of ray
sf::Angle m_angle{};
};
using RayVector = std::vector<Ray>;

View File

@ -102,7 +102,6 @@ inline sf::VertexArray constructRectangle(sf::Vector2f center, sf::Vector2f size
rectangle[4].position = rectangle[0].position; rectangle[4].position = rectangle[0].position;
return rectangle; return rectangle;
} }
inline sf::Vector2f constructVector(sf::Vector2f startPoint, sf::Angle angle, float length) inline sf::Vector2f constructVector(sf::Vector2f startPoint, sf::Angle angle, float length)
@ -133,3 +132,17 @@ inline float distanceBetween(sf::Vector2f startPoint, sf::Vector2f endPoint)
{ {
return sqrtf(powf(endPoint.x - startPoint.x, 2) + powf(endPoint.y - startPoint.y, 2)); return sqrtf(powf(endPoint.x - startPoint.x, 2) + powf(endPoint.y - startPoint.y, 2));
} }
inline sf::VertexArray constructVertexArray(sf::Shape& shape)
{
sf::VertexArray result(sf::PrimitiveType::LineStrip);
auto& transform = shape.getTransform();
for (int i = 0; i < shape.getPointCount(); i++)
{
result.append(sf::Vertex{ transform.transformPoint(shape.getPoint(i)), sf::Color::Black });
}
result.append(result[0]);
return result;
}

View File

@ -3,6 +3,6 @@ Pos=60,60
Size=400,400 Size=400,400
[Window][Config] [Window][Config]
Pos=6,12 Pos=7,12
Size=670,442 Size=670,442

View File

@ -9,7 +9,6 @@
#include <imgui.h> #include <imgui.h>
#include "Utility.hpp" #include "Utility.hpp"
#include "Ray.h"
#include "Light.h" #include "Light.h"
@ -17,6 +16,7 @@ auto window = sf::RenderWindow(sf::VideoMode({ 1920u, 1080u }), "Ray Casting Tes
Light light; Light light;
std::vector<sf::VertexArray> polygons; std::vector<sf::VertexArray> polygons;
sf::CircleShape circle{};
sf::Vector2f mousePos{}; sf::Vector2f mousePos{};
sf::Vector2f center{ 1920.f / 2.f, 1080.f / 2.f }; sf::Vector2f center{ 1920.f / 2.f, 1080.f / 2.f };
@ -53,6 +53,7 @@ int main()
//configure light with default imgui vatiables //configure light with default imgui vatiables
drawRays ? light.setFlags(Light::Flags::drawRays) : light.unsetFlags(Light::Flags::drawRays); drawRays ? light.setFlags(Light::Flags::drawRays) : light.unsetFlags(Light::Flags::drawRays);
drawLight ? light.setFlags(Light::Flags::visibility) : light.unsetFlags(Light::Flags::visibility); drawLight ? light.setFlags(Light::Flags::visibility) : light.unsetFlags(Light::Flags::visibility);
boundedLight ? light.addAngleBounds(sf::degrees(lightCenterAngle), sf::degrees(lightOffsetAngle)) : light.removeAngleBounds();
drawEndPoints ? light.setFlags(Light::Flags::drawEndPoints) : light.unsetFlags(Light::Flags::drawEndPoints); drawEndPoints ? light.setFlags(Light::Flags::drawEndPoints) : light.unsetFlags(Light::Flags::drawEndPoints);
infiniteRayLength ? light.setFlags(Light::Flags::infiniteLength) : light.unsetFlags(Light::Flags::infiniteLength); infiniteRayLength ? light.setFlags(Light::Flags::infiniteLength) : light.unsetFlags(Light::Flags::infiniteLength);
@ -66,6 +67,12 @@ int main()
polygons.emplace_back(constructRectangle(center, center)); polygons.emplace_back(constructRectangle(center, center));
circle.setOrigin({0,0});
circle.setPosition(center);
circle.setRadius(200.f);
circle.setPointCount(30u);
polygons.emplace_back(constructVertexArray(circle));
//main game loop //main game loop
while (window.isOpen()) while (window.isOpen())
{ {
@ -145,6 +152,7 @@ void GUI()
{ {
ImGui::ColorEdit4("End point color", &endPointColor.r); ImGui::ColorEdit4("End point color", &endPointColor.r);
} }
light.changeLightColor(lightColor.asSfColor()); light.changeLightColor(lightColor.asSfColor());
light.changeEndPointColor(endPointColor.asSfColor()); light.changeEndPointColor(endPointColor.asSfColor());
light.changeRayColor(rayColor.asSfColor()); light.changeRayColor(rayColor.asSfColor());

View File

@ -104,14 +104,14 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SFML_DIR)\include;$(IMGUI_SFML_DIR);C:\dev\libraries\opengl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SFML_DIR)\include;$(IMGUI_SFML_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
<AssemblerOutput>AssemblyCode</AssemblerOutput> <AssemblerOutput>AssemblyCode</AssemblerOutput>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SFML_DIR)\lib;C:\dev\libraries\opengl\lib-vc2022;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(SFML_DIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>sfml-graphics-d.lib;sfml-system-d.lib;sfml-window-d.lib;sfml-audio-d.lib;sfml-network-d.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>sfml-graphics-d.lib;sfml-system-d.lib;sfml-window-d.lib;sfml-audio-d.lib;sfml-network-d.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -123,7 +123,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\dev\libraries\SFML-3.0.0\include;C:\dev\libraries\imgui;C:\dev\libraries\opengl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(IMGUI_SFML_DIR);$(SFML_DIR)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
@ -131,7 +131,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\dev\libraries\SFML-3.0.0\lib;C:\dev\libraries\opengl\lib-vc2022;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(SFML_DIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>sfml-graphics.lib;sfml-system.lib;sfml-window.lib;sfml-audio.lib;sfml-network.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>sfml-graphics.lib;sfml-system.lib;sfml-window.lib;sfml-audio.lib;sfml-network.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol> <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
</Link> </Link>