bloboland
view src/level.cc @ 5:2f4406cc341e
meh
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 19 Dec 2012 02:37:20 +0200 |
parents | 9021a906c5d3 |
children |
line source
1 #include "level.h"
3 #include "opt.h"
5 Level::Level()
6 {
7 terrain = 0;
8 world_size = Vector3(1, 1, 1);
9 }
11 Level::~Level()
12 {
13 delete terrain;
14 }
16 static float terrain_func(float x, float y, float z)
17 {
18 float nx = (x * 2.0 - 1.0) * 0.9;
19 float ny = (y * 2.0 - 1.0) * 0.9;
20 float valley = nx * nx + ny * ny;
22 float s = opt.gen_noise_scale;
23 float noise = 0.2 * fbm2(x * s, y * s, 4) * (valley + 0.25);
24 float grad = 0.75 - z + noise + valley * 0.4;
26 return grad;
27 }
29 void Level::generate()
30 {
31 delete terrain;
33 int xsz = opt.world_size[0];
34 int ysz = opt.world_size[1];
35 int zsz = opt.world_size[2];
37 terrain = new Volume(xsz, ysz, zsz);
39 for(int i=0; i<xsz; i++) {
40 for(int j=0; j<ysz; j++) {
41 float x = (float)i / (float)xsz;
42 float y = (float)j / (float)ysz;
43 //float peak = 0.4 * noise2(x, y) * 0.5 + 0.5;
45 for(int k=0; k<zsz; k++) {
46 Vector4 voxel(1, 1, 1, 1);
47 float z = (float)k / (float)zsz;
49 float alpha = terrain_func(x, y, z);
51 if(z < 0.1) {
52 // lava
53 static const Vector4 col1(0.96, 0.3, 0.1, 1);
54 static const Vector4 col2(0.96, 0.75, 0.1, 1);
55 float t = noise3(x, y, z) * 0.5 + 0.5;
56 voxel = lerp(col1, col2, t);
57 } else if(z < 0.8) {
58 if(alpha < 0.56) {
59 // grass
60 voxel = Vector4(0.49, 0.72, 0.48);
61 } else {
62 // mud
63 voxel = Vector4(0.57, 0.43, 0.29, 1);
64 }
65 } // else snow (default)
67 voxel.w = alpha;
68 terrain->set_voxel(i, j, k, voxel);
69 }
70 }
71 }
73 // generate some blobs
74 for(int i=0; i<opt.gen_num_blobs; i++) {
75 Blob b;
76 b.pos = Vector3(frand(1.0) - 0.5, 2.0, frand(1.0) - 0.5) * 2.0;
77 printf("blob[%d]: %f %f %f\n", i, b.pos.x, b.pos.y, b.pos.z);
78 b.velocity = Vector3(0, 0, 0);
79 blobs.push_back(b);
80 }
81 }
83 bool Level::load(const char *fname)
84 {
85 return false;
86 }
88 bool Level::save(const char *fname) const
89 {
90 return false;
91 }
93 #define CLAMP(x, a, b) ((x) < (a) ? (a) : ((x) > (b) ? (b) : (x)))
95 const Vector4 &Level::get_voxel(const Vector3 &pos) const
96 {
97 Vector3 p = pos / world_size + Vector3(0.5, 0.5, 0.5);
99 int xsz = terrain->get_size(0);
100 int ysz = terrain->get_size(1);
101 int zsz = terrain->get_size(2);
103 int i = (int)(p.x * xsz);
104 int j = (int)(p.y * ysz);
105 int k = (int)(p.z * zsz);
107 return terrain->get_voxel(CLAMP(i, 0, xsz - 1), CLAMP(j, 0, ysz - 1), CLAMP(k, 0, zsz - 1));
108 }
110 Vector3 Level::calc_normal(const Vector3 &pos) const
111 {
112 int xsz = terrain->get_size(0);
113 int ysz = terrain->get_size(1);
114 int zsz = terrain->get_size(2);
116 float dx = world_size.x / (float)xsz;
117 float dy = world_size.y / (float)ysz;
118 float dz = world_size.z / (float)zsz;
120 float dfdx = get_voxel(pos + Vector3(dx, 0, 0)).w - get_voxel(pos - Vector3(dx, 0, 0)).w;
121 float dfdy = get_voxel(pos + Vector3(0, dy, 0)).w - get_voxel(pos - Vector3(0, dy, 0)).w;
122 float dfdz = get_voxel(pos + Vector3(0, 0, dz)).w - get_voxel(pos - Vector3(0, 0, dz)).w;
124 return Vector3(dfdx, dfdy, dfdz);
125 }
127 bool Level::collision(const Vector3 &pos0, const Vector3 &pos1, Vector3 *outpos, Vector3 *outnorm) const
128 {
129 Vector4 vox0 = get_voxel(pos0);
130 Vector4 vox1 = get_voxel(pos1);
132 if(vox0.w < 0.5 && vox1.w >= 0.5) {
133 *outpos = lerp(pos0, pos1, 0.5); // TODO
134 *outnorm = calc_normal(*outpos);
135 return true;
136 }
137 return false;
138 }