#include "camera.h"
#include "gfxapi.h"
-#include "image.h"
#include "mesh.h"
#include "meshgen.h"
#include "object.h"
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;
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;
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