diff --git a/src/entity/systems/astronomy.cpp b/src/entity/systems/astronomy.cpp index 458055c..f8753bc 100644 --- a/src/entity/systems/astronomy.cpp +++ b/src/entity/systems/astronomy.cpp @@ -55,9 +55,6 @@ astronomy::astronomy(entity::registry& registry): universal_time(0.0), time_scale(1.0), reference_entity(entt::null), - reference_orbit(nullptr), - reference_body(nullptr), - reference_atmosphere(nullptr), observer_location{0, 0, 0}, sun_light(nullptr), sky_pass(nullptr) @@ -85,19 +82,25 @@ void astronomy::update(double t, double dt) // Add scaled timestep to current time set_universal_time(universal_time + dt * time_scale); + // Abort if no reference body + if (reference_entity == entt::null) + return; + // Abort if either reference body or orbit have not been set - if (!reference_orbit || !reference_body) + if (!registry.has(reference_entity) || !registry.has(reference_entity)) return; + const entity::component::orbit& reference_orbit = registry.get(reference_entity); + const entity::component::celestial_body& reference_body = registry.get(reference_entity); // Determine axial rotation at current time - const double reference_axial_rotation = reference_body->axial_rotation + reference_body->angular_frequency * universal_time; + const double reference_axial_rotation = reference_body.axial_rotation + reference_body.angular_frequency * universal_time; // Construct reference frame which transforms coordinates from inertial space to reference body BCBF space inertial_to_bcbf = physics::orbit::inertial::to_bcbf ( - reference_orbit->state.r, - reference_orbit->elements.i, - reference_body->axial_tilt, + reference_orbit.state.r, + reference_orbit.elements.i, + reference_body.axial_tilt, reference_axial_rotation ); @@ -120,7 +123,7 @@ void astronomy::update(double t, double dt) [&](entity::id entity_id, const auto& celestial_body, const auto& orbit, const auto& blackbody) { // Calculate blackbody inertial basis - double3 blackbody_forward_inertial = math::normalize(reference_orbit->state.r - orbit.state.r); + double3 blackbody_forward_inertial = math::normalize(reference_orbit.state.r - orbit.state.r); double3 blackbody_up_inertial = {0, 0, 1}; // Transform blackbody inertial position and basis into topocentric space @@ -138,16 +141,18 @@ void astronomy::update(double t, double dt) double3 atmospheric_transmittance = {1.0, 1.0, 1.0}; // Get atmosphere component of reference body (if any) - if (reference_atmosphere) + if (this->registry.has(reference_entity)) { + const entity::component::atmosphere& reference_atmosphere = registry.get(reference_entity); + // Altitude of observer in meters geom::ray sample_ray; - sample_ray.origin = {0, reference_body->radius + observer_location[0], 0}; + sample_ray.origin = {0, reference_body.radius + observer_location[0], 0}; sample_ray.direction = math::normalize(blackbody_position_topocentric); geom::sphere exosphere; exosphere.center = {0, 0, 0}; - exosphere.radius = reference_body->radius + reference_atmosphere->exosphere_altitude; + exosphere.radius = reference_body.radius + reference_atmosphere.exosphere_altitude; auto intersection_result = geom::ray_sphere_intersection(sample_ray, exosphere); @@ -156,11 +161,11 @@ void astronomy::update(double t, double dt) double3 sample_start = sample_ray.origin; double3 sample_end = sample_ray.extrapolate(std::get<2>(intersection_result)); - double optical_depth_r = physics::atmosphere::optical_depth(sample_start, sample_end, reference_body->radius, reference_atmosphere->rayleigh_scale_height, 32); - double optical_depth_k = physics::atmosphere::optical_depth(sample_start, sample_end, reference_body->radius, reference_atmosphere->mie_scale_height, 32); + double optical_depth_r = physics::atmosphere::optical_depth(sample_start, sample_end, reference_body.radius, reference_atmosphere.rayleigh_scale_height, 32); + double optical_depth_k = physics::atmosphere::optical_depth(sample_start, sample_end, reference_body.radius, reference_atmosphere.mie_scale_height, 32); double optical_depth_o = 0.0; - atmospheric_transmittance = transmittance(optical_depth_r, optical_depth_k, optical_depth_o, reference_atmosphere->rayleigh_scattering, reference_atmosphere->mie_scattering); + atmospheric_transmittance = transmittance(optical_depth_r, optical_depth_k, optical_depth_o, reference_atmosphere.rayleigh_scattering, reference_atmosphere.mie_scattering); } } @@ -217,12 +222,14 @@ void astronomy::update(double t, double dt) sky_pass->set_observer_altitude(observer_location[0]); // Upload atmosphere params to sky pass - if (reference_atmosphere) + if (registry.has(reference_entity)) { - sky_pass->set_scale_heights(reference_atmosphere->rayleigh_scale_height, reference_atmosphere->mie_scale_height); - sky_pass->set_scattering_coefficients(math::type_cast(reference_atmosphere->rayleigh_scattering), math::type_cast(reference_atmosphere->mie_scattering)); - sky_pass->set_mie_anisotropy(reference_atmosphere->mie_anisotropy); - sky_pass->set_atmosphere_radii(reference_body->radius, reference_body->radius + reference_atmosphere->exosphere_altitude); + const entity::component::atmosphere& reference_atmosphere = registry.get(reference_entity); + + sky_pass->set_scale_heights(reference_atmosphere.rayleigh_scale_height, reference_atmosphere.mie_scale_height); + sky_pass->set_scattering_coefficients(math::type_cast(reference_atmosphere.rayleigh_scattering), math::type_cast(reference_atmosphere.mie_scattering)); + sky_pass->set_mie_anisotropy(reference_atmosphere.mie_anisotropy); + sky_pass->set_atmosphere_radii(reference_body.radius, reference_body.radius + reference_atmosphere.exosphere_altitude); } } } @@ -240,22 +247,6 @@ void astronomy::set_time_scale(double scale) void astronomy::set_reference_body(entity::id entity_id) { reference_entity = entity_id; - reference_orbit = nullptr; - reference_body = nullptr; - reference_atmosphere = nullptr; - - if (reference_entity != entt::null) - { - if (registry.has(reference_entity)) - reference_orbit = ®istry.get(reference_entity); - - if (registry.has(reference_entity)) - reference_body = ®istry.get(reference_entity); - - if (registry.has(reference_entity)) - reference_atmosphere = ®istry.get(reference_entity); - } - update_bcbf_to_topocentric(); } @@ -291,9 +282,10 @@ void astronomy::update_bcbf_to_topocentric() { double radial_distance = observer_location[0]; - if (reference_body) + if (reference_entity) { - radial_distance += reference_body->radius; + if (registry.has(reference_entity)) + radial_distance += registry.get(reference_entity).radius; } // Construct reference frame which transforms coordinates from BCBF space to topocentric space diff --git a/src/entity/systems/astronomy.hpp b/src/entity/systems/astronomy.hpp index 60d37b1..a032795 100644 --- a/src/entity/systems/astronomy.hpp +++ b/src/entity/systems/astronomy.hpp @@ -92,9 +92,6 @@ private: double time_scale; entity::id reference_entity; - const entity::component::orbit* reference_orbit; - const entity::component::celestial_body* reference_body; - const entity::component::atmosphere* reference_atmosphere; double3 observer_location; diff --git a/src/game/states/forage.cpp b/src/game/states/forage.cpp index caa37a5..e446f00 100644 --- a/src/game/states/forage.cpp +++ b/src/game/states/forage.cpp @@ -76,7 +76,7 @@ void enter(game::context* ctx) ctx->entity_registry->assign(observer_eid, observer); // Set reference location of astronomy system - ctx->astronomy_system->set_reference_body(planet_eid); + //ctx->astronomy_system->set_reference_body(planet_eid); ctx->astronomy_system->set_observer_location(double3{observer.elevation, observer.latitude, observer.longitude}); } @@ -250,8 +250,9 @@ void setup_tools(game::context* ctx) auto [window_w, window_h] = ctx->app->get_viewport_dimensions(); entity::id planet_eid = ctx->entities["planet"]; - entity::component::celestial_body& body = ctx->entity_registry->get(planet_eid); - body.axial_tilt = math::radians(360.0f) * ((float)mouse_x / (float)window_w); + entity::component::celestial_body body = ctx->entity_registry->get(planet_eid); + body.axial_rotation = math::radians(360.0f) * ((float)mouse_x / (float)window_w); + ctx->entity_registry->replace(planet_eid, body); }; ctx->entity_registry->assign(tool_eid, tool); diff --git a/src/game/states/loading.cpp b/src/game/states/loading.cpp index c0489f5..84ca63b 100644 --- a/src/game/states/loading.cpp +++ b/src/game/states/loading.cpp @@ -126,7 +126,7 @@ void exit(game::context* ctx) {} void load_controls(game::context* ctx) -{ +{ // If a control profile is set in the config file if (ctx->config->contains("control_profile")) { diff --git a/src/resources/entity-archetype-loader.cpp b/src/resources/entity-archetype-loader.cpp index 06bbceb..d95ebaa 100644 --- a/src/resources/entity-archetype-loader.cpp +++ b/src/resources/entity-archetype-loader.cpp @@ -104,11 +104,11 @@ static bool load_component_celestial_body(entity::archetype& archetype, const js if (element.contains("radius")) component.radius = element["radius"].get(); if (element.contains("axial_tilt")) - component.axial_tilt = element["axial_tilt"].get(); + component.axial_tilt = math::radians(element["axial_tilt"].get()); if (element.contains("axial_rotation")) - component.axial_rotation = element["axial_rotation"].get(); + component.axial_rotation = math::radians(element["axial_rotation"].get()); if (element.contains("angular_frequency")) - component.angular_frequency = element["angular_frequency"].get(); + component.angular_frequency = math::radians(element["angular_frequency"].get()); archetype.set(component); @@ -162,13 +162,13 @@ static bool load_component_orbit(entity::archetype& archetype, const json& eleme if (element.contains("a")) component.elements.a = element["a"].get(); if (element.contains("i")) - component.elements.i = element["i"].get(); + component.elements.i = math::radians(element["i"].get()); if (element.contains("raan")) - component.elements.raan = element["raan"].get(); + component.elements.raan = math::radians(element["raan"].get()); if (element.contains("w")) - component.elements.w = element["w"].get(); + component.elements.w = math::radians(element["w"].get()); if (element.contains("ta")) - component.elements.ta = element["ta"].get(); + component.elements.ta = math::radians(element["ta"].get()); archetype.set(component); @@ -205,7 +205,8 @@ static bool load_component_transform(entity::archetype& archetype, const json& e component.local.scale.y = translation[1].get(); component.local.scale.z = translation[2].get(); } - + + component.world = component.local; archetype.set(component); return true;