]> git.tdb.fi Git - r2c2.git/commitdiff
Support editing multiple terrain tiles at once
authorMikko Rasa <tdb@tdb.fi>
Thu, 21 Nov 2013 23:34:38 +0000 (01:34 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 21 Nov 2013 23:34:38 +0000 (01:34 +0200)
source/designer/terraintool.cpp
source/designer/terraintool.h

index 5dddb8247ead42f667844f07c29e6a2ef9663cb1..4e339bc7de9b33abac4dea956ac624c1b5b5bec4 100644 (file)
@@ -12,6 +12,7 @@ TerrainTool::TerrainTool(Designer &d, Input::Keyboard &k, Input::Mouse &m, Terra
        Tool(d, k, m),
        terrain(t),
        marker((GL::VERTEX3, GL::COLOR4_UBYTE)),
+       edit_size(0),
        marker_orientation(0),
        dragging(false),
        drag_start(0)
@@ -32,15 +33,32 @@ void TerrainTool::update_marker()
        GL::MeshBuilder bld(marker);
 
        float ts = terrain.get_type().get_tile_size();
+       bld.matrix() *= GL::Matrix::translation(edit_size/2*-ts, edit_size/2*-ts, 0);
        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);
+               if(edit_size==0)
+               {
+                       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);
+               }
+               else
+               {
+                       bld.vertex(0, 0, ts/4);
+                       bld.vertex(0, 0, -ts/4);
+                       bld.vertex(edit_size*ts, 0, ts/4);
+                       bld.vertex(edit_size*ts, 0, -ts/4);
+                       bld.vertex(edit_size*ts, edit_size*ts, ts/4);
+                       bld.vertex(edit_size*ts, edit_size*ts, -ts/4);
+                       bld.vertex(0, edit_size*ts, ts/4);
+                       bld.vertex(0, edit_size*ts, -ts/4);
+                       bld.element(0);
+                       bld.element(1);
+               }
                bld.end();
        }
        else
@@ -57,15 +75,46 @@ void TerrainTool::update_marker()
                bld.vertex(0, (edit_size+0.5)*ts, ts/4);
                bld.vertex(0, (edit_size+0.5)*ts, -ts/4);
                bld.end();
+               if(edit_size>0)
+               {
+                       bld.begin(GL::TRIANGLE_STRIP);
+                       bld.vertex(-ts/2, edit_size*ts, ts/4);
+                       bld.vertex(-ts/2, edit_size*ts, -ts/4);
+                       bld.vertex((edit_size+0.5)*ts, edit_size*ts, ts/4);
+                       bld.vertex((edit_size+0.5)*ts, edit_size*ts, -ts/4);
+                       bld.end();
+                       bld.begin(GL::TRIANGLE_STRIP);
+                       bld.vertex(edit_size*ts, -ts/2, ts/4);
+                       bld.vertex(edit_size*ts, -ts/2, -ts/4);
+                       bld.vertex(edit_size*ts, (edit_size+0.5)*ts, ts/4);
+                       bld.vertex(edit_size*ts, (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)
+       if(key==Input::KEY_PLUS)
+       {
+               ++edit_size;
                update_marker();
+       }
+       else if(key==Input::KEY_MINUS)
+       {
+               if(edit_size>0)
+               {
+                       --edit_size;
+                       update_marker();
+               }
+       }
+       else
+       {
+               bool shift_was_held = shift_held;
+               Tool::key_press(key);
+               if(shift_held!=shift_was_held)
+                       update_marker();
+       }
 }
 
 void TerrainTool::key_release(unsigned key)
@@ -102,9 +151,30 @@ 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, !shift_held);
-                       marker_position = terrain.get_node_position(highlight_node);
+                       if(edit_size==0)
+                               terrain.set_node_elevation(highlight_node, elev, !shift_held);
+                       else
+                       {
+                               unsigned bx = highlight_node.x-edit_size/2;
+                               unsigned by = highlight_node.y-edit_size/2;
+                               if(edit_size%2==0)
+                               {
+                                       bx += highlight_node.i%2;
+                                       by += highlight_node.i/2;
+                               }
+
+                               // TODO make it possible to adjust the area without flattening it
+                               for(unsigned y=0; y<edit_size; ++y)
+                                       for(unsigned x=0; x<edit_size; ++x)
+                                               for(unsigned i=0; i<4; ++i)
+                                               {
+                                                       Terrain::NodeCoordinates c(bx+x, by+y, i);
+                                                       if(c.x<terrain.get_width() && c.y<terrain.get_height())
+                                                               terrain.set_node_elevation(c, elev, !shift_held);
+                                               }
+                       }
 
+                       marker_position = terrain.get_node_position(highlight_node);
                        drag_start = pointer.y;
                }
        }
index e844ba28a64d57f1f05a0291e2c8bd2e61245cf8..79242355ddf5d42d371740331c6b0368997981ec 100644 (file)
@@ -12,6 +12,7 @@ private:
        R2C2::Terrain &terrain;
        Msp::GL::Mesh marker;
        R2C2::Terrain::NodeCoordinates highlight_node;
+       unsigned edit_size;
        R2C2::Vector marker_position;
        unsigned marker_orientation;
        bool dragging;