From 76291c56129965bdef4987f740b6356d854a7de9 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Mon, 27 Sep 2021 10:58:44 +0800 Subject: [PATCH] Add more constraints and constraint and control callback-based camera controls --- src/animation/orbit-cam.cpp | 2 +- src/application.cpp | 1 + src/entity/commands.cpp | 24 +- src/entity/commands.hpp | 3 +- src/entity/components/camera.hpp | 6 +- src/entity/components/chamber.hpp | 19 +- src/entity/components/constraint-stack.hpp | 61 +++ .../constraints.hpp} | 19 +- .../{ => constraints}/copy-rotation.hpp | 12 +- .../{ => constraints}/copy-scale.hpp | 24 +- .../{ => constraints}/copy-transform.hpp | 12 +- .../constraints/copy-translation.hpp | 63 +++ .../components/constraints/spring-to.hpp | 56 +++ .../components/constraints/three-dof.hpp | 46 +++ .../track-to.hpp} | 24 +- src/entity/systems/camera.cpp | 88 +--- src/entity/systems/camera.hpp | 42 +- src/entity/systems/constraint.cpp | 216 +++++++--- src/entity/systems/constraint.hpp | 20 + src/entity/systems/control.cpp | 45 +- src/entity/systems/control.hpp | 39 -- src/entity/systems/render.cpp | 16 + src/game/bootloader.cpp | 172 +++----- src/game/context.hpp | 18 +- src/game/states/brood.cpp | 388 ++++++++++++++++-- src/game/states/forage.cpp | 17 - src/game/states/nuptial-flight.cpp | 16 - src/input/control.cpp | 11 + src/input/control.hpp | 4 + src/input/event-router.cpp | 16 +- 30 files changed, 998 insertions(+), 482 deletions(-) create mode 100644 src/entity/components/constraint-stack.hpp rename src/entity/components/{camera-follow.hpp => constraints/constraints.hpp} (68%) rename src/entity/components/{ => constraints}/copy-rotation.hpp (74%) rename src/entity/components/{ => constraints}/copy-scale.hpp (69%) rename src/entity/components/{ => constraints}/copy-transform.hpp (74%) create mode 100644 src/entity/components/constraints/copy-translation.hpp create mode 100644 src/entity/components/constraints/spring-to.hpp create mode 100644 src/entity/components/constraints/three-dof.hpp rename src/entity/components/{copy-translation.hpp => constraints/track-to.hpp} (69%) diff --git a/src/animation/orbit-cam.cpp b/src/animation/orbit-cam.cpp index 898371c..729b4f2 100644 --- a/src/animation/orbit-cam.cpp +++ b/src/animation/orbit-cam.cpp @@ -74,7 +74,7 @@ void orbit_cam::update(float dt) float fov = math::log_lerp(fov_limits[1], fov_limits[0], zoom_spring.x0); float clip_near = math::log_lerp(clip_near_limits[1], clip_near_limits[0], zoom_spring.x0); float clip_far = math::log_lerp(clip_far_limits[1], clip_far_limits[0], zoom_spring.x0); - + // Calculate camera transform transform_type transform = math::identity_transform; diff --git a/src/application.cpp b/src/application.cpp index 21f7c16..2499e98 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -537,6 +537,7 @@ void application::translate_sdl_events() case SDL_MOUSEMOTION: { + /// @WARNING: more than one mouse motion event is often generated per frame and may be a source of lag. mouse->move(sdl_event.motion.x, sdl_event.motion.y, sdl_event.motion.xrel, sdl_event.motion.yrel); break; } diff --git a/src/entity/commands.cpp b/src/entity/commands.cpp index efddcf9..5111658 100644 --- a/src/entity/commands.cpp +++ b/src/entity/commands.cpp @@ -20,7 +20,6 @@ #include "entity/commands.hpp" #include "entity/components/model.hpp" #include "entity/components/transform.hpp" -#include "entity/components/copy-transform.hpp" #include "entity/components/snap.hpp" #include "entity/components/parent.hpp" #include "entity/components/celestial-body.hpp" @@ -40,6 +39,15 @@ void translate(entity::registry& registry, entity::id eid, const float3& transla } } +void rotate(entity::registry& registry, entity::id eid, float angle, const float3& axis) +{ + if (registry.has(eid)) + { + component::transform& transform = registry.get(eid); + transform.local.rotation = math::angle_axis(angle, axis) * transform.local.rotation; + } +} + void move_to(entity::registry& registry, entity::id eid, const float3& position) { if (registry.has(eid)) @@ -128,12 +136,6 @@ void assign_render_layers(entity::registry& registry, entity::id eid, unsigned i } } -void bind_transform(entity::registry& registry, entity::id source, entity::id target) -{ - component::copy_transform copy_transform = {target}; - registry.assign_or_replace(source, copy_transform); -} - math::transform get_local_transform(entity::registry& registry, entity::id eid) { if (registry.has(eid)) @@ -193,5 +195,13 @@ entity::id create(entity::registry& registry, const std::string& name) return eid; } +entity::id find_or_create(entity::registry& registry, const std::string& name) +{ + entity::id eid = find(registry, name); + if (eid == entt::null) + eid = create(registry, name); + return eid; +} + } // namespace command } // namespace entity diff --git a/src/entity/commands.hpp b/src/entity/commands.hpp index 913bb6f..1d63fdd 100644 --- a/src/entity/commands.hpp +++ b/src/entity/commands.hpp @@ -31,13 +31,13 @@ namespace entity { namespace command { void translate(entity::registry& registry, entity::id eid, const float3& translation); +void rotate(entity::registry& registry, entity::id eid, float angle, const float3& axis); void move_to(entity::registry& registry, entity::id eid, const float3& position); void warp_to(entity::registry& registry, entity::id eid, const float3& position); void set_scale(entity::registry& registry, entity::id eid, const float3& scale); void set_transform(entity::registry& registry, entity::id eid, const math::transform& transform, bool warp = false); void place(entity::registry& registry, entity::id eid, entity::id celestial_body_id, double altitude, double latitude, double longitude); void assign_render_layers(entity::registry& registry, entity::id eid, unsigned int layers); -void bind_transform(entity::registry& registry, entity::id source_eid, entity::id target_eid); math::transform get_local_transform(entity::registry& registry, entity::id eid); math::transform get_world_transform(entity::registry& registry, entity::id eid); void parent(entity::registry& registry, entity::id child, entity::id parent); @@ -46,6 +46,7 @@ void rename(entity::registry& registry, entity::id eid, const std::string& name) entity::id find(entity::registry& registry, const std::string& name); entity::id create(entity::registry& registry); entity::id create(entity::registry& registry, const std::string& name); +entity::id find_or_create(entity::registry& registry, const std::string& name); } // namespace command } // namespace entity diff --git a/src/entity/components/camera.hpp b/src/entity/components/camera.hpp index 0d2fd83..284c4dd 100644 --- a/src/entity/components/camera.hpp +++ b/src/entity/components/camera.hpp @@ -25,9 +25,11 @@ namespace entity { namespace component { -struct flight_controller +/// Camera scene object component. +struct camera { - + /// Pointer to camera scene object + scene::camera* object; }; } // namespace component diff --git a/src/entity/components/chamber.hpp b/src/entity/components/chamber.hpp index 72b61a1..dc6062d 100644 --- a/src/entity/components/chamber.hpp +++ b/src/entity/components/chamber.hpp @@ -27,16 +27,27 @@ namespace entity { namespace component { +/// Ant nest chamber. struct chamber { - entity nest; - float depth; + /// Entity ID of shaft to which the chamber is connected + entity::id shaft_eid; + + /// Distance along shaft at which the chamber is located + float distance; + + /// Entity ID of the chamber above this chamber + entity::id previous_chamber_eid; + + /// Entity ID of the chamber below this chamber + entity::id next_chamber_eid; + float outer_radius; float inner_radius; float inner_sector_angle; float tile_radius; - std::unordered_set> tiles; -} + //std::unordered_set> tiles; +}; } // namespace component } // namespace entity diff --git a/src/entity/components/constraint-stack.hpp b/src/entity/components/constraint-stack.hpp new file mode 100644 index 0000000..0e4da8a --- /dev/null +++ b/src/entity/components/constraint-stack.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_STACK_HPP +#define ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_STACK_HPP + +#include "entity/id.hpp" + +namespace entity { +namespace component { + +/** + * Causes an ordered stack of constraints to be applied to an entity. + * + * @see entity::component::constraint_stack_node + * @see entity::component::constraint + */ +struct constraint_stack +{ + /// ID of the entity containing the first constraint stack node. + entity::id head; +}; + +/** + * Single node in a constraint stack. Allows toggling and weighing of constraints and links to the following constraint stack node (if any). + * + * @see entity::component::constraint_stack + * @see entity::component::constraint + */ +struct constraint_stack_node +{ + /// Enables or disables the constraint. + bool active; + + /// Controls the amount of influence the constraint has on the final result. + float weight; + + /// ID of the entity containing the next constraint in the constraint stack. + entity::id next; +}; + +} // namespace component +} // namespace entity + +#endif // ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_STACK_HPP diff --git a/src/entity/components/camera-follow.hpp b/src/entity/components/constraints/constraints.hpp similarity index 68% rename from src/entity/components/camera-follow.hpp rename to src/entity/components/constraints/constraints.hpp index 472a696..6269671 100644 --- a/src/entity/components/camera-follow.hpp +++ b/src/entity/components/constraints/constraints.hpp @@ -17,19 +17,24 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_ENTITY_COMPONENT_CAMERA_FOLLOW_HPP -#define ANTKEEPER_ENTITY_COMPONENT_CAMERA_FOLLOW_HPP +#ifndef ANTKEEPER_ENTITY_COMPONENT_CONSTRAINTS_HPP +#define ANTKEEPER_ENTITY_COMPONENT_CONSTRAINTS_HPP namespace entity { namespace component { -struct camera_follow -{ - -}; +/// Transform constraint components +namespace constraint {} } // namespace component } // namespace entity -#endif // ANTKEEPER_ENTITY_COMPONENT_CAMERA_FOLLOW_HPP +#include "copy-translation.hpp" +#include "copy-rotation.hpp" +#include "copy-scale.hpp" +#include "copy-transform.hpp" +#include "track-to.hpp" +#include "spring-to.hpp" +#include "three-dof.hpp" +#endif // ANTKEEPER_ENTITY_COMPONENT_CONSTRAINTS_HPP diff --git a/src/entity/components/copy-rotation.hpp b/src/entity/components/constraints/copy-rotation.hpp similarity index 74% rename from src/entity/components/copy-rotation.hpp rename to src/entity/components/constraints/copy-rotation.hpp index 24df146..b82785e 100644 --- a/src/entity/components/copy-rotation.hpp +++ b/src/entity/components/constraints/copy-rotation.hpp @@ -17,20 +17,26 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_ENTITY_COMPONENT_COPY_ROTATION_HPP -#define ANTKEEPER_ENTITY_COMPONENT_COPY_ROTATION_HPP +#ifndef ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_ROTATION_HPP +#define ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_ROTATION_HPP #include "entity/id.hpp" namespace entity { namespace component { +namespace constraint { +/** + * Copies the rotation of a target entity. + */ struct copy_rotation { + /// Target entity ID. entity::id target; }; +} // namespace constraint } // namespace component } // namespace entity -#endif // ANTKEEPER_ENTITY_COMPONENT_COPY_ROTATION_HPP +#endif // ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_ROTATION_HPP diff --git a/src/entity/components/copy-scale.hpp b/src/entity/components/constraints/copy-scale.hpp similarity index 69% rename from src/entity/components/copy-scale.hpp rename to src/entity/components/constraints/copy-scale.hpp index 438739e..74dfb0c 100644 --- a/src/entity/components/copy-scale.hpp +++ b/src/entity/components/constraints/copy-scale.hpp @@ -17,23 +17,35 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_ENTITY_COMPONENT_COPY_SCALE_HPP -#define ANTKEEPER_ENTITY_COMPONENT_COPY_SCALE_HPP +#ifndef ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_SCALE_HPP +#define ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_SCALE_HPP #include "entity/id.hpp" namespace entity { namespace component { +namespace constraint { +/** + * Copies the scale of a target entity. + */ struct copy_scale { + /// Target entity ID. entity::id target; - bool use_x; - bool use_y; - bool use_z; + + /// Copy X scale. + bool copy_x; + + /// Copy Y scale. + bool copy_y; + + /// Copy Z scale. + bool copy_z; }; +} // namespace constraint } // namespace component } // namespace entity -#endif // ANTKEEPER_ENTITY_COMPONENT_COPY_SCALE_HPP +#endif // ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_SCALE_HPP diff --git a/src/entity/components/copy-transform.hpp b/src/entity/components/constraints/copy-transform.hpp similarity index 74% rename from src/entity/components/copy-transform.hpp rename to src/entity/components/constraints/copy-transform.hpp index 0fc753f..74f6719 100644 --- a/src/entity/components/copy-transform.hpp +++ b/src/entity/components/constraints/copy-transform.hpp @@ -17,20 +17,26 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_ENTITY_COMPONENT_COPY_TRANSFORM_HPP -#define ANTKEEPER_ENTITY_COMPONENT_COPY_TRANSFORM_HPP +#ifndef ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_TRANSFORM_HPP +#define ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_TRANSFORM_HPP #include "entity/id.hpp" namespace entity { namespace component { +namespace constraint { +/** + * Copies the transform of a target entity. + */ struct copy_transform { + /// Target entity ID. entity::id target; }; +} // namespace constraint } // namespace component } // namespace entity -#endif // ANTKEEPER_ENTITY_COMPONENT_COPY_TRANSFORM_HPP +#endif // ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_TRANSFORM_HPP diff --git a/src/entity/components/constraints/copy-translation.hpp b/src/entity/components/constraints/copy-translation.hpp new file mode 100644 index 0000000..b642880 --- /dev/null +++ b/src/entity/components/constraints/copy-translation.hpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_TRANSLATION_HPP +#define ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_TRANSLATION_HPP + +#include "entity/id.hpp" + +namespace entity { +namespace component { +namespace constraint { + +/** + * Copies the translation of a target entity. + */ +struct copy_translation +{ + /// Target entity ID. + entity::id target; + + /// Copy X translation. + bool copy_x; + + /// Copy Y translation. + bool copy_y; + + /// Copy Z translation. + bool copy_z; + + /// Invert the copied X translation. + bool invert_x; + + /// Invert the copied Y translation. + bool invert_y; + + /// Invert the copied Z translation. + bool invert_z; + + /// Add the copied translation. + bool offset; +}; + +} // namespace constraint +} // namespace component +} // namespace entity + +#endif // ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_COPY_TRANSLATION_HPP diff --git a/src/entity/components/constraints/spring-to.hpp b/src/entity/components/constraints/spring-to.hpp new file mode 100644 index 0000000..716e08a --- /dev/null +++ b/src/entity/components/constraints/spring-to.hpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_SPRING_TO_HPP +#define ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_SPRING_TO_HPP + +#include "entity/id.hpp" +#include "animation/spring.hpp" +#include "utility/fundamental-types.hpp" + +namespace entity { +namespace component { +namespace constraint { + +/** + * Springs to a target entity. + */ +struct spring_to +{ + /// Target entity ID. + entity::id target; + + /// Translation spring. + numeric_spring translation; + + /// Rotation spring. + numeric_spring rotation; + + /// Spring translation. + bool spring_translation; + + /// Spring rotation. + bool spring_rotation; +}; + +} // namespace constraint +} // namespace component +} // namespace entity + +#endif // ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_SPRING_TO_HPP diff --git a/src/entity/components/constraints/three-dof.hpp b/src/entity/components/constraints/three-dof.hpp new file mode 100644 index 0000000..6fcad80 --- /dev/null +++ b/src/entity/components/constraints/three-dof.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_THREE_DOF_HPP +#define ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_THREE_DOF_HPP + +namespace entity { +namespace component { +namespace constraint { + +/** + * Springs to a target entity. + */ +struct three_dof +{ + /// Yaw rotation angle, in radians. + float yaw; + + /// Pitch rotation angle, in radians. + float pitch; + + /// Roll rotation angle, in radians. + float roll; +}; + +} // namespace constraint +} // namespace component +} // namespace entity + +#endif // ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_THREE_DOF_HPP diff --git a/src/entity/components/copy-translation.hpp b/src/entity/components/constraints/track-to.hpp similarity index 69% rename from src/entity/components/copy-translation.hpp rename to src/entity/components/constraints/track-to.hpp index fd00d8d..60a89f9 100644 --- a/src/entity/components/copy-translation.hpp +++ b/src/entity/components/constraints/track-to.hpp @@ -17,26 +17,30 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_ENTITY_COMPONENT_COPY_TRANSLATION_HPP -#define ANTKEEPER_ENTITY_COMPONENT_COPY_TRANSLATION_HPP +#ifndef ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_TRACK_TO_HPP +#define ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_TRACK_TO_HPP #include "entity/id.hpp" +#include "utility/fundamental-types.hpp" namespace entity { namespace component { +namespace constraint { -struct copy_translation +/** + * Rotates a transform to face a target. + */ +struct track_to { + /// Target entity ID. entity::id target; - bool use_x; - bool use_y; - bool use_z; - bool invert_x; - bool invert_y; - bool invert_z; + + /// Up direction vector. + float3 up; }; +} // namespace constraint } // namespace component } // namespace entity -#endif // ANTKEEPER_ENTITY_COMPONENT_COPY_TRANSLATION_HPP +#endif // ANTKEEPER_ENTITY_COMPONENT_CONSTRAINT_TRACK_TO_HPP diff --git a/src/entity/systems/camera.cpp b/src/entity/systems/camera.cpp index 260b36b..2882b4f 100644 --- a/src/entity/systems/camera.cpp +++ b/src/entity/systems/camera.cpp @@ -18,107 +18,23 @@ */ #include "camera.hpp" -#include "entity/components/camera-follow.hpp" -#include "entity/components/transform.hpp" -#include "entity/id.hpp" -#include "math/math.hpp" -#include -#include namespace entity { namespace system { camera::camera(entity::registry& registry): updatable(registry), - active_camera(nullptr), - viewport{0, 0, 0, 0}, - mouse_position{0, 0} -{ - //orbit_cam.set_elevation_limits({math::radians(5.0f), math::radians(89.0f)}); - orbit_cam.set_elevation_limits({math::radians(-89.0f), math::radians(89.0f)}); - orbit_cam.set_focal_distance_limits({2.0f, 200.0f}); - orbit_cam.set_fov_limits({math::radians(80.0f), math::radians(35.0f)}); - orbit_cam.set_clip_near_limits({0.1f, 5.0f}); - orbit_cam.set_clip_far_limits({100.0f, 5000.0f}); - - orbit_cam.set_target_focal_point({0.0f, 0.0f, 0.0f}); - orbit_cam.set_target_azimuth(0.0f); - orbit_cam.set_target_elevation(math::radians(45.0f)); - orbit_cam.set_target_zoom(0.0f); - - orbit_cam.set_focal_point_oscillation(hz_to_rads(8.0f)); - orbit_cam.set_azimuth_oscillation(hz_to_rads(2.0f)); - orbit_cam.set_elevation_oscillation(hz_to_rads(2.0f)); - orbit_cam.set_zoom_oscillation(hz_to_rads(5.0f)); - - orbit_cam.reset_springs(); -} + viewport{0, 0, 0, 0} +{} void camera::update(double t, double dt) { - if (!active_camera) - return; - - // Determine target focal point - int subject_count = 0; - float3 target_focal_point = {0, 0, 0}; - registry.view().each( - [&](entity::id entity_id, auto& follow, auto& transform) - { - target_focal_point += transform.local.translation; - ++subject_count; - }); - if (subject_count > 1) - target_focal_point /= static_cast(subject_count); - - // Focus at ant's head height off the ground. - target_focal_point.y += 0.2f; - - // Check for collision with environment - //... - - orbit_cam.set_target_focal_point(target_focal_point); - orbit_cam.update(static_cast(dt)); -} - -void camera::pan(float angle) -{ - orbit_cam.pan(angle); -} - -void camera::tilt(float angle) -{ - orbit_cam.tilt(angle); -} - -void camera::zoom(float factor) -{ - orbit_cam.zoom(factor); -} -void camera::set_camera(scene::camera* active_camera) -{ - this->active_camera = active_camera; - if (active_camera) - { - orbit_cam.attach(active_camera); - } - else - { - orbit_cam.detach(); - } } void camera::set_viewport(const float4& viewport) { this->viewport = viewport; - orbit_cam.set_aspect_ratio(viewport[2] / viewport[3]); -} - -void camera::handle_event(const mouse_moved_event& event) -{ - mouse_position[0] = event.x; - mouse_position[1] = event.y; } void camera::handle_event(const window_resized_event& event) diff --git a/src/entity/systems/camera.hpp b/src/entity/systems/camera.hpp index 9d5e172..1cdb9fe 100644 --- a/src/entity/systems/camera.hpp +++ b/src/entity/systems/camera.hpp @@ -25,66 +25,26 @@ #include "event/input-events.hpp" #include "event/window-events.hpp" #include "utility/fundamental-types.hpp" -#include "math/quaternion-type.hpp" -#include "math/transform-type.hpp" -#include "animation/orbit-cam.hpp" -#include "scene/camera.hpp" - -class orbit_cam; namespace entity { namespace system { class camera: public updatable, - public event_handler, public event_handler { public: - typedef math::quaternion quaternion_type; - typedef math::transform transform_type; - camera(entity::registry& registry); virtual void update(double t, double dt); - void pan(float angle); - void tilt(float angle); - void zoom(float factor); - - void set_camera(scene::camera* active_camera); void set_viewport(const float4& viewport); - - const orbit_cam* get_orbit_cam() const; - orbit_cam* get_orbit_cam(); - - scene::camera* get_camera(); private: - virtual void handle_event(const mouse_moved_event& event); virtual void handle_event(const window_resized_event& event); - - scene::camera* active_camera; - float4 viewport; - float2 mouse_position; - orbit_cam orbit_cam; + float4 viewport; }; -inline const orbit_cam* camera::get_orbit_cam() const -{ - return &orbit_cam; -} - -inline orbit_cam* camera::get_orbit_cam() -{ - return &orbit_cam; -} - -inline scene::camera* camera::get_camera() -{ - return active_camera; -} - } // namespace system } // namespace entity diff --git a/src/entity/systems/constraint.cpp b/src/entity/systems/constraint.cpp index a025b03..371977a 100644 --- a/src/entity/systems/constraint.cpp +++ b/src/entity/systems/constraint.cpp @@ -18,12 +18,9 @@ */ #include "constraint.hpp" -#include "entity/components/copy-translation.hpp" -#include "entity/components/copy-rotation.hpp" -#include "entity/components/copy-scale.hpp" -#include "entity/components/copy-transform.hpp" +#include "entity/components/constraint-stack.hpp" +#include "entity/components/constraints/constraints.hpp" #include "entity/components/transform.hpp" -#include "utility/fundamental-types.hpp" namespace entity { namespace system { @@ -34,67 +31,176 @@ constraint::constraint(entity::registry& registry): void constraint::update(double t, double dt) { - auto transforms_view = registry.view(); - - // Handle copy translation constraints - registry.view().each - ( - [&](entity::id entity_id, auto& constraint, auto& transform) + // For each entity with transform and constraint stack components + registry.view().each( + [&](entity::id transform_eid, auto& transform, auto& stack) { - if (this->registry.has(constraint.target)) + // Get entity ID of first constraint + entity::id constraint_eid = stack.head; + + // Consecutively apply constraints + while (constraint_eid != entt::null) { - const float3& target_translation = transforms_view.get(constraint.target).world.translation; - if (constraint.use_x) - transform.world.translation.x = (constraint.invert_x) ? -target_translation.x : target_translation.x; - if (constraint.use_y) - transform.world.translation.y = (constraint.invert_y) ? -target_translation.y : target_translation.y; - if (constraint.use_z) - transform.world.translation.z = (constraint.invert_z) ? -target_translation.z : target_translation.z; + // Invalid constraint + if (!registry.has(constraint_eid)) + break; + + // Get constraint stack node of this constraint + const auto& node = registry.get(constraint_eid); + + // Apply constraint if enabled + if (node.active) + handle_constraint(transform, constraint_eid, static_cast(dt)); + + // Get entity ID of next constraint + constraint_eid = node.next; } - } - ); + }); +} + +void constraint::handle_constraint(component::transform& transform, entity::id constraint_eid, float dt) +{ + if (registry.has(constraint_eid)) + handle_copy_translation_constraint(transform, constraint_eid); + else if (registry.has(constraint_eid)) + handle_copy_rotation_constraint(transform, constraint_eid); + else if (registry.has(constraint_eid)) + handle_copy_scale_constraint(transform, constraint_eid); + else if (registry.has(constraint_eid)) + handle_copy_transform_constraint(transform, constraint_eid); + else if (registry.has(constraint_eid)) + handle_track_to_constraint(transform, constraint_eid); + else if (registry.has(constraint_eid)) + handle_three_dof_constraint(transform, constraint_eid); + else if (registry.has(constraint_eid)) + handle_spring_to_constraint(transform, constraint_eid, dt); +} + +void constraint::handle_copy_translation_constraint(component::transform& transform, entity::id constraint_eid) +{ + const auto& params = registry.get(constraint_eid); - // Handle copy rotation constraints - registry.view().each - ( - [&](entity::id entity_id, auto& constraint, auto& transform) + if (this->registry.has(params.target)) + { + const auto& target_translation = registry.get(params.target).world.translation; + + if (params.offset) { - if (this->registry.has(constraint.target)) - { - transform.world.rotation = transforms_view.get(constraint.target).world.rotation; - } + if (params.copy_x) + transform.world.translation.x += (params.invert_x) ? -target_translation.x : target_translation.x; + if (params.copy_y) + transform.world.translation.y += (params.invert_y) ? -target_translation.y : target_translation.y; + if (params.copy_z) + transform.world.translation.z += (params.invert_z) ? -target_translation.z : target_translation.z; } - ); - - // Handle copy scale constraints - registry.view().each - ( - [&](entity::id entity_id, auto& constraint, auto& transform) + else { - if (this->registry.has(constraint.target)) - { - const float3& target_scale = transforms_view.get(constraint.target).world.scale; - if (constraint.use_x) - transform.world.scale.x = target_scale.x; - if (constraint.use_y) - transform.world.scale.y = target_scale.y; - if (constraint.use_z) - transform.world.scale.z = target_scale.z; - } + if (params.copy_x) + transform.world.translation.x = (params.invert_x) ? -target_translation.x : target_translation.x; + if (params.copy_y) + transform.world.translation.y = (params.invert_y) ? -target_translation.y : target_translation.y; + if (params.copy_z) + transform.world.translation.z = (params.invert_z) ? -target_translation.z : target_translation.z; } - ); + + } +} + +void constraint::handle_copy_rotation_constraint(component::transform& transform, entity::id constraint_eid) +{ + const auto& params = registry.get(constraint_eid); + + if (this->registry.has(params.target)) + { + const auto& target_rotation = registry.get(params.target).world.rotation; + transform.world.rotation = target_rotation; + } +} + +void constraint::handle_copy_scale_constraint(component::transform& transform, entity::id constraint_eid) +{ + const auto& params = registry.get(constraint_eid); - // Handle copy transform constraints - registry.view().each - ( - [&](entity::id entity_id, auto& constraint, auto& transform) + if (this->registry.has(params.target)) + { + const auto& target_scale = registry.get(params.target).world.scale; + + if (params.copy_x) + transform.world.scale.x = target_scale.x; + if (params.copy_y) + transform.world.scale.y = target_scale.y; + if (params.copy_z) + transform.world.scale.z = target_scale.z; + } +} + +void constraint::handle_copy_transform_constraint(component::transform& transform, entity::id constraint_eid) +{ + const auto& params = registry.get(constraint_eid); + + if (this->registry.has(params.target)) + { + const auto& target_transform = registry.get(params.target).world; + transform.world = target_transform; + } +} + +void constraint::handle_track_to_constraint(component::transform& transform, entity::id constraint_eid) +{ + const auto& params = registry.get(constraint_eid); + + if (this->registry.has(params.target)) + { + const auto& target_transform = registry.get(params.target).world; + transform.world.rotation = math::look_rotation(math::normalize(math::sub(target_transform.translation, transform.world.translation)), params.up); + } +} + +void constraint::handle_three_dof_constraint(component::transform& transform, entity::id constraint_eid) +{ + const auto& params = registry.get(constraint_eid); + + const math::quaternion yaw = math::angle_axis(params.yaw, {0.0f, 1.0f, 0.0f}); + const math::quaternion pitch = math::angle_axis(params.pitch, {-1.0f, 0.0f, 0.0f}); + const math::quaternion roll = math::angle_axis(params.roll, {0.0f, 0.0f, -1.0f}); + transform.local.rotation = math::normalize(yaw * pitch * roll); +} + +void constraint::handle_spring_to_constraint(component::transform& transform, entity::id constraint_eid, float dt) +{ + auto& params = registry.get(constraint_eid); + + if (this->registry.has(params.target)) + { + // Get transform of target entity + const auto& target_transform = registry.get(params.target).world; + + // Spring translation + if (params.spring_translation) { - if (this->registry.has(constraint.target)) - { - transform.world = transforms_view.get(constraint.target).world; - } + // Update translation spring target + params.translation.x1 = target_transform.translation; + + // Solve translation spring + solve_numeric_spring(params.translation, dt); + + // Update transform translation + transform.world.translation = params.translation.x0; + } + + // Spring rotation + if (params.spring_rotation) + { + // Update rotation spring target + params.rotation.x1 = {target_transform.rotation.w, target_transform.rotation.x, target_transform.rotation.y, target_transform.rotation.z}; + + // Solve rotation spring + solve_numeric_spring(params.rotation, dt); + + // Update transform rotation + transform.world.rotation = math::normalize(math::quaternion{params.rotation.x0[0], params.rotation.x0[1], params.rotation.x0[2], params.rotation.x0[3]}); } - ); + } } } // namespace system diff --git a/src/entity/systems/constraint.hpp b/src/entity/systems/constraint.hpp index 24536c2..38731ef 100644 --- a/src/entity/systems/constraint.hpp +++ b/src/entity/systems/constraint.hpp @@ -21,16 +21,36 @@ #define ANTKEEPER_ENTITY_SYSTEM_CONSTRAINT_HPP #include "entity/systems/updatable.hpp" +#include "entity/components/transform.hpp" +#include "entity/id.hpp" namespace entity { namespace system { +/** + * Applies constraint stacks to transform components. + * + * @see entity::component::constraint_stack + * @see entity::component::constraint_stack_node + * @see entity::component::constraint + */ class constraint: public updatable { public: constraint(entity::registry& registry); virtual void update(double t, double dt); + +private: + void handle_constraint(component::transform& transform, entity::id constraint_eid, float dt); + + void handle_copy_translation_constraint(component::transform& transform, entity::id constraint_eid); + void handle_copy_rotation_constraint(component::transform& transform, entity::id constraint_eid); + void handle_copy_scale_constraint(component::transform& transform, entity::id constraint_eid); + void handle_copy_transform_constraint(component::transform& transform, entity::id constraint_eid); + void handle_track_to_constraint(component::transform& transform, entity::id constraint_eid); + void handle_three_dof_constraint(component::transform& transform, entity::id constraint_eid); + void handle_spring_to_constraint(component::transform& transform, entity::id constraint_eid, float dt); }; } // namespace system diff --git a/src/entity/systems/control.cpp b/src/entity/systems/control.cpp index d6a946d..563ac72 100644 --- a/src/entity/systems/control.cpp +++ b/src/entity/systems/control.cpp @@ -32,12 +32,7 @@ namespace entity { namespace system { control::control(entity::registry& registry): - updatable(registry), - timestep(0.0f), - zoom(0.0f), - tool(nullptr), - flashlight_entity(entt::null), - underground_camera(nullptr) + updatable(registry) { control_set.add_control(&move_forward_control); control_set.add_control(&move_back_control); @@ -74,6 +69,8 @@ control::control(entity::registry& registry): { control->set_deadzone(0.15f); } + + /* zoom_speed = 5.0f; //1 min_elevation = math::radians(-85.0f); @@ -96,11 +93,12 @@ control::control(entity::registry& registry): flashlight_turns = 0.0f; flashlight_turns_i = 0; flashlight_turns_f = 0.0f; + */ } void control::update(double t, double dt) { - timestep = dt; + /* // Zoom camera if (zoom_in_control.is_active()) @@ -192,31 +190,7 @@ void control::update(double t, double dt) } } } -} - -void control::set_camera_system(system::camera* camera_system) -{ - this->camera_system = camera_system; -} - -void control::set_nest(::nest* nest) -{ - this->nest = nest; -} - -void control::set_tool(scene::model_instance* tool) -{ - this->tool = tool; -} - -void control::set_flashlight(entity::id entity_id) -{ - flashlight_entity = entity_id; -} - -void control::set_camera_subject(entity::id entity_id) -{ - camera_subject_entity = entity_id; + */ } void control::set_viewport(const float4& viewport) @@ -224,13 +198,9 @@ void control::set_viewport(const float4& viewport) this->viewport = viewport; } -void control::set_underground_camera(scene::camera* camera) -{ - this->underground_camera = camera; -} - void control::handle_event(const mouse_moved_event& event) { + /* if (adjust_camera_control.is_active()) { bool invert_x = true; @@ -260,6 +230,7 @@ void control::handle_event(const mouse_moved_event& event) mouse_position[0] = event.x; mouse_position[1] = event.y; } + */ } void control::handle_event(const window_resized_event& event) diff --git a/src/entity/systems/control.hpp b/src/entity/systems/control.hpp index 1c0ad83..d6f0811 100644 --- a/src/entity/systems/control.hpp +++ b/src/entity/systems/control.hpp @@ -48,17 +48,7 @@ public: virtual void update(double t, double dt); - void set_invert_mouse_x(bool invert); - void set_invert_mouse_y(bool invert); - - void set_camera_system(system::camera* camera_system); - void set_nest(::nest* nest); - void set_tool(scene::model_instance* tool); - void set_flashlight(entity::id entity_id); - void set_camera_subject(entity::id entity_id); - void set_viewport(const float4& viewport); - void set_underground_camera(scene::camera* camera); input::control_set* get_control_set(); input::control* get_move_forward_control(); @@ -123,38 +113,9 @@ private: input::control rewind_control; input::control exposure_increase_control; input::control exposure_decrease_control; - - float zoom_speed; - float min_elevation; - float max_elevation; - float near_focal_distance; - float far_focal_distance; - float near_movement_speed; - float far_movement_speed; - float near_fov; - float far_fov; - float near_clip_near; - float far_clip_near; - float near_clip_far; - float far_clip_far; - float timestep; - float zoom; - system::camera* camera_system; - ::nest* nest; - scene::model_instance* tool; float2 mouse_position; float4 viewport; - - entity::id flashlight_entity; - entity::id camera_subject_entity; - scene::camera* underground_camera; - - float mouse_angle; - float old_mouse_angle; - float flashlight_turns; - float flashlight_turns_i; - float flashlight_turns_f; }; inline input::control_set* control::get_control_set() diff --git a/src/entity/systems/render.cpp b/src/entity/systems/render.cpp index 4757878..80679d4 100644 --- a/src/entity/systems/render.cpp +++ b/src/entity/systems/render.cpp @@ -19,6 +19,7 @@ #include "render.hpp" #include "entity/components/transform.hpp" +#include "entity/components/camera.hpp" #include "renderer/renderer.hpp" #include "scene/point-light.hpp" #include "scene/directional-light.hpp" @@ -61,6 +62,21 @@ void render::update(double t, double dt) } ); + // Update camera transforms + registry.view().each + ( + [this](entity::id entity_id, auto& transform, auto& camera) + { + camera.object->set_transform(transform.world); + if (transform.warp) + { + camera.object->get_transform_tween().update(); + camera.object->update_tweens(); + transform.warp = false; + } + } + ); + // Update light transforms registry.view().each ( diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp index 1db363f..9ebf4d6 100644 --- a/src/game/bootloader.cpp +++ b/src/game/bootloader.cpp @@ -375,7 +375,7 @@ void load_strings(game::context* ctx) { debug::logger* logger = ctx->logger; logger->push_task("Loading strings"); - + ctx->string_table = ctx->resource_manager->load("strings.csv"); build_string_table_map(&ctx->string_table_map, *ctx->string_table); @@ -815,13 +815,11 @@ void setup_systems(game::context* ctx) // Setup camera system ctx->camera_system = new entity::system::camera(*ctx->entity_registry); ctx->camera_system->set_viewport(viewport); - event_dispatcher->subscribe(ctx->camera_system); event_dispatcher->subscribe(ctx->camera_system); // Setup tool system ctx->tool_system = new entity::system::tool(*ctx->entity_registry, event_dispatcher); ctx->tool_system->set_camera(ctx->surface_camera); - ctx->tool_system->set_orbit_cam(ctx->camera_system->get_orbit_cam()); ctx->tool_system->set_viewport(viewport); // Setup subterrain system @@ -908,14 +906,8 @@ void setup_systems(game::context* ctx) // Setup control system ctx->control_system = new entity::system::control(*ctx->entity_registry); ctx->control_system->set_viewport(viewport); - ctx->control_system->set_underground_camera(ctx->underground_camera); - ctx->control_system->set_tool(nullptr); - //ctx->control_system->set_flashlight(flashlight, flashlight_light_cone); ctx->control_system->get_adjust_camera_control()->set_activated_callback([ctx](){ ctx->app->set_relative_mouse_mode(true); ctx->tool_system->set_pick(false); }); ctx->control_system->get_adjust_camera_control()->set_deactivated_callback([ctx](){ ctx->app->set_relative_mouse_mode(false); ctx->tool_system->set_pick(true); }); - ctx->control_system->set_flashlight(ctx->flashlight_entity); - ctx->control_system->set_camera_subject(ctx->focal_point_entity); - ctx->control_system->set_camera_system(ctx->camera_system); event_dispatcher->subscribe(ctx->control_system); event_dispatcher->subscribe(ctx->control_system); @@ -996,8 +988,23 @@ void setup_controls(game::context* ctx) ctx->menu_controls->add_control(ctx->menu_back_control); ctx->menu_controls->add_control(ctx->menu_select_control); - - + // Create camera controls + ctx->camera_control_modifier = new input::control(); + ctx->camera_control_mouse_left = new input::control(); + ctx->camera_control_mouse_right = new input::control(); + ctx->camera_control_mouse_down = new input::control(); + ctx->camera_control_mouse_up = new input::control(); + ctx->camera_control_orbit = new input::control(); + ctx->camera_control_dolly_forward = new input::control(); + ctx->camera_control_dolly_backward = new input::control(); + ctx->camera_control_truck_left = new input::control(); + ctx->camera_control_truck_right = new input::control(); + ctx->camera_control_pedestal_up = new input::control(); + ctx->camera_control_pedestal_down = new input::control(); + ctx->camera_control_pan_left = new input::control(); + ctx->camera_control_pan_right = new input::control(); + ctx->camera_control_tilt_up = new input::control(); + ctx->camera_control_tilt_down = new input::control(); ctx->camera_controls = ctx->control_system->get_control_set(); @@ -1009,7 +1016,7 @@ void setup_controls(game::context* ctx) ctx->input_event_router->add_mapping(input::key_mapping(ctx->menu_back_control, nullptr, input::scancode::escape)); ctx->input_event_router->add_mapping(input::key_mapping(ctx->menu_back_control, nullptr, input::scancode::backspace)); ctx->input_event_router->add_mapping(input::game_controller_button_mapping(ctx->menu_back_control, nullptr, input::game_controller_button::b)); - ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_tool_menu_control(), nullptr, input::scancode::left_shift)); + //ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_tool_menu_control(), nullptr, input::scancode::left_shift)); ctx->input_event_router->add_mapping(input::game_controller_button_mapping(ctx->control_system->get_tool_menu_control(), nullptr, input::game_controller_button::x)); ctx->input_event_router->add_mapping(input::key_mapping(ctx->menu_select_control, nullptr, input::scancode::enter)); ctx->input_event_router->add_mapping(input::key_mapping(ctx->menu_select_control, nullptr, input::scancode::space)); @@ -1066,7 +1073,7 @@ void setup_controls(game::context* ctx) ctx->input_event_router->add_mapping(input::game_controller_axis_mapping(ctx->control_system->get_tilt_down_control(), nullptr, input::game_controller_axis::right_y, true)); ctx->input_event_router->add_mapping(input::mouse_wheel_mapping(ctx->control_system->get_zoom_in_control(), nullptr, input::mouse_wheel_axis::positive_y)); ctx->input_event_router->add_mapping(input::mouse_wheel_mapping(ctx->control_system->get_zoom_out_control(), nullptr, input::mouse_wheel_axis::negative_y)); - ctx->input_event_router->add_mapping(input::mouse_button_mapping(ctx->control_system->get_adjust_camera_control(), nullptr, 3)); + //ctx->input_event_router->add_mapping(input::mouse_button_mapping(ctx->control_system->get_adjust_camera_control(), nullptr, 3)); ctx->input_event_router->add_mapping(input::game_controller_button_mapping(ctx->control_system->get_ascend_control(), nullptr, input::game_controller_button::y)); ctx->input_event_router->add_mapping(input::game_controller_button_mapping(ctx->control_system->get_descend_control(), nullptr, input::game_controller_button::a)); ctx->input_event_router->add_mapping(input::game_controller_axis_mapping(ctx->control_system->get_zoom_out_control(), nullptr, input::game_controller_axis::trigger_left, false)); @@ -1087,107 +1094,29 @@ void setup_controls(game::context* ctx) ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_equip_lens_control(), nullptr, input::scancode::five)); ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_equip_marker_control(), nullptr, input::scancode::six)); - //ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_next_marker_control(), nullptr, input::scancode::right_brace)); - //ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_previous_marker_control(), nullptr, input::scancode::left_brace)); - ctx->input_event_router->add_mapping(input::mouse_button_mapping(ctx->control_system->get_use_tool_control(), nullptr, 1)); - ctx->control_system->get_use_tool_control()->set_activated_callback - ( - [ctx]() - { - ctx->tool_system->set_tool_active(true); - } - ); - ctx->control_system->get_use_tool_control()->set_deactivated_callback - ( - [ctx]() - { - ctx->tool_system->set_tool_active(false); - } - ); + ctx->input_event_router->add_mapping(input::key_mapping(ctx->camera_control_modifier, nullptr, input::scancode::left_shift)); + ctx->input_event_router->add_mapping(input::key_mapping(ctx->camera_control_dolly_forward, nullptr, input::scancode::w)); + ctx->input_event_router->add_mapping(input::game_controller_axis_mapping(ctx->camera_control_dolly_forward, nullptr, input::game_controller_axis::left_y, true)); + ctx->input_event_router->add_mapping(input::key_mapping(ctx->camera_control_dolly_backward, nullptr, input::scancode::s)); + ctx->input_event_router->add_mapping(input::game_controller_axis_mapping(ctx->camera_control_dolly_backward, nullptr, input::game_controller_axis::left_y, false)); + ctx->input_event_router->add_mapping(input::key_mapping(ctx->camera_control_truck_left, nullptr, input::scancode::a)); + ctx->input_event_router->add_mapping(input::game_controller_axis_mapping(ctx->camera_control_truck_left, nullptr, input::game_controller_axis::left_x, true)); + ctx->input_event_router->add_mapping(input::key_mapping(ctx->camera_control_truck_right, nullptr, input::scancode::d)); + ctx->input_event_router->add_mapping(input::game_controller_axis_mapping(ctx->camera_control_truck_right, nullptr, input::game_controller_axis::left_x, false)); - ctx->control_system->get_equip_forceps_control()->set_activated_callback - ( - [ctx]() - { - ctx->tool_system->set_active_tool(ctx->forceps_entity); - } - ); - ctx->control_system->get_equip_brush_control()->set_activated_callback - ( - [ctx]() - { - ctx->tool_system->set_active_tool(ctx->brush_entity); - } - ); - ctx->control_system->get_equip_lens_control()->set_activated_callback - ( - [ctx]() - { - ctx->tool_system->set_active_tool(ctx->lens_entity); - } - ); - ctx->control_system->get_equip_marker_control()->set_activated_callback - ( - [ctx]() - { - ctx->tool_system->set_active_tool(ctx->marker_entity); - } - ); - ctx->control_system->get_equip_container_control()->set_activated_callback - ( - [ctx]() - { - ctx->tool_system->set_active_tool(ctx->container_entity); - } - ); - ctx->control_system->get_equip_twig_control()->set_activated_callback - ( - [ctx]() - { - ctx->tool_system->set_active_tool(ctx->twig_entity); - } - ); + ctx->input_event_router->add_mapping(input::mouse_wheel_mapping(ctx->camera_control_pedestal_up, nullptr, input::mouse_wheel_axis::positive_y)); + ctx->input_event_router->add_mapping(input::mouse_wheel_mapping(ctx->camera_control_pedestal_down, nullptr, input::mouse_wheel_axis::negative_y)); - ctx->control_system->get_next_marker_control()->set_activated_callback - ( - [ctx]() - { - auto& marker = ctx->entity_registry->get(ctx->marker_entity); - marker.color = (marker.color + 1) % 8; - const gl::texture_2d* marker_albedo_texture = ctx->marker_albedo_textures[marker.color]; - - model* marker_model = ctx->render_system->get_model_instance(ctx->marker_entity)->get_model(); - for (::model_group* group: *marker_model->get_groups()) - { - material_property_base* albedo_property = group->get_material()->get_property("albedo_texture"); - if (albedo_property) - { - static_cast*>(albedo_property)->set_value(marker_albedo_texture); - } - } - } - ); + ctx->input_event_router->add_mapping(input::mouse_button_mapping(ctx->camera_control_orbit, nullptr, 3)); + ctx->input_event_router->add_mapping(input::mouse_motion_mapping(ctx->camera_control_mouse_left, nullptr, input::mouse_motion_axis::negative_x)); + ctx->input_event_router->add_mapping(input::mouse_motion_mapping(ctx->camera_control_mouse_right, nullptr, input::mouse_motion_axis::positive_x)); + ctx->input_event_router->add_mapping(input::mouse_motion_mapping(ctx->camera_control_mouse_down, nullptr, input::mouse_motion_axis::positive_y)); + ctx->input_event_router->add_mapping(input::mouse_motion_mapping(ctx->camera_control_mouse_up, nullptr, input::mouse_motion_axis::negative_y)); + + //ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_next_marker_control(), nullptr, input::scancode::right_brace)); + //ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_previous_marker_control(), nullptr, input::scancode::left_brace)); - ctx->control_system->get_previous_marker_control()->set_activated_callback - ( - [ctx]() - { - auto& marker = ctx->entity_registry->get(ctx->marker_entity); - marker.color = (marker.color + 7) % 8; - const gl::texture_2d* marker_albedo_texture = ctx->marker_albedo_textures[marker.color]; - - model* marker_model = ctx->render_system->get_model_instance(ctx->marker_entity)->get_model(); - for (::model_group* group: *marker_model->get_groups()) - { - material_property_base* albedo_property = group->get_material()->get_property("albedo_texture"); - if (albedo_property) - { - static_cast*>(albedo_property)->set_value(marker_albedo_texture); - } - } - } - ); float time_scale = ctx->config->get("time_scale"); @@ -1265,7 +1194,10 @@ void setup_callbacks(game::context* ctx) ctx->timeline->advance(dt); - ctx->control_system->update(t, dt); + + + + ctx->terrain_system->update(t, dt); //ctx->vegetation_system->update(t, dt); ctx->snapping_system->update(t, dt); @@ -1304,6 +1236,24 @@ void setup_callbacks(game::context* ctx) ctx->application_controls->update(); ctx->menu_controls->update(); ctx->camera_controls->update(); + + ctx->control_system->update(t, dt); + ctx->camera_control_modifier->update(); + ctx->camera_control_mouse_left->update(); + ctx->camera_control_mouse_right->update(); + ctx->camera_control_mouse_down->update(); + ctx->camera_control_mouse_up->update(); + ctx->camera_control_dolly_forward->update(); + ctx->camera_control_dolly_backward->update(); + ctx->camera_control_truck_left->update(); + ctx->camera_control_truck_right->update(); + ctx->camera_control_pedestal_up->update(); + ctx->camera_control_pedestal_down->update(); + ctx->camera_control_pan_left->update(); + ctx->camera_control_pan_right->update(); + ctx->camera_control_tilt_up->update(); + ctx->camera_control_tilt_down->update(); + ctx->camera_control_orbit->update(); } ); diff --git a/src/game/context.hpp b/src/game/context.hpp index 0df5727..64e655e 100644 --- a/src/game/context.hpp +++ b/src/game/context.hpp @@ -228,6 +228,23 @@ struct context input::control* menu_select_control; input::control* screenshot_control; input::control* toggle_fullscreen_control; + + input::control* camera_control_mouse_left; + input::control* camera_control_mouse_right; + input::control* camera_control_mouse_down; + input::control* camera_control_mouse_up; + input::control* camera_control_orbit; + input::control* camera_control_dolly_forward; + input::control* camera_control_dolly_backward; + input::control* camera_control_truck_left; + input::control* camera_control_truck_right; + input::control* camera_control_pedestal_up; + input::control* camera_control_pedestal_down; + input::control* camera_control_pan_left; + input::control* camera_control_pan_right; + input::control* camera_control_tilt_up; + input::control* camera_control_tilt_down; + input::control* camera_control_modifier; // Entities entity::registry* entity_registry; @@ -264,7 +281,6 @@ struct context entity::system::astronomy* astronomy_system; entity::system::orbit* orbit_system; entity::system::proteome* proteome_system; - std::unordered_map named_entities; // Game biome* biome; diff --git a/src/game/states/brood.cpp b/src/game/states/brood.cpp index bdca63e..94e469b 100644 --- a/src/game/states/brood.cpp +++ b/src/game/states/brood.cpp @@ -21,9 +21,13 @@ #include "entity/archetype.hpp" #include "entity/commands.hpp" #include "entity/components/observer.hpp" -#include "entity/components/camera-follow.hpp" +#include "entity/components/camera.hpp" #include "entity/components/terrain.hpp" #include "entity/components/transform.hpp" +#include "entity/components/chamber.hpp" +#include "entity/components/constraints/spring-to.hpp" +#include "entity/components/constraints/three-dof.hpp" +#include "entity/components/constraint-stack.hpp" #include "entity/systems/control.hpp" #include "entity/systems/camera.hpp" #include "entity/systems/tool.hpp" @@ -31,48 +35,34 @@ #include "animation/ease.hpp" #include "resources/resource-manager.hpp" #include "renderer/passes/sky-pass.hpp" +#include "application.hpp" +#include namespace game { namespace state { namespace brood { +static void setup_nest(game::context* ctx); +static void setup_ants(game::context* ctx); +static void setup_camera(game::context* ctx); +static void setup_controls(game::context* ctx); + void enter(game::context* ctx) { - // Switch to underground camera - ctx->surface_camera->set_active(false); - ctx->underground_camera->set_active(true); + setup_nest(ctx); + setup_ants(ctx); + setup_camera(ctx); + setup_controls(ctx); ctx->underground_ambient_light->set_intensity(1.0f); - // Create camera focal point - { - entity::component::transform focal_point_transform; - focal_point_transform.local = math::identity_transform; - focal_point_transform.warp = true; - ctx->entity_registry->assign_or_replace(ctx->focal_point_entity, focal_point_transform); - - entity::component::camera_follow focal_point_follow; - ctx->entity_registry->assign_or_replace(ctx->focal_point_entity, focal_point_follow); - } - - // Setup camera - ctx->underground_camera->look_at({0, 0, 1}, {0, 0, 0}, {0, 1, 0}); - ctx->underground_camera->set_exposure(0.0f); - - ctx->camera_system->set_camera(ctx->underground_camera); - ctx->tool_system->set_camera(ctx->underground_camera); - ctx->tool_system->set_orbit_cam(ctx->camera_system->get_orbit_cam()); - - entity::system::control* control_system = ctx->control_system; - control_system->update(0.0, 0.0); - control_system->set_nest(nullptr); - // Create larva { entity::archetype* larva_archetype = ctx->resource_manager->load("ant-larva.ent"); auto larva_eid = larva_archetype->create(*ctx->entity_registry); entity::command::warp_to(*ctx->entity_registry, larva_eid, {0.0f, 0.0f, 0.0f}); entity::command::assign_render_layers(*ctx->entity_registry, larva_eid, 0b1); + entity::command::rename(*ctx->entity_registry, larva_eid, "larva"); } // Create cocoon @@ -81,8 +71,10 @@ void enter(game::context* ctx) auto cocoon_eid = cocoon_archetype->create(*ctx->entity_registry); entity::command::warp_to(*ctx->entity_registry, cocoon_eid, {-50, 0.1935f, 0}); entity::command::assign_render_layers(*ctx->entity_registry, cocoon_eid, 0b1); + entity::command::rename(*ctx->entity_registry, cocoon_eid, "cocoon"); } + // Reset tweening ctx->underground_scene->update_tweens(); // Start fade in @@ -92,6 +84,348 @@ void enter(game::context* ctx) void exit(game::context* ctx) {} +void setup_nest(game::context* ctx) +{ + // Find or create nest central shaft entity + entity::id shaft_eid = entity::command::find(*ctx->entity_registry, "shaft"); + if (shaft_eid == entt::null) + { + shaft_eid = entity::command::create(*ctx->entity_registry, "shaft"); + + entity::component::transform transform; + transform.local = math::identity_transform; + transform.world = transform.local; + transform.warp = true; + + ctx->entity_registry->assign(shaft_eid, transform); + } + + // Find or create nest lobby chamber entity + entity::id lobby_eid = entity::command::find(*ctx->entity_registry, "lobby"); + if (lobby_eid == entt::null) + { + lobby_eid = entity::command::create(*ctx->entity_registry, "lobby"); + + entity::component::chamber chamber; + chamber.shaft_eid = shaft_eid; + chamber.distance = 10.0f; + chamber.previous_chamber_eid = entt::null; + chamber.next_chamber_eid = entt::null; + } + + // Find or create nest shaft elevator entity + entity::id elevator_eid = entity::command::find(*ctx->entity_registry, "elevator"); + if (elevator_eid == entt::null) + { + elevator_eid = entity::command::create(*ctx->entity_registry, "elevator"); + + // Create transform component + entity::component::transform transform; + transform.local = math::identity_transform; + transform.world = transform.local; + transform.warp = true; + ctx->entity_registry->assign(elevator_eid, transform); + + /* + entity::component::constraint::follow_curve follow_curve; + follow_curve.target_eid = shaft_eid; + follow_curve.offset = 10.0f; + */ + } +} + +void setup_ants(game::context* ctx) +{ + // Find or create queen ant entity + entity::id queen_eid = entity::command::find(*ctx->entity_registry, "queen"); + if (queen_eid == entt::null) + { + queen_eid = entity::command::create(*ctx->entity_registry, "queen"); + } +} + +void setup_camera(game::context* ctx) +{ + // Switch to underground camera + ctx->surface_camera->set_active(false); + ctx->underground_camera->set_active(true); + + // Get underground camera entity + entity::id camera_eid = entity::command::find(*ctx->entity_registry, "underground_cam"); + + if (camera_eid == entt::null) + { + // Create camera target entity + entity::id target_eid = entity::command::create(*ctx->entity_registry, "underground_cam_target"); + { + // Transform + entity::component::transform target_transform; + target_transform.local = math::identity_transform; + target_transform.world = target_transform.local; + target_transform.warp = true; + ctx->entity_registry->assign(target_eid, target_transform); + + // 3DOF constraint + entity::id three_dof_eid = entity::command::create(*ctx->entity_registry, "underground_cam_3dof"); + entity::component::constraint::three_dof three_dof; + three_dof.yaw = 0.0f; + three_dof.pitch = 0.0f; + three_dof.roll = 0.0f; + ctx->entity_registry->assign(three_dof_eid, three_dof); + entity::component::constraint_stack_node node; + node.active = true; + node.weight = 1.0f; + node.next = entt::null; + ctx->entity_registry->assign(three_dof_eid, node); + + // Create target constraint stack component + entity::component::constraint_stack constraint_stack; + constraint_stack.head = three_dof_eid; + ctx->entity_registry->assign(target_eid, constraint_stack); + } + + // Create camera entity + camera_eid = entity::command::create(*ctx->entity_registry, "underground_cam"); + + // Create camera transform component + entity::component::transform transform; + transform.local = math::identity_transform; + transform.world = transform.local; + transform.warp = true; + ctx->entity_registry->assign(camera_eid, transform); + + // Create camera camera component + entity::component::camera camera; + camera.object = ctx->underground_camera; + ctx->entity_registry->assign(camera_eid, camera); + + // Create camera spring to constraint entity + entity::id spring_constraint_eid = entity::command::create(*ctx->entity_registry); + { + // Create spring to constraint + entity::component::constraint::spring_to spring; + spring.target = target_eid; + spring.translation = {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 1.0f, math::two_pi}; + spring.translation.w = hz_to_rads(8.0f); + + spring.rotation = {{1.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}, 1.0f, math::two_pi}; + spring.rotation.w = hz_to_rads(8.0f); + + spring.spring_translation = true; + spring.spring_rotation = true; + ctx->entity_registry->assign(spring_constraint_eid, spring); + + // Create constraint stack node component + entity::component::constraint_stack_node node; + node.active = true; + node.weight = 1.0f; + node.next = entt::null; + ctx->entity_registry->assign(spring_constraint_eid, node); + } + + // Create camera constraint stack component + entity::component::constraint_stack constraint_stack; + constraint_stack.head = spring_constraint_eid; + ctx->entity_registry->assign(camera_eid, constraint_stack); + } + + /* + entity::component::orbit_rig orbit; + orbit.azimuth_min = -std::numeric_limits::infinity(); + orbit.azimuth_max = std::numeric_limits::infinity(); + orbit.elevation_min = math::radians(-89.0f); + orbit.elevation_max = math::radians(89.0f); + orbit.dolly_min = 2.0f; + orbit.dolly_max = 200.0f; + orbit.fov_near = math::radians(80.0f); + orbit.fov_far = math::radians(35.0f); + orbit.clip_near_min = 0.1f; + orbit.clip_near_max = 5.0f; + orbit.clip_far_min = 100.0f; + orbit.clip_far_max = 5000.0f; + */ + + ctx->underground_camera->set_exposure(0.0f); +} + +void setup_controls(game::context* ctx) +{ + // Get underground camera entity + entity::id camera_eid = entity::command::find(*ctx->entity_registry, "underground_cam"); + entity::id target_eid = entity::command::find(*ctx->entity_registry, "underground_cam_target"); + entity::id three_dof_eid = entity::command::find(*ctx->entity_registry, "underground_cam_3dof"); + + const float dolly_speed = 10.0f; + const float truck_speed = dolly_speed; + const float pedestal_speed = 20.0f; + const float pan_speed = math::radians(10.0f); + const float tilt_speed = pan_speed; + + ctx->camera_control_dolly_forward->set_active_callback + ( + [ctx, target_eid, three_dof_eid, truck_speed](float value) + { + auto& three_dof = ctx->entity_registry->get(three_dof_eid); + const math::quaternion yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f}); + + const float3 movement = {0.0f, 0.0f, -truck_speed * value * (1.0f / 60.0f)}; + entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement); + } + ); + + ctx->camera_control_dolly_backward->set_active_callback + ( + [ctx, target_eid, three_dof_eid, truck_speed](float value) + { + auto& three_dof = ctx->entity_registry->get(three_dof_eid); + const math::quaternion yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f}); + + const float3 movement = {0.0f, 0.0f, truck_speed * value * (1.0f / 60.0f)}; + entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement); + } + ); + + ctx->camera_control_truck_right->set_active_callback + ( + [ctx, target_eid, three_dof_eid, truck_speed](float value) + { + auto& three_dof = ctx->entity_registry->get(three_dof_eid); + const math::quaternion yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f}); + + const float3 movement = {truck_speed * value * (1.0f / 60.0f), 0.0f, 0.0f}; + entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement); + } + ); + + ctx->camera_control_truck_left->set_active_callback + ( + [ctx, target_eid, three_dof_eid, truck_speed](float value) + { + auto& three_dof = ctx->entity_registry->get(three_dof_eid); + const math::quaternion yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f}); + + const float3 movement = {-truck_speed * value * (1.0f / 60.0f), 0.0f, 0.0f}; + entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement); + } + ); + + // Pedestal up + ctx->camera_control_pedestal_up->set_activated_callback + ( + [ctx, target_eid]() + { + if (ctx->camera_control_modifier->is_active()) + { + // Snap to chamber + + // Find closest chamber + // Pedestal to chamber + offset + } + } + ); + ctx->camera_control_pedestal_up->set_active_callback + ( + [ctx, target_eid, pedestal_speed](float value) + { + if (!ctx->camera_control_modifier->is_active()) + { + const float3 movement = {0.0f, pedestal_speed * value * (1.0f / 60.0f), 0.0f}; + entity::command::translate(*ctx->entity_registry, target_eid, movement); + } + } + ); + + // Pedestal down + ctx->camera_control_pedestal_down->set_activated_callback + ( + [ctx, target_eid]() + { + //... + } + ); + ctx->camera_control_pedestal_down->set_active_callback + ( + [ctx, target_eid, pedestal_speed](float value) + { + if (!ctx->camera_control_modifier->is_active()) + { + const float3 movement = {0.0f, -pedestal_speed * value * (1.0f / 60.0f), 0.0f}; + entity::command::translate(*ctx->entity_registry, target_eid, movement); + } + } + ); + + ctx->camera_control_orbit->set_activated_callback + ( + [ctx]() + { + ctx->app->set_relative_mouse_mode(true); + } + ); + + ctx->camera_control_orbit->set_deactivated_callback + ( + [ctx]() + { + ctx->app->set_relative_mouse_mode(false); + } + ); + + // Pan left + ctx->camera_control_mouse_left->set_active_callback + ( + [ctx, three_dof_eid, pan_speed](float value) + { + if (!ctx->camera_control_orbit->is_active()) + return; + + auto& three_dof = ctx->entity_registry->get(three_dof_eid); + three_dof.yaw += pan_speed * value * (1.0f / 60.0f); + } + ); + + // Pan right + ctx->camera_control_mouse_right->set_active_callback + ( + [ctx, three_dof_eid, pan_speed](float value) + { + if (!ctx->camera_control_orbit->is_active()) + return; + + auto& three_dof = ctx->entity_registry->get(three_dof_eid); + three_dof.yaw -= pan_speed * value * (1.0f / 60.0f); + } + ); + + // Tilt up + ctx->camera_control_mouse_up->set_active_callback + ( + [ctx, three_dof_eid, tilt_speed](float value) + { + if (!ctx->camera_control_orbit->is_active()) + return; + + auto& three_dof = ctx->entity_registry->get(three_dof_eid); + three_dof.pitch -= tilt_speed * value * (1.0f / 60.0f); + three_dof.pitch = std::max(math::radians(-89.0f), three_dof.pitch); + } + ); + + // Tilt down + ctx->camera_control_mouse_down->set_active_callback + ( + [ctx, three_dof_eid, tilt_speed](float value) + { + if (!ctx->camera_control_orbit->is_active()) + return; + + auto& three_dof = ctx->entity_registry->get(three_dof_eid); + three_dof.pitch += tilt_speed * value * (1.0f / 60.0f); + three_dof.pitch = std::min(math::radians(89.0f), three_dof.pitch); + } + ); +} + } // namespace brood } // namespace state } // namespace game diff --git a/src/game/states/forage.cpp b/src/game/states/forage.cpp index a026ea6..2f253c4 100644 --- a/src/game/states/forage.cpp +++ b/src/game/states/forage.cpp @@ -21,7 +21,6 @@ #include "entity/archetype.hpp" #include "entity/commands.hpp" #include "entity/components/observer.hpp" -#include "entity/components/camera-follow.hpp" #include "entity/components/terrain.hpp" #include "entity/components/transform.hpp" #include "entity/systems/astronomy.hpp" @@ -72,25 +71,9 @@ void enter(game::context* ctx) ctx->astronomy_system->set_observer_location(double3{observer.elevation, observer.latitude, observer.longitude}); } - // Create camera focal point - { - entity::component::transform focal_point_transform; - focal_point_transform.local = math::identity_transform; - focal_point_transform.warp = true; - ctx->entity_registry->assign_or_replace(ctx->focal_point_entity, focal_point_transform); - - entity::component::camera_follow focal_point_follow; - ctx->entity_registry->assign_or_replace(ctx->focal_point_entity, focal_point_follow); - } - // Setup camera ctx->surface_camera->look_at({0, 0, 1}, {0, 0, 0}, {0, 1, 0}); ctx->surface_camera->set_exposure(-14.5f); - ctx->camera_system->set_camera(ctx->surface_camera); - - entity::system::control* control_system = ctx->control_system; - control_system->update(0.0, 0.0); - control_system->set_nest(nullptr); // Create larva { diff --git a/src/game/states/nuptial-flight.cpp b/src/game/states/nuptial-flight.cpp index 05c13ca..1d62dd1 100644 --- a/src/game/states/nuptial-flight.cpp +++ b/src/game/states/nuptial-flight.cpp @@ -24,7 +24,6 @@ #include "entity/systems/control.hpp" #include "entity/systems/camera.hpp" #include "entity/components/observer.hpp" -#include "entity/components/camera-follow.hpp" #include "entity/components/transform.hpp" #include "entity/components/terrain.hpp" #include "entity/commands.hpp" @@ -86,24 +85,9 @@ void enter(game::context* ctx) auto orb_ring_eid = ctx->entity_registry->create(); //orb_ring_archetype->assign(*ctx->entity_registry, orb_ring_eid); - // Create camera focal point - { - entity::component::transform focal_point_transform; - focal_point_transform.local = math::identity_transform; - focal_point_transform.warp = true; - ctx->entity_registry->assign_or_replace(ctx->focal_point_entity, focal_point_transform); - - entity::component::camera_follow focal_point_follow; - ctx->entity_registry->assign_or_replace(ctx->focal_point_entity, focal_point_follow); - } - // Setup camera ctx->surface_camera->look_at({0, 0, 1}, {0, 0, 0}, {0, 1, 0}); ctx->surface_camera->set_exposure(-14.5f); - ctx->camera_system->set_camera(ctx->surface_camera); - - entity::system::control* control_system = ctx->control_system; - control_system->update(0.0, 0.0); ctx->surface_scene->update_tweens(); diff --git a/src/input/control.cpp b/src/input/control.cpp index e4963b8..0ab9dbc 100644 --- a/src/input/control.cpp +++ b/src/input/control.cpp @@ -29,6 +29,7 @@ control::control(): activated_callback(nullptr), deactivated_callback(nullptr), value_changed_callback(nullptr), + active_callback(nullptr), callbacks_enabled(true) {} @@ -66,6 +67,11 @@ void control::update() } } } + + if (active_callback && is_active()) + { + active_callback(current_value); + } } // Update previous value @@ -111,4 +117,9 @@ void control::set_value_changed_callback(std::function callback) this->value_changed_callback = callback; } +void control::set_active_callback(std::function callback) +{ + this->active_callback = callback; +} + } // namespace input diff --git a/src/input/control.hpp b/src/input/control.hpp index 82b461f..f89a078 100644 --- a/src/input/control.hpp +++ b/src/input/control.hpp @@ -68,6 +68,9 @@ public: /// Sets the callback for when the control value is changed. void set_value_changed_callback(std::function callback); + + /// Sets the callback for while the control is active. + void set_active_callback(std::function callback); /** * Enables or disables callbacks. @@ -99,6 +102,7 @@ private: std::function activated_callback; std::function deactivated_callback; std::function value_changed_callback; + std::function active_callback; bool callbacks_enabled; }; diff --git a/src/input/event-router.cpp b/src/input/event-router.cpp index a34a8ff..a9fcb35 100644 --- a/src/input/event-router.cpp +++ b/src/input/event-router.cpp @@ -235,19 +235,19 @@ void event_router::handle_event(const mouse_moved_event& event) { if (mapping->axis == mouse_motion_axis::negative_x && event.dx < 0) { - mapping->control->set_temporary_value(-event.dx); + mapping->control->set_temporary_value(mapping->control->get_current_value() - event.dx); } else if (mapping->axis == mouse_motion_axis::positive_x && event.dx > 0) { - mapping->control->set_temporary_value(event.dx); + mapping->control->set_temporary_value(mapping->control->get_current_value() + event.dx); } else if (mapping->axis == mouse_motion_axis::negative_y && event.dy < 0) { - mapping->control->set_temporary_value(-event.dy); + mapping->control->set_temporary_value(mapping->control->get_current_value() - event.dy); } else if (mapping->axis == mouse_motion_axis::positive_y && event.dy > 0) { - mapping->control->set_temporary_value(event.dy); + mapping->control->set_temporary_value(mapping->control->get_current_value() + event.dy); } } } @@ -261,19 +261,19 @@ void event_router::handle_event(const mouse_wheel_scrolled_event& event) { if (mapping->axis == mouse_wheel_axis::negative_x && event.x < 0) { - mapping->control->set_temporary_value(-event.x); + mapping->control->set_temporary_value(mapping->control->get_current_value() - event.x); } else if (mapping->axis == mouse_wheel_axis::positive_x && event.x > 0) { - mapping->control->set_temporary_value(event.x); + mapping->control->set_temporary_value(mapping->control->get_current_value() + event.x); } else if (mapping->axis == mouse_wheel_axis::negative_y && event.y < 0) { - mapping->control->set_temporary_value(-event.y); + mapping->control->set_temporary_value(mapping->control->get_current_value() - event.y); } else if (mapping->axis == mouse_wheel_axis::positive_y && event.y > 0) { - mapping->control->set_temporary_value(event.y); + mapping->control->set_temporary_value(mapping->control->get_current_value() + event.y); } } }