]> git.localhorst.tv Git - blank.git/blob - src/world/Steering.hpp
d6ec57f6556c50d5b4920fe561a857ae67289ca2
[blank.git] / src / world / Steering.hpp
1 #ifndef BLANK_WORLD_STEERING_HPP
2 #define BLANK_WORLD_STEERING_HPP
3
4 #include "../geometry/Location.hpp"
5 #include "../geometry/primitive.hpp"
6
7 #include <glm/glm.hpp>
8
9
10 namespace blank {
11
12 class Entity;
13 class EntityState;
14 class World;
15
16 class Steering {
17
18 public:
19         enum Behaviour {
20                 // standalone behaviours
21                 HALT = 0x0001,
22                 WANDER = 0x0002,
23                 OBSTACLE_AVOIDANCE = 0x0004,
24
25                 // requires target velocity
26                 TARGET_VELOCITY = 0x0008,
27
28                 // behaviours requiring a target entity
29                 EVADE_TARGET = 0x0010,
30                 PURSUE_TARGET = 0x0020,
31         };
32
33         explicit Steering(const Entity &);
34         ~Steering();
35
36         Steering &Enable(unsigned int b) noexcept { enabled |= b; return *this; }
37         Steering &Disable(unsigned int b) noexcept { enabled &= ~b; return *this; }
38         bool AnyEnabled(unsigned int b) const noexcept { return enabled & b; }
39         bool AllEnabled(unsigned int b) const noexcept { return (enabled & b) == b; }
40
41         Steering &SetTargetEntity(Entity &) noexcept;
42         Steering &ClearTargetEntity() noexcept;
43         bool HasTargetEntity() const noexcept { return target_entity; }
44         const Entity &GetTargetEntity() const noexcept { return *target_entity; }
45
46         Steering &SetTargetVelocity(const glm::vec3 &v) noexcept { target_velocity = v; return *this; }
47         const glm::vec3 &GetTargetVelocity() const noexcept { return target_velocity; }
48
49         /// time in seconds in which steering tried to arrive at target velocity
50         Steering &SetAcceleration(float a) noexcept { accel = a; return *this; }
51         /// maximum magnitude of velocity that behaviours generate
52         Steering &SetSpeed(float s) noexcept { speed = s; return *this; }
53
54         /// configure wandering
55         /// r is the radius of the sphere
56         /// dist is the distance between the entity and the sphere's center
57         /// disp is the maximum variance of the point on the sphere in units per second
58         Steering &SetWanderParams(float r, float dist, float disp) noexcept {
59                 wander_radius = r;
60                 wander_dist = dist;
61                 wander_disp = disp;
62                 return *this;
63         }
64
65         void Update(World &, float dt);
66
67         glm::vec3 Force(const EntityState &) const noexcept;
68
69 private:
70         void UpdateWander(World &, float dt);
71         void UpdateObstacle(World &);
72
73         /// try to add as much of in to out so it doesn't exceed max
74         /// returns true if it's maxed out
75         static bool SumForce(glm::vec3 &out, const glm::vec3 &in, float max) noexcept;
76
77         /// slow down to a halt
78         glm::vec3 Halt(const EntityState &) const noexcept;
79         /// accelerate to match given velocity
80         glm::vec3 TargetVelocity(const EntityState &, const glm::vec3 &) const noexcept;
81         /// move towards given location
82         glm::vec3 Seek(const EntityState &, const ExactLocation &) const noexcept;
83         /// move away from given location
84         glm::vec3 Flee(const EntityState &, const ExactLocation &) const noexcept;
85         /// try to halt at given location
86         glm::vec3 Arrive(const EntityState &, const ExactLocation &) const noexcept;
87         /// seek given entity's predicted position
88         glm::vec3 Pursuit(const EntityState &, const Entity &) const noexcept;
89         /// flee given entity's predicted position
90         glm::vec3 Evade(const EntityState &, const Entity &) const noexcept;
91         /// move around for no reason
92         glm::vec3 Wander(const EntityState &) const noexcept;
93         /// try not to crash into blocks
94         glm::vec3 ObstacleAvoidance(const EntityState &) const noexcept;
95
96 private:
97         const Entity &entity;
98
99         Entity *target_entity;
100         glm::vec3 target_velocity;
101
102         float accel;
103         float speed;
104
105         float wander_radius;
106         float wander_dist;
107         float wander_disp;
108         glm::vec3 wander_pos;
109
110         glm::vec3 obstacle_dir;
111
112         unsigned int enabled;
113
114
115
116 };
117
118 }
119
120 #endif