Browse Source

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

master
C. J. Howard 11 months 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