1 #include "AIController.hpp"
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"
11 #include <glm/glm.hpp>
16 AIController::AIController(GaloisLFSR &rand)
22 , wander_pos(1.0f, 0.0f, 0.0f)
26 , wander_speed(1.0f) {
30 AIController::~AIController() {
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
41 if (dot(displacement, displacement) > std::numeric_limits<float>::epsilon()) {
42 wander_pos = normalize(wander_pos + displacement * dt) * wander_radius;
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);
54 glm::vec3 AIController::ControlForce(const EntityState &state) const {
55 return (Heading(state) * wander_dist + wander_pos) * wander_speed;
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);
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));