X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld%2Fworld.cpp;h=1b2e058f90d666dfd79d52474ad12ad0fe652686;hb=475f28f06c9e14912bab8119264e247ef466513d;hp=9f19b68c02cdaa866a5c7bdc687daf945ad97f7b;hpb=b795a1df619349d45c3b0ca73e61e68ff483221c;p=blobs.git diff --git a/src/world/world.cpp b/src/world/world.cpp index 9f19b68..1b2e058 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -8,12 +8,13 @@ #include "Tile.hpp" #include "TileType.hpp" -#include "Creature.hpp" -#include "../const.hpp" #include "../app/Assets.hpp" +#include "../creature/Composition.hpp" +#include "../creature/Creature.hpp" #include "../graphics/Viewport.hpp" -#include "../rand/OctaveNoise.hpp" -#include "../rand/SimplexNoise.hpp" +#include "../math/const.hpp" +#include "../math/OctaveNoise.hpp" +#include "../math/SimplexNoise.hpp" #include #include @@ -50,11 +51,12 @@ Body::Body() , inverse_orbital(1.0) , local(1.0) , inverse_local(1.0) -, creatures() { +, creatures() +, atmosphere(-1) { } Body::~Body() { - for (Creature *c : creatures) { + for (creature::Creature *c : creatures) { delete c; } } @@ -137,6 +139,27 @@ glm::dmat4 Body::FromUniverse() const noexcept { return m; } +namespace { +std::vector ccache; +} + +void Body::Tick(double dt) { + rotation += dt * AngularMomentum() / Inertia(); + Cache(); + ccache = Creatures(); + for (creature::Creature *c : ccache) { + c->Tick(dt); + } + for (auto c = Creatures().begin(); c != Creatures().end();) { + if ((*c)->Removable()) { + delete *c; + c = Creatures().erase(c); + } else { + ++c; + } + } +} + void Body::Cache() noexcept { if (parent) { orbital = @@ -157,11 +180,17 @@ void Body::Cache() noexcept { * glm::eulerAngleY(-rotation); } -void Body::AddCreature(Creature *c) { - c->SetBody(*this); +void Body::AddCreature(creature::Creature *c) { creatures.push_back(c); } +void Body::RemoveCreature(creature::Creature *c) { + auto entry = std::find(creatures.begin(), creatures.end(), c); + if (entry != creatures.end()) { + creatures.erase(entry); + } +} + Orbit::Orbit() : sma(1.0) @@ -268,7 +297,6 @@ Planet::Planet(int sidelength) : Body() , sidelength(sidelength) , tiles(TilesTotal()) -, atmosphere(-1) , vao() { Radius(double(sidelength) / 2.0); } @@ -276,24 +304,41 @@ Planet::Planet(int sidelength) Planet::~Planet() { } -glm::dvec3 Planet::TileCenter(int surface, int x, int y) const noexcept { +const TileType &Planet::TypeAt(int srf, int x, int y) const { + return GetSimulation().TileTypes()[TileAt(srf, x, y).type]; +} + +glm::ivec2 Planet::SurfacePosition(int srf, const glm::dvec3 &pos) const noexcept { + return glm::ivec2( + PositionToTile(pos[(srf + 0) % 3]), + PositionToTile(pos[(srf + 1) % 3])); +} + +double Planet::SurfaceElevation(int srf, const glm::dvec3 &pos) const noexcept { + return srf < 3 + ? pos[(srf + 2) % 3] - Radius() + : -pos[(srf + 2) % 3] - Radius(); +} + +glm::dvec3 Planet::TileCenter(int srf, int x, int y, double e) const noexcept { glm::dvec3 center(0.0f); - center[(surface + 0) % 3] = x + 0.5 - Radius(); - center[(surface + 1) % 3] = y + 0.5 - Radius(); - center[(surface + 2) % 3] = surface < 3 ? Radius() : -Radius(); + center[(srf + 0) % 3] = x + 0.5 - Radius(); + center[(srf + 1) % 3] = y + 0.5 - Radius(); + center[(srf + 2) % 3] = srf < 3 ? (Radius() + e) : -(Radius() + e); return center; } void Planet::BuildVAO(const Set &ts) { - vao.Bind(); - vao.BindAttributes(); - vao.EnableAttribute(0); - vao.EnableAttribute(1); - vao.AttributePointer(0, false, offsetof(Attributes, position)); - vao.AttributePointer(1, false, offsetof(Attributes, tex_coord)); - vao.ReserveAttributes(TilesTotal() * 4, GL_STATIC_DRAW); + vao.reset(new graphics::SimpleVAO); + vao->Bind(); + vao->BindAttributes(); + vao->EnableAttribute(0); + vao->EnableAttribute(1); + vao->AttributePointer(0, false, offsetof(Attributes, position)); + vao->AttributePointer(1, false, offsetof(Attributes, tex_coord)); + vao->ReserveAttributes(TilesTotal() * 4, GL_STATIC_DRAW); { - auto attrib = vao.MapAttributes(GL_WRITE_ONLY); + auto attrib = vao->MapAttributes(GL_WRITE_ONLY); float offset = Radius(); // srf 0 1 2 3 4 5 @@ -303,43 +348,43 @@ void Planet::BuildVAO(const Set &ts) { for (int y = 0; y < sidelength; ++y) { for (int x = 0; x < sidelength; ++x, ++index) { float tex = ts[TileAt(surface, x, y).type].texture; - const float tex_u_begin = surface < 3 ? 1.0f : 0.0f; - const float tex_u_end = surface < 3 ? 0.0f : 1.0f; + const float tex_v_begin = surface < 3 ? 1.0f : 0.0f; + const float tex_v_end = surface < 3 ? 0.0f : 1.0f; attrib[4 * index + 0].position[(surface + 0) % 3] = x + 0 - offset; attrib[4 * index + 0].position[(surface + 1) % 3] = y + 0 - offset; attrib[4 * index + 0].position[(surface + 2) % 3] = surface < 3 ? offset : -offset; - attrib[4 * index + 0].tex_coord[0] = tex_u_begin; - attrib[4 * index + 0].tex_coord[1] = 1.0f; + attrib[4 * index + 0].tex_coord[0] = 0.0f; + attrib[4 * index + 0].tex_coord[1] = tex_v_begin; attrib[4 * index + 0].tex_coord[2] = tex; attrib[4 * index + 1].position[(surface + 0) % 3] = x + 0 - offset; attrib[4 * index + 1].position[(surface + 1) % 3] = y + 1 - offset; attrib[4 * index + 1].position[(surface + 2) % 3] = surface < 3 ? offset : -offset; - attrib[4 * index + 1].tex_coord[0] = tex_u_end; - attrib[4 * index + 1].tex_coord[1] = 1.0f; + attrib[4 * index + 1].tex_coord[0] = 0.0f; + attrib[4 * index + 1].tex_coord[1] = tex_v_end; attrib[4 * index + 1].tex_coord[2] = tex; attrib[4 * index + 2].position[(surface + 0) % 3] = x + 1 - offset; attrib[4 * index + 2].position[(surface + 1) % 3] = y + 0 - offset; attrib[4 * index + 2].position[(surface + 2) % 3] = surface < 3 ? offset : -offset; - attrib[4 * index + 2].tex_coord[0] = tex_u_begin; - attrib[4 * index + 2].tex_coord[1] = 0.0f; + attrib[4 * index + 2].tex_coord[0] = 1.0f; + attrib[4 * index + 2].tex_coord[1] = tex_v_begin; attrib[4 * index + 2].tex_coord[2] = tex; attrib[4 * index + 3].position[(surface + 0) % 3] = x + 1 - offset; attrib[4 * index + 3].position[(surface + 1) % 3] = y + 1 - offset; attrib[4 * index + 3].position[(surface + 2) % 3] = surface < 3 ? offset : -offset; - attrib[4 * index + 3].tex_coord[0] = tex_u_end; - attrib[4 * index + 3].tex_coord[1] = 0.0f; + attrib[4 * index + 3].tex_coord[0] = 1.0f; + attrib[4 * index + 3].tex_coord[1] = tex_v_end; attrib[4 * index + 3].tex_coord[2] = tex; } } } } - vao.BindElements(); - vao.ReserveElements(TilesTotal() * 6, GL_STATIC_DRAW); + vao->BindElements(); + vao->ReserveElements(TilesTotal() * 6, GL_STATIC_DRAW); { - auto element = vao.MapElements(GL_WRITE_ONLY); + auto element = vao->MapElements(GL_WRITE_ONLY); int index = 0; for (int surface = 0; surface < 3; ++surface) { for (int y = 0; y < sidelength; ++y) { @@ -366,30 +411,32 @@ void Planet::BuildVAO(const Set &ts) { } } } - vao.Unbind(); + vao->Unbind(); } void Planet::Draw(app::Assets &assets, graphics::Viewport &viewport) { - vao.Bind(); + if (!vao) return; + + vao->Bind(); const glm::mat4 &MV = assets.shaders.planet_surface.MV(); assets.shaders.planet_surface.SetNormal(glm::vec3(MV * glm::vec4(0.0f, 0.0f, 1.0f, 0.0f))); - vao.DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 0); + vao->DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 0); assets.shaders.planet_surface.SetNormal(glm::vec3(MV * glm::vec4(1.0f, 0.0f, 0.0f, 0.0f))); - vao.DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 1); + vao->DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 1); assets.shaders.planet_surface.SetNormal(glm::vec3(MV * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f))); - vao.DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 2); + vao->DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 2); assets.shaders.planet_surface.SetNormal(glm::vec3(MV * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f))); - vao.DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 3); + vao->DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 3); assets.shaders.planet_surface.SetNormal(glm::vec3(MV * glm::vec4(-1.0f, 0.0f, 0.0f, 0.0f))); - vao.DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 4); + vao->DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 4); assets.shaders.planet_surface.SetNormal(glm::vec3(MV * glm::vec4(0.0f, -1.0f, 0.0f, 0.0f))); - vao.DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 5); + vao->DrawTriangles(TilesPerSurface() * 6, TilesPerSurface() * 6 * 5); } void GenerateEarthlike(const Set &tiles, Planet &p) noexcept { - rand::SimplexNoise elevation_gen(0); - rand::SimplexNoise variation_gen(45623752346); + math::SimplexNoise elevation_gen(0); + math::SimplexNoise variation_gen(45623752346); const int ice = tiles["ice"].id; const int ocean = tiles["ocean"].id; @@ -427,7 +474,7 @@ void GenerateEarthlike(const Set &tiles, Planet &p) noexcept { p.TileAt(surface, x, y).type = ice; continue; } - float elevation = rand::OctaveNoise( + float elevation = math::OctaveNoise( elevation_gen, to_tile / p.Radius(), 3, // octaves @@ -436,7 +483,7 @@ void GenerateEarthlike(const Set &tiles, Planet &p) noexcept { 2, // amplitude 2 // growth ); - float variation = rand::OctaveNoise( + float variation = math::OctaveNoise( variation_gen, to_tile / p.Radius(), 3, // octaves @@ -517,5 +564,29 @@ Sun::Sun() Sun::~Sun() { } + +std::vector::const_iterator TileType::FindResource(int r) const { + auto yield = resources.cbegin(); + for (; yield != resources.cend(); ++yield) { + if (yield->resource == r) { + break; + } + } + return yield; +} + +std::vector::const_iterator TileType::FindBestResource(const creature::Composition &comp) const { + auto best = resources.cend(); + double best_value = 0.0; + for (auto yield = resources.cbegin(); yield != resources.cend(); ++yield) { + double value = comp.Get(yield->resource); + if (value > best_value) { + best = yield; + best_value = value; + } + } + return best; +} + } }