no clue :) just to push it
[demo] / src / terrain.cc
index 92dce56..89caa6e 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "camera.h"
 #include "gfxapi.h"
-#include "image.h"
 #include "mesh.h"
 #include "meshgen.h"
 #include "object.h"
@@ -33,6 +32,7 @@ void Terrain::destroy()
 }
 
 struct GenData {
+       const Terrain *terrain;
        const TerrainParams *tp;
        float xoffs;
        float yoffs;
@@ -41,6 +41,7 @@ struct GenData {
 bool Terrain::generate(const TerrainParams &params)
 {
        tiles.clear();
+       this->params = params;
 
        float txsz = params.xsz / params.xtiles;
        float tysz = params.ysz / params.ytiles;
@@ -51,13 +52,14 @@ bool Terrain::generate(const TerrainParams &params)
                        tile.mesh = gfx_create_mesh();
 
                        GenData data;
+                       data.terrain = this;
                        data.tp = &params;
                        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*)&data);
+                                       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;
@@ -68,10 +70,10 @@ bool Terrain::generate(const TerrainParams &params)
 
                        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;
@@ -88,23 +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;
+
+       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;
+}
 
-       GenData *data = (GenData*)ptr;
+static float calc_height(float u, float v, void *ptr)
+{
+       GenData *data = (GenData *)ptr;
        const TerrainParams *tp = data->tp;
 
-       // float ufreq = tp->noise_freq / tp->xtiles;
-       // float vfreq = tp->noise_freq / tp->ytiles;
-
        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);
-       /* todo use the image later */
-       return sn;
+       return data->terrain->get_height(u, v);
 }
\ No newline at end of file