]> git.tdb.fi Git - r2c2.git/blob - source/designer/terraintool.cpp
Add editable terrain objects
[r2c2.git] / source / designer / terraintool.cpp
1 #include <cmath>
2 #include <msp/gl/meshbuilder.h>
3 #include <msp/input/keys.h>
4 #include "designer.h"
5 #include "terraintool.h"
6
7 using namespace std;
8 using namespace Msp;
9 using namespace R2C2;
10
11 TerrainTool::TerrainTool(Designer &d, Input::Keyboard &k, Input::Mouse &m, Terrain &t):
12         Tool(d, k, m),
13         terrain(t),
14         marker((GL::VERTEX3, GL::COLOR4_UBYTE)),
15         dragging(false),
16         drag_start(0)
17 {
18         designer.get_layout_3d().get_scene().add(*this);
19
20         float ts = terrain.get_type().get_tile_size();
21         GL::MeshBuilder bld(marker);
22         bld.begin(GL::TRIANGLE_STRIP);
23         bld.vertex(-ts/2, 0, -ts/4);
24         bld.vertex(ts/2, 0, -ts/4);
25         bld.vertex(-ts/2, 0, ts/4);
26         bld.vertex(ts/2, 0, ts/4);
27         bld.end();
28         bld.begin(GL::TRIANGLE_STRIP);
29         bld.vertex(0, -ts/2, -ts/4);
30         bld.vertex(0, ts/2, -ts/4);
31         bld.vertex(0, -ts/2, ts/4);
32         bld.vertex(0, ts/2, ts/4);
33         bld.end();
34 }
35
36 TerrainTool::~TerrainTool()
37 {
38         designer.get_layout_3d().get_scene().remove(*this);
39 }
40
41 void TerrainTool::button_press(unsigned btn)
42 {
43         if(btn==1)
44         {
45                 dragging = true;
46                 drag_start = pointer.y;
47         }
48 }
49
50 void TerrainTool::button_release(unsigned btn)
51 {
52         if(btn==1)
53                 dragging = false;
54 }
55
56 void TerrainTool::pointer_motion()
57 {
58         if(dragging)
59         {
60                 float d = (pointer.y-drag_start)*20;
61
62                 if(abs(d)>1)
63                 {
64                         float elev = terrain.get_node_elevation(highlight_node);
65                         float eg = terrain.get_type().get_elevation_granularity();
66                         elev += eg*d;
67                         terrain.set_node_elevation(highlight_node, elev, true);
68                         marker_position = terrain.get_node_position(highlight_node);
69
70                         drag_start = pointer.y;
71                 }
72         }
73         else
74         {
75                 Ray ray = designer.get_view().create_ray(pointer.x, pointer.y);
76                 highlight_node = terrain.get_closest_node(ray);
77                 marker_position = terrain.get_node_position(highlight_node);
78         }
79 }
80
81 void TerrainTool::render(GL::Renderer &renderer, const GL::Tag &tag) const
82 {
83         if(tag.id)
84                 return;
85
86         GL::Renderer::Push push(renderer);
87
88         renderer.matrix_stack() *= GL::Matrix::translation(marker_position);
89         marker.draw(renderer);
90 }