From ea043f719cd4e38ed675dd48ad4f1407d65499a8 Mon Sep 17 00:00:00 2001 From: Joseph Aquino Date: Tue, 14 Apr 2026 02:55:37 -0400 Subject: [PATCH] forgot to add files --- Create-Solution.bat | 2 + build-ninja.sh | 5 + build.sh | 5 + clean-ninja.sh | 3 + clean.sh | 7 + ecc.sh | 3 + include/Light.h | 117 + include/Random.h | 77 + include/Utility.hpp | 153 + premake5.lua | 148 + run.sh | 3 + src/Light.cpp | 192 + src/main.cpp | 276 + vendor/SFML/include/SFML/Audio.hpp | 55 + .../SFML/include/SFML/Audio/AudioResource.hpp | 93 + vendor/SFML/include/SFML/Audio/Export.hpp | 44 + .../include/SFML/Audio/InputSoundFile.hpp | 336 + vendor/SFML/include/SFML/Audio/Listener.hpp | 234 + vendor/SFML/include/SFML/Audio/Music.hpp | 377 + .../include/SFML/Audio/OutputSoundFile.hpp | 147 + .../include/SFML/Audio/PlaybackDevice.hpp | 110 + vendor/SFML/include/SFML/Audio/Sound.hpp | 284 + .../SFML/include/SFML/Audio/SoundBuffer.hpp | 451 + .../SFML/Audio/SoundBufferRecorder.hpp | 149 + .../SFML/include/SFML/Audio/SoundChannel.hpp | 65 + .../include/SFML/Audio/SoundFileFactory.hpp | 200 + .../include/SFML/Audio/SoundFileFactory.inl | 96 + .../include/SFML/Audio/SoundFileReader.hpp | 167 + .../include/SFML/Audio/SoundFileWriter.hpp | 130 + .../SFML/include/SFML/Audio/SoundRecorder.hpp | 362 + .../SFML/include/SFML/Audio/SoundSource.hpp | 686 + .../SFML/include/SFML/Audio/SoundStream.hpp | 385 + vendor/SFML/include/SFML/Config.hpp | 156 + vendor/SFML/include/SFML/GpuPreference.hpp | 70 + vendor/SFML/include/SFML/Graphics.hpp | 67 + .../SFML/include/SFML/Graphics/BlendMode.hpp | 220 + .../include/SFML/Graphics/CircleShape.hpp | 165 + vendor/SFML/include/SFML/Graphics/Color.hpp | 274 + vendor/SFML/include/SFML/Graphics/Color.inl | 156 + .../include/SFML/Graphics/ConvexShape.hpp | 155 + .../include/SFML/Graphics/CoordinateType.hpp | 43 + .../SFML/include/SFML/Graphics/Drawable.hpp | 120 + vendor/SFML/include/SFML/Graphics/Export.hpp | 44 + vendor/SFML/include/SFML/Graphics/Font.hpp | 531 + vendor/SFML/include/SFML/Graphics/Glsl.hpp | 224 + vendor/SFML/include/SFML/Graphics/Glsl.inl | 177 + vendor/SFML/include/SFML/Graphics/Glyph.hpp | 67 + vendor/SFML/include/SFML/Graphics/Image.hpp | 417 + .../include/SFML/Graphics/PrimitiveType.hpp | 48 + vendor/SFML/include/SFML/Graphics/Rect.hpp | 203 + vendor/SFML/include/SFML/Graphics/Rect.inl | 130 + .../include/SFML/Graphics/RectangleShape.hpp | 143 + .../include/SFML/Graphics/RenderStates.hpp | 191 + .../include/SFML/Graphics/RenderTarget.hpp | 606 + .../include/SFML/Graphics/RenderTexture.hpp | 342 + .../include/SFML/Graphics/RenderWindow.hpp | 308 + vendor/SFML/include/SFML/Graphics/Shader.hpp | 1023 + vendor/SFML/include/SFML/Graphics/Shape.hpp | 357 + vendor/SFML/include/SFML/Graphics/Sprite.hpp | 278 + .../include/SFML/Graphics/StencilMode.hpp | 256 + vendor/SFML/include/SFML/Graphics/Text.hpp | 486 + vendor/SFML/include/SFML/Graphics/Texture.hpp | 874 + .../SFML/include/SFML/Graphics/Transform.hpp | 393 + .../SFML/include/SFML/Graphics/Transform.inl | 236 + .../include/SFML/Graphics/Transformable.hpp | 340 + vendor/SFML/include/SFML/Graphics/Vertex.hpp | 122 + .../include/SFML/Graphics/VertexArray.hpp | 223 + .../include/SFML/Graphics/VertexBuffer.hpp | 414 + vendor/SFML/include/SFML/Graphics/View.hpp | 357 + vendor/SFML/include/SFML/Main.hpp | 39 + vendor/SFML/include/SFML/Network.hpp | 51 + vendor/SFML/include/SFML/Network/Export.hpp | 44 + vendor/SFML/include/SFML/Network/Ftp.hpp | 629 + vendor/SFML/include/SFML/Network/Http.hpp | 480 + .../SFML/include/SFML/Network/IpAddress.hpp | 297 + vendor/SFML/include/SFML/Network/Packet.hpp | 552 + vendor/SFML/include/SFML/Network/Socket.hpp | 229 + .../include/SFML/Network/SocketHandle.hpp | 52 + .../include/SFML/Network/SocketSelector.hpp | 273 + .../SFML/include/SFML/Network/TcpListener.hpp | 166 + .../SFML/include/SFML/Network/TcpSocket.hpp | 317 + .../SFML/include/SFML/Network/UdpSocket.hpp | 293 + vendor/SFML/include/SFML/OpenGL.hpp | 78 + vendor/SFML/include/SFML/System.hpp | 55 + vendor/SFML/include/SFML/System/Angle.hpp | 511 + vendor/SFML/include/SFML/System/Angle.inl | 274 + vendor/SFML/include/SFML/System/Clock.hpp | 196 + vendor/SFML/include/SFML/System/Err.hpp | 77 + vendor/SFML/include/SFML/System/Exception.hpp | 46 + vendor/SFML/include/SFML/System/Export.hpp | 44 + .../include/SFML/System/FileInputStream.hpp | 212 + .../SFML/include/SFML/System/InputStream.hpp | 166 + .../include/SFML/System/MemoryInputStream.hpp | 139 + .../include/SFML/System/NativeActivity.hpp | 58 + vendor/SFML/include/SFML/System/Sleep.hpp | 57 + vendor/SFML/include/SFML/System/String.hpp | 700 + vendor/SFML/include/SFML/System/String.inl | 64 + .../include/SFML/System/SuspendAwareClock.hpp | 76 + vendor/SFML/include/SFML/System/Time.hpp | 500 + vendor/SFML/include/SFML/System/Time.inl | 284 + vendor/SFML/include/SFML/System/Utf.hpp | 764 + vendor/SFML/include/SFML/System/Utf.inl | 732 + vendor/SFML/include/SFML/System/Vector2.hpp | 435 + vendor/SFML/include/SFML/System/Vector2.inl | 217 + vendor/SFML/include/SFML/System/Vector3.hpp | 356 + vendor/SFML/include/SFML/System/Vector3.inl | 214 + vendor/SFML/include/SFML/Window.hpp | 55 + vendor/SFML/include/SFML/Window/Clipboard.hpp | 114 + vendor/SFML/include/SFML/Window/Context.hpp | 224 + .../include/SFML/Window/ContextSettings.hpp | 125 + vendor/SFML/include/SFML/Window/Cursor.hpp | 303 + vendor/SFML/include/SFML/Window/Event.hpp | 430 + vendor/SFML/include/SFML/Window/Event.inl | 78 + vendor/SFML/include/SFML/Window/Export.hpp | 44 + .../SFML/include/SFML/Window/GlResource.hpp | 122 + vendor/SFML/include/SFML/Window/Joystick.hpp | 213 + vendor/SFML/include/SFML/Window/Keyboard.hpp | 475 + vendor/SFML/include/SFML/Window/Mouse.hpp | 175 + vendor/SFML/include/SFML/Window/Sensor.hpp | 139 + vendor/SFML/include/SFML/Window/Touch.hpp | 131 + vendor/SFML/include/SFML/Window/VideoMode.hpp | 224 + vendor/SFML/include/SFML/Window/Vulkan.hpp | 112 + vendor/SFML/include/SFML/Window/Window.hpp | 422 + .../SFML/include/SFML/Window/WindowBase.hpp | 653 + .../SFML/include/SFML/Window/WindowBase.inl | 75 + .../SFML/include/SFML/Window/WindowEnums.hpp | 60 + .../SFML/include/SFML/Window/WindowHandle.hpp | 98 + vendor/SFML/lib/FLAC.lib | Bin 0 -> 762682 bytes vendor/SFML/lib/FLACd.lib | Bin 0 -> 1915762 bytes vendor/SFML/lib/freetype.lib | Bin 0 -> 1903422 bytes vendor/SFML/lib/freetyped.lib | Bin 0 -> 3694730 bytes vendor/SFML/lib/ogg.lib | Bin 0 -> 49622 bytes vendor/SFML/lib/oggd.lib | Bin 0 -> 80034 bytes vendor/SFML/lib/sfml-audio-s-d.lib | Bin 0 -> 18607622 bytes vendor/SFML/lib/sfml-audio-s.lib | Bin 0 -> 4730942 bytes vendor/SFML/lib/sfml-graphics-s-d.lib | Bin 0 -> 16132912 bytes vendor/SFML/lib/sfml-graphics-s.lib | Bin 0 -> 3647310 bytes vendor/SFML/lib/sfml-main-d.lib | Bin 0 -> 16422 bytes vendor/SFML/lib/sfml-main.lib | Bin 0 -> 1392 bytes vendor/SFML/lib/sfml-network-s-d.lib | Bin 0 -> 7211876 bytes vendor/SFML/lib/sfml-network-s.lib | Bin 0 -> 1996410 bytes vendor/SFML/lib/sfml-system-s-d.lib | Bin 0 -> 2683376 bytes vendor/SFML/lib/sfml-system-s.lib | Bin 0 -> 606082 bytes vendor/SFML/lib/sfml-window-s-d.lib | Bin 0 -> 11547782 bytes vendor/SFML/lib/sfml-window-s.lib | Bin 0 -> 2268398 bytes vendor/SFML/lib/vorbis.lib | Bin 0 -> 1062762 bytes vendor/SFML/lib/vorbisd.lib | Bin 0 -> 1415258 bytes vendor/SFML/lib/vorbisenc.lib | Bin 0 -> 696406 bytes vendor/SFML/lib/vorbisencd.lib | Bin 0 -> 855172 bytes vendor/SFML/lib/vorbisfile.lib | Bin 0 -> 65076 bytes vendor/SFML/lib/vorbisfiled.lib | Bin 0 -> 93846 bytes vendor/SFML/share/doc/SFML/license.md | 9 + vendor/SFML/share/doc/SFML/readme.md | 79 + vendor/imgui/LICENSE | 23 + vendor/imgui/LICENSE.txt | 21 + vendor/imgui/README.md | 284 + vendor/imgui/imconfig-SFML.h | 34 + vendor/imgui/imconfig.h | 176 + vendor/imgui/imgui-SFML.cpp | 1468 ++ vendor/imgui/imgui-SFML.h | 134 + vendor/imgui/imgui-SFML_export.h | 25 + vendor/imgui/imgui.cpp | 16839 ++++++++++++++++ vendor/imgui/imgui.h | 3724 ++++ vendor/imgui/imgui_demo.cpp | 10405 ++++++++++ vendor/imgui/imgui_draw.cpp | 4787 +++++ vendor/imgui/imgui_internal.h | 3585 ++++ vendor/imgui/imgui_tables.cpp | 4468 ++++ vendor/imgui/imgui_widgets.cpp | 10320 ++++++++++ vendor/imgui/imstb_rectpack.h | 627 + vendor/imgui/imstb_textedit.h | 1469 ++ vendor/imgui/imstb_truetype.h | 5085 +++++ vendor/imgui/misc/README.txt | 23 + vendor/imgui/misc/cpp/README.txt | 13 + vendor/imgui/misc/cpp/imgui_stdlib.cpp | 85 + vendor/imgui/misc/cpp/imgui_stdlib.h | 21 + vendor/imgui/misc/debuggers/README.txt | 16 + vendor/imgui/misc/debuggers/imgui.gdb | 12 + .../imgui/misc/debuggers/imgui.natstepfilter | 31 + vendor/imgui/misc/debuggers/imgui.natvis | 58 + vendor/imgui/misc/fonts/Cousine-Regular.ttf | Bin 0 -> 43912 bytes vendor/imgui/misc/fonts/DroidSans.ttf | Bin 0 -> 190044 bytes vendor/imgui/misc/fonts/Karla-Regular.ttf | Bin 0 -> 16848 bytes vendor/imgui/misc/fonts/ProggyClean.ttf | Bin 0 -> 41208 bytes vendor/imgui/misc/fonts/ProggyTiny.ttf | Bin 0 -> 35656 bytes vendor/imgui/misc/fonts/Roboto-Medium.ttf | Bin 0 -> 162588 bytes .../misc/fonts/binary_to_compressed_c.cpp | 424 + vendor/imgui/misc/freetype/README.md | 62 + vendor/imgui/misc/freetype/imgui_freetype.cpp | 969 + vendor/imgui/misc/freetype/imgui_freetype.h | 58 + .../misc/single_file/imgui_single_file.h | 29 + vendor/premake5/LICENSE.txt | 27 + vendor/premake5/ecc/LICENSE.md | 29 + vendor/premake5/ecc/README.md | 49 + vendor/premake5/ecc/_manifest.lua | 4 + vendor/premake5/ecc/_preload.lua | 35 + vendor/premake5/ecc/ecc.lua | 122 + vendor/premake5/ninja/LICENSE | 22 + vendor/premake5/ninja/README.md | 43 + vendor/premake5/ninja/_manifest.lua | 4 + vendor/premake5/ninja/_preload.lua | 60 + vendor/premake5/ninja/ninja.lua | 845 + vendor/premake5/premake5 | Bin 0 -> 2659760 bytes vendor/premake5/premake5.exe | Bin 0 -> 1312256 bytes 203 files changed, 96130 insertions(+) create mode 100644 Create-Solution.bat create mode 100755 build-ninja.sh create mode 100755 build.sh create mode 100644 clean-ninja.sh create mode 100755 clean.sh create mode 100755 ecc.sh create mode 100644 include/Light.h create mode 100644 include/Random.h create mode 100644 include/Utility.hpp create mode 100644 premake5.lua create mode 100755 run.sh create mode 100644 src/Light.cpp create mode 100644 src/main.cpp create mode 100644 vendor/SFML/include/SFML/Audio.hpp create mode 100644 vendor/SFML/include/SFML/Audio/AudioResource.hpp create mode 100644 vendor/SFML/include/SFML/Audio/Export.hpp create mode 100644 vendor/SFML/include/SFML/Audio/InputSoundFile.hpp create mode 100644 vendor/SFML/include/SFML/Audio/Listener.hpp create mode 100644 vendor/SFML/include/SFML/Audio/Music.hpp create mode 100644 vendor/SFML/include/SFML/Audio/OutputSoundFile.hpp create mode 100644 vendor/SFML/include/SFML/Audio/PlaybackDevice.hpp create mode 100644 vendor/SFML/include/SFML/Audio/Sound.hpp create mode 100644 vendor/SFML/include/SFML/Audio/SoundBuffer.hpp create mode 100644 vendor/SFML/include/SFML/Audio/SoundBufferRecorder.hpp create mode 100644 vendor/SFML/include/SFML/Audio/SoundChannel.hpp create mode 100644 vendor/SFML/include/SFML/Audio/SoundFileFactory.hpp create mode 100644 vendor/SFML/include/SFML/Audio/SoundFileFactory.inl create mode 100644 vendor/SFML/include/SFML/Audio/SoundFileReader.hpp create mode 100644 vendor/SFML/include/SFML/Audio/SoundFileWriter.hpp create mode 100644 vendor/SFML/include/SFML/Audio/SoundRecorder.hpp create mode 100644 vendor/SFML/include/SFML/Audio/SoundSource.hpp create mode 100644 vendor/SFML/include/SFML/Audio/SoundStream.hpp create mode 100644 vendor/SFML/include/SFML/Config.hpp create mode 100644 vendor/SFML/include/SFML/GpuPreference.hpp create mode 100644 vendor/SFML/include/SFML/Graphics.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/BlendMode.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/CircleShape.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Color.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Color.inl create mode 100644 vendor/SFML/include/SFML/Graphics/ConvexShape.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/CoordinateType.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Drawable.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Export.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Font.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Glsl.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Glsl.inl create mode 100644 vendor/SFML/include/SFML/Graphics/Glyph.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Image.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/PrimitiveType.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Rect.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Rect.inl create mode 100644 vendor/SFML/include/SFML/Graphics/RectangleShape.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/RenderStates.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/RenderTarget.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/RenderTexture.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/RenderWindow.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Shader.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Shape.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Sprite.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/StencilMode.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Text.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Texture.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Transform.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Transform.inl create mode 100644 vendor/SFML/include/SFML/Graphics/Transformable.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/Vertex.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/VertexArray.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/VertexBuffer.hpp create mode 100644 vendor/SFML/include/SFML/Graphics/View.hpp create mode 100644 vendor/SFML/include/SFML/Main.hpp create mode 100644 vendor/SFML/include/SFML/Network.hpp create mode 100644 vendor/SFML/include/SFML/Network/Export.hpp create mode 100644 vendor/SFML/include/SFML/Network/Ftp.hpp create mode 100644 vendor/SFML/include/SFML/Network/Http.hpp create mode 100644 vendor/SFML/include/SFML/Network/IpAddress.hpp create mode 100644 vendor/SFML/include/SFML/Network/Packet.hpp create mode 100644 vendor/SFML/include/SFML/Network/Socket.hpp create mode 100644 vendor/SFML/include/SFML/Network/SocketHandle.hpp create mode 100644 vendor/SFML/include/SFML/Network/SocketSelector.hpp create mode 100644 vendor/SFML/include/SFML/Network/TcpListener.hpp create mode 100644 vendor/SFML/include/SFML/Network/TcpSocket.hpp create mode 100644 vendor/SFML/include/SFML/Network/UdpSocket.hpp create mode 100644 vendor/SFML/include/SFML/OpenGL.hpp create mode 100644 vendor/SFML/include/SFML/System.hpp create mode 100644 vendor/SFML/include/SFML/System/Angle.hpp create mode 100644 vendor/SFML/include/SFML/System/Angle.inl create mode 100644 vendor/SFML/include/SFML/System/Clock.hpp create mode 100644 vendor/SFML/include/SFML/System/Err.hpp create mode 100644 vendor/SFML/include/SFML/System/Exception.hpp create mode 100644 vendor/SFML/include/SFML/System/Export.hpp create mode 100644 vendor/SFML/include/SFML/System/FileInputStream.hpp create mode 100644 vendor/SFML/include/SFML/System/InputStream.hpp create mode 100644 vendor/SFML/include/SFML/System/MemoryInputStream.hpp create mode 100644 vendor/SFML/include/SFML/System/NativeActivity.hpp create mode 100644 vendor/SFML/include/SFML/System/Sleep.hpp create mode 100644 vendor/SFML/include/SFML/System/String.hpp create mode 100644 vendor/SFML/include/SFML/System/String.inl create mode 100644 vendor/SFML/include/SFML/System/SuspendAwareClock.hpp create mode 100644 vendor/SFML/include/SFML/System/Time.hpp create mode 100644 vendor/SFML/include/SFML/System/Time.inl create mode 100644 vendor/SFML/include/SFML/System/Utf.hpp create mode 100644 vendor/SFML/include/SFML/System/Utf.inl create mode 100644 vendor/SFML/include/SFML/System/Vector2.hpp create mode 100644 vendor/SFML/include/SFML/System/Vector2.inl create mode 100644 vendor/SFML/include/SFML/System/Vector3.hpp create mode 100644 vendor/SFML/include/SFML/System/Vector3.inl create mode 100644 vendor/SFML/include/SFML/Window.hpp create mode 100644 vendor/SFML/include/SFML/Window/Clipboard.hpp create mode 100644 vendor/SFML/include/SFML/Window/Context.hpp create mode 100644 vendor/SFML/include/SFML/Window/ContextSettings.hpp create mode 100644 vendor/SFML/include/SFML/Window/Cursor.hpp create mode 100644 vendor/SFML/include/SFML/Window/Event.hpp create mode 100644 vendor/SFML/include/SFML/Window/Event.inl create mode 100644 vendor/SFML/include/SFML/Window/Export.hpp create mode 100644 vendor/SFML/include/SFML/Window/GlResource.hpp create mode 100644 vendor/SFML/include/SFML/Window/Joystick.hpp create mode 100644 vendor/SFML/include/SFML/Window/Keyboard.hpp create mode 100644 vendor/SFML/include/SFML/Window/Mouse.hpp create mode 100644 vendor/SFML/include/SFML/Window/Sensor.hpp create mode 100644 vendor/SFML/include/SFML/Window/Touch.hpp create mode 100644 vendor/SFML/include/SFML/Window/VideoMode.hpp create mode 100644 vendor/SFML/include/SFML/Window/Vulkan.hpp create mode 100644 vendor/SFML/include/SFML/Window/Window.hpp create mode 100644 vendor/SFML/include/SFML/Window/WindowBase.hpp create mode 100644 vendor/SFML/include/SFML/Window/WindowBase.inl create mode 100644 vendor/SFML/include/SFML/Window/WindowEnums.hpp create mode 100644 vendor/SFML/include/SFML/Window/WindowHandle.hpp create mode 100644 vendor/SFML/lib/FLAC.lib create mode 100644 vendor/SFML/lib/FLACd.lib create mode 100644 vendor/SFML/lib/freetype.lib create mode 100644 vendor/SFML/lib/freetyped.lib create mode 100644 vendor/SFML/lib/ogg.lib create mode 100644 vendor/SFML/lib/oggd.lib create mode 100644 vendor/SFML/lib/sfml-audio-s-d.lib create mode 100644 vendor/SFML/lib/sfml-audio-s.lib create mode 100644 vendor/SFML/lib/sfml-graphics-s-d.lib create mode 100644 vendor/SFML/lib/sfml-graphics-s.lib create mode 100644 vendor/SFML/lib/sfml-main-d.lib create mode 100644 vendor/SFML/lib/sfml-main.lib create mode 100644 vendor/SFML/lib/sfml-network-s-d.lib create mode 100644 vendor/SFML/lib/sfml-network-s.lib create mode 100644 vendor/SFML/lib/sfml-system-s-d.lib create mode 100644 vendor/SFML/lib/sfml-system-s.lib create mode 100644 vendor/SFML/lib/sfml-window-s-d.lib create mode 100644 vendor/SFML/lib/sfml-window-s.lib create mode 100644 vendor/SFML/lib/vorbis.lib create mode 100644 vendor/SFML/lib/vorbisd.lib create mode 100644 vendor/SFML/lib/vorbisenc.lib create mode 100644 vendor/SFML/lib/vorbisencd.lib create mode 100644 vendor/SFML/lib/vorbisfile.lib create mode 100644 vendor/SFML/lib/vorbisfiled.lib create mode 100644 vendor/SFML/share/doc/SFML/license.md create mode 100644 vendor/SFML/share/doc/SFML/readme.md create mode 100644 vendor/imgui/LICENSE create mode 100644 vendor/imgui/LICENSE.txt create mode 100644 vendor/imgui/README.md create mode 100644 vendor/imgui/imconfig-SFML.h create mode 100644 vendor/imgui/imconfig.h create mode 100644 vendor/imgui/imgui-SFML.cpp create mode 100644 vendor/imgui/imgui-SFML.h create mode 100644 vendor/imgui/imgui-SFML_export.h create mode 100644 vendor/imgui/imgui.cpp create mode 100644 vendor/imgui/imgui.h create mode 100644 vendor/imgui/imgui_demo.cpp create mode 100644 vendor/imgui/imgui_draw.cpp create mode 100644 vendor/imgui/imgui_internal.h create mode 100644 vendor/imgui/imgui_tables.cpp create mode 100644 vendor/imgui/imgui_widgets.cpp create mode 100644 vendor/imgui/imstb_rectpack.h create mode 100644 vendor/imgui/imstb_textedit.h create mode 100644 vendor/imgui/imstb_truetype.h create mode 100644 vendor/imgui/misc/README.txt create mode 100644 vendor/imgui/misc/cpp/README.txt create mode 100644 vendor/imgui/misc/cpp/imgui_stdlib.cpp create mode 100644 vendor/imgui/misc/cpp/imgui_stdlib.h create mode 100644 vendor/imgui/misc/debuggers/README.txt create mode 100644 vendor/imgui/misc/debuggers/imgui.gdb create mode 100644 vendor/imgui/misc/debuggers/imgui.natstepfilter create mode 100644 vendor/imgui/misc/debuggers/imgui.natvis create mode 100644 vendor/imgui/misc/fonts/Cousine-Regular.ttf create mode 100644 vendor/imgui/misc/fonts/DroidSans.ttf create mode 100644 vendor/imgui/misc/fonts/Karla-Regular.ttf create mode 100644 vendor/imgui/misc/fonts/ProggyClean.ttf create mode 100644 vendor/imgui/misc/fonts/ProggyTiny.ttf create mode 100644 vendor/imgui/misc/fonts/Roboto-Medium.ttf create mode 100644 vendor/imgui/misc/fonts/binary_to_compressed_c.cpp create mode 100644 vendor/imgui/misc/freetype/README.md create mode 100644 vendor/imgui/misc/freetype/imgui_freetype.cpp create mode 100644 vendor/imgui/misc/freetype/imgui_freetype.h create mode 100644 vendor/imgui/misc/single_file/imgui_single_file.h create mode 100644 vendor/premake5/LICENSE.txt create mode 100644 vendor/premake5/ecc/LICENSE.md create mode 100644 vendor/premake5/ecc/README.md create mode 100644 vendor/premake5/ecc/_manifest.lua create mode 100644 vendor/premake5/ecc/_preload.lua create mode 100644 vendor/premake5/ecc/ecc.lua create mode 100644 vendor/premake5/ninja/LICENSE create mode 100644 vendor/premake5/ninja/README.md create mode 100644 vendor/premake5/ninja/_manifest.lua create mode 100644 vendor/premake5/ninja/_preload.lua create mode 100644 vendor/premake5/ninja/ninja.lua create mode 100755 vendor/premake5/premake5 create mode 100644 vendor/premake5/premake5.exe diff --git a/Create-Solution.bat b/Create-Solution.bat new file mode 100644 index 0000000..2cd4d72 --- /dev/null +++ b/Create-Solution.bat @@ -0,0 +1,2 @@ +.\vendor\premake5\premake5.exe vs2022 +PAUSE \ No newline at end of file diff --git a/build-ninja.sh b/build-ninja.sh new file mode 100755 index 0000000..c963c86 --- /dev/null +++ b/build-ninja.sh @@ -0,0 +1,5 @@ +#! /bin/bash + +./vendor/premake5/premake5 ecc +./vendor/premake5/premake5 ninja +ninja $1 diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..cdc8fdd --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +#! /bin/bash + +./vendor/premake5/premake5 ecc +./vendor/premake5/premake5 gmake +make config=$1 \ No newline at end of file diff --git a/clean-ninja.sh b/clean-ninja.sh new file mode 100644 index 0000000..4b8a403 --- /dev/null +++ b/clean-ninja.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +ninja clean \ No newline at end of file diff --git a/clean.sh b/clean.sh new file mode 100755 index 0000000..9f7c6eb --- /dev/null +++ b/clean.sh @@ -0,0 +1,7 @@ +#! /bin/bash + if [ -z "$1" ] || [ $# -eq 0 ] + then + make config=debug clean && make config=release clean + else + make config=$1 clean + fi \ No newline at end of file diff --git a/ecc.sh b/ecc.sh new file mode 100755 index 0000000..006ddac --- /dev/null +++ b/ecc.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +./vendor/premake5/premake5 ecc \ No newline at end of file diff --git a/include/Light.h b/include/Light.h new file mode 100644 index 0000000..e31a4ce --- /dev/null +++ b/include/Light.h @@ -0,0 +1,117 @@ +#pragma once +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "Utility.hpp" + +class Light +{ +public: + Light() = default; + + Light(sf::Vector2f origin, bool visible = true) + : m_origin(origin) + { + m_light.push_back(sf::Vertex{ m_origin, m_lightColor}); + visible ? setFlags(Flags::visibility) : unsetFlags(Flags::visibility); + } + + Light(sf::Vector2f origin, sf::Angle center, sf::Angle offset, bool visible = true) + : m_center(center) + , m_offset(offset) + , m_origin(origin) + { + m_light.push_back(sf::Vertex{ m_origin, m_lightColor }); + visible ? setFlags(Flags::visibility) : unsetFlags(Flags::visibility); + } + +public: + enum class Flags + { + visibility = 1 << 0, + infiniteLength = 1 << 1, + drawRays = 1 << 2, + drawEndPoints = 1 << 3 + }; + + void addAngleBounds(sf::Angle center, sf::Angle offset) + { + m_center = center; + m_offset = offset; + } + + void removeAngleBounds() + { + m_center.reset(); + m_offset.reset(); + } + + void setFlags(Flags flags) { m_flags |= (int)flags; } + void unsetFlags(Flags flags) { m_flags &= ~(int)flags; } + void toggleFlags(Flags flags) { m_flags ^= (int)flags; } + bool hasFlags(Flags flags) const { return (m_flags & (int)flags) == (int)flags; } + + void setCenterAngle(sf::Angle center) { m_center = center; } + std::optional getCenterAngle() const { return m_center; } + + void setOffsetAngle(sf::Angle offset) { m_offset = offset; } + std::optional getOffsetAngle() const { return m_offset; } + + void setOrigin(sf::Vector2f point) { m_origin = point; } + sf::Vector2f getOrigin() const { return m_origin; } + + void setRayCount(int input) { m_rayCount = input; } + int getRayCount() const { return m_rayCount; }; + + float getRayLength() { return m_rayLength; } + void setRayLength(float input) { m_rayLength = input; } + + void draw(sf::RenderWindow& window); + + void clearRays() { m_rays.clear(); m_light.clear(); m_light.push_back(sf::Vertex{ {0.f,0.f}, m_lightColor }); } + + void changeLightColor(sf::Color color) { m_lightColor = color; } + void changeEndPointColor(sf::Color color) { m_endPointColor = color; } + void changeRayColor(sf::Color color) { m_rayColor = color; } + + void processRays(const std::vector& polygons); + +private: + std::vector m_light{}; + std::vector m_rays{}; + std::optional m_center{}; + std::optional m_offset{}; + sf::Vector2f m_origin{}; + sf::Color m_lightColor{ sf::Color::Yellow }; + sf::Color m_endPointColor{ sf::Color::Magenta }; + sf::Color m_rayColor{ sf::Color::Red }; + + float m_rayLength{ 500.f }; + int m_rayCount{ 500 }; + int m_flags{}; + + enum + { + start, + end + };//used for sf::VertexArray index + +private: + void constructFullLight(const std::vector& polygons); + void constructPartialLight(const std::vector& polygons); + + void createAndSortRays(const std::vector& polygons); + void createAndSortRays(const std::vector& polygons, sf::Angle lowerAngleBounds, sf::Angle upperAngleBounds);// for bounded light + + void calculateIntersects(const std::vector& polygons); + + bool withinBounds(sf::Vector2f point, sf::Vector2f lower, sf::Vector2f upper); +}; + diff --git a/include/Random.h b/include/Random.h new file mode 100644 index 0000000..c1b4fea --- /dev/null +++ b/include/Random.h @@ -0,0 +1,77 @@ +#pragma once +#ifndef RANDOM_MT_H +#define RANDOM_MT_H + +#include +#include + +// This header-only Random namespace implements a self-seeding Mersenne Twister +// It can be included into as many code files as needed (The inline keyword avoids ODR violations) +// Freely redistributable, courtesy of learncpp.com +namespace Random +{ + // Returns a seeded Mersenne Twister + // Note: we'd prefer to return a std::seed_seq (to initialize a std::mt19937), but std::seed can't be copied, so it can't be returned by value. + // Instead, we'll create a std::mt19937, seed it, and then return the std::mt19937 (which can be copied). + inline std::mt19937 generate() + { + std::random_device rd{}; + + // Create seed_seq with clock and 7 random numbers from std::random_device + std::seed_seq ss{ + static_cast(std::chrono::steady_clock::now().time_since_epoch().count()), + rd(), rd(), rd(), rd(), rd(), rd(), rd() }; + + return std::mt19937{ ss }; + } + + // Here's our global std::mt19937 object. + // The inline keyword means we only have one global instance for our whole program. + inline std::mt19937 mt{ generate() }; // generates a seeded std::mt19937 and copies it into our global object + + // Generate a random int between [min, max] (inclusive) + inline int get(int min, int max) + { + return std::uniform_int_distribution{ min, max }(mt); + } + + // The following function templates can be used to generate random numbers + // when min and/or max are not type int + // See https://www.learncpp.com/cpp-tutorial/function-template-instantiation/ + // You can ignore these if you don't understand them + + // Generate a random value between [min, max] (inclusive) + // * min and max have same type + // * Return value has same type as min and max + // * Supported types: + // * short, int, long, long long + // * unsigned short, unsigned int, unsigned long, or unsigned long long + // Sample call: Random::get(1L, 6L); // returns long + // Sample call: Random::get(1u, 6u); // returns unsigned int + template + T get(T min, T max) + { + return std::uniform_int_distribution{min, max}(mt); + } + + // Generate a random value between [min, max] (inclusive) + // * min and max can have different types + // * Must explicitly specify return type as template type argument + // * min and max will be converted to the return type + // Sample call: Random::get(0, 6); // returns std::size_t + // Sample call: Random::get(0, 6u); // returns std::size_t + // Sample call: Random::get(0, 6u); // returns int + template + R get(S min, T max) + { + return get(static_cast(min), static_cast(max)); + } + + template + T getRandomNumber(U min, V max) + { + return static_cast(get(min, max)); + } +} + +#endif \ No newline at end of file diff --git a/include/Utility.hpp b/include/Utility.hpp new file mode 100644 index 0000000..15dd30b --- /dev/null +++ b/include/Utility.hpp @@ -0,0 +1,153 @@ +#pragma once + +#include +#include +#include + +#include "Random.h" + + + +template +inline T getRandomNumber(U min, V max) +{ + return static_cast(Random::get(min, max)); +} + +template +inline sf::Color createColor(T r, U g, V b, W a) +{ + return sf::Color(static_cast(r), static_cast(g), static_cast(b), static_cast(a)); +} + +template +inline sf::Color createColor(T r, U g, V b, std::uint8_t a = 255u) +{ + return sf::Color(static_cast(r), static_cast(g), static_cast(b), a); +} + +inline sf::Color getRandomColor() +{ + return sf::Color(getRandomNumber(0u, 255u), getRandomNumber(0u, 255u), getRandomNumber(0u, 255u)); +} + +template +inline T signage(T in) +{ + T zero{}; + if (in > zero) return ++zero; + if (in < zero) return --zero; + return zero; +} + +struct LineSegment +{ + sf::Vector2f startPoint{}; + + sf::Vector2f endPoint{}; +}; + +struct ImguiColor +{ + ImguiColor() = default; + ImguiColor(float r_in, float g_in, float b_in, float a_in) + : r(r_in) + , g(g_in) + , b(b_in) + , a(a_in) + { } + + float r{}; + float g{}; + float b{}; + float a{ 1.f }; + + sf::Color asSfColor() + { + return sf::Color(std::uint8_t(r * 255.f), std::uint8_t(g * 255.f), std::uint8_t(b * 255.f), std::uint8_t(a * 255.f)); + } +}; + +inline ImguiColor constructImguiColor(sf::Color color) +{ + return ImguiColor((float)color.r / 255.f, (float)color.g / 255.f, (float)color.b / 255.f, (float)color.a / 255.f); +} + +inline std::optional lineIntersect(LineSegment first, LineSegment second) +{ + sf::Vector2f firstVector = (first.endPoint - first.startPoint); + sf::Vector2f secondVector = (second.endPoint - second.startPoint); + + float lengthCrossProduct = firstVector.cross(secondVector); + + sf::Vector2f fms = second.startPoint - first.startPoint; //first line start point minus second + + float firstScalar = fms.cross(secondVector) / lengthCrossProduct; + float secondScalar = fms.cross(firstVector) / lengthCrossProduct; + + if ((firstScalar >= 0 and firstScalar <= 1) and (secondScalar >= 0 and secondScalar <= 1)) + return sf::Vector2f(first.startPoint.x + (firstScalar * firstVector.x), first.startPoint.y + (firstScalar * firstVector.y)); + else + return std::nullopt; +} + +inline sf::VertexArray constructRectangle(sf::Vector2f center, sf::Vector2f size, sf::Color color = sf::Color::Black) +{ + sf::VertexArray rectangle(sf::PrimitiveType::LineStrip, 5); + rectangle[0].color = color; + rectangle[1].color = color; + rectangle[2].color = color; + rectangle[3].color = color; + rectangle[4].color = color; + + rectangle[0].position = { center.x - size.x, center.y - size.y }; + rectangle[1].position = { center.x + size.x, center.y - size.y }; + rectangle[2].position = { center.x + size.x, center.y + size.y }; + rectangle[3].position = { center.x - size.x, center.y + size.y }; + rectangle[4].position = rectangle[0].position; + + return rectangle; +} + +inline sf::Vector2f constructVector(sf::Vector2f startPoint, sf::Angle angle, float length) +{ + return { startPoint.x + (length * std::cos(angle.asRadians())), startPoint.y + (length * std::sin(angle.asRadians())) }; +} + +inline sf::VertexArray constructRandomPolygon(sf::Vector2f center, int vertexLowerBound, int vertexUpperBound, int averageSize, sf::Color color = sf::Color::Black) +{ + const std::size_t vertexCount = getRandomNumber(vertexLowerBound, vertexUpperBound); + sf::VertexArray polygon(sf::PrimitiveType::LineStrip, vertexCount); + + const float angleIncrement = 360.f / (float)(vertexCount - 1); + const float angleStart = getRandomNumber(0, 360); + + for (int i = 0; i < vertexCount - 1; i++) + { + float angleOffset = getRandomNumber(-(90 / (int)vertexCount), (90 / (int)vertexCount)); + polygon[i].color = color; + polygon[i].position = constructVector(center, sf::degrees(angleStart + (angleIncrement * i) + angleOffset), getRandomNumber((averageSize - 50), (averageSize + 50))); + } + polygon[vertexCount - 1].position = polygon[0].position; + polygon[vertexCount - 1].color = color; + return polygon; +} + +inline float distanceBetween(sf::Vector2f startPoint, sf::Vector2f endPoint) +{ + 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; +} \ No newline at end of file diff --git a/premake5.lua b/premake5.lua new file mode 100644 index 0000000..b81d69d --- /dev/null +++ b/premake5.lua @@ -0,0 +1,148 @@ +require "ecc/ecc" +require "ninja/ninja" + +workspace "ray-casting-demos" + architecture "x64" + + configurations + { + "debug", + "release" + } + +output_dir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}" +vs_intdir = "$(SolutionDir)intermediate-files/" .. output_dir +intdir = "%{wks.location}/intermediate-files/" .. output_dir +vs_bindir = "$(SolutionDir)bin/" .. output_dir +bindir = "%{wks.location}/bin/" .. output_dir +vs_sfmldir = "$(SolutionDir)vendor/SFML" +sfmldir = "%{wks.location}/vendor/SFML" +vs_imguidir = "$(SolutionDir)vendor/imgui" +imguidir = "%{wks.location}/vendor/imgui" +vs_include_dir = "$(SolutionDir)include" +include_dir = "%{wks.location}/include" + +project "Game" + language "C++" + cppdialect "C++17" + systemversion "latest" + targetname "Game" + + files + { + "src/**.cpp", + "include/**.h", + "include/**.hpp", + "vendor/imgui/imgui.cpp", + "vendor/imgui/imgui_draw.cpp", + "vendor/imgui/imgui_tables.cpp", + "vendor/imgui/imgui_widgets.cpp", + "vendor/imgui/imgui-SFML.cpp" + } + --visual studio-- + filter {"action:vs*", "system:windows"} + targetdir (vs_bindir) + objdir (vs_intdir) + + includedirs + { + "src", + vs_include_dir, + vs_sfmldir .. "/include", + vs_imguidir + } + + libdirs {vs_sfmldir .."/lib"} + + --not visual studio on windows-- + filter {"not action:vs*", "system:windows"} + targetdir (bindir) + objdir (intdir) + includedirs + { + "src", + include_dir, + sfmldir .. "/include", + imguidir + } + + libdirs {sfmldir .."/lib"} + + filter{"system:windows"} + defines "SFML_STATIC" + defines "PLATFORM_WINDOWS" + staticruntime "on" + + filter {"system:windows", "configurations:debug"} + defines{"_DEBUG", "_CONSOLE"} + links + { + "sfml-main-d", + "sfml-graphics-s-d", + "sfml-window-s-d", + "opengl32", + "gdi32", + "freetype", + "sfml-audio-s-d", + "flac", + "vorbisfile", + "vorbis", + "ogg", + "sfml-system-s-d", + "winmm" + } + + filter {"system:windows", "configurations:release"} + defines{"NDEBUG"} + links + { + "sfml-main", + "sfml-graphics-s", + "sfml-window-s", + "opengl32", + "gdi32", + "freetype", + "sfml-audio-s", + "openal32", + "flac", + "vorbisfile", + "vorbis", + "ogg", + "sfml-system-s", + "winmm" + } + + filter {"system:linux"} + targetdir (bindir) + objdir (intdir) + defines "PLATFORM_LINUX" + includedirs + { + "src", + include_dir, + imguidir + } + + links + { + "sfml-graphics", + "sfml-window", + "sfml-audio", + "sfml-system", + "OpenGL", + } + + --config settings-- + filter "configurations:debug" + defines {"LOG_ENABLE", "GAME_DEBUG"} + symbols "on" + runtime "Debug" + kind "ConsoleApp" + + filter "configurations:release" + defines {"GAME_RELEASE"} + optimize "Speed" + inlining "Auto" + symbols "off" + runtime "Release" + kind "WindowedApp" \ No newline at end of file diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..20dacf1 --- /dev/null +++ b/run.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +./bin/$1-linux-x86_64/Game \ No newline at end of file diff --git a/src/Light.cpp b/src/Light.cpp new file mode 100644 index 0000000..becbd66 --- /dev/null +++ b/src/Light.cpp @@ -0,0 +1,192 @@ +#include "Light.h" + +void Light::draw(sf::RenderWindow& window) +{ + if (hasFlags(Flags::visibility)) + { + window.draw(m_light.data(), m_light.size(), sf::PrimitiveType::TriangleFan); + } + + if (hasFlags(Flags::drawRays)) + { + sf::VertexArray tempRay(sf::PrimitiveType::Lines, 2); + tempRay[start].position = m_origin; + tempRay[start].color = m_rayColor; + tempRay[end].color = m_rayColor; + + for (auto& ray : m_rays) + { + tempRay[end].position = ray.position; + window.draw(tempRay); + } + } + + if (hasFlags(Flags::drawEndPoints)) + { + sf::CircleShape endPoint(5.f, 20u); + endPoint.setOrigin({ 5, 5 }); + endPoint.setFillColor(m_endPointColor); + + for (auto& ray : m_rays) + { + endPoint.setPosition(ray.position); + window.draw(endPoint); + } + } +} + + +void Light::processRays(const std::vector& polygons) +{ + m_light[0].position = m_origin; + if (m_center and m_offset) + { + constructPartialLight(polygons); + } + else + { + constructFullLight(polygons); + } +} + + +void Light::constructFullLight(const std::vector& polygons) +{ + createAndSortRays(polygons); + + calculateIntersects(polygons); + + for (auto& ray : m_rays) + { + m_light.emplace_back(ray); + } + + m_light.emplace_back(m_rays.front());//fully connect the triangle fan + +} + + +void Light::constructPartialLight(const std::vector& polygons) +{ + createAndSortRays(polygons, m_center.value() - m_offset.value(), m_center.value() + m_offset.value()); + + calculateIntersects(polygons); + + for (auto& ray : m_rays) + { + m_light.emplace_back(ray); + } + +} + + +void Light::createAndSortRays(const std::vector& polygons) +{ + + if (not hasFlags(Flags::infiniteLength)) + { + if (m_rayCount > 0) + { + float angleIncrement = 360.f / (float)m_rayCount; + for (int i = 0; i < m_rayCount; i++) m_rays.emplace_back(sf::Vertex{ constructVector( m_origin, sf::degrees(angleIncrement * i), m_rayLength ), m_lightColor }); + } + } + + sf::Angle angle; + const float infiniteLength = 5000.f * hasFlags(Flags::infiniteLength); + + for (auto& poly : polygons) + { + for (std::size_t i = 0; i < poly.getVertexCount() - 1; i++) + { + if (hasFlags(Flags::infiniteLength) ? false : distanceBetween(m_origin, poly[i].position) >= m_rayLength) continue; + + 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{ 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), m_lightColor }); + } + } + + std::sort(m_rays.begin(), m_rays.end(), [&](const auto& lhs, const auto& rhs) { return (lhs.position - m_origin).angle().wrapUnsigned().asRadians() < (rhs.position - m_origin).angle().wrapUnsigned().asRadians(); }); +} + +// overload for bounded light +void Light::createAndSortRays(const std::vector& polygons, sf::Angle lowerAngleBounds, sf::Angle upperAngleBounds) +{ + const float infiniteLength = 5000.f * hasFlags(Flags::infiniteLength); + sf::Vertex lowerBound{ constructVector( m_origin, lowerAngleBounds, m_rayLength + infiniteLength), m_lightColor }; + sf::Vertex upperBound{ constructVector( m_origin, upperAngleBounds, m_rayLength + infiniteLength), m_lightColor }; + auto lowerBoundVector = lowerBound.position - m_origin; + auto upperBoundVector = upperBound.position - m_origin; + + if (not hasFlags(Flags::infiniteLength)) + { + sf::Vertex temp; + float angleIncrement = 360.f / (float)m_rayCount; + for (int i = 0; i < m_rayCount; i++) + { + temp = sf::Vertex{ constructVector(m_origin, sf::degrees(angleIncrement * i), m_rayLength), m_lightColor }; + + if (withinBounds(temp.position - m_origin, lowerBoundVector, upperBoundVector)) m_rays.emplace_back(temp); + } + } + + sf::Angle angle; + + for (auto& poly : polygons) + { + for (std::size_t i = 0; i < poly.getVertexCount() - 1; i++) + { + if (poly[i].position == m_origin) continue;// cannot pass zero vector to sf::Vector2::angleTo() + + if (hasFlags(Flags::infiniteLength) ? false : distanceBetween(m_origin, poly[i].position) >= m_rayLength) continue; + + if (not withinBounds(poly[i].position - m_origin, lowerBoundVector, upperBoundVector)) continue; + + 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{ 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), m_lightColor }); + } + } + + m_rays.emplace_back(lowerBound); + m_rays.emplace_back(upperBound); + + std::sort(m_rays.begin(), m_rays.end(), [&](const auto& lhs, const auto& rhs) { return (lhs.position - m_origin).angleTo(upperBoundVector).wrapUnsigned().asRadians() < (rhs.position - m_origin).angleTo(upperBoundVector).wrapUnsigned().asRadians(); }); +} + +void Light::calculateIntersects(const std::vector& polygons) +{ + std::optional currentIntersect{}; + + for (auto& ray : m_rays) + { + sf::Vector2f closestIntersection = ray.position; + currentIntersect.reset(); + + for (auto& poly : polygons) + { + for (std::size_t i = 1; i <= poly.getVertexCount() - 1; i++) + { + currentIntersect = lineIntersect({ m_origin, ray.position }, { poly[i - 1].position , poly[i].position }); + + if (not currentIntersect) continue; + if ((closestIntersection - m_origin).length() < (currentIntersect.value() - m_origin).length()) continue; + + closestIntersection = currentIntersect.value(); + } + } + + ray.position = closestIntersection; + } + +} + +bool Light::withinBounds(sf::Vector2f point, sf::Vector2f lower, sf::Vector2f upper) +{ + return point.angleTo(upper).wrapUnsigned().asRadians() < (lower).angleTo(upper).wrapUnsigned().asRadians(); +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..da3276e --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,276 @@ + +#include +#include + +#include +#include +#include + +#include "Utility.hpp" +#include "Light.h" + + +auto window = sf::RenderWindow(sf::VideoMode({ 1920u, 1080u }), "Ray Casting Test"); + +Light light; +std::vector polygons; +sf::CircleShape circle{}; + +sf::Vector2f mousePos{}; +sf::Vector2f center{ 1920.f / 2.f, 1080.f / 2.f }; + +//imGui Variables +constexpr int numRaysBounds[2] = { 5, 500 }; +constexpr float rayLengthBounds[2] = {5.f, 5000.f}; +constexpr float offsetAngleBounds[2] = { 5.f, 175.f }; +constexpr int vertexMin{ 3 }; +constexpr int vertexMax{ 20 }; +constexpr float rotationSpeedScale{ 3.f }; +float polySize[2] = { 100.f, 100.f }; +int numRays{ 500 }; +int vertexBounds[2] = { 3, 10 }; +int averageSize{ 100 }; +float rayLength{ 500.f }; +imguiColor rayColor = constructImguiColor(sf::Color::Red); +imguiColor lightColor = constructImguiColor(sf::Color::Yellow); +imguiColor endPointColor = constructImguiColor(sf::Color::Magenta); +bool drawRays{ false }; +bool drawLight{ true }; +bool drawEndPoints{ false }; +bool boundedLight{ false }; +bool infiniteRayLength{ false }; +float lightCenterAngle{ 0.f }; +float lightOffsetAngle{ 45.f }; + +void GUI(); +void userInput(); +void render(); + +int main() +{ + //configure light with default imgui vatiables + drawRays ? light.setFlags(Light::Flags::drawRays) : light.unsetFlags(Light::Flags::drawRays); + 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); + infiniteRayLength ? light.setFlags(Light::Flags::infiniteLength) : light.unsetFlags(Light::Flags::infiniteLength); + + //sfml setup + sf::Clock clock; + window.setFramerateLimit(144); + if (!ImGui::SFML::Init(window)) + return -1; + + mousePos = 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 + while (window.isOpen()) + { + ImGui::SFML::Update(window, clock.restart()); + + light.clearRays(); + + userInput(); + + GUI(); + + light.setOrigin(mousePos); + light.processRays(polygons); + + render(); + + } + + ImGui::SFML::Shutdown(); +} + +void GUI() +{ + ImGui::Begin("Config"); + ImGui::Text("Controls:"); + ImGui::Indent(); + ImGui::Text("Right Click: place rectangle at mouse position"); + ImGui::Text("R: place a randomly sized polygon at mouse position"); + ImGui::Text("C: clear all polygons"); + ImGui::Text("Scroll wheel: increase/decrease light direction (if light is bounded)"); + ImGui::Unindent(); + if (ImGui::Checkbox("Render rays", &drawRays)) + { + light.toggleFlags(Light::Flags::drawRays); + } + + ImGui::SameLine(); + if (ImGui::Checkbox("Render end points", &drawEndPoints)) + { + light.toggleFlags(Light::Flags::drawEndPoints); + } + + ImGui::SameLine(); + if (ImGui::Checkbox("Render light", &drawLight)) + { + light.toggleFlags(Light::Flags::visibility); + } + + if (ImGui::Checkbox("Infinite ray length", &infiniteRayLength)) + { + light.toggleFlags(Light::Flags::infiniteLength); + } + + if (not infiniteRayLength) + { + ImGui::SliderInt("number of rays", &numRays, numRaysBounds[0], numRaysBounds[1]); + light.setRayCount(numRays); + + if (ImGui::InputFloat("Ray Length", &rayLength)) + { + rayLength = std::clamp(rayLength, rayLengthBounds[0], rayLengthBounds[1]); + } + light.setRayLength(rayLength); + } + + if (drawRays) + { + ImGui::ColorEdit4("Ray color", &rayColor.r); + } + + if (drawLight) + { + ImGui::ColorEdit4("Light color", &lightColor.r); + } + + if (drawEndPoints) + { + ImGui::ColorEdit4("End point color", &endPointColor.r); + } + + light.changeLightColor(lightColor.asSfColor()); + light.changeEndPointColor(endPointColor.asSfColor()); + light.changeRayColor(rayColor.asSfColor()); + + if(ImGui::Checkbox("Light is bounded", &boundedLight)) + { + boundedLight ? light.addAngleBounds(sf::degrees(lightCenterAngle), sf::degrees(lightOffsetAngle)) : light.removeAngleBounds(); + } + + if (boundedLight) + { + ImGui::SliderFloat("Light direction", &lightCenterAngle, 0.f, 359.f, "%.0f", ImGuiSliderFlags_::ImGuiSliderFlags_AlwaysClamp); + light.setCenterAngle(sf::degrees(lightCenterAngle)); + + ImGui::SliderFloat("Offset size", &lightOffsetAngle, offsetAngleBounds[0], offsetAngleBounds[1], "%.0f", ImGuiSliderFlags_::ImGuiSliderFlags_AlwaysClamp); + light.setOffsetAngle(sf::degrees(lightOffsetAngle)); + } + + ImGui::InputFloat2("rectangle Size (X,Y)", polySize, "%.1f"); + ImGui::Text("Random polygon config: "); + if (ImGui::SliderInt2("vertex count lower/upper bounds", vertexBounds, vertexMin, vertexMax)) + { + if (vertexBounds[0] > vertexBounds[1]) + vertexBounds[0] = vertexBounds[1]; + + if (vertexBounds[1] < vertexBounds[0]) + vertexBounds[0] = vertexBounds[1]; + } + + if (ImGui::InputInt("Average size", &averageSize)) + { + if (averageSize < 20) + { + averageSize = 20; + } + } + + ImGui::End(); +} + +void userInput() +{ + while (const std::optional event = window.pollEvent()) + { + ImGui::SFML::ProcessEvent(window, *event); + + if (event->is()) + { + window.close(); + } + + if (const auto* buttonPressed = event->getIf()) + { + switch (buttonPressed->scancode) + { + case sf::Keyboard::Scancode::C: + polygons.clear(); + polygons.emplace_back(constructRectangle(center, center)); + break; + + case sf::Keyboard::Scancode::R: + polygons.emplace_back(constructRandomPolygon(mousePos, vertexBounds[0] + 1, vertexBounds[1] + 1, averageSize)); + break; + + case sf::Keyboard::Scancode::Escape: + window.close(); + break; + + default: + break; + } + } + + if (const auto* mousePressed = event->getIf()) + { + switch (mousePressed->button) + { + case sf::Mouse::Button::Right: + polygons.emplace_back(constructRectangle((sf::Vector2f)mousePressed->position, { polySize[0], polySize[1] }, sf::Color::Black)); + break; + + default: + break; + } + } + + if (const auto* mouseWheelScrolled = event->getIf()) + { + switch (mouseWheelScrolled->wheel) + { + case sf::Mouse::Wheel::Vertical: + if (boundedLight) + { + lightCenterAngle += mouseWheelScrolled->delta * rotationSpeedScale; + if (lightCenterAngle > 359.f) lightCenterAngle = 0.f; + if (lightCenterAngle < 0.f) lightCenterAngle = 359.f; + } + break; + + default: + break; + } + } + + if (const auto* mouseMoved = event->getIf()) + { + mousePos = (sf::Vector2f)mouseMoved->position; + } + } +} + +void render() +{ + window.clear(sf::Color::White); + + light.draw(window); + + for (auto& poly : polygons) window.draw(poly); + + ImGui::SFML::Render(window); + + window.display(); +} \ No newline at end of file diff --git a/vendor/SFML/include/SFML/Audio.hpp b/vendor/SFML/include/SFML/Audio.hpp new file mode 100644 index 0000000..f0d262e --- /dev/null +++ b/vendor/SFML/include/SFML/Audio.hpp @@ -0,0 +1,55 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +//////////////////////////////////////////////////////////// +/// \defgroup audio Audio module +/// +/// Sounds, streaming (musics or custom sources), recording, +/// spatialization. +/// +//////////////////////////////////////////////////////////// diff --git a/vendor/SFML/include/SFML/Audio/AudioResource.hpp b/vendor/SFML/include/SFML/Audio/AudioResource.hpp new file mode 100644 index 0000000..3230637 --- /dev/null +++ b/vendor/SFML/include/SFML/Audio/AudioResource.hpp @@ -0,0 +1,93 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#include + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \brief Base class for classes that require an audio device +/// +//////////////////////////////////////////////////////////// +class SFML_AUDIO_API AudioResource +{ +public: + //////////////////////////////////////////////////////////// + /// \brief Copy constructor + /// + //////////////////////////////////////////////////////////// + AudioResource(const AudioResource&) = default; + + //////////////////////////////////////////////////////////// + /// \brief Copy assignment + /// + //////////////////////////////////////////////////////////// + AudioResource& operator=(const AudioResource&) = default; + + //////////////////////////////////////////////////////////// + /// \brief Move constructor + /// + //////////////////////////////////////////////////////////// + AudioResource(AudioResource&&) noexcept = default; + + //////////////////////////////////////////////////////////// + /// \brief Move assignment + /// + //////////////////////////////////////////////////////////// + AudioResource& operator=(AudioResource&&) noexcept = default; + +protected: + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + AudioResource(); + +private: + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + std::shared_ptr m_device; //!< Sound device +}; + +} // namespace sf + + +//////////////////////////////////////////////////////////// +/// \class sf::AudioResource +/// \ingroup audio +/// +/// This class is for internal use only, it must be the base +/// of every class that requires a valid audio device in +/// order to work. +/// +//////////////////////////////////////////////////////////// diff --git a/vendor/SFML/include/SFML/Audio/Export.hpp b/vendor/SFML/include/SFML/Audio/Export.hpp new file mode 100644 index 0000000..c50efc0 --- /dev/null +++ b/vendor/SFML/include/SFML/Audio/Export.hpp @@ -0,0 +1,44 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +//////////////////////////////////////////////////////////// +// Portable import / export macros +//////////////////////////////////////////////////////////// +#if defined(SFML_AUDIO_EXPORTS) + +#define SFML_AUDIO_API SFML_API_EXPORT + +#else + +#define SFML_AUDIO_API SFML_API_IMPORT + +#endif diff --git a/vendor/SFML/include/SFML/Audio/InputSoundFile.hpp b/vendor/SFML/include/SFML/Audio/InputSoundFile.hpp new file mode 100644 index 0000000..523b8e5 --- /dev/null +++ b/vendor/SFML/include/SFML/Audio/InputSoundFile.hpp @@ -0,0 +1,336 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#include + +#include +#include +#include + +#include +#include + + +namespace sf +{ +class Time; +class InputStream; + +//////////////////////////////////////////////////////////// +/// \brief Provide read access to sound files +/// +//////////////////////////////////////////////////////////// +class SFML_AUDIO_API InputSoundFile +{ +public: + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Construct an input sound file that is not associated + /// with a file to read. + /// + //////////////////////////////////////////////////////////// + InputSoundFile() = default; + + //////////////////////////////////////////////////////////// + /// \brief Construct a sound file from the disk for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC, MP3. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// Because of minimp3_ex limitation, for MP3 files with big (>16kb) APEv2 tag, + /// it may not be properly removed, tag data will be treated as MP3 data + /// and there is a low chance of garbage decoded at the end of file. + /// See also: https://github.com/lieff/minimp3 + /// + /// \param filename Path of the sound file to load + /// + /// \throws sf::Exception if opening the file was unsuccessful + /// + //////////////////////////////////////////////////////////// + explicit InputSoundFile(const std::filesystem::path& filename); + + //////////////////////////////////////////////////////////// + /// \brief Construct a sound file in memory for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param data Pointer to the file data in memory + /// \param sizeInBytes Size of the data to load, in bytes + /// + /// \throws sf::Exception if opening the file was unsuccessful + /// + //////////////////////////////////////////////////////////// + InputSoundFile(const void* data, std::size_t sizeInBytes); + + //////////////////////////////////////////////////////////// + /// \brief Construct a sound file from a custom stream for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param stream Source stream to read from + /// + /// \throws sf::Exception if opening the file was unsuccessful + /// + //////////////////////////////////////////////////////////// + explicit InputSoundFile(InputStream& stream); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file from the disk for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC, MP3. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// Because of minimp3_ex limitation, for MP3 files with big (>16kb) APEv2 tag, + /// it may not be properly removed, tag data will be treated as MP3 data + /// and there is a low chance of garbage decoded at the end of file. + /// See also: https://github.com/lieff/minimp3 + /// + /// \param filename Path of the sound file to load + /// + /// \return `true` if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] bool openFromFile(const std::filesystem::path& filename); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file in memory for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param data Pointer to the file data in memory + /// \param sizeInBytes Size of the data to load, in bytes + /// + /// \return `true` if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] bool openFromMemory(const void* data, std::size_t sizeInBytes); + + //////////////////////////////////////////////////////////// + /// \brief Open a sound file from a custom stream for reading + /// + /// The supported audio formats are: WAV (PCM only), OGG/Vorbis, FLAC. + /// The supported sample sizes for FLAC and WAV are 8, 16, 24 and 32 bit. + /// + /// \param stream Source stream to read from + /// + /// \return `true` if the file was successfully opened + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] bool openFromStream(InputStream& stream); + + //////////////////////////////////////////////////////////// + /// \brief Get the total number of audio samples in the file + /// + /// \return Number of samples + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] std::uint64_t getSampleCount() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the number of channels used by the sound + /// + /// \return Number of channels (1 = mono, 2 = stereo) + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] unsigned int getChannelCount() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the sample rate of the sound + /// + /// \return Sample rate, in samples per second + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] unsigned int getSampleRate() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the map of position in sample frame to sound channel + /// + /// This is used to map a sample in the sample stream to a + /// position during spatialization. + /// + /// \return Map of position in sample frame to sound channel + /// + /// \see `getSampleRate`, `getChannelCount`, `getDuration` + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] const std::vector& getChannelMap() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the total duration of the sound file + /// + /// This function is provided for convenience, the duration is + /// deduced from the other sound file attributes. + /// + /// \return Duration of the sound file + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] Time getDuration() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the read offset of the file in time + /// + /// \return Time position + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] Time getTimeOffset() const; + + //////////////////////////////////////////////////////////// + /// \brief Get the read offset of the file in samples + /// + /// \return Sample position + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] std::uint64_t getSampleOffset() const; + + //////////////////////////////////////////////////////////// + /// \brief Change the current read position to the given sample offset + /// + /// This function takes a sample offset to provide maximum + /// precision. If you need to jump to a given time, use the + /// other overload. + /// + /// The sample offset takes the channels into account. + /// If you have a time offset instead, you can easily find + /// the corresponding sample offset with the following formula: + /// `timeInSeconds * sampleRate * channelCount` + /// If the given offset exceeds to total number of samples, + /// this function jumps to the end of the sound file. + /// + /// \param sampleOffset Index of the sample to jump to, relative to the beginning + /// + //////////////////////////////////////////////////////////// + void seek(std::uint64_t sampleOffset); + + //////////////////////////////////////////////////////////// + /// \brief Change the current read position to the given time offset + /// + /// Using a time offset is handy but imprecise. If you need an accurate + /// result, consider using the overload which takes a sample offset. + /// + /// If the given time exceeds to total duration, this function jumps + /// to the end of the sound file. + /// + /// \param timeOffset Time to jump to, relative to the beginning + /// + //////////////////////////////////////////////////////////// + void seek(Time timeOffset); + + //////////////////////////////////////////////////////////// + /// \brief Read audio samples from the open file + /// + /// \param samples Pointer to the sample array to fill + /// \param maxCount Maximum number of samples to read + /// + /// \return Number of samples actually read (may be less than \a maxCount) + /// + //////////////////////////////////////////////////////////// + [[nodiscard]] std::uint64_t read(std::int16_t* samples, std::uint64_t maxCount); + + //////////////////////////////////////////////////////////// + /// \brief Close the current file + /// + //////////////////////////////////////////////////////////// + void close(); + +private: + //////////////////////////////////////////////////////////// + /// \brief Deleter for input streams that only conditionally deletes + /// + //////////////////////////////////////////////////////////// + struct SFML_AUDIO_API StreamDeleter + { + StreamDeleter(bool theOwned); + + // To accept ownership transfer from usual std::unique_ptr + template + StreamDeleter(const std::default_delete&); + + void operator()(InputStream* ptr) const; + + bool owned{true}; + }; + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + std::unique_ptr m_reader; //!< Reader that handles I/O on the file's format + std::unique_ptr m_stream{nullptr, false}; //!< Input stream used to access the file's data + std::uint64_t m_sampleOffset{}; //!< Sample Read Position + std::uint64_t m_sampleCount{}; //!< Total number of samples in the file + unsigned int m_sampleRate{}; //!< Number of samples per second + std::vector m_channelMap; //!< The map of position in sample frame to sound channel +}; + +} // namespace sf + + +//////////////////////////////////////////////////////////// +/// \class sf::InputSoundFile +/// \ingroup audio +/// +/// This class decodes audio samples from a sound file. It is +/// used internally by higher-level classes such as `sf::SoundBuffer` +/// and `sf::Music`, but can also be useful if you want to process +/// or analyze audio files without playing them, or if you want to +/// implement your own version of `sf::Music` with more specific +/// features. +/// +/// Usage example: +/// \code +/// // Open a sound file +/// sf::InputSoundFile file("music.ogg"); +/// +/// // Print the sound attributes +/// std::cout << "duration: " << file.getDuration().asSeconds() << '\n' +/// << "channels: " << file.getChannelCount() << '\n' +/// << "sample rate: " << file.getSampleRate() << '\n' +/// << "sample count: " << file.getSampleCount() << std::endl; +/// +/// // Read and process batches of samples until the end of file is reached +/// std::array samples; +/// std::uint64_t count; +/// do +/// { +/// count = file.read(samples.data(), samples.size()); +/// +/// // process, analyze, play, convert, or whatever +/// // you want to do with the samples... +/// } +/// while (count > 0); +/// \endcode +/// +/// \see `sf::SoundFileReader`, `sf::OutputSoundFile` +/// +//////////////////////////////////////////////////////////// diff --git a/vendor/SFML/include/SFML/Audio/Listener.hpp b/vendor/SFML/include/SFML/Audio/Listener.hpp new file mode 100644 index 0000000..81c1794 --- /dev/null +++ b/vendor/SFML/include/SFML/Audio/Listener.hpp @@ -0,0 +1,234 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#include +#include + + +//////////////////////////////////////////////////////////// +/// \brief The audio listener is the point in the scene +/// from where all the sounds are heard +/// +//////////////////////////////////////////////////////////// +namespace sf::Listener +{ +//////////////////////////////////////////////////////////// +/// \brief Structure defining the properties of a directional cone +/// +/// Sounds will play at gain 1 when they are positioned +/// within the inner angle of the cone. Sounds will play +/// at `outerGain` when they are positioned outside the +/// outer angle of the cone. The gain declines linearly +/// from 1 to `outerGain` as the sound moves from the inner +/// angle to the outer angle. +/// +//////////////////////////////////////////////////////////// +struct Cone +{ + Angle innerAngle; //!< Inner angle + Angle outerAngle; //!< Outer angle + float outerGain{}; //!< Outer gain +}; + +//////////////////////////////////////////////////////////// +/// \brief Change the global volume of all the sounds and musics +/// +/// `volume` is a number between 0 and 100; it is combined +/// with the individual volume of each sound / music. +/// The default value for the volume is 100 (maximum). +/// +/// \param volume New global volume, in the range [0, 100] +/// +/// \see `getGlobalVolume` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setGlobalVolume(float volume); + +//////////////////////////////////////////////////////////// +/// \brief Get the current value of the global volume +/// +/// \return Current global volume, in the range [0, 100] +/// +/// \see `setGlobalVolume` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API float getGlobalVolume(); + +//////////////////////////////////////////////////////////// +/// \brief Set the position of the listener in the scene +/// +/// The default listener's position is (0, 0, 0). +/// +/// \param position New listener's position +/// +/// \see `getPosition`, `setDirection` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setPosition(const Vector3f& position); + +//////////////////////////////////////////////////////////// +/// \brief Get the current position of the listener in the scene +/// +/// \return Listener's position +/// +/// \see `setPosition` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API Vector3f getPosition(); + +//////////////////////////////////////////////////////////// +/// \brief Set the forward vector of the listener in the scene +/// +/// The direction (also called "at vector") is the vector +/// pointing forward from the listener's perspective. Together +/// with the up vector, it defines the 3D orientation of the +/// listener in the scene. The direction vector doesn't +/// have to be normalized. +/// The default listener's direction is (0, 0, -1). +/// +/// \param direction New listener's direction +/// +/// \see `getDirection`, `setUpVector`, `setPosition` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setDirection(const Vector3f& direction); + +//////////////////////////////////////////////////////////// +/// \brief Get the current forward vector of the listener in the scene +/// +/// \return Listener's forward vector (not normalized) +/// +/// \see `setDirection` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API Vector3f getDirection(); + +//////////////////////////////////////////////////////////// +/// \brief Set the velocity of the listener in the scene +/// +/// The default listener's velocity is (0, 0, -1). +/// +/// \param velocity New listener's velocity +/// +/// \see `getVelocity`, `getDirection`, `setUpVector`, `setPosition` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setVelocity(const Vector3f& velocity); + +//////////////////////////////////////////////////////////// +/// \brief Get the current forward vector of the listener in the scene +/// +/// \return Listener's velocity +/// +/// \see `setVelocity` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API Vector3f getVelocity(); + +//////////////////////////////////////////////////////////// +/// \brief Set the cone properties of the listener in the audio scene +/// +/// The cone defines how directional attenuation is applied. +/// The default cone of a sound is (2 * PI, 2 * PI, 1). +/// +/// \param cone Cone properties of the listener in the scene +/// +/// \see `getCone` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setCone(const Listener::Cone& cone); + +//////////////////////////////////////////////////////////// +/// \brief Get the cone properties of the listener in the audio scene +/// +/// \return Cone properties of the listener +/// +/// \see `setCone` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API Listener::Cone getCone(); + +//////////////////////////////////////////////////////////// +/// \brief Set the upward vector of the listener in the scene +/// +/// The up vector is the vector that points upward from the +/// listener's perspective. Together with the direction, it +/// defines the 3D orientation of the listener in the scene. +/// The up vector doesn't have to be normalized. +/// The default listener's up vector is (0, 1, 0). It is usually +/// not necessary to change it, especially in 2D scenarios. +/// +/// \param upVector New listener's up vector +/// +/// \see `getUpVector`, `setDirection`, `setPosition` +/// +//////////////////////////////////////////////////////////// +SFML_AUDIO_API void setUpVector(const Vector3f& upVector); + +//////////////////////////////////////////////////////////// +/// \brief Get the current upward vector of the listener in the scene +/// +/// \return Listener's upward vector (not normalized) +/// +/// \see `setUpVector` +/// +//////////////////////////////////////////////////////////// +[[nodiscard]] SFML_AUDIO_API Vector3f getUpVector(); +} // namespace sf::Listener + + +//////////////////////////////////////////////////////////// +/// \namespace sf::Listener +/// \ingroup audio +/// +/// The audio listener defines the global properties of the +/// audio environment, it defines where and how sounds and musics +/// are heard. If `sf::View` is the eyes of the user, then +/// `sf::Listener` are their ears (by the way, they are often linked +/// together -- same position, orientation, etc.). +/// +/// `sf::Listener` is a simple interface, which allows to setup the +/// listener in the 3D audio environment (position, direction and +/// up vector), and to adjust the global volume. +/// +/// Usage example: +/// \code +/// // Move the listener to the position (1, 0, -5) +/// sf::Listener::setPosition({1, 0, -5}); +/// +/// // Make it face the right axis (1, 0, 0) +/// sf::Listener::setDirection({1, 0, 0}); +/// +/// // Reduce the global volume +/// sf::Listener::setGlobalVolume(50); +/// \endcode +/// +//////////////////////////////////////////////////////////// diff --git a/vendor/SFML/include/SFML/Audio/Music.hpp b/vendor/SFML/include/SFML/Audio/Music.hpp new file mode 100644 index 0000000..91a2787 --- /dev/null +++ b/vendor/SFML/include/SFML/Audio/Music.hpp @@ -0,0 +1,377 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + +#include + +#include +#include +#include + +#include +#include + + +namespace sf +{ +class Time; +class InputStream; +class InputSoundFile; + +//////////////////////////////////////////////////////////// +/// \brief Streamed music played from an audio file +/// +//////////////////////////////////////////////////////////// +class SFML_AUDIO_API Music : public SoundStream +{ +public: + //////////////////////////////////////////////////////////// + /// \brief Structure defining a time range using the template type + /// + //////////////////////////////////////////////////////////// + template + struct Span + { + T offset{}; //!< The beginning offset of the time range + T length{}; //!< The length of the time range + }; + + // Associated `Span` type + using TimeSpan = Span