From: Daniel Karbach Date: Fri, 8 Dec 2017 22:38:52 +0000 (+0100) Subject: switch creatures with left click X-Git-Url: http://git.localhorst.tv/?p=blobs.git;a=commitdiff_plain;h=200f9da6241613a1c19431896b09d1715c262c6d switch creatures with left click --- diff --git a/src/app/Application.hpp b/src/app/Application.hpp index 040935f..1ae7b6f 100644 --- a/src/app/Application.hpp +++ b/src/app/Application.hpp @@ -32,6 +32,12 @@ public: State &GetState(); bool HasState() const noexcept; + Window &GetWindow() noexcept { return window; } + const Window &GetWindow() const noexcept { return window; } + + graphics::Viewport &GetViewport() noexcept { return viewport; } + const graphics::Viewport &GetViewport() const noexcept { return viewport; } + /// Loop until states is empty. void Run(); /// Evaluate a single frame of dt milliseconds. diff --git a/src/app/states.cpp b/src/app/states.cpp index cbb2309..eff36da 100644 --- a/src/app/states.cpp +++ b/src/app/states.cpp @@ -1,5 +1,6 @@ #include "MasterState.hpp" +#include "Application.hpp" #include "../creature/Creature.hpp" #include "../graphics/Viewport.hpp" #include "../math/const.hpp" @@ -92,14 +93,33 @@ void MasterState::OnKeyDown(const SDL_KeyboardEvent &e) { } void MasterState::OnMouseDown(const SDL_MouseButtonEvent &e) { - if (e.button == SDL_BUTTON_RIGHT) { + if (e.button == SDL_BUTTON_RIGHT && cp.Shown()) { SDL_SetRelativeMouseMode(SDL_TRUE); cam_dragging = true; } } void MasterState::OnMouseUp(const SDL_MouseButtonEvent &e) { - if (e.button == SDL_BUTTON_RIGHT) { + if (e.button == SDL_BUTTON_LEFT) { + glm::dmat4 inverse(glm::inverse(cam.Projection() * cam.View())); + math::Ray ray(inverse * App().GetViewport().ShootPixel(e.x, e.y)); + creature::Creature *closest = nullptr; + double closest_dist = 1.0e24; + for (creature::Creature *c : sim.LiveCreatures()) { + glm::dvec3 normal(0.0); + double dist = 0.0; + if (Intersect(ray, c->CollisionBox(), glm::dmat4(cam.Model(c->GetSituation().GetPlanet())) * c->CollisionTransform(), normal, dist) + && dist < closest_dist) { + closest = c; + closest_dist = dist; + } + } + if (closest) { + cp.Show(*closest); + } else { + cp.Hide(); + } + } else if (e.button == SDL_BUTTON_RIGHT) { SDL_SetRelativeMouseMode(SDL_FALSE); cam_dragging = false; } diff --git a/src/blobs.cpp b/src/blobs.cpp index f5cc988..1cd3f9f 100644 --- a/src/blobs.cpp +++ b/src/blobs.cpp @@ -15,36 +15,6 @@ using namespace blobs; -namespace { - -struct SwitchPanel { - SwitchPanel(world::Planet &p, app::Application &app, app::MasterState &state) - : planet(p), app(app), state(state) { } - - void operator ()(creature::Creature &c) { - if (planet.Creatures().empty()) { - planet.GetSimulation().Log() << "no more creatures, game over" << std::endl; - state.GetCreaturePanel().Hide(); - while (app.HasState()) { - app.PopState(); - } - } else { - for (auto a : planet.Creatures()) { - if (a != &c) { - state.GetCreaturePanel().Show(*a); - a->WhenDead([&](creature::Creature &b) { (*this)(b); }); - break; - } - } - } - } - - world::Planet &planet; - app::Application &app; - app::MasterState &state; -}; -} - int main(int argc, char *argv[]) { app::Init init(true, 8); app::Assets assets; @@ -101,8 +71,6 @@ int main(int argc, char *argv[]) { state.GetTimePanel().SetBody(planet); app::Application app(init.window, init.viewport); - SwitchPanel swp(planet, app, state); - blob->WhenDead([&](creature::Creature &c) { swp(c); }); app.PushState(&state); app.Run(); diff --git a/src/graphics/Viewport.hpp b/src/graphics/Viewport.hpp index eab642b..ef227b4 100644 --- a/src/graphics/Viewport.hpp +++ b/src/graphics/Viewport.hpp @@ -1,6 +1,8 @@ #ifndef BLOBS_GRAPHICS_VIEWPORT_HPP_ #define BLOBS_GRAPHICS_VIEWPORT_HPP_ +#include "../math/geometry.hpp" + namespace blobs { namespace graphics { @@ -26,6 +28,13 @@ public: } void Resize(int w, int h); + math::Ray ShootPixel(int x, int y) const noexcept { + return math::Ray({ + ((double(x) / double(width)) * 2.0) - 1.0, + 1.0 - ((double(y) / double(height)) * 2.0), + -1.0 }, { 0.0, 0.0, 1.0 }); + } + void Clear(); void ClearDepth(); diff --git a/src/math/geometry.hpp b/src/math/geometry.hpp index 6410ee0..8f06284 100644 --- a/src/math/geometry.hpp +++ b/src/math/geometry.hpp @@ -4,6 +4,8 @@ #include "glm.hpp" #include +#include +#include namespace blobs { @@ -26,6 +28,9 @@ struct AABB { }; +inline std::ostream &operator <<(std::ostream &out, const AABB &b) { + return out << "AABB(" << b.min << ", " << b.max << ")"; +} /// matrices must not scale bool Intersect( const AABB &a_box, @@ -54,6 +59,16 @@ private: }; +inline Ray operator *(const glm::dmat4 &m, const Ray &r) noexcept { + glm::dvec4 o(m * glm::dvec4(r.Origin(), 1.0)); + glm::dvec4 d(m * glm::dvec4(r.Origin() + r.Direction(), 1.0)); + return Ray(glm::dvec3(o) / o.w, glm::normalize((glm::dvec3(d) / d.w) - (glm::dvec3(o) / o.w))); +} + +inline std::ostream &operator <<(std::ostream &out, const Ray &r) { + return out << "Ray(" << r.Origin() << ", " << r.Direction() << ")"; +} + /// oriented ray/box intersection test bool Intersect( const Ray &,