Browse Source

Add tool events and tracking system

master
C. J. Howard 1 year ago
parent
commit
6840e8c9d2
14 changed files with 540 additions and 45 deletions
  1. +0
    -1
      CMakeLists.txt
  2. +97
    -41
      src/game/bootloader.cpp
  3. +32
    -0
      src/game/components/marker-component.hpp
  4. +34
    -0
      src/game/components/trackable-component.hpp
  5. +34
    -0
      src/game/events/tool-events.cpp
  6. +40
    -0
      src/game/events/tool-events.hpp
  7. +3
    -0
      src/game/game-context.hpp
  8. +2
    -0
      src/game/systems/control-system.cpp
  9. +14
    -0
      src/game/systems/control-system.hpp
  10. +23
    -2
      src/game/systems/tool-system.cpp
  11. +4
    -1
      src/game/systems/tool-system.hpp
  12. +174
    -0
      src/game/systems/tracking-system.cpp
  13. +67
    -0
      src/game/systems/tracking-system.hpp
  14. +16
    -0
      src/resources/entity-archetype-loader.cpp

+ 0
- 1
CMakeLists.txt View File

@ -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

+ 97
- 41
src/game/bootloader.cpp View File

@ -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<texture_2d>("marker-clear-albedo.png");
ctx->marker_albedo_textures[1] = ctx->resource_manager->load<texture_2d>("marker-yellow-albedo.png");
ctx->marker_albedo_textures[2] = ctx->resource_manager->load<texture_2d>("marker-green-albedo.png");
ctx->marker_albedo_textures[3] = ctx->resource_manager->load<texture_2d>("marker-blue-albedo.png");
ctx->marker_albedo_textures[4] = ctx->resource_manager->load<texture_2d>("marker-purple-albedo.png");
ctx->marker_albedo_textures[5] = ctx->resource_manager->load<texture_2d>("marker-pink-albedo.png");
ctx->marker_albedo_textures[6] = ctx->resource_manager->load<texture_2d>("marker-red-albedo.png");
ctx->marker_albedo_textures[7] = ctx->resource_manager->load<texture_2d>("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<shader_program>("ui-element-textured.glsl"));
billboard_material->add_property<const texture_2d*>("background")->set_value(ctx->resource_manager->load<texture_2d>("arrow.png"));
billboard_material->add_property<float4>("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<shader_program>("portal-card.glsl"));
billboard_material->add_property<float4>("color")->set_value(float4{1, 1, 1, 1});
billboard_material->add_property<float2>("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<float>(viewport_dimensions[0]), static_cast<float>(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<mouse_moved_event>(ctx->camera_system);
event_dispatcher->subscribe<window_resized_event>(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<mouse_moved_event>(ctx->control_system);
event_dispatcher->subscribe<window_resized_event>(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<mouse_moved_event>(ctx->ui_system);
event_dispatcher->subscribe<window_resized_event>(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<mouse_moved_event>(ctx->control_system);
event_dispatcher->subscribe<mouse_moved_event>(ctx->camera_system);
event_dispatcher->subscribe<mouse_moved_event>(ctx->tool_system);
event_dispatcher->subscribe<mouse_moved_event>(ctx->ui_system);
event_dispatcher->subscribe<window_resized_event>(ctx->control_system);
event_dispatcher->subscribe<window_resized_event>(ctx->camera_system);
event_dispatcher->subscribe<window_resized_event>(ctx->tool_system);
event_dispatcher->subscribe<window_resized_event>(ctx->ui_system);
ctx->control_system->get_next_marker_control()->set_activated_callback
(
[ctx]()
{
auto& marker_component = ctx->ecs_registry->get<ecs::marker_component>(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<material_property<const texture_2d*>*>(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<ecs::marker_component>(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<material_property<const texture_2d*>*>(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();

+ 32
- 0
src/game/components/marker-component.hpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

+ 34
- 0
src/game/components/trackable-component.hpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

+ 34
- 0
src/game/events/tool-events.cpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}

+ 40
- 0
src/game/events/tool-events.hpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_TOOL_EVENTS_HPP
#define ANTKEEPER_TOOL_EVENTS_HPP
#include "event/event.hpp"
#include <entt/entt.hpp>
class tool_pressed_event: public event<tool_pressed_event>
{
public:
virtual event_base* clone() const;
entt::entity entity;
};
class tool_released_event: public event<tool_released_event>
{
public:
virtual event_base* clone() const;
entt::entity entity;
};
#endif // ANTKEEPER_TOOL_EVENTS_HPP

+ 3
- 0
src/game/game-context.hpp View File

@ -84,6 +84,7 @@ class input_event_router;
class input_mapper;
class cli;
class outline_pass;
class tracking_system;
template <typename T> class animation;
template <typename T> class material_property;
template <typename T> 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;

+ 2
- 0
src/game/systems/control-system.cpp View File

@ -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

+ 14
- 0
src/game/systems/control-system.hpp View File

@ -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;

+ 23
- 2
src/game/systems/tool-system.cpp View File

@ -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 <iostream>
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<mouse_moved_event>(this);
event_dispatcher->subscribe<window_resized_event>(this);
}
tool_system::~tool_system()
{
event_dispatcher->unsubscribe<mouse_moved_event>(this);
event_dispatcher->unsubscribe<window_resized_event>(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);
}
}

+ 4
- 1
src/game/systems/tool-system.hpp View File

@ -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<window_resized_event>
{
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;

+ 174
- 0
src/game/systems/tracking-system.cpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 <iostream>
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<trackable_component>().connect<&tracking_system::on_component_construct>(this);
registry.on_destroy<trackable_component>().connect<&tracking_system::on_component_destroy>(this);
// Load tracker material
tracker_material = resource_manager->load<material>("tracker.mtl");
// Load paint ball model
paint_ball_model = resource_manager->load<model>("paint-ball.obj");
// Load paint ball materials
paint_ball_materials = new material*[7];
paint_ball_materials[0] = resource_manager->load<material>("paint-ball-yellow.mtl");
paint_ball_materials[1] = resource_manager->load<material>("paint-ball-green.mtl");
paint_ball_materials[2] = resource_manager->load<material>("paint-ball-blue.mtl");
paint_ball_materials[3] = resource_manager->load<material>("paint-ball-purple.mtl");
paint_ball_materials[4] = resource_manager->load<material>("paint-ball-pink.mtl");
paint_ball_materials[5] = resource_manager->load<material>("paint-ball-red.mtl");
paint_ball_materials[6] = resource_manager->load<material>("paint-ball-orange.mtl");
event_dispatcher->subscribe<tool_pressed_event>(this);
event_dispatcher->subscribe<tool_released_event>(this);
event_dispatcher->subscribe<window_resized_event>(this);
}
tracking_system::~tracking_system()
{
event_dispatcher->unsubscribe<tool_pressed_event>(this);
event_dispatcher->unsubscribe<tool_released_event>(this);
event_dispatcher->unsubscribe<window_resized_event>(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<transform_component>(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<marker_component>(event.entity))
{
math::transform<float> transform = ec::get_world_transform(registry, event.entity);
int marker_index = registry.get<marker_component>(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<float>(event.w), static_cast<float>(event.h)});
}

+ 67
- 0
src/game/systems/tracking-system.hpp View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 <unordered_map>
class billboard;
class material;
class event_dispatcher;
class resource_manager;
class scene;
class model;
class tracking_system: public entity_system,
public event_handler<tool_pressed_event>,
public event_handler<tool_released_event>,
public event_handler<window_resized_event>
{
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<entt::entity, billboard*> billboards;
};
#endif // ANTKEEPER_TRACKING_SYSTEM_HPP

+ 16
- 0
src/resources/entity-archetype-loader.cpp View File

@ -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 <sstream>
@ -108,6 +109,20 @@ static bool load_nest_component(archetype& archetype, const std::vector
return true;
}
static bool load_marker_component(archetype& archetype, const std::vector<std::string>& 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<marker_component>(component);
return true;
}
static bool load_terrain_component(archetype& archetype, const std::vector<std::string>& 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);

Loading…
Cancel
Save