diff options
author | Jon Bergli Heier <snakebite@jvnv.net> | 2011-07-03 15:31:06 +0200 |
---|---|---|
committer | Jon Bergli Heier <snakebite@jvnv.net> | 2011-07-03 15:31:06 +0200 |
commit | c24d988742997af9e4689e0836a6073cdd302c1f (patch) | |
tree | 1327de6e00fb2dcc4156a85896393b1e7c668714 | |
parent | 7add4dd07e17c5a6ba0a2a1d9700d72055b812ae (diff) |
m--------- | common | 0 | ||||
-rw-r--r-- | server.cpp | 7 | ||||
-rw-r--r-- | terrain_generator.cpp | 54 | ||||
-rw-r--r-- | terrain_generator.h | 7 |
4 files changed, 68 insertions, 0 deletions
diff --git a/common b/common -Subproject ff7f9de199213ea6d4832c0b91f2a96f5edc6bb +Subproject e95b3cb3e1a054a9d6bd766d4904e569ac2b2a6 @@ -106,6 +106,7 @@ void Server::handle_pos(Connection::p c) { m.recv(c->socket); c->pos = m.get_pos(); + TerrainGenerator::p tg = boost::static_pointer_cast<TerrainGenerator>(cache->tl); std::set<std::pair<int64_t, int64_t> > chunks = c->check_chunks(); for(std::set<std::pair<int64_t, int64_t> >::iterator it = chunks.begin(); it != chunks.end(); it++) { // TODO: fix sizes @@ -113,6 +114,12 @@ void Server::handle_pos(Connection::p c) { message::Chunk chunk(it->first, it->second); chunk.set_data(obj->heights); chunk.send(c->socket); + + std::list<Vector3> trees = tg->get_objects(it->first, it->second, 35, 35); + for(std::list<Vector3>::iterator it = trees.begin(); it != trees.end(); it++) { + message::Object tree(0, *it); + tree.send(c->socket); + } } for(std::list<Connection::p>::iterator it = clients.begin(); it != clients.end(); it++) { if(*it == c) diff --git a/terrain_generator.cpp b/terrain_generator.cpp index a57f5d1..fe9ddd0 100644 --- a/terrain_generator.cpp +++ b/terrain_generator.cpp @@ -2,6 +2,8 @@ #include <noise/noise.h> #include "noiseutils/noiseutils.h" +#include <boost/random.hpp> +#include <boost/random/variate_generator.hpp> using namespace noise; @@ -46,3 +48,55 @@ float *TerrainGenerator::get_chunk(int64_t x, int64_t y, unsigned int width, uns h = generate_heights(x, y, width, height); return h; } + +// TODO: merge this into terrain height generation above somehow +std::list<Vector3> TerrainGenerator::generate_objects(int64_t x, int64_t y, unsigned int width, unsigned int height) { + std::list<Vector3> trees; + + const double scale_factor = 0.004; + // "base" needs to match the terrain heightmap noise + module::Perlin base; + base.SetSeed(seed); + + module::Const low; + low.SetConstValue(0); + + module::Select final; + final.SetSourceModule(0, low); + final.SetSourceModule(1, base); + final.SetControlModule(base); + const float lower = -.24; + const float upper = .19; + final.SetBounds(lower, upper); + + utils::NoiseMap heightmap; + utils::NoiseMapBuilderPlane heightmap_builder; + + heightmap_builder.SetSourceModule(final); + heightmap_builder.SetDestNoiseMap(heightmap); + + heightmap_builder.SetDestSize(width, height); + heightmap_builder.SetBounds((double)x * scale_factor, (double)(x+33) * scale_factor, + (double)y * scale_factor, (double)(y+33) * scale_factor); + heightmap_builder.Build(); + + boost::mt19937 rng(seed); + boost::normal_distribution<float> nd(-2, .7); + boost::variate_generator<boost::mt19937&, boost::normal_distribution<float> > r(rng, nd); + + for(unsigned int i = 0; i < 32; i++) { + for(unsigned int j = 0; j < 32; j++) { + if(heightmap.GetValue(i, j) > 0 && r() > 0) + trees.push_back(Vector3(x + i, 0, y + j)); + } + } + + return trees; +} + +std::list<Vector3> TerrainGenerator::get_objects(int64_t x, int64_t y, unsigned int width, unsigned int height) { + if(has_objects(x, y)) + return load_objects(x, y); + else + return generate_objects(x, y, width, height); +} diff --git a/terrain_generator.h b/terrain_generator.h index e301e7b..717419d 100644 --- a/terrain_generator.h +++ b/terrain_generator.h @@ -2,17 +2,24 @@ #define TERRAIN_GENERATOR_H #include "terrain_loader.h" +#include "vector.h" + +#include <boost/shared_ptr.hpp> class TerrainGenerator : public TerrainLoader { private: int seed; public: + typedef boost::shared_ptr<TerrainGenerator> p; + TerrainGenerator(int seed, fs::path root); virtual ~TerrainGenerator() {}; float *generate_heights(int64_t x, int64_t y, unsigned int width, unsigned int height); virtual float *get_chunk(int64_t x, int64_t y, unsigned int width, unsigned int height); + std::list<Vector3> generate_objects(int64_t x, int64_t y, unsigned int width, unsigned int height); + virtual std::list<Vector3> get_objects(int64_t x, int64_t y, unsigned int width, unsigned int height); }; #endif |