@@ -1439,174 +1439,231 @@ Dictionary TerrainGen::generate(
1439
1439
// | m6 | m7 | m8 |
1440
1440
// +----+----+----+
1441
1441
1442
- if (nEdge && eEdge) { // m2 + m5
1442
+ // Diagonal's
1443
+ //
1444
+ // NE (m3), SE (m8), SW (m6), NW (m1)
1445
+ // if -1, not ground tile
1446
+ vector<int > dElevation = { -1 , -1 , -1 , -1 };
1447
+ if (neGround) {
1448
+ dElevation[0 ] = neHeight;
1443
1449
}
1444
- if ( sEdge && eEdge) { // m5 + m7
1445
- }
1446
- if (nEdge && wEdge) { // m4 + m2
1450
+
1451
+ if (seGround) {
1452
+ dElevation[ 1 ] = seHeight;
1447
1453
}
1448
- if (sEdge && wEdge) { // m4 + m7
1454
+
1455
+ if (swGround) {
1456
+ dElevation[2 ] = swHeight;
1449
1457
}
1450
1458
1451
- myGridMap-> set_cell_item ( Vector3i (x, c_height, y), tile_id, rotation_val);
1452
- }
1453
- }
1459
+ if (nwGround) {
1460
+ dElevation[ 3 ] = nwHeight;
1461
+ }
1454
1462
1455
- /* ****************************************************
1463
+ if (!(nEdge && eEdge)) { // m2 + m5 | m3
1464
+ dElevation[0 ] = -1 ;
1465
+ }
1456
1466
1457
- Open Area Finder
1467
+ if (!(sEdge && eEdge)) { // m5 + m7 | m8
1468
+ dElevation[1 ] = -1 ;
1469
+ }
1458
1470
1459
- Find areas that have 3x3 flat areas
1460
- Used for placing Large Structures
1471
+ if (!(sEdge && wEdge)) { // m4 + m7 | m6
1472
+ dElevation[2 ] = -1 ;
1473
+ }
1461
1474
1462
- **************************************************** */
1463
- // Empty FlatZones
1464
- flatZones. clear ();
1475
+ if (!(nEdge && wEdge)) { // m4 + m2 | m1
1476
+ dElevation[ 3 ] = - 1 ;
1477
+ }
1465
1478
1466
- for (int i = 0 ; i <= width - 3 ; i += 3 ) {
1467
- for (int j = 0 ; j <= height - 3 ; j += 3 ) {
1468
- bool allGround = true ;
1479
+ int maxElevation = dElevation[0 ];
1480
+ int dEleIndex = 0 ;
1469
1481
1470
- // Check Neighbors
1471
- for (int dx = 0 ; dx < 3 && allGround; dx++) {
1472
- for (int dy = 0 ; dy < 3 ; dy++) {
1473
- if (tileMap[i + dx][j + dy] != GROUND) {
1474
- allGround = false ;
1475
- break ;
1476
- }
1482
+ for (size_t i = 1 ; i < dElevation.size (); ++i) {
1483
+ if (dElevation[i] > maxElevation) {
1484
+ maxElevation = dElevation[i];
1485
+ dEleIndex = static_cast <int >(i);
1477
1486
}
1478
1487
}
1479
1488
1480
- if (allGround) {
1481
- int centerX = i + 1 ;
1482
- int centerY = j + 1 ;
1483
- int elevation = elevationMap[centerX][centerY];
1484
-
1485
- flatZones.push_back ({ centerX, elevation, centerY });
1489
+ switch (dEleIndex) {
1490
+ case 0 :
1491
+ rotation_val = EAST;
1492
+ break ;
1493
+ case 1 :
1494
+ rotation_val = SOUTH;
1495
+ break ;
1496
+ case 2 :
1497
+ rotation_val = WEST;
1498
+ break ;
1499
+ case 3 :
1500
+ rotation_val = NORTH;
1501
+ break ;
1502
+ default :
1503
+ rotation_val = NORTH;
1504
+ break ;
1486
1505
}
1487
1506
}
1507
+
1508
+ myGridMap->set_cell_item (Vector3i (x, c_height, y), tile_id, rotation_val);
1488
1509
}
1510
+ }
1489
1511
1490
- /* ****************************************************
1512
+ /* ****************************************************
1491
1513
1492
- Poisson Object Placement
1514
+ Open Area Finder
1493
1515
1494
- Use Walkable map to find non-walkable area's as placeable area's
1495
- Use Cliffs & Ramp's Placement as non-placeable area's
1516
+ Find areas that have 3x3 flat areas
1517
+ Used for placing Large Structures
1496
1518
1497
- *****************************************************/
1519
+ *****************************************************/
1520
+ // Empty FlatZones
1521
+ flatZones.clear ();
1522
+
1523
+ for (int i = 0 ; i <= width - 3 ; i += 3 ) {
1524
+ for (int j = 0 ; j <= height - 3 ; j += 3 ) {
1525
+ bool allGround = true ;
1526
+
1527
+ // Check Neighbors
1528
+ for (int dx = 0 ; dx < 3 && allGround; dx++) {
1529
+ for (int dy = 0 ; dy < 3 ; dy++) {
1530
+ if (tileMap[i + dx][j + dy] != GROUND) {
1531
+ allGround = false ;
1532
+ break ;
1533
+ }
1534
+ }
1535
+ }
1498
1536
1499
- // Generate Placeable Area's
1537
+ if (allGround) {
1538
+ int centerX = i + 1 ;
1539
+ int centerY = j + 1 ;
1540
+ int elevation = elevationMap[centerX][centerY];
1500
1541
1501
- for (int x = 0 ; x < width; x++) {
1502
- for (int y = 0 ; y < height; y++) {
1503
- bool isNonWalkable = walkableMap[x][y];
1504
- bool isNotCliffOrRamp = tileMap[x][y] != TileType::CLIFF &&
1505
- tileMap[x][y] != TileType::RAMP &&
1506
- tileMap[x][y] != TileType::CLIFF_CORNER &&
1507
- tileMap[x][y] != TileType::RAMP_CORNER;
1542
+ flatZones.push_back ({ centerX, elevation, centerY });
1543
+ }
1544
+ }
1545
+ }
1546
+
1547
+ /* ****************************************************
1508
1548
1509
- // Only mark subcells as placeable if both conditions are true
1510
- bool isPlaceable = isNonWalkable && isNotCliffOrRamp;
1549
+ Poisson Object Placement
1511
1550
1512
- placeableMap[x * 2 ][y * 2 ] = isPlaceable;
1513
- placeableMap[x * 2 + 1 ][y * 2 ] = isPlaceable;
1514
- placeableMap[x * 2 ][y * 2 + 1 ] = isPlaceable;
1515
- placeableMap[x * 2 + 1 ][y * 2 + 1 ] = isPlaceable;
1516
- }
1551
+ Use Walkable map to find non-walkable area's as placeable area's
1552
+ Use Cliffs & Ramp's Placement as non-placeable area's
1553
+
1554
+ *****************************************************/
1555
+
1556
+ // Generate Placeable Area's
1557
+
1558
+ for (int x = 0 ; x < width; x++) {
1559
+ for (int y = 0 ; y < height; y++) {
1560
+ bool isNonWalkable = walkableMap[x][y];
1561
+ bool isNotCliffOrRamp = tileMap[x][y] != TileType::CLIFF &&
1562
+ tileMap[x][y] != TileType::RAMP &&
1563
+ tileMap[x][y] != TileType::CLIFF_CORNER &&
1564
+ tileMap[x][y] != TileType::RAMP_CORNER;
1565
+
1566
+ // Only mark subcells as placeable if both conditions are true
1567
+ bool isPlaceable = isNonWalkable && isNotCliffOrRamp;
1568
+
1569
+ placeableMap[x * 2 ][y * 2 ] = isPlaceable;
1570
+ placeableMap[x * 2 + 1 ][y * 2 ] = isPlaceable;
1571
+ placeableMap[x * 2 ][y * 2 + 1 ] = isPlaceable;
1572
+ placeableMap[x * 2 + 1 ][y * 2 + 1 ] = isPlaceable;
1517
1573
}
1574
+ }
1518
1575
1519
- // Poisson Disk Sampling
1576
+ // Poisson Disk Sampling
1520
1577
1521
- float minDistance = 3 .0f ; // Minimum spacing between objects
1578
+ float minDistance = 3 .0f ; // Minimum spacing between objects
1522
1579
1523
- for (int x = 0 ; x < widthx2; x++) {
1524
- for (int y = 0 ; y < heightx2; y++) {
1525
- if (!placeableMap[x][y])
1526
- continue ;
1580
+ for (int x = 0 ; x < widthx2; x++) {
1581
+ for (int y = 0 ; y < heightx2; y++) {
1582
+ if (!placeableMap[x][y])
1583
+ continue ;
1527
1584
1528
- bool tooClose = false ;
1529
- for (const Point &p : poissonSamples) {
1530
- float dx = p.x - x;
1531
- float dy = p.y - y;
1532
- if (sqrt (dx * dx + dy * dy) < minDistance) {
1533
- tooClose = true ;
1534
- break ;
1535
- }
1585
+ bool tooClose = false ;
1586
+ for (const Point &p : poissonSamples) {
1587
+ float dx = p.x - x;
1588
+ float dy = p.y - y;
1589
+ if (sqrt (dx * dx + dy * dy) < minDistance) {
1590
+ tooClose = true ;
1591
+ break ;
1536
1592
}
1593
+ }
1537
1594
1538
- if (!tooClose) {
1539
- poissonSamples.push_back ({ x, y });
1540
- }
1595
+ if (!tooClose) {
1596
+ poissonSamples.push_back ({ x, y });
1541
1597
}
1542
1598
}
1599
+ }
1543
1600
1544
- /* ****************************************************
1601
+ /* ****************************************************
1545
1602
1546
- Return's
1603
+ Return's
1547
1604
1548
- Return a dictionary of values needed for object
1549
- placement
1605
+ Return a dictionary of values needed for object
1606
+ placement
1550
1607
1551
- Return : Elevation Map
1552
- Necessary for height of objects
1608
+ Return : Elevation Map
1609
+ Necessary for height of objects
1553
1610
1554
- Return : Flat Zones
1555
- Necessary for placing large stuctures
1611
+ Return : Flat Zones
1612
+ Necessary for placing large stuctures
1556
1613
1557
- Return : Poisson Points
1614
+ Return : Poisson Points
1558
1615
1559
- *****************************************************/
1616
+ *****************************************************/
1560
1617
1561
- // TODO : Return data needed for object placement's
1562
- // TODO : Return flatZones/openArea's
1563
- // TODO : Return poisson disk sampling results
1618
+ // TODO : Return data needed for object placement's
1619
+ // TODO : Return flatZones/openArea's
1620
+ // TODO : Return poisson disk sampling results
1564
1621
1565
- Dictionary result;
1622
+ Dictionary result;
1566
1623
1567
- // Convert poissonSamples → Array<Vector3i>
1568
- Array poissonPoints;
1569
- for (size_t i = 0 ; i < poissonSamples.size (); ++i) {
1570
- int px = poissonSamples[i].x ;
1571
- int py = poissonSamples[i].y ;
1572
- int ex = px / 2 ;
1573
- int ey = py / 2 ;
1624
+ // Convert poissonSamples → Array<Vector3i>
1625
+ Array poissonPoints;
1626
+ for (size_t i = 0 ; i < poissonSamples.size (); ++i) {
1627
+ int px = poissonSamples[i].x ;
1628
+ int py = poissonSamples[i].y ;
1629
+ int ex = px / 2 ;
1630
+ int ey = py / 2 ;
1574
1631
1575
- if (ex >= 0 && ex < width && ey >= 0 && ey < height) {
1576
- int elevation = elevationMap[ex][ey];
1577
- Vector3i point (px, elevation, py);
1578
- poissonPoints.push_back (point);
1579
- }
1632
+ if (ex >= 0 && ex < width && ey >= 0 && ey < height) {
1633
+ int elevation = elevationMap[ex][ey];
1634
+ Vector3i point (px, elevation, py);
1635
+ poissonPoints.push_back (point);
1580
1636
}
1581
- result[" poissonPoints" ] = poissonPoints;
1637
+ }
1638
+ result[" poissonPoints" ] = poissonPoints;
1582
1639
1583
- // Convert flatZones → Array<Dictionary>
1584
- Array flatZonePoints;
1585
- for (size_t i = 0 ; i < flatZones.size (); ++i) {
1586
- int fx = flatZones[i].x ;
1587
- int fy = flatZones[i].y ;
1588
- int elevation = flatZones[i].elevation ;
1640
+ // Convert flatZones → Array<Dictionary>
1641
+ Array flatZonePoints;
1642
+ for (size_t i = 0 ; i < flatZones.size (); ++i) {
1643
+ int fx = flatZones[i].x ;
1644
+ int fy = flatZones[i].y ;
1645
+ int elevation = flatZones[i].elevation ;
1589
1646
1590
- Vector3i point (fx, elevation, fy);
1591
- flatZonePoints.push_back (point);
1592
- }
1593
- result[" flatZonePoints" ] = flatZonePoints;
1594
-
1595
- // Convert elevationMap → Array<Array<int>>
1596
- Array elevationArray;
1597
- for (size_t i = 0 ; i < elevationMap.size (); ++i) {
1598
- Array inner;
1599
- for (size_t j = 0 ; j < elevationMap[i].size (); ++j) {
1600
- int val = elevationMap[i][j];
1601
- inner.push_back (val);
1602
- }
1603
- elevationArray.push_back (inner);
1647
+ Vector3i point (fx, elevation, fy);
1648
+ flatZonePoints.push_back (point);
1649
+ }
1650
+ result[" flatZonePoints" ] = flatZonePoints;
1651
+
1652
+ // Convert elevationMap → Array<Array<int>>
1653
+ Array elevationArray;
1654
+ for (size_t i = 0 ; i < elevationMap.size (); ++i) {
1655
+ Array inner;
1656
+ for (size_t j = 0 ; j < elevationMap[i].size (); ++j) {
1657
+ int val = elevationMap[i][j];
1658
+ inner.push_back (val);
1604
1659
}
1605
- result[" elevationMap" ] = elevationArray;
1606
-
1607
- return result;
1660
+ elevationArray.push_back (inner);
1608
1661
}
1662
+ result[" elevationMap" ] = elevationArray;
1663
+
1664
+ return result;
1665
+ }
1609
1666
1610
- void TerrainGen::_bind_methods () {
1611
- ClassDB::bind_method (D_METHOD (" generate" , " GridMap" , " height" , " width" , " elevationMax" , " seed" , " openAreaMin" , " noiseType" , " waterRemoval" , " cliffsThreshold" , " noiseFreq" ), &TerrainGen::generate);
1612
- }
1667
+ void TerrainGen::_bind_methods () {
1668
+ ClassDB::bind_method (D_METHOD (" generate" , " GridMap" , " height" , " width" , " elevationMax" , " seed" , " openAreaMin" , " noiseType" , " waterRemoval" , " cliffsThreshold" , " noiseFreq" ), &TerrainGen::generate);
1669
+ }
0 commit comments