💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

397 lines
9.0 KiB

/*
* 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/controls.hpp"
#include "game/components/orbit-camera-component.hpp"
#include <engine/debug/log.hpp>
namespace {
/*
void orbit_camera(::game& ctx, float yaw_factor, float pitch_factor)
{
if (ctx.active_camera_eid == entt::null)
{
return;
}
auto& orbit_cam = ctx.entity_registry->get<orbit_camera_component>(ctx.active_camera_eid);
// Adjust yaw and pitch angles according to mouse motion
orbit_cam.yaw -= ctx.mouse_pan_factor * static_cast<double>(event.difference.x());
orbit_cam.pitch += ctx.mouse_tilt_factor * static_cast<double>(event.difference.y());
// Limit pitch
orbit_cam.pitch = std::min(math::half_pi<double>, std::max(-math::half_pi<double>, orbit_cam.pitch));
}
*/
void handle_mouse_motion(::game& ctx, const input::mouse_moved_event& event)
{
if (ctx.active_camera_eid == entt::null)
{
return;
}
auto& orbit_cam = ctx.entity_registry->get<orbit_camera_component>(ctx.active_camera_eid);
// Rotate camera
if (ctx.camera_mouse_look_action.is_active())
{
// Adjust yaw and pitch angles according to mouse motion
orbit_cam.yaw -= ctx.mouse_pan_factor * static_cast<double>(event.difference.x());
orbit_cam.pitch += ctx.mouse_tilt_factor * static_cast<double>(event.difference.y());
// Limit pitch
orbit_cam.pitch = std::min(math::half_pi<double>, std::max(-math::half_pi<double>, orbit_cam.pitch));
}
// Zoom camera
if (ctx.camera_mouse_zoom_action.is_active())
{
// Adjust zoom factor
orbit_cam.zoom -= static_cast<double>(event.difference.y()) / static_cast<double>(ctx.window->get_viewport_size().y());
// Limit zoom factor
orbit_cam.zoom = std::min<double>(std::max<double>(orbit_cam.zoom, 0.0), 1.0);
}
}
void load_camera_preset(::game& ctx,std::uint8_t index)
{
}
void save_camera_preset(::game& ctx,std::uint8_t index)
{
}
void step_camera_zoom(::game& ctx, double scale)
{
if (ctx.active_camera_eid == entt::null)
{
return;
}
auto& orbit_cam = ctx.entity_registry->get<orbit_camera_component>(ctx.active_camera_eid);
// Step zoom factor
constexpr double zoom_step = 1.0 / 6.0;
orbit_cam.zoom += zoom_step * scale;
// Limit zoom factor
orbit_cam.zoom = std::min<double>(std::max<double>(orbit_cam.zoom, 0.0), 1.0);
}
void update_relative_mouse_mode(::game& ctx)
{
if (ctx.camera_mouse_look_action.is_active() ||
ctx.camera_mouse_drag_action.is_active() ||
ctx.camera_mouse_zoom_action.is_active())
{
ctx.input_manager->set_relative_mouse_mode(true);
}
else
{
ctx.input_manager->set_relative_mouse_mode(false);
}
}
void load_or_save_camera_preset(::game& ctx, std::uint8_t index)
{
if (ctx.camera_save_preset_action.is_active())
{
save_camera_preset(ctx, index);
}
else
{
load_camera_preset(ctx, index);
}
}
}
void setup_camera_controls(::game& ctx)
{
// Camera mouse motion
ctx.event_subscriptions.emplace_back
(
ctx.input_manager->get_event_dispatcher().subscribe<input::mouse_moved_event>
(
[&](const auto& event)
{
if (ctx.camera_action_map.is_enabled())
{
handle_mouse_motion(ctx, event);
}
}
)
);
// Camera mouse pick
ctx.event_subscriptions.emplace_back
(
ctx.camera_mouse_pick_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
}
)
);
// Camera mouse look
ctx.event_subscriptions.emplace_back
(
ctx.camera_mouse_look_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
update_relative_mouse_mode(ctx);
}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_mouse_look_action.get_deactivated_channel().subscribe
(
[&](const auto& event)
{
update_relative_mouse_mode(ctx);
}
)
);
// Camera mouse drag
ctx.event_subscriptions.emplace_back
(
ctx.camera_mouse_drag_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
update_relative_mouse_mode(ctx);
/*
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);
*/
}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_mouse_drag_action.get_deactivated_channel().subscribe
(
[&](const auto& event)
{
update_relative_mouse_mode(ctx);
}
)
);
// Camera mouse zoom
ctx.event_subscriptions.emplace_back
(
ctx.camera_mouse_zoom_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
update_relative_mouse_mode(ctx);
}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_mouse_zoom_action.get_deactivated_channel().subscribe
(
[&](const auto& event)
{
update_relative_mouse_mode(ctx);
}
)
);
// Camera zoom in
ctx.event_subscriptions.emplace_back
(
ctx.camera_zoom_in_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
step_camera_zoom(ctx, 1.0 * static_cast<double>(ctx.camera_zoom_in_action.get_input_value()));
}
)
);
// Camera zoom out
ctx.event_subscriptions.emplace_back
(
ctx.camera_zoom_out_action.get_activated_channel().subscribe
(
[&](const auto& event)
{
step_camera_zoom(ctx, -1.0 * static_cast<double>(ctx.camera_zoom_out_action.get_input_value()));
}
)
);
// Camera orbit left
ctx.event_subscriptions.emplace_back
(
ctx.camera_orbit_left_action.get_active_channel().subscribe
(
[&](const auto& event)
{
}
)
);
// Camera orbit right
ctx.event_subscriptions.emplace_back
(
ctx.camera_orbit_right_action.get_active_channel().subscribe
(
[&](const auto& event)
{
}
)
);
// Camera orbit up
ctx.event_subscriptions.emplace_back
(
ctx.camera_orbit_up_action.get_active_channel().subscribe
(
[&](const auto& event)
{
}
)
);
// Camera orbit down
ctx.event_subscriptions.emplace_back
(
ctx.camera_orbit_down_action.get_active_channel().subscribe
(
[&](const auto& event)
{
}
)
);
// Camera presets
ctx.event_subscriptions.emplace_back
(
ctx.camera_preset_1_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(ctx, 0);}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_preset_2_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(ctx, 1);}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_preset_3_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(ctx, 2);}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_preset_4_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(ctx, 3);}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_preset_5_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(ctx, 4);}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_preset_6_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(ctx, 5);}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_preset_7_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(ctx, 6);}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_preset_8_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(ctx, 7);}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_preset_9_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(ctx, 8);}
)
);
ctx.event_subscriptions.emplace_back
(
ctx.camera_preset_10_action.get_activated_channel().subscribe
(
[&](const auto& event) {load_or_save_camera_preset(ctx, 9);}
)
);
}
void enable_camera_controls(::game& ctx)
{
ctx.camera_action_map.enable();
}
void disable_camera_controls(::game& ctx)
{
ctx.camera_action_map.disable();
ctx.camera_action_map.reset();
}