diff options
Diffstat (limited to 'terrain.cpp')
-rw-r--r-- | terrain.cpp | 122 |
1 files changed, 15 insertions, 107 deletions
diff --git a/terrain.cpp b/terrain.cpp index 1fd75db..f3f573d 100644 --- a/terrain.cpp +++ b/terrain.cpp @@ -3,20 +3,10 @@ #include "gl.h" -#include <noise/noise.h> -#include "noiseutils/noiseutils.h" -#include <boost/format.hpp> -#include <boost/filesystem.hpp> -#include <boost/filesystem/fstream.hpp> - #include <cmath> #include <queue> #include <set> -using namespace noise; - -namespace fs = boost::filesystem; - using std::min; using std::max; @@ -129,7 +119,7 @@ float Terrain::Node::get_height(float px, float py) { /* Chunk */ -Terrain::Chunk::Chunk(Terrain *terrain, float x, float y, float width, float height) { +Terrain::Chunk::Chunk(Terrain *terrain, float x, float y, float width, float height) : cache_obj(terrain->tc->get_chunk(x, y, width+1, height+1)) { this->terrain = terrain; this->x = x; this->y = y; @@ -139,7 +129,7 @@ Terrain::Chunk::Chunk(Terrain *terrain, float x, float y, float width, float hei this->h_height = height+1; this->vbo_object = this->node_count = this->vertices = 0; this->nodes = NULL; - heights = terrain->get_chunk(x, y, h_width, h_height); + heights = cache_obj->heights; normals = new Vector3[(int)((h_width)*(h_height))]; calc_normals(); @@ -158,7 +148,6 @@ Terrain::Chunk::~Chunk() { for(unsigned int i = 0; i < node_count; i++) delete nodes[i]; delete[] nodes; - delete[] heights; delete[] normals; } @@ -281,11 +270,16 @@ Terrain::Node* Terrain::Chunk::find(float x, float y) { void Terrain::Chunk::calc_normals() { float *right, *left, *up, *down; - right = left = up = down = NULL; - right = terrain->get_chunk(this->x - chunk_size, this->y, h_width, h_height); - left = terrain->get_chunk(this->x + chunk_size, this->y, h_width, h_height); - up = terrain->get_chunk(this->x, this->y + chunk_size, h_width, h_height); - down = terrain->get_chunk(this->x, this->y - chunk_size, h_width, h_height); + + TerrainCacheObject::p right_ob = terrain->tc->get_chunk(this->x - chunk_size, this->y, h_width, h_height), + left_ob = terrain->tc->get_chunk(this->x + chunk_size, this->y, h_width, h_height), + up_ob = terrain->tc->get_chunk(this->x, this->y + chunk_size, h_width, h_height), + down_ob = terrain->tc->get_chunk(this->x, this->y - chunk_size, h_width, h_height); + + right = right_ob->heights; + left = left_ob->heights; + up = up_ob->heights; + down = down_ob->heights; for(int x = 0; x < h_width; x++) { for(int y = 0; y < h_height; y++) { @@ -343,98 +337,17 @@ void Terrain::Chunk::calc_normals() { normals[x*h_height + y] = N; } } - - if(right) - delete[] right; - if(left) - delete[] left; - if(up) - delete[] up; - if(down) - delete[] down; } Terrain::Terrain() { + tc = new TerrainCache(0, "map", 120); } Terrain::~Terrain() { for(std::list<Chunk*>::iterator it = chunks.begin(); it != chunks.end(); it++) { delete *it; } -} - -float *Terrain::generate_heights(int x, int y, int width, int height) { - module::Perlin mod; - mod.SetSeed(0); - - utils::NoiseMap heightmap; - utils::NoiseMapBuilderPlane heightmap_builder; - - heightmap_builder.SetSourceModule(mod); - heightmap_builder.SetDestNoiseMap(heightmap); - - heightmap_builder.SetDestSize(width, height); - heightmap_builder.SetBounds((double)x / 100, (double)(x+width) / 100, (double)y / 100, (double)(y+height) / 100); - heightmap_builder.Build(); - - float *heights = new float[width*height]; - for(int i = 0; i < width; i++) { - for(int j = 0; j < height; j++) { - heights[i*height + j] = 10*(1+heightmap.GetValue(i, j)); - } - } - - chunk_indices.insert(std::pair<int, int>(x, y)); - save_chunk(heights, x, y, width, height); - - return heights; -} - -float *Terrain::get_chunk(int x, int y, int width, int height) { - if(has_chunk(x, y)) - return load_chunk(x, y, width, height); - else - return generate_heights(x, y, width, height); -} - -bool Terrain::has_chunk(int x, int y) { - return fs::exists((boost::format("map/%d.%d.chunk") % x % y).str()); - //return chunk_indices.find(std::pair<int, int>(x, y)) != chunk_indices.end(); -} - -void Terrain::save_chunk(float *chunk, int x, int y, int width, int height) { - fs::path p = (boost::format("map/%d.%d.chunk") % x % y).str(); - fs::ofstream os(p); - - os << width << std::endl; - os << height << std::endl; - - for(int x = 0; x < width; x++) - for(int y = 0; y < height; y++) - os << chunk[x*height + y] << std::endl; - os.close(); -} - -// NOTE: assumes width <= chunk_size+, likewise for height -float *Terrain::load_chunk(int x, int y, int width, int height) { - fs::path p = (boost::format("map/%d.%d.chunk") % x % y).str(); - fs::ifstream is(p); - - int w, h; - is >> w; - is >> h; - - float *chunk = new float[width*height]; - for(int x = 0; x < w; x++) - for(int y = 0; y < h; y++) { - float v; - is >> v; - if(x < width && y < height) - chunk[x*height + y] = v; - } - is.close(); - - return chunk; + delete tc; } void Terrain::raise(float x, float z, float radius, float focus, float strength, bool up) { @@ -498,12 +411,6 @@ void Terrain::raise(float x, float z, float radius, float focus, float strength, } } - // save chunks - for(std::set<Chunk*>::iterator it = changed_chunks.begin(); it != changed_chunks.end(); it++) { - Chunk *chunk = *it; - save_chunk(chunk->heights, chunk->x, chunk->y, chunk->h_width, chunk->h_height); - } - /* recalculate normals */ for(std::set<Chunk*>::iterator it = changed_chunks.begin(); it != changed_chunks.end(); it++) { (*it)->calc_normals(); @@ -540,6 +447,7 @@ void Terrain::update(float x, float z) { chunk_indices.erase(ind_it); } if((*it)->distance(x, z) > chunk_dist_threshold) { + delete *it; it = chunks.erase(it); } } |