public static int GetTerrainHeight(int x, int y, BiomeDefData biomeDef, NativeArray <float2> offsets, NativeArray <int> terrainCurve) { var sampleNoise = Noise.GetHeight(x, y, biomeDef.Octaves, biomeDef.Lacunarity, biomeDef.Persistance, biomeDef.Frequency, offsets, biomeDef.Offset); var heightFromNoise = Mathf.FloorToInt(GeometryConsts.CHUNK_HEIGHT * sampleNoise); return(math.clamp(terrainCurve[biomeDef.TerrainCurveStartPos + heightFromNoise], 0, GeometryConsts.CHUNK_HEIGHT - 1)); }
public override void PostConstruct() { base.PostConstruct(); var defs = GetAllDefinitions(); //TODO: count lode array size properly! const int MAX_LODES_PER_DEF = 20; const int MAX_THRESHOLD_PER_DEF = MAX_LODES_PER_DEF * GeometryConsts.CHUNK_HEIGHT; _biomeDefData = new NativeArray <BiomeDefData>(defs.Length, Allocator.Persistent); _terrainCurvesSampled = new NativeArray <int>(defs.Length * GeometryConsts.CHUNK_HEIGHT, Allocator.Persistent); _lodes = new NativeArray <LodeDefData>(defs.Length * MAX_LODES_PER_DEF, Allocator.Persistent); _lodeThresholds = new NativeArray <float>(defs.Length * MAX_THRESHOLD_PER_DEF, Allocator.Persistent); var lodeIndex = 0; for (var i = 0; i < defs.Length; i++) { var def = defs[i]; //////////// BIOME DEF ///////////// _biomeDefData[i] = new BiomeDefData(def, lodeIndex); ////////// TERRAIN CURVES ////////// CurveHelper.SampleCurve(def.TerrainCurve, _terrainCurvesSampled, i * GeometryConsts.CHUNK_HEIGHT); ////////////// LODES ////////////// foreach (var lodeDef in def.lodeDefs) { _lodes[lodeIndex] = new LodeDefData(lodeDef); CurveHelper.SampleCurve(lodeDef.ThresholdByY, _lodeThresholds, lodeIndex * GeometryConsts.CHUNK_HEIGHT); lodeIndex++; } } }
/// <summary> /// Generates single voxel on world coordinates - called only by WorldModel when we truly want to generate /// and know that coordinates are valid /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="z"></param> /// <param name="terrainHeight"></param> /// <param name="biome"></param> /// <param name="lodes"></param> /// <param name="lodeTresholds"></param> /// <returns></returns> public static byte GenerateVoxel(int x, int y, int z, int terrainHeight, BiomeDefData biome, NativeArray <LodeDefData> lodes, NativeArray <float> lodeTresholds) { //TODO: generate whole column, so height biome and determination etc is not called every voxel! // ======== STATIC RULES ======== if (y == 0) { return(BlockTypeByte.GREY_STONE); } // ======== BASIC PASS ======== byte voxelValue = 0; //everything higher then terrainHeight is air if (y >= terrainHeight) { return(BlockTypeByte.AIR); } //top voxels are grass if (y == terrainHeight - 1) { voxelValue = BlockMaskByte.TOP; } //3 voxels under grass are dirt else if (y >= terrainHeight - 4) { voxelValue = BlockMaskByte.MIDDLE; } //rest is rock else { voxelValue = BlockMaskByte.BOTTOM; } //LODES PASS bool lodesPassResolved = false; for (var i = biome.LodesStartPos; i < biome.LodesCount; i++) { var lode = lodes[i]; if ((lode.BlockMask & voxelValue) == 0) { continue; //try next lode } if (y > lode.MinHeight && y < lode.MaxHeight) { var treshold = lodeTresholds[biome.LodesStartPos + i * GeometryConsts.CHUNK_HEIGHT + y]; if (Noise.GetLodePresence(lode.Algorithm, x, y, z, lode.Offset, lode.Frequency, treshold)) { voxelValue = lode.BlockId; lodesPassResolved = true; break; //We found our block - continue to next pass! } } } //if no lode was applied, show basic biome block for given placeholder if (!lodesPassResolved) { switch (voxelValue) { case BlockMaskByte.TOP: voxelValue = biome.TopBlock; break; case BlockMaskByte.MIDDLE: voxelValue = biome.MiddleBlock; break; case BlockMaskByte.BOTTOM: voxelValue = biome.BottomBlock; break; } } return(voxelValue); }