22declare(strict_types=1);
38 public function __construct(
float $minX,
float $minY,
float $minZ,
float $maxX,
float $maxY,
float $maxZ){
40 throw new \InvalidArgumentException(
"minX $minX is larger than maxX $maxX");
43 throw new \InvalidArgumentException(
"minY $minY is larger than maxY $maxY");
46 throw new \InvalidArgumentException(
"minZ $minZ is larger than maxZ $maxZ");
87 return new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ);
95 public function expand(
float $x,
float $y,
float $z){
110 return (clone $this)->expand($x, $y, $z);
133 return (clone $this)->offset($x, $y, $z);
144 [$offsetX, $offsetY, $offsetZ] =
Facing::OFFSET[$face] ?? throw new \InvalidArgumentException(
"Invalid Facing $face");
146 return $this->offset($offsetX * $distance, $offsetY * $distance, $offsetZ * $distance);
153 return (clone $this)->offsetTowards($face, $distance);
176 return (clone $this)->contract($x, $y, $z);
189 Facing::DOWN => $this->minY -= $distance,
190 Facing::UP => $this->maxY += $distance,
191 Facing::NORTH => $this->minZ -= $distance,
192 Facing::SOUTH => $this->maxZ += $distance,
193 Facing::WEST => $this->minX -= $distance,
194 Facing::EAST => $this->maxX += $distance,
195 default =>
throw new \InvalidArgumentException(
"Invalid face $face"),
208 return (clone $this)->extend($face, $distance);
221 return $this->extend($face, -$distance);
231 return $this->extendedCopy($face, -$distance);
244 if($axis ===
Axis::Y){
245 $this->minY -= $distance;
246 $this->maxY += $distance;
247 }elseif($axis === Axis::Z){
248 $this->minZ -= $distance;
249 $this->maxZ += $distance;
250 }elseif($axis === Axis::X){
251 $this->minX -= $distance;
252 $this->maxX += $distance;
254 throw new \InvalidArgumentException(
"Invalid axis $axis");
266 return (clone $this)->stretch($axis, $distance);
277 return $this->stretch($axis, -$distance);
287 return $this->stretchedCopy($axis, -$distance);
290 public function calculateXOffset(
AxisAlignedBB $bb,
float $x) : float{
291 if($bb->maxY <= $this->minY or $bb->minY >= $this->maxY){
294 if($bb->maxZ <= $this->minZ or $bb->minZ >= $this->maxZ){
297 if($x > 0 and $bb->maxX <= $this->minX){
298 $x1 = $this->minX - $bb->maxX;
302 }elseif($x < 0 and $bb->minX >= $this->maxX){
303 $x2 = $this->maxX - $bb->minX;
312 public function calculateYOffset(AxisAlignedBB $bb,
float $y) : float{
313 if($bb->maxX <= $this->minX or $bb->minX >= $this->maxX){
316 if($bb->maxZ <= $this->minZ or $bb->minZ >= $this->maxZ){
319 if($y > 0 and $bb->maxY <= $this->minY){
320 $y1 = $this->minY - $bb->maxY;
324 }elseif($y < 0 and $bb->minY >= $this->maxY){
325 $y2 = $this->maxY - $bb->minY;
334 public function calculateZOffset(AxisAlignedBB $bb,
float $z) : float{
335 if($bb->maxX <= $this->minX or $bb->minX >= $this->maxX){
338 if($bb->maxY <= $this->minY or $bb->minY >= $this->maxY){
341 if($z > 0 and $bb->maxZ <= $this->minZ){
342 $z1 = $this->minZ - $bb->maxZ;
346 }elseif($z < 0 and $bb->minZ >= $this->maxZ){
347 $z2 = $this->maxZ - $bb->minZ;
360 if($bb->maxX - $this->minX > $epsilon and $this->maxX - $bb->minX > $epsilon){
361 if($bb->maxY - $this->minY > $epsilon and $this->maxY - $bb->minY > $epsilon){
362 return $bb->maxZ - $this->minZ > $epsilon and $this->maxZ - $bb->minZ > $epsilon;
373 if($vector->x <= $this->minX or $vector->x >= $this->maxX){
376 if($vector->y <= $this->minY or $vector->y >= $this->maxY){
380 return $vector->z > $this->minZ and $vector->z < $this->maxZ;
387 return ($this->maxX - $this->minX + $this->maxY - $this->minY + $this->maxZ - $this->minZ) / 3;
390 public function getXLength() : float{ return $this->maxX - $this->minX; }
392 public function getYLength() : float{ return $this->maxY - $this->minY; }
394 public function getZLength() : float{ return $this->maxZ - $this->minZ; }
396 public function isCube(
float $epsilon = 0.000001) : bool{
397 [$xLen, $yLen, $zLen] = [$this->getXLength(), $this->getYLength(), $this->getZLength()];
398 return abs($xLen - $yLen) < $epsilon && abs($yLen - $zLen) < $epsilon;
405 return ($this->maxX - $this->minX) * ($this->maxY - $this->minY) * ($this->maxZ - $this->minZ);
412 return $vector->y >= $this->minY and $vector->y <= $this->maxY and $vector->z >= $this->minZ and $vector->z <= $this->maxZ;
419 return $vector->x >= $this->minX and $vector->x <= $this->maxX and $vector->z >= $this->minZ and $vector->z <= $this->maxZ;
426 return $vector->x >= $this->minX and $vector->x <= $this->maxX and $vector->y >= $this->minY and $vector->y <= $this->maxY;
435 $v1 = $pos1->getIntermediateWithXValue($pos2, $this->minX);
442 if($v1 !==
null and !$this->isVectorInYZ($v1)){
446 if($v2 !==
null and !$this->isVectorInYZ($v2)){
450 if($v3 !==
null and !$this->isVectorInXZ($v3)){
454 if($v4 !==
null and !$this->isVectorInXZ($v4)){
458 if($v5 !==
null and !$this->isVectorInXY($v5)){
462 if($v6 !==
null and !$this->isVectorInXY($v6)){
467 $distance = PHP_INT_MAX;
475 Facing::NORTH => $v5,
478 if($v !==
null and ($d = $pos1->distanceSquared($v)) < $distance){
485 if($vector ===
null){
489 return new RayTraceResult($this, $face, $vector);
492 public function __toString() : string{
493 return
"AxisAlignedBB({$this->minX}, {$this->minY}, {$this->minZ}, {$this->maxX}, {$this->maxY}, {$this->maxZ})";
isVectorInside(Vector3 $vector)
extend(int $face, float $distance)
squash(int $axis, float $distance)
squashedCopy(int $axis, float $distance)
trimmedCopy(int $face, float $distance)
isVectorInXZ(Vector3 $vector)
offset(float $x, float $y, float $z)
extendedCopy(int $face, float $distance)
intersectsWith(AxisAlignedBB $bb, float $epsilon=0.00001)
trim(int $face, float $distance)
stretch(int $axis, float $distance)
isVectorInXY(Vector3 $vector)
isVectorInYZ(Vector3 $vector)
expand(float $x, float $y, float $z)
expandedCopy(float $x, float $y, float $z)
contractedCopy(float $x, float $y, float $z)
contract(float $x, float $y, float $z)
offsetTowards(int $face, float $distance)
addCoord(float $x, float $y, float $z)
stretchedCopy(int $axis, float $distance)
offsetCopy(float $x, float $y, float $z)
offsetTowardsCopy(int $face, float $distance)
calculateIntercept(Vector3 $pos1, Vector3 $pos2)
getIntermediateWithZValue(Vector3 $v, float $z)
getIntermediateWithXValue(Vector3 $v, float $x)
getIntermediateWithYValue(Vector3 $v, float $y)