-
Notifications
You must be signed in to change notification settings - Fork 4
/
TerrainGenerator.cpp
114 lines (94 loc) · 3.34 KB
/
TerrainGenerator.cpp
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
#include "TerrainGenerator.h"
#include <vector>
TerrainGenerator::TerrainGenerator() {
ofEnableDepthTest();
glShadeModel(GL_FLAT);
mesh.setMode(OF_PRIMITIVE_TRIANGLES);
camera.setPosition(ofVec3f(0, -350, 2050));
}
void TerrainGenerator::setup(GUI::Settings s) {
this->seed = s.seed;
this->tileSize = s.tileSize;
this->mapWidth = s.mapWidth;
this->mapHeight = s.mapHeight;
this->octaves = s.octaves;
this->noiseScale = s.noiseScale;
this->lacunarity = s.lacunarity;
this->persistence = s.persistence;
this->maxElevation = s.maxElevation;
terrainElevation = TerrainElevation(s);
terrainElevation.initializeMatrix();
terrainElevation.calculateNoise();
terrainElevation.applyMapType();
elevationMap = terrainElevation.getElevationMap();
terrainColor = TerrainColor(s);
mesh.clear();
int columns = mapWidth / tileSize;
int rows = mapHeight / tileSize;
ofVec3f topLeft, topRight, bottomLeft, bottomRight;
for (int j = 0; j < rows; j++) {
for (int i = 0; i < columns; i++) {
topLeft = ofVec3f(i, j);
topRight = ofVec3f(i + 1, j);
bottomLeft = ofVec3f(i, j + 1);
bottomRight = ofVec3f(i + 1, j + 1);
if ((i % 2 == 0 && j % 2 == 0) || (i % 2 != 0 && j % 2 != 0)) {
addTriangle(topLeft, topRight, bottomLeft);
addTriangle(bottomLeft, topRight, bottomRight);
}
else {
addTriangle(bottomLeft, topLeft, bottomRight);
addTriangle(bottomRight, topLeft, topRight);
}
}
}
mesh.setupIndicesAuto();
calculateNormals();
}
void TerrainGenerator::addTriangle(ofVec3f p1, ofVec3f p2, ofVec3f p3) {
p1.z = elevationMap.at(p1.y).at(p1.x);
p2.z = elevationMap.at(p2.y).at(p2.x);
p3.z = elevationMap.at(p3.y).at(p3.x);
float triangleElevation = (p1.z + p2.z + p3.z) / 3;
addVertex(p1, triangleElevation);
addVertex(p2, triangleElevation);
addVertex(p3, triangleElevation);
}
void TerrainGenerator::addVertex(ofVec3f p, float triangleElevation) {
p.x *= tileSize;
p.y *= tileSize;
if (p.z < 0) {
p.z = 0;
}
triangleElevation = ofMap(triangleElevation, -maxElevation, maxElevation, 0, 1);
terrainColor.calculateColor(triangleElevation);
mesh.addVertex(p);
mesh.addColor(terrainColor.getColor());
mesh.addNormal(ofVec3f(0, 0, 0));
}
void TerrainGenerator::calculateNormals() {
int p1, p2, p3;
ofVec3f v1, v2, crossProduct;
for (int i = 0; i < mesh.getIndices().size(); i += 3) {
p1 = mesh.getIndices()[i];
p2 = mesh.getIndices()[i+1];
p3 = mesh.getIndices()[i+2];
v1 = mesh.getVertices()[p1] - mesh.getVertices()[p2];
v2 = mesh.getVertices()[p3] - mesh.getVertices()[p2];
crossProduct = v2.cross(v1);
mesh.getNormals()[p1] += crossProduct;
mesh.getNormals()[p2] += crossProduct;
mesh.getNormals()[p3] += crossProduct;
}
}
void TerrainGenerator::draw() {
camera.begin();
light.enable();
light.setParent(camera);
ofPushMatrix();
ofRotateXDeg(-45);
ofTranslate(-mapWidth/2, -mapHeight/2);
mesh.drawFaces();
ofPopMatrix();
camera.end();
}