From d6022e7d82b1acd628e57844252b0eb19be4243f Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Sat, 8 Aug 2020 22:23:15 -0700 Subject: [PATCH] Add constraint system --- CMakeLists.txt | 1 - src/application.cpp | 6 +- src/application.hpp | 2 + src/entity/components/chamber-component.hpp | 37 +++++++ .../components/copy-rotation-component.hpp | 34 +++++++ .../components/copy-scale-component.hpp | 37 +++++++ .../components/copy-transform-component.hpp | 34 +++++++ .../components/copy-translation-component.hpp | 40 ++++++++ src/scene/scene-object.hpp | 4 +- src/state/play-state.cpp | 14 +++ src/systems/constraint-system.cpp | 97 +++++++++++++++++++ src/systems/constraint-system.hpp | 33 +++++++ 12 files changed, 334 insertions(+), 5 deletions(-) create mode 100644 src/entity/components/chamber-component.hpp create mode 100644 src/entity/components/copy-rotation-component.hpp create mode 100644 src/entity/components/copy-scale-component.hpp create mode 100644 src/entity/components/copy-transform-component.hpp create mode 100644 src/entity/components/copy-translation-component.hpp create mode 100644 src/systems/constraint-system.cpp create mode 100644 src/systems/constraint-system.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d516876..7739ede 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,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 vmq diff --git a/src/application.cpp b/src/application.cpp index b9b61a4..c9ea6d2 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -100,6 +100,7 @@ #include "systems/tool-system.hpp" #include "systems/control-system.hpp" #include "systems/ui-system.hpp" +#include "systems/constraint-system.hpp" #include // Entity components @@ -570,6 +571,7 @@ application::application(int argc, char** argv): placement_system = new ::placement_system(ecs_registry); behavior_system = new ::behavior_system(ecs_registry); locomotion_system = new ::locomotion_system(ecs_registry); + constraint_system = new ::constraint_system(ecs_registry); model_system = new ::model_system(ecs_registry, overworld_scene); // Setup systems @@ -588,15 +590,15 @@ application::application(int argc, char** argv): systems.push_back(std::bind(&behavior_system::update, behavior_system, std::placeholders::_1, std::placeholders::_2)); systems.push_back(std::bind(&locomotion_system::update, locomotion_system, std::placeholders::_1, std::placeholders::_2)); systems.push_back([this](double t, double dt){ this->control_system->update(dt); }); + systems.push_back(std::bind(&tool_system::update, tool_system, std::placeholders::_1, std::placeholders::_2)); + systems.push_back(std::bind(&constraint_system::update, constraint_system, std::placeholders::_1, std::placeholders::_2)); systems.push_back([this](double t, double dt){ this->subterrain_light.set_translation(orbit_cam.get_focal_point()); this->lantern.set_translation(orbit_cam.get_focal_point()); this->spotlight.set_transform(overworld_camera.get_transform()); this->focal_point_tween[1] = orbit_cam.get_focal_point(); }); - systems.push_back([this](double t, double dt){ this->ui_system->update(dt); }); - systems.push_back(std::bind(&tool_system::update, tool_system, std::placeholders::_1, std::placeholders::_2)); systems.push_back(std::bind(&model_system::update, model_system, std::placeholders::_1, std::placeholders::_2)); systems.push_back([this](double t, double dt){ this->animator->animate(dt); }); systems.push_back([this](double t, double dt){ this->application_controls.update(); this->menu_controls.update(); this->camera_controls->update(); }); diff --git a/src/application.hpp b/src/application.hpp index ba226c0..ab827b5 100644 --- a/src/application.hpp +++ b/src/application.hpp @@ -118,6 +118,7 @@ class vegetation_system; class tool_system; class control_system; + class constraint_system; class ui_system; // Scene @@ -335,6 +336,7 @@ private: terrain_system* terrain_system; vegetation_system* vegetation_system; tool_system* tool_system; + constraint_system* constraint_system; // UI ui_system* ui_system; diff --git a/src/entity/components/chamber-component.hpp b/src/entity/components/chamber-component.hpp new file mode 100644 index 0000000..a6e90cd --- /dev/null +++ b/src/entity/components/chamber-component.hpp @@ -0,0 +1,37 @@ +/* + * 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_CHAMBER_COMPONENT_HPP +#define ANTKEEPER_ECS_CHAMBER_COMPONENT_HPP + +#include +#include + +namespace ecs { + +struct chamber_component +{ + entt::entity nest; + float depth; + std::unordered_set> tiles; +} + +} // namespace ecs + +#endif // ANTKEEPER_ECS_CHAMBER_COMPONENT_HPP diff --git a/src/entity/components/copy-rotation-component.hpp b/src/entity/components/copy-rotation-component.hpp new file mode 100644 index 0000000..1c46c12 --- /dev/null +++ b/src/entity/components/copy-rotation-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_COPY_ROTATION_COMPONENT_HPP +#define ANTKEEPER_COPY_ROTATION_COMPONENT_HPP + +#include + +namespace ecs { + +struct copy_rotation_component +{ + entt::entity target; +}; + +} // namespace ecs + +#endif // ANTKEEPER_COPY_ROTATION_COMPONENT_HPP diff --git a/src/entity/components/copy-scale-component.hpp b/src/entity/components/copy-scale-component.hpp new file mode 100644 index 0000000..69ff652 --- /dev/null +++ b/src/entity/components/copy-scale-component.hpp @@ -0,0 +1,37 @@ +/* + * 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_COPY_SCALE_COMPONENT_HPP +#define ANTKEEPER_COPY_SCALE_COMPONENT_HPP + +#include + +namespace ecs { + +struct copy_scale_component +{ + entt::entity target; + bool use_x; + bool use_y; + bool use_z; +}; + +} // namespace ecs + +#endif // ANTKEEPER_COPY_SCALE_COMPONENT_HPP diff --git a/src/entity/components/copy-transform-component.hpp b/src/entity/components/copy-transform-component.hpp new file mode 100644 index 0000000..14c9bd0 --- /dev/null +++ b/src/entity/components/copy-transform-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_COPY_TRANSFORM_COMPONENT_HPP +#define ANTKEEPER_COPY_TRANSFORM_COMPONENT_HPP + +#include + +namespace ecs { + +struct copy_transform_component +{ + entt::entity target; +}; + +} // namespace ecs + +#endif // ANTKEEPER_COPY_TRANSFORM_COMPONENT_HPP diff --git a/src/entity/components/copy-translation-component.hpp b/src/entity/components/copy-translation-component.hpp new file mode 100644 index 0000000..020e1ca --- /dev/null +++ b/src/entity/components/copy-translation-component.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_COPY_TRANSLATION_COMPONENT_HPP +#define ANTKEEPER_COPY_TRANSLATION_COMPONENT_HPP + +#include + +namespace ecs { + +struct copy_translation_component +{ + entt::entity target; + bool use_x; + bool use_y; + bool use_z; + bool invert_x; + bool invert_y; + bool invert_z; +}; + +} // namespace ecs + +#endif // ANTKEEPER_COPY_TRANSLATION_COMPONENT_HPP diff --git a/src/scene/scene-object.hpp b/src/scene/scene-object.hpp index b1ca26a..4ee883e 100644 --- a/src/scene/scene-object.hpp +++ b/src/scene/scene-object.hpp @@ -36,7 +36,7 @@ using vmq::transform; class scene_object_base { public: - /// Returns the type ID for this scene_object type. + /// Returns the type ID for this scene object type. virtual const std::size_t get_object_type_id() const = 0; /** @@ -220,7 +220,7 @@ template class scene_object: public scene_object_base { public: - /// Unique type ID for this scene_object type. + /// Unique type ID for this scene object type. static const std::atomic object_type_id; virtual const std::size_t get_object_type_id() const final; diff --git a/src/state/play-state.cpp b/src/state/play-state.cpp index e0fad97..9a66e4d 100644 --- a/src/state/play-state.cpp +++ b/src/state/play-state.cpp @@ -34,6 +34,8 @@ #include "entity/components/cavity-component.hpp" #include "entity/components/tool-component.hpp" #include "entity/components/placement-component.hpp" +#include "entity/components/copy-transform-component.hpp" +#include "entity/components/copy-translation-component.hpp" #include "entity/archetype.hpp" #include "nest.hpp" #include "math.hpp" @@ -162,6 +164,18 @@ void enter_play_state(application* app) ecs::tool_component forceps_tool_component; forceps_tool_component.active = true; ecs_registry.assign(forceps_entity, forceps_tool_component); + + + // Add copy transform constraint to ant-hill + ecs::copy_translation_component constraint; + constraint.target = forceps_entity; + constraint.use_x = true; + constraint.use_y = true; + constraint.use_z = true; + constraint.invert_x = true; + constraint.invert_y = false; + constraint.invert_z = true; + ecs_registry.assign(ant_hill_entity, constraint); app->get_scene().update_tweens(); diff --git a/src/systems/constraint-system.cpp b/src/systems/constraint-system.cpp new file mode 100644 index 0000000..09d0367 --- /dev/null +++ b/src/systems/constraint-system.cpp @@ -0,0 +1,97 @@ +/* + * 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 "constraint-system.hpp" +#include "entity/components/copy-translation-component.hpp" +#include "entity/components/copy-rotation-component.hpp" +#include "entity/components/copy-scale-component.hpp" +#include "entity/components/copy-transform-component.hpp" +#include "entity/components/transform-component.hpp" + +using namespace ecs; +using namespace vmq; + +constraint_system::constraint_system(entt::registry& registry): + entity_system(registry) +{} + +void constraint_system::update(double t, double dt) +{ + auto transforms_view = registry.view(); + + // Handle copy translation constraints + registry.view().each + ( + [&](auto entity, auto& constraint, auto& transform) + { + if (registry.has(constraint.target)) + { + const float3& target_translation = transforms_view.get(constraint.target).transform.translation; + if (constraint.use_x) + transform.transform.translation.x = (constraint.invert_x) ? -target_translation.x : target_translation.x; + if (constraint.use_y) + transform.transform.translation.y = (constraint.invert_y) ? -target_translation.y : target_translation.y; + if (constraint.use_z) + transform.transform.translation.z = (constraint.invert_z) ? -target_translation.z : target_translation.z; + } + } + ); + + // Handle copy rotation constraints + registry.view().each + ( + [&](auto entity, auto& constraint, auto& transform) + { + if (registry.has(constraint.target)) + { + transform.transform.rotation = transforms_view.get(constraint.target).transform.rotation; + } + } + ); + + // Handle copy scale constraints + registry.view().each + ( + [&](auto entity, auto& constraint, auto& transform) + { + if (registry.has(constraint.target)) + { + const float3& target_scale = transforms_view.get(constraint.target).transform.scale; + if (constraint.use_x) + transform.transform.scale.x = target_scale.x; + if (constraint.use_y) + transform.transform.scale.y = target_scale.y; + if (constraint.use_z) + transform.transform.scale.z = target_scale.z; + } + } + ); + + // Handle copy transform constraints + registry.view().each + ( + [&](auto entity, auto& constraint, auto& transform) + { + if (registry.has(constraint.target)) + { + transform.transform = transforms_view.get(constraint.target).transform; + } + } + ); +} diff --git a/src/systems/constraint-system.hpp b/src/systems/constraint-system.hpp new file mode 100644 index 0000000..a09dfbc --- /dev/null +++ b/src/systems/constraint-system.hpp @@ -0,0 +1,33 @@ +/* + * 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_CONSTRAINT_SYSTEM_HPP +#define ANTKEEPER_CONSTRAINT_SYSTEM_HPP + +#include "entity-system.hpp" + +class constraint_system: + public entity_system +{ +public: + constraint_system(entt::registry& registry); + virtual void update(double t, double dt); +}; + +#endif // ANTKEEPER_CONSTRAINT_SYSTEM_HPP