X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fcreature%2Fcreature.cpp;h=d870755cfa8ae46607c62d7b4be120c5755b290c;hb=b0e73e632f0b681a0af78f889dd82d370563944a;hp=4345bd9837b668bdd96a2cc612514c22a25ae686;hpb=69dade793864169f7773cc133d54277eea9bf760;p=blobs.git diff --git a/src/creature/creature.cpp b/src/creature/creature.cpp index 4345bd9..d870755 100644 --- a/src/creature/creature.cpp +++ b/src/creature/creature.cpp @@ -1,6 +1,7 @@ #include "Creature.hpp" #include "Genome.hpp" #include "Memory.hpp" +#include "NameGenerator.hpp" #include "Situation.hpp" #include "Steering.hpp" @@ -16,6 +17,7 @@ #include "../world/TileType.hpp" #include +#include #include #include @@ -41,7 +43,6 @@ Creature::Creature(world::Simulation &sim) , goals() , situation() , steering() -, vel(0.0) , vao() { } @@ -104,10 +105,20 @@ bool GoalCompare(const std::unique_ptr &a, const std::unique_ptr &b) } void Creature::Tick(double dt) { - // TODO: better integration method - glm::dvec3 acc(steering.Acceleration(*this)); - situation.Move(vel * dt); - vel += acc * dt; + { + Situation::State state(situation.GetState()); + Situation::Derivative a(Step(Situation::Derivative(), 0.0)); + Situation::Derivative b(Step(a, dt * 0.5)); + Situation::Derivative c(Step(b, dt * 0.5)); + Situation::Derivative d(Step(c, dt)); + Situation::Derivative f( + (1.0 / 6.0) * (a.vel + 2.0 * (b.vel + c.vel) + d.vel), + (1.0 / 6.0) * (a.acc + 2.0 * (b.acc + c.acc) + d.acc) + ); + state.pos += f.vel * dt; + state.vel += f.acc * dt; + situation.SetState(state); + } if (Age() > properties.death_age) { std::cout << "[" << int(sim.Time()) << "s] " @@ -151,6 +162,13 @@ void Creature::Tick(double dt) { } } +Situation::Derivative Creature::Step(const Situation::Derivative &ds, double dt) const noexcept { + Situation::State s = situation.GetState(); + s.pos += ds.vel * dt; + s.vel += ds.acc * dt; + return { s.vel, steering.Acceleration(s) }; +} + glm::dmat4 Creature::LocalTransform() noexcept { // TODO: surface transform const double half_size = size * 0.5; @@ -371,7 +389,7 @@ void Split(Creature &c) { Creature *a = new Creature(c.GetSimulation()); const Situation &s = c.GetSituation(); // TODO: generate names - a->Name("Blobby"); + a->Name(c.GetSimulation().Assets().name.Sequential()); // TODO: mutate c.GetGenome().Configure(*a); s.GetPlanet().AddCreature(a); @@ -382,7 +400,7 @@ void Split(Creature &c) { a->BuildVAO(); Creature *b = new Creature(c.GetSimulation()); - b->Name("Sir Blobalot"); + b->Name(c.GetSimulation().Assets().name.Sequential()); c.GetGenome().Configure(*b); s.GetPlanet().AddCreature(b); b->GetSituation().SetPlanetSurface( @@ -427,9 +445,23 @@ void Memory::TrackStay(const Location &l, double t) { } +NameGenerator::NameGenerator() +: counter(0) { +} + +NameGenerator::~NameGenerator() { +} + +std::string NameGenerator::Sequential() { + std::stringstream ss; + ss << "Blob " << ++counter; + return ss.str(); +} + + Situation::Situation() : planet(nullptr) -, position(0.0) +, state(glm::dvec3(0.0), glm::dvec3(0.0)) , surface(0) , type(LOST) { } @@ -446,34 +478,34 @@ bool Situation::OnSurface() const noexcept { } bool Situation::OnTile() const noexcept { - glm::ivec2 t(planet->SurfacePosition(surface, position)); + glm::ivec2 t(planet->SurfacePosition(surface, state.pos)); return type == PLANET_SURFACE && t.x >= 0 && t.x < planet->SideLength() && t.y >= 0 && t.y < planet->SideLength(); } glm::ivec2 Situation::SurfacePosition() const noexcept { - return planet->SurfacePosition(surface, position); + return planet->SurfacePosition(surface, state.pos); } world::Tile &Situation::GetTile() const noexcept { - glm::ivec2 t(planet->SurfacePosition(surface, position)); + glm::ivec2 t(planet->SurfacePosition(surface, state.pos)); return planet->TileAt(surface, t.x, t.y); } const world::TileType &Situation::GetTileType() const noexcept { - glm::ivec2 t(planet->SurfacePosition(surface, position)); + glm::ivec2 t(planet->SurfacePosition(surface, state.pos)); return planet->TypeAt(surface, t.x, t.y); } void Situation::Move(const glm::dvec3 &dp) noexcept { - position += dp; + state.pos += dp; if (OnSurface()) { // enforce ground constraint if (Surface() < 3) { - position[(Surface() + 2) % 3] = std::max(0.0, position[(Surface() + 2) % 3]); + state.pos[(Surface() + 2) % 3] = std::max(0.0, state.pos[(Surface() + 2) % 3]); } else { - position[(Surface() + 2) % 3] = std::min(0.0, position[(Surface() + 2) % 3]); + state.pos[(Surface() + 2) % 3] = std::min(0.0, state.pos[(Surface() + 2) % 3]); } } } @@ -482,7 +514,7 @@ void Situation::SetPlanetSurface(world::Planet &p, int srf, const glm::dvec3 &po type = PLANET_SURFACE; planet = &p; surface = srf; - position = pos; + state.pos = pos; } @@ -508,15 +540,15 @@ void Steering::GoTo(const glm::dvec3 &t) noexcept { seeking = true; } -glm::dvec3 Steering::Acceleration(Creature &c) const noexcept { +glm::dvec3 Steering::Acceleration(const Situation::State &s) const noexcept { glm::dvec3 acc(0.0); if (halting) { - SumForce(acc, c.Velocity() * -max_accel); + SumForce(acc, s.vel * -max_accel); } if (seeking) { - glm::dvec3 diff = seek_target - c.GetSituation().Position(); + glm::dvec3 diff = seek_target - s.pos; if (!allzero(diff)) { - SumForce(acc, ((normalize(diff) * max_speed) - c.Velocity()) * max_accel); + SumForce(acc, ((normalize(diff) * max_speed) - s.vel) * max_accel); } } return acc;