All four road tiers now carve into the 3D world. Rugged and Trail were generated, exported and parsed all along, but nothing ever consumed them — which is why county roads visible on the 2D map did not exist in 3D. Tier identity is now carried into the carve via a RoadSegment struct, so each tier gets its own width, shoulder and grade-smoothing from one tunable block in Constants: highways widest and holding a grade, trails narrow and hugging the land. Rugged and Trail surface as dirt rather than asphalt. Because tiers now have different reach, nearest-by-distance was no longer a sound way to pick the governing road — a nearby footpath could shadow a highway whose shoulder still covered the column. The carve now considers only roads whose shoulder actually reaches, and takes the closest of those. The per-chunk cull pad is derived from the widest shoulder plus a margin, so widening a road cannot silently truncate it at chunk edges. Untouched: density field, Marching Cubes interpolation/welding, chunk dims, the .dat contract, the 2D A* generation, and mesher normals. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
49 lines
2.4 KiB
C#
49 lines
2.4 KiB
C#
using Godot;
|
|
|
|
namespace IslaApocalypse.Core
|
|
{
|
|
public class ChunkData
|
|
{
|
|
public Vector2I ChunkPosition; // The X/Z coordinate of this chunk (e.g., 0,0 or 1,0)
|
|
|
|
// We need Width+1 and Depth+1 so the Marching Cubes mesh connects seamlessly to the neighbor chunks!
|
|
// public float[,,] Densities = new float[Constants.CHUNK_SIZE_X + 1, Constants.CHUNK_HEIGHT, Constants.CHUNK_SIZE_Z + 1];
|
|
// public byte[,,] BlockIDs = new byte[Constants.CHUNK_SIZE_X + 1, Constants.CHUNK_HEIGHT, Constants.CHUNK_SIZE_Z + 1];
|
|
// OLD:
|
|
// Densities = new float[Constants.CHUNK_SIZE_X, Constants.CHUNK_HEIGHT, Constants.CHUNK_SIZE_Z];
|
|
// BlockIDs = new int[Constants.CHUNK_SIZE_X, Constants.CHUNK_HEIGHT, Constants.CHUNK_SIZE_Z];
|
|
|
|
// NEW (Fix 3): We expand by 1 to sample the neighbor's border perfectly without seams!
|
|
public float[,,] Densities = new float[Constants.CHUNK_SIZE_X + 1, Constants.CHUNK_HEIGHT + 1, Constants.CHUNK_SIZE_Z + 1];
|
|
public byte[,,] BlockIDs = new byte[Constants.CHUNK_SIZE_X + 1, Constants.CHUNK_HEIGHT + 1, Constants.CHUNK_SIZE_Z + 1];
|
|
|
|
// --- PER-COLUMN DATA, FOR VERTEX COLOURING ONLY ----------------------
|
|
// One entry per X/Z column of this chunk (same +1 padding as above).
|
|
//
|
|
// Why these exist: BlockIDs are classified against a ROUNDED surface
|
|
// height, which is fine for storage but makes the rendered colour jump
|
|
// in whole-metre steps (the "contour band" artefact). The renderer
|
|
// instead reads the TRUE, unrounded surface height from here, so the
|
|
// material fade follows the real ground.
|
|
//
|
|
// These are read by the mesher only. Nothing about geometry, collision
|
|
// or storage depends on them.
|
|
public float[,] SurfaceHeights = new float[Constants.CHUNK_SIZE_X + 1, Constants.CHUNK_SIZE_Z + 1];
|
|
public Biome[,] ColumnBiomes = new Biome[Constants.CHUNK_SIZE_X + 1, Constants.CHUNK_SIZE_Z + 1];
|
|
|
|
// What this column's road surface is paved with — asphalt for highways,
|
|
// dirt for trails, and 0 (BlockRegistry.AIR) for "not a road at all".
|
|
// Carries the tier's material rather than a plain yes/no, so a footpath
|
|
// doesn't get painted like a motorway.
|
|
public byte[,] ColumnRoadMaterial = new byte[Constants.CHUNK_SIZE_X + 1, Constants.CHUNK_SIZE_Z + 1];
|
|
|
|
// For our future delta-save system
|
|
public bool IsPlayerProtected = false;
|
|
public bool NeedsSaving = false;
|
|
|
|
public ChunkData(Vector2I position)
|
|
{
|
|
ChunkPosition = position;
|
|
}
|
|
}
|
|
}
|