Skip to content

Commit 7922aa7

Browse files
committed
Small changes
1 parent b6de727 commit 7922aa7

10 files changed

+172
-118
lines changed

demo/TerrainTiles/3D_Terrain_Tiles.tres

Lines changed: 50 additions & 50 deletions
Large diffs are not rendered by default.

demo/TerrainTiles/Grid_Meshes_Loader.tscn

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
[ext_resource type="PackedScene" uid="uid://r3attbe54kel" path="res://TerrainTiles/cliffs.tscn" id="7_1ubri"]
1010
[ext_resource type="PackedScene" uid="uid://ci3xp1iywxf2o" path="res://TerrainTiles/cliffs_corner.tscn" id="8_2ix0w"]
1111
[ext_resource type="PackedScene" uid="uid://bnup07coye8fx" path="res://TerrainTiles/Cliff_Corner_Inner.glb" id="9_vsn3x"]
12-
[ext_resource type="PackedScene" uid="uid://q7oiyh40co85" path="res://TerrainTiles/Water_Corner_Inner.glb" id="10_4p2ei"]
12+
[ext_resource type="PackedScene" uid="uid://dy7je7lfyqw1y" path="res://TerrainTiles/Water_Corner_Inner.glb" id="10_4p2ei"]
1313

1414
[node name="GridMeshesLoader" type="Node3D"]
1515

@@ -29,6 +29,7 @@ visible = false
2929
visible = false
3030

3131
[node name="Ramp_Corner" parent="." instance=ExtResource("6_21lxm")]
32+
visible = false
3233

3334
[node name="Cliffs" parent="." instance=ExtResource("7_1ubri")]
3435
visible = false
0 Bytes
Binary file not shown.

demo/TerrainTiles/Water_Corner_Inner.blend.import

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
importer="scene"
44
importer_version=1
55
type="PackedScene"
6-
uid="uid://bj1kj2vg4g1w6"
6+
uid="uid://ckwxcl3a0k4qv"
77
path="res://.godot/imported/Water_Corner_Inner.blend-35e66b59c1fefbf752fbc64d0dbfe211.scn"
88

99
[deps]
-7 KB
Binary file not shown.
-88 Bytes
Binary file not shown.

demo/TerrainTiles/Water_Corner_Inner.glb.import

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
importer="scene"
44
importer_version=1
55
type="PackedScene"
6-
uid="uid://q7oiyh40co85"
6+
uid="uid://dy7je7lfyqw1y"
77
path="res://.godot/imported/Water_Corner_Inner.glb-822af3d9b979e2b662823f1f4607f037.scn"
88

99
[deps]

demo/Test.tscn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ cell_size = Vector3(1, 0.25, 1)
2323
data = {
2424
"cells": PackedInt32Array(65546, 2, 1048588, 65547, 1, 655372)
2525
}
26-
metadata/_editor_floor_ = Vector3(0, 1, 0)
26+
metadata/_editor_floor_ = Vector3(0, 0, 0)
2727

2828
[node name="Camera3D" type="Camera3D" parent="."]
2929
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 22.3218, 36.7455)

demo/terrain_gen_script.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func _ready():
1919
#generate(grid_map, 128, 128, 4, seed_value, 12, NoiseType.VALUE, 0.79, 0.1);
2020

2121
# Simplex Noise Based
22-
var result: Dictionary = generate(grid_map, 128, 128, 4, seed_value, 12, NoiseType.SIMPLEX, 0.6, 0.005, 0.015);
22+
var result: Dictionary = generate(grid_map, 128, 128, 4, seed_value, 12, NoiseType.SIMPLEX, 0.5, 0.005, 0.015);
2323

2424
#
2525
#

src/TerrainGen/Terrain_Gen.cpp

Lines changed: 116 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,8 @@ Dictionary TerrainGen::generate(
309309
(Cardinal Neighbors Only)
310310
311311
*****************************************************/
312-
int neighborRadius = 1; // 3x3 neighborhood (cardinal only)
313312
int threshold = 2; // Minimum matching neighbors to preserve center
314-
int iterations = 1; // Number of CA generations to apply
313+
int iterations = 2; // Number of CA generations to apply
315314

316315
vector<vector<int>> curr = heightMap;
317316
vector<vector<int>> next = heightMap;
@@ -321,6 +320,24 @@ Dictionary TerrainGen::generate(
321320
{ 0, -1 }, { 0, 1 }, { -1, 0 }, { 1, 0 }
322321
};
323322

323+
// Height Map is a double grid
324+
// +----+----+----+----+
325+
// | z1 | z2 | y1 | y2 |
326+
// +----+----+----+----+
327+
// | z3 | z4 | y3 | y5 |
328+
// +----+----+----+----+
329+
// | x1 | x2 | w1 | w2 |
330+
// +----+----+----+----+
331+
// | x3 | x4 | w3 | w4 |
332+
// +----+----+----+----+
333+
//
334+
// Eventually the map will be reduced to :
335+
// +----+----+
336+
// | z | y |
337+
// +----+----+
338+
// | x | w |
339+
// +----+----+
340+
324341
for (int it = 0; it < iterations; ++it) {
325342
bool anyChanged = false;
326343

@@ -395,80 +412,84 @@ Dictionary TerrainGen::generate(
395412
396413
*****************************************************/
397414

415+
int caCcount = 2;
416+
398417
if (waterRemoval >= 10.0f) {
399418
// Clamp percentage
400419
if (waterRemoval > 100.0f)
401420
waterRemoval = 100.0f;
402421
if (waterRemoval < 0.0f)
403422
waterRemoval = 0.0f;
404423

405-
vector<vector<bool>> visited(heightx2, vector<bool>(widthx2, false));
424+
for (int iter = 0; iter < caCcount; iter++) {
425+
vector<vector<bool>> visited(heightx2, vector<bool>(widthx2, false));
406426

407-
for (int y = 0; y < heightx2; y++) {
408-
for (int x = 0; x < widthx2; x++) {
409-
if (heightMap[y][x] != 0 || visited[y][x])
410-
continue;
427+
for (int y = 0; y < heightx2; y++) {
428+
for (int x = 0; x < widthx2; x++) {
429+
if (heightMap[y][x] != 0 || visited[y][x])
430+
continue;
411431

412-
// Manual stack flood fill
413-
vector<pair<int, int>> stack;
414-
vector<pair<int, int>> region;
415-
stack.push_back(make_pair(x, y));
416-
visited[y][x] = true;
417-
418-
while (!stack.empty()) {
419-
pair<int, int> current = stack.back();
420-
stack.pop_back();
421-
int cx = current.first;
422-
int cy = current.second;
423-
region.push_back(current);
424-
425-
for (int d = 0; d < 4; d++) {
426-
int nx = cx + dx[d];
427-
int ny = cy + dy[d];
428-
if (nx < 0 || ny < 0 || nx >= widthx2 || ny >= heightx2)
429-
continue;
430-
if (visited[ny][nx])
431-
continue;
432-
if (heightMap[ny][nx] != 0)
433-
continue;
434-
visited[ny][nx] = true;
435-
stack.push_back(make_pair(nx, ny));
432+
// Manual stack flood fill
433+
vector<pair<int, int>> stack;
434+
vector<pair<int, int>> region;
435+
stack.push_back(make_pair(x, y));
436+
visited[y][x] = true;
437+
438+
while (!stack.empty()) {
439+
pair<int, int> current = stack.back();
440+
stack.pop_back();
441+
int cx = current.first;
442+
int cy = current.second;
443+
region.push_back(current);
444+
445+
for (int d = 0; d < 4; d++) {
446+
int nx = cx + dx[d];
447+
int ny = cy + dy[d];
448+
if (nx < 0 || ny < 0 || nx >= widthx2 || ny >= heightx2)
449+
continue;
450+
if (visited[ny][nx])
451+
continue;
452+
if (heightMap[ny][nx] != 0)
453+
continue;
454+
visited[ny][nx] = true;
455+
stack.push_back(make_pair(nx, ny));
456+
}
436457
}
437-
}
438458

439-
// Determine how many cells to flip
440-
int regionSize = region.size();
441-
int toFlip = (int)(regionSize * (waterRemoval / 100.0f));
442-
if (toFlip <= 0)
443-
continue;
459+
// Determine how many cells to flip
460+
int regionSize = region.size();
461+
int toFlip = (int)(regionSize * (waterRemoval / 100.0f));
462+
if (toFlip <= 0)
463+
continue;
444464

445-
// Rank by proximity to edge
446-
vector<pair<int, pair<int, int>>> candidates;
447-
for (int i = 0; i < regionSize; i++) {
448-
int rx = region[i].first;
449-
int ry = region[i].second;
450-
int distX = min(rx, widthx2 - 1 - rx);
451-
int distY = min(ry, heightx2 - 1 - ry);
452-
int edgeDist = min(distX, distY);
453-
candidates.push_back(make_pair(edgeDist, region[i]));
454-
}
465+
// Rank by proximity to edge
466+
vector<pair<int, pair<int, int>>> candidates;
467+
for (int i = 0; i < regionSize; i++) {
468+
int rx = region[i].first;
469+
int ry = region[i].second;
470+
int distX = min(rx, widthx2 - 1 - rx);
471+
int distY = min(ry, heightx2 - 1 - ry);
472+
int edgeDist = min(distX, distY);
473+
candidates.push_back(make_pair(edgeDist, region[i]));
474+
}
455475

456-
// Bubble sort
457-
for (int i = 0; i < (int)candidates.size(); i++) {
458-
for (int j = i + 1; j < (int)candidates.size(); j++) {
459-
if (candidates[j].first < candidates[i].first) {
460-
pair<int, pair<int, int>> temp = candidates[i];
461-
candidates[i] = candidates[j];
462-
candidates[j] = temp;
476+
// Bubble sort
477+
for (int i = 0; i < (int)candidates.size(); i++) {
478+
for (int j = i + 1; j < (int)candidates.size(); j++) {
479+
if (candidates[j].first < candidates[i].first) {
480+
pair<int, pair<int, int>> temp = candidates[i];
481+
candidates[i] = candidates[j];
482+
candidates[j] = temp;
483+
}
463484
}
464485
}
465-
}
466486

467-
// Flip top N water cells to land
468-
for (int i = 0; i < toFlip && i < (int)candidates.size(); i++) {
469-
int fx = candidates[i].second.first;
470-
int fy = candidates[i].second.second;
471-
heightMap[fy][fx] = 1;
487+
// Flip top N water cells to land
488+
for (int i = 0; i < toFlip && i < (int)candidates.size(); i++) {
489+
int fx = candidates[i].second.first;
490+
int fy = candidates[i].second.second;
491+
heightMap[fy][fx] = 1;
492+
}
472493
}
473494
}
474495
}
@@ -798,7 +819,7 @@ Dictionary TerrainGen::generate(
798819
// | n3 | n4 | | 1 | 1 | | 2 | 2 |
799820
// +----+----+ +---+---+ +---+---+
800821
//
801-
if (n1 == n2 && n2 == n3 && n3 == n4 && n1 > 0 && n2 > 0 && n3 > 0 && n4 > 0) {
822+
if (n1 == n2 && n2 == n3 && n3 == n4 && n1 == n4 && n1 > 0 && n2 > 0 && n3 > 0 && n4 > 0) {
802823
tileMap[x][y] = GROUND;
803824
}
804825

@@ -1072,7 +1093,9 @@ Dictionary TerrainGen::generate(
10721093
//
10731094
//
10741095
//
1075-
// Phase 2 : Determine the Tile's Rotation
1096+
// Phase 2 : Corrections & Rotations
1097+
//
1098+
// Description: Determine the Tile's Rotation and correct tiles
10761099
//
10771100
// Models: Ramp Corner's/ Cliff Corner's / Water Corner's start with HIGH at (−Z, +X)
10781101
// i.e., NE corner.
@@ -1087,11 +1110,12 @@ Dictionary TerrainGen::generate(
10871110
// | m6 | m7 | m8 |
10881111
// +----+----+----+
10891112
//
1113+
10901114
for (int x = 0; x < width; x++) {
10911115
for (int y = 0; y < height; y++) {
10921116
int c_height = elevationMap[x][y];
10931117
int tile_id = myGridMap->get_cell_item(Vector3i(x, c_height, y));
1094-
if (tile_id == -1 || tile_id == WATER || tile_id == GROUND)
1118+
if (tile_id == -1 || tile_id == GROUND)
10951119
continue;
10961120

10971121
auto in_bounds = [&](int gx, int gy) {
@@ -1107,6 +1131,10 @@ Dictionary TerrainGen::generate(
11071131
return myGridMap->get_cell_item(Vector3i(gx, h, gy));
11081132
};
11091133

1134+
auto isWaterLike = [&](TileType t) {
1135+
return t == WATER || t == WATER_EDGE || t == WATER_CORNER || t == WATER_CORNER_INNER;
1136+
};
1137+
11101138
int rotation_val = NORTH; // default face −Z
11111139

11121140
//
@@ -1151,6 +1179,31 @@ Dictionary TerrainGen::generate(
11511179
int nwHeight = safe_height(x - 1, y + 1, c_height);
11521180
int nwTile = safe_tile_at(x - 1, y + 1); // m1
11531181

1182+
//
1183+
// Water Tiles
1184+
//
1185+
1186+
bool nWater = isWaterLike(static_cast<TileType>(nTile));
1187+
bool sWater = isWaterLike(static_cast<TileType>(sTile));
1188+
bool eWater = isWaterLike(static_cast<TileType>(eTile));
1189+
bool wWater = isWaterLike(static_cast<TileType>(wTile));
1190+
bool neWater = isWaterLike(static_cast<TileType>(neTile));
1191+
bool nwWater = isWaterLike(static_cast<TileType>(nwTile));
1192+
bool seWater = isWaterLike(static_cast<TileType>(seTile));
1193+
bool swWater = isWaterLike(static_cast<TileType>(swTile));
1194+
1195+
if (isWaterLike(static_cast<TileType>(tile_id))) {
1196+
int waterNeighbors =
1197+
nWater + sWater + eWater + wWater +
1198+
neWater + nwWater + seWater + swWater;
1199+
1200+
// Fully surrounded by water
1201+
if (waterNeighbors == 8) {
1202+
tile_id = WATER;
1203+
rotation_val = 0;
1204+
}
1205+
}
1206+
11541207
if (tile_id == RAMP || tile_id == CLIFF || tile_id == WATER_EDGE) {
11551208
// +----+----+----+
11561209
// | m1 | m2 | m3 |

0 commit comments

Comments
 (0)