diff options
| -rw-r--r-- | src/core/application.cpp | 4 | ||||
| -rw-r--r-- | src/core/application.h | 10 | ||||
| -rw-r--r-- | src/engine/engine.cpp | 82 | ||||
| -rw-r--r-- | src/engine/engine.h | 7 | ||||
| -rw-r--r-- | src/states/config_state.cpp | 9 | ||||
| -rw-r--r-- | src/states/simulation_state.cpp | 110 | ||||
| -rw-r--r-- | src/states/simulation_state.h | 1 | ||||
| -rw-r--r-- | src/states/world_builder_state.cpp | 10 |
8 files changed, 164 insertions, 69 deletions
diff --git a/src/core/application.cpp b/src/core/application.cpp index 85c7645..37d7fa0 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -71,6 +71,7 @@ namespace Donut m_minimized = false; Renderer::on_window_resize(e.get_width(), e.get_height()); + m_engine->set_window_dimensions(e.get_width(), e.get_height()); event.handled = true; return true; }); @@ -118,6 +119,9 @@ namespace Donut Renderer::on_window_resize(1280, 720); RenderCommand::set_face_culling(false); + m_engine = create_scope<Engine>(); + m_engine->set_window_dimensions(1280, 720); + m_state_manager = create_scope<StateManager>(); m_state_manager->register_state("Config", create_scope<ConfigState>()); m_state_manager->register_state("Simulation", create_scope<SimulationState>()); diff --git a/src/core/application.h b/src/core/application.h index 521b15b..8e13f7b 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -1,10 +1,12 @@ #pragma once +#include "state_manager.h" #include "memory.h" #include "window.h" #include "event.h" #include "log.h" -#include "state_manager.h" + +#include "engine/engine.h" namespace Donut { @@ -18,9 +20,10 @@ namespace Donut void run(); void close(); - Window& get_window() { return *m_window; } + Window& get_window() { return *m_window; } StateManager& get_state_manager() { return *m_state_manager; } - static Application& get() { return *s_instance; } + Engine& get_engine() { return *m_engine; } + static Application& get() { return *s_instance; } private: void on_init(); void on_shutdown(); @@ -31,6 +34,7 @@ namespace Donut private: Scope<StateManager> m_state_manager; Scope<Window> m_window; + Scope<Engine> m_engine; bool m_running; bool m_minimized; diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 9577d1e..ef9b93d 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -5,6 +5,7 @@ #include <GLFW/glfw3.h> #include "engine.h" +#include "core/log.h" #include "rendering/vertex_buffer.h" #include "rendering/index_buffer.h" @@ -13,14 +14,14 @@ namespace Donut Engine::Engine() : m_sag_a(glm::vec3(0.0f, 0.0f, 0.0f), 8.54e36f) { - GLFWwindow* window = static_cast<GLFWwindow*>(Application::get().get_window().get_native_window()); - glfwGetFramebufferSize(window, &m_width, &m_height); + m_width = 1280; + m_height = 720; m_camera.set_camera_mode(CameraMode::Orbital); - m_camera.set_orbital_radius(6.34194e10); - m_camera.set_orbital_limits(1e10, 1e12); + m_camera.set_orbital_radius(1e11); + m_camera.set_orbital_limits(1e9, 1e13); m_camera.set_orbital_speed(0.01f); - m_camera.set_zoom_speed(25e9f); + m_camera.set_zoom_speed(1e10f); m_objects = { @@ -47,12 +48,17 @@ namespace Donut void Engine::update_window_dimensions() { - GLFWwindow* window = static_cast<GLFWwindow*>(Application::get().get_window().get_native_window()); + update_compute_dimensions(); + } + + void Engine::set_window_dimensions(int width, int height) + { int old_width = m_width; int old_height = m_height; int old_compute_height = m_compute_height; - glfwGetFramebufferSize(window, &m_width, &m_height); + m_width = width; + m_height = height; if (old_width != m_width || old_height != m_height || @@ -273,4 +279,66 @@ namespace Donut return { vertex_array, texture }; } + + void Engine::load_objects_from_scene(const std::vector<Donut::Object>& objects) + { + m_objects.clear(); + m_objects.push_back( + { + glm::vec4(0.00f, 0.00f, 0.00f, m_sag_a.m_rs), + glm::vec4(0, 0, 0, 1), + static_cast<float>(m_sag_a.m_mass) + }); + + for (const auto& obj : objects) + { + ObjectData engine_obj; + + float scale_factor = 1e10f; + engine_obj.m_pos_radius = glm::vec4 + ( + obj.m_centre.x * scale_factor, + obj.m_centre.y * scale_factor, + obj.m_centre.z * scale_factor, + obj.m_radius * scale_factor + ); + + engine_obj.m_color = glm::vec4(obj.m_material.m_color, 1.0f); + + float volume = (4.0f / 3.0f) * 3.14159f * engine_obj.m_pos_radius.w * engine_obj.m_pos_radius.w * engine_obj.m_pos_radius.w; + float density = 1e12f; + engine_obj.m_mass = volume * density; + engine_obj.m_velocity = glm::vec3(0.0f, 0.0f, 0.0f); + + m_objects.push_back(engine_obj); + } + + DONUT_INFO("Loaded {} objects from WorldBuilder scene (scaled up by {})", objects.size(), 1e10f); + print_object_info(); + } + + void Engine::print_object_info() const + { + DONUT_INFO("=== Object Information ==="); + DONUT_INFO("Total objects: {}", m_objects.size()); + + for (size_t i = 0; i < m_objects.size(); ++i) + { + const auto& obj = m_objects[i]; + DONUT_INFO("Object {}: Pos=({:.2e}, {:.2e}, {:.2e}), Radius={:.2e}, Mass={:.2e}, Color=({:.2f}, {:.2f}, {:.2f})", + i, + obj.m_pos_radius.x, obj.m_pos_radius.y, obj.m_pos_radius.z, + obj.m_pos_radius.w, + obj.m_mass, + obj.m_color.x, obj.m_color.y, obj.m_color.z + ); + } + DONUT_INFO("Camera position: ({:.2e}, {:.2e}, {:.2e})", + m_camera.get_orbital_position().x, + m_camera.get_orbital_position().y, + m_camera.get_orbital_position().z + ); + DONUT_INFO("Camera radius: {:.2e}", m_camera.get_orbital_radius()); + DONUT_INFO("========================"); + } } diff --git a/src/engine/engine.h b/src/engine/engine.h index 124fa39..b0e06f3 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -8,8 +8,9 @@ #include <chrono> #include <cmath> -#include "core/application.h" #include "core/camera.h" +#include "object.h" + #include "rendering/renderer.h" #include "rendering/shader.h" #include "rendering/vertex_array.h" @@ -73,6 +74,7 @@ namespace Donut void render_scene(); void update_physics(float delta_time); void update_window_dimensions(); + void set_window_dimensions(int width, int height); int get_width() const { return m_width; } int get_height() const { return m_height; } @@ -97,6 +99,9 @@ namespace Donut void set_max_steps_moving(int steps) { m_max_steps_moving = steps; } void set_max_steps_static(int steps) { m_max_steps_static = steps; } void set_early_exit_distance(float distance) { m_early_exit_distance = distance; } + + void load_objects_from_scene(const std::vector<Donut::Object>& objects); + void print_object_info() const; private: Ref<Shader> create_compute_program(const char* path); std::pair<Ref<VertexArray>, Ref<Texture2D>> quad_vao(); diff --git a/src/states/config_state.cpp b/src/states/config_state.cpp index 41fbaad..4573aab 100644 --- a/src/states/config_state.cpp +++ b/src/states/config_state.cpp @@ -216,15 +216,8 @@ namespace Donut ImGui::Separator(); ImGui::Spacing(); - float button_width = (ImGui::GetWindowWidth() - 120) / 6.0f; + float button_width = (ImGui::GetWindowWidth() - 120) / 5.0f; - if (ImGui::Button("Start Simulation", ImVec2(button_width, 35))) - { - apply_settings(); - Application::get().get_state_manager().switch_to_state("Simulation"); - } - - ImGui::SameLine(); if (ImGui::Button("World Builder", ImVec2(button_width, 35))) { apply_settings(); diff --git a/src/states/simulation_state.cpp b/src/states/simulation_state.cpp index e71d498..6964852 100644 --- a/src/states/simulation_state.cpp +++ b/src/states/simulation_state.cpp @@ -15,15 +15,16 @@ namespace Donut DONUT_INFO("Entering Simulation State"); const auto& settings = SettingsManager::get_settings_const(); + auto& engine = Application::get().get_engine(); - m_engine.set_target_fps(settings.simulation.target_fps); - m_engine.set_compute_height(settings.simulation.compute_height); - m_engine.set_max_steps_moving(settings.simulation.max_steps_moving); - m_engine.set_max_steps_static(settings.simulation.max_steps_static); - m_engine.set_early_exit_distance(settings.simulation.early_exit_distance); - m_engine.get_gravity() = settings.simulation.gravity_enabled; + engine.set_target_fps(settings.simulation.target_fps); + engine.set_compute_height(settings.simulation.compute_height); + engine.set_max_steps_moving(settings.simulation.max_steps_moving); + engine.set_max_steps_static(settings.simulation.max_steps_static); + engine.set_early_exit_distance(settings.simulation.early_exit_distance); + engine.get_gravity() = settings.simulation.gravity_enabled; - m_engine.update_compute_dimensions(); + engine.update_compute_dimensions(); m_initialized = true; } @@ -34,38 +35,42 @@ namespace Donut void SimulationState::on_update(float delta_time) { - m_engine.update_performance(delta_time); - m_engine.update_window_dimensions(); - m_engine.update_physics(delta_time); + auto& engine = Application::get().get_engine(); + engine.update_performance(delta_time); + engine.update_window_dimensions(); + engine.update_physics(delta_time); - if (m_engine.get_camera().is_dragging()) + if (engine.get_camera().is_dragging()) { GLFWwindow* window = static_cast<GLFWwindow*>(Application::get().get_window().get_native_window()); double xpos, ypos; glfwGetCursorPos(window, &xpos, &ypos); - m_engine.get_camera().process_orbital_mouse_move(xpos, ypos); + engine.get_camera().process_orbital_mouse_move(xpos, ypos); } } void SimulationState::on_render() { + auto& engine = Application::get().get_engine(); RenderCommand::set_clear_color(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); RenderCommand::clear(); - RenderCommand::set_viewport(0, 0, m_engine.get_width(), m_engine.get_height()); + RenderCommand::set_viewport(0, 0, static_cast<uint32_t>(engine.get_width()), static_cast<uint32_t>(engine.get_height())); - m_engine.dispatch_compute(m_engine.get_camera()); - m_engine.draw_full_screen_quad(); + engine.dispatch_compute(engine.get_camera()); + engine.draw_full_screen_quad(); } void SimulationState::on_event(Event& event) { + auto& engine = Application::get().get_engine(); + if (event.get_event_type() == EventType::MouseButtonPressed) { MouseButtonPressedEvent& e = (MouseButtonPressedEvent&)event; int button = e.get_mouse_button(); GLFWwindow* window = static_cast<GLFWwindow*>(Application::get().get_window().get_native_window()); - Camera& camera = m_engine.get_camera(); + Camera& camera = engine.get_camera(); double last_x = camera.get_last_x(); double last_y = camera.get_last_y(); glfwGetCursorPos(window, &last_x, &last_y); @@ -76,13 +81,13 @@ namespace Donut { MouseButtonReleasedEvent& e = (MouseButtonReleasedEvent&)event; int button = e.get_mouse_button(); - m_engine.get_camera().process_orbital_mouse_button(button, GLFW_RELEASE, 0); + engine.get_camera().process_orbital_mouse_button(button, GLFW_RELEASE, 0); } if (event.get_event_type() == EventType::MouseScrolled) { MouseScrolledEvent& e = (MouseScrolledEvent&)event; - m_engine.get_camera().process_orbital_scroll(e.get_x_offset(), e.get_y_offset()); + engine.get_camera().process_orbital_scroll(e.get_x_offset(), e.get_y_offset()); } if (event.get_event_type() == EventType::KeyPressed) @@ -90,14 +95,16 @@ namespace Donut KeyPressedEvent& e = (KeyPressedEvent&)event; if (e.get_key_code() == GLFW_KEY_G) { - m_engine.get_gravity() = !m_engine.get_gravity(); - DONUT_INFO("Gravity turned {}", m_engine.get_gravity() ? "ON" : "OFF"); + engine.get_gravity() = !engine.get_gravity(); + DONUT_INFO("Gravity turned {}", engine.get_gravity() ? "ON" : "OFF"); } } } void SimulationState::on_im_ui_render() { + auto& engine = Application::get().get_engine(); + ImGui::SetNextWindowSize(ImVec2(400, 600), ImGuiCond_FirstUseEver); ImGui::SetNextWindowPos(ImVec2(ImGui::GetIO().DisplaySize.x - 420, 20), ImGuiCond_FirstUseEver); @@ -111,12 +118,12 @@ namespace Donut if (ImGui::Button("Save Settings")) { SimulationSettings settings = SettingsManager::get_settings_const().simulation; - settings.target_fps = m_engine.get_target_fps(); - settings.compute_height = m_engine.get_compute_height(); - settings.max_steps_moving = m_engine.get_max_steps_moving(); - settings.max_steps_static = m_engine.get_max_steps_static(); - settings.early_exit_distance = m_engine.get_early_exit_distance(); - settings.gravity_enabled = m_engine.get_gravity(); + settings.target_fps = engine.get_target_fps(); + settings.compute_height = engine.get_compute_height(); + settings.max_steps_moving = engine.get_max_steps_moving(); + settings.max_steps_static = engine.get_max_steps_static(); + settings.early_exit_distance = engine.get_early_exit_distance(); + settings.gravity_enabled = engine.get_gravity(); SettingsManager::set_simulation_settings(settings); DONUT_INFO("Simulation settings saved manually"); } @@ -128,12 +135,12 @@ namespace Donut ImGui::Text("FPS: %.1f", ImGui::GetIO().Framerate); ImGui::Text("Frame Time: %.3f ms", 1000.0f / ImGui::GetIO().Framerate); - ImGui::Text("Engine FPS: %.1f", m_engine.get_current_fps()); + ImGui::Text("Engine FPS: %.1f", engine.get_current_fps()); - int target_fps = m_engine.get_target_fps(); + int target_fps = engine.get_target_fps(); if (ImGui::SliderInt("Target FPS", &target_fps, 30, 120)) { - m_engine.set_target_fps(target_fps); + engine.set_target_fps(target_fps); SimulationSettings settings = SettingsManager::get_settings_const().simulation; settings.target_fps = target_fps; SettingsManager::set_simulation_settings(settings); @@ -144,47 +151,52 @@ namespace Donut ImGui::TextColored(ImVec4(0.9f, 0.9f, 1.0f, 1.0f), "Simulation Info"); ImGui::Separator(); - ImGui::Text("Resolution: %dx%d", m_engine.get_width(), m_engine.get_height()); - ImGui::Text("Compute Resolution: %dx%d", m_engine.get_compute_width(), m_engine.get_compute_height()); - ImGui::Text("Objects: %zu", m_engine.get_objects().size()); + ImGui::Text("Resolution: %dx%d", engine.get_width(), engine.get_height()); + ImGui::Text("Compute Resolution: %dx%d", engine.get_compute_width(), engine.get_compute_height()); + ImGui::Text("Objects: %zu", engine.get_objects().size()); + + if (ImGui::Button("Print Object Info")) + { + engine.print_object_info(); + } - int compute_height = m_engine.get_compute_height(); + int compute_height = engine.get_compute_height(); if (ImGui::SliderInt("Compute Height", &compute_height, 64, 2048)) { - m_engine.set_compute_height(compute_height); - m_engine.update_compute_dimensions(); + engine.set_compute_height(compute_height); + engine.update_compute_dimensions(); SimulationSettings settings = SettingsManager::get_settings_const().simulation; settings.compute_height = compute_height; SettingsManager::set_simulation_settings(settings); } - ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "Compute Width: %d (auto-calculated)", m_engine.get_compute_width()); + ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "Compute Width: %d (auto-calculated)", engine.get_compute_width()); ImGui::Spacing(); ImGui::TextColored(ImVec4(0.9f, 0.9f, 1.0f, 1.0f), "Quality Settings"); ImGui::Separator(); - int max_steps_moving = m_engine.get_max_steps_moving(); + int max_steps_moving = engine.get_max_steps_moving(); if (ImGui::SliderInt("Max Steps (Moving)", &max_steps_moving, 1000, 60000)) { - m_engine.set_max_steps_moving(max_steps_moving); + engine.set_max_steps_moving(max_steps_moving); SimulationSettings settings = SettingsManager::get_settings_const().simulation; settings.max_steps_moving = max_steps_moving; SettingsManager::set_simulation_settings(settings); } - int max_steps_static = m_engine.get_max_steps_static(); + int max_steps_static = engine.get_max_steps_static(); if (ImGui::SliderInt("Max Steps (Static)", &max_steps_static, 1000, 30000)) { - m_engine.set_max_steps_static(max_steps_static); + engine.set_max_steps_static(max_steps_static); SimulationSettings settings = SettingsManager::get_settings_const().simulation; settings.max_steps_static = max_steps_static; SettingsManager::set_simulation_settings(settings); } - float early_exit_distance = m_engine.get_early_exit_distance(); + float early_exit_distance = engine.get_early_exit_distance(); if (ImGui::SliderFloat("Early Exit Distance", &early_exit_distance, 1e11f, 1e13f, "%.2e")) { - m_engine.set_early_exit_distance(early_exit_distance); + engine.set_early_exit_distance(early_exit_distance); SimulationSettings settings = SettingsManager::get_settings_const().simulation; settings.early_exit_distance = early_exit_distance; SettingsManager::set_simulation_settings(settings); @@ -195,7 +207,7 @@ namespace Donut ImGui::TextColored(ImVec4(0.9f, 0.9f, 1.0f, 1.0f), "Physics"); ImGui::Separator(); - bool& gravity = m_engine.get_gravity(); + bool& gravity = engine.get_gravity(); if (ImGui::Checkbox("Gravity Enabled", &gravity)) { SimulationSettings settings = SettingsManager::get_settings_const().simulation; @@ -209,12 +221,12 @@ namespace Donut ImGui::Separator(); ImGui::Text("Position: (%.2e, %.2e, %.2e)", - m_engine.get_camera().get_orbital_position().x, - m_engine.get_camera().get_orbital_position().y, - m_engine.get_camera().get_orbital_position().z); - ImGui::Text("Radius: %.2e", m_engine.get_camera().get_orbital_radius()); - ImGui::Text("Azimuth: %.2f", m_engine.get_camera().get_azimuth()); - ImGui::Text("Elevation: %.2f", m_engine.get_camera().get_elevation()); + engine.get_camera().get_orbital_position().x, + engine.get_camera().get_orbital_position().y, + engine.get_camera().get_orbital_position().z); + ImGui::Text("Radius: %.2e", engine.get_camera().get_orbital_radius()); + ImGui::Text("Azimuth: %.2f", engine.get_camera().get_azimuth()); + ImGui::Text("Elevation: %.2f", engine.get_camera().get_elevation()); ImGui::Spacing(); diff --git a/src/states/simulation_state.h b/src/states/simulation_state.h index cc55901..9a89fea 100644 --- a/src/states/simulation_state.h +++ b/src/states/simulation_state.h @@ -22,7 +22,6 @@ namespace Donut void on_event(Event& event) override; private: - Engine m_engine; bool m_initialized = false; }; }; diff --git a/src/states/world_builder_state.cpp b/src/states/world_builder_state.cpp index a01935c..f28f70a 100644 --- a/src/states/world_builder_state.cpp +++ b/src/states/world_builder_state.cpp @@ -480,6 +480,16 @@ namespace Donut ImGui::Spacing(); + if (ImGui::Button("Start Simulation", ImVec2(ImGui::GetWindowWidth() - 20, 30))) + { + auto& engine = Application::get().get_engine(); + engine.load_objects_from_scene(m_scene.objs); + + Application::get().get_state_manager().switch_to_state("Simulation"); + } + + ImGui::Spacing(); + if (ImGui::Button("Back to Config", ImVec2(ImGui::GetWindowWidth() - 20, 30))) Application::get().get_state_manager().switch_to_state("Config"); |
