#pragma once #include #include #include #include #include #include #include #include "core/camera.h" #include "object.h" #include "rendering/renderer.h" #include "rendering/shader.h" #include "rendering/vertex_array.h" #include "rendering/texture.h" #include "rendering/uniform_buffer.h" #include "rendering/texture_manager.h" #include #include #include #include namespace Donut { const double c = 299792458.0; const double G = 6.67430e-11; struct BlackHole { glm::vec3 m_position; double m_mass; double m_radius; double m_rs; BlackHole(glm::vec3 pos, float mass) : m_position(pos), m_mass(mass) { m_rs = 2.0 * G * m_mass / (c * c); } bool intercept(float px, float py, float pz) const { double dx = double(px) - double(m_position.x); double dy = double(py) - double(m_position.y); double dz = double(pz) - double(m_position.z); double dist2 = dx * dx + dy * dy + dz * dz; return dist2 < m_rs * m_rs; } }; struct ObjectData { glm::vec4 m_pos_radius; glm::vec4 m_color; float m_mass; glm::vec3 m_velocity = glm::vec3(0.0f, 0.0f, 0.0f); }; class Engine { public: Engine(); ~Engine() = default; void draw_full_screen_quad(); void dispatch_compute(const Camera& cam); void upload_camera_ubo(const Camera& cam); void upload_objects_ubo(const std::vector& objs); void upload_disk_ubo(); void upload_simulation_ubo(); 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; } std::vector& get_objects() { return m_objects; } BlackHole& get_sag_a() { return m_sag_a; } Camera& get_camera() { return m_camera; } bool& get_gravity() { return m_gravity; } void update_performance(float delta_time); void set_target_fps(int fps) { m_target_fps = fps; } int get_target_fps() const { return m_target_fps; } float get_current_fps() const { return m_current_fps; } void set_compute_height(int height) { m_compute_height = height; } int get_compute_height() const { return m_compute_height; } int get_compute_width() const { return (m_width * m_compute_height) / m_height; } void update_compute_dimensions(); int get_max_steps_moving() const { return m_max_steps_moving; } int get_max_steps_static() const { return m_max_steps_static; } float get_early_exit_distance() const { return m_early_exit_distance; } 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; } float get_disk_thickness() const { return m_disk_thickness; } void set_disk_thickness(float thickness) { m_disk_thickness = thickness; } float get_disk_density() const { return m_disk_density; } void set_disk_density(float density) { m_disk_density = density; } float get_rotation_speed() const { return m_rotation_speed; } void set_rotation_speed(float speed) { m_rotation_speed = speed; } void load_objects_from_scene(const std::vector& objects); void export_high_res_frame(const std::string& filename, int width = 4096, int height = 3072); void print_object_info() const; private: Ref create_compute_program(const char* path); std::pair, Ref> quad_vao(); private: Ref m_quad_vao; Ref m_texture; Ref m_shader_program; Ref m_compute_program; Ref m_camera_ubo; Ref m_disk_ubo; Ref m_objects_ubo; Ref m_simulation_ubo; int m_width; int m_height; float m_width_f = 100*10e10f; float m_height_f = 75*10e10f; int m_target_fps = 60; float m_current_fps = 60.0f; float m_last_frame_time = 0.0f; int m_compute_height = 150; std::vector m_objects; BlackHole m_sag_a; Camera m_camera; bool m_gravity = false; int m_max_steps_moving = 60000; int m_max_steps_static = 30000; float m_early_exit_distance = 5e11f; float m_disk_thickness = 0.1; float m_disk_density = 1.2f; float m_rotation_speed = 1.0f; }; };