-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathGrid.C
134 lines (109 loc) · 2.94 KB
/
Grid.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "Grid.h"
#include <assert.h>
#include <cmath>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_real_distribution.hpp>
Grid::Grid(float width, float length, int segs)
: _width(width), _length(length), _widthSegs(segs), _lengthSegs(segs), _widthVtex(segs + 1), _lengthVtex(segs + 1)
{
_vertices = new float[_widthSegs * _lengthSegs];
}
Grid::Grid(float width, float length, int segs, float* vertexHeights)
: _width(width), _length(length), _widthSegs(segs), _lengthSegs(segs), _widthVtex(segs + 1), _lengthVtex(segs + 1)
{
_vertices = vertexHeights;
}
Grid::~Grid(void)
{
delete [] _vertices;
}
float Grid::GetWidth() const
{
return _width;
}
float Grid::GetLength() const
{
return _length;
}
int Grid::GetWidthSegs() const
{
return _widthSegs;
}
int Grid::GetLengthSegs() const
{
return _lengthSegs;
}
int Grid::GetWidthVertices() const
{
return _widthVtex;
}
int Grid::GetLengthVertices() const
{
return _lengthVtex;
}
int Grid::GetTotalVertices() const
{
return _widthVtex * _lengthVtex;
}
float* Grid::GetVertexHeights() const
{
return _vertices;
}
void Grid::SetVertexHeightWrap(int u, int v, float height)
{
u = (u + _widthSegs) % _widthSegs;
v = (v + _lengthSegs) % _lengthSegs;
*(_vertices + u * _lengthSegs + v) = height;
}
float Grid::GetVertexHeightWrap(int u, int v) const
{
u = (u + _widthSegs) % _widthSegs;
v = (v + _lengthSegs) % _lengthSegs;
return *(_vertices + u * _lengthSegs + v);
}
void Grid::Clear()
{
int total = _widthSegs * _lengthSegs;
for (int i = 0; i < total; i++)
{
_vertices[i] = 0.0;
}
}
void Grid::Diamond(int u, int v, int r, float rand)
{
float avg = (GetVertexHeightWrap(u - r, v - r)
+ GetVertexHeightWrap(u - r, v + r)
+ GetVertexHeightWrap(u + r, v - r)
+ GetVertexHeightWrap(u + r, v + r)) / 4.0f;
SetVertexHeightWrap(u, v, avg + rand);
}
void Grid::Square(int u, int v, int r, float rand)
{
float avg = (GetVertexHeightWrap(u - r, v)
+ GetVertexHeightWrap(u + r, v)
+ GetVertexHeightWrap(u, v - r)
+ GetVertexHeightWrap(u, v + r)) / 4.0f;
SetVertexHeightWrap(u, v, avg + rand);
}
void Grid::DiamondSquare(unsigned long seed, float rough, float height)
{
Clear();
boost::mt19937 engine;
engine.seed(seed);
float d = height;
// Shift will divide radius in half, except 1 >> 1 becomes 0.
for (int r = _widthSegs / 2; r > 0; r >>= 1) {
// Before each iteration.
boost::random::uniform_real_distribution<float> dist(-d, d);
for (int i = 0; i < _widthSegs; i += 2 * r)
{
for (int j = 0; j < _lengthSegs; j += 2 * r)
{
Diamond(i + r, j + r, r, dist(engine));
Square(i + r, j, r, dist(engine));
Square(i, j + r, r, dist(engine));
}
}
d *= pow(2.0f, -1.0f + rough); // After each iteration.
}
}