From 13d0032aac322423e66a83094e8c904c052e1cf2 Mon Sep 17 00:00:00 2001 From: Timofey Zakharchuk Date: Mon, 19 Jan 2026 12:39:42 +0300 Subject: [PATCH 1/7] Update cmake-multi-platform.yml --- .github/workflows/cmake-multi-platform.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index 16480ea..e79f8a1 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -7,10 +7,12 @@ on: branches: - main - glsl-experiments + - v1.0.0-beta pull_request: branches: - main - glsl-experiments + - v1.0.0-beta jobs: build: From 8261e3d69e8310dd80ba65ebf642e394aa29d723 Mon Sep 17 00:00:00 2001 From: Timofey Zakharchuk Date: Mon, 19 Jan 2026 12:59:21 +0300 Subject: [PATCH 2/7] Add 3D --- src/conf.h | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/conf.h b/src/conf.h index ec2d501..ece7fa6 100644 --- a/src/conf.h +++ b/src/conf.h @@ -6,23 +6,24 @@ struct Particle { - double x, y; - double vx, vy; + double x, y, z; + double vx, vy, vz; double m; double r; std::string name; - Particle(double px, double py, double pvx, double pvy, double pm, double pr, const std::string&n) - : x(px), y(py), vx(pvx), vy(pvy), m(pm), r(pr), name(n) {} + Particle(double px, double py, double pz, double pvx, double pvy, double pvz, double pm, double pr, const std::string&n) + : x(px), y(py), z(pz), vx(pvx), vy(pvy), vz(pvz), m(pm), r(pr), name(n) {} }; inline void Gravity(Particle& a, Particle& b, double dt) { - const double G (6.67430e-11); + constexpr double G (6.67430e-11); double dx = b.x - a.x; double dy = b.y - a.y; - double distSq = dx*dx + dy*dy; + double dz = b.z - a.z; + double distSq = dx*dx + dy*dy + dz*dz; double dist = std::sqrt(distSq); if (dist > 1e-5) @@ -30,12 +31,16 @@ inline void Gravity(Particle& a, Particle& b, double dt) double F = G * a.m * b.m / distSq; double ax = F * dx / dist / a.m; double ay = F * dy / dist / a.m; - double bx = -F * dx / dist / b.m; - double by = -F * dy / dist / b.m; + double az = F * dz / dist / a.m; + double bx = -ax * a.m / b.m; + double by = -ay * a.m / b.m; + double bz = -az * a.m / b.m; a.vx += ax * dt; a.vy += ay * dt; + a.vz += az * dt; b.vx += bx * dt; b.vy += by * dt; + b.vz += bz * dt; } -} \ No newline at end of file +} From a8da4cca34fea09a607caf5e095798aa5ef0e271 Mon Sep 17 00:00:00 2001 From: Timofey Zakharchuk Date: Mon, 19 Jan 2026 13:01:46 +0300 Subject: [PATCH 3/7] Update main.cpp --- src/main.cpp | 224 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 209 insertions(+), 15 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a4520c6..aa12b6a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,82 +1,276 @@ -// Copyright 2026 Timofey Zakharchuk (GitHub: TimGoTheCreator) -// Licensed under the Apache License, Version 2.0 +// Copyright 2026 Timofey Zakharchuk (GitHub: TimGoTheCreator) + +// Licensed under the Apache License, Version 2.0 + #include "conf.h" + #include "raylib.h" + #include + #include +#include "rlImGui.h" + +#include "imgui.h" + + + int main() { + + SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_ALWAYS_RUN); + InitWindow(800, 600, "CxxGRAV"); + + rlImGuiSetup(true); + std::vector particles; - particles.emplace_back(0, 0, 0, 0, 1.99e30, 6.96e8, "Sun"); - particles.emplace_back(150000000000, 0, 0, 29780, 5.97e24, 6.37e6, "Earth"); - particles.emplace_back(150384400000, 0, 0, 30802, 7.35e22, 1.74e6, "Moon"); + + particles.emplace_back(0, 0, 0, 0, 0, 0, 1.99e30, 6.96e8, "Sun"); + + particles.emplace_back(150000000000, 0, 0, 0, 29780, 0, 5.97e24, 6.37e6, "Earth"); + + particles.emplace_back(150384400000, 0, 0, 0, 30802, 0, 7.35e22, 1.74e6, "Moon"); + SetTargetFPS(0); + + double dt = 0.4; + double camX = 0.0; + double camY = 0.0; + double simTime = 0.0; + double scale = 1.5e6; + int steps = 10000; + double camSpeed = 5000000; + bool paused = false; + Vector2 dragStart = {0, 0}; + + bool dragging = false; + + double effectiveSpeed = camSpeed * scale * (IsKeyDown(KEY_LEFT_SHIFT) ? 0.01 : 0.001); + + + while (!WindowShouldClose()) { - if (IsKeyDown(KEY_W)) camY -= camSpeed; - if (IsKeyDown(KEY_S)) camY += camSpeed; - if (IsKeyDown(KEY_A)) camX -= camSpeed; - if (IsKeyDown(KEY_D)) camX += camSpeed; + + static int lastW = 0; + + static int lastH = 0; + + + + int w = GetScreenWidth(); + + int h = GetScreenHeight(); + + + + if (w != lastW || h != lastH) + + { + + SetWindowSize(w, h); + + lastW = w; + + lastH = h; + + } + + + + int cx = w / 2; + + int cy = h / 2; + + + + BeginDrawing(); + + ClearBackground(BLACK); + + + + if (IsKeyPressed(KEY_F11)) ToggleBorderlessWindowed(); + + + + if (IsKeyDown(KEY_W)) camY -= effectiveSpeed; + + if (IsKeyDown(KEY_S)) camY += effectiveSpeed; + + if (IsKeyDown(KEY_A)) camX -= effectiveSpeed; + + if (IsKeyDown(KEY_D)) camX += effectiveSpeed; + if (IsKeyDown(KEY_UP)) scale *= 1.005; + + + if (!ImGui::GetIO().WantCaptureMouse) { + + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { + + dragStart = GetMousePosition(); + + dragging = true; + + } + + } + + + + if (dragging && IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) { + + dragging = false; + + + + Vector2 dragEnd = GetMousePosition(); + + double worldX = (dragStart.x - cx) * scale + camX; + + double worldY = (dragStart.y - cy) * scale + camY; + + + + double dvx = (dragEnd.x - dragStart.x) * 1000; + + double dvy = (dragEnd.y - dragStart.y) * 1000; + + + + particles.emplace_back(worldX, worldY, 0, dvx, dvy, 0, 5.97e24, 6.37e6, "Shot"); + + } + + + if (IsKeyDown(KEY_DOWN)) scale /= 1.005; - if (IsKeyPressed(KEY_SPACE)) { + + + + if (IsKeyPressed(KEY_SPACE)) { + paused = !paused; + } + + if(!paused) { + for (int s = 0; s < steps; s++) { + for (size_t i = 0; i < particles.size(); i++) { + for (size_t j = i + 1; j < particles.size(); j++) { + Gravity(particles[i], particles[j], dt); + } + } + + for (auto& p : particles) { + p.x += p.vx * dt; + p.y += p.vy * dt; + + p.z += p.vz * dt; + } + + simTime += dt; + } + } - BeginDrawing(); - ClearBackground(BLACK); + + for (auto& p : particles) { + + int radius = (int)(p.r / scale); + if (radius < 1) radius = 1; + + Color color = WHITE; + if (p.name == "Earth") color = BLUE; + else if (p.name == "Sun") color = YELLOW; + else if (p.name == "Moon") color = GRAY; + + DrawCircle( - (int)((p.x - camX) / scale) + 400, - (int)((p.y - camY) / scale) + 300, + + (int)((p.x - camX) / scale) + cx, + + (int)((p.y - camY) / scale) + cy, + radius, + color + ); + } + + if (paused) { + DrawText("PAUSED", 10, 10, 20, WHITE); + + } + + + + if (dragging) { + + DrawLineV(dragStart, GetMousePosition(), RED); + } + + + rlImGuiBegin();; + + rlImGuiEnd(); + EndDrawing(); + } -} \ No newline at end of file + + + + rlImGuiShutdown(); + + CloseWindow(); + +} + From 599bd3398a3ee1688837e089346cd678a98cff3a Mon Sep 17 00:00:00 2001 From: Timofey Zakharchuk Date: Mon, 19 Jan 2026 13:04:53 +0300 Subject: [PATCH 4/7] Fix file endings (hopefully) --- src/main.cpp | 138 --------------------------------------------------- 1 file changed, 138 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index aa12b6a..be85bb7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,276 +1,138 @@ // Copyright 2026 Timofey Zakharchuk (GitHub: TimGoTheCreator) - // Licensed under the Apache License, Version 2.0 - #include "conf.h" - #include "raylib.h" - #include - #include - #include "rlImGui.h" - #include "imgui.h" - - int main() { - SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_ALWAYS_RUN); - InitWindow(800, 600, "CxxGRAV"); - rlImGuiSetup(true); - std::vector particles; - particles.emplace_back(0, 0, 0, 0, 0, 0, 1.99e30, 6.96e8, "Sun"); - particles.emplace_back(150000000000, 0, 0, 0, 29780, 0, 5.97e24, 6.37e6, "Earth"); - particles.emplace_back(150384400000, 0, 0, 0, 30802, 0, 7.35e22, 1.74e6, "Moon"); - - SetTargetFPS(0); - - double dt = 0.4; - double camX = 0.0; - double camY = 0.0; - double simTime = 0.0; - double scale = 1.5e6; - int steps = 10000; - double camSpeed = 5000000; - bool paused = false; - Vector2 dragStart = {0, 0}; - bool dragging = false; - double effectiveSpeed = camSpeed * scale * (IsKeyDown(KEY_LEFT_SHIFT) ? 0.01 : 0.001); - - while (!WindowShouldClose()) { - static int lastW = 0; - static int lastH = 0; - - int w = GetScreenWidth(); - int h = GetScreenHeight(); - - if (w != lastW || h != lastH) - { - SetWindowSize(w, h); - lastW = w; - lastH = h; - } - - int cx = w / 2; - int cy = h / 2; - - BeginDrawing(); - ClearBackground(BLACK); - - if (IsKeyPressed(KEY_F11)) ToggleBorderlessWindowed(); - - if (IsKeyDown(KEY_W)) camY -= effectiveSpeed; - if (IsKeyDown(KEY_S)) camY += effectiveSpeed; - if (IsKeyDown(KEY_A)) camX -= effectiveSpeed; - if (IsKeyDown(KEY_D)) camX += effectiveSpeed; - if (IsKeyDown(KEY_UP)) scale *= 1.005; - - if (!ImGui::GetIO().WantCaptureMouse) { - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { - dragStart = GetMousePosition(); - dragging = true; - } - } - - if (dragging && IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) { - dragging = false; - - Vector2 dragEnd = GetMousePosition(); - double worldX = (dragStart.x - cx) * scale + camX; - double worldY = (dragStart.y - cy) * scale + camY; - - double dvx = (dragEnd.x - dragStart.x) * 1000; - double dvy = (dragEnd.y - dragStart.y) * 1000; - - particles.emplace_back(worldX, worldY, 0, dvx, dvy, 0, 5.97e24, 6.37e6, "Shot"); - } - - if (IsKeyDown(KEY_DOWN)) scale /= 1.005; - - if (IsKeyPressed(KEY_SPACE)) { - paused = !paused; - } - - if(!paused) { - for (int s = 0; s < steps; s++) { - for (size_t i = 0; i < particles.size(); i++) { - for (size_t j = i + 1; j < particles.size(); j++) { - Gravity(particles[i], particles[j], dt); - } - } - - for (auto& p : particles) { - p.x += p.vx * dt; - p.y += p.vy * dt; - p.z += p.vz * dt; - } - - simTime += dt; - } - } - - for (auto& p : particles) { - - int radius = (int)(p.r / scale); - if (radius < 1) radius = 1; - - Color color = WHITE; - if (p.name == "Earth") color = BLUE; - else if (p.name == "Sun") color = YELLOW; - else if (p.name == "Moon") color = GRAY; - - DrawCircle( - (int)((p.x - camX) / scale) + cx, - (int)((p.y - camY) / scale) + cy, - radius, - color - ); - } - - if (paused) { - DrawText("PAUSED", 10, 10, 20, WHITE); - } - - if (dragging) { - DrawLineV(dragStart, GetMousePosition(), RED); - } - - rlImGuiBegin();; - rlImGuiEnd(); - EndDrawing(); - } - - rlImGuiShutdown(); - CloseWindow(); - } - From ad81185b0de61a7583bd41106c27396cabbcfa5e Mon Sep 17 00:00:00 2001 From: Timofey Zakharchuk Date: Mon, 19 Jan 2026 13:12:39 +0300 Subject: [PATCH 5/7] Update CMakeLists.txt --- CMakeLists.txt | 61 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5de0036..744461d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,5 @@ - cmake_minimum_required(VERSION 3.15) -project(CxxGRAV VERSION 0.9.3 LANGUAGES CXX) +project(CxxGRAV VERSION 1.0.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -15,15 +14,12 @@ set_target_properties(CxxGRAV PROPERTIES target_compile_options(CxxGRAV PRIVATE -O2) -# --- Auto-download Raylib per platform --- if (WIN32) if (MSVC) - # MSVC-compatible Raylib binary set(RAYLIB_URL https://github.com/raysan5/raylib/releases/download/5.5/raylib-5.5_win64_msvc16.zip) set(RAYLIB_ARCHIVE ${CMAKE_BINARY_DIR}/raylib_msvc.zip) set(RAYLIB_ROOT ${CMAKE_SOURCE_DIR}/libmsvc) else() - # MinGW-compatible Raylib binary set(RAYLIB_URL https://github.com/raysan5/raylib/releases/download/5.5/raylib-5.5_win64_mingw-w64.zip) set(RAYLIB_ARCHIVE ${CMAKE_BINARY_DIR}/raylib.zip) set(RAYLIB_ROOT ${CMAKE_SOURCE_DIR}/lib) @@ -39,57 +35,41 @@ endif() file(MAKE_DIRECTORY ${RAYLIB_ROOT}) if (NOT EXISTS ${RAYLIB_ARCHIVE}) - message(STATUS "Downloading Raylib from ${RAYLIB_URL}") file(DOWNLOAD ${RAYLIB_URL} ${RAYLIB_ARCHIVE} SHOW_PROGRESS) endif() -# Unpack archive -message(STATUS "Extracting Raylib to ${RAYLIB_ROOT}") file(ARCHIVE_EXTRACT INPUT ${RAYLIB_ARCHIVE} DESTINATION ${RAYLIB_ROOT}) -# Detect the extracted subdirectory file(GLOB RAYLIB_SUBDIRS LIST_DIRECTORIES true "${RAYLIB_ROOT}/raylib-*") -list(LENGTH RAYLIB_SUBDIRS _raylib_count) -if (_raylib_count EQUAL 0) - message(FATAL_ERROR "Raylib extraction failed—no raylib-* directory found in ${RAYLIB_ROOT}") -elseif(_raylib_count GREATER 1) - list(SORT RAYLIB_SUBDIRS) - list(GET RAYLIB_SUBDIRS 0 RAYLIB_DIR) -else() - list(GET RAYLIB_SUBDIRS 0 RAYLIB_DIR) -endif() +list(SORT RAYLIB_SUBDIRS) +list(GET RAYLIB_SUBDIRS 0 RAYLIB_DIR) set(RAYLIB_INCLUDE_DIR "${RAYLIB_DIR}/include") set(RAYLIB_LIB_DIR "${RAYLIB_DIR}/lib") -# --- Platform-specific includes and libs --- if (WIN32) target_include_directories(CxxGRAV PRIVATE ${RAYLIB_INCLUDE_DIR}) target_link_directories(CxxGRAV PRIVATE ${RAYLIB_LIB_DIR}) target_link_libraries(CxxGRAV PRIVATE raylib opengl32 gdi32 winmm ws2_32) if (MSVC) - # On MSVC, system libs are provided by the Windows SDK — no setup.sh needed target_compile_options(CxxGRAV PRIVATE /O2) target_link_options(CxxGRAV PRIVATE /INCREMENTAL:NO) else() - # MinGW target_link_options(CxxGRAV PRIVATE -s) endif() elseif(UNIX) - # Check for system dependencies find_package(OpenGL) find_package(X11) if (NOT OpenGL_FOUND OR NOT X11_FOUND) - message(WARNING "Missing system libraries. Running setup.sh to install dependencies...") execute_process( COMMAND bash ${CMAKE_SOURCE_DIR}/setup.sh RESULT_VARIABLE setup_result ) if (NOT setup_result EQUAL 0) - message(FATAL_ERROR "setup.sh failed. Please run it manually with sudo.") + message(FATAL_ERROR "setup.sh failed.") endif() endif() @@ -99,4 +79,37 @@ elseif(UNIX) target_compile_options(CxxGRAV PRIVATE -Wall -Wextra -Wpedantic) endif() +include(FetchContent) + +FetchContent_Declare( + imgui + URL https://github.com/ocornut/imgui/archive/refs/heads/master.zip +) + +FetchContent_Declare( + rlimgui + URL https://github.com/raylib-extras/rlImGui/archive/refs/heads/main.zip +) + +FetchContent_MakeAvailable(imgui rlimgui) + +add_library(imgui_bundle STATIC + ${imgui_SOURCE_DIR}/imgui.cpp + ${imgui_SOURCE_DIR}/imgui_draw.cpp + ${imgui_SOURCE_DIR}/imgui_tables.cpp + ${imgui_SOURCE_DIR}/imgui_widgets.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp + ${rlimgui_SOURCE_DIR}/rlImGui.cpp +) + +target_include_directories(imgui_bundle PUBLIC + ${imgui_SOURCE_DIR} + ${imgui_SOURCE_DIR}/backends + ${rlimgui_SOURCE_DIR} + ${RAYLIB_INCLUDE_DIR} +) + +target_link_libraries(CxxGRAV PRIVATE imgui_bundle) + install(TARGETS CxxGRAV DESTINATION bin) From 1c7ed6859fa57ea12d993b9735ce720f18ed5bf7 Mon Sep 17 00:00:00 2001 From: Timofey Zakharchuk Date: Mon, 19 Jan 2026 13:15:39 +0300 Subject: [PATCH 6/7] Update CMakeLists.txt --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 744461d..c6cd95b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,8 +98,6 @@ add_library(imgui_bundle STATIC ${imgui_SOURCE_DIR}/imgui_draw.cpp ${imgui_SOURCE_DIR}/imgui_tables.cpp ${imgui_SOURCE_DIR}/imgui_widgets.cpp - ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp - ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp ${rlimgui_SOURCE_DIR}/rlImGui.cpp ) From 66e9acc5dadb610078f1239cd056972ea08c8d4d Mon Sep 17 00:00:00 2001 From: Timofey Zakharchuk Date: Mon, 19 Jan 2026 22:10:33 +0300 Subject: [PATCH 7/7] Add files via upload --- src/conf.h | 17 +++----- src/main.cpp | 113 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 102 insertions(+), 28 deletions(-) diff --git a/src/conf.h b/src/conf.h index ece7fa6..7da2dd9 100644 --- a/src/conf.h +++ b/src/conf.h @@ -6,14 +6,14 @@ struct Particle { - double x, y, z; - double vx, vy, vz; + double x, y; + double vx, vy; double m; double r; std::string name; - Particle(double px, double py, double pz, double pvx, double pvy, double pvz, double pm, double pr, const std::string&n) - : x(px), y(py), z(pz), vx(pvx), vy(pvy), vz(pvz), m(pm), r(pr), name(n) {} + Particle(double px, double py, double pvx, double pvy, double pm, double pr, const std::string&n) + : x(px), y(py), vx(pvx), vy(pvy), m(pm), r(pr), name(n) {} }; @@ -22,8 +22,7 @@ inline void Gravity(Particle& a, Particle& b, double dt) constexpr double G (6.67430e-11); double dx = b.x - a.x; double dy = b.y - a.y; - double dz = b.z - a.z; - double distSq = dx*dx + dy*dy + dz*dz; + double distSq = dx*dx + dy*dy; double dist = std::sqrt(distSq); if (dist > 1e-5) @@ -31,16 +30,12 @@ inline void Gravity(Particle& a, Particle& b, double dt) double F = G * a.m * b.m / distSq; double ax = F * dx / dist / a.m; double ay = F * dy / dist / a.m; - double az = F * dz / dist / a.m; double bx = -ax * a.m / b.m; double by = -ay * a.m / b.m; - double bz = -az * a.m / b.m; a.vx += ax * dt; a.vy += ay * dt; - a.vz += az * dt; b.vx += bx * dt; b.vy += by * dt; - b.vz += bz * dt; } -} +} diff --git a/src/main.cpp b/src/main.cpp index be85bb7..1da5912 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,9 +12,9 @@ int main() { InitWindow(800, 600, "CxxGRAV"); rlImGuiSetup(true); std::vector particles; - particles.emplace_back(0, 0, 0, 0, 0, 0, 1.99e30, 6.96e8, "Sun"); - particles.emplace_back(150000000000, 0, 0, 0, 29780, 0, 5.97e24, 6.37e6, "Earth"); - particles.emplace_back(150384400000, 0, 0, 0, 30802, 0, 7.35e22, 1.74e6, "Moon"); + particles.emplace_back(0, 0, 0, 0, 1.99e30, 6.96e8, "Sun"); + particles.emplace_back(150000000000, 0, 0, 29780, 5.97e24, 6.37e6, "Earth"); + particles.emplace_back(150384400000, 0, 0, 30802, 7.35e22, 1.74e6, "Moon"); SetTargetFPS(0); @@ -24,13 +24,19 @@ int main() { double simTime = 0.0; double scale = 1.5e6; int steps = 10000; - double camSpeed = 5000000; - bool paused = false; + static bool paused = false; Vector2 dragStart = {0, 0}; bool dragging = false; - double effectiveSpeed = camSpeed * scale * (IsKeyDown(KEY_LEFT_SHIFT) ? 0.01 : 0.001); + static bool left_locked = true; + static bool right_locked = true; + double userSpeed = 1.0; + int trackedIndex = -1; + static double shotMass = 5.97e24; + static double shotRadius = 6.37e6; + static char shotName[64] = "Shot"; while (!WindowShouldClose()) { + double effectiveSpeed = scale * userSpeed * (IsKeyDown(KEY_LEFT_SHIFT) ? 5.0 : 1.0); static int lastW = 0; static int lastH = 0; @@ -52,10 +58,14 @@ int main() { if (IsKeyPressed(KEY_F11)) ToggleBorderlessWindowed(); - if (IsKeyDown(KEY_W)) camY -= effectiveSpeed; - if (IsKeyDown(KEY_S)) camY += effectiveSpeed; - if (IsKeyDown(KEY_A)) camX -= effectiveSpeed; - if (IsKeyDown(KEY_D)) camX += effectiveSpeed; + if (!ImGui::GetIO().WantTextInput) + { + if (IsKeyDown(KEY_W)) camY -= effectiveSpeed; + if (IsKeyDown(KEY_S)) camY += effectiveSpeed; + if (IsKeyDown(KEY_A)) camX -= effectiveSpeed; + if (IsKeyDown(KEY_D)) camX += effectiveSpeed; + } + if (IsKeyDown(KEY_UP)) scale *= 1.005; if (!ImGui::GetIO().WantCaptureMouse) { @@ -75,7 +85,7 @@ int main() { double dvx = (dragEnd.x - dragStart.x) * 1000; double dvy = (dragEnd.y - dragStart.y) * 1000; - particles.emplace_back(worldX, worldY, 0, dvx, dvy, 0, 5.97e24, 6.37e6, "Shot"); + particles.emplace_back(worldX, worldY, dvx, dvy, shotMass, shotRadius, shotName); } if (IsKeyDown(KEY_DOWN)) scale /= 1.005; @@ -95,12 +105,18 @@ int main() { for (auto& p : particles) { p.x += p.vx * dt; p.y += p.vy * dt; - p.z += p.vz * dt; } simTime += dt; } } + + if (trackedIndex >= 0 && trackedIndex < particles.size()) + { + camX = particles[trackedIndex].x; + camY = particles[trackedIndex].y; + } + for (auto& p : particles) { @@ -120,15 +136,78 @@ int main() { ); } - if (paused) { - DrawText("PAUSED", 10, 10, 20, WHITE); - } - if (dragging) { DrawLineV(dragStart, GetMousePosition(), RED); } - rlImGuiBegin();; + rlImGuiBegin(); + + { + ImGuiWindowFlags flags = ImGuiWindowFlags_NoCollapse; + if (left_locked) + { + ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always); + ImGui::SetNextWindowSize(ImVec2(250, ImGui::GetMainViewport()->Size.y), ImGuiCond_Always); + + flags |= ImGuiWindowFlags_NoMove; + flags |= ImGuiWindowFlags_NoResize; + } + + ImGui::Begin("CXXGrav Panel", nullptr, flags); + + if (ImGui::Button(left_locked ? "Unlock" : "Lock")) + left_locked = !left_locked; + + if (ImGui::Button(paused ? "Resume" : "Pause")) { + paused = !paused; + } + + ImGui::DragScalar("Camera Speed", ImGuiDataType_Double, &userSpeed, 0.1, nullptr, nullptr, "%.6f"); + + ImGui::Separator(); + + ImGui::DragScalar("Mass (KG)", ImGuiDataType_Double, &shotMass, 1e20, nullptr, nullptr, "%.6e"); + ImGui::DragScalar("Radius (M)", ImGuiDataType_Double, &shotRadius, 1e5, nullptr, nullptr, "%.6e"); + ImGui::InputText("Name", shotName, IM_ARRAYSIZE(shotName)); + ImGui::End(); + + { + ImGuiWindowFlags flags = ImGuiWindowFlags_NoCollapse; + if (right_locked) + { + ImGui::SetNextWindowPos(ImVec2(GetScreenWidth() - 250, 0), ImGuiCond_Always); + ImGui::SetNextWindowSize(ImVec2(250, ImGui::GetMainViewport()->Size.y), ImGuiCond_Always); + + flags |= ImGuiWindowFlags_NoMove; + flags |= ImGuiWindowFlags_NoResize; + } + + ImGui::Begin("Bodies", nullptr, flags); + if (ImGui::Button(right_locked ? "Unlock" : "Lock")) + right_locked = !right_locked; + + ImGui::Separator(); + ImGui::Text("Bodies in simulation:"); + + for (int i = 0; i < particles.size(); i++) { + std::string label = particles[i].name + "##" + std::to_string(i); + if (ImGui::Selectable(label.c_str(), trackedIndex == i)) { + trackedIndex = i;} + } + + if (trackedIndex != -1) + { + if (ImGui::Button("Stop Tracking")) { + trackedIndex = -1; + } + } + + + ImGui::End(); + + } + } + rlImGuiEnd(); EndDrawing(); }