mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-05 12:07:25 -04:00
79 lines
2.6 KiB
C#
79 lines
2.6 KiB
C#
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
|
// Based on:
|
|
// https://github.com/UnknownShadow200/ClassicalSharp/wiki/Minecraft-Classic-map-generation-algorithm
|
|
// Thanks to Jerralish for originally reverse engineering classic's algorithm, then preparing a high level overview of the algorithm.
|
|
// I believe this process adheres to clean room reverse engineering.
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace ClassicalSharp.Generator {
|
|
|
|
// TODO: figure out how noise functions differ, probably based on rnd.
|
|
public sealed partial class NotchyGenerator {
|
|
|
|
void FillOblateSpheroid( int x, int y, int z, float radius, byte block ) {
|
|
int xStart = Utils.Floor( Math.Max( x - radius, 0 ) );
|
|
int xEnd = Utils.Floor( Math.Min( x + radius, width - 1 ) );
|
|
int yStart = Utils.Floor( Math.Max( y - radius, 0 ) );
|
|
int yEnd = Utils.Floor( Math.Min( y + radius, height - 1 ) );
|
|
int zStart = Utils.Floor( Math.Max( z - radius, 0 ) );
|
|
int zEnd = Utils.Floor( Math.Min( z + radius, length - 1 ) );
|
|
float radiusSq = radius * radius;
|
|
|
|
for( int yy = yStart; yy <= yEnd; yy++ )
|
|
for( int zz = zStart; zz <= zEnd; zz++ )
|
|
for( int xx = xStart; xx <= xEnd; xx++ )
|
|
{
|
|
int dx = xx - x, dy = yy - y, dz = zz - z;
|
|
if( (dx * dx + 2 * dy * dy + dz * dz) < radiusSq ) {
|
|
int index = (yy * length + zz) * width + xx;
|
|
if( blocks[index] == (byte)Block.Stone )
|
|
blocks[index] = block;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FloodFill( int startIndex, byte block ) {
|
|
FastIntStack stack = new FastIntStack( 4 );
|
|
stack.Push( startIndex );
|
|
while( stack.Size > 0 ) {
|
|
int index = stack.Pop();
|
|
if( blocks[index] == 0 ) {
|
|
blocks[index] = block;
|
|
|
|
int x = index % width;
|
|
int y = index / oneY;
|
|
int z = (index / width) % length;
|
|
if( x > 0 ) stack.Push( index - 1 );
|
|
if( x < width - 1 ) stack.Push( index + 1 );
|
|
if( z > 0 ) stack.Push( index - width );
|
|
if( z < length - 1 ) stack.Push( index + width );
|
|
if( y > 0 ) stack.Push( index - oneY );
|
|
}
|
|
}
|
|
}
|
|
|
|
sealed class FastIntStack {
|
|
public int[] Values;
|
|
public int Size;
|
|
|
|
public FastIntStack( int capacity ) {
|
|
Values = new int[capacity];
|
|
Size = 0;
|
|
}
|
|
|
|
public int Pop() {
|
|
return Values[--Size];
|
|
}
|
|
|
|
public void Push( int item ) {
|
|
if( Size == Values.Length ) {
|
|
int[] array = new int[Values.Length * 2];
|
|
Buffer.BlockCopy( Values, 0, array, 0, Size * sizeof(int) );
|
|
Values = array;
|
|
}
|
|
Values[Size++] = item;
|
|
}
|
|
}
|
|
}
|
|
} |