ChunkSelector: Improve algorithm to send chunks in proper circles, instead of squares

this ensures that the edge of loaded terain is always the same distance
away in any direction. This also means that when flying parallel to X or
Z axes, you now have about 12% more chunks directly in front of you,
instead of to your left and right, which gives the impression that
chunks are loading faster (they aren't, they are just being ordered in a
more sensible way).
This commit is contained in:
Dylan K. Taylor 2021-11-06 00:06:08 +00:00
parent 07b1cff306
commit dbf9a33160
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\player; namespace pocketmine\player;
use pocketmine\world\World; use pocketmine\world\World;
use const M_SQRT2;
//TODO: turn this into an interface? //TODO: turn this into an interface?
final class ChunkSelector{ final class ChunkSelector{
@ -33,14 +34,23 @@ final class ChunkSelector{
* @phpstan-return \Generator<int, int, void, void> * @phpstan-return \Generator<int, int, void, void>
*/ */
public function selectChunks(int $radius, int $centerX, int $centerZ) : \Generator{ public function selectChunks(int $radius, int $centerX, int $centerZ) : \Generator{
$radiusSquared = $radius ** 2; for($subRadius = 0; $subRadius < $radius; $subRadius++){
$subRadiusSquared = $subRadius ** 2;
$nextSubRadiusSquared = ($subRadius + 1) ** 2;
$minX = (int) ($subRadius / M_SQRT2);
for($x = 0; $x < $radius; ++$x){ $lastZ = 0;
for($z = 0; $z <= $x; ++$z){
if(($x ** 2 + $z ** 2) > $radiusSquared){ for($x = $subRadius; $x >= $minX; --$x){
break; //skip to next band for($z = $lastZ; $z <= $x; ++$z){
$distanceSquared = ($x ** 2 + $z ** 2);
if($distanceSquared < $subRadiusSquared){
continue;
}elseif($distanceSquared >= $nextSubRadiusSquared){
break; //skip to next X
} }
$lastZ = $z;
//If the chunk is in the radius, others at the same offsets in different quadrants are also guaranteed to be. //If the chunk is in the radius, others at the same offsets in different quadrants are also guaranteed to be.
/* Top right quadrant */ /* Top right quadrant */
@ -66,3 +76,4 @@ final class ChunkSelector{
} }
} }
} }
}