-void Chaser::Update(int dt) {
- glm::vec3 diff(Target().AbsoluteDifference(Controlled()));
- float dist = dot (diff, diff);
- // TODO: line of sight test
- if (dist > stop_dist) {
- Controlled().Velocity(normalize(diff) * speed);
- } else if (dist < flee_dist) {
- Controlled().Velocity(normalize(diff) * -speed);
- } else {
- Controlled().Velocity(glm::vec3(0.0f));
+void AIController::SetState(const AIState &s) {
+ state->Exit(*this);
+ state = &s;
+ state->Enter(*this);
+}
+
+void AIController::Update(Entity &e, float dt) {
+ // movement: for now, wander only
+ if (wandering) {
+ glm::vec3 displacement(
+ random.SNorm() * wander_disp,
+ random.SNorm() * wander_disp,
+ random.SNorm() * wander_disp
+ );
+ if (!iszero(displacement)) {
+ wander_pos = normalize(wander_pos + displacement * dt) * wander_radius;
+ }
+ }
+
+ if (e.Moving()) {
+ // orient head towards heading
+ glm::vec3 heading(Heading(e.GetState()));
+ float tgt_pitch = std::atan(heading.y / length(glm::vec2(heading.x, heading.z)));
+ float tgt_yaw = std::atan2(-heading.x, -heading.z);
+ e.SetHead(tgt_pitch, tgt_yaw);