Improved light spread algorithm even more

This commit is contained in:
Shoghi Cervantes 2014-11-29 11:27:22 +01:00
parent 329ca62465
commit 66ba327e62

View File

@ -926,7 +926,6 @@ class Level implements ChunkManager, Metadatable{
} }
public function updateAllLight(Vector3 $pos){ public function updateAllLight(Vector3 $pos){
$start = microtime(true);
$this->updateBlockSkyLight($pos->x, $pos->y, $pos->z); $this->updateBlockSkyLight($pos->x, $pos->y, $pos->z);
$this->updateBlockLight($pos->x, $pos->y, $pos->z); $this->updateBlockLight($pos->x, $pos->y, $pos->z);
} }
@ -946,13 +945,14 @@ class Level implements ChunkManager, Metadatable{
if($oldLevel !== $newLevel){ if($oldLevel !== $newLevel){
$this->setBlockLightAt($x, $y, $z, $newLevel); $this->setBlockLightAt($x, $y, $z, $newLevel);
$visited["$x:$y:$z"] = true;
$lightPropagationQueue->enqueue(new Vector3($x, $y, $z));
}
if($newLevel < $oldLevel){ if($newLevel < $oldLevel){
$removalVisited["$x:$y:$z"] = true; $removalVisited["$x:$y:$z"] = true;
$lightRemovalQueue->enqueue([new Vector3($x, $y, $z), $oldLevel]); $lightRemovalQueue->enqueue([new Vector3($x, $y, $z), $oldLevel]);
}else{
$visited["$x:$y:$z"] = true;
$lightPropagationQueue->enqueue(new Vector3($x, $y, $z));
}
} }
while(!$lightRemovalQueue->isEmpty()){ while(!$lightRemovalQueue->isEmpty()){
@ -973,8 +973,11 @@ class Level implements ChunkManager, Metadatable{
/** @var Vector3 $node */ /** @var Vector3 $node */
$node = $lightPropagationQueue->dequeue(); $node = $lightPropagationQueue->dequeue();
$lightLevel = $this->getBlockLightAt($node->x, $node->y, $node->z); $blockId = $this->getBlockIdAt($node->x, $node->y, $node->z);
$decrease = (Block::$solid[$blockId] and !Block::$transparent[$blockId]) ? 15 : 1;
$lightLevel = $this->getBlockLightAt($node->x, $node->y, $node->z) - $decrease;
if($lightLevel >= 1){
$this->computeSpreadBlockLight($node->x - 1, $node->y, $node->z, $lightLevel, $lightPropagationQueue, $visited); $this->computeSpreadBlockLight($node->x - 1, $node->y, $node->z, $lightLevel, $lightPropagationQueue, $visited);
$this->computeSpreadBlockLight($node->x + 1, $node->y, $node->z, $lightLevel, $lightPropagationQueue, $visited); $this->computeSpreadBlockLight($node->x + 1, $node->y, $node->z, $lightLevel, $lightPropagationQueue, $visited);
$this->computeSpreadBlockLight($node->x, $node->y - 1, $node->z, $lightLevel, $lightPropagationQueue, $visited); $this->computeSpreadBlockLight($node->x, $node->y - 1, $node->z, $lightLevel, $lightPropagationQueue, $visited);
@ -983,6 +986,7 @@ class Level implements ChunkManager, Metadatable{
$this->computeSpreadBlockLight($node->x, $node->y, $node->z + 1, $lightLevel, $lightPropagationQueue, $visited); $this->computeSpreadBlockLight($node->x, $node->y, $node->z + 1, $lightLevel, $lightPropagationQueue, $visited);
} }
} }
}
private function computeRemoveBlockLight($x, $y, $z, $currentLight, \SplQueue $queue, \SplQueue $spreadQueue, array &$visited, array &$spreadVisited){ private function computeRemoveBlockLight($x, $y, $z, $currentLight, \SplQueue $queue, \SplQueue $spreadQueue, array &$visited, array &$spreadVisited){
$current = $this->getBlockLightAt($x, $y, $z); $current = $this->getBlockLightAt($x, $y, $z);
@ -992,8 +996,10 @@ class Level implements ChunkManager, Metadatable{
if(!isset($visited[$index = "$x:$y:$z"])){ if(!isset($visited[$index = "$x:$y:$z"])){
$visited[$index] = true; $visited[$index] = true;
if($current > 1){
$queue->enqueue([new Vector3($x, $y, $z), $current]); $queue->enqueue([new Vector3($x, $y, $z), $current]);
} }
}
}elseif($current >= $currentLight){ }elseif($current >= $currentLight){
if(!isset($spreadVisited[$index = "$x:$y:$z"])){ if(!isset($spreadVisited[$index = "$x:$y:$z"])){
$spreadVisited[$index] = true; $spreadVisited[$index] = true;
@ -1003,19 +1009,19 @@ class Level implements ChunkManager, Metadatable{
} }
private function computeSpreadBlockLight($x, $y, $z, $currentLight, \SplQueue $queue, array &$visited){ private function computeSpreadBlockLight($x, $y, $z, $currentLight, \SplQueue $queue, array &$visited){
$blockId = $this->getBlockIdAt($x, $y, $z);
$decrease = (Block::$solid[$blockId] and !Block::$transparent[$blockId]) ? 15 : 1;
$current = $this->getBlockLightAt($x, $y, $z); $current = $this->getBlockLightAt($x, $y, $z);
if($decrease < 15 and ($current + 2) <= $currentLight){ if($current < $currentLight){
$this->setBlockLightAt($x, $y, $z, $currentLight - 1); $this->setBlockLightAt($x, $y, $z, $currentLight);
if(!isset($visited[$index = "$x:$y:$z"])){ if(!isset($visited[$index = "$x:$y:$z"])){
$visited[$index] = true; $visited[$index] = true;
if($currentLight > 1){
$queue->enqueue(new Vector3($x, $y, $z)); $queue->enqueue(new Vector3($x, $y, $z));
} }
} }
} }
}
/** /**
* Sets on Vector3 the data from a Block object, * Sets on Vector3 the data from a Block object,