@@ -1439,174 +1439,231 @@ Dictionary TerrainGen::generate(
14391439 // | m6 | m7 | m8 |
14401440 // +----+----+----+
14411441
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;
14431449 }
1444- if ( sEdge && eEdge) { // m5 + m7
1445- }
1446- if (nEdge && wEdge) { // m4 + m2
1450+
1451+ if (seGround) {
1452+ dElevation[ 1 ] = seHeight;
14471453 }
1448- if (sEdge && wEdge) { // m4 + m7
1454+
1455+ if (swGround) {
1456+ dElevation[2 ] = swHeight;
14491457 }
14501458
1451- myGridMap-> set_cell_item ( Vector3i (x, c_height, y), tile_id, rotation_val);
1452- }
1453- }
1459+ if (nwGround) {
1460+ dElevation[ 3 ] = nwHeight;
1461+ }
14541462
1455- /* ****************************************************
1463+ if (!(nEdge && eEdge)) { // m2 + m5 | m3
1464+ dElevation[0 ] = -1 ;
1465+ }
14561466
1457- Open Area Finder
1467+ if (!(sEdge && eEdge)) { // m5 + m7 | m8
1468+ dElevation[1 ] = -1 ;
1469+ }
14581470
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+ }
14611474
1462- **************************************************** */
1463- // Empty FlatZones
1464- flatZones. clear ();
1475+ if (!(nEdge && wEdge)) { // m4 + m2 | m1
1476+ dElevation[ 3 ] = - 1 ;
1477+ }
14651478
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 ;
14691481
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);
14771486 }
14781487 }
14791488
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 ;
14861505 }
14871506 }
1507+
1508+ myGridMap->set_cell_item (Vector3i (x, c_height, y), tile_id, rotation_val);
14881509 }
1510+ }
14891511
1490- /* ****************************************************
1512+ /* ****************************************************
14911513
1492- Poisson Object Placement
1514+ Open Area Finder
14931515
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
14961518
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+ }
14981536
1499- // Generate Placeable Area's
1537+ if (allGround) {
1538+ int centerX = i + 1 ;
1539+ int centerY = j + 1 ;
1540+ int elevation = elevationMap[centerX][centerY];
15001541
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+ /* ****************************************************
15081548
1509- // Only mark subcells as placeable if both conditions are true
1510- bool isPlaceable = isNonWalkable && isNotCliffOrRamp;
1549+ Poisson Object Placement
15111550
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;
15171573 }
1574+ }
15181575
1519- // Poisson Disk Sampling
1576+ // Poisson Disk Sampling
15201577
1521- float minDistance = 3 .0f ; // Minimum spacing between objects
1578+ float minDistance = 3 .0f ; // Minimum spacing between objects
15221579
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 ;
15271584
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 ;
15361592 }
1593+ }
15371594
1538- if (!tooClose) {
1539- poissonSamples.push_back ({ x, y });
1540- }
1595+ if (!tooClose) {
1596+ poissonSamples.push_back ({ x, y });
15411597 }
15421598 }
1599+ }
15431600
1544- /* ****************************************************
1601+ /* ****************************************************
15451602
1546- Return's
1603+ Return's
15471604
1548- Return a dictionary of values needed for object
1549- placement
1605+ Return a dictionary of values needed for object
1606+ placement
15501607
1551- Return : Elevation Map
1552- Necessary for height of objects
1608+ Return : Elevation Map
1609+ Necessary for height of objects
15531610
1554- Return : Flat Zones
1555- Necessary for placing large stuctures
1611+ Return : Flat Zones
1612+ Necessary for placing large stuctures
15561613
1557- Return : Poisson Points
1614+ Return : Poisson Points
15581615
1559- *****************************************************/
1616+ *****************************************************/
15601617
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
15641621
1565- Dictionary result;
1622+ Dictionary result;
15661623
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 ;
15741631
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);
15801636 }
1581- result[" poissonPoints" ] = poissonPoints;
1637+ }
1638+ result[" poissonPoints" ] = poissonPoints;
15821639
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 ;
15891646
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);
16041659 }
1605- result[" elevationMap" ] = elevationArray;
1606-
1607- return result;
1660+ elevationArray.push_back (inner);
16081661 }
1662+ result[" elevationMap" ] = elevationArray;
1663+
1664+ return result;
1665+ }
16091666
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