]> git.localhorst.tv Git - blank.git/blob - src/ai/ai.cpp
1d424cc218c73c9224f3d0abe6eea37a41bae06f
[blank.git] / src / ai / ai.cpp
1 #include "AIController.hpp"
2
3 #include "../model/geometry.hpp"
4 #include "../rand/GaloisLFSR.hpp"
5 #include "../world/Entity.hpp"
6 #include "../world/World.hpp"
7 #include "../world/WorldCollision.hpp"
8
9 #include <cmath>
10 #include <limits>
11 #include <glm/glm.hpp>
12
13
14 namespace blank {
15
16 AIController::AIController(GaloisLFSR &rand)
17 : random(rand)
18 , chase_speed(2.0f)
19 , flee_speed(-5.0f)
20 , stop_dist(10.0f)
21 , flee_dist(5.0f)
22 , wander_pos(1.0f, 0.0f, 0.0f)
23 , wander_dist(2.0f)
24 , wander_radius(1.0f)
25 , wander_disp(1.0f)
26 , wander_speed(1.0f) {
27
28 }
29
30 AIController::~AIController() {
31
32 }
33
34 void AIController::Update(Entity &e, float dt) {
35         // movement: for now, wander only
36         glm::vec3 displacement(
37                 random.SNorm() * wander_disp,
38                 random.SNorm() * wander_disp,
39                 random.SNorm() * wander_disp
40         );
41         if (dot(displacement, displacement) > std::numeric_limits<float>::epsilon()) {
42                 wander_pos = normalize(wander_pos + displacement * dt) * wander_radius;
43         }
44
45         if (e.Moving()) {
46                 // orient head towards heading
47                 glm::vec3 heading(Heading(e.GetState()));
48                 float tgt_pitch = std::atan(heading.y / length(glm::vec2(heading.x, heading.z)));
49                 float tgt_yaw = std::atan2(-heading.x, -heading.z);
50                 e.SetHead(tgt_pitch, tgt_yaw);
51         }
52 }
53
54 glm::vec3 AIController::ControlForce(const EntityState &state) const {
55         return (Heading(state) * wander_dist + wander_pos) * wander_speed;
56 }
57
58 glm::vec3 AIController::Heading(const EntityState &state) noexcept {
59         if (dot(state.velocity, state.velocity) > std::numeric_limits<float>::epsilon()) {
60                 return normalize(state.velocity);
61         } else {
62                 float cp = std::cos(state.pitch);
63                 return glm::vec3(std::cos(state.yaw) * cp, std::sin(state.yaw) * cp, std::sin(state.pitch));
64         }
65 }
66
67 }