X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld%2Fworld.cpp;h=d7e293a5509d2d456c88cbca5b09daa44fdb49ba;hb=b4deadd9f4e399207e2530ea39a447c0d9d260a3;hp=eee12833b39ca80d467d0f8fc19868284f796419;hpb=e22daa10d55c26f15a170ab76645e656e956901c;p=blobs.git diff --git a/src/world/world.cpp b/src/world/world.cpp index eee1283..d7e293a 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -1,4 +1,5 @@ #include "Body.hpp" +#include "CreatureCreatureCollision.hpp" #include "Orbit.hpp" #include "Planet.hpp" #include "Resource.hpp" @@ -9,9 +10,11 @@ #include "TileType.hpp" #include "../app/Assets.hpp" +#include "../creature/Composition.hpp" #include "../creature/Creature.hpp" #include "../graphics/Viewport.hpp" #include "../math/const.hpp" +#include "../math/geometry.hpp" #include "../math/OctaveNoise.hpp" #include "../math/SimplexNoise.hpp" @@ -140,6 +143,7 @@ glm::dmat4 Body::FromUniverse() const noexcept { namespace { std::vector ccache; +std::vector collisions; } void Body::Tick(double dt) { @@ -149,6 +153,7 @@ void Body::Tick(double dt) { for (creature::Creature *c : ccache) { c->Tick(dt); } + // first remove creatures so they don't collide for (auto c = Creatures().begin(); c != Creatures().end();) { if ((*c)->Removable()) { delete *c; @@ -157,6 +162,7 @@ void Body::Tick(double dt) { ++c; } } + CheckCollision(); } void Body::Cache() noexcept { @@ -179,6 +185,35 @@ void Body::Cache() noexcept { * glm::eulerAngleY(-rotation); } +void Body::CheckCollision() noexcept { + if (Creatures().size() < 2) return; + collisions.clear(); + auto end = Creatures().end(); + for (auto i = Creatures().begin(); i != end; ++i) { + math::AABB i_box((*i)->CollisionBox()); + glm::dmat4 i_mat((*i)->CollisionTransform()); + for (auto j = (i + 1); j != end; ++j) { + glm::dvec3 diff((*i)->GetSituation().Position() - (*j)->GetSituation().Position()); + double max_dist = ((*i)->Size() + (*j)->Size()) * 1.74; + if (length2(diff) > max_dist * max_dist) continue; + math::AABB j_box((*j)->CollisionBox()); + glm::dmat4 j_mat((*j)->CollisionTransform()); + glm::dvec3 normal; + double depth; + if (Intersect(i_box, i_mat, j_box, j_mat, normal, depth)) { + collisions.push_back({ **i, **j, normal, depth }); + } + } + } + for (auto &c : collisions) { + c.A().GetSituation().Move(c.Normal() * (c.Depth() * -0.5)); + c.B().GetSituation().Move(c.Normal() * (c.Depth() * 0.5)); + c.A().GetSituation().Accelerate(c.Normal() * -dot(c.Normal(), c.AVel())); + c.B().GetSituation().Accelerate(c.Normal() * -dot(c.Normal(), c.BVel())); + // TODO: notify participants so they can be annoyed + } +} + void Body::AddCreature(creature::Creature *c) { creatures.push_back(c); } @@ -191,6 +226,26 @@ void Body::RemoveCreature(creature::Creature *c) { } +CreatureCreatureCollision::~CreatureCreatureCollision() { +} + +const glm::dvec3 &CreatureCreatureCollision::APos() const noexcept { + return a->GetSituation().Position(); +} + +const glm::dvec3 &CreatureCreatureCollision::AVel() const noexcept { + return a->GetSituation().Velocity(); +} + +const glm::dvec3 &CreatureCreatureCollision::BPos() const noexcept { + return b->GetSituation().Position(); +} + +const glm::dvec3 &CreatureCreatureCollision::BVel() const noexcept { + return b->GetSituation().Velocity(); +} + + Orbit::Orbit() : sma(1.0) , ecc(0.0) @@ -347,34 +402,34 @@ 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; } } @@ -574,5 +629,18 @@ std::vector::const_iterator TileType::FindResource(int r) const 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; +} + } }