From 30d68648befc4a84ae532fb0d28a109501105c28 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Wed, 29 Sep 2021 14:16:51 +0800 Subject: [PATCH] Revise tool component and remove tool system --- CMakeLists.txt | 1 - src/entity/components/tool.hpp | 12 +- src/entity/systems/painting.cpp | 2 + src/entity/systems/tool.cpp | 330 ---------------------- src/entity/systems/tool.hpp | 91 ------ src/game/bootloader.cpp | 7 - src/game/context.hpp | 2 - src/game/states/forage.cpp | 68 ++++- src/resources/entity-archetype-loader.cpp | 19 -- 9 files changed, 62 insertions(+), 470 deletions(-) delete mode 100644 src/entity/systems/tool.cpp delete mode 100644 src/entity/systems/tool.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index af368e1..d4aa351 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 3.7) - option(VERSION_STRING "Project version string" "0.0.0") project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX) diff --git a/src/entity/components/tool.hpp b/src/entity/components/tool.hpp index 0bccf6c..f8a4f7b 100644 --- a/src/entity/components/tool.hpp +++ b/src/entity/components/tool.hpp @@ -20,18 +20,16 @@ #ifndef ANTKEEPER_ENTITY_COMPONENT_TOOL_HPP #define ANTKEEPER_ENTITY_COMPONENT_TOOL_HPP +#include + namespace entity { namespace component { struct tool { - bool active; - float idle_distance; - float active_distance; - bool heliotropic; - float3 cursor; - - //float activation_speed; + std::function activated; + std::function deactivated; + std::function active; }; } // namespace component diff --git a/src/entity/systems/painting.cpp b/src/entity/systems/painting.cpp index e624ac8..607abdb 100644 --- a/src/entity/systems/painting.cpp +++ b/src/entity/systems/painting.cpp @@ -96,6 +96,7 @@ painting::~painting() void painting::update(double t, double dt) { + /* if (is_painting) { const component::tool& tool = registry.get(brush_entity); @@ -264,6 +265,7 @@ void painting::update(double t, double dt) } } } + */ } void painting::set_scene(scene::collection* collection) diff --git a/src/entity/systems/tool.cpp b/src/entity/systems/tool.cpp deleted file mode 100644 index 03a4f65..0000000 --- a/src/entity/systems/tool.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* - * 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 . - */ - -#include "tool.hpp" -#include "entity/components/collision.hpp" -#include "entity/components/tool.hpp" -#include "entity/components/transform.hpp" -#include "event/event-dispatcher.hpp" -#include "game/events/tool-events.hpp" -#include "animation/ease.hpp" -#include "geom/mesh.hpp" -#include "geom/intersection.hpp" -#include "math/math.hpp" -#include "entity/commands.hpp" - -namespace entity { -namespace system { - -tool::tool(entity::registry& registry, ::event_dispatcher* event_dispatcher): - updatable(registry), - event_dispatcher(event_dispatcher), - camera(nullptr), - viewport{0, 0, 0, 0}, - mouse_position{0, 0}, - pick_enabled(true), - was_pick_enabled(pick_enabled), - active_tool(entt::null) -{ - hand_angle_spring.z = 1.0f; - hand_angle_spring.w = hz_to_rads(8.0f); - hand_angle_spring.x1 = math::pi; - hand_angle_spring.x0 = hand_angle_spring.x1; - hand_angle_spring.v = 0.0f; - - pick_spring.z = 1.0f; - pick_spring.w = hz_to_rads(30.0f); - pick_spring.x1 = {0.0f, 0.0f, 0.0f}; - pick_spring.x0 = pick_spring.x1; - pick_spring.v = {0.0f, 0.0f, 0.0f}; - - // Create descend animation - animation_channel* channel = descend_animation.add_channel(0); - descend_animation.set_interpolator(ease::out_cubic); - descend_animation.set_frame_callback - ( - [this](int channel, const float& t) - { - this->active_tool_distance = t; - } - ); - - // Create descend animation - channel = ascend_animation.add_channel(0); - ascend_animation.set_interpolator(ease::out_cubic); - ascend_animation.set_frame_callback - ( - [this](int channel, const float& t) - { - this->active_tool_distance = t; - } - ); - - active_tool = entt::null; - active_tool_distance = 0.0f; - warp = true; - tool_active = false; - - event_dispatcher->subscribe(this); - event_dispatcher->subscribe(this); -} - -tool::~tool() -{ - event_dispatcher->unsubscribe(this); - event_dispatcher->unsubscribe(this); -} - -void tool::update(double t, double dt) -{ - /* - if (active_tool == entt::null) - return; - - // Advance animations - ascend_animation.advance(dt); - descend_animation.advance(dt); - - if (!camera) - return; - - float3 pick_near = camera->unproject({mouse_position[0], viewport[3] - mouse_position[1], 0.0f}, viewport); - float3 pick_far = camera->unproject({mouse_position[0], viewport[3] - mouse_position[1], 1.0f}, viewport); - float3 pick_origin = pick_near; - float3 pick_direction = math::normalize(pick_far - pick_near); - geom::ray picking_ray = {pick_near, pick_direction}; - - float a = std::numeric_limits::infinity(); - bool intersection = false; - float3 pick; - - // Cast ray from cursor to collision components to find closest intersection - registry.view().each( - [&](entity::id entity_id, auto& transform, auto& collision) - { - math::transform inverse_transform = math::inverse(transform.local); - float3 origin = inverse_transform * pick_origin; - float3 direction = math::normalize(math::conjugate(transform.local.rotation) * pick_direction); - geom::ray transformed_ray = {origin, direction}; - - // Broad phase AABB test - auto aabb_result = geom::ray_aabb_intersection(transformed_ray, collision.bounds); - if (!std::get<0>(aabb_result)) - { - return; - } - - // Narrow phase mesh test - auto mesh_result = collision.mesh_accelerator.query_nearest(transformed_ray); - if (mesh_result) - { - intersection = true; - if (mesh_result->t < a) - { - a = mesh_result->t; - pick = picking_ray.extrapolate(a); - pick_spring.x1 = pick; - } - } - }); - - const float3& camera_position = camera->get_translation(); - float3 pick_planar_position = float3{pick.x, 0, pick.z}; - float3 camera_planar_position = float3{camera_position.x, 0, camera_position.z}; - - float pick_angle = 0.0f; - float3 pick_planar_direction = math::normalize(pick_planar_position - camera_planar_position); - float3 camera_planar_focal_point = float3{orbit_cam->get_focal_point().x, 0, orbit_cam->get_focal_point().z}; - float3 camera_planar_direction = math::normalize(camera_planar_focal_point - camera_planar_position); - if (std::fabs(math::length_squared(camera_planar_direction - pick_planar_direction) > 0.0001f)) - { - pick_angle = std::acos(math::dot(camera_planar_direction, pick_planar_direction)); - if (math::dot(math::cross(camera_planar_direction, pick_planar_direction), float3{0, 1, 0}) < 0.0f) - pick_angle = -pick_angle; - } - - // Determine target hand angle - hand_angle_spring.x1 = -std::min(0.5f, std::max(-0.5f, ((mouse_position[0] / viewport[2]) - 0.5f) * 1.0f)) * (math::pi); - - // Solve springs - solve_numeric_spring(hand_angle_spring, dt); - solve_numeric_spring(pick_spring, dt); - - // Don't use spring for picking - pick_spring.x0 = pick_spring.x1; - - // Move active tools to intersection location - registry.view().each( - [&](entity::id entity_id, auto& tool, auto& transform) - { - - if (!tool.active) - return; - - active_tool = entity_id; - - float tool_distance = active_tool_distance;//(tool_active) ? tool.active_distance : tool.idle_distance; - - - // Interpolate between left and right hand - math::quaternion hand_rotation = math::angle_axis(orbit_cam->get_azimuth() + hand_angle_spring.x0, float3{0, 1, 0}); - - math::quaternion tilt_rotation = math::angle_axis(orbit_cam->get_elevation(), float3{-1.0f, 0.0f, 0.0f}); - - if (tool.heliotropic) - { - math::quaternion solar_rotation = math::rotation(float3{0, -1, 0}, sun_direction); - transform.local.translation = pick_spring.x0 + solar_rotation * float3{0, tool_distance, 0}; - transform.local.rotation = solar_rotation * hand_rotation; - } - else - { - math::quaternion rotation = hand_rotation * tilt_rotation; - transform.local.translation = pick_spring.x0 + rotation * float3{0, tool_distance, 0}; - transform.local.rotation = rotation; - } - - if (warp) - { - transform.warp = true; - command::assign_render_layers(registry, active_tool, 1); - warp = false; - } - - // Update tool's cursor position - tool.cursor = pick_spring.x0; - - //math::quaternion rotation = math::angle_axis(orbit_cam->get_azimuth() + pick_angle, float3{0, 1, 0}); - //transform.transform.rotation = rotation; - }); - - was_pick_enabled = pick_enabled; - */ -} - -void tool::set_camera(const scene::camera* camera) -{ - this->camera = camera; -} - -void tool::set_viewport(const float4& viewport) -{ - this->viewport = viewport; - mouse_position.x = viewport[2] * 0.5f; - mouse_position.y = viewport[3] * 0.5f; -} - -void tool::set_pick(bool enabled) -{ - pick_enabled = enabled; -} - -void tool::set_sun_direction(const float3& direction) -{ - sun_direction = direction; -} - -void tool::set_active_tool(entity::id entity_id) -{ - if (active_tool == entity_id) - return; - - const float descent_time = 0.1f; - const float ascent_time = 0.1f; - - if (active_tool != entt::null) - { - auto& tool = registry.get(active_tool); - tool.active = false; - command::assign_render_layers(registry, active_tool, 0); - } - - active_tool = entity_id; - - if (active_tool != entt::null) - { - auto& tool = registry.get(active_tool); - tool.active = true; - - active_tool_distance = tool.idle_distance; - - command::warp_to(registry, active_tool, pick_spring.x0 + float3{0.0f, tool.idle_distance, 0.0f}); - - // Adjust descend and ascend animations - animation_channel* channel = descend_animation.get_channel(0); - channel->remove_keyframes(); - channel->insert_keyframe({0.0, tool.idle_distance}); - channel->insert_keyframe({descent_time, tool.active_distance}); - - channel = ascend_animation.get_channel(0); - channel->remove_keyframes(); - channel->insert_keyframe({0.0, tool.active_distance}); - channel->insert_keyframe({ascent_time, tool.idle_distance}); - } - - warp = true; -} - -void tool::set_tool_active(bool active) -{ - if (active_tool == entt::null) - return; - - tool_active = active; - - if (active) - { - descend_animation.rewind(); - descend_animation.play(); - - // Queue tool pressed event - tool_pressed_event event; - event.entity_id = active_tool; - event.position = pick_spring.x0; - event_dispatcher->queue(event); - } - else - { - ascend_animation.rewind(); - ascend_animation.play(); - - // Queue tool pressed event - tool_released_event event; - event.entity_id = active_tool; - event.position = pick_spring.x0; - event_dispatcher->queue(event); - } -} - -void tool::handle_event(const mouse_moved_event& event) -{ - if (pick_enabled && was_pick_enabled) - { - mouse_position[0] = event.x; - mouse_position[1] = event.y; - } -} - -void tool::handle_event(const window_resized_event& event) -{ - set_viewport({0.0f, 0.0f, static_cast(event.w), static_cast(event.h)}); -} - -} // namespace system -} // namespace entity diff --git a/src/entity/systems/tool.hpp b/src/entity/systems/tool.hpp deleted file mode 100644 index 282afc2..0000000 --- a/src/entity/systems/tool.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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_SYSTEM_TOOL_HPP -#define ANTKEEPER_ENTITY_SYSTEM_TOOL_HPP - -#include "entity/systems/updatable.hpp" -#include "entity/id.hpp" -#include "event/event-handler.hpp" -#include "event/input-events.hpp" -#include "event/window-events.hpp" -#include "utility/fundamental-types.hpp" -#include "animation/spring.hpp" -#include "animation/animation.hpp" -#include "scene/camera.hpp" - -class event_dispatcher; - -namespace entity { -namespace system { - -class tool: - public updatable, - public event_handler, - public event_handler -{ -public: - tool(entity::registry& registry, event_dispatcher* event_dispatcher); - virtual ~tool(); - virtual void update(double t, double dt); - - void set_camera(const scene::camera* camera); - void set_viewport(const float4& viewport); - void set_pick(bool enabled); - void set_sun_direction(const float3& direction); - - void set_active_tool(entity::id entity_id); - - void set_tool_active(bool active); - - entity::id get_active_tool() const; - -private: - virtual void handle_event(const mouse_moved_event& event); - virtual void handle_event(const window_resized_event& event); - - event_dispatcher* event_dispatcher; - const scene::camera* camera; - float4 viewport; - float2 mouse_position; - bool was_pick_enabled; - bool pick_enabled; - float3 sun_direction; - entity::id active_tool; - bool warp; - bool tool_active; - - - numeric_spring hand_angle_spring; - numeric_spring pick_spring; - - animation descend_animation; - animation ascend_animation; - float active_tool_distance; -}; - -inline entity::id tool::get_active_tool() const -{ - return active_tool; -} - -} // namespace system -} // namespace entity - -#endif // ANTKEEPER_ENTITY_SYSTEM_TOOL_HPP diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp index e7941cd..ab0f9ba 100644 --- a/src/game/bootloader.cpp +++ b/src/game/bootloader.cpp @@ -64,7 +64,6 @@ #include "entity/systems/samara.hpp" #include "entity/systems/subterrain.hpp" #include "entity/systems/terrain.hpp" -#include "entity/systems/tool.hpp" #include "entity/systems/ui.hpp" #include "entity/systems/vegetation.hpp" #include "entity/systems/spatial.hpp" @@ -794,11 +793,6 @@ void setup_systems(game::context* ctx) ctx->camera_system->set_viewport(viewport); 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_viewport(viewport); - // Setup subterrain system ctx->subterrain_system = new entity::system::subterrain(*ctx->entity_registry, ctx->resource_manager); ctx->subterrain_system->set_scene(ctx->underground_scene); @@ -1023,7 +1017,6 @@ void setup_callbacks(game::context* ctx) ctx->behavior_system->update(t, dt); ctx->locomotion_system->update(t, dt); ctx->camera_system->update(t, dt); - ctx->tool_system->update(t, dt); ctx->orbit_system->update(t, dt); ctx->blackbody_system->update(t, dt); diff --git a/src/game/context.hpp b/src/game/context.hpp index 2b43185..16f98b5 100644 --- a/src/game/context.hpp +++ b/src/game/context.hpp @@ -79,7 +79,6 @@ namespace entity class subterrain; class terrain; class vegetation; - class tool; class ui; class spatial; class tracking; @@ -233,7 +232,6 @@ struct context entity::system::samara* samara_system; entity::system::subterrain* subterrain_system; entity::system::terrain* terrain_system; - entity::system::tool* tool_system; entity::system::ui* ui_system; entity::system::vegetation* vegetation_system; entity::system::spatial* spatial_system; diff --git a/src/game/states/forage.cpp b/src/game/states/forage.cpp index 5a791ad..7be4745 100644 --- a/src/game/states/forage.cpp +++ b/src/game/states/forage.cpp @@ -23,6 +23,8 @@ #include "entity/components/observer.hpp" #include "entity/components/terrain.hpp" #include "entity/components/transform.hpp" +#include "entity/components/celestial-body.hpp" +#include "entity/components/tool.hpp" #include "entity/systems/astronomy.hpp" #include "animation/screen-transition.hpp" #include "animation/ease.hpp" @@ -44,6 +46,7 @@ static void setup_controls(game::context* ctx); void enter(game::context* ctx) { setup_camera(ctx); + setup_tools(ctx); setup_controls(ctx); // Find planet EID by name @@ -93,6 +96,15 @@ void enter(game::context* ctx) entity::command::assign_render_layers(*ctx->entity_registry, cocoon_eid, 0b10); } + // Create moon + { + entity::archetype* moon_archetype = ctx->resource_manager->load("moon.ent"); + auto moon_eid = moon_archetype->create(*ctx->entity_registry); + entity::command::warp_to(*ctx->entity_registry, moon_eid, {50.0f, 50.0f, 50.0f}); + entity::command::assign_render_layers(*ctx->entity_registry, moon_eid, 0b10); + entity::command::set_scale(*ctx->entity_registry, moon_eid, float3{1.0f, 1.0f, 1.0f} * 10.0f); + } + ctx->surface_scene->update_tweens(); // Start fade in @@ -226,14 +238,27 @@ void setup_tools(game::context* ctx) ctx->entities["label_tool"] = tool_eid; } - if (!ctx->entities.count("wait_tool")) + if (!ctx->entities.count("time_tool")) { entity::id tool_eid = ctx->entity_registry->create(); - ctx->entities["wait_tool"] = tool_eid; + ctx->entities["time_tool"] = tool_eid; + + entity::component::tool tool; + tool.active = [ctx]() + { + auto [mouse_x, mouse_y] = ctx->app->get_mouse()->get_current_position(); + auto [window_w, window_h] = ctx->app->get_viewport_dimensions(); + + entity::id planet_eid = ctx->entities["planet"]; + entity::component::celestial_body& body = ctx->entity_registry->get(planet_eid); + body.axial_tilt = math::radians(360.0f) * ((float)mouse_x / (float)window_w); + }; + + ctx->entity_registry->assign(tool_eid, tool); } - // Set move tool as active tool - ctx->entities["active_tool"] = ctx->entities["move_tool"]; + // Set active tool + ctx->entities["active_tool"] = ctx->entities["time_tool"]; } void setup_controls(game::context* ctx) @@ -466,33 +491,50 @@ void setup_controls(game::context* ctx) ( [ctx]() { - if (ctx->entities["active_tool"] == ctx->entities["move_tool"]) + if (ctx->entities.count("active_tool")) { - // Project mouse position into scene and grab selectable entity - auto [mouse_x, mouse_y] = ctx->app->get_mouse()->get_current_position(); + entity::id tool_eid = ctx->entities["active_tool"]; + const auto& tool = ctx->entity_registry->get(tool_eid); + if (tool.activated) + tool.activated(); } } ); - ctx->controls["use_tool"]->set_deactivated_callback ( [ctx]() { - if (ctx->entities["active_tool"] == ctx->entities["move_tool"]) + if (ctx->entities.count("active_tool")) { - + entity::id tool_eid = ctx->entities["active_tool"]; + const auto& tool = ctx->entity_registry->get(tool_eid); + if (tool.deactivated) + tool.deactivated(); } } ); - ctx->controls["use_tool"]->set_active_callback ( [ctx](float value) { - auto [mouse_x, mouse_y] = ctx->app->get_mouse()->get_current_position(); - ctx->logger->log("tool used (" + std::to_string(mouse_x) + ", " + std::to_string(mouse_y) + ")"); + if (ctx->entities.count("active_tool")) + { + entity::id tool_eid = ctx->entities["active_tool"]; + const auto& tool = ctx->entity_registry->get(tool_eid); + if (tool.active) + tool.active(); + } } ); + + /* + auto [mouse_x, mouse_y] = ctx->app->get_mouse()->get_current_position(); + ctx->logger->log("tool used (" + std::to_string(mouse_x) + ", " + std::to_string(mouse_y) + ")"); + + entity::id planet_eid = ctx->entities["planet"]; + entity::component::celestial_body& body = ctx->entity_registry->get(planet_eid); + body.axial_tilt += math::radians(30.0f) * 1.0f / 60.0f; + */ } } // namespace forage diff --git a/src/resources/entity-archetype-loader.cpp b/src/resources/entity-archetype-loader.cpp index 09904f3..0005cff 100644 --- a/src/resources/entity-archetype-loader.cpp +++ b/src/resources/entity-archetype-loader.cpp @@ -27,7 +27,6 @@ #include "entity/components/transform.hpp" #include "entity/components/model.hpp" #include "entity/components/nest.hpp" -#include "entity/components/tool.hpp" #include "entity/components/marker.hpp" #include "entity/components/brush.hpp" #include "entity/archetype.hpp" @@ -136,23 +135,6 @@ static bool load_component_brush(entity::archetype& archetype, const std::vector return true; } -static bool load_component_tool(entity::archetype& archetype, const std::vector& parameters) -{ - if (parameters.size() != 5) - { - throw std::runtime_error("load_component_tool(): Invalid parameter count."); - } - - entity::component::tool component; - component.active = static_cast(std::stoi(parameters[1])); - component.idle_distance = std::stof(parameters[2]); - component.active_distance = std::stof(parameters[3]); - component.heliotropic = static_cast(std::stoi(parameters[4])); - archetype.set(component); - - return true; -} - static bool load_component_transform(entity::archetype& archetype, const std::vector& parameters) { if (parameters.size() != 11) @@ -192,7 +174,6 @@ static bool load_component(entity::archetype& archetype, resource_manager& resou if (parameters[0] == "collision") return load_component_collision(archetype, resource_manager, parameters); if (parameters[0] == "model") return load_component_model(archetype, resource_manager, parameters); if (parameters[0] == "nest") return load_component_nest(archetype, parameters); - if (parameters[0] == "tool") return load_component_tool(archetype, parameters); if (parameters[0] == "transform") return load_component_transform(archetype, parameters); if (parameters[0] == "marker") return load_component_marker(archetype, parameters); if (parameters[0] == "brush") return load_component_brush(archetype, parameters);