+#include <gmath/gmath.h>
+
#include "camera.h"
+#include "gfxapi.h"
#include "image.h"
+#include "mesh.h"
+#include "meshgen.h"
+#include "object.h"
#include "scene.h"
#include "terrain.h"
-Terrain::Terrain() {}
+static float calc_height(float u, float v, void *ptr);
+
+Terrain::Terrain()
+{
+ vis_scene = 0;
+}
Terrain::~Terrain()
{
}
+bool Terrain::init()
+{
+ vis_scene = new Scene;
+
+ return true;
+}
+
+void Terrain::destroy()
+{
+ delete vis_scene;
+}
+
+struct GenData {
+ const TerrainParams *tp;
+ float xoffs;
+ float yoffs;
+};
+
bool Terrain::generate(const TerrainParams ¶ms)
{
- // if(xsz <= 0 || ysz <=0) {
- // fprintf(stderr, "Invalid terrain size.\n");
- // return false;
- // }
+ tiles.clear();
+
+ float txsz = params.xsz / params.xtiles;
+ float tysz = params.ysz / params.ytiles;
+
+ for(int i=0; i<params.ytiles; i++) {
+ for(int j=0; j<params.xtiles; j++) {
+ TerrainTile tile;
+ tile.mesh = gfx_create_mesh();
- // if(xtiles <= 0 || ytiles <= 0) {
- // fprintf(stderr, "Invalid number of terrain tiles.\n");
- // return false;
- // }
+ GenData data;
+ data.tp = ¶ms;
+ data.xoffs = (float)j / (float)params.xtiles;
+ data.yoffs = (float)i / (float)params.ytiles;
- // if(tiles)
- // tiles.clear();
+ gen_heightfield(tile.mesh, txsz, tysz, params.max_height,
+ params.tile_usub, params.tile_vsub, calc_height,
+ (void*)&data);
- // int tsz = xtiles * ytiles;
- // tiles.resize(tsz);
+ float xoffs = j * txsz - params.xsz / 2.0 + txsz / 2.0;
+ float yoffs = i * tysz - params.ysz / 2.0 + tysz / 2.0;
- // for(int i=0; i<tsz; i++) {
+ Mat4 offmat;
+ offmat.translation(xoffs, 0, yoffs);
+ tile.mesh->transform(offmat);
- // }
+ tiles.push_back(tile);
+
+/*
+ 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;
+ o->transform = Mat4::identity;
+
+ vis_scene->objects.push_back(o);
+ }
+ }
return true;
}
Scene *Terrain::get_visible(const Camera *camera) const
{
- return 0;
+ return vis_scene;
}
+
+static float calc_height(float u, float v, void *ptr)
+{
+ if(!ptr) {
+ fprintf(stderr, "Terrain parameters not found.\n");
+ return 0;
+ }
+
+ GenData *data = (GenData*)ptr;
+ const TerrainParams *tp = data->tp;
+
+ u = u / tp->xtiles + data->xoffs;
+ v = v / tp->ytiles + data->yoffs;
+
+ float sn = gph::fbm(u * tp->noise_freq, v * tp->noise_freq, tp->num_octaves);
+
+ if(tp->coarse_heightmap) {
+ Vec4 texel = tp->coarse_heightmap->lookup_nearest(u, v);
+ sn *= texel.x;
+ }
+ return sn;
+}
\ No newline at end of file