ff54f4603b6336af5b611f48a27f4443d7346858
[demo] / src / terrain.cc
1 #include <gmath/gmath.h>
2
3 #include "camera.h"
4 #include "gfxapi.h"
5 #include "image.h"
6 #include "mesh.h"
7 #include "meshgen.h"
8 #include "object.h"
9 #include "scene.h"
10 #include "terrain.h"
11
12 static float calc_height(float u, float v, void *ptr);
13
14 Terrain::Terrain()
15 {
16         vis_scene = 0;
17 }
18
19 Terrain::~Terrain()
20 {
21 }
22
23 bool Terrain::init()
24 {
25         vis_scene = new Scene;
26
27         return true;
28 }
29
30 void Terrain::destroy()
31 {
32         delete vis_scene;
33 }
34
35 struct GenData {
36         const TerrainParams *tp;
37         float xoffs;
38         float yoffs;
39 };
40
41 bool Terrain::generate(const TerrainParams &params)
42 {
43         tiles.clear();
44
45         float txsz = params.xsz / params.xtiles;
46         float tysz = params.ysz / params.ytiles;
47
48         for(int i=0; i<params.ytiles; i++) {
49                 for(int j=0; j<params.xtiles; j++) {
50                         TerrainTile tile;
51                         tile.mesh = gfx_create_mesh();
52
53                         GenData data;
54                         data.tp = &params;
55                         data.xoffs = (float)j / (float)params.xtiles;
56                         data.yoffs = (float)i / (float)params.ytiles;
57
58                         gen_heightfield(tile.mesh, txsz, tysz, params.max_height,
59                                         params.tile_usub, params.tile_vsub, calc_height,
60                                         (void*)&data);
61
62                         float xoffs = j * txsz - params.xsz / 2.0 + txsz / 2.0;
63                         float yoffs = i * tysz - params.ysz / 2.0 + tysz / 2.0;
64
65                         Mat4 offmat;
66                         offmat.translation(xoffs, 0, yoffs);
67                         tile.mesh->transform(offmat);
68
69                         tiles.push_back(tile);
70
71 /*
72         the terrain scene stores objects only
73         no need to fill the mat, mesh std::vectors
74 */
75                         Object *o = new Object;
76                         o->mesh = tile.mesh;
77                         o->material = &material;
78                         o->transform = Mat4::identity;
79
80                         vis_scene->objects.push_back(o);
81                 }
82         }
83         return true;
84 }
85
86 Scene *Terrain::get_visible(const Camera *camera) const
87 {
88         return vis_scene;
89 }
90
91 static float calc_height(float u, float v, void *ptr)
92 {
93         if(!ptr) {
94                 fprintf(stderr, "Terrain parameters not found.\n");
95                 return 0;
96         }
97
98         GenData *data = (GenData*)ptr;
99         const TerrainParams *tp = data->tp;
100
101         u = u / tp->xtiles + data->xoffs;
102         v = v / tp->ytiles + data->yoffs;
103
104         float sn = gph::fbm(u * tp->noise_freq, v * tp->noise_freq, tp->num_octaves);
105
106         if(tp->coarse_heightmap) {
107                 Vec4 texel = tp->coarse_heightmap->lookup_nearest(u, v);
108                 sn *= texel.x;
109         }
110         return sn;
111 }