From 6f4d7471f254011f35496dda1169ef543d0bf196 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Thu, 3 Jun 2021 15:26:14 +0800 Subject: [PATCH] Separate atmospheric scattering-related functions out of astronomy system and into new atmosphere system --- CMakeLists.txt | 1 + src/ecs/systems/astronomy-system.cpp | 42 +------------- src/ecs/systems/astronomy-system.hpp | 6 -- src/ecs/systems/atmosphere-system.cpp | 80 +++++++++++++++++++++++++++ src/ecs/systems/atmosphere-system.hpp | 53 ++++++++++++++++++ src/game/bootloader.cpp | 5 ++ src/game/game-context.hpp | 2 + src/game/states/play-state.cpp | 2 +- src/physics/atmosphere.hpp | 1 + 9 files changed, 146 insertions(+), 46 deletions(-) create mode 100644 src/ecs/systems/atmosphere-system.cpp create mode 100644 src/ecs/systems/atmosphere-system.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d4aa351..af368e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.7) + option(VERSION_STRING "Project version string" "0.0.0") project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX) diff --git a/src/ecs/systems/astronomy-system.cpp b/src/ecs/systems/astronomy-system.cpp index b728376..fba0e1c 100644 --- a/src/ecs/systems/astronomy-system.cpp +++ b/src/ecs/systems/astronomy-system.cpp @@ -59,14 +59,7 @@ astronomy_system::astronomy_system(ecs::registry& registry): reference_atmosphere(nullptr), sun_light(nullptr), sky_pass(nullptr) -{ - // RGB wavelengths determined by matching wavelengths to XYZ, transforming XYZ to ACEScg, then selecting the max wavelengths for R, G, and B. - rgb_wavelengths_nm = {602.224, 541.069, 448.143}; - rgb_wavelengths_m = rgb_wavelengths_nm * 1e-9; - - registry.on_construct().connect<&astronomy_system::on_atmosphere_construct>(this); - registry.on_replace().connect<&astronomy_system::on_atmosphere_replace>(this); -} +{} void astronomy_system::update(double t, double dt) { @@ -93,8 +86,8 @@ void astronomy_system::update(double t, double dt) inertial_to_topocentric = inertial_to_bcbf * bcbf_to_topocentric; // Set the transform component translations of orbiting bodies to their topocentric positions - registry.view().each( - [&](ecs::entity entity, const auto& orbit, auto& transform) + registry.view().each( + [&](ecs::entity entity, const auto& celestial_body, const auto& orbit, auto& transform) { // Transform Cartesian position vector (r) from inertial space to topocentric space const math::vector3 r_topocentric = inertial_to_topocentric * orbit.state.r; @@ -276,33 +269,4 @@ void astronomy_system::set_sky_pass(::sky_pass* pass) this->sky_pass = pass; } -void astronomy_system::on_atmosphere_construct(ecs::registry& registry, ecs::entity entity, ecs::atmosphere_component& atmosphere) -{ - on_atmosphere_replace(registry, entity, atmosphere); -} - -void astronomy_system::on_atmosphere_replace(ecs::registry& registry, ecs::entity entity, ecs::atmosphere_component& atmosphere) -{ - // Calculate polarization factors - const double rayleigh_polarization = physics::atmosphere::polarization(atmosphere.index_of_refraction, atmosphere.rayleigh_density); - const double mie_polarization = physics::atmosphere::polarization(atmosphere.index_of_refraction, atmosphere.mie_density); - - // Calculate Rayleigh scattering coefficients - atmosphere.rayleigh_scattering = - { - physics::atmosphere::scattering_rayleigh(rgb_wavelengths_m.x, atmosphere.rayleigh_density, rayleigh_polarization), - physics::atmosphere::scattering_rayleigh(rgb_wavelengths_m.y, atmosphere.rayleigh_density, rayleigh_polarization), - physics::atmosphere::scattering_rayleigh(rgb_wavelengths_m.z, atmosphere.rayleigh_density, rayleigh_polarization) - }; - - // Calculate Mie scattering coefficients - const double mie_scattering = physics::atmosphere::scattering_mie(atmosphere.mie_density, mie_polarization); - atmosphere.mie_scattering = - { - mie_scattering, - mie_scattering, - mie_scattering - }; -} - } // namespace ecs diff --git a/src/ecs/systems/astronomy-system.hpp b/src/ecs/systems/astronomy-system.hpp index dc3230a..ea09563 100644 --- a/src/ecs/systems/astronomy-system.hpp +++ b/src/ecs/systems/astronomy-system.hpp @@ -82,15 +82,9 @@ public: void set_sky_pass(sky_pass* pass); private: - void on_atmosphere_construct(ecs::registry& registry, ecs::entity entity, ecs::atmosphere_component& atmosphere); - void on_atmosphere_replace(ecs::registry& registry, ecs::entity entity, ecs::atmosphere_component& atmosphere); - double universal_time; double time_scale; - double3 rgb_wavelengths_nm; - double3 rgb_wavelengths_m; - ecs::entity reference_entity; const ecs::orbit_component* reference_orbit; const ecs::celestial_body_component* reference_body; diff --git a/src/ecs/systems/atmosphere-system.cpp b/src/ecs/systems/atmosphere-system.cpp new file mode 100644 index 0000000..f49888c --- /dev/null +++ b/src/ecs/systems/atmosphere-system.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include "ecs/systems/atmosphere-system.hpp" +#include "physics/atmosphere.hpp" + +namespace ecs { + +atmosphere_system::atmosphere_system(ecs::registry& registry): + entity_system(registry) +{ + // RGB wavelengths determined by matching wavelengths to XYZ, transforming XYZ to ACEScg, then selecting the max wavelengths for R, G, and B. + rgb_wavelengths_nm = {602.224, 541.069, 448.143}; + rgb_wavelengths_m = rgb_wavelengths_nm * 1e-9; + + registry.on_construct().connect<&atmosphere_system::on_atmosphere_construct>(this); + registry.on_replace().connect<&atmosphere_system::on_atmosphere_replace>(this); +} + +void atmosphere_system::update(double t, double dt) +{} + +void atmosphere_system::update_coefficients(ecs::entity entity) +{ + // Abort if entity has no atmosphere component + if (!registry.has(entity)) + return; + + // Get atmosphere component of the entity + atmosphere_component& atmosphere = registry.get(entity); + + // Calculate polarization factors + const double rayleigh_polarization = physics::atmosphere::polarization(atmosphere.index_of_refraction, atmosphere.rayleigh_density); + const double mie_polarization = physics::atmosphere::polarization(atmosphere.index_of_refraction, atmosphere.mie_density); + + // Calculate Rayleigh scattering coefficients + atmosphere.rayleigh_scattering = + { + physics::atmosphere::scattering_rayleigh(rgb_wavelengths_m.x, atmosphere.rayleigh_density, rayleigh_polarization), + physics::atmosphere::scattering_rayleigh(rgb_wavelengths_m.y, atmosphere.rayleigh_density, rayleigh_polarization), + physics::atmosphere::scattering_rayleigh(rgb_wavelengths_m.z, atmosphere.rayleigh_density, rayleigh_polarization) + }; + + // Calculate Mie scattering coefficients + const double mie_scattering = physics::atmosphere::scattering_mie(atmosphere.mie_density, mie_polarization); + atmosphere.mie_scattering = + { + mie_scattering, + mie_scattering, + mie_scattering + }; +} + +void atmosphere_system::on_atmosphere_construct(ecs::registry& registry, ecs::entity entity, ecs::atmosphere_component& atmosphere) +{ + update_coefficients(entity); +} + +void atmosphere_system::on_atmosphere_replace(ecs::registry& registry, ecs::entity entity, ecs::atmosphere_component& atmosphere) +{ + update_coefficients(entity); +} + +} // namespace ecs diff --git a/src/ecs/systems/atmosphere-system.hpp b/src/ecs/systems/atmosphere-system.hpp new file mode 100644 index 0000000..1b6252b --- /dev/null +++ b/src/ecs/systems/atmosphere-system.hpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_ECS_ATMOSPHERE_SYSTEM_HPP +#define ANTKEEPER_ECS_ATMOSPHERE_SYSTEM_HPP + +#include "entity-system.hpp" +#include "ecs/entity.hpp" +#include "utility/fundamental-types.hpp" +#include "ecs/components/atmosphere-component.hpp" + +namespace ecs { + +/** + * Updates variables related to atmospheric scattering. + */ +class atmosphere_system: + public entity_system +{ +public: + atmosphere_system(ecs::registry& registry); + + virtual void update(double t, double dt); + +private: + void update_coefficients(ecs::entity entity); + + void on_atmosphere_construct(ecs::registry& registry, ecs::entity entity, ecs::atmosphere_component& atmosphere); + void on_atmosphere_replace(ecs::registry& registry, ecs::entity entity, ecs::atmosphere_component& atmosphere); + + double3 rgb_wavelengths_nm; + double3 rgb_wavelengths_m; +}; + +} // namespace ecs + +#endif // ANTKEEPER_ECS_ATMOSPHERE_SYSTEM_HPP diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp index 53515eb..256d8c1 100644 --- a/src/game/bootloader.cpp +++ b/src/game/bootloader.cpp @@ -75,6 +75,7 @@ #include "ecs/systems/painting-system.hpp" #include "ecs/systems/astronomy-system.hpp" #include "ecs/systems/blackbody-system.hpp" +#include "ecs/systems/atmosphere-system.hpp" #include "ecs/systems/orbit-system.hpp" #include "ecs/components/marker-component.hpp" #include "ecs/commands.hpp" @@ -864,6 +865,9 @@ void setup_systems(game_context* ctx) // Setup blackbody system ctx->blackbody_system = new ecs::blackbody_system(*ctx->ecs_registry); + // Setup atmosphere system + ctx->atmosphere_system = new ecs::atmosphere_system(*ctx->ecs_registry); + // Setup astronomy system ctx->astronomy_system = new ecs::astronomy_system(*ctx->ecs_registry); @@ -1260,6 +1264,7 @@ void setup_callbacks(game_context* ctx) ctx->orbit_system->update(t, dt); ctx->blackbody_system->update(t, dt); + ctx->atmosphere_system->update(t, dt); ctx->astronomy_system->update(t, dt); ctx->spatial_system->update(t, dt); ctx->constraint_system->update(t, dt); diff --git a/src/game/game-context.hpp b/src/game/game-context.hpp index 6a12136..5395c0d 100644 --- a/src/game/game-context.hpp +++ b/src/game/game-context.hpp @@ -84,6 +84,7 @@ namespace ecs class painting_system; class astronomy_system; class blackbody_system; + class atmosphere_system; class orbit_system; class behavior_system; class collision_system; @@ -249,6 +250,7 @@ struct game_context ecs::tracking_system* tracking_system; ecs::painting_system* painting_system; ecs::blackbody_system* blackbody_system; + ecs::atmosphere_system* atmosphere_system; ecs::astronomy_system* astronomy_system; ecs::orbit_system* orbit_system; diff --git a/src/game/states/play-state.cpp b/src/game/states/play-state.cpp index 55f4329..3a18c30 100644 --- a/src/game/states/play-state.cpp +++ b/src/game/states/play-state.cpp @@ -112,7 +112,7 @@ void play_state_enter(game_context* ctx) orbit.elements.ta = math::radians(0.0); ecs::blackbody_component blackbody; - blackbody.temperature = 5777.0; + blackbody.temperature = 5778.0; ecs::transform_component transform; transform.local = math::identity_transform; diff --git a/src/physics/atmosphere.hpp b/src/physics/atmosphere.hpp index e758c39..c713b81 100644 --- a/src/physics/atmosphere.hpp +++ b/src/physics/atmosphere.hpp @@ -21,6 +21,7 @@ #define ANTKEEPER_PHYSICS_ATMOSPHERE_HPP #include "physics/constants.hpp" +#include "math/constants.hpp" #include namespace physics {