diff --git a/CMakeLists.txt b/CMakeLists.txt
index af368e1..d4aa351 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,5 @@
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/components/blackbody-component.hpp b/src/ecs/components/blackbody-component.hpp
index 68e4370..18cfbbd 100644
--- a/src/ecs/components/blackbody-component.hpp
+++ b/src/ecs/components/blackbody-component.hpp
@@ -28,9 +28,6 @@ struct blackbody_component
/// Effective temperature, in Kelvin.
double temperature;
- /// Blackbody radius, in meters.
- double radius;
-
/// (Dependent) RGB luminous intensity, in candela.
double3 luminous_intensity;
};
diff --git a/src/ecs/components/celestial-body-component.hpp b/src/ecs/components/celestial-body-component.hpp
new file mode 100644
index 0000000..5ae1613
--- /dev/null
+++ b/src/ecs/components/celestial-body-component.hpp
@@ -0,0 +1,43 @@
+/*
+ * 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_CELESTIAL_BODY_COMPONENT_HPP
+#define ANTKEEPER_ECS_CELESTIAL_BODY_COMPONENT_HPP
+
+namespace ecs {
+
+/// A simple celestial body.
+struct celestial_body_component
+{
+ /// Body radius, in meters.
+ double radius;
+
+ /// Angle between the body's rotational axis and its orbital axis, in radians.
+ double axial_tilt;
+
+ /// Angle of rotation about the body's rotational axis at epoch, in radians.
+ double axial_rotation;
+
+ /// Angular frequency, in radians per day.
+ double angular_frequency;
+};
+
+} // namespace ecs
+
+#endif // ANTKEEPER_ECS_CELESTIAL_BODY_COMPONENT_HPP
diff --git a/src/ecs/systems/astronomy-system.cpp b/src/ecs/systems/astronomy-system.cpp
index 7ffbfed..b728376 100644
--- a/src/ecs/systems/astronomy-system.cpp
+++ b/src/ecs/systems/astronomy-system.cpp
@@ -19,20 +19,16 @@
#include "ecs/systems/astronomy-system.hpp"
#include "astro/apparent-size.hpp"
-#include "ecs/components/orbit-component.hpp"
#include "ecs/components/blackbody-component.hpp"
-#include "ecs/components/atmosphere-component.hpp"
#include "ecs/components/transform-component.hpp"
#include "geom/intersection.hpp"
#include "color/color.hpp"
#include "physics/orbit/orbit.hpp"
#include "physics/time/ut1.hpp"
-#include "physics/light/blackbody.hpp"
#include "physics/light/photometry.hpp"
#include "physics/light/luminosity.hpp"
#include "physics/light/refraction.hpp"
#include "physics/atmosphere.hpp"
-#include "math/quadrature.hpp"
#include "geom/cartesian.hpp"
#include
@@ -57,9 +53,10 @@ astronomy_system::astronomy_system(ecs::registry& registry):
entity_system(registry),
universal_time(0.0),
time_scale(1.0),
- reference_body(entt::null),
- reference_body_axial_tilt(0.0),
- reference_body_axial_rotation(0.0),
+ reference_entity(entt::null),
+ reference_orbit(nullptr),
+ reference_body(nullptr),
+ reference_atmosphere(nullptr),
sun_light(nullptr),
sky_pass(nullptr)
{
@@ -67,9 +64,6 @@ astronomy_system::astronomy_system(ecs::registry& registry):
rgb_wavelengths_nm = {602.224, 541.069, 448.143};
rgb_wavelengths_m = rgb_wavelengths_nm * 1e-9;
- registry.on_construct().connect<&astronomy_system::on_blackbody_construct>(this);
- registry.on_replace().connect<&astronomy_system::on_blackbody_replace>(this);
-
registry.on_construct().connect<&astronomy_system::on_atmosphere_construct>(this);
registry.on_replace().connect<&astronomy_system::on_atmosphere_replace>(this);
}
@@ -79,35 +73,28 @@ void astronomy_system::update(double t, double dt)
// Add scaled timestep to current time
set_universal_time(universal_time + dt * time_scale);
- // Abort if reference body has not been set
- if (reference_body == entt::null)
- return;
-
- // Abort if reference body has no orbit component
- if (!registry.has(reference_body))
+ // Abort if either reference body or orbit have not been set
+ if (!reference_orbit || !reference_body)
return;
- // Update axial rotation of reference body
- reference_body_axial_rotation = physics::time::ut1::era(universal_time);
-
- // Get orbit component of reference body
- const auto& reference_orbit = registry.get(reference_body);
+ // Determine axial rotation at current 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
+ // 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_body_axial_rotation
+ reference_orbit->state.r,
+ reference_orbit->elements.i,
+ reference_body->axial_tilt,
+ reference_axial_rotation
);
- /// Construct reference frame which transforms coordinates from inertial space to reference body topocentric space
+ // Construct reference frame which transforms coordinates from inertial space to reference body topocentric space
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, auto& orbit, auto& transform)
+ [&](ecs::entity entity, 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;
@@ -116,14 +103,12 @@ void astronomy_system::update(double t, double dt)
transform.local.translation = math::type_cast(r_topocentric);
});
- const double earth_radius = 6.3781e6;
-
// Update blackbody lighting
- registry.view().each(
- [&](ecs::entity entity, auto& blackbody, auto& orbit)
+ registry.view().each(
+ [&](ecs::entity entity, 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
@@ -141,10 +126,8 @@ void astronomy_system::update(double t, double dt)
double3 atmospheric_transmittance = {1.0, 1.0, 1.0};
// Get atmosphere component of reference body (if any)
- if (this->registry.has(reference_body))
+ if (reference_atmosphere)
{
- const ecs::atmosphere_component& atmosphere = this->registry.get(reference_body);
-
// Altitude of observer in meters
geom::ray sample_ray;
sample_ray.origin = {0, observer_location[0], 0};
@@ -152,7 +135,7 @@ void astronomy_system::update(double t, double dt)
geom::sphere exosphere;
exosphere.center = {0, 0, 0};
- exosphere.radius = earth_radius + atmosphere.exosphere_altitude;
+ exosphere.radius = reference_body->radius + reference_atmosphere->exosphere_altitude;
auto intersection_result = geom::ray_sphere_intersection(sample_ray, exosphere);
@@ -161,11 +144,11 @@ void astronomy_system::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, earth_radius, atmosphere.rayleigh_scale_height, 32);
- double optical_depth_k = physics::atmosphere::optical_depth(sample_start, sample_end, earth_radius, 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, atmosphere.rayleigh_scattering, atmosphere.mie_scattering);
+ atmospheric_transmittance = transmittance(optical_depth_r, optical_depth_k, optical_depth_o, reference_atmosphere->rayleigh_scattering, reference_atmosphere->mie_scattering);
}
}
@@ -192,7 +175,7 @@ void astronomy_system::update(double t, double dt)
this->sky_pass->set_sun_position(math::type_cast(blackbody_position_topocentric));
this->sky_pass->set_sun_color(math::type_cast(blackbody.luminous_intensity * distance_attenuation));
- double blackbody_angular_radius = std::asin((blackbody.radius * 2.0) / (blackbody_distance * 2.0));
+ double blackbody_angular_radius = std::asin((celestial_body.radius * 2.0) / (blackbody_distance * 2.0));
this->sky_pass->set_sun_angular_radius(static_cast(blackbody_angular_radius));
}
}
@@ -212,18 +195,16 @@ void astronomy_system::update(double t, double dt)
);
// Upload observer altitude to sky pass
- float observer_altitude = observer_location[0] - earth_radius;
+ float observer_altitude = observer_location[0] - reference_body->radius;
sky_pass->set_observer_altitude(observer_altitude);
// Upload atmosphere params to sky pass
- if (this->registry.has(reference_body))
+ if (reference_atmosphere)
{
- const ecs::atmosphere_component& atmosphere = this->registry.get(reference_body);
-
- sky_pass->set_scale_heights(atmosphere.rayleigh_scale_height, atmosphere.mie_scale_height);
- sky_pass->set_scattering_coefficients(math::type_cast(atmosphere.rayleigh_scattering), math::type_cast(atmosphere.mie_scattering));
- sky_pass->set_mie_anisotropy(atmosphere.mie_anisotropy);
- sky_pass->set_atmosphere_radii(earth_radius, earth_radius + atmosphere.exosphere_altitude);
+ 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,12 +221,22 @@ void astronomy_system::set_time_scale(double scale)
void astronomy_system::set_reference_body(ecs::entity entity)
{
- reference_body = entity;
-}
-
-void astronomy_system::set_reference_body_axial_tilt(double angle)
-{
- reference_body_axial_tilt = angle;
+ reference_entity = entity;
+ 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);
+ }
}
void astronomy_system::set_observer_location(const double3& location)
@@ -285,40 +276,6 @@ void astronomy_system::set_sky_pass(::sky_pass* pass)
this->sky_pass = pass;
}
-void astronomy_system::on_blackbody_construct(ecs::registry& registry, ecs::entity entity, ecs::blackbody_component& blackbody)
-{
- on_blackbody_replace(registry, entity, blackbody);
-}
-
-void astronomy_system::on_blackbody_replace(ecs::registry& registry, ecs::entity entity, ecs::blackbody_component& blackbody)
-{
- // Calculate the surface area of a spherical blackbody
- const double surface_area = 4.0 * math::pi * blackbody.radius * blackbody.radius;
-
- // Construct a lambda function which calculates the blackbody's RGB luminous intensity of a given wavelength
- auto rgb_luminous_intensity = [blackbody, surface_area](double wavelength_nm) -> double3
- {
- // Convert wavelength from nanometers to meters
- const double wavelength_m = wavelength_nm * 1e-9;
-
- // Calculate the spectral intensity of the wavelength
- const double spectral_intensity = physics::light::blackbody::spectral_intensity(blackbody.temperature, surface_area, wavelength_m);
-
- // Calculate the ACEScg color of the wavelength using CIE color matching functions
- double3 spectral_color = color::xyz::to_acescg(color::xyz::match(wavelength_nm));
-
- // Scale the spectral color by spectral intensity
- return spectral_color * spectral_intensity * 1e-9 * physics::light::max_luminous_efficacy;
- };
-
- // Construct a range of sample wavelengths in the visible spectrum
- std::vector samples(780 - 280);
- std::iota(samples.begin(), samples.end(), 280);
-
- // Integrate the blackbody RGB luminous intensity over wavelengths in the visible spectrum
- blackbody.luminous_intensity = math::quadrature::simpson(rgb_luminous_intensity, samples.begin(), samples.end());
-}
-
void astronomy_system::on_atmosphere_construct(ecs::registry& registry, ecs::entity entity, ecs::atmosphere_component& atmosphere)
{
on_atmosphere_replace(registry, entity, atmosphere);
diff --git a/src/ecs/systems/astronomy-system.hpp b/src/ecs/systems/astronomy-system.hpp
index 20a8fd3..dc3230a 100644
--- a/src/ecs/systems/astronomy-system.hpp
+++ b/src/ecs/systems/astronomy-system.hpp
@@ -26,8 +26,9 @@
#include "utility/fundamental-types.hpp"
#include "physics/frame.hpp"
#include "renderer/passes/sky-pass.hpp"
-#include "ecs/components/blackbody-component.hpp"
#include "ecs/components/atmosphere-component.hpp"
+#include "ecs/components/celestial-body-component.hpp"
+#include "ecs/components/orbit-component.hpp"
namespace ecs {
@@ -63,19 +64,12 @@ public:
void set_time_scale(double scale);
/**
- * Sets the reference body, from which observations are taking place.
+ * Sets the reference body entity, from which observations are taking place.
*
* @param entity Entity of the reference body.
*/
void set_reference_body(ecs::entity entity);
- /**
- * Sets the axial tilt of the reference body.
- *
- * @param angle Angle between the reference body's rotational axis and its orbital axis, in radians.
- */
- void set_reference_body_axial_tilt(double angle);
-
/**
* Sets the location of the observer using spherical coordinates in BCBF space.
*
@@ -88,21 +82,21 @@ public:
void set_sky_pass(sky_pass* pass);
private:
- void on_blackbody_construct(ecs::registry& registry, ecs::entity entity, ecs::blackbody_component& blackbody);
- void on_blackbody_replace(ecs::registry& registry, ecs::entity entity, ecs::blackbody_component& blackbody);
-
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;
- ecs::entity reference_body;
- double reference_body_axial_tilt;
- double reference_body_axial_rotation;
+
+ 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;
+ const ecs::atmosphere_component* reference_atmosphere;
+
double3 observer_location;
- scene::directional_light* sun_light;
- sky_pass* sky_pass;
physics::frame inertial_to_bcbf;
physics::frame bcbf_to_topocentric;
@@ -110,8 +104,8 @@ private:
physics::frame sez_to_ezs;
physics::frame ezs_to_sez;
- double3 rgb_wavelengths_nm;
- double3 rgb_wavelengths_m;
+ scene::directional_light* sun_light;
+ sky_pass* sky_pass;
};
} // namespace ecs
diff --git a/src/ecs/systems/blackbody-system.cpp b/src/ecs/systems/blackbody-system.cpp
new file mode 100644
index 0000000..dfde8ef
--- /dev/null
+++ b/src/ecs/systems/blackbody-system.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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/blackbody-system.hpp"
+#include "color/color.hpp"
+#include "physics/light/blackbody.hpp"
+#include "physics/light/photometry.hpp"
+#include "math/quadrature.hpp"
+
+namespace ecs {
+
+blackbody_system::blackbody_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;
+
+ // Construct a range of sample wavelengths in the visible spectrum
+ visible_wavelengths_nm.resize(780 - 280);
+ std::iota(visible_wavelengths_nm.begin(), visible_wavelengths_nm.end(), 280);
+
+ registry.on_construct().connect<&blackbody_system::on_blackbody_construct>(this);
+ registry.on_replace().connect<&blackbody_system::on_blackbody_replace>(this);
+
+ registry.on_construct().connect<&blackbody_system::on_celestial_body_construct>(this);
+ registry.on_replace().connect<&blackbody_system::on_celestial_body_replace>(this);
+}
+
+void blackbody_system::update(double t, double dt)
+{}
+
+void blackbody_system::update_luminous_intensity(ecs::entity entity)
+{
+ // Abort if entity has no blackbody component
+ if (!registry.has(entity))
+ return;
+
+ // Get blackbody component of the entity
+ blackbody_component& blackbody = registry.get(entity);
+
+ // Clear luminous intensity
+ blackbody.luminous_intensity = {0, 0, 0};
+
+ // Abort if entity has no celestial body component
+ if (!registry.has(entity))
+ return;
+
+ // Get celestial body component of the entity
+ const celestial_body_component& celestial_body = registry.get(entity);
+
+ // Calculate (spherical) surface area of the celestial body
+ const double surface_area = 4.0 * math::pi * celestial_body.radius * celestial_body.radius;
+
+ // Construct a lambda function which calculates the blackbody's RGB luminous intensity of a given wavelength
+ auto rgb_luminous_intensity = [blackbody, surface_area](double wavelength_nm) -> double3
+ {
+ // Convert wavelength from nanometers to meters
+ const double wavelength_m = wavelength_nm * 1e-9;
+
+ // Calculate the spectral intensity of the wavelength
+ const double spectral_intensity = physics::light::blackbody::spectral_intensity(blackbody.temperature, surface_area, wavelength_m);
+
+ // Calculate the ACEScg color of the wavelength using CIE color matching functions
+ double3 spectral_color = color::xyz::to_acescg(color::xyz::match(wavelength_nm));
+
+ // Scale the spectral color by spectral intensity
+ return spectral_color * spectral_intensity * 1e-9 * physics::light::max_luminous_efficacy;
+ };
+
+ // Integrate the blackbody RGB luminous intensity over wavelengths in the visible spectrum
+ blackbody.luminous_intensity = math::quadrature::simpson(rgb_luminous_intensity, visible_wavelengths_nm.begin(), visible_wavelengths_nm.end());
+}
+
+void blackbody_system::on_blackbody_construct(ecs::registry& registry, ecs::entity entity, ecs::blackbody_component& blackbody)
+{
+ update_luminous_intensity(entity);
+}
+
+void blackbody_system::on_blackbody_replace(ecs::registry& registry, ecs::entity entity, ecs::blackbody_component& blackbody)
+{
+ update_luminous_intensity(entity);
+}
+
+void blackbody_system::on_celestial_body_construct(ecs::registry& registry, ecs::entity entity, ecs::celestial_body_component& celestial_body)
+{
+ update_luminous_intensity(entity);
+}
+
+void blackbody_system::on_celestial_body_replace(ecs::registry& registry, ecs::entity entity, ecs::celestial_body_component& celestial_body)
+{
+ update_luminous_intensity(entity);
+}
+
+} // namespace ecs
diff --git a/src/ecs/systems/blackbody-system.hpp b/src/ecs/systems/blackbody-system.hpp
new file mode 100644
index 0000000..4715cdd
--- /dev/null
+++ b/src/ecs/systems/blackbody-system.hpp
@@ -0,0 +1,59 @@
+/*
+ * 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_BLACKBODY_SYSTEM_HPP
+#define ANTKEEPER_ECS_BLACKBODY_SYSTEM_HPP
+
+#include "entity-system.hpp"
+#include "ecs/entity.hpp"
+#include "utility/fundamental-types.hpp"
+#include "ecs/components/blackbody-component.hpp"
+#include "ecs/components/celestial-body-component.hpp"
+#include
+
+namespace ecs {
+
+/**
+ * Calculates the RGB luminous intensity of blackbody radiators.
+ */
+class blackbody_system:
+ public entity_system
+{
+public:
+ blackbody_system(ecs::registry& registry);
+
+ virtual void update(double t, double dt);
+
+private:
+ void update_luminous_intensity(ecs::entity entity);
+
+ void on_blackbody_construct(ecs::registry& registry, ecs::entity entity, ecs::blackbody_component& blackbody);
+ void on_blackbody_replace(ecs::registry& registry, ecs::entity entity, ecs::blackbody_component& blackbody);
+
+ void on_celestial_body_construct(ecs::registry& registry, ecs::entity entity, ecs::celestial_body_component& celestial_body);
+ void on_celestial_body_replace(ecs::registry& registry, ecs::entity entity, ecs::celestial_body_component& celestial_body);
+
+ double3 rgb_wavelengths_nm;
+ double3 rgb_wavelengths_m;
+ std::vector visible_wavelengths_nm;
+};
+
+} // namespace ecs
+
+#endif // ANTKEEPER_ECS_BLACKBODY_SYSTEM_HPP
diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp
index aafc153..53515eb 100644
--- a/src/game/bootloader.cpp
+++ b/src/game/bootloader.cpp
@@ -74,6 +74,7 @@
#include "ecs/systems/tracking-system.hpp"
#include "ecs/systems/painting-system.hpp"
#include "ecs/systems/astronomy-system.hpp"
+#include "ecs/systems/blackbody-system.hpp"
#include "ecs/systems/orbit-system.hpp"
#include "ecs/components/marker-component.hpp"
#include "ecs/commands.hpp"
@@ -860,6 +861,9 @@ void setup_systems(game_context* ctx)
// Setup solar system
ctx->orbit_system = new ecs::orbit_system(*ctx->ecs_registry);
+ // Setup blackbody system
+ ctx->blackbody_system = new ecs::blackbody_system(*ctx->ecs_registry);
+
// Setup astronomy system
ctx->astronomy_system = new ecs::astronomy_system(*ctx->ecs_registry);
@@ -1255,6 +1259,7 @@ void setup_callbacks(game_context* ctx)
ctx->tool_system->update(t, dt);
ctx->orbit_system->update(t, dt);
+ ctx->blackbody_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 b9169ce..6a12136 100644
--- a/src/game/game-context.hpp
+++ b/src/game/game-context.hpp
@@ -83,6 +83,7 @@ namespace ecs
class tracking_system;
class painting_system;
class astronomy_system;
+ class blackbody_system;
class orbit_system;
class behavior_system;
class collision_system;
@@ -247,6 +248,7 @@ struct game_context
ecs::spatial_system* spatial_system;
ecs::tracking_system* tracking_system;
ecs::painting_system* painting_system;
+ ecs::blackbody_system* blackbody_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 cbedfdf..55f4329 100644
--- a/src/game/states/play-state.cpp
+++ b/src/game/states/play-state.cpp
@@ -33,6 +33,7 @@
#include "ecs/components/camera-follow-component.hpp"
#include "ecs/components/orbit-component.hpp"
#include "ecs/components/blackbody-component.hpp"
+#include "ecs/components/celestial-body-component.hpp"
#include "ecs/components/atmosphere-component.hpp"
#include "ecs/components/light-component.hpp"
#include "ecs/commands.hpp"
@@ -96,6 +97,12 @@ void play_state_enter(game_context* ctx)
// Create sun
auto sun_entity = ecs_registry.create();
{
+ ecs::celestial_body_component body;
+ body.radius = 6.957e+8;
+ body.axial_tilt = math::radians(0.0);
+ body.axial_rotation = math::radians(0.0);
+ body.angular_frequency = math::radians(0.0);
+
ecs::orbit_component orbit;
orbit.elements.a = 0.0;
orbit.elements.e = 0.0;
@@ -106,12 +113,12 @@ void play_state_enter(game_context* ctx)
ecs::blackbody_component blackbody;
blackbody.temperature = 5777.0;
- blackbody.radius = 6.957e+8;
ecs::transform_component transform;
transform.local = math::identity_transform;
transform.warp = true;
+ ecs_registry.assign(sun_entity, body);
ecs_registry.assign(sun_entity, orbit);
ecs_registry.assign(sun_entity, blackbody);
ecs_registry.assign(sun_entity, transform);
@@ -120,6 +127,12 @@ void play_state_enter(game_context* ctx)
// Create Earth
auto earth_entity = ecs_registry.create();
{
+ ecs::celestial_body_component body;
+ body.radius = 6.3781e6;
+ body.axial_tilt = math::radians(23.4393);
+ body.axial_rotation = math::radians(280.46061837504);
+ body.angular_frequency = math::radians(360.9856122880876128);
+
ecs::orbit_component orbit;
orbit.elements.a = 1.496e+11;
orbit.elements.e = 0.01671123;
@@ -131,12 +144,10 @@ void play_state_enter(game_context* ctx)
ecs::atmosphere_component atmosphere;
atmosphere.exosphere_altitude = 65e3;
-
atmosphere.index_of_refraction = 1.000293;
atmosphere.rayleigh_density = 2.545e25;
- atmosphere.mie_density = 14.8875;
-
atmosphere.rayleigh_scale_height = 8000.0;
+ atmosphere.mie_density = 14.8875;
atmosphere.mie_scale_height = 1200.0;
atmosphere.mie_anisotropy = 0.8;
@@ -144,6 +155,7 @@ void play_state_enter(game_context* ctx)
transform.local = math::identity_transform;
transform.warp = true;
+ ecs_registry.assign(earth_entity, body);
ecs_registry.assign(earth_entity, orbit);
ecs_registry.assign(earth_entity, atmosphere);
ecs_registry.assign(earth_entity, transform);
@@ -172,7 +184,6 @@ void play_state_enter(game_context* ctx)
// Set astronomy system observation parameters
ctx->astronomy_system->set_reference_body(earth_entity);
- ctx->astronomy_system->set_reference_body_axial_tilt(math::radians(23.4393));
ctx->astronomy_system->set_observer_location(double3{6.3781e6, math::radians(0.0f), math::radians(0.0f)});
ctx->astronomy_system->set_sun_light(sun);
ctx->astronomy_system->set_sky_pass(ctx->overworld_sky_pass);