Browse Source

Improve camera controls, remove custom attenuation factors for point and spot lights

master
C. J. Howard 1 year ago
parent
commit
a3188f3b9f
16 changed files with 944 additions and 109 deletions
  1. +0
    -1
      CMakeLists.txt
  2. +4
    -12
      src/engine/render/passes/material-pass.cpp
  3. +0
    -2
      src/engine/render/passes/material-pass.hpp
  4. +5
    -0
      src/engine/scene/directional-light.cpp
  5. +7
    -0
      src/engine/scene/directional-light.hpp
  6. +0
    -17
      src/engine/scene/point-light.hpp
  7. +0
    -17
      src/engine/scene/spot-light.hpp
  8. +54
    -0
      src/game/controls.cpp
  9. +26
    -26
      src/game/game.cpp
  10. +23
    -8
      src/game/game.hpp
  11. +3
    -1
      src/game/states/main-menu-state.cpp
  12. +6
    -1
      src/game/states/nest-selection-state.cpp
  13. +699
    -0
      src/game/states/nest-view-state.cpp
  14. +108
    -0
      src/game/states/nest-view-state.hpp
  15. +8
    -22
      src/game/states/nuptial-flight-state.cpp
  16. +1
    -2
      src/game/states/nuptial-flight-state.hpp

+ 0
- 1
CMakeLists.txt View File

@ -1,6 +1,5 @@
cmake_minimum_required(VERSION 3.25)
option(APPLICATION_NAME "Application name" "Antkeeper")
option(APPLICATION_VERSION "Application version string" "0.0.0")
option(APPLICATION_AUTHOR "Application author" "C. J. Howard")

+ 4
- 12
src/engine/render/passes/material-pass.cpp View File

@ -352,12 +352,10 @@ void material_pass::evaluate_lighting(const render::context& ctx)
{
point_light_colors.resize(point_light_count);
point_light_positions.resize(point_light_count);
point_light_attenuations.resize(point_light_count);
}
point_light_colors[index] = point_light.get_luminous_flux() * ctx.camera->get_exposure_normalization();
point_light_positions[index] = point_light.get_translation();
point_light_attenuations[index] = point_light.get_attenuation();
break;
}
@ -413,14 +411,12 @@ void material_pass::evaluate_lighting(const render::context& ctx)
spot_light_colors.resize(spot_light_count);
spot_light_positions.resize(spot_light_count);
spot_light_directions.resize(spot_light_count);
spot_light_attenuations.resize(spot_light_count);
spot_light_cutoffs.resize(spot_light_count);
}
spot_light_colors[index] = spot_light.get_luminous_flux() * ctx.camera->get_exposure_normalization();
spot_light_positions[index] = spot_light.get_translation();
spot_light_directions[index] = spot_light.get_direction();
spot_light_attenuations[index] = spot_light.get_attenuation();
spot_light_cutoffs[index] = spot_light.get_cosine_cutoff();
break;
}
@ -583,17 +579,15 @@ void material_pass::build_shader_command_buffer(std::vector
if (auto point_light_colors_var = shader_program.variable("point_light_colors"))
{
auto point_light_positions_var = shader_program.variable("point_light_positions");
auto point_light_attenuations_var = shader_program.variable("point_light_attenuations");
if (point_light_positions_var && point_light_attenuations_var)
if (point_light_positions_var)
{
command_buffer.emplace_back
(
[&, point_light_colors_var, point_light_positions_var, point_light_attenuations_var]()
[&, point_light_colors_var, point_light_positions_var]()
{
point_light_colors_var->update(std::span<const float3>{point_light_colors.data(), point_light_count});
point_light_positions_var->update(std::span<const float3>{point_light_positions.data(), point_light_count});
point_light_attenuations_var->update(std::span<const float3>{point_light_attenuations.data(), point_light_count});
}
);
}
@ -607,19 +601,17 @@ void material_pass::build_shader_command_buffer(std::vector
{
auto spot_light_positions_var = shader_program.variable("spot_light_positions");
auto spot_light_directions_var = shader_program.variable("spot_light_directions");
auto spot_light_attenuations_var = shader_program.variable("spot_light_attenuations");
auto spot_light_cutoffs_var = shader_program.variable("spot_light_cutoffs");
if (spot_light_positions_var && spot_light_directions_var && spot_light_attenuations_var && spot_light_cutoffs_var)
if (spot_light_positions_var && spot_light_directions_var && spot_light_cutoffs_var)
{
command_buffer.emplace_back
(
[&, spot_light_colors_var, spot_light_positions_var, spot_light_directions_var, spot_light_attenuations_var, spot_light_cutoffs_var]()
[&, spot_light_colors_var, spot_light_positions_var, spot_light_directions_var, spot_light_cutoffs_var]()
{
spot_light_colors_var->update(std::span<const float3>{spot_light_colors.data(), spot_light_count});
spot_light_positions_var->update(std::span<const float3>{spot_light_positions.data(), spot_light_count});
spot_light_directions_var->update(std::span<const float3>{spot_light_directions.data(), spot_light_count});
spot_light_attenuations_var->update(std::span<const float3>{spot_light_attenuations.data(), spot_light_count});
spot_light_cutoffs_var->update(std::span<const float2>{spot_light_cutoffs.data(), spot_light_count});
}
);

+ 0
- 2
src/engine/render/passes/material-pass.hpp View File

@ -99,7 +99,6 @@ private:
// Point lights
std::vector<float3> point_light_colors;
std::vector<float3> point_light_positions;
std::vector<float3> point_light_attenuations;
std::size_t point_light_count;
// Directional lights
@ -118,7 +117,6 @@ private:
std::vector<float3> spot_light_colors;
std::vector<float3> spot_light_positions;
std::vector<float3> spot_light_directions;
std::vector<float3> spot_light_attenuations;
std::vector<float2> spot_light_cutoffs;
std::size_t spot_light_count;

+ 5
- 0
src/engine/scene/directional-light.cpp View File

@ -26,6 +26,11 @@ directional_light::directional_light():
m_shadow_cascade_matrices(m_shadow_cascade_count)
{}
void directional_light::set_direction(const math::vector<float, 3>& direction)
{
set_rotation(math::rotation(math::vector<float, 3>{0.0f, 0.0f, -1.0f}, direction));
}
void directional_light::set_shadow_caster(bool caster) noexcept
{
m_shadow_caster = caster;

+ 7
- 0
src/engine/scene/directional-light.hpp View File

@ -68,6 +68,13 @@ public:
return m_illuminance;
}
/**
* Sets the direction of the directional light.
*
* @param direction Unit-length light direction vector.
*/
void set_direction(const math::vector<float, 3>& direction);
/// @}
/// @name Shadow

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

@ -52,26 +52,9 @@ public:
{
return m_luminous_flux;
}
/**
* Sets the attenuation factors of the light.
*
* @param attenuation Vector containing the constant, linear, and quadratic attenuation factors, as x, y, and z, respectively.
*/
inline void set_attenuation(const float3& attenuation) noexcept
{
m_attenuation = attenuation;
}
/// Returns the attenuation factors of the light.
[[nodiscard]] inline const math::vector<float, 3>& get_attenuation() const noexcept
{
return m_attenuation;
}
private:
math::vector<float, 3> m_luminous_flux{0.0f, 0.0f, 0.0f};
math::vector<float, 3> m_attenuation{1.0f, 0.0f, 0.0f};
};
} // namespace scene

+ 0
- 17
src/engine/scene/spot-light.hpp View File

@ -54,16 +54,6 @@ public:
return m_luminous_flux;
}
/**
* Sets the attenuation factors of the light.
*
* @param attenuation Vector containing the constant, linear, and quadratic attenuation factors, as x, y, and z, respectively.
*/
inline void set_attenuation(const math::vector<float, 3>& attenuation) noexcept
{
m_attenuation = attenuation;
}
/**
* Sets the spot light cutoff angles.
*
@ -77,12 +67,6 @@ public:
return m_direction;
}
/// Returns the attenuation factors of the light.
[[nodiscard]] inline const math::vector<float, 3>& get_attenuation() const noexcept
{
return m_attenuation;
}
/// Returns the spot light cutoff angles.
[[nodiscard]] inline const math::vector<float, 2>& get_cutoff() const noexcept
{
@ -100,7 +84,6 @@ private:
math::vector<float, 3> m_luminous_flux{0.0f, 0.0f, 0.0f};
math::vector<float, 3> m_direction{0.0f, 0.0f, -1.0f};
math::vector<float, 3> m_attenuation{1.0f, 0.0f, 0.0f};
math::vector<float, 2> m_cutoff{math::pi<float>, math::pi<float>};
math::vector<float, 2> m_cosine_cutoff{-1.0f, -1.0f};
};

+ 54
- 0
src/game/controls.cpp View File

@ -127,12 +127,38 @@ void reset_control_profile(::control_profile& profile)
// Mouse pick
mappings.emplace("mouse_pick", std::make_unique<input::mouse_button_mapping>(nullptr, input::mouse_button::left));
mappings.emplace("mouse_pick", std::make_unique<input::key_mapping>(nullptr, input::scancode::space, 0, false));
// Mouse look
mappings.emplace("mouse_look", std::make_unique<input::mouse_button_mapping>(nullptr, input::mouse_button::right));
mappings.emplace("mouse_look", std::make_unique<input::key_mapping>(nullptr, input::scancode::left_alt, 0, false));
// Mouse grip
mappings.emplace("mouse_grip", std::make_unique<input::mouse_button_mapping>(nullptr, input::mouse_button::left));
mappings.emplace("mouse_grip", std::make_unique<input::key_mapping>(nullptr, input::scancode::left_shift, 0, false));
// Mouse zoom
mappings.emplace("mouse_zoom", std::make_unique<input::mouse_button_mapping>(nullptr, input::mouse_button::middle));
mappings.emplace("mouse_zoom", std::make_unique<input::key_mapping>(nullptr, input::scancode::left_ctrl, 0, false));
// Focus
mappings.emplace("focus", std::make_unique<input::key_mapping>(nullptr, input::scancode::left_shift, 0, false));
// Load camera
mappings.emplace("camera_1", std::make_unique<input::key_mapping>(nullptr, input::scancode::digit_1, 0, false));
mappings.emplace("camera_2", std::make_unique<input::key_mapping>(nullptr, input::scancode::digit_2, 0, false));
mappings.emplace("camera_3", std::make_unique<input::key_mapping>(nullptr, input::scancode::digit_3, 0, false));
mappings.emplace("camera_4", std::make_unique<input::key_mapping>(nullptr, input::scancode::digit_4, 0, false));
mappings.emplace("camera_5", std::make_unique<input::key_mapping>(nullptr, input::scancode::digit_5, 0, false));
mappings.emplace("camera_6", std::make_unique<input::key_mapping>(nullptr, input::scancode::digit_6, 0, false));
mappings.emplace("camera_7", std::make_unique<input::key_mapping>(nullptr, input::scancode::digit_7, 0, false));
mappings.emplace("camera_8", std::make_unique<input::key_mapping>(nullptr, input::scancode::digit_8, 0, false));
mappings.emplace("camera_9", std::make_unique<input::key_mapping>(nullptr, input::scancode::digit_9, 0, false));
mappings.emplace("camera_10", std::make_unique<input::key_mapping>(nullptr, input::scancode::digit_0, 0, false));
// Save camera
mappings.emplace("save_camera", std::make_unique<input::key_mapping>(nullptr, input::scancode::left_ctrl, 0, false));
mappings.emplace("save_camera", std::make_unique<input::key_mapping>(nullptr, input::scancode::right_ctrl, 0, false));
}
void apply_control_profile(::game& ctx, const ::control_profile& profile)
@ -175,7 +201,20 @@ void apply_control_profile(::game& ctx, const ::control_profile& profile)
ctx.keeper_action_map.remove_mappings();
add_mappings(ctx.keeper_action_map, ctx.mouse_pick_action, "mouse_pick");
add_mappings(ctx.keeper_action_map, ctx.mouse_look_action, "mouse_look");
add_mappings(ctx.keeper_action_map, ctx.mouse_grip_action, "mouse_grip");
add_mappings(ctx.keeper_action_map, ctx.mouse_zoom_action, "mouse_zoom");
add_mappings(ctx.keeper_action_map, ctx.focus_action, "focus");
add_mappings(ctx.keeper_action_map, ctx.camera_1_action, "camera_1");
add_mappings(ctx.keeper_action_map, ctx.camera_2_action, "camera_2");
add_mappings(ctx.keeper_action_map, ctx.camera_3_action, "camera_3");
add_mappings(ctx.keeper_action_map, ctx.camera_4_action, "camera_4");
add_mappings(ctx.keeper_action_map, ctx.camera_5_action, "camera_5");
add_mappings(ctx.keeper_action_map, ctx.camera_6_action, "camera_6");
add_mappings(ctx.keeper_action_map, ctx.camera_7_action, "camera_7");
add_mappings(ctx.keeper_action_map, ctx.camera_8_action, "camera_8");
add_mappings(ctx.keeper_action_map, ctx.camera_9_action, "camera_9");
add_mappings(ctx.keeper_action_map, ctx.camera_10_action, "camera_10");
add_mappings(ctx.keeper_action_map, ctx.save_camera_action, "save_camera");
}
void update_control_profile(::game& ctx, ::control_profile& profile)
@ -242,7 +281,20 @@ void update_control_profile(::game& ctx, ::control_profile& profile)
// Keeper controls
add_mappings(ctx.keeper_action_map, ctx.mouse_pick_action, "mouse_pick");
add_mappings(ctx.keeper_action_map, ctx.mouse_look_action, "mouse_look");
add_mappings(ctx.keeper_action_map, ctx.mouse_grip_action, "mouse_grip");
add_mappings(ctx.keeper_action_map, ctx.mouse_zoom_action, "mouse_zoom");
add_mappings(ctx.keeper_action_map, ctx.focus_action, "focus");
add_mappings(ctx.keeper_action_map, ctx.camera_1_action, "camera_1");
add_mappings(ctx.keeper_action_map, ctx.camera_2_action, "camera_2");
add_mappings(ctx.keeper_action_map, ctx.camera_3_action, "camera_3");
add_mappings(ctx.keeper_action_map, ctx.camera_4_action, "camera_4");
add_mappings(ctx.keeper_action_map, ctx.camera_5_action, "camera_5");
add_mappings(ctx.keeper_action_map, ctx.camera_6_action, "camera_6");
add_mappings(ctx.keeper_action_map, ctx.camera_7_action, "camera_7");
add_mappings(ctx.keeper_action_map, ctx.camera_8_action, "camera_8");
add_mappings(ctx.keeper_action_map, ctx.camera_9_action, "camera_9");
add_mappings(ctx.keeper_action_map, ctx.camera_10_action, "camera_10");
add_mappings(ctx.keeper_action_map, ctx.save_camera_action, "save_camera");
}
void setup_window_controls(::game& ctx)
@ -553,6 +605,8 @@ void disable_keeper_controls(::game& ctx)
ctx.mouse_pick_action.reset();
ctx.mouse_look_action.reset();
ctx.mouse_grip_action.reset();
ctx.mouse_zoom_action.reset();
ctx.focus_action.reset();
}

+ 26
- 26
src/game/game.cpp View File

@ -669,7 +669,7 @@ void game::setup_rendering()
// Default rendering settings
render_scale = 1.0f;
anti_aliasing_method = render::anti_aliasing_method::fxaa;
anti_aliasing_method = render::anti_aliasing_method::none;
shadow_map_resolution = 4096;
// Read rendering settings
@ -727,25 +727,6 @@ void game::setup_rendering()
ui_compositor->add_pass(ui_material_pass.get());
}
// Setup underground compositor
{
underground_clear_pass = std::make_unique<render::clear_pass>(window->get_rasterizer(), hdr_framebuffer.get());
underground_clear_pass->set_cleared_buffers(true, true, false);
underground_clear_pass->set_clear_color({1, 0, 1, 0});
underground_clear_pass->set_clear_depth(-1.0f);
underground_material_pass = std::make_unique<render::material_pass>(window->get_rasterizer(), hdr_framebuffer.get(), resource_manager.get());
underground_material_pass->set_fallback_material(fallback_material);
underground_compositor = std::make_unique<render::compositor>();
underground_compositor->add_pass(underground_clear_pass.get());
underground_compositor->add_pass(underground_material_pass.get());
underground_compositor->add_pass(bloom_pass.get());
underground_compositor->add_pass(common_final_pass.get());
underground_compositor->add_pass(fxaa_pass.get());
underground_compositor->add_pass(resample_pass.get());
}
// Setup surface compositor
{
surface_shadow_map_clear_pass = std::make_unique<render::clear_pass>(window->get_rasterizer(), shadow_map_framebuffer.get());
@ -785,6 +766,25 @@ void game::setup_rendering()
surface_compositor->add_pass(resample_pass.get());
}
// Setup underground compositor
{
underground_clear_pass = std::make_unique<render::clear_pass>(window->get_rasterizer(), hdr_framebuffer.get());
underground_clear_pass->set_cleared_buffers(true, true, false);
underground_clear_pass->set_clear_color({0, 0, 0, 1});
underground_clear_pass->set_clear_depth(-1.0f);
underground_material_pass = std::make_unique<render::material_pass>(window->get_rasterizer(), hdr_framebuffer.get(), resource_manager.get());
underground_material_pass->set_fallback_material(fallback_material);
underground_compositor = std::make_unique<render::compositor>();
underground_compositor->add_pass(underground_clear_pass.get());
underground_compositor->add_pass(underground_material_pass.get());
underground_compositor->add_pass(bloom_pass.get());
underground_compositor->add_pass(common_final_pass.get());
underground_compositor->add_pass(fxaa_pass.get());
underground_compositor->add_pass(resample_pass.get());
}
// Create renderer
renderer = std::make_unique<render::renderer>();
@ -799,21 +799,21 @@ void game::setup_scenes()
const auto& viewport_size = window->get_viewport_size();
const float viewport_aspect_ratio = static_cast<float>(viewport_size[0]) / static_cast<float>(viewport_size[1]);
// Setup surface scene
// Allocate surface scene
surface_scene = std::make_unique<scene::collection>();
// Setup surface camera
// Allocate and init surface camera
surface_camera = std::make_shared<scene::camera>();
surface_camera->set_perspective(math::radians<float>(45.0f), viewport_aspect_ratio, 0.1f, 5000.0f);
surface_camera->set_compositor(surface_compositor.get());
surface_camera->set_composite_index(0);
// Setup underground scene
// Allocate underground scene
underground_scene = std::make_unique<scene::collection>();
// Setup underground camera
// Allocate and init underground camera
underground_camera = std::make_shared<scene::camera>();
underground_camera->set_perspective(math::radians<float>(45.0f), viewport_aspect_ratio, 0.1f, 1000.0f);
underground_camera->set_perspective(math::radians<float>(45.0f), viewport_aspect_ratio, 0.1f, 200.0f);
underground_camera->set_compositor(underground_compositor.get());
underground_camera->set_composite_index(0);
@ -1094,8 +1094,8 @@ void game::setup_systems()
// Setup render system
render_system = std::make_unique<::render_system>(*entity_registry);
render_system->set_renderer(renderer.get());
//render_system->add_layer(underground_scene.get());
render_system->add_layer(surface_scene.get());
render_system->add_layer(underground_scene.get());
render_system->add_layer(ui_scene.get());
}

+ 23
- 8
src/game/game.hpp View File

@ -49,6 +49,7 @@
#include <engine/utility/frame-scheduler.hpp>
#include <engine/scene/text.hpp>
#include <engine/scene/directional-light.hpp>
#include <engine/scene/point-light.hpp>
#include <engine/scene/spot-light.hpp>
#include <engine/scene/ambient-light.hpp>
#include <engine/scene/camera.hpp>
@ -224,7 +225,20 @@ public:
input::action pause_action;
input::action mouse_pick_action;
input::action mouse_look_action;
input::action mouse_grip_action;
input::action mouse_zoom_action;
input::action focus_action;
input::action camera_1_action;
input::action camera_2_action;
input::action camera_3_action;
input::action camera_4_action;
input::action camera_5_action;
input::action camera_6_action;
input::action camera_7_action;
input::action camera_8_action;
input::action camera_9_action;
input::action camera_10_action;
input::action save_camera_action;
std::vector<std::shared_ptr<::event::subscription>> window_action_subscriptions;
std::vector<std::shared_ptr<::event::subscription>> menu_action_subscriptions;
@ -238,6 +252,8 @@ public:
bool invert_mouse_pan{false};
bool invert_mouse_tilt{false};
bool toggle_mouse_look{false};
bool toggle_mouse_grip{false};
bool toggle_mouse_zoom{false};
double mouse_pan_factor{1.0};
double mouse_tilt_factor{1.0};
@ -288,13 +304,6 @@ public:
std::unique_ptr<render::ground_pass> ground_pass;
std::unique_ptr<render::renderer> renderer;
// Scene utilities
scene::collection* active_scene;
std::unique_ptr<scene::directional_light> sun_light;
std::unique_ptr<scene::directional_light> moon_light;
std::unique_ptr<scene::ambient_light> sky_light;
std::unique_ptr<scene::directional_light> bounce_light;
// UI
std::unique_ptr<scene::collection> ui_scene;
std::unique_ptr<scene::camera> ui_camera;
@ -321,10 +330,16 @@ public:
// Scene
std::unique_ptr<scene::collection> surface_scene;
std::shared_ptr<scene::camera> surface_camera;
std::unique_ptr<scene::directional_light> sun_light;
std::unique_ptr<scene::directional_light> moon_light;
std::unique_ptr<scene::ambient_light> sky_light;
std::unique_ptr<scene::directional_light> bounce_light;
std::unique_ptr<scene::collection> underground_scene;
std::shared_ptr<scene::camera> underground_camera;
std::unique_ptr<scene::directional_light> underground_directional_light;
std::unique_ptr<scene::ambient_light> underground_ambient_light;
std::unique_ptr<scene::spot_light> flashlight_spot_light;
std::unique_ptr<scene::point_light> underground_point_light;
scene::collection* active_scene;
// Animation
std::unique_ptr<timeline> timeline;

+ 3
- 1
src/game/states/main-menu-state.cpp View File

@ -32,6 +32,7 @@
#include "game/states/extras-menu-state.hpp"
#include "game/states/nuptial-flight-state.hpp"
#include "game/states/nest-selection-state.hpp"
#include "game/states/nest-view-state.hpp"
#include "game/states/options-menu-state.hpp"
#include "game/strings.hpp"
#include "game/world.hpp"
@ -130,7 +131,8 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in):
ctx.state_machine.pop();
//ctx.state_machine.emplace(std::make_unique<nuptial_flight_state>(ctx));
//ctx.state_machine.emplace(std::make_unique<collection_menu_state>(ctx));
ctx.state_machine.emplace(std::make_unique<nest_selection_state>(ctx));
// ctx.state_machine.emplace(std::make_unique<nest_selection_state>(ctx));
ctx.state_machine.emplace(std::make_unique<nest_view_state>(ctx));
}
);
};

+ 6
- 1
src/game/states/nest-selection-state.cpp View File

@ -100,7 +100,7 @@ nest_selection_state::nest_selection_state(::game& ctx):
debug::log::trace("Generated genome");
debug::log::trace("Building worker phenome...");
ant_phenome worker_phenome = ant_phenome(*genome, ant_caste_type::worker);
ant_phenome worker_phenome = ant_phenome(*genome, ant_caste_type::queen);
debug::log::trace("Built worker phenome...");
debug::log::trace("Generating worker model...");
@ -158,6 +158,11 @@ nest_selection_state::nest_selection_state(::game& ctx):
worker_body->set_collider(std::move(worker_collider));
//ctx.entity_registry->emplace<rigid_body_component>(worker_ant_eid, std::move(worker_body));
auto cocoon_eid = ctx.entity_registry->create();
ctx.entity_registry->emplace<scene_component>(cocoon_eid, std::make_shared<scene::static_mesh>(worker_phenome.cocoon->model), std::uint8_t{1});
larva_eid = ctx.entity_registry->create();
auto larva_skeletal_mesh = std::make_shared<scene::skeletal_mesh>(worker_phenome.larva->model);

+ 699
- 0
src/game/states/nest-view-state.cpp View File

@ -0,0 +1,699 @@
/*
* Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
*/
#include "game/states/nest-view-state.hpp"
#include "game/ant/ant-cladogenesis.hpp"
#include "game/ant/ant-genome.hpp"
#include "game/ant/ant-morphogenesis.hpp"
#include "game/ant/ant-phenome.hpp"
#include "game/commands/commands.hpp"
#include "game/components/constraint-stack-component.hpp"
#include "game/components/scene-component.hpp"
#include "game/components/picking-component.hpp"
#include "game/components/spring-component.hpp"
#include "game/components/rigid-body-component.hpp"
#include "game/components/rigid-body-constraint-component.hpp"
#include "game/components/steering-component.hpp"
#include "game/components/terrain-component.hpp"
#include "game/components/legged-locomotion-component.hpp"
#include "game/components/winged-locomotion-component.hpp"
#include "game/components/ik-component.hpp"
#include "game/components/transform-component.hpp"
#include "game/constraints/child-of-constraint.hpp"
#include "game/constraints/copy-rotation-constraint.hpp"
#include "game/constraints/copy-scale-constraint.hpp"
#include "game/constraints/copy-transform-constraint.hpp"
#include "game/constraints/copy-translation-constraint.hpp"
#include "game/constraints/ease-to-constraint.hpp"
#include "game/constraints/pivot-constraint.hpp"
#include "game/constraints/spring-rotation-constraint.hpp"
#include "game/constraints/spring-to-constraint.hpp"
#include "game/constraints/spring-translation-constraint.hpp"
#include "game/constraints/three-dof-constraint.hpp"
#include "game/constraints/track-to-constraint.hpp"
#include "game/controls.hpp"
#include "game/spawn.hpp"
#include "game/states/pause-menu-state.hpp"
#include "game/systems/astronomy-system.hpp"
#include "game/systems/atmosphere-system.hpp"
#include "game/systems/camera-system.hpp"
#include "game/systems/collision-system.hpp"
#include "game/world.hpp"
#include <engine/animation/ease.hpp>
#include <engine/animation/screen-transition.hpp>
#include <engine/config.hpp>
#include <engine/entity/archetype.hpp>
#include <engine/input/mouse.hpp>
#include <engine/math/interpolation.hpp>
#include <engine/math/projection.hpp>
#include <engine/physics/light/exposure.hpp>
#include <engine/physics/kinematics/constraints/spring-constraint.hpp>
#include <engine/physics/kinematics/colliders/sphere-collider.hpp>
#include <engine/physics/kinematics/colliders/plane-collider.hpp>
#include <engine/physics/kinematics/colliders/box-collider.hpp>
#include <engine/physics/kinematics/colliders/capsule-collider.hpp>
#include <engine/render/passes/clear-pass.hpp>
#include <engine/render/passes/ground-pass.hpp>
#include <engine/resources/resource-manager.hpp>
#include <engine/utility/state-machine.hpp>
#include <engine/scene/static-mesh.hpp>
#include <engine/scene/skeletal-mesh.hpp>
#include <engine/geom/intersection.hpp>
#include <engine/animation/ease.hpp>
nest_view_state::nest_view_state(::game& ctx):
game_state(ctx)
{
debug::log::trace("Entering nest selection state...");
// Create world if not yet created
if (ctx.entities.find("earth") == ctx.entities.end())
{
// Create cosmos
::world::cosmogenesis(ctx);
// Create observer
::world::create_observer(ctx);
}
ctx.active_ecoregion = ctx.resource_manager->load<::ecoregion>("seedy-scrub.eco");
::world::enter_ecoregion(ctx, *ctx.active_ecoregion);
debug::log::trace("Generating genome...");
std::unique_ptr<ant_genome> genome = ant_cladogenesis(ctx.active_ecoregion->gene_pools[0], ctx.rng);
debug::log::trace("Generated genome");
debug::log::trace("Building worker phenome...");
ant_phenome worker_phenome = ant_phenome(*genome, ant_caste_type::queen);
debug::log::trace("Built worker phenome...");
debug::log::trace("Generating worker model...");
std::shared_ptr<render::model> worker_model = ant_morphogenesis(worker_phenome);
debug::log::trace("Generated worker model");
// Create directional light
ctx.underground_directional_light = std::make_unique<scene::directional_light>();
ctx.underground_directional_light->set_illuminance(float3{0.747f, 0.756f, 1.0f} * 2.0f);
ctx.underground_directional_light->set_direction(math::normalize(math::vector<float, 3>{1, -1, 0}));
// ctx.underground_directional_light->set_shadow_caster(true);
// ctx.underground_directional_light->set_shadow_framebuffer(ctx.shadow_map_framebuffer);
// ctx.underground_directional_light->set_shadow_bias(0.005f);
// ctx.underground_directional_light->set_shadow_cascade_count(4);
// ctx.underground_directional_light->set_shadow_cascade_coverage(0.15f);
// ctx.underground_directional_light->set_shadow_cascade_distribution(0.8f);
// ctx.underground_scene->add_object(*ctx.underground_directional_light);
// Create ambient light
ctx.underground_ambient_light = std::make_unique<scene::ambient_light>();
ctx.underground_ambient_light->set_illuminance(float3{1.0f, 1.0f, 1.0f} * 0.025f);
ctx.underground_scene->add_object(*ctx.underground_ambient_light);
// Create point light
ctx.underground_point_light = std::make_unique<scene::point_light>();
ctx.underground_point_light->set_luminous_flux(float3{1.0f, 1.0f, 1.0f} * 200.0f);
ctx.underground_point_light->set_translation(float3{-13.0f, 7.0f, -6.0f});
ctx.underground_scene->add_object(*ctx.underground_point_light);
// Create chamber
auto chamber_eid = ctx.entity_registry->create();
scene_component chamber_scene_component;
chamber_scene_component.object = std::make_shared<scene::static_mesh>(ctx.resource_manager->load<render::model>("soil-nest.mdl"));
chamber_scene_component.layer_mask = 2;
ctx.entity_registry->emplace<scene_component>(chamber_eid, std::move(chamber_scene_component));
// Create worker
auto worker_skeletal_mesh = std::make_unique<scene::skeletal_mesh>(worker_model);
auto worker_ant_eid = ctx.entity_registry->create();
transform_component worker_transform_component;
worker_transform_component.local = math::transform<float>::identity();
worker_transform_component.local.translation = {0, 0.5f, -4};
worker_transform_component.world = worker_transform_component.local;
ctx.entity_registry->emplace<transform_component>(worker_ant_eid, worker_transform_component);
ctx.entity_registry->emplace<scene_component>(worker_ant_eid, std::move(worker_skeletal_mesh), std::uint8_t{1});
// Create cocoon
auto cocoon_eid = ctx.entity_registry->create();
ctx.entity_registry->emplace<scene_component>(cocoon_eid, std::make_shared<scene::static_mesh>(worker_phenome.cocoon->model), std::uint8_t{2});
// Create larva
auto larva_eid = ctx.entity_registry->create();
auto larva_skeletal_mesh = std::make_shared<scene::skeletal_mesh>(worker_phenome.larva->model);
ctx.entity_registry->emplace<scene_component>(larva_eid, std::move(larva_skeletal_mesh), std::uint8_t{2});
ctx.entity_registry->patch<scene_component>
(
larva_eid,
[&](auto& component)
{
component.object->set_translation({-10.0f, -1.5f, -10.0f});
}
);
// Disable UI color clear
ctx.ui_clear_pass->set_cleared_buffers(false, true, false);
// Set world time
::world::set_time(ctx, 2022, 6, 21, 12, 0, 0.0);
// Init time scale
double time_scale = 60.0;
// Set time scale
::world::set_time_scale(ctx, time_scale);
// Setup camera
ctx.underground_camera->set_exposure_value(0.0f);
const auto& viewport_size = ctx.window->get_viewport_size();
const float aspect_ratio = static_cast<float>(viewport_size[0]) / static_cast<float>(viewport_size[1]);
// Create third person camera rig
create_third_person_camera_rig();
// Setup controls
setup_controls();
// Queue enable game controls
ctx.function_queue.push
(
[&ctx]()
{
::enable_game_controls(ctx);
::enable_keeper_controls(ctx);
}
);
// Queue fade in
ctx.fade_transition_color->set({0, 0, 0});
ctx.function_queue.push(std::bind(&screen_transition::transition, ctx.fade_transition.get(), 1.0f, true, ease<float>::out_sine, true, nullptr));
// Refresh frame scheduler
ctx.frame_scheduler.refresh();
debug::log::trace("Entered nest selection state");
}
nest_view_state::~nest_view_state()
{
debug::log::trace("Exiting nest selection state...");
// Disable game controls
::disable_game_controls(ctx);
::disable_keeper_controls(ctx);
destroy_third_person_camera_rig();
debug::log::trace("Exited nest selection state");
}
void nest_view_state::create_third_person_camera_rig()
{
// Construct third person camera rig scene component
scene_component third_person_camera_rig_camera;
third_person_camera_rig_camera.object = ctx.underground_camera;
third_person_camera_rig_camera.layer_mask = 2;
// Construct third person camera rig entity
third_person_camera_rig_eid = ctx.entity_registry->create();
ctx.entity_registry->emplace<scene_component>(third_person_camera_rig_eid, third_person_camera_rig_camera);
set_third_person_camera_zoom(third_person_camera_zoom);
set_third_person_camera_rotation(third_person_camera_yaw, third_person_camera_pitch);
update_third_person_camera();
}
void nest_view_state::destroy_third_person_camera_rig()
{
ctx.entity_registry->destroy(third_person_camera_rig_eid);
}
void nest_view_state::set_third_person_camera_zoom(double zoom)
{
// Clamp zoom
third_person_camera_zoom = std::min<double>(std::max<double>(zoom, 0.0), 1.0);
// Update FoV
third_person_camera_hfov = ease<double, double>::out_sine(third_person_camera_far_hfov, third_person_camera_near_hfov, third_person_camera_zoom);
third_person_camera_vfov = math::vertical_fov(third_person_camera_hfov, static_cast<double>(ctx.underground_camera->get_aspect_ratio()));
// Update focal plane size
third_person_camera_focal_plane_height = ease<double, double>::out_sine(third_person_camera_far_focal_plane_height, third_person_camera_near_focal_plane_height, third_person_camera_zoom);
third_person_camera_focal_plane_width = third_person_camera_focal_plane_height * ctx.underground_camera->get_aspect_ratio();
// Update focal distance
third_person_camera_focal_distance = third_person_camera_focal_plane_height * 0.5 / std::tan(third_person_camera_vfov * 0.5);
// update_third_person_camera();
}
void nest_view_state::set_third_person_camera_rotation(double yaw, double pitch)
{
third_person_camera_yaw = yaw;
third_person_camera_pitch = std::min(math::half_pi<double>, std::max(-math::half_pi<double>, pitch));
third_person_camera_yaw_rotation = math::angle_axis(third_person_camera_yaw, {0.0, 1.0, 0.0});
third_person_camera_pitch_rotation = math::angle_axis(third_person_camera_pitch, {-1.0, 0.0, 0.0});
third_person_camera_orientation = math::normalize(third_person_camera_yaw_rotation * third_person_camera_pitch_rotation);
}
void nest_view_state::zoom_third_person_camera(double zoom)
{
set_third_person_camera_zoom(third_person_camera_zoom + zoom);
}
void nest_view_state::translate_third_person_camera(const math::vector<double, 3>& direction, double magnitude)
{
// Scale translation magnitude by factor of focal plane height
magnitude *= third_person_camera_focal_plane_height * third_person_camera_speed;
// Rotate translation direction according to camera yaw
const math::vector<double, 3> rotated_direction = third_person_camera_yaw_rotation * direction;
third_person_camera_focal_point += rotated_direction * magnitude;
// update_third_person_camera();
}
void nest_view_state::rotate_third_person_camera(const input::mouse_moved_event& event)
{
const double yaw = third_person_camera_yaw - ctx.mouse_pan_factor * static_cast<double>(event.difference.x());
const double pitch = third_person_camera_pitch + ctx.mouse_tilt_factor * static_cast<double>(event.difference.y());
set_third_person_camera_rotation(yaw, pitch);
}
void nest_view_state::handle_mouse_motion(const input::mouse_moved_event& event)
{
if (!mouse_look && !mouse_grip && !mouse_zoom)
{
return;
}
if (mouse_grip)
{
const math::vector<double, 2> viewport_size = math::vector<double, 2>(ctx.window->get_viewport_size());
math::vector<double, 3> translation
{
third_person_camera_focal_plane_width * (static_cast<double>(-event.difference.x()) / (viewport_size.x() - 1.0)),
0.0,
third_person_camera_focal_plane_height * (static_cast<double>(-event.difference.y()) / (viewport_size.y() - 1.0)),
};
if (third_person_camera_pitch < 0.0)
{
translation.z() *= -1.0;
}
third_person_camera_focal_point += third_person_camera_yaw_rotation * translation;
}
if (mouse_look)
{
rotate_third_person_camera(event);
}
if (mouse_zoom)
{
const double zoom_speed = -1.0 / static_cast<double>(ctx.window->get_viewport_size().y());
zoom_third_person_camera(static_cast<double>(event.difference.y()) * zoom_speed);
}
update_third_person_camera();
}
void nest_view_state::update_third_person_camera()
{
const math::vector<double, 3> camera_position = third_person_camera_focal_point + third_person_camera_orientation * math::vector<double, 3>{0.0f, 0.0f, third_person_camera_focal_distance};
ctx.entity_registry->patch<scene_component>
(
third_person_camera_rig_eid,
[&](auto& component)
{
auto& camera = static_cast<scene::camera&>(*component.object);
camera.set_translation(math::vector<float, 3>(camera_position));
camera.set_rotation(math::quaternion<float>(third_person_camera_orientation));
camera.set_perspective(static_cast<float>(third_person_camera_vfov), camera.get_aspect_ratio(), camera.get_clip_near(), camera.get_clip_far());
}
);
}
void nest_view_state::load_camera_preset(std::uint8_t index)
{
if (!camera_presets[index])
{
return;
}
const auto& preset = *camera_presets[index];
third_person_camera_yaw = preset.yaw;
third_person_camera_pitch = preset.pitch;
third_person_camera_focal_point = preset.focal_point;
zoom_third_person_camera(preset.zoom - third_person_camera_zoom);
third_person_camera_yaw_rotation = math::angle_axis(third_person_camera_yaw, {0.0, 1.0, 0.0});
third_person_camera_pitch_rotation = math::angle_axis(third_person_camera_pitch, {-1.0, 0.0, 0.0});
third_person_camera_orientation = math::normalize(third_person_camera_yaw_rotation * third_person_camera_pitch_rotation);
update_third_person_camera();
}
void nest_view_state::save_camera_preset(std::uint8_t index)
{
camera_presets[index] =
{
third_person_camera_yaw,
third_person_camera_pitch,
third_person_camera_focal_point,
third_person_camera_zoom
};
}
void nest_view_state::load_or_save_camera_preset(std::uint8_t index)
{
if (ctx.save_camera_action.is_active())
{
save_camera_preset(index);
}
else
{
load_camera_preset(index);
}
}
geom::ray<float, 3> nest_view_state::get_mouse_ray(const math::vector<std::int32_t, 2>& mouse_position) const
{
// Get window viewport size
const auto& viewport_size = ctx.window->get_viewport_size();
// Transform mouse coordinates from window space to NDC space
const math::vector<float, 2> mouse_ndc =
{
static_cast<float>(mouse_position.x()) / static_cast<float>(viewport_size.x() - 1) * 2.0f - 1.0f,
(1.0f - static_cast<float>(mouse_position.y()) / static_cast<float>(viewport_size.y() - 1)) * 2.0f - 1.0f
};
const auto& scene_component = ctx.entity_registry->get<::scene_component>(third_person_camera_rig_eid);
const auto& camera = static_cast<const scene::camera&>(*scene_component.object);
return camera.pick(mouse_ndc);
}
void nest_view_state::setup_controls()
{
// Enable/toggle mouse look
action_subscriptions.emplace_back
(
ctx.mouse_look_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
mouse_look = ctx.toggle_mouse_look ? !mouse_look : true;
//ctx.input_manager->set_cursor_visible(!mouse_look);
ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
}
)
);
// Disable mouse look
action_subscriptions.emplace_back
(
ctx.mouse_look_action.get_deactivated_channel().subscribe
(
[&](const auto& event)
{
if (!ctx.toggle_mouse_look && mouse_look)
{
mouse_look = false;
//ctx.input_manager->set_cursor_visible(true);
ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
}
}
)
);
// Enable/toggle mouse grip
action_subscriptions.emplace_back
(
ctx.mouse_grip_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
mouse_grip = ctx.toggle_mouse_grip ? !mouse_grip : true;
if (mouse_grip)
{
const auto& mouse_position = (*ctx.input_manager->get_mice().begin())->get_position();
// Cast ray to plane
const auto mouse_ray = get_mouse_ray(mouse_position);
const auto intersection = geom::intersection(mouse_ray, mouse_grip_plane);
if (intersection)
{
mouse_grip_point = mouse_ray.origin + mouse_ray.direction * (*intersection);
}
}
ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
}
)
);
// Disable mouse grip
action_subscriptions.emplace_back
(
ctx.mouse_grip_action.get_deactivated_channel().subscribe
(
[&](const auto& event)
{
mouse_grip = false;
ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
}
)
);
// Enable/toggle mouse zoom
action_subscriptions.emplace_back
(
ctx.mouse_zoom_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
mouse_zoom = ctx.toggle_mouse_zoom ? !mouse_zoom : true;
ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
}
)
);
// Disable mouse zoom
action_subscriptions.emplace_back
(
ctx.mouse_zoom_action.get_deactivated_channel().subscribe
(
[&](const auto& event)
{
mouse_zoom = false;
ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom);
}
)
);
// Mouse look
mouse_motion_subscription = ctx.input_manager->get_event_dispatcher().subscribe<input::mouse_moved_event>
(
std::bind_front(&nest_view_state::handle_mouse_motion, this)
);
// Move forward
action_subscriptions.emplace_back
(
ctx.move_forward_action.get_active_channel().subscribe
(
[&](const auto& event)
{
translate_third_person_camera({0.0, 0.0, -1.0}, event.input_value / ctx.fixed_update_rate);
update_third_person_camera();
}
)
);
// Move back
action_subscriptions.emplace_back
(
ctx.move_back_action.get_active_channel().subscribe
(
[&](const auto& event)
{
translate_third_person_camera({0.0, 0.0, 1.0}, event.input_value / ctx.fixed_update_rate);
update_third_person_camera();
}
)
);
// Move left
action_subscriptions.emplace_back
(
ctx.move_left_action.get_active_channel().subscribe
(
[&](const auto& event)
{
translate_third_person_camera({-1.0, 0.0, 0.0}, event.input_value / ctx.fixed_update_rate);
update_third_person_camera();
}
)
);
// Move right
action_subscriptions.emplace_back
(
ctx.move_right_action.get_active_channel().subscribe
(
[&](const auto& event)
{
translate_third_person_camera({1.0, 0.0, 0.0}, event.input_value / ctx.fixed_update_rate);
update_third_person_camera();
}
)
);
// Zoom in
action_subscriptions.emplace_back
(
ctx.move_up_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
zoom_third_person_camera(1.0 / static_cast<double>(third_person_camera_zoom_step_count));
update_third_person_camera();
}
)
);
// Zoom out
action_subscriptions.emplace_back
(
ctx.move_down_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
zoom_third_person_camera(-1.0 / static_cast<double>(third_person_camera_zoom_step_count));
update_third_person_camera();
}
)
);
// Focus
action_subscriptions.emplace_back
(
ctx.focus_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
}
)
);
action_subscriptions.emplace_back
(
ctx.focus_action.get_deactivated_channel().subscribe
(
[&](const auto& event)
{
}
)
);
// Camera presets
action_subscriptions.emplace_back
(
ctx.camera_1_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(0);}
)
);
action_subscriptions.emplace_back
(
ctx.camera_2_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(1);}
)
);
action_subscriptions.emplace_back
(
ctx.camera_3_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(2);}
)
);
action_subscriptions.emplace_back
(
ctx.camera_4_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(3);}
)
);
action_subscriptions.emplace_back
(
ctx.camera_5_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(4);}
)
);
action_subscriptions.emplace_back
(
ctx.camera_6_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(5);}
)
);
action_subscriptions.emplace_back
(
ctx.camera_7_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(6);}
)
);
action_subscriptions.emplace_back
(
ctx.camera_8_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(7);}
)
);
action_subscriptions.emplace_back
(
ctx.camera_9_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(8);}
)
);
action_subscriptions.emplace_back
(
ctx.camera_10_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(9);}
)
);
}

+ 108
- 0
src/game/states/nest-view-state.hpp View File

@ -0,0 +1,108 @@
/*
* Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_NEST_VIEW_STATE_HPP
#define ANTKEEPER_NEST_VIEW_STATE_HPP
#include "game/states/game-state.hpp"
#include <engine/entity/id.hpp>
#include <engine/utility/fundamental-types.hpp>
#include <engine/render/model.hpp>
#include <engine/event/subscription.hpp>
#include <engine/input/mouse-events.hpp>
#include <engine/geom/primitives/ray.hpp>
#include <engine/geom/primitives/plane.hpp>
#include <engine/math/angles.hpp>
class nest_view_state: public game_state
{
public:
explicit nest_view_state(::game& ctx);
virtual ~nest_view_state();
private:
void create_third_person_camera_rig();
void destroy_third_person_camera_rig();
void set_third_person_camera_zoom(double zoom);
void set_third_person_camera_rotation(double yaw, double pitch);
void zoom_third_person_camera(double zoom);
void translate_third_person_camera(const math::vector<double, 3>& direction, double magnitude);
void rotate_third_person_camera(const input::mouse_moved_event& event);
void handle_mouse_motion(const input::mouse_moved_event& event);
void update_third_person_camera();
void load_camera_preset(std::uint8_t index);
void save_camera_preset(std::uint8_t index);
void load_or_save_camera_preset(std::uint8_t index);
[[nodiscard]] geom::ray<float, 3> get_mouse_ray(const math::vector<std::int32_t, 2>& mouse_position) const;
void setup_controls();
std::vector<std::shared_ptr<::event::subscription>> action_subscriptions;
std::shared_ptr<::event::subscription> mouse_motion_subscription;
bool mouse_look{false};
bool mouse_grip{false};
bool mouse_zoom{false};
geom::plane<float> mouse_grip_plane{{0.0, 1.0, 0.0}, 0.0};
math::vector<float, 3> mouse_grip_point{};
bool moving{false};
entity::id third_person_camera_rig_eid{entt::null};
double third_person_camera_yaw{0.0};
double third_person_camera_pitch{math::radians(45.0)};
math::vector<double, 3> third_person_camera_focal_point{0.0, 0.0, 0.0};
double third_person_camera_zoom{0.25};
std::uint32_t third_person_camera_zoom_step_count{6};
double third_person_camera_near_focal_plane_height{2.0f};
double third_person_camera_far_focal_plane_height{50.0f};
double third_person_camera_near_hfov{math::radians(45.0)};
double third_person_camera_far_hfov{math::radians(90.0)};
/// In focal plane heights per second.
double third_person_camera_speed{1.0f};
double third_person_camera_hfov{};
double third_person_camera_vfov{};
double third_person_camera_focal_plane_width{};
double third_person_camera_focal_plane_height{};
double third_person_camera_focal_distance{};
math::quaternion<double> third_person_camera_yaw_rotation{math::quaternion<double>::identity()};
math::quaternion<double> third_person_camera_pitch_rotation{math::quaternion<double>::identity()};
math::quaternion<double> third_person_camera_orientation{math::quaternion<double>::identity()};
struct camera_preset
{
double yaw{};
double pitch{};
math::vector<double, 3> focal_point{};
double zoom{0.25};
};
std::vector<std::optional<camera_preset>> camera_presets{10};
};
#endif // ANTKEEPER_NEST_VIEW_STATE_HPP

+ 8
- 22
src/game/states/nuptial-flight-state.cpp View File

@ -104,33 +104,20 @@ nuptial_flight_state::nuptial_flight_state(::game& ctx):
// Create mating swarm
swarm_eid = create_ant_swarm(ctx);
// Load name pools
female_name_pool = ctx.resource_manager->load<text_file>("female-names-en.txt");
male_name_pool = ctx.resource_manager->load<text_file>("male-names-en.txt");
// Load name pool
name_pool = ctx.resource_manager->load<text_file>("name-pool-en.txt");
// Assign random ant names
std::uniform_int_distribution<> female_name_pool_distribution(0, static_cast<int>(female_name_pool->lines.size() - 1));
std::uniform_int_distribution<> male_name_pool_distribution(0, static_cast<int>(male_name_pool->lines.size() - 1));
std::uniform_int_distribution<> name_pool_distribution(0, static_cast<int>(name_pool->lines.size() - 1));
ctx.entity_registry->view<ant_caste_component>().each
(
[&](entity::id entity_id, const auto& caste)
{
if (caste.caste_type == ant_caste_type::male)
{
ctx.entity_registry->emplace_or_replace<name_component>
(
entity_id,
male_name_pool->lines[male_name_pool_distribution(ctx.rng)]
);
}
else
{
ctx.entity_registry->emplace_or_replace<name_component>
(
entity_id,
female_name_pool->lines[female_name_pool_distribution(ctx.rng)]
);
}
ctx.entity_registry->emplace_or_replace<name_component>
(
entity_id,
name_pool->lines[name_pool_distribution(ctx.rng)]
);
}
);
@ -189,7 +176,6 @@ nuptial_flight_state::nuptial_flight_state(::game& ctx):
(
[&ctx]()
{
::enable_keeper_controls(ctx);
::enable_game_controls(ctx);
}

+ 1
- 2
src/game/states/nuptial-flight-state.hpp View File

@ -72,8 +72,7 @@ private:
entity::id swarm_eid;
// Name generation
std::shared_ptr<text_file> female_name_pool;
std::shared_ptr<text_file> male_name_pool;
std::shared_ptr<text_file> name_pool;
// Picking
std::uint32_t selected_picking_flag;

Loading…
Cancel
Save