]> git.tdb.fi Git - r2c2.git/commitdiff
Edit a single terrain node at a time if shift is held
authorMikko Rasa <tdb@tdb.fi>
Thu, 21 Nov 2013 17:48:50 +0000 (19:48 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 21 Nov 2013 17:48:50 +0000 (19:48 +0200)
source/designer/terraintool.cpp
source/designer/terraintool.h
source/libr2c2/terrain.cpp

index 46076ec03c0679573161853c1485145a2aa4fce5..5dddb8247ead42f667844f07c29e6a2ef9663cb1 100644 (file)
@@ -12,25 +12,13 @@ TerrainTool::TerrainTool(Designer &d, Input::Keyboard &k, Input::Mouse &m, Terra
        Tool(d, k, m),
        terrain(t),
        marker((GL::VERTEX3, GL::COLOR4_UBYTE)),
+       marker_orientation(0),
        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();
+       update_marker();
 }
 
 TerrainTool::~TerrainTool()
@@ -38,6 +26,56 @@ TerrainTool::~TerrainTool()
        designer.get_layout_3d().get_scene().remove(*this);
 }
 
+void TerrainTool::update_marker()
+{
+       marker.clear();
+       GL::MeshBuilder bld(marker);
+
+       float ts = terrain.get_type().get_tile_size();
+       if(shift_held)
+       {
+               bld.begin(GL::TRIANGLE_STRIP);
+               bld.vertex(0, ts/2, ts/4);
+               bld.vertex(0, ts/2, -ts/4);
+               bld.vertex(0, 0, ts/4);
+               bld.vertex(0, 0, -ts/4);
+               bld.vertex(ts/2, 0, ts/4);
+               bld.vertex(ts/2, 0, -ts/4);
+               bld.end();
+       }
+       else
+       {
+               bld.begin(GL::TRIANGLE_STRIP);
+               bld.vertex(-ts/2, 0, ts/4);
+               bld.vertex(-ts/2, 0, -ts/4);
+               bld.vertex((edit_size+0.5)*ts, 0, ts/4);
+               bld.vertex((edit_size+0.5)*ts, 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, (edit_size+0.5)*ts, ts/4);
+               bld.vertex(0, (edit_size+0.5)*ts, -ts/4);
+               bld.end();
+       }
+}
+
+void TerrainTool::key_press(unsigned key)
+{
+       bool shift_was_held = shift_held;
+       Tool::key_press(key);
+       if(shift_held!=shift_was_held)
+               update_marker();
+}
+
+void TerrainTool::key_release(unsigned key)
+{
+       bool shift_was_held = shift_held;
+       Tool::key_release(key);
+       if(shift_held!=shift_was_held)
+               update_marker();
+}
+
 void TerrainTool::button_press(unsigned btn)
 {
        if(btn==1)
@@ -64,7 +102,7 @@ void TerrainTool::pointer_motion()
                        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);
+                       terrain.set_node_elevation(highlight_node, elev, !shift_held);
                        marker_position = terrain.get_node_position(highlight_node);
 
                        drag_start = pointer.y;
@@ -75,6 +113,7 @@ void TerrainTool::pointer_motion()
                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);
+               marker_orientation = highlight_node.i^(highlight_node.i>>1);
        }
 }
 
@@ -86,5 +125,6 @@ void TerrainTool::render(GL::Renderer &renderer, const GL::Tag &tag) const
        GL::Renderer::Push push(renderer);
 
        renderer.matrix_stack() *= GL::Matrix::translation(marker_position);
+       renderer.matrix_stack() *= GL::Matrix::rotation(Angle::from_turns(marker_orientation*0.25), 0, 0, 1);
        marker.draw(renderer);
 }
index f5f8354372ce9fe53a34baa49adfd1244e143bbb..e844ba28a64d57f1f05a0291e2c8bd2e61245cf8 100644 (file)
@@ -13,6 +13,7 @@ private:
        Msp::GL::Mesh marker;
        R2C2::Terrain::NodeCoordinates highlight_node;
        R2C2::Vector marker_position;
+       unsigned marker_orientation;
        bool dragging;
        float drag_start;
 
@@ -21,6 +22,10 @@ public:
        virtual ~TerrainTool();
 
 private:
+       void update_marker();
+
+       virtual void key_press(unsigned);
+       virtual void key_release(unsigned);
        virtual void button_press(unsigned);
        virtual void button_release(unsigned);
        virtual void pointer_motion();
index d4f3e416a84357efd1107d82d3c2c1b9fe91e573..5a317747e74f96f57f3b598e934ee2e2773a012e 100644 (file)
@@ -144,7 +144,7 @@ Terrain::NodeCoordinates Terrain::get_closest_node(const Ray &ray) const
                        for(unsigned i=0; i<4; ++i)
                        {
                                NodeCoordinates c(x, y, i);
-                               Vector node_pos((x+i%2)*ts, (y+i/2)*ts, get_node_elevation(c));
+                               Vector node_pos((x+0.25+(i%2)*0.5)*ts, (y+0.25+(i/2)*0.5)*ts, get_node_elevation(c));
                                Vector v = node_pos-local_ray.get_start();
                                float dist = (v-local_ray.get_direction()*dot(local_ray.get_direction(), v)).norm();
                                if(closest_dist<0 || dist<closest_dist)