summaryrefslogtreecommitdiff
path: root/terrain_loader.cpp
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2011-05-14 23:22:05 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2011-05-14 23:22:05 +0200
commite7e6a79f8bf2855b5d1d432613151e48d2d685da (patch)
tree147fbe4a4af633427958d1bf1dcbaaaf0c0a1e00 /terrain_loader.cpp
parent07ec7829e75a71fa7b70b513f0a2c7daeaea11d5 (diff)
Implemented terrain chunk caching.
Diffstat (limited to 'terrain_loader.cpp')
-rw-r--r--terrain_loader.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/terrain_loader.cpp b/terrain_loader.cpp
new file mode 100644
index 0000000..d908aca
--- /dev/null
+++ b/terrain_loader.cpp
@@ -0,0 +1,90 @@
+#include "terrain_loader.h"
+
+#include <noise/noise.h>
+#include "noiseutils/noiseutils.h"
+#include <boost/format.hpp>
+#include <boost/filesystem/fstream.hpp>
+
+using namespace noise;
+
+TerrainLoader::TerrainLoader(int seed, fs::path root) {
+ this->seed = seed;
+ this->root = root;
+}
+
+TerrainLoader::~TerrainLoader() {
+}
+
+float *TerrainLoader::generate_heights(int x, int y, int width, int height) {
+ module::Perlin mod;
+ mod.SetSeed(seed);
+
+ 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));
+ }
+ }
+
+ save_chunk(heights, x, y, width, height);
+
+ return heights;
+}
+
+float *TerrainLoader::get_chunk(int x, int y, int width, int height) {
+ float *h;
+ if(has_chunk(x, y))
+ h = load_chunk(x, y, width, height);
+ else
+ h = generate_heights(x, y, width, height);
+ return h;
+}
+
+bool TerrainLoader::has_chunk(int x, int y) {
+ return fs::exists(root / (boost::format("%d.%d.chunk") % x % y).str());
+}
+
+void TerrainLoader::save_chunk(float *chunk, int x, int y, int width, int height) {
+ fs::path p = root / (boost::format("%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+1, likewise for height
+float *TerrainLoader::load_chunk(int x, int y, int width, int height) {
+ fs::path p = root / (boost::format("%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;
+}