X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Fterrain.cpp;h=002a536581a6201698baa2e45ab2870b8cd42cb3;hb=9f0d428e974defa64cdf8e7b7072967327250958;hp=e84c7cdc1c360102a89fb60d92af868363e27d2f;hpb=2220ba2f11705ea9a4e480603d43ab7ed4cf5a89;p=r2c2.git diff --git a/source/libr2c2/terrain.cpp b/source/libr2c2/terrain.cpp index e84c7cd..002a536 100644 --- a/source/libr2c2/terrain.cpp +++ b/source/libr2c2/terrain.cpp @@ -1,3 +1,4 @@ +#include #include #include #include "layout.h" @@ -37,6 +38,8 @@ Terrain *Terrain::clone(Layout *to_layout) const void Terrain::set_position(const Vector &p) { position = p; + float eg = type.get_elevation_granularity(); + position.z = int(position.z/eg+0.5)*eg; signal_moved.emit(); } @@ -62,7 +65,7 @@ void Terrain::set_size(unsigned w, unsigned h) delete shape; float ts = type.get_tile_size(); - Vector dim(width*ts, height*ts, ts); + Vector dim(width*ts, height*ts, ts/10.0f); shape = new Geometry::TransformedShape( Geometry::Box(dim), Transform::translation(dim/2.0f)); @@ -83,7 +86,7 @@ void Terrain::set_node_elevation(const NodeCoordinates &c, float elev, bool join throw out_of_range("Terrain::set_node_elevation"); float eg = type.get_elevation_granularity(); - elev = int(elev/eg+0.5)*eg; + elev = floor(elev/eg+0.5)*eg; if(joined) { @@ -97,7 +100,7 @@ void Terrain::set_node_elevation(const NodeCoordinates &c, float elev, bool join Tile &tile = tiles[x+y*width]; if(tile.nodes[i].elevation==ref) { - tile.nodes[i].elevation = elev; + tile.set_node_elevation(i, elev); signal_tile_changed.emit(x, y); } } @@ -105,7 +108,7 @@ void Terrain::set_node_elevation(const NodeCoordinates &c, float elev, bool join } else { - tiles[c.x+c.y*width].nodes[c.i].elevation = elev; + tiles[c.x+c.y*width].set_node_elevation(c.i, elev); signal_tile_changed.emit(c.x, c.y); } } @@ -132,6 +135,11 @@ Vector Terrain::get_node_position(const NodeCoordinates &c) const Terrain::NodeCoordinates Terrain::get_closest_node(const Ray &ray) const { + Transform reverse_trans = Transform::rotation(rotation, Vector(0, 0, -1))* + Transform::translation(-position); + Ray local_ray = reverse_trans.transform(ray); + + float ts = type.get_tile_size(); NodeCoordinates coords; float closest_dist = -1; for(unsigned y=0; y &st) const { + st.push_back((DataFile::Statement("position"), position.x, position.y, position.z)); + st.push_back((DataFile::Statement("rotation"), rotation.radians())); st.push_back((DataFile::Statement("size"), width, height)); for(vector::const_iterator i=tiles.begin(); i!=tiles.end(); ++i) { @@ -182,28 +191,51 @@ Terrain::Tile::Tile(): secondary_axis(false) { } +void Terrain::Tile::set_node_elevation(unsigned i, float e) +{ + nodes[i].elevation = e; + update_axis(); +} + +void Terrain::Tile::update_axis() +{ + secondary_axis = (abs(nodes[1].elevation-nodes[2].elevation) < abs(nodes[0].elevation-nodes[3].elevation)); +} + void Terrain::Tile::save(list &st) const { - bool flat = true; - for(unsigned i=1; (flat && i<4); ++i) - flat = (nodes[i].elevation==nodes[0].elevation && nodes[i].ground==nodes[0].ground && nodes[i].wall==nodes[0].wall); - if(flat) - { - st.push_back((DataFile::Statement("elevation"), nodes[0].elevation)); - st.push_back((DataFile::Statement("ground"), nodes[0].ground)); - } - else + float elevation_mode = find_mode(&Node::elevation); + unsigned ground_mode = find_mode(&Node::ground); + if(elevation_mode) + st.push_back((DataFile::Statement("elevation"), elevation_mode)); + if(ground_mode) + st.push_back((DataFile::Statement("ground"), ground_mode)); + + for(unsigned i=0; i<4; ++i) { - for(unsigned i=0; i<4; ++i) - { - DataFile::Statement ss("node"); - ss.append(i); - nodes[i].save(ss.sub); - st.push_back(ss); - } + if(nodes[i].elevation==elevation_mode && nodes[i].ground==ground_mode) + continue; + + DataFile::Statement ss("node"); + ss.append(i); + if(nodes[i].elevation!=elevation_mode) + ss.sub.push_back((DataFile::Statement("elevation"), nodes[i].elevation)); + if(nodes[i].ground!=ground_mode) + ss.sub.push_back((DataFile::Statement("ground"), nodes[i].ground)); + st.push_back(ss); } } +template +T Terrain::Tile::find_mode(T Node::*member) const +{ + for(unsigned i=0; i<3; ++i) + for(unsigned j=i+1; j<4; ++j) + if(nodes[i].*member==nodes[j].*member) + return nodes[i].*member; + return T(); +} + Terrain::NodeCoordinates::NodeCoordinates(): x(0), @@ -252,6 +284,7 @@ void Terrain::Loader::tile() Tile &t = obj.tiles[next_tile]; Tile::Loader ldr(obj, t); load_sub_with(ldr); + t.update_axis(); unsigned x = next_tile%obj.width; unsigned y = next_tile/obj.width; ++next_tile;