X-Git-Url: http://git.mutantstargoat.com?a=blobdiff_plain;f=src%2Fterrain.cc;h=89caa6ea92a0c0cb9fdebcda2acc51c505427127;hb=1e8963fc3f8191e328bbecd04cfbcba31d7d0bdf;hp=bdd787fdd4e3b44eb2181997f79f54488e36d75a;hpb=243eb502c5dc70e586a9e81815234069bf623480;p=demo diff --git a/src/terrain.cc b/src/terrain.cc index bdd787f..89caa6e 100644 --- a/src/terrain.cc +++ b/src/terrain.cc @@ -2,7 +2,6 @@ #include "camera.h" #include "gfxapi.h" -#include "image.h" #include "mesh.h" #include "meshgen.h" #include "object.h" @@ -32,9 +31,17 @@ void Terrain::destroy() delete vis_scene; } +struct GenData { + const Terrain *terrain; + const TerrainParams *tp; + float xoffs; + float yoffs; +}; + bool Terrain::generate(const TerrainParams ¶ms) { tiles.clear(); + this->params = params; float txsz = params.xsz / params.xtiles; float tysz = params.ysz / params.ytiles; @@ -44,17 +51,29 @@ bool Terrain::generate(const TerrainParams ¶ms) TerrainTile tile; tile.mesh = gfx_create_mesh(); + GenData data; + data.terrain = this; + data.tp = ¶ms; + data.xoffs = (float)j / (float)params.xtiles; + data.yoffs = (float)i / (float)params.ytiles; + gen_heightfield(tile.mesh, txsz, tysz, params.max_height, - params.tile_usub, params.tile_vsub, calc_height, - (void*)¶ms); + params.tile_usub, params.tile_vsub, calc_height, + (void *)&data); + + float xoffs = j * txsz - params.xsz / 2.0 + txsz / 2.0; + float yoffs = i * tysz - params.ysz / 2.0 + tysz / 2.0; + + Mat4 offmat; + offmat.translation(xoffs, 0, yoffs); + tile.mesh->transform(offmat); - tile.mesh->update_vertex_data(); tiles.push_back(tile); -/* - the terrain scene stores objects only - no need to fill the mat, mesh std::vectors -*/ + /* + the terrain scene stores objects only + no need to fill the mat, mesh std::vectors + */ Object *o = new Object; o->mesh = tile.mesh; o->material = &material; @@ -71,15 +90,44 @@ Scene *Terrain::get_visible(const Camera *camera) const return vis_scene; } -static float calc_height(float u, float v, void *ptr) +float Terrain::get_height(const Vec3 &pos) const { - if(!ptr) { - fprintf(stderr, "Terrain parameters not found.\n"); + float x = pos.x; + float y = pos.z; + + float half_width = params.xsz / 2.0; + float half_height = params.ysz / 2.0; + + if(x < -half_width || x > half_width) + return 0; + if(y < -half_height || y > half_height) return 0; - } - TerrainParams *tp = (TerrainParams*)ptr; - float sn = gph::fbm(u * tp->noise_freq, v * tp->noise_freq, tp->num_octaves); - /* todo use the image later */ + float u = (x + half_width) / params.xsz; + float v = (y + half_height) / params.ysz; + + return get_height(u, v) * params.max_height; +} + +float Terrain::get_height(float u, float v) const +{ + float sn = gph::fbm(u * params.noise_freq, v * params.noise_freq, params.num_octaves); + sn = sn * 0.5 + 0.5; + + if(params.coarse_heightmap.pixels) { + Vec4 texel = params.coarse_heightmap.lookup_linear(u, v, 1.0 / params.tile_usub, 1.0 / params.tile_vsub); + sn *= texel.x; + } return sn; +} + +static float calc_height(float u, float v, void *ptr) +{ + GenData *data = (GenData *)ptr; + const TerrainParams *tp = data->tp; + + u = u / tp->xtiles + data->xoffs; + v = v / tp->ytiles + data->yoffs; + + return data->terrain->get_height(u, v); } \ No newline at end of file