From f764c5e628865648bb277b1081bc23d60de38d9d Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Mon, 4 Dec 2017 14:53:23 +0100 Subject: [PATCH] perception --- src/creature/Creature.hpp | 4 ++++ src/creature/creature.cpp | 23 +++++++++++++++++++++++ src/creature/goal.cpp | 6 ++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/creature/Creature.hpp b/src/creature/Creature.hpp index 1c2556a..28e4131 100644 --- a/src/creature/Creature.hpp +++ b/src/creature/Creature.hpp @@ -130,6 +130,10 @@ public: double Adaptability() const noexcept; double OffspringMass() const noexcept; + double PerceptionRange() const noexcept; + double PerceptionOmniRange() const noexcept; + double PerceptionField() const noexcept; + bool PerceptionTest(const glm::dvec3 &) const noexcept; /// chance of giving birth per tick double OffspringChance() const noexcept; /// chance of arbitrary genetic mutation per tick diff --git a/src/creature/creature.cpp b/src/creature/creature.cpp index 376ad3f..667dc17 100644 --- a/src/creature/creature.cpp +++ b/src/creature/creature.cpp @@ -321,6 +321,28 @@ double Creature::OffspringMass() const noexcept { return properties.OffspringMass(); } +double Creature::PerceptionRange() const noexcept { + return 3.0 * (Dexerty() / (Dexerty() + 1)) + Size(); +} + +double Creature::PerceptionOmniRange() const noexcept { + return 0.5 * (Dexerty() / (Dexerty() + 1)) + Size(); +} + +double Creature::PerceptionField() const noexcept { + // this is the cosine of half the angle, so 1.0 is none, -1.0 is perfect + return 0.8 - (Dexerty() / (Dexerty() + 1)); +} + +bool Creature::PerceptionTest(const glm::dvec3 &p) const noexcept { + const glm::dvec3 diff(p - situation.Position()); + double omni_range = PerceptionOmniRange(); + if (length2(diff) < omni_range * omni_range) return true; + double range = PerceptionRange(); + if (length2(diff) > range * range) return false; + return dot(normalize(diff), situation.Heading()) > PerceptionField(); +} + double Creature::OffspringChance() const noexcept { return AgeFactor(0.25) * properties.Fertility() * (1.0 / 3600.0); } @@ -925,6 +947,7 @@ glm::dvec3 Steering::Force(const Situation::State &s) const noexcept { if (&*other == &c) continue; glm::dvec3 diff = s.Position() - other->GetSituation().Position(); if (length2(diff) > max_look * max_look) continue; + if (!c.PerceptionTest(other->GetSituation().Position())) continue; double sep = length(diff) - other->Size() * 0.707 - c.Size() * 0.707; if (sep < min_dist) { repulse += normalize(diff) * (1.0 - sep / min_dist); diff --git a/src/creature/goal.cpp b/src/creature/goal.cpp index f20ecc5..61ecb37 100644 --- a/src/creature/goal.cpp +++ b/src/creature/goal.cpp @@ -406,9 +406,11 @@ void LocateResourceGoal::SearchVicinity() { const world::TileType &type = planet.TypeAt(srf, x, y); auto yield = type.FindBestResource(accept); if (yield != type.resources.cend()) { + glm::dvec3 tc(planet.TileCenter(srf, x, y)); + if (!GetCreature().PerceptionTest(tc)) continue; // TODO: subtract minimum yield rating[y - begin.y][x - begin.x] = yield->ubiquity * accept.Get(yield->resource); - double dist = std::max(0.125, 0.25 * glm::length(planet.TileCenter(srf, x, y) - pos)); + double dist = std::max(0.125, 0.25 * glm::length(tc - pos)); rating[y - begin.y][x - begin.x] /= dist; } } @@ -421,7 +423,7 @@ void LocateResourceGoal::SearchVicinity() { glm::ivec2 coords(c->GetSituation().SurfacePosition()); if (coords.x < begin.x || coords.x >= end.x) continue; if (coords.y < begin.y || coords.y >= end.y) continue; - rating[coords.y - begin.y][coords.x - begin.x] *= 0.9; + rating[coords.y - begin.y][coords.x - begin.x] *= 0.8; } glm::ivec2 best_pos(0); -- 2.39.2