mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-15 18:29:46 +00:00
Drastically improved performance of basic chunk sky-light population
back 2 commits: 53ms per chunk back 1 commit: 27ms per chunk this commit: 3ms per chunk (on my machine, of course)
This commit is contained in:
parent
728851594b
commit
30c5487f94
@ -313,6 +313,17 @@ class Chunk{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $level
|
||||
*/
|
||||
public function setAllBlockSkyLight(int $level){
|
||||
$char = chr(($level & 0x0f) | ($level << 4));
|
||||
$data = str_repeat($char, 2048);
|
||||
for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){
|
||||
$this->getSubChunk($y, true)->setBlockSkyLightArray($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block light level at the specified chunk block coordinates
|
||||
*
|
||||
@ -340,6 +351,17 @@ class Chunk{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $level
|
||||
*/
|
||||
public function setAllBlockLight(int $level){
|
||||
$char = chr(($level & 0x0f) | ($level << 4));
|
||||
$data = str_repeat($char, 2048);
|
||||
for($y = $this->getHighestSubChunkIndex(); $y >= 0; --$y){
|
||||
$this->getSubChunk($y, true)->setBlockLightArray($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Y coordinate of the highest non-air block at the specified X/Z chunk block coordinates
|
||||
*
|
||||
@ -366,6 +388,10 @@ class Chunk{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getMaxY() : int{
|
||||
return ($this->getHighestSubChunkIndex() << 4) | 0x0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the heightmap value at the specified X/Z chunk block coordinates
|
||||
*
|
||||
@ -427,7 +453,10 @@ class Chunk{
|
||||
* TODO: fast adjacent light spread
|
||||
*/
|
||||
public function populateSkyLight(){
|
||||
$maxY = ($this->getHighestSubChunkIndex() + 1) << 4;
|
||||
$maxY = $this->getMaxY();
|
||||
|
||||
$this->setAllBlockSkyLight(0);
|
||||
|
||||
for($x = 0; $x < 16; ++$x){
|
||||
for($z = 0; $z < 16; ++$z){
|
||||
$heightMap = $this->getHeightMap($x, $z);
|
||||
@ -437,11 +466,11 @@ class Chunk{
|
||||
}
|
||||
|
||||
$light = 15;
|
||||
for(; $y > 0; --$y){
|
||||
for(; $y >= 0; --$y){
|
||||
if($light > 0){
|
||||
$light -= Block::$lightFilter[$this->getBlockId($x, $y, $z)];
|
||||
if($light < 0){
|
||||
$light = 0;
|
||||
if($light <= 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->setBlockSkyLight($x, $y, $z, $light);
|
||||
|
@ -101,10 +101,18 @@ class EmptySubChunk implements SubChunkInterface{
|
||||
return str_repeat("\x00", 2048);
|
||||
}
|
||||
|
||||
public function setBlockLightArray(string $data){
|
||||
|
||||
}
|
||||
|
||||
public function getBlockSkyLightArray() : string{
|
||||
return str_repeat("\xff", 2048);
|
||||
}
|
||||
|
||||
public function setBlockSkyLightArray(string $data){
|
||||
|
||||
}
|
||||
|
||||
public function networkSerialize() : string{
|
||||
return "\x00" . str_repeat("\x00", 10240);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ class SubChunk implements SubChunkInterface{
|
||||
protected $blockLight;
|
||||
protected $skyLight;
|
||||
|
||||
private static function assignData(&$target, $data, $length, $value = "\x00"){
|
||||
private static function assignData(&$target, string $data, int $length, string $value = "\x00"){
|
||||
if(strlen($data) !== $length){
|
||||
assert($data === "", "Invalid non-zero length given, expected $length, got " . strlen($data));
|
||||
$target = str_repeat($value, $length);
|
||||
@ -203,11 +203,21 @@ class SubChunk implements SubChunkInterface{
|
||||
return $this->skyLight;
|
||||
}
|
||||
|
||||
public function setBlockSkyLightArray(string $data){
|
||||
assert(strlen($data) === 2048, "Wrong length of skylight array, expecting 2048 bytes, got " . strlen($data));
|
||||
$this->skyLight = $data;
|
||||
}
|
||||
|
||||
public function getBlockLightArray() : string{
|
||||
assert(strlen($this->blockLight) === 2048, "Wrong length of light array, expecting 2048 bytes, got " . strlen($this->blockLight));
|
||||
return $this->blockLight;
|
||||
}
|
||||
|
||||
public function setBlockLightArray(string $data){
|
||||
assert(strlen($data) === 2048, "Wrong length of light array, expecting 2048 bytes, got " . strlen($data));
|
||||
$this->blockLight = $data;
|
||||
}
|
||||
|
||||
public function networkSerialize() : string{
|
||||
// storage version, ids, data, skylight, blocklight
|
||||
return "\x00" . $this->ids . $this->data . $this->skyLight . $this->blockLight;
|
||||
|
@ -182,11 +182,21 @@ interface SubChunkInterface{
|
||||
*/
|
||||
public function getBlockSkyLightArray() : string;
|
||||
|
||||
/**
|
||||
* @param string $data
|
||||
*/
|
||||
public function setBlockSkyLightArray(string $data);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBlockLightArray() : string;
|
||||
|
||||
/**
|
||||
* @param string $data
|
||||
*/
|
||||
public function setBlockLightArray(string $data);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user