mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-08 02:42:58 +00:00
Implemented sky light generation-time population and updating, obsolete and close #160
This commit is contained in:
@ -119,7 +119,7 @@ class Chunk{
|
||||
$this->heightMap = $heightMap;
|
||||
}else{
|
||||
assert(count($heightMap) === 0, "Wrong HeightMap value count, expected 256, got " . count($heightMap));
|
||||
$val = ($this->height * 16) - 1;
|
||||
$val = ($this->height * 16);
|
||||
$this->heightMap = array_fill(0, 256, $val);
|
||||
}
|
||||
|
||||
@ -344,22 +344,13 @@ class Chunk{
|
||||
*
|
||||
* @param int $x 0-15
|
||||
* @param int $z 0-15
|
||||
* @param bool $useHeightMap whether to use pre-calculated heightmap values or not
|
||||
*
|
||||
* @return int
|
||||
* @return int 0-255, or -1 if there are no blocks in the column
|
||||
*/
|
||||
public function getHighestBlockAt(int $x, int $z, bool $useHeightMap = true) : int{
|
||||
if($useHeightMap){
|
||||
$height = $this->getHeightMap($x, $z);
|
||||
|
||||
if($height !== 0 and $height !== 255){
|
||||
return $height;
|
||||
}
|
||||
}
|
||||
|
||||
public function getHighestBlockAt(int $x, int $z) : int{
|
||||
$index = $this->getHighestSubChunkIndex();
|
||||
if($index < 0){
|
||||
return 0;
|
||||
if($index === -1){
|
||||
return -1;
|
||||
}
|
||||
|
||||
$height = $index << 4;
|
||||
@ -367,12 +358,11 @@ class Chunk{
|
||||
for($y = $index; $y >= 0; --$y){
|
||||
$height = $this->getSubChunk($y)->getHighestBlockAt($x, $z) | ($y << 4);
|
||||
if($height !== -1){
|
||||
break;
|
||||
return $height;
|
||||
}
|
||||
}
|
||||
|
||||
$this->setHeightMap($x, $z, $height);
|
||||
return $height;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -403,15 +393,37 @@ class Chunk{
|
||||
public function recalculateHeightMap(){
|
||||
for($z = 0; $z < 16; ++$z){
|
||||
for($x = 0; $x < 16; ++$x){
|
||||
$this->setHeightMap($x, $z, $this->getHighestBlockAt($x, $z, false));
|
||||
$this->recalculateHeightMapColumn($x, $z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs basic sky light population on the chunk.
|
||||
* Recalculates the heightmap for the block column at the specified X/Z chunk coordinates
|
||||
*
|
||||
* TODO: rewrite this, use block light filters and diffusion, actual proper sky light population
|
||||
* @param int $x 0-15
|
||||
* @param int $z 0-15
|
||||
*
|
||||
* @return int New calculated heightmap value (0-256 inclusive)
|
||||
*/
|
||||
public function recalculateHeightMapColumn(int $x, int $z) : int{
|
||||
$max = $this->getHighestBlockAt($x, $z);
|
||||
for($y = $max; $y >= 0; --$y){
|
||||
if(Block::$lightFilter[$id = $this->getBlockId($x, $y, $z)] > 1 or Block::$diffusesSkyLight[$id]){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->setHeightMap($x, $z, $y + 1);
|
||||
return $y + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs basic sky light population on the chunk.
|
||||
* This does not cater for adjacent sky light, this performs direct sky light population only. This may cause some strange visual artifacts
|
||||
* if the chunk is light-populated after being terrain-populated.
|
||||
*
|
||||
* TODO: fast adjacent light spread
|
||||
*/
|
||||
public function populateSkyLight(){
|
||||
for($x = 0; $x < 16; ++$x){
|
||||
@ -420,19 +432,19 @@ class Chunk{
|
||||
|
||||
$y = ($this->getHighestSubChunkIndex() + 1) << 4;
|
||||
|
||||
//TODO: replace a section of the array with a string in one call to improve performance
|
||||
|
||||
for(; $y > $heightMap; --$y){
|
||||
for(; $y >= $heightMap; --$y){
|
||||
$this->setBlockSkyLight($x, $y, $z, 15);
|
||||
}
|
||||
|
||||
for(; $y > 0 and $this->getBlockId($x, $y, $z) === Block::AIR; --$y){
|
||||
$this->setBlockSkyLight($x, $y, $z, 15);
|
||||
}
|
||||
$this->setHeightMap($x, $z, $y);
|
||||
|
||||
$light = 15;
|
||||
for(; $y > 0; --$y){
|
||||
$this->setBlockSkyLight($x, $y, $z, 0);
|
||||
if($light > 0){
|
||||
$light -= Block::$lightFilter[$this->getBlockId($x, $y, $z)];
|
||||
if($light < 0){
|
||||
$light = 0;
|
||||
}
|
||||
}
|
||||
$this->setBlockSkyLight($x, $y, $z, $light);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -920,9 +932,9 @@ class Chunk{
|
||||
}
|
||||
$stream->putByte($count);
|
||||
$stream->put($subChunks);
|
||||
$stream->put(pack("C*", ...$this->heightMap) .
|
||||
$stream->put(pack("v*", ...$this->heightMap) .
|
||||
$this->biomeIds .
|
||||
chr(($this->lightPopulated ? 1 << 2 : 0) | ($this->terrainPopulated ? 1 << 1 : 0) | ($this->terrainGenerated ? 1 : 0)));
|
||||
chr(($this->lightPopulated ? 4 : 0) | ($this->terrainPopulated ? 2 : 0) | ($this->terrainGenerated ? 1 : 0)));
|
||||
return $stream->getBuffer();
|
||||
}
|
||||
|
||||
@ -944,7 +956,7 @@ class Chunk{
|
||||
for($y = 0; $y < $count; ++$y){
|
||||
$subChunks[$stream->getByte()] = SubChunk::fastDeserialize($stream->get(10240));
|
||||
}
|
||||
$heightMap = array_values(unpack("C*", $stream->get(256)));
|
||||
$heightMap = array_values(unpack("v*", $stream->get(512)));
|
||||
$biomeIds = $stream->get(256);
|
||||
|
||||
$chunk = new Chunk($x, $z, $subChunks, [], [], $biomeIds, $heightMap);
|
||||
|
Reference in New Issue
Block a user