From 6840e8c9d24d595327a53ca7121041dacc557e78 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Tue, 1 Sep 2020 13:18:32 -0700 Subject: [PATCH] Add tool events and tracking system --- CMakeLists.txt | 1 - src/game/bootloader.cpp | 138 +++++++++++----- src/game/components/marker-component.hpp | 32 ++++ src/game/components/trackable-component.hpp | 34 ++++ src/game/events/tool-events.cpp | 34 ++++ src/game/events/tool-events.hpp | 40 +++++ src/game/game-context.hpp | 3 + src/game/systems/control-system.cpp | 2 + src/game/systems/control-system.hpp | 14 ++ src/game/systems/tool-system.cpp | 25 ++- src/game/systems/tool-system.hpp | 5 +- src/game/systems/tracking-system.cpp | 174 ++++++++++++++++++++ src/game/systems/tracking-system.hpp | 67 ++++++++ src/resources/entity-archetype-loader.cpp | 16 ++ 14 files changed, 540 insertions(+), 45 deletions(-) create mode 100644 src/game/components/marker-component.hpp create mode 100644 src/game/components/trackable-component.hpp create mode 100644 src/game/events/tool-events.cpp create mode 100644 src/game/events/tool-events.hpp create mode 100644 src/game/systems/tracking-system.cpp create mode 100644 src/game/systems/tracking-system.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 17a1613..0b6fdd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,6 @@ find_package(SDL2 REQUIRED COMPONENTS SDL2::SDL2-static SDL2::SDL2main CONFIG) find_package(OpenAL REQUIRED CONFIG) find_library(physfs REQUIRED NAMES physfs-static PATHS "${CMAKE_PREFIX_PATH}/lib") - # Determine dependencies set(STATIC_LIBS dr_wav diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp index 4e3bd1a..713bcff 100644 --- a/src/game/bootloader.cpp +++ b/src/game/bootloader.cpp @@ -76,6 +76,8 @@ #include "game/systems/ui-system.hpp" #include "game/systems/vegetation-system.hpp" #include "game/systems/spatial-system.hpp" +#include "game/systems/tracking-system.hpp" +#include "game/components/marker-component.hpp" #include "game/entity-commands.hpp" #include "utility/paths.hpp" #include "event/event-dispatcher.hpp" @@ -555,6 +557,24 @@ void setup_rendering(game_context* ctx) ctx->billboard_vao->bind_attribute(VERTEX_BARYCENTRIC_LOCATION, *ctx->billboard_vbo, 3, vertex_attribute_type::float_32, billboard_vertex_stride, sizeof(float) * 5); } + // Load marker albedo textures + ctx->marker_albedo_textures = new texture_2d*[8]; + ctx->marker_albedo_textures[0] = ctx->resource_manager->load("marker-clear-albedo.png"); + ctx->marker_albedo_textures[1] = ctx->resource_manager->load("marker-yellow-albedo.png"); + ctx->marker_albedo_textures[2] = ctx->resource_manager->load("marker-green-albedo.png"); + ctx->marker_albedo_textures[3] = ctx->resource_manager->load("marker-blue-albedo.png"); + ctx->marker_albedo_textures[4] = ctx->resource_manager->load("marker-purple-albedo.png"); + ctx->marker_albedo_textures[5] = ctx->resource_manager->load("marker-pink-albedo.png"); + ctx->marker_albedo_textures[6] = ctx->resource_manager->load("marker-red-albedo.png"); + ctx->marker_albedo_textures[7] = ctx->resource_manager->load("marker-orange-albedo.png"); + for (int i = 0; i < 8; ++i) + { + texture_2d* texture = ctx->marker_albedo_textures[i]; + texture->set_wrapping(texture_wrapping::clamp, texture_wrapping::clamp); + texture->set_filters(texture_min_filter::nearest, texture_mag_filter::nearest); + texture->set_max_anisotropy(0.0f); + } + // Create renderer ctx->renderer = new renderer(); ctx->renderer->set_billboard_vao(ctx->billboard_vao); @@ -642,31 +662,6 @@ void setup_scenes(game_context* ctx) ctx->splash_billboard->set_translation({0.0f, 0.0f, 0.0f}); ctx->splash_billboard->update_tweens(); - material* billboard_material = new material(); - billboard_material->set_shader_program(ctx->resource_manager->load("ui-element-textured.glsl")); - billboard_material->add_property("background")->set_value(ctx->resource_manager->load("arrow.png")); - billboard_material->add_property("tint")->set_value(float4{1, 1, 1, 1}); - billboard_material->set_flags(MATERIAL_FLAG_TRANSLUCENT | MATERIAL_FLAG_NOT_SHADOW_CASTER); - billboard* arrow_billboard = new billboard(); - arrow_billboard->set_material(billboard_material); - arrow_billboard->set_scale(float3{1, 1, 1} * 2.0f); - arrow_billboard->set_translation({0, 10, 0}); - arrow_billboard->set_billboard_type(billboard_type::cylindrical); - arrow_billboard->set_alignment_axis({0, 1, 0}); - arrow_billboard->update_tweens(); - - billboard_material = new material(); - billboard_material->set_shader_program(ctx->resource_manager->load("portal-card.glsl")); - billboard_material->add_property("color")->set_value(float4{1, 1, 1, 1}); - billboard_material->add_property("range")->set_value(float2{50.0f, 500.0f}); - billboard_material->set_flags(MATERIAL_FLAG_TRANSLUCENT | MATERIAL_FLAG_NOT_SHADOW_CASTER); - billboard* portal_billboard = new billboard(); - portal_billboard->set_material(billboard_material); - portal_billboard->set_scale(float3{1, 1, 1} * 10.0f); - portal_billboard->set_translation({0.0f, 0, 0}); - portal_billboard->set_billboard_type(billboard_type::spherical); - portal_billboard->set_alignment_axis({0, 1, 0}); - portal_billboard->update_tweens(); // Create depth debug billboard /* @@ -688,7 +683,6 @@ void setup_scenes(game_context* ctx) ctx->overworld_scene->add_object(ctx->sun_indirect); ctx->overworld_scene->add_object(ctx->sun_direct); //ctx->overworld_scene->add_object(ctx->spotlight); - ctx->overworld_scene->add_object(arrow_billboard); // Setup underworld scene ctx->underworld_scene = new scene(); @@ -776,6 +770,8 @@ void setup_entities(game_context* ctx) void setup_systems(game_context* ctx) { + event_dispatcher* event_dispatcher = ctx->app->get_event_dispatcher(); + const auto& viewport_dimensions = ctx->app->get_viewport_dimensions(); float4 viewport = {0.0f, 0.0f, static_cast(viewport_dimensions[0]), static_cast(viewport_dimensions[1])}; @@ -794,9 +790,11 @@ void setup_systems(game_context* ctx) // Setup camera system ctx->camera_system = new camera_system(*ctx->ecs_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 tool_system(*ctx->ecs_registry); + ctx->tool_system = new tool_system(*ctx->ecs_registry, event_dispatcher); ctx->tool_system->set_camera(ctx->overworld_camera); ctx->tool_system->set_orbit_cam(ctx->camera_system->get_orbit_cam()); ctx->tool_system->set_viewport(viewport); @@ -839,6 +837,10 @@ void setup_systems(game_context* ctx) // Setup constraint system ctx->constraint_system = new constraint_system(*ctx->ecs_registry); + // Setup tracking system + ctx->tracking_system = new tracking_system(*ctx->ecs_registry, event_dispatcher, ctx->resource_manager); + ctx->tracking_system->set_scene(ctx->overworld_scene); + // Setup render system ctx->render_system = new ::render_system(*ctx->ecs_registry); ctx->render_system->add_layer(ctx->overworld_scene); @@ -857,6 +859,8 @@ void setup_systems(game_context* ctx) 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); // Setup UI system ctx->ui_system = new ui_system(ctx->resource_manager); @@ -864,6 +868,10 @@ void setup_systems(game_context* ctx) ctx->ui_system->set_scene(ctx->ui_scene); ctx->ui_system->set_viewport(viewport); ctx->ui_system->set_tool_menu_control(ctx->control_system->get_tool_menu_control()); + event_dispatcher->subscribe(ctx->ui_system); + event_dispatcher->subscribe(ctx->ui_system); + + } void setup_controls(game_context* ctx) @@ -1011,12 +1019,16 @@ void setup_controls(game_context* ctx) ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_rotate_ccw_control(), nullptr, scancode::q)); ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_rotate_cw_control(), nullptr, scancode::e)); - ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_forceps_control(), nullptr, scancode::one)); - ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_brush_control(), nullptr, scancode::two)); - ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_lens_control(), nullptr, scancode::three)); - ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_marker_control(), nullptr, scancode::four)); - ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_container_control(), nullptr, scancode::five)); - ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_twig_control(), nullptr, scancode::six)); + + ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_brush_control(), nullptr, scancode::one)); + ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_twig_control(), nullptr, scancode::two)); + ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_forceps_control(), nullptr, scancode::three)); + ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_container_control(), nullptr, scancode::four)); + ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_lens_control(), nullptr, scancode::five)); + ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_equip_marker_control(), nullptr, scancode::six)); + + ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_next_marker_control(), nullptr, scancode::right_brace)); + ctx->input_event_router->add_mapping(key_mapping(ctx->control_system->get_previous_marker_control(), nullptr, scancode::left_brace)); ctx->input_event_router->add_mapping(mouse_button_mapping(ctx->control_system->get_use_tool_control(), nullptr, 1)); ctx->control_system->get_use_tool_control()->set_activated_callback @@ -1077,15 +1089,58 @@ void setup_controls(game_context* ctx) } ); - event_dispatcher->subscribe(ctx->control_system); - event_dispatcher->subscribe(ctx->camera_system); - event_dispatcher->subscribe(ctx->tool_system); - event_dispatcher->subscribe(ctx->ui_system); - event_dispatcher->subscribe(ctx->control_system); - event_dispatcher->subscribe(ctx->camera_system); - event_dispatcher->subscribe(ctx->tool_system); - event_dispatcher->subscribe(ctx->ui_system); + + ctx->control_system->get_next_marker_control()->set_activated_callback + ( + [ctx]() + { + auto& marker_component = ctx->ecs_registry->get(ctx->marker_entity); + marker_component.color = (marker_component.color + 1) % 8; + const texture_2d* marker_albedo_texture = ctx->marker_albedo_textures[marker_component.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->control_system->get_previous_marker_control()->set_activated_callback + ( + [ctx]() + { + auto& marker_component = ctx->ecs_registry->get(ctx->marker_entity); + marker_component.color = (marker_component.color + 7) % 8; + const texture_2d* marker_albedo_texture = ctx->marker_albedo_textures[marker_component.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); + } + } + } + ); + + + + + // Make lens tool's model instance unculled, so its shadow is always visible. + model_instance* lens_model_instance = ctx->render_system->get_model_instance(ctx->lens_entity); + if (lens_model_instance) + { + lens_model_instance->set_culling_mask(&ctx->no_cull); + } + } void setup_cli(game_context* ctx) @@ -1133,6 +1188,7 @@ void setup_callbacks(game_context* ctx) ctx->spatial_system->update(t, dt); ctx->constraint_system->update(t, dt); + ctx->tracking_system->update(t, dt); //(*ctx->focal_point_tween)[1] = ctx->orbit_cam->get_focal_point(); diff --git a/src/game/components/marker-component.hpp b/src/game/components/marker-component.hpp new file mode 100644 index 0000000..c90cbf0 --- /dev/null +++ b/src/game/components/marker-component.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 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_ECS_MARKER_COMPONENT_HPP +#define ANTKEEPER_ECS_MARKER_COMPONENT_HPP + +namespace ecs { + +struct marker_component +{ + int color; +}; + +} // namespace ecs + +#endif // ANTKEEPER_ECS_MARKER_COMPONENT_HPP diff --git a/src/game/components/trackable-component.hpp b/src/game/components/trackable-component.hpp new file mode 100644 index 0000000..7aa3844 --- /dev/null +++ b/src/game/components/trackable-component.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2020 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_ECS_TRACKABLE_COMPONENT_HPP +#define ANTKEEPER_ECS_TRACKABLE_COMPONENT_HPP + +#include "utility/fundamental-types.hpp" + +namespace ecs { + +struct trackable_component +{ + float distance; +}; + +} // namespace ecs + +#endif // ANTKEEPER_ECS_TRACKABLE_COMPONENT_HPP diff --git a/src/game/events/tool-events.cpp b/src/game/events/tool-events.cpp new file mode 100644 index 0000000..bcb51e2 --- /dev/null +++ b/src/game/events/tool-events.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2020 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 "game/events/tool-events.hpp" + +event_base* tool_pressed_event::clone() const +{ + tool_pressed_event* event = new tool_pressed_event(); + event->entity = entity; + return event; +} + +event_base* tool_released_event::clone() const +{ + tool_released_event* event = new tool_released_event(); + event->entity = entity; + return event; +} diff --git a/src/game/events/tool-events.hpp b/src/game/events/tool-events.hpp new file mode 100644 index 0000000..4b41581 --- /dev/null +++ b/src/game/events/tool-events.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 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_TOOL_EVENTS_HPP +#define ANTKEEPER_TOOL_EVENTS_HPP + +#include "event/event.hpp" +#include + +class tool_pressed_event: public event +{ +public: + virtual event_base* clone() const; + entt::entity entity; +}; + +class tool_released_event: public event +{ +public: + virtual event_base* clone() const; + entt::entity entity; +}; + +#endif // ANTKEEPER_TOOL_EVENTS_HPP diff --git a/src/game/game-context.hpp b/src/game/game-context.hpp index fbc4517..cdcb105 100644 --- a/src/game/game-context.hpp +++ b/src/game/game-context.hpp @@ -84,6 +84,7 @@ class input_event_router; class input_mapper; class cli; class outline_pass; +class tracking_system; template class animation; template class material_property; template class tween; @@ -144,6 +145,7 @@ struct game_context vertex_array* billboard_vao; material* fallback_material; material* splash_billboard_material; + texture_2d** marker_albedo_textures; // Compositing bloom_pass* overworld_bloom_pass; @@ -234,6 +236,7 @@ struct game_context ui_system* ui_system; vegetation_system* vegetation_system; spatial_system* spatial_system; + tracking_system* tracking_system; // Debug cli* cli; diff --git a/src/game/systems/control-system.cpp b/src/game/systems/control-system.cpp index 8f0754e..6802c43 100644 --- a/src/game/systems/control-system.cpp +++ b/src/game/systems/control-system.cpp @@ -57,6 +57,8 @@ control_system::control_system(entt::registry& registry): control_set.add_control(&equip_marker_control); control_set.add_control(&equip_container_control); control_set.add_control(&equip_twig_control); + control_set.add_control(&next_marker_control); + control_set.add_control(&previous_marker_control); control_set.add_control(&use_tool_control); // Set deadzone at 15% for all controls diff --git a/src/game/systems/control-system.hpp b/src/game/systems/control-system.hpp index a3f9f50..65702f9 100644 --- a/src/game/systems/control-system.hpp +++ b/src/game/systems/control-system.hpp @@ -77,6 +77,8 @@ public: control* get_equip_marker_control(); control* get_equip_container_control(); control* get_equip_twig_control(); + control* get_next_marker_control(); + control* get_previous_marker_control(); control* get_use_tool_control(); private: @@ -105,6 +107,8 @@ private: control equip_marker_control; control equip_container_control; control equip_twig_control; + control next_marker_control; + control previous_marker_control; control use_tool_control; float zoom_speed; @@ -250,6 +254,16 @@ inline control* control_system::get_equip_twig_control() return &equip_twig_control; } +inline control* control_system::get_next_marker_control() +{ + return &next_marker_control; +} + +inline control* control_system::get_previous_marker_control() +{ + return &previous_marker_control; +} + inline control* control_system::get_use_tool_control() { return &use_tool_control; diff --git a/src/game/systems/tool-system.cpp b/src/game/systems/tool-system.cpp index 4acfb74..9167cee 100644 --- a/src/game/systems/tool-system.cpp +++ b/src/game/systems/tool-system.cpp @@ -21,6 +21,8 @@ #include "game/components/collision-component.hpp" #include "game/components/tool-component.hpp" #include "game/components/transform-component.hpp" +#include "event/event-dispatcher.hpp" +#include "game/events/tool-events.hpp" #include "scene/camera.hpp" #include "animation/orbit-cam.hpp" #include "animation/ease.hpp" @@ -28,12 +30,12 @@ #include "geometry/intersection.hpp" #include "math/math.hpp" #include "game/entity-commands.hpp" -#include using namespace ecs; -tool_system::tool_system(entt::registry& registry): +tool_system::tool_system(entt::registry& registry, ::event_dispatcher* event_dispatcher): entity_system(registry), + event_dispatcher(event_dispatcher), camera(nullptr), orbit_cam(orbit_cam), viewport{0, 0, 0, 0}, @@ -79,6 +81,15 @@ tool_system::tool_system(entt::registry& registry): active_tool_distance = 0.0f; warp = true; tool_active = false; + + event_dispatcher->subscribe(this); + event_dispatcher->subscribe(this); +} + +tool_system::~tool_system() +{ + event_dispatcher->unsubscribe(this); + event_dispatcher->unsubscribe(this); } void tool_system::update(double t, double dt) @@ -281,11 +292,21 @@ void tool_system::set_tool_active(bool active) { descend_animation.rewind(); descend_animation.play(); + + // Queue tool pressed event + tool_pressed_event event; + event.entity = active_tool; + event_dispatcher->queue(event); } else { ascend_animation.rewind(); ascend_animation.play(); + + // Queue tool pressed event + tool_released_event event; + event.entity = active_tool; + event_dispatcher->queue(event); } } diff --git a/src/game/systems/tool-system.hpp b/src/game/systems/tool-system.hpp index 152cf62..e386013 100644 --- a/src/game/systems/tool-system.hpp +++ b/src/game/systems/tool-system.hpp @@ -30,6 +30,7 @@ class camera; class orbit_cam; +class event_dispatcher; class tool_system: public entity_system, @@ -37,7 +38,8 @@ class tool_system: public event_handler { public: - tool_system(entt::registry& registry); + tool_system(entt::registry& registry, event_dispatcher* event_dispatcher); + virtual ~tool_system(); virtual void update(double t, double dt); void set_camera(const camera* camera); @@ -56,6 +58,7 @@ private: virtual void handle_event(const mouse_moved_event& event); virtual void handle_event(const window_resized_event& event); + event_dispatcher* event_dispatcher; const camera* camera; const orbit_cam* orbit_cam; float4 viewport; diff --git a/src/game/systems/tracking-system.cpp b/src/game/systems/tracking-system.cpp new file mode 100644 index 0000000..b9bdbb8 --- /dev/null +++ b/src/game/systems/tracking-system.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2020 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 "tracking-system.hpp" +#include "game/components/transform-component.hpp" +#include "game/components/marker-component.hpp" +#include "event/event-dispatcher.hpp" +#include "resources/resource-manager.hpp" +#include "scene/billboard.hpp" +#include "scene/scene.hpp" +#include "scene/model-instance.hpp" +#include "math/math.hpp" +#include "renderer/material.hpp" +#include "renderer/material-flags.hpp" +#include "renderer/model.hpp" +#include "rasterizer/texture-2d.hpp" +#include "rasterizer/shader-program.hpp" +#include "utility/fundamental-types.hpp" +#include "game/entity-commands.hpp" +#include + +using namespace ecs; + +tracking_system::tracking_system(entt::registry& registry, ::event_dispatcher* event_dispatcher, ::resource_manager* resource_manager): + entity_system(registry), + event_dispatcher(event_dispatcher), + resource_manager(resource_manager), + scene(nullptr) +{ + registry.on_construct().connect<&tracking_system::on_component_construct>(this); + registry.on_destroy().connect<&tracking_system::on_component_destroy>(this); + + // Load tracker material + tracker_material = resource_manager->load("tracker.mtl"); + + // Load paint ball model + paint_ball_model = resource_manager->load("paint-ball.obj"); + + // Load paint ball materials + paint_ball_materials = new material*[7]; + paint_ball_materials[0] = resource_manager->load("paint-ball-yellow.mtl"); + paint_ball_materials[1] = resource_manager->load("paint-ball-green.mtl"); + paint_ball_materials[2] = resource_manager->load("paint-ball-blue.mtl"); + paint_ball_materials[3] = resource_manager->load("paint-ball-purple.mtl"); + paint_ball_materials[4] = resource_manager->load("paint-ball-pink.mtl"); + paint_ball_materials[5] = resource_manager->load("paint-ball-red.mtl"); + paint_ball_materials[6] = resource_manager->load("paint-ball-orange.mtl"); + + event_dispatcher->subscribe(this); + event_dispatcher->subscribe(this); + event_dispatcher->subscribe(this); +} + +tracking_system::~tracking_system() +{ + event_dispatcher->unsubscribe(this); + event_dispatcher->unsubscribe(this); + event_dispatcher->unsubscribe(this); + + for (auto it = billboards.begin(); it != billboards.end(); ++it) + { + delete it->second; + } + + delete[] paint_ball_materials; +} + + +void tracking_system::update(double t, double dt) +{ + for (auto it = billboards.begin(); it != billboards.end(); ++it) + { + const transform_component& transform = registry.get(it->first); + + // Project world coordinates to screen coordinates + + // Update billboard position + it->second->set_translation(transform.world.translation); + if (transform.warp) + { + it->second->update_tweens(); + } + } +} + +void tracking_system::set_scene(::scene* scene) +{ + this->scene = scene; +} + +void tracking_system::set_viewport(const float4& viewport) +{ + this->viewport = viewport; +} + +void tracking_system::on_component_construct(entt::registry& registry, entt::entity entity, trackable_component& component) +{ + +} + +void tracking_system::on_component_destroy(entt::registry& registry, entt::entity entity) +{ + if (auto it = billboards.find(entity); it != billboards.end()) + { + // Remove model instance from all layers + /* + for (std::size_t i = 0; i < layers.size(); ++i) + { + layers[i]->remove_object(it->second); + } + */ + + delete it->second; + billboards.erase(it); + } +} + +void tracking_system::handle_event(const tool_pressed_event& event) +{ + if (registry.has(event.entity)) + { + math::transform transform = ec::get_world_transform(registry, event.entity); + + int marker_index = registry.get(event.entity).color; + + if (marker_index > 0) + { + ::billboard* billboard = new ::billboard(); + billboard->set_material(tracker_material); + billboard->set_scale(float3{1, 1, 1}); + billboard->set_translation(transform.translation); + billboard->set_billboard_type(billboard_type::spherical); + //billboard->set_alignment_axis({0, 1, 0}); + billboard->update_tweens(); + + const float paint_ball_scale = 0.393f; + model_instance* instance = new model_instance(); + instance->set_model(paint_ball_model); + instance->set_material(0, paint_ball_materials[marker_index - 1]); + instance->set_translation(transform.translation); + instance->set_scale(float3{paint_ball_scale, paint_ball_scale, paint_ball_scale}); + instance->update_tweens(); + + scene->add_object(billboard); + scene->add_object(instance); + } + } +} + +void tracking_system::handle_event(const tool_released_event& event) +{ + +} + +void tracking_system::handle_event(const window_resized_event& event) +{ + set_viewport({0.0f, 0.0f, static_cast(event.w), static_cast(event.h)}); +} diff --git a/src/game/systems/tracking-system.hpp b/src/game/systems/tracking-system.hpp new file mode 100644 index 0000000..0c8505c --- /dev/null +++ b/src/game/systems/tracking-system.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 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_TRACKING_SYSTEM_HPP +#define ANTKEEPER_TRACKING_SYSTEM_HPP + +#include "entity-system.hpp" +#include "game/components/trackable-component.hpp" +#include "event/event-handler.hpp" +#include "event/window-events.hpp" +#include "game/events/tool-events.hpp" +#include + +class billboard; +class material; +class event_dispatcher; +class resource_manager; +class scene; +class model; + +class tracking_system: public entity_system, + public event_handler, + public event_handler, + public event_handler +{ +public: + tracking_system(entt::registry& registry, event_dispatcher* event_dispatcher, resource_manager* resource_manager); + virtual ~tracking_system(); + virtual void update(double t, double dt); + + void set_scene(scene* scene); + void set_viewport(const float4& viewport); + +private: + void on_component_construct(entt::registry& registry, entt::entity entity, ecs::trackable_component& component); + void on_component_destroy(entt::registry& registry, entt::entity entity); + virtual void handle_event(const tool_pressed_event& event); + virtual void handle_event(const tool_released_event& event); + virtual void handle_event(const window_resized_event& event); + + event_dispatcher* event_dispatcher; + resource_manager* resource_manager; + scene* scene; + float4 viewport; + material* tracker_material; + model* paint_ball_model; + material** paint_ball_materials; + std::unordered_map billboards; +}; + +#endif // ANTKEEPER_TRACKING_SYSTEM_HPP diff --git a/src/resources/entity-archetype-loader.cpp b/src/resources/entity-archetype-loader.cpp index ce6d70b..4bd4314 100644 --- a/src/resources/entity-archetype-loader.cpp +++ b/src/resources/entity-archetype-loader.cpp @@ -28,6 +28,7 @@ #include "game/components/model-component.hpp" #include "game/components/nest-component.hpp" #include "game/components/tool-component.hpp" +#include "game/components/marker-component.hpp" #include "entity/archetype.hpp" #include "game/behavior/ebt.hpp" #include @@ -108,6 +109,20 @@ static bool load_nest_component(archetype& archetype, const std::vector& parameters) +{ + if (parameters.size() != 2) + { + throw std::runtime_error("load_marker_component(): Invalid parameter count."); + } + + marker_component component; + component.color = std::stoi(parameters[1]); + archetype.set(component); + + return true; +} + static bool load_terrain_component(archetype& archetype, const std::vector& parameters) { if (parameters.size() != 4) @@ -183,6 +198,7 @@ static bool load_component(archetype& archetype, resource_manager& resource_mana if (parameters[0] == "terrain") return load_terrain_component(archetype, parameters); if (parameters[0] == "tool") return load_tool_component(archetype, parameters); if (parameters[0] == "transform") return load_transform_component(archetype, parameters); + if (parameters[0] == "marker") return load_marker_component(archetype, parameters); std::string message = std::string("load_component(): Unknown component type \"") + parameters[0] + std::string("\""); throw std::runtime_error(message);