public function __construct(Level $level, Vector3 $start, Vector3 $direction, $yOffset = 0, $maxDistance = 0)
{
$this->level = $level;
$this->maxDistance = (int) $maxDistance;
$this->blockQueue = new \SplFixedArray(3);
$startClone = new Vector3($start->x, $start->y, $start->z);
$startClone->y += $yOffset;
$this->currentDistance = 0;
$mainDirection = 0;
$secondDirection = 0;
$thirdDirection = 0;
$mainPosition = 0;
$secondPosition = 0;
$thirdPosition = 0;
$pos = new Vector3($startClone->x, $startClone->y, $startClone->z);
$startBlock = $this->level->getBlock($pos->floor());
if ($this->getXLength($direction) > $mainDirection) {
$this->mainFace = $this->getXFace($direction);
$mainDirection = $this->getXLength($direction);
$mainPosition = $this->getXPosition($direction, $startClone, $startBlock);
$this->secondFace = $this->getYFace($direction);
$secondDirection = $this->getYLength($direction);
$secondPosition = $this->getYPosition($direction, $startClone, $startBlock);
$this->thirdFace = $this->getZFace($direction);
$thirdDirection = $this->getZLength($direction);
$thirdPosition = $this->getZPosition($direction, $startClone, $startBlock);
}
if ($this->getYLength($direction) > $mainDirection) {
$this->mainFace = $this->getYFace($direction);
$mainDirection = $this->getYLength($direction);
$mainPosition = $this->getYPosition($direction, $startClone, $startBlock);
$this->secondFace = $this->getZFace($direction);
$secondDirection = $this->getZLength($direction);
$secondPosition = $this->getZPosition($direction, $startClone, $startBlock);
$this->thirdFace = $this->getXFace($direction);
$thirdDirection = $this->getXLength($direction);
$thirdPosition = $this->getXPosition($direction, $startClone, $startBlock);
}
if ($this->getZLength($direction) > $mainDirection) {
$this->mainFace = $this->getZFace($direction);
$mainDirection = $this->getZLength($direction);
$mainPosition = $this->getZPosition($direction, $startClone, $startBlock);
$this->secondFace = $this->getXFace($direction);
$secondDirection = $this->getXLength($direction);
$secondPosition = $this->getXPosition($direction, $startClone, $startBlock);
$this->thirdFace = $this->getYFace($direction);
$thirdDirection = $this->getYLength($direction);
$thirdPosition = $this->getYPosition($direction, $startClone, $startBlock);
}
$d = $mainPosition / $mainDirection;
$secondd = $secondPosition - $secondDirection * $d;
$thirdd = $thirdPosition - $thirdDirection * $d;
$this->secondError = floor($secondd * self::$gridSize);
$this->secondStep = round($secondDirection / $mainDirection * self::$gridSize);
$this->thirdError = floor($thirdd * self::$gridSize);
$this->thirdStep = round($thirdDirection / $mainDirection * self::$gridSize);
if ($this->secondError + $this->secondStep <= 0) {
$this->secondError = -$this->secondStep + 1;
}
if ($this->thirdError + $this->thirdStep <= 0) {
$this->thirdError = -$this->thirdStep + 1;
}
$lastBlock = $startBlock->getSide(Vector3::getOppositeSide($this->mainFace));
if ($this->secondError < 0) {
$this->secondError += self::$gridSize;
$lastBlock = $lastBlock->getSide(Vector3::getOppositeSide($this->secondFace));
}
if ($this->thirdError < 0) {
$this->thirdError += self::$gridSize;
$lastBlock = $lastBlock->getSide(Vector3::getOppositeSide($this->thirdFace));
}
$this->secondError -= self::$gridSize;
$this->thirdError -= self::$gridSize;
$this->blockQueue[0] = $lastBlock;
$this->currentBlock = -1;
$this->scan();
$startBlockFound = false;
for ($cnt = $this->currentBlock; $cnt >= 0; --$cnt) {
if ($this->blockEquals($this->blockQueue[$cnt], $startBlock)) {
$this->currentBlock = $cnt;
$startBlockFound = true;
break;
}
}
if (!$startBlockFound) {
throw new \InvalidStateException("Start block missed in BlockIterator");
}
$this->maxDistanceInt = round($maxDistance / (sqrt($mainDirection ** 2 + $secondDirection ** 2 + $thirdDirection ** 2) / $mainDirection));
}