Browse Source

Add parent component, spatial system, and make transform components support parent-child relationships

master
C. J. Howard 4 years ago
parent
commit
bca1201e6c
20 changed files with 241 additions and 67 deletions
  1. +1
    -0
      CMakeLists.txt
  2. +1
    -1
      src/game/behavior/ebt.cpp
  3. +11
    -3
      src/game/bootloader.cpp
  4. +32
    -0
      src/game/components/parent-component.hpp
  5. +2
    -1
      src/game/components/transform-component.hpp
  6. +33
    -5
      src/game/entity-commands.cpp
  7. +3
    -1
      src/game/entity-commands.hpp
  8. +2
    -0
      src/game/game-context.hpp
  9. +13
    -13
      src/game/states/play-state.cpp
  10. +1
    -1
      src/game/systems/camera-system.cpp
  11. +10
    -10
      src/game/systems/constraint-system.cpp
  12. +1
    -1
      src/game/systems/render-system.cpp
  13. +6
    -6
      src/game/systems/samara-system.cpp
  14. +5
    -5
      src/game/systems/snapping-system.cpp
  15. +56
    -0
      src/game/systems/spatial-system.cpp
  16. +34
    -0
      src/game/systems/spatial-system.hpp
  17. +3
    -3
      src/game/systems/terrain-system.cpp
  18. +16
    -7
      src/game/systems/tool-system.cpp
  19. +1
    -0
      src/game/systems/tool-system.hpp
  20. +10
    -10
      src/resources/entity-archetype-loader.cpp

+ 1
- 0
CMakeLists.txt View File

@ -14,6 +14,7 @@ find_package(SDL2 REQUIRED COMPONENTS SDL2::SDL2-static SDL2::SDL2main CONFIG)
find_package(OpenAL REQUIRED CONFIG) find_package(OpenAL REQUIRED CONFIG)
find_library(physfs REQUIRED NAMES physfs-static PATHS "${CMAKE_PREFIX_PATH}/lib") find_library(physfs REQUIRED NAMES physfs-static PATHS "${CMAKE_PREFIX_PATH}/lib")
# Determine dependencies # Determine dependencies
set(STATIC_LIBS set(STATIC_LIBS
dr_wav dr_wav

+ 1
- 1
src/game/behavior/ebt.cpp View File

@ -40,7 +40,7 @@ status print_eid(context& context)
status warp_to(context& context, float x, float y, float z) status warp_to(context& context, float x, float y, float z)
{ {
auto& transform = context.registry->get<transform_component>(context.entity); auto& transform = context.registry->get<transform_component>(context.entity);
transform.transform.translation = {x, y, z};
transform.local.translation = {x, y, z};
transform.warp = true; transform.warp = true;
return status::success; return status::success;
} }

+ 11
- 3
src/game/bootloader.cpp View File

@ -75,6 +75,7 @@
#include "game/systems/tool-system.hpp" #include "game/systems/tool-system.hpp"
#include "game/systems/ui-system.hpp" #include "game/systems/ui-system.hpp"
#include "game/systems/vegetation-system.hpp" #include "game/systems/vegetation-system.hpp"
#include "game/systems/spatial-system.hpp"
#include "game/entity-commands.hpp" #include "game/entity-commands.hpp"
#include "utility/paths.hpp" #include "utility/paths.hpp"
#include "event/event-dispatcher.hpp" #include "event/event-dispatcher.hpp"
@ -818,7 +819,6 @@ void setup_systems(game_context* ctx)
// Setup locomotion system // Setup locomotion system
ctx->locomotion_system = new locomotion_system(*ctx->ecs_registry); ctx->locomotion_system = new locomotion_system(*ctx->ecs_registry);
ctx->constraint_system = new constraint_system(*ctx->ecs_registry);
// Setup pheromone system // Setup pheromone system
ctx->pheromones = new pheromone_matrix(); ctx->pheromones = new pheromone_matrix();
@ -830,6 +830,12 @@ void setup_systems(game_context* ctx)
ctx->pheromones->current = 0; ctx->pheromones->current = 0;
//diffuse(ctx->pheromones); //diffuse(ctx->pheromones);
// Setup spatial system
ctx->spatial_system = new spatial_system(*ctx->ecs_registry);
// Setup constraint system
ctx->constraint_system = new constraint_system(*ctx->ecs_registry);
// Setup render system // Setup render system
ctx->render_system = new ::render_system(*ctx->ecs_registry); ctx->render_system = new ::render_system(*ctx->ecs_registry);
ctx->render_system->add_layer(ctx->overworld_scene); ctx->render_system->add_layer(ctx->overworld_scene);
@ -1095,14 +1101,16 @@ void setup_callbacks(game_context* ctx)
ctx->locomotion_system->update(t, dt); ctx->locomotion_system->update(t, dt);
ctx->camera_system->update(t, dt); ctx->camera_system->update(t, dt);
ctx->tool_system->update(t, dt); ctx->tool_system->update(t, dt);
ctx->spatial_system->update(t, dt);
ctx->constraint_system->update(t, dt); ctx->constraint_system->update(t, dt);
//(*ctx->focal_point_tween)[1] = ctx->orbit_cam->get_focal_point(); //(*ctx->focal_point_tween)[1] = ctx->orbit_cam->get_focal_point();
auto xf = ec::get_transform(*ctx->ecs_registry, ctx->lens_entity);
auto xf = ec::get_world_transform(*ctx->ecs_registry, ctx->lens_entity);
ctx->lens_spotlight->look_at(xf.translation, xf.translation + ctx->sun_direct->get_direction(), {0, 1, 0}); ctx->lens_spotlight->look_at(xf.translation, xf.translation + ctx->sun_direct->get_direction(), {0, 1, 0});
xf = ec::get_transform(*ctx->ecs_registry, ctx->flashlight_entity);
xf = ec::get_world_transform(*ctx->ecs_registry, ctx->flashlight_entity);
//ctx->flashlight_spotlight->set_transform(xf); //ctx->flashlight_spotlight->set_transform(xf);
ctx->flashlight_spotlight->look_at(xf.translation, xf.translation + xf.rotation * float3{0, 0, 1}, {0, 0, -1}); ctx->flashlight_spotlight->look_at(xf.translation, xf.translation + xf.rotation * float3{0, 0, 1}, {0, 0, -1});

+ 32
- 0
src/game/components/parent-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_PARENT_COMPONENT_HPP
#define ANTKEEPER_ECS_PARENT_COMPONENT_HPP
namespace ecs {
struct parent_component
{
entt::entity parent;
};
} // namespace ecs
#endif // ANTKEEPER_ECS_PARENT_COMPONENT_HPP

+ 2
- 1
src/game/components/transform-component.hpp View File

@ -26,7 +26,8 @@ namespace ecs {
struct transform_component struct transform_component
{ {
math::transform<float> transform;
math::transform<float> local;
math::transform<float> world;
bool warp; bool warp;
}; };

+ 33
- 5
src/game/entity-commands.cpp View File

@ -22,6 +22,7 @@
#include "game/components/transform-component.hpp" #include "game/components/transform-component.hpp"
#include "game/components/copy-transform-component.hpp" #include "game/components/copy-transform-component.hpp"
#include "game/components/snap-component.hpp" #include "game/components/snap-component.hpp"
#include "game/components/parent-component.hpp"
#include <limits> #include <limits>
namespace ec { namespace ec {
@ -33,7 +34,7 @@ void translate(entt::registry& registry, entt::entity eid, const float3& transla
if (registry.has<transform_component>(eid)) if (registry.has<transform_component>(eid))
{ {
transform_component& transform = registry.get<transform_component>(eid); transform_component& transform = registry.get<transform_component>(eid);
transform.transform.translation += translation;
transform.local.translation += translation;
} }
} }
@ -42,7 +43,7 @@ void move_to(entt::registry& registry, entt::entity eid, const float3& position)
if (registry.has<transform_component>(eid)) if (registry.has<transform_component>(eid))
{ {
transform_component& transform = registry.get<transform_component>(eid); transform_component& transform = registry.get<transform_component>(eid);
transform.transform.translation = position;
transform.local.translation = position;
} }
} }
@ -51,6 +52,7 @@ void warp_to(entt::registry& registry, entt::entity eid, const float3& position)
if (registry.has<transform_component>(eid)) if (registry.has<transform_component>(eid))
{ {
transform_component& transform = registry.get<transform_component>(eid); transform_component& transform = registry.get<transform_component>(eid);
transform.local.translation = position;
transform.warp = true; transform.warp = true;
} }
} }
@ -60,7 +62,7 @@ void set_transform(entt::registry& registry, entt::entity eid, const math::trans
if (registry.has<transform_component>(eid)) if (registry.has<transform_component>(eid))
{ {
transform_component& component = registry.get<transform_component>(eid); transform_component& component = registry.get<transform_component>(eid);
component.transform = transform;
component.local = transform;
component.warp = warp; component.warp = warp;
} }
} }
@ -83,6 +85,14 @@ void assign_render_layers(entt::registry& registry, entt::entity eid, unsigned i
model_component model = registry.get<model_component>(eid); model_component model = registry.get<model_component>(eid);
model.layers = layers; model.layers = layers;
registry.replace<model_component>(eid, model); registry.replace<model_component>(eid, model);
// Apply to child layers
registry.view<parent_component>().each(
[&](auto entity, auto& component)
{
if (component.parent == eid)
assign_render_layers(registry, entity, layers);
});
} }
} }
@ -92,15 +102,33 @@ void bind_transform(entt::registry& registry, entt::entity source_eid, entt::ent
registry.assign_or_replace<copy_transform_component>(source_eid, copy_transform); registry.assign_or_replace<copy_transform_component>(source_eid, copy_transform);
} }
math::transform<float> get_transform(entt::registry& registry, entt::entity eid)
math::transform<float> get_local_transform(entt::registry& registry, entt::entity eid)
{ {
if (registry.has<transform_component>(eid)) if (registry.has<transform_component>(eid))
{ {
const transform_component& component = registry.get<transform_component>(eid); const transform_component& component = registry.get<transform_component>(eid);
return component.transform;
return component.local;
} }
return math::identity_transform<float>; return math::identity_transform<float>;
} }
math::transform<float> get_world_transform(entt::registry& registry, entt::entity eid)
{
if (registry.has<transform_component>(eid))
{
const transform_component& component = registry.get<transform_component>(eid);
return component.world;
}
return math::identity_transform<float>;
}
void parent(entt::registry& registry, entt::entity child, entt::entity parent)
{
parent_component component;
component.parent = parent;
registry.assign_or_replace<parent_component>(child, component);
}
} // namespace ec } // namespace ec

+ 3
- 1
src/game/entity-commands.hpp View File

@ -33,7 +33,9 @@ void set_transform(entt::registry& registry, entt::entity eid, const math::trans
void place(entt::registry& registry, entt::entity eid, const float2& translation); void place(entt::registry& registry, entt::entity eid, const float2& translation);
void assign_render_layers(entt::registry& registry, entt::entity eid, unsigned int layers); void assign_render_layers(entt::registry& registry, entt::entity eid, unsigned int layers);
void bind_transform(entt::registry& registry, entt::entity source_eid, entt::entity target_eid); void bind_transform(entt::registry& registry, entt::entity source_eid, entt::entity target_eid);
math::transform<float> get_transform(entt::registry& registry, entt::entity eid);
math::transform<float> get_local_transform(entt::registry& registry, entt::entity eid);
math::transform<float> get_world_transform(entt::registry& registry, entt::entity eid);
void parent(entt::registry& registry, entt::entity child, entt::entity parent);
} // namespace ec } // namespace ec

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

@ -74,6 +74,7 @@ class texture_2d;
class timeline; class timeline;
class tool_system; class tool_system;
class ui_system; class ui_system;
class spatial_system;
class vegetation_system; class vegetation_system;
class vertex_array; class vertex_array;
class vertex_buffer; class vertex_buffer;
@ -231,6 +232,7 @@ struct game_context
tool_system* tool_system; tool_system* tool_system;
ui_system* ui_system; ui_system* ui_system;
vegetation_system* vegetation_system; vegetation_system* vegetation_system;
spatial_system* spatial_system;
// Debug // Debug
cli* cli; cli* cli;

+ 13
- 13
src/game/states/play-state.cpp View File

@ -91,12 +91,11 @@ void play_state_enter(game_context* ctx)
lens_archetype->assign(ecs_registry, ctx->lens_entity); lens_archetype->assign(ecs_registry, ctx->lens_entity);
brush_archetype->assign(ecs_registry, ctx->brush_entity); brush_archetype->assign(ecs_registry, ctx->brush_entity);
// Create flashlight and light cone, bind light cone to flashlight, and move both to underworld scene
// Create flashlight and light cone, set light cone parent to flashlight, and move both to underworld scene
flashlight_archetype->assign(ecs_registry, ctx->flashlight_entity); flashlight_archetype->assign(ecs_registry, ctx->flashlight_entity);
auto flashlight_light_cone = flashlight_light_cone_archetype->create(ecs_registry); auto flashlight_light_cone = flashlight_light_cone_archetype->create(ecs_registry);
ec::bind_transform(ecs_registry, flashlight_light_cone, ctx->flashlight_entity);
ec::parent(ecs_registry, flashlight_light_cone, ctx->flashlight_entity);
ec::assign_render_layers(ecs_registry, ctx->flashlight_entity, 2); ec::assign_render_layers(ecs_registry, ctx->flashlight_entity, 2);
ec::assign_render_layers(ecs_registry, flashlight_light_cone, 2);
// Make lens tool's model instance unculled, so its shadow is always visible. // 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); model_instance* lens_model_instance = ctx->render_system->get_model_instance(ctx->lens_entity);
@ -105,9 +104,10 @@ void play_state_enter(game_context* ctx)
lens_model_instance->set_culling_mask(&ctx->no_cull); lens_model_instance->set_culling_mask(&ctx->no_cull);
} }
// Create lens light cone and bind to lens
// Create lens light cone and set its parent to lens
auto lens_light_cone = lens_light_cone_archetype->create(ecs_registry); auto lens_light_cone = lens_light_cone_archetype->create(ecs_registry);
ec::bind_transform(ecs_registry, lens_light_cone, ctx->lens_entity);
//ec::bind_transform(ecs_registry, lens_light_cone, ctx->lens_entity);
ec::parent(ecs_registry, lens_light_cone, ctx->lens_entity);
// Activate lens tool // Activate lens tool
auto& active_tool_component = ecs_registry.get<ecs::tool_component>(ctx->lens_entity); auto& active_tool_component = ecs_registry.get<ecs::tool_component>(ctx->lens_entity);
@ -132,9 +132,9 @@ void play_state_enter(game_context* ctx)
auto pebble_entity = pebble_archetype->create(ecs_registry); auto pebble_entity = pebble_archetype->create(ecs_registry);
auto& transform = ecs_registry.get<ecs::transform_component>(pebble_entity); auto& transform = ecs_registry.get<ecs::transform_component>(pebble_entity);
transform.transform = math::identity_transform<float>;
transform.transform.rotation = math::angle_axis(math::random(0.0f, math::two_pi<float>), {0, 1, 0});
transform.transform.scale = float3{1, 1, 1} * math::random(0.75f, 1.25f);
transform.local = math::identity_transform<float>;
transform.local.rotation = math::angle_axis(math::random(0.0f, math::two_pi<float>), {0, 1, 0});
transform.local.scale = float3{1, 1, 1} * math::random(0.75f, 1.25f);
ec::place(ecs_registry, pebble_entity, {x, z}); ec::place(ecs_registry, pebble_entity, {x, z});
} }
@ -168,10 +168,10 @@ void play_state_enter(game_context* ctx)
auto& transform = ecs_registry.get<ecs::transform_component>(samara_entity); auto& transform = ecs_registry.get<ecs::transform_component>(samara_entity);
float zone = 200.0f; float zone = 200.0f;
transform.transform = math::identity_transform<float>;
transform.transform.translation.x = math::random(-zone, zone);
transform.transform.translation.y = math::random(50.0f, 150.0f);
transform.transform.translation.z = math::random(-zone, zone);
transform.local = math::identity_transform<float>;
transform.local.translation.x = math::random(-zone, zone);
transform.local.translation.y = math::random(50.0f, 150.0f);
transform.local.translation.z = math::random(-zone, zone);
ecs::samara_component samara_component; ecs::samara_component samara_component;
samara_component.angle = math::random(0.0f, math::radians(360.0f)); samara_component.angle = math::random(0.0f, math::radians(360.0f));
@ -183,7 +183,7 @@ void play_state_enter(game_context* ctx)
// Setup camera focal point // Setup camera focal point
ecs::transform_component focal_point_transform; ecs::transform_component focal_point_transform;
focal_point_transform.transform = math::identity_transform<float>;
focal_point_transform.local = math::identity_transform<float>;
focal_point_transform.warp = true; focal_point_transform.warp = true;
ecs::camera_follow_component focal_point_follow; ecs::camera_follow_component focal_point_follow;
ecs::snap_component focal_point_snap; ecs::snap_component focal_point_snap;

+ 1
- 1
src/game/systems/camera-system.cpp View File

@ -65,7 +65,7 @@ void camera_system::update(double t, double dt)
registry.view<camera_follow_component, transform_component>().each( registry.view<camera_follow_component, transform_component>().each(
[&](auto entity, auto& follow, auto& transform) [&](auto entity, auto& follow, auto& transform)
{ {
target_focal_point += transform.transform.translation;
target_focal_point += transform.local.translation;
++subject_count; ++subject_count;
}); });
if (subject_count > 1) if (subject_count > 1)

+ 10
- 10
src/game/systems/constraint-system.cpp View File

@ -42,13 +42,13 @@ void constraint_system::update(double t, double dt)
{ {
if (registry.has<transform_component>(constraint.target)) if (registry.has<transform_component>(constraint.target))
{ {
const float3& target_translation = transforms_view.get(constraint.target).transform.translation;
const float3& target_translation = transforms_view.get(constraint.target).world.translation;
if (constraint.use_x) if (constraint.use_x)
transform.transform.translation.x = (constraint.invert_x) ? -target_translation.x : target_translation.x;
transform.world.translation.x = (constraint.invert_x) ? -target_translation.x : target_translation.x;
if (constraint.use_y) if (constraint.use_y)
transform.transform.translation.y = (constraint.invert_y) ? -target_translation.y : target_translation.y;
transform.world.translation.y = (constraint.invert_y) ? -target_translation.y : target_translation.y;
if (constraint.use_z) if (constraint.use_z)
transform.transform.translation.z = (constraint.invert_z) ? -target_translation.z : target_translation.z;
transform.world.translation.z = (constraint.invert_z) ? -target_translation.z : target_translation.z;
} }
} }
); );
@ -60,7 +60,7 @@ void constraint_system::update(double t, double dt)
{ {
if (registry.has<transform_component>(constraint.target)) if (registry.has<transform_component>(constraint.target))
{ {
transform.transform.rotation = transforms_view.get(constraint.target).transform.rotation;
transform.world.rotation = transforms_view.get(constraint.target).world.rotation;
} }
} }
); );
@ -72,13 +72,13 @@ void constraint_system::update(double t, double dt)
{ {
if (registry.has<transform_component>(constraint.target)) if (registry.has<transform_component>(constraint.target))
{ {
const float3& target_scale = transforms_view.get(constraint.target).transform.scale;
const float3& target_scale = transforms_view.get(constraint.target).world.scale;
if (constraint.use_x) if (constraint.use_x)
transform.transform.scale.x = target_scale.x;
transform.world.scale.x = target_scale.x;
if (constraint.use_y) if (constraint.use_y)
transform.transform.scale.y = target_scale.y;
transform.world.scale.y = target_scale.y;
if (constraint.use_z) if (constraint.use_z)
transform.transform.scale.z = target_scale.z;
transform.world.scale.z = target_scale.z;
} }
} }
); );
@ -90,7 +90,7 @@ void constraint_system::update(double t, double dt)
{ {
if (registry.has<transform_component>(constraint.target)) if (registry.has<transform_component>(constraint.target))
{ {
transform.transform = transforms_view.get(constraint.target).transform;
transform.world = transforms_view.get(constraint.target).world;
} }
} }
); );

+ 1
- 1
src/game/systems/render-system.cpp View File

@ -40,7 +40,7 @@ void render_system::update(double t, double dt)
{ {
model_instance* instance = model_instances[entity]; model_instance* instance = model_instances[entity];
instance->set_transform(transform.transform);
instance->set_transform(transform.world);
if (transform.warp) if (transform.warp)
{ {

+ 6
- 6
src/game/systems/samara-system.cpp View File

@ -36,18 +36,18 @@ void samara_system::update(double t, double dt)
{ {
samara.angle += samara.chirality * math::radians(360.0f * 6.0f) * dt; samara.angle += samara.chirality * math::radians(360.0f * 6.0f) * dt;
transform.transform.translation += samara.direction * 20.0f * (float)dt;
transform.transform.rotation =
transform.local.translation += samara.direction * 20.0f * (float)dt;
transform.local.rotation =
math::angle_axis(samara.angle, float3{0, 1, 0}) * math::angle_axis(samara.angle, float3{0, 1, 0}) *
math::angle_axis(math::radians(20.0f), float3{1, 0, 0}) * math::angle_axis(math::radians(20.0f), float3{1, 0, 0}) *
((samara.chirality < 0.0f) ? math::angle_axis(math::radians(180.0f), float3{0, 0, -1}) : math::quaternion<float>{1, 0, 0, 0}); ((samara.chirality < 0.0f) ? math::angle_axis(math::radians(180.0f), float3{0, 0, -1}) : math::quaternion<float>{1, 0, 0, 0});
if (transform.transform.translation.y < 0.0f)
if (transform.local.translation.y < 0.0f)
{ {
const float zone = 200.0f; const float zone = 200.0f;
transform.transform.translation.x = math::random(-zone, zone);
transform.transform.translation.y = math::random(100.0f, 150.0f);
transform.transform.translation.z = math::random(-zone, zone);
transform.local.translation.x = math::random(-zone, zone);
transform.local.translation.y = math::random(100.0f, 150.0f);
transform.local.translation.z = math::random(-zone, zone);
transform.warp = true; transform.warp = true;
samara.chirality = (math::random(0.0f, 1.0f) < 0.5f) ? -1.0f : 1.0f; samara.chirality = (math::random(0.0f, 1.0f) < 0.5f) ? -1.0f : 1.0f;

+ 5
- 5
src/game/systems/snapping-system.cpp View File

@ -41,17 +41,17 @@ void snapping_system::update(double t, double dt)
ray<float> snap_ray = snap.ray; ray<float> snap_ray = snap.ray;
if (snap.relative) if (snap.relative)
{ {
snap_ray.origin += snap_transform.transform.translation;
snap_ray.direction = snap_transform.transform.rotation * snap_ray.direction;
snap_ray.origin += snap_transform.local.translation;
snap_ray.direction = snap_transform.local.rotation * snap_ray.direction;
} }
registry.view<transform_component, collision_component>().each( registry.view<transform_component, collision_component>().each(
[&](auto entity, auto& collision_transform, auto& collision) [&](auto entity, auto& collision_transform, auto& collision)
{ {
// Transform ray into local space of collision component // Transform ray into local space of collision component
math::transform<float> inverse_transform = math::inverse(collision_transform.transform);
math::transform<float> inverse_transform = math::inverse(collision_transform.local);
float3 origin = inverse_transform * snap_ray.origin; float3 origin = inverse_transform * snap_ray.origin;
float3 direction = math::normalize(math::conjugate(collision_transform.transform.rotation) * snap_ray.direction);
float3 direction = math::normalize(math::conjugate(collision_transform.local.rotation) * snap_ray.direction);
ray<float> transformed_ray = {origin, direction}; ray<float> transformed_ray = {origin, direction};
// Broad phase AABB test // Broad phase AABB test
@ -76,7 +76,7 @@ void snapping_system::update(double t, double dt)
if (intersection) if (intersection)
{ {
snap_transform.transform.translation = pick;
snap_transform.local.translation = pick;
snap_transform.warp = snap.warp; snap_transform.warp = snap.warp;
if (snap.autoremove) if (snap.autoremove)

+ 56
- 0
src/game/systems/spatial-system.cpp View File

@ -0,0 +1,56 @@
/*
* 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 "spatial-system.hpp"
#include "game/components/parent-component.hpp"
#include "game/components/transform-component.hpp"
using namespace ecs;
spatial_system::spatial_system(entt::registry& registry):
entity_system(registry)
{}
void spatial_system::update(double t, double dt)
{
/// @TODO: sort transforms by parent, for more multi-level hierarchies
// Process parent transforms first
registry.view<transform_component>().each(
[&](auto entity, auto& transform)
{
if (!registry.has<parent_component>(entity))
{
transform.world = transform.local;
}
});
// Process child transforms second
registry.view<transform_component>().each(
[&](auto entity, auto& transform)
{
if (registry.has<parent_component>(entity))
{
entt::entity parent = registry.get<parent_component>(entity).parent;
const transform_component& parent_transform = registry.get<transform_component>(parent);
transform.world = parent_transform.world * transform.local;
transform.warp = parent_transform.warp;
}
});
}

+ 34
- 0
src/game/systems/spatial-system.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_SPATIAL_SYSTEM_HPP
#define ANTKEEPER_SPATIAL_SYSTEM_HPP
#include "entity-system.hpp"
class spatial_system:
public entity_system
{
public:
spatial_system(entt::registry& registry);
virtual void update(double t, double dt);
};
#endif // ANTKEEPER_SPATIAL_SYSTEM_HPP

+ 3
- 3
src/game/systems/terrain-system.cpp View File

@ -55,7 +55,7 @@ void terrain_system::update(double t, double dt)
registry.view<terrain_component, transform_component>().each( registry.view<terrain_component, transform_component>().each(
[this](auto entity, auto& terrain, auto& transform) [this](auto entity, auto& terrain, auto& transform)
{ {
transform.transform.translation = float3{(float)terrain.x * patch_size, 0.0f, (float)terrain.z * patch_size};
transform.local.translation = float3{(float)terrain.x * patch_size, 0.0f, (float)terrain.z * patch_size};
transform.warp = true; transform.warp = true;
}); });
} }
@ -330,8 +330,8 @@ void terrain_system::on_terrain_construct(entt::registry& registry, entt::entity
// Assign the entity a transform component // Assign the entity a transform component
transform_component transform; transform_component transform;
transform.transform = math::identity_transform<float>;
transform.transform.translation = float3{(float)component.x * patch_size, 0.0f, (float)component.z * patch_size};
transform.local = math::identity_transform<float>;
transform.local.translation = float3{(float)component.x * patch_size, 0.0f, (float)component.z * patch_size};
transform.warp = true; transform.warp = true;
registry.assign_or_replace<transform_component>(entity, transform); registry.assign_or_replace<transform_component>(entity, transform);
} }

+ 16
- 7
src/game/systems/tool-system.cpp View File

@ -52,6 +52,7 @@ tool_system::tool_system(entt::registry& registry):
pick_spring.v = {0.0f, 0.0f, 0.0f}; pick_spring.v = {0.0f, 0.0f, 0.0f};
active_tool = entt::null; active_tool = entt::null;
warp = true;
} }
void tool_system::update(double t, double dt) void tool_system::update(double t, double dt)
@ -73,9 +74,9 @@ void tool_system::update(double t, double dt)
registry.view<transform_component, collision_component>().each( registry.view<transform_component, collision_component>().each(
[&](auto entity, auto& transform, auto& collision) [&](auto entity, auto& transform, auto& collision)
{ {
math::transform<float> inverse_transform = math::inverse(transform.transform);
math::transform<float> inverse_transform = math::inverse(transform.local);
float3 origin = inverse_transform * pick_origin; float3 origin = inverse_transform * pick_origin;
float3 direction = math::normalize(math::conjugate(transform.transform.rotation) * pick_direction);
float3 direction = math::normalize(math::conjugate(transform.local.rotation) * pick_direction);
ray<float> transformed_ray = {origin, direction}; ray<float> transformed_ray = {origin, direction};
// Broad phase AABB test // Broad phase AABB test
@ -138,7 +139,7 @@ void tool_system::update(double t, double dt)
if (intersection) if (intersection)
{ {
transform.transform.translation = pick_spring.x0 + float3{0, tool.hover_distance, 0};
transform.local.translation = pick_spring.x0 + float3{0, tool.hover_distance, 0};
} }
// Interpolate between left and right hand // Interpolate between left and right hand
@ -147,13 +148,20 @@ void tool_system::update(double t, double dt)
if (tool.heliotropic) if (tool.heliotropic)
{ {
math::quaternion<float> solar_rotation = math::rotation(float3{0, -1, 0}, sun_direction); math::quaternion<float> solar_rotation = math::rotation(float3{0, -1, 0}, sun_direction);
transform.transform.translation = pick_spring.x0 + solar_rotation * float3{0, tool.hover_distance, 0};
transform.local.translation = pick_spring.x0 + solar_rotation * float3{0, tool.hover_distance, 0};
transform.transform.rotation = solar_rotation * hand_rotation;
transform.local.rotation = solar_rotation * hand_rotation;
} }
else else
{ {
transform.transform.rotation = hand_rotation;
transform.local.rotation = hand_rotation;
}
if (warp)
{
transform.warp = true;
ec::assign_render_layers(registry, active_tool, 1);
warp = false;
} }
//math::quaternion<float> rotation = math::angle_axis(orbit_cam->get_azimuth() + pick_angle, float3{0, 1, 0}); //math::quaternion<float> rotation = math::angle_axis(orbit_cam->get_azimuth() + pick_angle, float3{0, 1, 0});
@ -203,8 +211,9 @@ void tool_system::set_active_tool(entt::entity entity)
{ {
auto& tool = registry.get<tool_component>(active_tool); auto& tool = registry.get<tool_component>(active_tool);
tool.active = true; tool.active = true;
ec::assign_render_layers(registry, active_tool, 1);
} }
warp = true;
} }

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

@ -61,6 +61,7 @@ private:
bool pick_enabled; bool pick_enabled;
float3 sun_direction; float3 sun_direction;
entt::entity active_tool; entt::entity active_tool;
bool warp;
numeric_spring<float, float> hand_angle_spring; numeric_spring<float, float> hand_angle_spring;
numeric_spring<float3, float> pick_spring; numeric_spring<float3, float> pick_spring;

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

@ -156,16 +156,16 @@ static bool load_transform_component(archetype& archetype, const std::vector
} }
transform_component component; transform_component component;
stream >> component.transform.translation.x;
stream >> component.transform.translation.y;
stream >> component.transform.translation.z;
stream >> component.transform.rotation.w;
stream >> component.transform.rotation.x;
stream >> component.transform.rotation.y;
stream >> component.transform.rotation.z;
stream >> component.transform.scale.x;
stream >> component.transform.scale.y;
stream >> component.transform.scale.z;
stream >> component.local.translation.x;
stream >> component.local.translation.y;
stream >> component.local.translation.z;
stream >> component.local.rotation.w;
stream >> component.local.rotation.x;
stream >> component.local.rotation.y;
stream >> component.local.rotation.z;
stream >> component.local.scale.x;
stream >> component.local.scale.y;
stream >> component.local.scale.z;
component.warp = true; component.warp = true;
archetype.set<transform_component>(component); archetype.set<transform_component>(component);

Loading…
Cancel
Save