Extract a Gaussian unit from Normal generator

This commit is contained in:
Dylan K. Taylor 2020-06-28 18:45:11 +01:00
parent 78c270a96e
commit db8e094d11
3 changed files with 63 additions and 26 deletions

View File

@ -0,0 +1,51 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\world\generator;
use function exp;
final class Gaussian{
/** @var int */
public $smoothSize;
/** @var float[][] */
public $kernel = [];
public function __construct(int $smoothSize){
$this->smoothSize = $smoothSize;
$bellSize = 1 / $this->smoothSize;
$bellHeight = 2 * $this->smoothSize;
for($sx = -$this->smoothSize; $sx <= $this->smoothSize; ++$sx){
$this->kernel[$sx + $this->smoothSize] = [];
for($sz = -$this->smoothSize; $sz <= $this->smoothSize; ++$sz){
$bx = $bellSize * $sx;
$bz = $bellSize * $sz;
$this->kernel[$sx + $this->smoothSize][$sz + $this->smoothSize] = $bellHeight * exp(-($bx * $bx + $bz * $bz) / 2);
}
}
}
}

View File

@ -27,6 +27,7 @@ use pocketmine\block\VanillaBlocks;
use pocketmine\world\biome\Biome;
use pocketmine\world\ChunkManager;
use pocketmine\world\generator\biome\BiomeSelector;
use pocketmine\world\generator\Gaussian;
use pocketmine\world\generator\Generator;
use pocketmine\world\generator\InvalidGeneratorOptionsException;
use pocketmine\world\generator\noise\Simplex;
@ -35,7 +36,6 @@ use pocketmine\world\generator\populator\GroundCover;
use pocketmine\world\generator\populator\Ore;
use pocketmine\world\generator\populator\Populator;
use pocketmine\world\World;
use function exp;
class Normal extends Generator{
@ -52,10 +52,8 @@ class Normal extends Generator{
/** @var BiomeSelector */
private $selector;
/** @var float[][]|null */
/** @var Gaussian|null */
private static $GAUSSIAN_KERNEL = null;
/** @var int */
private static $SMOOTH_SIZE = 2;
/**
* @param mixed[] $options
@ -66,7 +64,7 @@ class Normal extends Generator{
public function __construct(ChunkManager $world, int $seed, array $options = []){
parent::__construct($world, $seed, $options);
if(self::$GAUSSIAN_KERNEL === null){
self::generateKernel();
self::$GAUSSIAN_KERNEL = new Gaussian(2);
}
$this->noiseBase = new Simplex($this->random, 4, 1 / 4, 1 / 32);
@ -132,23 +130,6 @@ class Normal extends Generator{
$this->populators[] = $ores;
}
private static function generateKernel() : void{
self::$GAUSSIAN_KERNEL = [];
$bellSize = 1 / self::$SMOOTH_SIZE;
$bellHeight = 2 * self::$SMOOTH_SIZE;
for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){
self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE] = [];
for($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz){
$bx = $bellSize * $sx;
$bz = $bellSize * $sz;
self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE] = $bellHeight * exp(-($bx * $bx + $bz * $bz) / 2);
}
}
}
private function pickBiome(int $x, int $z) : Biome{
$hash = $x * 2345803 ^ $z * 9236449 ^ $this->seed;
$hash *= $hash + 223;
@ -186,10 +167,10 @@ class Normal extends Generator{
$biome = $this->pickBiome($chunkX * 16 + $x, $chunkZ * 16 + $z);
$chunk->setBiomeId($x, $z, $biome->getId());
for($sx = -self::$SMOOTH_SIZE; $sx <= self::$SMOOTH_SIZE; ++$sx){
for($sz = -self::$SMOOTH_SIZE; $sz <= self::$SMOOTH_SIZE; ++$sz){
for($sx = -self::$GAUSSIAN_KERNEL->smoothSize; $sx <= self::$GAUSSIAN_KERNEL->smoothSize; ++$sx){
for($sz = -self::$GAUSSIAN_KERNEL->smoothSize; $sz <= self::$GAUSSIAN_KERNEL->smoothSize; ++$sz){
$weight = self::$GAUSSIAN_KERNEL[$sx + self::$SMOOTH_SIZE][$sz + self::$SMOOTH_SIZE];
$weight = self::$GAUSSIAN_KERNEL->kernel[$sx + self::$GAUSSIAN_KERNEL->smoothSize][$sz + self::$GAUSSIAN_KERNEL->smoothSize];
if($sx === 0 and $sz === 0){
$adjacent = $biome;

View File

@ -1041,7 +1041,12 @@ parameters:
path: ../../../src/world/generator/normal/Normal.php
-
message: "#^Offset int does not exist on array\\<array\\<float\\>\\>\\|null\\.$#"
message: "#^Cannot access property \\$smoothSize on pocketmine\\\\world\\\\generator\\\\Gaussian\\|null\\.$#"
count: 6
path: ../../../src/world/generator/normal/Normal.php
-
message: "#^Cannot access property \\$kernel on pocketmine\\\\world\\\\generator\\\\Gaussian\\|null\\.$#"
count: 1
path: ../../../src/world/generator/normal/Normal.php