]> git.tdb.fi Git - r2c2.git/blobdiff - source/designer/terraintool.cpp
Add editable terrain objects
[r2c2.git] / source / designer / terraintool.cpp
diff --git a/source/designer/terraintool.cpp b/source/designer/terraintool.cpp
new file mode 100644 (file)
index 0000000..46076ec
--- /dev/null
@@ -0,0 +1,90 @@
+#include <cmath>
+#include <msp/gl/meshbuilder.h>
+#include <msp/input/keys.h>
+#include "designer.h"
+#include "terraintool.h"
+
+using namespace std;
+using namespace Msp;
+using namespace R2C2;
+
+TerrainTool::TerrainTool(Designer &d, Input::Keyboard &k, Input::Mouse &m, Terrain &t):
+       Tool(d, k, m),
+       terrain(t),
+       marker((GL::VERTEX3, GL::COLOR4_UBYTE)),
+       dragging(false),
+       drag_start(0)
+{
+       designer.get_layout_3d().get_scene().add(*this);
+
+       float ts = terrain.get_type().get_tile_size();
+       GL::MeshBuilder bld(marker);
+       bld.begin(GL::TRIANGLE_STRIP);
+       bld.vertex(-ts/2, 0, -ts/4);
+       bld.vertex(ts/2, 0, -ts/4);
+       bld.vertex(-ts/2, 0, ts/4);
+       bld.vertex(ts/2, 0, ts/4);
+       bld.end();
+       bld.begin(GL::TRIANGLE_STRIP);
+       bld.vertex(0, -ts/2, -ts/4);
+       bld.vertex(0, ts/2, -ts/4);
+       bld.vertex(0, -ts/2, ts/4);
+       bld.vertex(0, ts/2, ts/4);
+       bld.end();
+}
+
+TerrainTool::~TerrainTool()
+{
+       designer.get_layout_3d().get_scene().remove(*this);
+}
+
+void TerrainTool::button_press(unsigned btn)
+{
+       if(btn==1)
+       {
+               dragging = true;
+               drag_start = pointer.y;
+       }
+}
+
+void TerrainTool::button_release(unsigned btn)
+{
+       if(btn==1)
+               dragging = false;
+}
+
+void TerrainTool::pointer_motion()
+{
+       if(dragging)
+       {
+               float d = (pointer.y-drag_start)*20;
+
+               if(abs(d)>1)
+               {
+                       float elev = terrain.get_node_elevation(highlight_node);
+                       float eg = terrain.get_type().get_elevation_granularity();
+                       elev += eg*d;
+                       terrain.set_node_elevation(highlight_node, elev, true);
+                       marker_position = terrain.get_node_position(highlight_node);
+
+                       drag_start = pointer.y;
+               }
+       }
+       else
+       {
+               Ray ray = designer.get_view().create_ray(pointer.x, pointer.y);
+               highlight_node = terrain.get_closest_node(ray);
+               marker_position = terrain.get_node_position(highlight_node);
+       }
+}
+
+void TerrainTool::render(GL::Renderer &renderer, const GL::Tag &tag) const
+{
+       if(tag.id)
+               return;
+
+       GL::Renderer::Push push(renderer);
+
+       renderer.matrix_stack() *= GL::Matrix::translation(marker_position);
+       marker.draw(renderer);
+}