summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/builders/freeExtend.cpp77
-rw-r--r--ui/builders/freeExtend.h21
-rw-r--r--ui/builders/join.cpp55
-rw-r--r--ui/builders/join.h18
-rw-r--r--ui/builders/straight.cpp58
-rw-r--r--ui/builders/straight.h20
-rw-r--r--ui/editNetwork.cpp91
-rw-r--r--ui/editNetwork.h34
-rw-r--r--ui/gameMainWindow.cpp2
9 files changed, 57 insertions, 319 deletions
diff --git a/ui/builders/freeExtend.cpp b/ui/builders/freeExtend.cpp
deleted file mode 100644
index aff7cd7..0000000
--- a/ui/builders/freeExtend.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-#include "freeExtend.h"
-#include <game/geoData.h>
-
-std::string
-BuilderFreeExtend::hint() const
-{
- if (p1) {
- return "Pick next point";
- }
- return "Pick start node";
-}
-
-void
-BuilderFreeExtend::move(
- Network * network, const GeoData * geoData, const SDL_MouseMotionEvent &, const Ray<GlobalPosition3D> & ray)
-{
- if (p1) {
- if (const auto p = network->intersectRayNodes(ray)) {
- candidateLinks = network->candidateJoins(*p1, p->pos);
- }
- else if (const auto p = geoData->intersectRay(ray)) {
- candidateLinks = network->candidateExtend(*p1, p->first);
- }
- else {
- candidateLinks.clear();
- }
- }
- else {
- candidateLinks.clear();
- }
-}
-
-void
-BuilderFreeExtend::click(
- Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray<GlobalPosition3D> & ray)
-{
- switch (e.button) {
- case SDL_BUTTON_LEFT:
- if (p1) {
- if (const auto p = network->intersectRayNodes(ray)) {
- createJoin(network, geoData, *p1, p->pos);
- p1 = p->pos;
- }
- else if (const auto p = geoData->intersectRay(ray)) {
- createExtend(network, geoData, *p1, p->first);
- p1 = p->first;
- }
- }
- else {
- if (const auto p = network->intersectRayNodes(ray)) {
- p1 = p->pos;
- }
- }
- return;
- case SDL_BUTTON_MIDDLE:
- p1.reset();
- return;
- }
-}
-
-Link::CCollection
-BuilderFreeExtend::createJoin(
- Network * network, const GeoData * geoData, GlobalPosition3D p1, GlobalPosition3D p2) const
-{
- const auto links = network->addJoins(geoData, p1, p2);
- setHeightsFor(network, links);
- return links;
-}
-
-Link::CCollection
-BuilderFreeExtend::createExtend(
- Network * network, const GeoData * geoData, GlobalPosition3D p1, GlobalPosition3D p2) const
-{
- const auto links = network->addExtend(geoData, p1, p2);
- setHeightsFor(network, links);
- return links;
-}
diff --git a/ui/builders/freeExtend.h b/ui/builders/freeExtend.h
deleted file mode 100644
index 6f28493..0000000
--- a/ui/builders/freeExtend.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-#include "../editNetwork.h"
-
-class Network;
-class GeoData;
-
-class BuilderFreeExtend : public EditNetwork::Builder {
-private:
- std::string hint() const override;
- void click(Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e,
- const Ray<GlobalPosition3D> & ray) override;
- void move(Network * network, const GeoData * geoData, const SDL_MouseMotionEvent & e,
- const Ray<GlobalPosition3D> & ray) override;
-
-public:
- Link::CCollection createJoin(Network * network, const GeoData *, GlobalPosition3D, GlobalPosition3D) const;
- Link::CCollection createExtend(Network * network, const GeoData *, GlobalPosition3D, GlobalPosition3D) const;
-
-private:
- std::optional<GlobalPosition3D> p1;
-};
diff --git a/ui/builders/join.cpp b/ui/builders/join.cpp
deleted file mode 100644
index f6cbce5..0000000
--- a/ui/builders/join.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "join.h"
-#include <game/geoData.h>
-
-std::string
-BuilderJoin::hint() const
-{
- if (p1) {
- return "Pick second node";
- }
- return "Pick first node";
-}
-
-void
-BuilderJoin::move(Network * network, const GeoData *, const SDL_MouseMotionEvent &, const Ray<GlobalPosition3D> & ray)
-{
- if (p1) {
- if (const auto p = network->intersectRayNodes(ray)) {
- candidateLinks = network->candidateJoins(p1->pos, p->pos);
- }
- else {
- candidateLinks.clear();
- }
- }
-}
-
-void
-BuilderJoin::click(
- Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray<GlobalPosition3D> & ray)
-{
- switch (e.button) {
- case SDL_BUTTON_LEFT:
- if (const auto p = network->intersectRayNodes(ray)) {
- if (p1) {
- create(network, geoData, p1, p);
- p1.reset();
- candidateLinks.clear();
- }
- else {
- p1 = p;
- }
- }
- return;
- case SDL_BUTTON_MIDDLE:
- p1.reset();
- return;
- }
-}
-
-Link::CCollection
-BuilderJoin::create(Network * network, const GeoData * geoData, const Node::Ptr & p1, const Node::Ptr & p2) const
-{
- const auto links = network->addJoins(geoData, p1->pos, p2->pos);
- setHeightsFor(network, links);
- return links;
-}
diff --git a/ui/builders/join.h b/ui/builders/join.h
deleted file mode 100644
index 326d23d..0000000
--- a/ui/builders/join.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-#include "../editNetwork.h"
-
-class Network;
-class GeoData;
-
-class BuilderJoin : public EditNetwork::Builder {
-private:
- std::string hint() const override;
- void click(Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e,
- const Ray<GlobalPosition3D> & ray) override;
- void move(Network * network, const GeoData * geoData, const SDL_MouseMotionEvent & e,
- const Ray<GlobalPosition3D> & ray) override;
-
- Link::CCollection create(Network * network, const GeoData *, const Node::Ptr & p1, const Node::Ptr & p2) const;
-
- Node::Ptr p1;
-};
diff --git a/ui/builders/straight.cpp b/ui/builders/straight.cpp
deleted file mode 100644
index e7d83b5..0000000
--- a/ui/builders/straight.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#include "straight.h"
-#include "stream_support.h"
-#include <game/geoData.h>
-
-std::string
-BuilderStraight::hint() const
-{
- if (p1) {
- return "Pick straight end point";
- }
- return "Pick straight start point";
-}
-
-void
-BuilderStraight::move(
- Network * network, const GeoData * geoData, const SDL_MouseMotionEvent &, const Ray<GlobalPosition3D> & ray)
-{
- if (p1) {
- if (const auto p = geoData->intersectRay(ray)) {
- candidateLinks = network->candidateStraight(*p1, p->first);
- }
- else {
- candidateLinks.clear();
- }
- }
-}
-
-void
-BuilderStraight::click(
- Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray<GlobalPosition3D> & ray)
-{
- switch (e.button) {
- case SDL_BUTTON_LEFT:
- if (const auto p = geoData->intersectRay(ray)) {
- if (p1) {
- create(network, geoData, *p1, p->first);
- candidateLinks.clear();
- p1.reset();
- }
- else {
- p1 = p->first;
- }
- }
- return;
- case SDL_BUTTON_MIDDLE:
- p1.reset();
- candidateLinks.clear();
- return;
- }
-}
-
-Link::CCollection
-BuilderStraight::create(Network * network, const GeoData * geoData, GlobalPosition3D p1, GlobalPosition3D p2) const
-{
- const auto links = network->addStraight(geoData, p1, p2);
- setHeightsFor(network, links);
- return links;
-}
diff --git a/ui/builders/straight.h b/ui/builders/straight.h
deleted file mode 100644
index 0a6f290..0000000
--- a/ui/builders/straight.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-#include "../editNetwork.h"
-
-class Network;
-class GeoData;
-
-class BuilderStraight : public EditNetwork::Builder {
-private:
- std::string hint() const override;
- void click(Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e,
- const Ray<GlobalPosition3D> & ray) override;
- void move(Network * network, const GeoData * geoData, const SDL_MouseMotionEvent & e,
- const Ray<GlobalPosition3D> & ray) override;
-
-public:
- Link::CCollection create(Network * network, const GeoData *, GlobalPosition3D p1, GlobalPosition3D p2) const;
-
-private:
- std::optional<GlobalPosition3D> p1;
-};
diff --git a/ui/editNetwork.cpp b/ui/editNetwork.cpp
index c900191..cab13f2 100644
--- a/ui/editNetwork.cpp
+++ b/ui/editNetwork.cpp
@@ -1,32 +1,53 @@
#include "editNetwork.h"
-#include "builders/freeExtend.h"
-#include "builders/join.h"
-#include "builders/straight.h"
#include "imgui_wrap.h"
#include <game/gamestate.h>
#include <game/terrain.h>
#include <gfx/gl/sceneShader.h>
#include <gfx/models/texture.h>
-constexpr const glm::u8vec4 TRANSPARENT_BLUE {30, 50, 255, 200};
-
-EditNetwork::EditNetwork(Network * n) : network {n}, blue {1, 1, &TRANSPARENT_BLUE} { }
+EditNetwork::EditNetwork(Network * n) : network {n} { }
bool
-EditNetwork::click(const SDL_MouseButtonEvent & e, const Ray<GlobalPosition3D> & ray)
+EditNetwork::click(const SDL_MouseButtonEvent & event, const Ray<GlobalPosition3D> & ray)
{
- if (builder && (e.button == SDL_BUTTON_LEFT || e.button == SDL_BUTTON_MIDDLE)) {
- builder->click(network, gameState->terrain.get(), e, ray);
- return true;
+ switch (event.button) {
+ case SDL_BUTTON_MIDDLE:
+ currentStart.reset();
+ candidates.clear();
+ return true;
+ case SDL_BUTTON_LEFT:
+ if (!currentStart) {
+ currentStart = resolveRay(ray);
+ }
+ else {
+ if (const auto def = resolveRay(ray)) {
+ candidates = network->create(CreationDefinition {.fromEnd = *currentStart, .toEnd = *def});
+ for (const auto & link : candidates) {
+ network->add(gameState->terrain.get(), link);
+ }
+ if (continuousMode) {
+ currentStart = def;
+ currentStart->direction = candidates.back()->endAt(def->position)->dir;
+ }
+ else {
+ currentStart.reset();
+ }
+ candidates.clear();
+ }
+ }
+ return true;
+ default:
+ return false;
}
- return false;
}
bool
-EditNetwork::move(const SDL_MouseMotionEvent & e, const Ray<GlobalPosition3D> & ray)
+EditNetwork::move(const SDL_MouseMotionEvent &, const Ray<GlobalPosition3D> & ray)
{
- if (builder) {
- builder->move(network, gameState->terrain.get(), e, ray);
+ if (currentStart) {
+ if (const auto def = resolveRay(ray)) {
+ candidates = network->create(CreationDefinition {.fromEnd = *currentStart, .toEnd = *def});
+ }
}
return false;
}
@@ -38,30 +59,22 @@ EditNetwork::handleInput(const SDL_Event &)
}
void
-EditNetwork::render(const SceneShader & shader, const Frustum & frustum) const
-{
- if (builder) {
- blue.bind();
- shader.absolute.use();
- builder->render(shader, frustum);
- }
-}
-
-void
-EditNetwork::Builder::render(const SceneShader & shader, const Frustum & frustum) const
+EditNetwork::render(const SceneShader &, const Frustum &) const
{
- candidateLinks.apply<const Renderable>(&Renderable::render, shader, frustum);
}
-void
-EditNetwork::Builder::setHeightsFor(Network * network, const Link::CCollection & links, GeoData::SetHeightsOpts opts)
+std::optional<CreationDefinitionEnd>
+EditNetwork::resolveRay(const Ray<GlobalPosition3D> & ray) const
{
- opts.surface = network->getBaseSurface();
- const auto width = network->getBaseWidth();
-
- for (const auto & link : links) {
- gameState->terrain->setHeights(link->getBase(width), opts);
+ if (const auto position = gameState->terrain->intersectRay(ray)) {
+ const auto node = network->intersectRayNodes(ray);
+ if (node) {
+ const auto direction = network->findNodeDirection(node);
+ return CreationDefinitionEnd {.position = node->pos, .direction = direction};
+ }
+ return CreationDefinitionEnd {.position = position->first, .direction = std::nullopt};
}
+ return {};
}
void
@@ -69,16 +82,6 @@ EditNetwork::render(bool & open)
{
ImGui::SetNextWindowSize({-1, -1});
ImGui::Begin("Edit Network", &open);
-
- auto builderChoice = [this]<typename Impl>(const char * name) {
- if (ImGui::RadioButton(name, dynamic_cast<Impl *>(builder.get()))) {
- builder = std::make_unique<Impl>();
- }
- };
- builderChoice.operator()<BuilderStraight>("Straight");
- builderChoice.operator()<BuilderJoin>("Join");
- builderChoice.operator()<BuilderFreeExtend>("Free Extend");
- ImGui::TextUnformatted(builder ? builder->hint().c_str() : "Select a build mode");
-
+ ImGui::Checkbox("Continuous mode", &continuousMode);
ImGui::End();
}
diff --git a/ui/editNetwork.h b/ui/editNetwork.h
index 4155534..e155105 100644
--- a/ui/editNetwork.h
+++ b/ui/editNetwork.h
@@ -1,6 +1,5 @@
#pragma once
-#include "game/geoData.h"
#include "gameMainSelector.h"
#include "worldOverlay.h"
#include <game/gamestate.h>
@@ -13,40 +12,25 @@ class EditNetwork : public GameMainSelector::Component, public WorldOverlay {
public:
explicit EditNetwork(Network *);
- bool click(const SDL_MouseButtonEvent & e, const Ray<GlobalPosition3D> &) override;
- bool move(const SDL_MouseMotionEvent & e, const Ray<GlobalPosition3D> &) override;
- bool handleInput(const SDL_Event & e) override;
+ bool click(const SDL_MouseButtonEvent &, const Ray<GlobalPosition3D> &) override;
+ bool move(const SDL_MouseMotionEvent &, const Ray<GlobalPosition3D> &) override;
+ bool handleInput(const SDL_Event &) override;
void render(const SceneShader &, const Frustum &) const override;
void render(bool & open) override;
- using NetworkClickPos = std::variant<GlobalPosition3D, Node::Ptr>;
-
- class Builder {
- public:
- virtual ~Builder() = default;
- virtual void render(const SceneShader & shader, const Frustum &) const;
- virtual std::string hint() const = 0;
- virtual void click(Network *, const GeoData *, const SDL_MouseButtonEvent &, const Ray<GlobalPosition3D> &) = 0;
- virtual void move(Network *, const GeoData *, const SDL_MouseMotionEvent &, const Ray<GlobalPosition3D> &) = 0;
-
- static void setHeightsFor(Network *, const Link::CCollection &, GeoData::SetHeightsOpts = {});
-
- using Ptr = std::unique_ptr<Builder>;
-
- protected:
- SharedCollection<const Link> candidateLinks;
- };
-
private:
+ [[nodiscard]] std::optional<CreationDefinitionEnd> resolveRay(const Ray<GlobalPosition3D> &) const;
+
Network * network;
- Builder::Ptr builder;
- Texture blue;
+ bool continuousMode {false};
+ std::optional<CreationDefinitionEnd> currentStart;
+ Link::Collection candidates;
};
template<typename T> class EditNetworkOf : public EditNetwork {
public:
template<typename... P>
- explicit EditNetworkOf(P &&... p) : EditNetwork(gameState->world.findOrCreate<T>(), std::forward<P>(p)...)
+ explicit EditNetworkOf(P &&... params) : EditNetwork(gameState->world.findOrCreate<T>(), std::forward<P>(params)...)
{
}
};
diff --git a/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp
index dbbf8a7..2b15284 100644
--- a/ui/gameMainWindow.cpp
+++ b/ui/gameMainWindow.cpp
@@ -52,7 +52,7 @@ private:
GameMainWindow::GameMainWindow(ScreenAbsCoord size) : SceneRenderer {size, 0}
{
- uiComponents.create<ManualCameraController>(glm::vec2 {310'727'624, 494'018'810});
+ uiComponents.create<ManualCameraController>(glm::vec2 {315103000, 491067000});
auto gms = uiComponents.create<GameMainSelector>(&camera);
uiComponents.create<GameMainToolbar>(gms);
}