Browse Source

Apply temporary fix to astronomy system and sun position calculation

master
C. J. Howard 3 years ago
parent
commit
3023e75cf5
14 changed files with 270 additions and 51 deletions
  1. +60
    -1
      src/ecs/systems/astronomy-system.cpp
  2. +9
    -0
      src/ecs/systems/astronomy-system.hpp
  3. +10
    -6
      src/game/bootloader.cpp
  4. +61
    -27
      src/game/states/play-state.cpp
  5. +31
    -6
      src/renderer/passes/material-pass.cpp
  6. +4
    -2
      src/renderer/passes/material-pass.hpp
  7. +2
    -2
      src/renderer/passes/sky-pass.cpp
  8. +1
    -1
      src/renderer/passes/sky-pass.hpp
  9. +19
    -1
      src/scene/directional-light.cpp
  10. +34
    -2
      src/scene/directional-light.hpp
  11. +0
    -1
      src/scene/light.cpp
  12. +32
    -2
      src/scene/light.hpp
  13. +3
    -0
      src/scene/point-light.hpp
  14. +4
    -0
      src/scene/spotlight.hpp

+ 60
- 1
src/ecs/systems/astronomy-system.cpp View File

@ -22,6 +22,9 @@
#include "astro/apparent-size.hpp"
#include "ecs/components/celestial-body-component.hpp"
#include "ecs/components/transform-component.hpp"
#include "renderer/passes/sky-pass.hpp"
#include "astro/blackbody.hpp"
#include <iostream>
namespace ecs {
@ -36,7 +39,9 @@ astronomy_system::astronomy_system(ecs::registry& registry):
obliquity(0.0),
axial_rotation(0.0),
axial_rotation_at_epoch(0.0),
axial_rotation_speed(0.0)
axial_rotation_speed(0.0),
sky_pass(nullptr),
sun_light(nullptr)
{}
void astronomy_system::update(double t, double dt)
@ -69,7 +74,51 @@ void astronomy_system::update(double t, double dt)
transform.local.translation = math::type_cast<float>(translation);
transform.local.rotation = math::type_cast<float>(math::quaternion_cast(rotation));
transform.local.scale = math::type_cast<float>(double3{body.radius, body.radius, body.radius});
if (sun_light != nullptr)
{
math::quaternion<float> sun_azimuth_rotation = math::angle_axis(static_cast<float>(spherical.z), float3{0, 1, 0});
math::quaternion<float> sun_elevation_rotation = math::angle_axis(static_cast<float>(spherical.y), float3{-1, 0, 0});
math::quaternion<float> sun_az_el_rotation = math::normalize(sun_azimuth_rotation * sun_elevation_rotation);
sun_az_el_rotation = math::angle_axis((float)universal_time * math::two_pi<float>, float3{1, 0, 0});
//
//sun_light->look_at({0, 0, 0}, {0, -1, 0}, {0, 0, 1});
// Set sun color
float factor = std::cos(spherical.y);
float correlated_temperature = math::lerp(8000.0f, 2000.0f, factor);
float3 correlated_color = math::type_cast<float>(astro::blackbody(correlated_temperature));
float intensity = math::lerp(1000.0f, 100.0f, factor);
sun_light->set_color(correlated_color);
sun_light->set_intensity(intensity);
sun_light->set_translation({0, 500, 0});
//sun_light->set_rotation(math::look_rotation(math::normalize(transform.local.translation), {0, 1, 0}));
sun_light->set_rotation(sun_az_el_rotation);
//sun_light->set_rotation(sun_elevation_rotation);
if (this->sky_pass)
{
this->sky_pass->set_sun_coordinates(sun_az_el_rotation * float3{0, 0, -1}, {static_cast<float>(spherical.z), static_cast<float>(spherical.y)});
}
}
});
if (sky_pass)
{
// Calculate local time
double time_correction = observer_location[2] / (math::two_pi<double> / 24.0);
double local_jd = universal_time + time_correction / 24.0 - 0.5;
double local_time = (local_jd - std::floor(local_jd)) * 24.0;
sky_pass->set_time_of_day(local_time);
}
}
void astronomy_system::set_universal_time(double time)
@ -107,6 +156,16 @@ void astronomy_system::set_axial_rotation_at_epoch(double angle)
update_axial_rotation();
}
void astronomy_system::set_sky_pass(::sky_pass* pass)
{
sky_pass = pass;
}
void astronomy_system::set_sun_light(scene::directional_light* light)
{
sun_light = light;
}
void astronomy_system::update_axial_rotation()
{
axial_rotation = math::wrap_radians<double>(axial_rotation_at_epoch + universal_time * axial_rotation_speed);

+ 9
- 0
src/ecs/systems/astronomy-system.hpp View File

@ -22,8 +22,11 @@
#include "entity-system.hpp"
#include "ecs/entity.hpp"
#include "scene/directional-light.hpp"
#include "utility/fundamental-types.hpp"
class sky_pass;
namespace ecs {
/**
@ -85,6 +88,10 @@ public:
*/
void set_axial_rotation_at_epoch(double angle);
void set_sky_pass(sky_pass* pass);
void set_sun_light(scene::directional_light* light);
private:
/// Updates the axial rotation angle
void update_axial_rotation();
@ -104,6 +111,8 @@ private:
double3 observer_location;
double obliquity;
double3x3 ecliptic_to_horizontal;
sky_pass* sky_pass;
scene::directional_light* sun_light;
};
} // namespace ecs

+ 10
- 6
src/game/bootloader.cpp View File

@ -865,6 +865,10 @@ void setup_systems(game_context* ctx)
// Setup astronomy system
ctx->astronomy_system = new ecs::astronomy_system(*ctx->ecs_registry);
ctx->astronomy_system->set_obliquity(math::radians<double>(23.4365472133));
ctx->astronomy_system->set_axial_rotation_speed(math::radians<double>(360.9856));
ctx->astronomy_system->set_axial_rotation_at_epoch(0.0);
ctx->astronomy_system->set_sky_pass(ctx->overworld_sky_pass);
// Set time scale
float time_scale = 60.0f;
@ -1170,9 +1174,9 @@ void setup_controls(game_context* ctx)
(
[ctx, time_scale]()
{
ctx->weather_system->set_time_scale(time_scale * 500.0f);
ctx->solar_system->set_time_scale(time_scale * 500.0f);
ctx->astronomy_system->set_time_scale(time_scale * 500.0f);
ctx->weather_system->set_time_scale(time_scale * 100.0f);
ctx->solar_system->set_time_scale(time_scale * 100.0f);
ctx->astronomy_system->set_time_scale(time_scale * 100.0f);
}
);
ctx->control_system->get_fast_forward_control()->set_deactivated_callback
@ -1188,9 +1192,9 @@ void setup_controls(game_context* ctx)
(
[ctx, time_scale]()
{
ctx->weather_system->set_time_scale(time_scale * -500.0f);
ctx->solar_system->set_time_scale(time_scale * -500.0f);
ctx->astronomy_system->set_time_scale(time_scale * -500.0f);
ctx->weather_system->set_time_scale(time_scale * -100.0f);
ctx->solar_system->set_time_scale(time_scale * -100.0f);
ctx->astronomy_system->set_time_scale(time_scale * -100.0f);
}
);
ctx->control_system->get_rewind_control()->set_deactivated_callback

+ 61
- 27
src/game/states/play-state.cpp View File

@ -27,7 +27,6 @@
#include "ecs/components/copy-translation-component.hpp"
#include "ecs/components/model-component.hpp"
#include "ecs/components/snap-component.hpp"
#include "ecs/components/samara-component.hpp"
#include "ecs/components/terrain-component.hpp"
#include "ecs/components/tool-component.hpp"
#include "ecs/components/transform-component.hpp"
@ -63,6 +62,7 @@
#include "game/biome.hpp"
#include "utility/fundamental-types.hpp"
#include "utility/gamma.hpp"
#include "astro/blackbody.hpp"
#include "utility/bit-math.hpp"
#include "genetics/genetics.hpp"
@ -76,14 +76,17 @@ void play_state_enter(game_context* ctx)
debug::logger* logger = ctx->logger;
logger->push_task("Entering play state");
resource_manager* resource_manager = ctx->resource_manager;
entt::registry& ecs_registry = *ctx->ecs_registry;
// Load biome
if (ctx->option_biome.has_value())
{
ctx->biome = ctx->resource_manager->load<biome>(ctx->option_biome.value() + ".bio");
ctx->biome = resource_manager->load<biome>(ctx->option_biome.value() + ".bio");
}
else
{
ctx->biome = ctx->resource_manager->load<biome>("forest.bio");
ctx->biome = resource_manager->load<biome>("forest.bio");
}
// Apply biome parameters to scene
@ -92,13 +95,16 @@ void play_state_enter(game_context* ctx)
sky_pass->set_sky_model(ctx->resource_manager->load<model>("sky-dome.mdl"));
sky_pass->set_moon_model(ctx->resource_manager->load<model>("moon.mdl"));
sky_pass->set_horizon_color({1.0f, 1.0f, 1.0f});
sky_pass->set_horizon_color({0.1f, 0.1f, 0.1f});
sky_pass->set_zenith_color({0.0f, 0.0f, 0.0f});
sky_pass->set_time_of_day(0.0f);
sky_pass->set_julian_day(0.0f);
sky_pass->set_observer_location(0.0f, 0.0f, 0.0f);
sky_pass->set_observer_location(4.26352e-5, ctx->biome->location[0], ctx->biome->location[1]);
sky_pass->set_moon_angular_radius(math::radians(1.0f));
sky_pass->set_sun_angular_radius(math::radians(1.0f));
sky_pass->set_sun_coordinates({0, 1, 0}, {0, 3.1415f / 2.0f});
sky_pass->set_moon_coordinates({1, 0, 0}, {0, 0});
sky_pass->set_moon_rotation(math::identity_quaternion<float>);
@ -108,10 +114,43 @@ void play_state_enter(game_context* ctx)
ambient->update_tweens();
ctx->overworld_scene->add_object(ambient);
// Create sun
{
ecs::celestial_body_component sun_body;
sun_body.orbital_elements.a = 1.0;
sun_body.orbital_elements.ec = 0.016709;
sun_body.orbital_elements.w = math::radians(282.9404);
sun_body.orbital_elements.ma = math::radians(356.0470);
sun_body.orbital_elements.i = 0.0;
sun_body.orbital_elements.om = 0.0;
sun_body.orbital_rate.a = 0.0;
sun_body.orbital_rate.ec = -1.151e-9;
sun_body.orbital_rate.w = math::radians(4.70935e-5);
sun_body.orbital_rate.ma = math::radians(0.9856002585);
sun_body.orbital_rate.i = 0.0;
sun_body.orbital_rate.om = 0.0;
ecs::transform_component sun_transform;
sun_transform.local = math::identity_transform<float>;
sun_transform.warp = true;
auto sun_entity = ecs_registry.create();
ecs_registry.assign<ecs::transform_component>(sun_entity, sun_transform);
ecs_registry.assign<ecs::celestial_body_component>(sun_entity, sun_body);
//ctx->astronomy_system->set_sun(sun_entity);
}
scene::directional_light* sun = new scene::directional_light();
sun->set_color({1, 1, 1});
float3 sun_color = math::type_cast<float>(astro::blackbody(6000.0)); // NOTE: this is linear sRGB, should be ACEScg
sun->set_color(sun_color);
sun->set_intensity(750.0f);
sun->look_at({0, 1, 1}, {0, 0, 0}, {0, 1, 0});
sun->set_light_texture(resource_manager->load<gl::texture_2d>("forest-gobo.tex"));
sun->look_at({2, 1, 0}, {0, 0, 0}, {0, 0, 1});
sun->update_tweens();
ctx->overworld_scene->add_object(sun);
ctx->overworld_shadow_map_pass->set_light(sun);
@ -126,15 +165,15 @@ void play_state_enter(game_context* ctx)
ctx->astronomy_system->set_obliquity(math::radians(23.4393));
ctx->astronomy_system->set_axial_rotation_at_epoch(math::radians(280.4606));
ctx->astronomy_system->set_axial_rotation_speed(math::radians(360.9856));
ctx->astronomy_system->set_sun_light(sun);
resource_manager* resource_manager = ctx->resource_manager;
entt::registry& ecs_registry = *ctx->ecs_registry;
// Load entity archetypes
ecs::archetype* ant_hill_archetype = resource_manager->load<ecs::archetype>("ant-hill.ent");
ecs::archetype* nest_archetype = resource_manager->load<ecs::archetype>("harvester-nest.ent");
ecs::archetype* samara_archetype = resource_manager->load<ecs::archetype>("samara.ent");
ecs::archetype* redwood_archetype = resource_manager->load<ecs::archetype>("redwood.ent");
ecs::archetype* forceps_archetype = resource_manager->load<ecs::archetype>("forceps.ent");
ecs::archetype* lens_archetype = resource_manager->load<ecs::archetype>("lens.ent");
ecs::archetype* brush_archetype = resource_manager->load<ecs::archetype>("brush.ent");
@ -145,6 +184,7 @@ void play_state_enter(game_context* ctx)
ecs::archetype* flashlight_archetype = resource_manager->load<ecs::archetype>("flashlight.ent");
ecs::archetype* flashlight_light_cone_archetype = resource_manager->load<ecs::archetype>("flashlight-light-cone.ent");
ecs::archetype* lens_light_cone_archetype = resource_manager->load<ecs::archetype>("lens-light-cone.ent");
ecs::archetype* cube_archetype = resource_manager->load<ecs::archetype>("unit-cube.ent");
// Create tools
forceps_archetype->assign(ecs_registry, ctx->forceps_entity);
@ -190,7 +230,7 @@ void play_state_enter(game_context* ctx)
// Creat nest
auto nest_entity = nest_archetype->create(ecs_registry);
// Create terrain
int terrain_radius = 6;
for (int x = -terrain_radius; x <= terrain_radius; ++x)
@ -206,26 +246,20 @@ void play_state_enter(game_context* ctx)
}
}
// Create samaras
for (int i = 0; i < 15; ++i)
// Create trees
for (int i = 0; i < 30; ++i)
{
auto samara_entity = samara_archetype->create(ecs_registry);
auto& transform = ecs_registry.get<ecs::transform_component>(samara_entity);
float zone = 200.0f;
transform.local = math::identity_transform<float>;
transform.local.translation.x = math::random(-zone, zone);
transform.local.translation.y = math::random(50.0f, 150.0f);
transform.local.translation.z = math::random(-zone, zone);
auto redwood = redwood_archetype->create(ecs_registry);
ecs::samara_component samara_component;
samara_component.angle = math::random(0.0f, math::radians(360.0f));
samara_component.direction = math::normalize(float3{math::random(-1.0f, 1.0f), math::random(-1.0f, -5.0f), math::random(-1.0f, 1.0f)});
samara_component.chirality = (math::random(0.0f, 1.0f) < 0.5f) ? -1.0f : 1.0f;
ecs_registry.assign_or_replace<ecs::samara_component>(samara_entity, samara_component);
auto& transform = ecs_registry.get<ecs::transform_component>(redwood);
float zone = 500.0f;
ecs::command::place(ecs_registry, redwood, {math::random(-zone, zone), math::random(-zone, zone)});
}
// Create unit cube
auto cube = cube_archetype->create(ecs_registry);
ecs::command::place(ecs_registry, cube, {10, 10});
// Setup camera focal point
ecs::transform_component focal_point_transform;
focal_point_transform.local = math::identity_transform<float>;

+ 31
- 6
src/renderer/passes/material-pass.cpp View File

@ -62,8 +62,6 @@ material_pass::material_pass(gl::rasterizer* rasterizer, const gl::framebuffer*
shadow_map(nullptr),
shadow_strength(1.0f)
{
soft_shadows_texture = resource_manager->load<gl::texture_2d>("forest-gobo.tex");
max_ambient_light_count = MATERIAL_PASS_MAX_AMBIENT_LIGHT_COUNT;
max_point_light_count = MATERIAL_PASS_MAX_POINT_LIGHT_COUNT;
max_directional_light_count = MATERIAL_PASS_MAX_DIRECTIONAL_LIGHT_COUNT;
@ -75,6 +73,8 @@ material_pass::material_pass(gl::rasterizer* rasterizer, const gl::framebuffer*
point_light_attenuations = new float3[max_point_light_count];
directional_light_colors = new float3[max_directional_light_count];
directional_light_directions = new float3[max_directional_light_count];
directional_light_matrices = new float4x4[max_directional_light_count];
directional_light_textures = new const gl::texture_2d*[max_directional_light_count];
spotlight_colors = new float3[max_spotlight_count];
spotlight_positions = new float3[max_spotlight_count];
spotlight_directions = new float3[max_spotlight_count];
@ -90,6 +90,8 @@ material_pass::~material_pass()
delete[] point_light_attenuations;
delete[] directional_light_colors;
delete[] directional_light_directions;
delete[] directional_light_matrices;
delete[] directional_light_textures;
delete[] spotlight_colors;
delete[] spotlight_positions;
delete[] spotlight_directions;
@ -189,6 +191,8 @@ void material_pass::render(render_context* context) const
{
if (directional_light_count < max_directional_light_count)
{
const scene::directional_light* directional_light = static_cast<const scene::directional_light*>(light);
directional_light_colors[directional_light_count] = light->get_scaled_color_tween().interpolate(context->alpha);
// Transform direction into view-space
@ -196,6 +200,24 @@ void material_pass::render(render_context* context) const
float3 view_space_direction = math::normalize(math::resize<3>(view * math::resize<4>(-direction)));
directional_light_directions[directional_light_count] = view_space_direction;
// Calculate a view-projection matrix from the directional light's transform
math::transform<float> light_transform = light->get_transform_tween().interpolate(context->alpha);
float3 forward = light_transform.rotation * global_forward;
float3 up = light_transform.rotation * global_up;
float4x4 light_view = math::look_at(light_transform.translation, light_transform.translation + forward, up);
float4x4 light_projection = math::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
float4x4 bias = math::translate(math::identity4x4<float>, {0.5f, 0.5f, 0.5f}) * math::scale(math::identity4x4<float>, {0.5f, 0.5f, 0.5f});
//float scale_u = 1.0f;
//float scale_v = 1.0f;
//float4x4 light_projection = math::ortho(-scale_u, scale_u, -scale_v, scale_v, -1.0f, 1.0f);
directional_light_matrices[directional_light_count] = bias * light_projection * light_view;
directional_light_textures[directional_light_count] = directional_light->get_light_texture();
++directional_light_count;
}
break;
@ -245,7 +267,7 @@ void material_pass::render(render_context* context) const
for (int i = 0; i < 4; ++i)
shadow_map_split_distances[i] = shadow_map_pass->get_split_distances()[i + 1];
}
// Sort render operations
context->operations.sort(operation_compare);
@ -443,6 +465,10 @@ void material_pass::render(render_context* context) const
parameters->directional_light_colors->upload(0, directional_light_colors, directional_light_count);
if (parameters->directional_light_directions)
parameters->directional_light_directions->upload(0, directional_light_directions, directional_light_count);
if (parameters->directional_light_matrices)
parameters->directional_light_matrices->upload(0, directional_light_matrices, directional_light_count);
if (parameters->directional_light_textures)
parameters->directional_light_textures->upload(0, directional_light_textures, directional_light_count);
if (parameters->spotlight_count)
parameters->spotlight_count->upload(spotlight_count);
if (parameters->spotlight_colors)
@ -455,8 +481,6 @@ void material_pass::render(render_context* context) const
parameters->spotlight_attenuations->upload(0, spotlight_attenuations, spotlight_count);
if (parameters->spotlight_cutoffs)
parameters->spotlight_cutoffs->upload(0, spotlight_cutoffs, spotlight_count);
if (parameters->soft_shadows)
parameters->soft_shadows->upload(soft_shadows_texture);
if (parameters->focal_point)
parameters->focal_point->upload(focal_point);
if (parameters->shadow_map_matrices)
@ -548,13 +572,14 @@ const material_pass::parameter_set* material_pass::load_parameter_set(const gl::
parameters->directional_light_count = program->get_input("directional_light_count");
parameters->directional_light_colors = program->get_input("directional_light_colors");
parameters->directional_light_directions = program->get_input("directional_light_directions");
parameters->directional_light_matrices = program->get_input("directional_light_matrices");
parameters->directional_light_textures = program->get_input("directional_light_textures");
parameters->spotlight_count = program->get_input("spotlight_count");
parameters->spotlight_colors = program->get_input("spotlight_colors");
parameters->spotlight_positions = program->get_input("spotlight_positions");
parameters->spotlight_directions = program->get_input("spotlight_directions");
parameters->spotlight_attenuations = program->get_input("spotlight_attenuations");
parameters->spotlight_cutoffs = program->get_input("spotlight_cutoffs");
parameters->soft_shadows = program->get_input("soft_shadows");
parameters->focal_point = program->get_input("focal_point");
parameters->shadow_map_matrices = program->get_input("shadow_map_matrices");
parameters->shadow_map_split_distances = program->get_input("shadow_map_split_distances");

+ 4
- 2
src/renderer/passes/material-pass.hpp View File

@ -89,6 +89,8 @@ private:
const gl::shader_input* directional_light_count;
const gl::shader_input* directional_light_colors;
const gl::shader_input* directional_light_directions;
const gl::shader_input* directional_light_matrices;
const gl::shader_input* directional_light_textures;
const gl::shader_input* spotlight_count;
const gl::shader_input* spotlight_colors;
const gl::shader_input* spotlight_positions;
@ -96,7 +98,6 @@ private:
const gl::shader_input* spotlight_attenuations;
const gl::shader_input* spotlight_cutoffs;
const gl::shader_input* soft_shadows;
const gl::shader_input* focal_point;
const gl::shader_input* shadow_map_matrices;
@ -112,7 +113,6 @@ private:
const tween<double>* time_tween;
float2 mouse_position;
const tween<float3>* focal_point_tween;
gl::texture_2d* soft_shadows_texture;
float shadow_strength;
int max_ambient_light_count;
@ -131,6 +131,8 @@ private:
float3* point_light_attenuations;
float3* directional_light_colors;
float3* directional_light_directions;
float4x4* directional_light_matrices;
const gl::texture_2d** directional_light_textures;
float3* spotlight_colors;
float3* spotlight_positions;
float3* spotlight_directions;

+ 2
- 2
src/renderer/passes/sky-pass.cpp View File

@ -285,9 +285,9 @@ void sky_pass::set_julian_day(float jd)
julian_day_tween[1] = jd;
}
void sky_pass::set_observer_location(float latitude, float longitude, float altitude)
void sky_pass::set_observer_location(float altitude, float latitude, float longitude)
{
observer_location = {latitude, longitude, altitude};
observer_location = {altitude, latitude, longitude};
}
void sky_pass::set_sun_coordinates(const float3& position, const float2& az_el)

+ 1
- 1
src/renderer/passes/sky-pass.hpp View File

@ -59,7 +59,7 @@ public:
void set_moon_model(const model* model);
void set_julian_day(float jd);
void set_observer_location(float latitude, float longitude, float altitude);
void set_observer_location(float altitude, float latitude, float longitude);
void set_sun_coordinates(const float3& position, const float2& az_el);
void set_moon_coordinates(const float3& position, const float2& az_el);
void set_moon_rotation(const math::quaternion<float>& rotation);

+ 19
- 1
src/scene/directional-light.cpp View File

@ -31,13 +31,31 @@ static float3 interpolate_direction(const float3& x, const float3& y, float a)
}
directional_light::directional_light():
direction(global_forward, interpolate_direction)
direction(global_forward, interpolate_direction),
light_texture(nullptr),
light_texture_opacity(1.0f, math::lerp<float, float>),
light_texture_translation({0.0f, 0.0f}, math::lerp<float2, float>),
light_texture_rotation(0.0f, math::lerp_angle<float>),
light_texture_scale({1.0f, 1.0f}, math::lerp<float2, float>)
{}
void directional_light::set_light_texture(const gl::texture_2d* texture)
{
light_texture = texture;
}
void directional_light::update_tweens()
{
light::update_tweens();
direction.update();
if (light_texture)
{
light_texture_opacity.update();
light_texture_translation.update();
light_texture_rotation.update();
light_texture_scale.update();
}
}
void directional_light::transformed()

+ 34
- 2
src/scene/directional-light.hpp View File

@ -21,22 +21,44 @@
#define ANTKEEPER_SCENE_DIRECTIONAL_LIGHT_HPP
#include "scene/light.hpp"
#include "gl/texture-2d.hpp"
#include "utility/fundamental-types.hpp"
namespace scene {
/**
* Light source with parallel rays and constant intensity.
*/
class directional_light: public light
{
public:
/// Creates a directional light.
directional_light();
/// Returns light_type::directional
/**
* Sets the light texture, also known as a gobo, cucoloris, or cookie.
*
* @param texture Light texture.
*/
void set_light_texture(const gl::texture_2d* texture);
void set_light_texture_opacity(float opacity);
void set_light_texture_translation(const float2& translation);
void set_light_texture_rotation(float rotation);
void set_light_texture_scale(const float2& scale);
/// Returns light_type::directional.
virtual light_type get_light_type() const;
/// Returns the normalized direction vector of the light.
const float3& get_direction() const;
/// Returns the light texture for this light, or `nullptr` if no light texture is set.
const gl::texture_2d* get_light_texture() const;
const tween<float3>& get_direction_tween() const;
/// @copydoc object_base::update_tweens();
virtual void update_tweens();
@ -44,6 +66,11 @@ private:
virtual void transformed();
tween<float3> direction;
const gl::texture_2d* light_texture;
tween<float> light_texture_opacity;
tween<float2> light_texture_translation;
tween<float> light_texture_rotation;
tween<float2> light_texture_scale;
};
inline light_type directional_light::get_light_type() const
@ -61,6 +88,11 @@ inline const tween& directional_light::get_direction_tween() const
return direction;
}
inline const gl::texture_2d* directional_light::get_light_texture() const
{
return light_texture;
}
} // namespace scene
#endif // ANTKEEPER_SCENE_DIRECTIONAL_LIGHT_HPP

+ 0
- 1
src/scene/light.cpp View File

@ -18,7 +18,6 @@
*/
#include "scene/light.hpp"
#include "animation/ease.hpp"
#include "math/interpolation.hpp"
namespace scene {

+ 32
- 2
src/scene/light.hpp View File

@ -26,30 +26,60 @@
namespace scene {
/// Light object type enumerations.
enum class light_type
{
/// Denotes an ambient light.
ambient,
/// Denotes a directional light.
directional,
/// Denotes a point light.
point,
/// Denotes a spot light.
spot
};
/**
* Abstract base class for light objects.
*/
class light: public object<light>
{
public:
typedef geom::sphere<float> sphere_type;
/// Creates a light.
light();
/// Returns an enumeration denoting the light object type.
virtual light_type get_light_type() const = 0;
/**
* Sets the color of the light.
*
* @param color Scene-linear light color.
*/
void set_color(const float3& color);
/**
* Sets the intensity of the light.
*
* @param intensity Light intensity.
*/
void set_intensity(float intensity);
/// Returns the bounding volume of the light.
virtual const bounding_volume_type& get_bounds() const;
/// Returns the light color.
const float3& get_color() const;
/// Returns the light intensity.
float get_intensity() const;
/// Returns the intensity-scaled light color.
const float3& get_scaled_color() const;
const tween<float3>& get_color_tween() const;

+ 3
- 0
src/scene/point-light.hpp View File

@ -25,6 +25,9 @@
namespace scene {
/**
* Light source that radiates outward from a point.
*/
class point_light: public light
{
public:

+ 4
- 0
src/scene/spotlight.hpp View File

@ -25,9 +25,13 @@
namespace scene {
/**
* Directional cone light source.
*/
class spotlight: public light
{
public:
/// Creates a spotlight.
spotlight();
/// Returns light_type::spot

Loading…
Cancel
Save