diff --git a/src/pocketmine/level/generator/Generator.php b/src/pocketmine/level/generator/Generator.php index ad588682c..d2a5fbdda 100644 --- a/src/pocketmine/level/generator/Generator.php +++ b/src/pocketmine/level/generator/Generator.php @@ -28,7 +28,6 @@ namespace pocketmine\level\generator; use pocketmine\level\ChunkManager; use pocketmine\level\generator\hell\Nether; -use pocketmine\level\generator\noise\Noise; use pocketmine\level\generator\normal\Normal; use pocketmine\math\Vector3; use pocketmine\utils\Random; @@ -84,159 +83,6 @@ abstract class Generator{ return "unknown"; } - /** - * @param Noise $noise - * @param int $xSize - * @param int $samplingRate - * @param int $x - * @param int $y - * @param int $z - * - * @return \SplFixedArray - */ - public static function getFastNoise1D(Noise $noise, int $xSize, int $samplingRate, int $x, int $y, int $z) : \SplFixedArray{ - if($samplingRate === 0){ - throw new \InvalidArgumentException("samplingRate cannot be 0"); - } - if($xSize % $samplingRate !== 0){ - throw new \InvalidArgumentException("xSize % samplingRate must return 0"); - } - - $noiseArray = new \SplFixedArray($xSize + 1); - - for($xx = 0; $xx <= $xSize; $xx += $samplingRate){ - $noiseArray[$xx] = $noise->noise3D($xx + $x, $y, $z); - } - - for($xx = 0; $xx < $xSize; ++$xx){ - if($xx % $samplingRate !== 0){ - $nx = (int) ($xx / $samplingRate) * $samplingRate; - $noiseArray[$xx] = Noise::linearLerp($xx, $nx, $nx + $samplingRate, $noiseArray[$nx], $noiseArray[$nx + $samplingRate]); - } - } - - return $noiseArray; - } - - /** - * @param Noise $noise - * @param int $xSize - * @param int $zSize - * @param int $samplingRate - * @param int $x - * @param int $y - * @param int $z - * - * @return \SplFixedArray - */ - public static function getFastNoise2D(Noise $noise, int $xSize, int $zSize, int $samplingRate, int $x, int $y, int $z) : \SplFixedArray{ - assert($samplingRate !== 0, new \InvalidArgumentException("samplingRate cannot be 0")); - - assert($xSize % $samplingRate === 0, new \InvalidArgumentException("xSize % samplingRate must return 0")); - assert($zSize % $samplingRate === 0, new \InvalidArgumentException("zSize % samplingRate must return 0")); - - $noiseArray = new \SplFixedArray($xSize + 1); - - for($xx = 0; $xx <= $xSize; $xx += $samplingRate){ - $noiseArray[$xx] = new \SplFixedArray($zSize + 1); - for($zz = 0; $zz <= $zSize; $zz += $samplingRate){ - $noiseArray[$xx][$zz] = $noise->noise3D($x + $xx, $y, $z + $zz); - } - } - - for($xx = 0; $xx < $xSize; ++$xx){ - if($xx % $samplingRate !== 0){ - $noiseArray[$xx] = new \SplFixedArray($zSize + 1); - } - - for($zz = 0; $zz < $zSize; ++$zz){ - if($xx % $samplingRate !== 0 or $zz % $samplingRate !== 0){ - $nx = (int) ($xx / $samplingRate) * $samplingRate; - $nz = (int) ($zz / $samplingRate) * $samplingRate; - $noiseArray[$xx][$zz] = Noise::bilinearLerp( - $xx, $zz, $noiseArray[$nx][$nz], $noiseArray[$nx][$nz + $samplingRate], - $noiseArray[$nx + $samplingRate][$nz], $noiseArray[$nx + $samplingRate][$nz + $samplingRate], - $nx, $nx + $samplingRate, $nz, $nz + $samplingRate - ); - } - } - } - - return $noiseArray; - } - - /** - * @param Noise $noise - * @param int $xSize - * @param int $ySize - * @param int $zSize - * @param int $xSamplingRate - * @param int $ySamplingRate - * @param int $zSamplingRate - * @param int $x - * @param int $y - * @param int $z - * - * @return array - */ - public static function getFastNoise3D(Noise $noise, int $xSize, int $ySize, int $zSize, int $xSamplingRate, int $ySamplingRate, int $zSamplingRate, int $x, int $y, int $z) : array{ - - assert($xSamplingRate !== 0, new \InvalidArgumentException("xSamplingRate cannot be 0")); - assert($zSamplingRate !== 0, new \InvalidArgumentException("zSamplingRate cannot be 0")); - assert($ySamplingRate !== 0, new \InvalidArgumentException("ySamplingRate cannot be 0")); - - assert($xSize % $xSamplingRate === 0, new \InvalidArgumentException("xSize % xSamplingRate must return 0")); - assert($zSize % $zSamplingRate === 0, new \InvalidArgumentException("zSize % zSamplingRate must return 0")); - assert($ySize % $ySamplingRate === 0, new \InvalidArgumentException("ySize % ySamplingRate must return 0")); - - $noiseArray = array_fill(0, $xSize + 1, array_fill(0, $zSize + 1, [])); - - for($xx = 0; $xx <= $xSize; $xx += $xSamplingRate){ - for($zz = 0; $zz <= $zSize; $zz += $zSamplingRate){ - for($yy = 0; $yy <= $ySize; $yy += $ySamplingRate){ - $noiseArray[$xx][$zz][$yy] = $noise->noise3D($x + $xx, $y + $yy, $z + $zz, true); - } - } - } - - for($xx = 0; $xx < $xSize; ++$xx){ - for($zz = 0; $zz < $zSize; ++$zz){ - for($yy = 0; $yy < $ySize; ++$yy){ - if($xx % $xSamplingRate !== 0 or $zz % $zSamplingRate !== 0 or $yy % $ySamplingRate !== 0){ - $nx = (int) ($xx / $xSamplingRate) * $xSamplingRate; - $ny = (int) ($yy / $ySamplingRate) * $ySamplingRate; - $nz = (int) ($zz / $zSamplingRate) * $zSamplingRate; - - $nnx = $nx + $xSamplingRate; - $nny = $ny + $ySamplingRate; - $nnz = $nz + $zSamplingRate; - - $dx1 = (($nnx - $xx) / ($nnx - $nx)); - $dx2 = (($xx - $nx) / ($nnx - $nx)); - $dy1 = (($nny - $yy) / ($nny - $ny)); - $dy2 = (($yy - $ny) / ($nny - $ny)); - - $noiseArray[$xx][$zz][$yy] = (($nnz - $zz) / ($nnz - $nz)) * ( - $dy1 * ( - $dx1 * $noiseArray[$nx][$nz][$ny] + $dx2 * $noiseArray[$nnx][$nz][$ny] - ) + $dy2 * ( - $dx1 * $noiseArray[$nx][$nz][$nny] + $dx2 * $noiseArray[$nnx][$nz][$nny] - ) - ) + (($zz - $nz) / ($nnz - $nz)) * ( - $dy1 * ( - $dx1 * $noiseArray[$nx][$nnz][$ny] + $dx2 * $noiseArray[$nnx][$nnz][$ny] - ) + $dy2 * ( - $dx1 * $noiseArray[$nx][$nnz][$nny] + $dx2 * $noiseArray[$nnx][$nnz][$nny] - ) - ); - } - } - } - } - - return $noiseArray; - } - abstract public function __construct(array $settings = []); abstract public function init(ChunkManager $level, Random $random); diff --git a/src/pocketmine/level/generator/hell/Nether.php b/src/pocketmine/level/generator/hell/Nether.php index e5e9c6b89..51edaf2d1 100644 --- a/src/pocketmine/level/generator/hell/Nether.php +++ b/src/pocketmine/level/generator/hell/Nether.php @@ -118,7 +118,7 @@ class Nether extends Generator{ public function generateChunk(int $chunkX, int $chunkZ){ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed()); - $noise = Generator::getFastNoise3D($this->noiseBase, 16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); + $noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); $chunk = $this->level->getChunk($chunkX, $chunkZ); diff --git a/src/pocketmine/level/generator/noise/Noise.php b/src/pocketmine/level/generator/noise/Noise.php index 481d6512d..b16b05aab 100644 --- a/src/pocketmine/level/generator/noise/Noise.php +++ b/src/pocketmine/level/generator/noise/Noise.php @@ -143,6 +143,157 @@ abstract class Noise{ return $result; } + + /** + * @param int $xSize + * @param int $samplingRate + * @param int $x + * @param int $y + * @param int $z + * + * @return \SplFixedArray + */ + public function getFastNoise1D(int $xSize, int $samplingRate, int $x, int $y, int $z) : \SplFixedArray{ + if($samplingRate === 0){ + throw new \InvalidArgumentException("samplingRate cannot be 0"); + } + if($xSize % $samplingRate !== 0){ + throw new \InvalidArgumentException("xSize % samplingRate must return 0"); + } + + $noiseArray = new \SplFixedArray($xSize + 1); + + for($xx = 0; $xx <= $xSize; $xx += $samplingRate){ + $noiseArray[$xx] = $this->noise3D($xx + $x, $y, $z); + } + + for($xx = 0; $xx < $xSize; ++$xx){ + if($xx % $samplingRate !== 0){ + $nx = (int) ($xx / $samplingRate) * $samplingRate; + $noiseArray[$xx] = self::linearLerp($xx, $nx, $nx + $samplingRate, $noiseArray[$nx], $noiseArray[$nx + $samplingRate]); + } + } + + return $noiseArray; + } + + /** + * @param int $xSize + * @param int $zSize + * @param int $samplingRate + * @param int $x + * @param int $y + * @param int $z + * + * @return \SplFixedArray + */ + public function getFastNoise2D(int $xSize, int $zSize, int $samplingRate, int $x, int $y, int $z) : \SplFixedArray{ + assert($samplingRate !== 0, new \InvalidArgumentException("samplingRate cannot be 0")); + + assert($xSize % $samplingRate === 0, new \InvalidArgumentException("xSize % samplingRate must return 0")); + assert($zSize % $samplingRate === 0, new \InvalidArgumentException("zSize % samplingRate must return 0")); + + $noiseArray = new \SplFixedArray($xSize + 1); + + for($xx = 0; $xx <= $xSize; $xx += $samplingRate){ + $noiseArray[$xx] = new \SplFixedArray($zSize + 1); + for($zz = 0; $zz <= $zSize; $zz += $samplingRate){ + $noiseArray[$xx][$zz] = $this->noise3D($x + $xx, $y, $z + $zz); + } + } + + for($xx = 0; $xx < $xSize; ++$xx){ + if($xx % $samplingRate !== 0){ + $noiseArray[$xx] = new \SplFixedArray($zSize + 1); + } + + for($zz = 0; $zz < $zSize; ++$zz){ + if($xx % $samplingRate !== 0 or $zz % $samplingRate !== 0){ + $nx = (int) ($xx / $samplingRate) * $samplingRate; + $nz = (int) ($zz / $samplingRate) * $samplingRate; + $noiseArray[$xx][$zz] = Noise::bilinearLerp( + $xx, $zz, $noiseArray[$nx][$nz], $noiseArray[$nx][$nz + $samplingRate], + $noiseArray[$nx + $samplingRate][$nz], $noiseArray[$nx + $samplingRate][$nz + $samplingRate], + $nx, $nx + $samplingRate, $nz, $nz + $samplingRate + ); + } + } + } + + return $noiseArray; + } + + /** + * @param int $xSize + * @param int $ySize + * @param int $zSize + * @param int $xSamplingRate + * @param int $ySamplingRate + * @param int $zSamplingRate + * @param int $x + * @param int $y + * @param int $z + * + * @return array + */ + public function getFastNoise3D(int $xSize, int $ySize, int $zSize, int $xSamplingRate, int $ySamplingRate, int $zSamplingRate, int $x, int $y, int $z) : array{ + + assert($xSamplingRate !== 0, new \InvalidArgumentException("xSamplingRate cannot be 0")); + assert($zSamplingRate !== 0, new \InvalidArgumentException("zSamplingRate cannot be 0")); + assert($ySamplingRate !== 0, new \InvalidArgumentException("ySamplingRate cannot be 0")); + + assert($xSize % $xSamplingRate === 0, new \InvalidArgumentException("xSize % xSamplingRate must return 0")); + assert($zSize % $zSamplingRate === 0, new \InvalidArgumentException("zSize % zSamplingRate must return 0")); + assert($ySize % $ySamplingRate === 0, new \InvalidArgumentException("ySize % ySamplingRate must return 0")); + + $noiseArray = array_fill(0, $xSize + 1, array_fill(0, $zSize + 1, [])); + + for($xx = 0; $xx <= $xSize; $xx += $xSamplingRate){ + for($zz = 0; $zz <= $zSize; $zz += $zSamplingRate){ + for($yy = 0; $yy <= $ySize; $yy += $ySamplingRate){ + $noiseArray[$xx][$zz][$yy] = $this->noise3D($x + $xx, $y + $yy, $z + $zz, true); + } + } + } + + for($xx = 0; $xx < $xSize; ++$xx){ + for($zz = 0; $zz < $zSize; ++$zz){ + for($yy = 0; $yy < $ySize; ++$yy){ + if($xx % $xSamplingRate !== 0 or $zz % $zSamplingRate !== 0 or $yy % $ySamplingRate !== 0){ + $nx = (int) ($xx / $xSamplingRate) * $xSamplingRate; + $ny = (int) ($yy / $ySamplingRate) * $ySamplingRate; + $nz = (int) ($zz / $zSamplingRate) * $zSamplingRate; + + $nnx = $nx + $xSamplingRate; + $nny = $ny + $ySamplingRate; + $nnz = $nz + $zSamplingRate; + + $dx1 = (($nnx - $xx) / ($nnx - $nx)); + $dx2 = (($xx - $nx) / ($nnx - $nx)); + $dy1 = (($nny - $yy) / ($nny - $ny)); + $dy2 = (($yy - $ny) / ($nny - $ny)); + + $noiseArray[$xx][$zz][$yy] = (($nnz - $zz) / ($nnz - $nz)) * ( + $dy1 * ( + $dx1 * $noiseArray[$nx][$nz][$ny] + $dx2 * $noiseArray[$nnx][$nz][$ny] + ) + $dy2 * ( + $dx1 * $noiseArray[$nx][$nz][$nny] + $dx2 * $noiseArray[$nnx][$nz][$nny] + ) + ) + (($zz - $nz) / ($nnz - $nz)) * ( + $dy1 * ( + $dx1 * $noiseArray[$nx][$nnz][$ny] + $dx2 * $noiseArray[$nnx][$nnz][$ny] + ) + $dy2 * ( + $dx1 * $noiseArray[$nx][$nnz][$nny] + $dx2 * $noiseArray[$nnx][$nnz][$nny] + ) + ); + } + } + } + } + + return $noiseArray; + } + public function setOffset($x, $y, $z){ $this->offsetX = $x; $this->offsetY = $y; diff --git a/src/pocketmine/level/generator/normal/Normal.php b/src/pocketmine/level/generator/normal/Normal.php index 6605084eb..068c9a680 100644 --- a/src/pocketmine/level/generator/normal/Normal.php +++ b/src/pocketmine/level/generator/normal/Normal.php @@ -187,7 +187,7 @@ class Normal extends Generator{ public function generateChunk(int $chunkX, int $chunkZ){ $this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed()); - $noise = Generator::getFastNoise3D($this->noiseBase, 16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); + $noise = $this->noiseBase->getFastNoise3D(16, 128, 16, 4, 8, 4, $chunkX * 16, 0, $chunkZ * 16); $chunk = $this->level->getChunk($chunkX, $chunkZ);