]> git.localhorst.tv Git - blank.git/commitdiff
cache some basic entity axes
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 28 Oct 2015 13:52:24 +0000 (14:52 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 28 Oct 2015 13:52:24 +0000 (14:52 +0100)
src/ai/AIController.hpp
src/ai/ai.cpp
src/client/net.cpp
src/world/Entity.hpp
src/world/world.cpp

index bd88290fdcb9d44075552807c560c9ac137411d5..cda3e8a08086465f694b020f6615c4c58ebd1271 100644 (file)
@@ -28,8 +28,6 @@ public:
 
        glm::vec3 ControlForce(const Entity &, const EntityState &) const override;
 
-       static glm::vec3 Heading(const EntityState &) noexcept;
-
        /// get the closest player that given entity can see
        /// returns nullptr if none are in sight
        Player *ClosestVisiblePlayer(const Entity &) noexcept;
@@ -54,7 +52,7 @@ public:
        void ExitHalt() noexcept;
        bool IsHalted() const noexcept;
        void SetHaltSpeed(float) noexcept;
-       glm::vec3 GetHaltForce(const EntityState &) const noexcept;
+       glm::vec3 GetHaltForce(const Entity &, const EntityState &) const noexcept;
 
        void StartFleeing() noexcept;
        void StopFleeing() noexcept;
@@ -63,7 +61,7 @@ public:
        void SetFleeSpeed(float) noexcept;
        Entity &GetFleeTarget() noexcept;
        const Entity &GetFleeTarget() const noexcept;
-       glm::vec3 GetFleeForce(const EntityState &) const noexcept;
+       glm::vec3 GetFleeForce(const Entity &, const EntityState &) const noexcept;
 
        void StartSeeking() noexcept;
        void StopSeeking() noexcept;
@@ -72,7 +70,7 @@ public:
        void SetSeekSpeed(float) noexcept;
        Entity &GetSeekTarget() noexcept;
        const Entity &GetSeekTarget() const noexcept;
-       glm::vec3 GetSeekForce(const EntityState &) const noexcept;
+       glm::vec3 GetSeekForce(const Entity &, const EntityState &) const noexcept;
 
        void StartEvading() noexcept;
        void StopEvading() noexcept;
@@ -81,7 +79,7 @@ public:
        void SetEvadeSpeed(float) noexcept;
        Entity &GetEvadeTarget() noexcept;
        const Entity &GetEvadeTarget() const noexcept;
-       glm::vec3 GetEvadeForce(const EntityState &) const noexcept;
+       glm::vec3 GetEvadeForce(const Entity &, const EntityState &) const noexcept;
 
        void StartPursuing() noexcept;
        void StopPursuing() noexcept;
@@ -90,7 +88,7 @@ public:
        void SetPursuitSpeed(float) noexcept;
        Entity &GetPursuitTarget() noexcept;
        const Entity &GetPursuitTarget() const noexcept;
-       glm::vec3 GetPursuitForce(const EntityState &) const noexcept;
+       glm::vec3 GetPursuitForce(const Entity &, const EntityState &) const noexcept;
 
        /// start wandering randomly
        void StartWandering() noexcept;
@@ -106,7 +104,7 @@ public:
                float radius = 1.0f,
                float displacement = 1.0f
        ) noexcept;
-       glm::vec3 GetWanderForce(const EntityState &) const noexcept;
+       glm::vec3 GetWanderForce(const Entity &, const EntityState &) const noexcept;
 
 private:
        World &world;
index 11add89bb049f079fad1bc62f01c612ce03e685e..ff39127151332dc544f23ae6784f719ec7d6bd6c 100644 (file)
@@ -86,7 +86,7 @@ void AIController::Update(Entity &e, float dt) {
 
        if (e.Moving()) {
                // orient head towards heading
-               glm::vec3 heading(Heading(e.GetState()));
+               glm::vec3 heading(e.Heading());
                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);
@@ -95,46 +95,37 @@ void AIController::Update(Entity &e, float dt) {
 
 glm::vec3 AIController::ControlForce(const Entity &entity, const EntityState &state) const {
        if (IsHalted()) {
-               return GetHaltForce(state);
+               return GetHaltForce(entity, state);
        }
        glm::vec3 force(0.0f);
        if (IsFleeing()) {
-               if (MaxOutForce(force, GetFleeForce(state), entity.MaxControlForce())) {
+               if (MaxOutForce(force, GetFleeForce(entity, state), entity.MaxControlForce())) {
                        return force;
                }
        }
        if (IsSeeking()) {
-               if (MaxOutForce(force, GetSeekForce(state), entity.MaxControlForce())) {
+               if (MaxOutForce(force, GetSeekForce(entity, state), entity.MaxControlForce())) {
                        return force;
                }
        }
        if (IsEvading()) {
-               if (MaxOutForce(force, GetEvadeForce(state), entity.MaxControlForce())) {
+               if (MaxOutForce(force, GetEvadeForce(entity, state), entity.MaxControlForce())) {
                        return force;
                }
        }
        if (IsPursuing()) {
-               if (MaxOutForce(force, GetPursuitForce(state), entity.MaxControlForce())) {
+               if (MaxOutForce(force, GetPursuitForce(entity, state), entity.MaxControlForce())) {
                        return force;
                }
        }
        if (IsWandering()) {
-               if (MaxOutForce(force, GetWanderForce(state), entity.MaxControlForce())) {
+               if (MaxOutForce(force, GetWanderForce(entity, state), entity.MaxControlForce())) {
                        return force;
                }
        }
        return force;
 }
 
-glm::vec3 AIController::Heading(const EntityState &state) noexcept {
-       if (dot(state.velocity, state.velocity) > std::numeric_limits<float>::epsilon()) {
-               return normalize(state.velocity);
-       } else {
-               float cp = std::cos(state.pitch);
-               return glm::vec3(std::cos(state.yaw) * cp, std::sin(state.yaw) * cp, std::sin(state.pitch));
-       }
-}
-
 Player *AIController::ClosestVisiblePlayer(const Entity &e) noexcept {
        Player *target = nullptr;
        float distance = sight_dist;
@@ -145,17 +136,17 @@ Player *AIController::ClosestVisiblePlayer(const Entity &e) noexcept {
 
                // distance test
                const glm::vec3 diff(pe.AbsoluteDifference(e));
-               float dist = length_squared(diff);
+               float dist = length(diff);
                if (dist > distance) continue;
 
                // FOV test, 45° in each direction
-               if (dot(normalize(diff), aim.dir) < sight_angle) {
+               if (dot(diff / dist, aim.dir) < sight_angle) {
                        continue;
                }
 
                // LOS test, assumes all entities are see-through
                WorldCollision col;
-               if (world.Intersection(aim, glm::mat4(1.0f), reference, col) && col.depth * col.depth < dist) {
+               if (world.Intersection(aim, glm::mat4(1.0f), reference, col) && col.depth < dist) {
                        continue;
                }
 
@@ -228,7 +219,7 @@ void AIController::SetHaltSpeed(float speed) noexcept {
        halt_speed = speed;
 }
 
-glm::vec3 AIController::GetHaltForce(const EntityState &state) const noexcept {
+glm::vec3 AIController::GetHaltForce(const Entity &, const EntityState &state) const noexcept {
        return Halt(state, halt_speed);
 }
 
@@ -270,7 +261,7 @@ const Entity &AIController::GetFleeTarget() const noexcept {
        return *flee_target;
 }
 
-glm::vec3 AIController::GetFleeForce(const EntityState &state) const noexcept {
+glm::vec3 AIController::GetFleeForce(const Entity &, const EntityState &state) const noexcept {
        return Flee(state, GetFleeTarget().GetState(), flee_speed, 2.0f);
 }
 
@@ -312,7 +303,7 @@ const Entity &AIController::GetSeekTarget() const noexcept {
        return *seek_target;
 }
 
-glm::vec3 AIController::GetSeekForce(const EntityState &state) const noexcept {
+glm::vec3 AIController::GetSeekForce(const Entity &, const EntityState &state) const noexcept {
        return Seek(state, GetSeekTarget().GetState(), seek_speed, 2.0f);
 }
 
@@ -354,7 +345,7 @@ const Entity &AIController::GetEvadeTarget() const noexcept {
        return *evade_target;
 }
 
-glm::vec3 AIController::GetEvadeForce(const EntityState &state) const noexcept{
+glm::vec3 AIController::GetEvadeForce(const Entity &, const EntityState &state) const noexcept{
        glm::vec3 cur_diff(state.Diff(GetEvadeTarget().GetState()));
        float time_estimate = length(cur_diff) / evade_speed;
        EntityState pred_state(GetEvadeTarget().GetState());
@@ -400,7 +391,7 @@ const Entity &AIController::GetPursuitTarget() const noexcept {
        return *pursuit_target;
 }
 
-glm::vec3 AIController::GetPursuitForce(const EntityState &state) const noexcept {
+glm::vec3 AIController::GetPursuitForce(const Entity &, const EntityState &state) const noexcept {
        glm::vec3 cur_diff(state.Diff(GetPursuitTarget().GetState()));
        float time_estimate = length(cur_diff) / pursuit_speed;
        EntityState pred_state(GetPursuitTarget().GetState());
@@ -434,8 +425,8 @@ void AIController::SetWanderParams(
        wander_disp = displacement;
 }
 
-glm::vec3 AIController::GetWanderForce(const EntityState &state) const noexcept {
-       glm::vec3 wander_target(normalize(Heading(state) * wander_dist + wander_pos) * wander_speed);
+glm::vec3 AIController::GetWanderForce(const Entity &e, const EntityState &state) const noexcept {
+       glm::vec3 wander_target(normalize(e.Heading() * wander_dist + wander_pos) * wander_speed);
        return TargetVelocity(wander_target, state, 0.5f);
 }
 
index 18f593ac5831d218f0019723c511ff977a7e2ffe..aba3e767421534b9f7dde0b97ba124b68cbb3566 100644 (file)
@@ -398,7 +398,6 @@ void NetworkedInput::MergePlayerCorrection(uint16_t seq, const EntityState &corr
 
        vector<WorldCollision> col;
        while (entry != end) {
-               replay.Velocity(entry->state.velocity);
                SetMovement(entry->movement);
                GetWorld().Update(replay, entry->delta_t);
                entry->state.chunk_pos = replay.GetState().chunk_pos;
index 33eeb7db20540e5e354f1398d7105894d7b3f6ea..efd9224a9f86f7f7e25fbc0dd42bb7d116ea56bf 100644 (file)
@@ -62,7 +62,6 @@ public:
        glm::vec3 ControlForce(const EntityState &) const noexcept;
 
        const glm::vec3 &Velocity() const noexcept { return state.velocity; }
-       void Velocity(const glm::vec3 &v) noexcept { state.velocity = v; }
 
        bool Moving() const noexcept {
                return dot(Velocity(), Velocity()) > std::numeric_limits<float>::epsilon();
@@ -83,7 +82,6 @@ public:
 
        /// orientation of local coordinate system
        const glm::quat &Orientation() const noexcept { return state.orient; }
-       void Orientation(const glm::quat &o) noexcept { state.orient = o; }
 
        /// orientation of head within local coordinate system, in radians
        float Pitch() const noexcept { return state.pitch; }
@@ -98,6 +96,8 @@ public:
        /// get a ray in entity's face direction originating from center of vision
        Ray Aim(const Chunk::Pos &chunk_offset) const noexcept;
 
+       const glm::vec3 &Heading() const noexcept { return heading; }
+
        void SetState(const EntityState &s) noexcept { state = s; UpdateModel(); }
        const EntityState &GetState() const noexcept { return state; }
 
@@ -116,6 +116,8 @@ public:
 
 private:
        void UpdateModel() noexcept;
+       void UpdateView() noexcept;
+       void UpdateHeading() noexcept;
 
 private:
        EntityController *ctrl;
@@ -127,6 +129,13 @@ private:
        AABB bounds;
        EntityState state;
 
+       /// local transform of eyes
+       /// if this entity has no model, the eyes are assumed to
+       /// be at local origin and oriented towards -Z
+       glm::mat4 view_local;
+       /// normalized velocity or heading if standing still
+       glm::vec3 heading;
+
        // TODO: I'd prefer a drag solution
        float max_vel;
        float max_force;
index 925046cbd0c9f4a2559822b34821498d362c2f9a..4f73243c5d4ca61b87b0bd7ba92abca74c834287 100644 (file)
@@ -30,6 +30,7 @@ Entity::Entity() noexcept
 , name("anonymous")
 , bounds()
 , state()
+, heading(0.0f, 0.0f, -1.0f)
 , max_vel(5.0f)
 , max_force(25.0f)
 , ref_count(0)
@@ -112,20 +113,14 @@ glm::mat4 Entity::Transform(const glm::ivec3 &reference) const noexcept {
 }
 
 glm::mat4 Entity::ViewTransform(const glm::ivec3 &reference) const noexcept {
-       glm::mat4 transform = Transform(reference);
-       if (model) {
-               transform *= model.EyesTransform();
-       }
+       glm::mat4 transform = view_local;
+       transform[3] += glm::vec4(state.RelativePosition(reference), 0.0f);
        return transform;
 }
 
 Ray Entity::Aim(const Chunk::Pos &chunk_offset) const noexcept {
        glm::mat4 transform = ViewTransform(chunk_offset);
-       glm::vec4 from = transform * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
-       from /= from.w;
-       glm::vec4 to = transform * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f);
-       to /= to.w;
-       return Ray{ glm::vec3(from), glm::normalize(glm::vec3(to - from)) };
+       return Ray{ glm::vec3(transform[3]), -glm::vec3(transform[2]) };
 }
 
 void Entity::UpdateModel() noexcept {
@@ -143,11 +138,33 @@ void Entity::UpdateModel() noexcept {
 }
 
 void Entity::Update(float dt) {
+       UpdateView();
+       UpdateHeading();
        if (HasController()) {
                GetController().Update(*this, dt);
        }
 }
 
+void Entity::UpdateView() noexcept {
+       // create local transform
+       view_local = Transform(ChunkCoords());
+       // clear the translation part
+       view_local[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+       // add the model's eyes translation, if any
+       if (model) {
+               view_local *= model.EyesTransform();
+       }
+}
+
+void Entity::UpdateHeading() noexcept {
+       if (Moving()) {
+               heading = normalize(Velocity());
+       } else {
+               // use -Z (forward axis) of local view transform
+               heading = -glm::vec3(view_local[2]);
+       }
+}
+
 
 EntityController::~EntityController() {
 
@@ -215,26 +232,19 @@ void EntityState::AdjustPosition() noexcept {
 }
 
 void EntityState::AdjustHeading() noexcept {
-       while (pitch > PI / 2) {
-               pitch = PI / 2;
-       }
-       while (pitch < -PI / 2) {
-               pitch = -PI / 2;
-       }
+       glm::clamp(pitch, -PI_0p5, PI_0p5);
        while (yaw > PI) {
-               yaw -= PI * 2;
+               yaw -= PI_2p0;
        }
        while (yaw < -PI) {
-               yaw += PI * 2;
+               yaw += PI_2p0;
        }
 }
 
 glm::mat4 EntityState::Transform(const glm::ivec3 &reference) const noexcept {
        const glm::vec3 translation = RelativePosition(reference);
        glm::mat4 transform(toMat4(orient));
-       transform[3].x = translation.x;
-       transform[3].y = translation.y;
-       transform[3].z = translation.z;
+       transform[3] = glm::vec4(translation, 1.0f);
        return transform;
 }