diff --git a/src/entity/systems/astronomy.cpp b/src/entity/systems/astronomy.cpp index 3bd6c15..79ceff4 100644 --- a/src/entity/systems/astronomy.cpp +++ b/src/entity/systems/astronomy.cpp @@ -66,7 +66,8 @@ astronomy::astronomy(entity::registry& registry): moon_light(nullptr), camera(nullptr), sky_pass(nullptr), - exposure_offset(0.0) + exposure_offset(0.0), + starlight_illuminance(0.0) { // Construct transformation which transforms coordinates from ENU to EUS enu_to_eus = math::transformation::se3 @@ -79,6 +80,12 @@ astronomy::astronomy(entity::registry& registry): registry.on_replace().connect<&astronomy::on_celestial_body_replace>(this); } +astronomy::~astronomy() +{ + registry.on_construct().disconnect<&astronomy::on_celestial_body_construct>(this); + registry.on_replace().disconnect<&astronomy::on_celestial_body_replace>(this); +} + void astronomy::update(double t, double dt) { double total_illuminance = 0.0; @@ -271,7 +278,6 @@ void astronomy::update(double t, double dt) sky_light_illuminance += sky_illuminance; // Add starlight illuminance to sky light illuminance - const double starlight_illuminance = 0.0002; sky_light_illuminance += starlight_illuminance; // Add sky light illuminance to total illuminance @@ -478,6 +484,11 @@ void astronomy::set_exposure_offset(float offset) exposure_offset = offset; } +void astronomy::set_starlight_illuminance(double illuminance) +{ + starlight_illuminance = illuminance; +} + void astronomy::set_sky_pass(::render::sky_pass* pass) { this->sky_pass = pass; diff --git a/src/entity/systems/astronomy.hpp b/src/entity/systems/astronomy.hpp index d8a0769..83599f4 100644 --- a/src/entity/systems/astronomy.hpp +++ b/src/entity/systems/astronomy.hpp @@ -43,6 +43,7 @@ class astronomy: { public: astronomy(entity::registry& registry); + ~astronomy(); /** * Scales then adds the timestep `dt` to the current time, then recalculates the positions of celestial bodies. @@ -86,6 +87,8 @@ public: void set_camera(scene::camera* camera); void set_exposure_offset(float offset); + void set_starlight_illuminance(double illuminance); + inline float get_exposure_offset() const { return exposure_offset; }; void set_sky_pass(::render::sky_pass* pass); @@ -115,6 +118,7 @@ private: scene::camera* camera; ::render::sky_pass* sky_pass; float exposure_offset; + double starlight_illuminance; }; } // namespace system diff --git a/src/entity/systems/orbit.cpp b/src/entity/systems/orbit.cpp index fb8a8ba..8bfa9d5 100644 --- a/src/entity/systems/orbit.cpp +++ b/src/entity/systems/orbit.cpp @@ -29,7 +29,16 @@ orbit::orbit(entity::registry& registry): ephemeris(nullptr), time(0.0), time_scale(1.0) -{} +{ + registry.on_construct().connect<&orbit::on_orbit_construct>(this); + registry.on_replace().connect<&orbit::on_orbit_replace>(this); +} + +orbit::~orbit() +{ + registry.on_construct().disconnect<&orbit::on_orbit_construct>(this); + registry.on_replace().disconnect<&orbit::on_orbit_replace>(this); +} void orbit::update(double t, double dt) { @@ -40,7 +49,7 @@ void orbit::update(double t, double dt) return; // Calculate positions of ephemeris items, in meters - for (std::size_t i = 0; i < ephemeris->size(); ++i) + for (int i: ephemeris_indices) positions[i] = (*ephemeris)[i].position(time) * 1000.0; // Propagate orbits @@ -75,5 +84,15 @@ void orbit::set_time_scale(double scale) time_scale = scale; } +void orbit::on_orbit_construct(entity::registry& registry, entity::id entity_id, entity::component::orbit& component) +{ + ephemeris_indices.insert(component.ephemeris_index); +} + +void orbit::on_orbit_replace(entity::registry& registry, entity::id entity_id, entity::component::orbit& component) +{ + ephemeris_indices.insert(component.ephemeris_index); +} + } // namespace system } // namespace entity diff --git a/src/entity/systems/orbit.hpp b/src/entity/systems/orbit.hpp index a6069a6..a08f9cb 100644 --- a/src/entity/systems/orbit.hpp +++ b/src/entity/systems/orbit.hpp @@ -25,6 +25,7 @@ #include "entity/id.hpp" #include "entity/components/orbit.hpp" #include "physics/orbit/ephemeris.hpp" +#include namespace entity { namespace system { @@ -37,6 +38,7 @@ class orbit: { public: orbit(entity::registry& registry); + ~orbit(); /** * Scales then adds the timestep `dt` to the current time, then recalculates the positions of orbiting bodies. @@ -68,10 +70,14 @@ public: void set_ephemeris(const physics::orbit::ephemeris* ephemeris); private: + void on_orbit_construct(entity::registry& registry, entity::id entity_id, entity::component::orbit& component); + void on_orbit_replace(entity::registry& registry, entity::id entity_id, entity::component::orbit& component); + const physics::orbit::ephemeris* ephemeris; double time; double time_scale; std::vector positions; + std::unordered_set ephemeris_indices; }; } // namespace system diff --git a/src/game/world.cpp b/src/game/world.cpp index 3fdccde..0bfc9a2 100644 --- a/src/game/world.cpp +++ b/src/game/world.cpp @@ -75,6 +75,7 @@ void create_stars(game::context& ctx) float* star_vertex_data = new float[star_count * star_vertex_size]; float* star_vertex = star_vertex_data; + // Init starlight illuminance double starlight_illuminance = 0.0; // Build star catalog vertex data @@ -100,8 +101,6 @@ void create_stars(game::context& ctx) continue; } - starlight_illuminance += physics::light::vmag::to_illuminance(vmag); - // Convert right ascension and declination from degrees to radians ra = math::wrap_radians(math::radians(ra)); dec = math::wrap_radians(math::radians(dec)); @@ -109,6 +108,9 @@ void create_stars(game::context& ctx) // Convert ICRF coordinates from spherical to Cartesian double3 position = physics::orbit::frame::bci::cartesian(double3{1.0, dec, ra}); + // Convert apparent magnitude to brightness factor relative to a 0th magnitude star + double brightness = physics::light::vmag::to_brightness(vmag); + // Convert color index to color temperature double cct = color::index::bv_to_cct(bv_color); @@ -118,24 +120,22 @@ void create_stars(game::context& ctx) // Transform XYZ color to ACEScg colorspace double3 color_acescg = color::xyz::to_acescg(color_xyz); - // Convert apparent magnitude to brightness factor relative to a 0th magnitude star - double brightness = physics::light::vmag::to_brightness(vmag); - // Scale color by relative brightness - double3 scaled_color = color_acescg * brightness; + color_acescg *= brightness; // Build vertex *(star_vertex++) = static_cast(position.x); *(star_vertex++) = static_cast(position.y); *(star_vertex++) = static_cast(position.z); - *(star_vertex++) = static_cast(scaled_color.x); - *(star_vertex++) = static_cast(scaled_color.y); - *(star_vertex++) = static_cast(scaled_color.z); + *(star_vertex++) = static_cast(color_acescg.x); + *(star_vertex++) = static_cast(color_acescg.y); + *(star_vertex++) = static_cast(color_acescg.z); *(star_vertex++) = static_cast(brightness); + + // Convert apparent magnitude to illuminance and add to total starlight + starlight_illuminance += physics::light::vmag::to_illuminance(vmag); } - std::cout << "TOTAL STARLIGHT: " << starlight_illuminance << std::endl; - // Unload star catalog ctx.resource_manager->unload("stars.csv"); @@ -188,6 +188,9 @@ void create_stars(game::context& ctx) // Pass stars model to sky pass ctx.sky_pass->set_stars_model(stars_model); + + // Pass starlight illuminance to astronomy system + ctx.astronomy_system->set_starlight_illuminance(starlight_illuminance); } void create_sun(game::context& ctx)