Antkeeper  0.0.1
steering-system.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
25 #include <engine/entity/id.hpp>
29 #include <engine/config.hpp>
30 
33 {}
34 
35 void steering_system::update(float t, float dt)
36 {
37  registry.group<steering_component>(entt::get<transform_component, winged_locomotion_component, rigid_body_component>).each
38  (
39  [&](entity::id entity_id, auto& steering, auto& transform, auto& locomotion, const auto& body_component)
40  {
41  auto& agent = steering.agent;
42  auto& body = *body_component.body;
43 
44  // Update agent parameters
45  agent.position = transform.local.translation;
46  agent.orientation = transform.local.rotation;
47  agent.velocity = body.get_linear_velocity();
48 
49  // Accumulate steering forces
50  math::fvec3 force = {0, 0, 0};
51  if (steering.wander_weight)
52  {
53  //force += ai::steering::behavior::wander_2d(agent, steering.wander_noise * dt, steering.wander_distance, steering.wander_radius, steering.wander_angle) * steering.wander_weight;
54  force += ai::steering::behavior::wander_3d(agent, steering.wander_noise * dt, steering.wander_distance, steering.wander_radius, steering.wander_angle, steering.wander_angle2) * steering.wander_weight;
55  }
56  if (steering.seek_weight)
57  {
58  force += ai::steering::behavior::seek(agent, steering.seek_target) * steering.seek_weight;
59  }
60 
61  // Normalize force
62  if (steering.sum_weights)
63  {
64  force /= steering.sum_weights;
65  }
66 
67  // Pass force to winged locomotion component
69  (
70  entity_id,
71  [&](auto& component)
72  {
73  component.force = force;
74  }
75  );
76 
77  // Rotate agent
78  const float speed_squared = math::sqr_length(agent.velocity);
79  if (speed_squared)
80  {
81  agent.orientation = math::look_rotation(agent.velocity / std::sqrt(speed_squared), agent.up);
82  agent.forward = agent.orientation * config::global_forward;
83  agent.up = agent.orientation * config::global_up;
84  }
85 
86  // Update orientation
88  (
89  entity_id,
90  [&agent](auto& component)
91  {
92  component.local.rotation = agent.orientation;
93  }
94  );
95  }
96  );
97 }
steering_system(entity::registry &registry)
virtual void update(float t, float dt)
Perform's a system's update() function.
Abstract base class for updatable systems.
entity::registry & registry
Registry on which the system operate.
math::fvec3 wander_3d(const agent &agent, float noise, float distance, float radius, float &theta, float &phi)
Steers an agent in a continuously shifting random direction.
Definition: wander.cpp:47
math::fvec3 seek(const agent &agent, const math::fvec3 &target)
Attempts to steer an agent so that it moves toward a target.
Definition: seek.cpp:26
entt::registry registry
Component registry type.
Definition: registry.hpp:28
entt::entity id
Entity ID type.
Definition: id.hpp:28
quaternion< T > look_rotation(const vec3< T > &forward, vec3< T > up)
Creates a unit quaternion rotation using forward and up vectors.
Definition: quaternion.hpp:618
constexpr T sqr_length(const quaternion< T > &q) noexcept
Calculates the square length of a quaternion.
Definition: quaternion.hpp:744
vector< T, N > sqrt(const vector< T, N > &x)
Takes the square root of each element.
n-dimensional vector.
Definition: vector.hpp:44