]> git.localhorst.tv Git - blobs.git/commitdiff
switch creatures with left click
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 8 Dec 2017 22:38:52 +0000 (23:38 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 8 Dec 2017 22:38:52 +0000 (23:38 +0100)
src/app/Application.hpp
src/app/states.cpp
src/blobs.cpp
src/graphics/Viewport.hpp
src/math/geometry.hpp

index 040935f714d2a2a7081470a4dd31ba660faec024..1ae7b6f12eb8b607050262ecd597cfa891d47536 100644 (file)
@@ -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.
index cbb2309581f05d35f0babf00374b0b97729ccaf0..eff36da0f4621c3225571216507dae99e630cfa3 100644 (file)
@@ -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;
        }
index f5cc98842b0c13280761b8004c176277a847625a..1cd3f9fad69cb6b01c60d67cf34264ab5cdd833f 100644 (file)
 
 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();
 
index eab642bae94ff76cf4facadb4e7d4a13c16c0b42..ef227b41da9072175b0a157a81f50441ecf65bb6 100644 (file)
@@ -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();
 
index 6410ee013cb622f84879e3788dfd5dee8bb6d720..8f062841fe8adf64b05f6c8a0668f3e8a07adf2f 100644 (file)
@@ -4,6 +4,8 @@
 #include "glm.hpp"
 
 #include <algorithm>
+#include <ostream>
+#include <glm/gtx/io.hpp>
 
 
 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 &,