1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _TERRAINNOISE_H
5 #define _TERRAINNOISE_H
6 
7 #include "perlin.h"
8 #include "../libs.h"
9 
10 namespace TerrainNoise {
11 
12 	// octavenoise functions return range [0,1] if persistence = 0.5
octavenoise(const fracdef_t & def,const double persistence,const vector3d & p)13 	inline double octavenoise(const fracdef_t &def, const double persistence, const vector3d &p)
14 	{
15 		//assert(persistence <= (1.0 / def.lacunarity));
16 		double n = 0;
17 		double amplitude = persistence;
18 		double frequency = def.frequency;
19 		for (int i = 0; i < def.octaves; i++) {
20 			n += amplitude * noise(frequency * p);
21 			amplitude *= persistence;
22 			frequency *= def.lacunarity;
23 		}
24 		return (n + 1.0) * 0.5;
25 	}
26 
river_octavenoise(const fracdef_t & def,const double persistence,const vector3d & p)27 	inline double river_octavenoise(const fracdef_t &def, const double persistence, const vector3d &p)
28 	{
29 		//assert(persistence <= (1.0 / def.lacunarity));
30 		double n = 0;
31 		double amplitude = persistence;
32 		double frequency = def.frequency;
33 		for (int i = 0; i < def.octaves; i++) {
34 			n += amplitude * fabs(noise(frequency * p));
35 			amplitude *= persistence;
36 			frequency *= def.lacunarity;
37 		}
38 		return fabs(n);
39 	}
40 
ridged_octavenoise(const fracdef_t & def,const double persistence,const vector3d & p)41 	inline double ridged_octavenoise(const fracdef_t &def, const double persistence, const vector3d &p)
42 	{
43 		//assert(persistence <= (1.0 / def.lacunarity));
44 		double n = 0;
45 		double amplitude = persistence;
46 		double frequency = def.frequency;
47 		for (int i = 0; i < def.octaves; i++) {
48 			n += amplitude * noise(frequency * p);
49 			amplitude *= persistence;
50 			frequency *= def.lacunarity;
51 		}
52 		n = 1.0 - fabs(n);
53 		n *= n;
54 		return n;
55 	}
56 
billow_octavenoise(const fracdef_t & def,const double persistence,const vector3d & p)57 	inline double billow_octavenoise(const fracdef_t &def, const double persistence, const vector3d &p)
58 	{
59 		//assert(persistence <= (1.0 / def.lacunarity));
60 		double n = 0;
61 		double amplitude = persistence;
62 		double frequency = def.frequency;
63 		for (int i = 0; i < def.octaves; i++) {
64 			n += amplitude * noise(frequency * p);
65 			amplitude *= persistence;
66 			frequency *= def.lacunarity;
67 		}
68 		return (2.0 * fabs(n) - 1.0) + 1.0;
69 	}
70 
voronoiscam_octavenoise(const fracdef_t & def,const double persistence,const vector3d & p)71 	inline double voronoiscam_octavenoise(const fracdef_t &def, const double persistence, const vector3d &p)
72 	{
73 		//assert(persistence <= (1.0 / def.lacunarity));
74 		double n = 0;
75 		double amplitude = persistence;
76 		double frequency = def.frequency;
77 		for (int i = 0; i < def.octaves; i++) {
78 			n += amplitude * noise(frequency * p);
79 			amplitude *= persistence;
80 			frequency *= def.lacunarity;
81 		}
82 		return sqrt(10.0 * fabs(n));
83 	}
84 
dunes_octavenoise(const fracdef_t & def,const double persistence,const vector3d & p)85 	inline double dunes_octavenoise(const fracdef_t &def, const double persistence, const vector3d &p)
86 	{
87 		//assert(persistence <= (1.0 / def.lacunarity));
88 		double n = 0;
89 		double amplitude = persistence;
90 		double frequency = def.frequency;
91 		for (int i = 0; i < 3; i++) {
92 			n += amplitude * noise(frequency * p);
93 			amplitude *= persistence;
94 			frequency *= def.lacunarity;
95 		}
96 		return 1.0 - fabs(n);
97 	}
98 
99 	// XXX merge these with their fracdef versions
octavenoise(int octaves,const double persistence,const double lacunarity,const vector3d & p)100 	inline double octavenoise(int octaves, const double persistence, const double lacunarity, const vector3d &p)
101 	{
102 		//assert(persistence <= (1.0 / lacunarity));
103 		double n = 0;
104 		double amplitude = persistence;
105 		double frequency = 1.0;
106 		while (octaves--) {
107 			n += amplitude * noise(frequency * p);
108 			amplitude *= persistence;
109 			frequency *= lacunarity;
110 		}
111 		return (n + 1.0) * 0.5;
112 	}
113 
river_octavenoise(int octaves,const double persistence,const double lacunarity,const vector3d & p)114 	inline double river_octavenoise(int octaves, const double persistence, const double lacunarity, const vector3d &p)
115 	{
116 		//assert(persistence <= (1.0 / lacunarity));
117 		double n = 0;
118 		double amplitude = persistence;
119 		double frequency = 1.0;
120 		while (octaves--) {
121 			n += amplitude * fabs(noise(frequency * p));
122 			amplitude *= persistence;
123 			frequency *= lacunarity;
124 		}
125 		return n;
126 	}
127 
ridged_octavenoise(int octaves,const double persistence,const double lacunarity,const vector3d & p)128 	inline double ridged_octavenoise(int octaves, const double persistence, const double lacunarity, const vector3d &p)
129 	{
130 		//assert(persistence <= (1.0 / lacunarity));
131 		double n = 0;
132 		double amplitude = persistence;
133 		double frequency = 1.0;
134 		while (octaves--) {
135 			n += amplitude * noise(frequency * p);
136 			amplitude *= persistence;
137 			frequency *= lacunarity;
138 		}
139 		n = 1.0 - fabs(n);
140 		n *= n;
141 		return n;
142 	}
143 
billow_octavenoise(int octaves,const double persistence,const double lacunarity,const vector3d & p)144 	inline double billow_octavenoise(int octaves, const double persistence, const double lacunarity, const vector3d &p)
145 	{
146 		//assert(persistence <= (1.0 / lacunarity));
147 		double n = 0;
148 		double amplitude = persistence;
149 		double frequency = 1.0;
150 		while (octaves--) {
151 			n += amplitude * noise(frequency * p);
152 			amplitude *= persistence;
153 			frequency *= lacunarity;
154 		}
155 		return (2.0 * fabs(n) - 1.0) + 1.0;
156 	}
157 
voronoiscam_octavenoise(int octaves,const double persistence,const double lacunarity,const vector3d & p)158 	inline double voronoiscam_octavenoise(int octaves, const double persistence, const double lacunarity, const vector3d &p)
159 	{
160 		//assert(persistence <= (1.0 / lacunarity));
161 		double n = 0;
162 		double amplitude = persistence;
163 		double frequency = 1.0;
164 		while (octaves--) {
165 			n += amplitude * noise(frequency * p);
166 			amplitude *= persistence;
167 			frequency *= lacunarity;
168 		}
169 		return sqrt(10.0 * fabs(n));
170 	}
171 
172 	// not really a noise function but no better place for it
interpolate_color(const double n,const vector3d & start,const vector3d & end)173 	inline vector3d interpolate_color(const double n, const vector3d &start, const vector3d &end)
174 	{
175 		const double nClamped = Clamp(n, 0.0, 1.0);
176 		return start * (1.0 - nClamped) + end * nClamped;
177 	}
178 
179 } // namespace TerrainNoise
180 
181 // common colours for earthlike worlds
182 // XXX better way to do this?
183 
184 #define terrain_colournoise_rock octavenoise(GetFracDef(0), 0.65, p)
185 #define terrain_colournoise_rock2 octavenoise(GetFracDef(1), 0.6, p) * 0.6 * ridged_octavenoise(GetFracDef(0), 0.55, p)
186 // #define terrain_colournoise_rock3  0.5*ridged_octavenoise(GetFracDef(0), 0.5, p)*voronoiscam_octavenoise(GetFracDef(0), 0.5, p)*ridged_octavenoise(GetFracDef(1), 0.5, p)
187 // #define terrain_colournoise_rock4  0.5*ridged_octavenoise(GetFracDef(1), 0.5, p)*octavenoise(GetFracDef(1), 0.5, p)*octavenoise(GetFracDef(5), 0.5, p)
188 #define terrain_colournoise_mud 0.1 * voronoiscam_octavenoise(GetFracDef(1), 0.5, p) * octavenoise(GetFracDef(1), 0.5, p) * GetFracDef(5).amplitude
189 #define terrain_colournoise_sand ridged_octavenoise(GetFracDef(0), 0.4, p) * dunes_octavenoise(GetFracDef(2), 0.4, p) + 0.1 * dunes_octavenoise(GetFracDef(1), 0.5, p)
190 #define terrain_colournoise_sand2 dunes_octavenoise(GetFracDef(0), 0.6, p) * octavenoise(GetFracDef(4), 0.6, p)
191 // #define terrain_colournoise_sand3  dunes_octavenoise(GetFracDef(2), 0.6, p)*dunes_octavenoise(GetFracDef(6), 0.6, p)
192 #define terrain_colournoise_grass billow_octavenoise(GetFracDef(1), 0.8, p)
193 #define terrain_colournoise_grass2 billow_octavenoise(GetFracDef(3), 0.6, p) * voronoiscam_octavenoise(GetFracDef(4), 0.6, p) * river_octavenoise(GetFracDef(5), 0.6, p)
194 #define terrain_colournoise_forest octavenoise(GetFracDef(1), 0.65, p) * voronoiscam_octavenoise(GetFracDef(2), 0.65, p)
195 #define terrain_colournoise_water dunes_octavenoise(GetFracDef(6), 0.6, p)
196 
197 #endif
198