diff --git a/src/Axis.php b/src/Axis.php index 68f3198..34b3027 100644 --- a/src/Axis.php +++ b/src/Axis.php @@ -23,24 +23,21 @@ namespace pocketmine\math; -final class Axis{ - private function __construct(){ - //NOOP - } - - public const Y = 0; - public const Z = 1; - public const X = 2; +enum Axis: int{ + case Y = 0; + case Z = 1; + case X = 2; /** + * @deprecated * Returns a human-readable string representation of the given axis. */ - public static function toString(int $axis) : string{ + public static function toString(Axis $axis) : string{ return match($axis){ Axis::Y => "y", Axis::Z => "z", Axis::X => "x", - default => throw new \InvalidArgumentException("Invalid axis $axis") + default => throw new \InvalidArgumentException("Invalid axis " . $axis->name) }; } } diff --git a/src/AxisAlignedBB.php b/src/AxisAlignedBB.php index cf4a3e2..ae4b4cf 100644 --- a/src/AxisAlignedBB.php +++ b/src/AxisAlignedBB.php @@ -136,12 +136,10 @@ public function offsetCopy(float $x, float $y, float $z) : AxisAlignedBB{ /** * Offsets this AxisAlignedBB in the given direction by the specified distance. * - * @param int $face one of the Facing::* constants - * * @return $this */ - public function offsetTowards(int $face, float $distance) : AxisAlignedBB{ - [$offsetX, $offsetY, $offsetZ] = Facing::OFFSET[$face] ?? throw new \InvalidArgumentException("Invalid Facing $face"); + public function offsetTowards(Facing $face, float $distance) : AxisAlignedBB{ + [$offsetX, $offsetY, $offsetZ] = $face->offset(); return $this->offset($offsetX * $distance, $offsetY * $distance, $offsetZ * $distance); } @@ -149,7 +147,7 @@ public function offsetTowards(int $face, float $distance) : AxisAlignedBB{ /** * Returns an offset clone of this AxisAlignedBB. */ - public function offsetTowardsCopy(int $face, float $distance) : AxisAlignedBB{ + public function offsetTowardsCopy(Facing $face, float $distance) : AxisAlignedBB{ return (clone $this)->offsetTowards($face, $distance); } @@ -184,7 +182,7 @@ public function contractedCopy(float $x, float $y, float $z) : AxisAlignedBB{ * @return $this * @throws \InvalidArgumentException */ - public function extend(int $face, float $distance) : AxisAlignedBB{ + public function extend(Facing $face, float $distance) : AxisAlignedBB{ match($face){ Facing::DOWN => $this->minY -= $distance, Facing::UP => $this->maxY += $distance, @@ -192,7 +190,6 @@ public function extend(int $face, float $distance) : AxisAlignedBB{ Facing::SOUTH => $this->maxZ += $distance, Facing::WEST => $this->minX -= $distance, Facing::EAST => $this->maxX += $distance, - default => throw new \InvalidArgumentException("Invalid face $face"), }; return $this; @@ -204,7 +201,7 @@ public function extend(int $face, float $distance) : AxisAlignedBB{ * * @throws \InvalidArgumentException */ - public function extendedCopy(int $face, float $distance) : AxisAlignedBB{ + public function extendedCopy(Facing $face, float $distance) : AxisAlignedBB{ return (clone $this)->extend($face, $distance); } @@ -217,7 +214,7 @@ public function extendedCopy(int $face, float $distance) : AxisAlignedBB{ * @return $this * @throws \InvalidArgumentException */ - public function trim(int $face, float $distance) : AxisAlignedBB{ + public function trim(Facing $face, float $distance) : AxisAlignedBB{ return $this->extend($face, -$distance); } @@ -227,20 +224,18 @@ public function trim(int $face, float $distance) : AxisAlignedBB{ * * @throws \InvalidArgumentException */ - public function trimmedCopy(int $face, float $distance) : AxisAlignedBB{ + public function trimmedCopy(Facing $face, float $distance) : AxisAlignedBB{ return $this->extendedCopy($face, -$distance); } /** * Increases the dimension of the AABB along the given axis. * - * @param int $axis one of the Axis::* constants * @param float $distance Negative values reduce width, positive values increase width. * * @return $this - * @throws \InvalidArgumentException */ - public function stretch(int $axis, float $distance) : AxisAlignedBB{ + public function stretch(Axis $axis, float $distance) : AxisAlignedBB{ if($axis === Axis::Y){ $this->minY -= $distance; $this->maxY += $distance; @@ -250,19 +245,16 @@ public function stretch(int $axis, float $distance) : AxisAlignedBB{ }elseif($axis === Axis::X){ $this->minX -= $distance; $this->maxX += $distance; - }else{ - throw new \InvalidArgumentException("Invalid axis $axis"); } + return $this; } /** * Returns a stretched copy of this bounding box. * @see AxisAlignedBB::stretch() - * - * @throws \InvalidArgumentException */ - public function stretchedCopy(int $axis, float $distance) : AxisAlignedBB{ + public function stretchedCopy(Axis $axis, float $distance) : AxisAlignedBB{ return (clone $this)->stretch($axis, $distance); } @@ -271,19 +263,16 @@ public function stretchedCopy(int $axis, float $distance) : AxisAlignedBB{ * @see AxisAlignedBB::stretch() * * @return $this - * @throws \InvalidArgumentException */ - public function squash(int $axis, float $distance) : AxisAlignedBB{ + public function squash(Axis $axis, float $distance) : AxisAlignedBB{ return $this->stretch($axis, -$distance); } /** * Returns a squashed copy of this bounding box. * @see AxisAlignedBB::squash() - * - * @throws \InvalidArgumentException */ - public function squashedCopy(int $axis, float $distance) : AxisAlignedBB{ + public function squashedCopy(Axis $axis, float $distance) : AxisAlignedBB{ return $this->stretchedCopy($axis, -$distance); } diff --git a/src/Facing.php b/src/Facing.php index 134a29b..cf3f4ad 100644 --- a/src/Facing.php +++ b/src/Facing.php @@ -25,21 +25,21 @@ use function in_array; -final class Facing{ - private function __construct(){ - //NOOP - } +enum Facing: int{ - public const FLAG_AXIS_POSITIVE = 1; + private const FLAG_AXIS_POSITIVE = 1; /* most significant 2 bits = axis, least significant bit = is positive direction */ - public const DOWN = Axis::Y << 1; - public const UP = (Axis::Y << 1) | self::FLAG_AXIS_POSITIVE; - public const NORTH = Axis::Z << 1; - public const SOUTH = (Axis::Z << 1) | self::FLAG_AXIS_POSITIVE; - public const WEST = Axis::X << 1; - public const EAST = (Axis::X << 1) | self::FLAG_AXIS_POSITIVE; + case DOWN = Axis::Y << 1; + case UP = (Axis::Y << 1) | self::FLAG_AXIS_POSITIVE; + case NORTH = Axis::Z << 1; + case SOUTH = (Axis::Z << 1) | self::FLAG_AXIS_POSITIVE; + case WEST = Axis::X << 1; + case EAST = (Axis::X << 1) | self::FLAG_AXIS_POSITIVE; + /** + * @deprecated use Facing::cases() + */ public const ALL = [ self::DOWN, self::UP, @@ -56,6 +56,9 @@ private function __construct(){ self::EAST ]; + /** + * @deprecated + */ public const OFFSET = [ self::DOWN => [ 0, -1, 0], self::UP => [ 0, +1, 0], @@ -65,6 +68,9 @@ private function __construct(){ self::EAST => [+1, 0, 0] ]; + /** + * @var Facing[][] + */ private const CLOCKWISE = [ Axis::Y => [ self::NORTH => self::EAST, @@ -89,67 +95,60 @@ private function __construct(){ /** * Returns the axis of the given direction. */ - public static function axis(int $direction) : int{ - return $direction >> 1; //shift off positive/negative bit + public static function axis(Facing $direction) : Axis{ + return Axis::from($direction >> 1); //shift off positive/negative bit } /** * Returns whether the direction is facing the positive of its axis. */ - public static function isPositive(int $direction) : bool{ - return ($direction & self::FLAG_AXIS_POSITIVE) === self::FLAG_AXIS_POSITIVE; + public static function isPositive(Facing $direction) : bool{ + return ($direction->value & self::FLAG_AXIS_POSITIVE) === self::FLAG_AXIS_POSITIVE; } /** * Returns the opposite Facing of the specified one. * - * @param int $direction 0-5 one of the Facing::* constants + * @throws \ValueError if opposite facing don't exist */ - public static function opposite(int $direction) : int{ - return $direction ^ self::FLAG_AXIS_POSITIVE; + public static function opposite(Facing $direction) : Facing{ + return self::from($direction->value ^ self::FLAG_AXIS_POSITIVE); } /** * Rotates the given direction around the axis. - * - * @throws \InvalidArgumentException if not possible to rotate $direction around $axis */ - public static function rotate(int $direction, int $axis, bool $clockwise) : int{ - if(!isset(self::CLOCKWISE[$axis])){ - throw new \InvalidArgumentException("Invalid axis $axis"); - } - if(!isset(self::CLOCKWISE[$axis][$direction])){ - throw new \InvalidArgumentException("Cannot rotate facing \"" . self::toString($direction) . "\" around axis \"" . Axis::toString($axis) . "\""); - } - - $rotated = self::CLOCKWISE[$axis][$direction]; + public static function rotate(Facing $direction, Axis $axis, bool $clockwise) : Facing{ + $rotated = self::CLOCKWISE[$axis->value][$direction->value]; return $clockwise ? $rotated : self::opposite($rotated); } - /** - * @throws \InvalidArgumentException - */ - public static function rotateY(int $direction, bool $clockwise) : int{ + public static function rotateY(Facing $direction, bool $clockwise) : Facing{ return self::rotate($direction, Axis::Y, $clockwise); } - /** - * @throws \InvalidArgumentException - */ - public static function rotateZ(int $direction, bool $clockwise) : int{ + public static function rotateZ(Facing $direction, bool $clockwise) : Facing{ return self::rotate($direction, Axis::Z, $clockwise); } - /** - * @throws \InvalidArgumentException - */ - public static function rotateX(int $direction, bool $clockwise) : int{ + public static function rotateX(Facing $direction, bool $clockwise) : Facing{ return self::rotate($direction, Axis::X, $clockwise); } + public function offset(): array { + return match($this){ + self::DOWN => [ 0, -1, 0], + self::UP => [ 0, +1, 0], + self::NORTH => [ 0, 0, -1], + self::SOUTH => [ 0, 0, +1], + self::WEST => [-1, 0, 0], + self::EAST => [+1, 0, 0] + }; + } + /** * Validates the given integer as a Facing direction. - * + * @deprecated * @throws \InvalidArgumentException if the argument is not a valid Facing constant */ public static function validate(int $facing) : void{ @@ -172,4 +171,4 @@ public static function toString(int $facing) : string{ default => throw new \InvalidArgumentException("Invalid facing $facing") }; } -} +} \ No newline at end of file diff --git a/src/RayTraceResult.php b/src/RayTraceResult.php index 4d0928a..156c7b1 100644 --- a/src/RayTraceResult.php +++ b/src/RayTraceResult.php @@ -28,12 +28,9 @@ */ class RayTraceResult{ - /** - * @param int $hitFace one of the Facing::* constants - */ public function __construct( public AxisAlignedBB $bb, - public int $hitFace, + public Facing $hitFace, public Vector3 $hitVector ){} @@ -41,7 +38,7 @@ public function getBoundingBox() : AxisAlignedBB{ return $this->bb; } - public function getHitFace() : int{ + public function getHitFace() : Facing{ return $this->hitFace; } diff --git a/src/Vector3.php b/src/Vector3.php index ca8701d..00e15e7 100644 --- a/src/Vector3.php +++ b/src/Vector3.php @@ -117,8 +117,8 @@ public function abs() : Vector3{ /** * @return Vector3 */ - public function getSide(int $side, int $step = 1){ - [$offsetX, $offsetY, $offsetZ] = Facing::OFFSET[$side] ?? [0, 0, 0]; + public function getSide(Facing $side, int $step = 1){ + [$offsetX, $offsetY, $offsetZ] = $side->offset(); return $this->add($offsetX * $step, $offsetY * $step, $offsetZ * $step); } @@ -174,7 +174,7 @@ public function east(int $step = 1){ * @phpstan-return \Generator */ public function sides(int $step = 1) : \Generator{ - foreach(Facing::ALL as $facing){ + foreach(Facing::cases() as $facing){ yield $facing => $this->getSide($facing, $step); } } @@ -191,13 +191,11 @@ public function sidesArray(bool $keys = false, int $step = 1) : array{ /** * Yields vectors stepped out from this one in directions except those on the given axis. * - * @param int $axis Facing directions on this axis will be excluded - * * @return \Generator|Vector3[] * @phpstan-return \Generator */ - public function sidesAroundAxis(int $axis, int $step = 1) : \Generator{ - foreach(Facing::ALL as $facing){ + public function sidesAroundAxis(Axis $axis, int $step = 1) : \Generator{ + foreach(Facing::cases() as $facing){ if(Facing::axis($facing) !== $axis){ yield $facing => $this->getSide($facing, $step); } diff --git a/tests/phpunit/FacingTest.php b/tests/phpunit/FacingTest.php index 9e42070..fd1b8cd 100644 --- a/tests/phpunit/FacingTest.php +++ b/tests/phpunit/FacingTest.php @@ -37,10 +37,10 @@ public function axisProvider() : \Generator{ /** * @dataProvider axisProvider * - * @param int $direction - * @param int $axis + * @param Facing $facing + * @param Axis $axis */ - public function testAxis(int $direction, int $axis) : void{ + public function testAxis(Facing $direction, Axis $axis) : void{ self::assertEquals($axis, Facing::axis($direction)); } @@ -53,10 +53,10 @@ public function oppositeProvider() : \Generator{ /** * @dataProvider oppositeProvider * - * @param int $dir1 - * @param int $dir2 + * @param Facing $dir1 + * @param Facing $dir2 */ - public function testOpposite(int $dir1, int $dir2) : void{ + public function testOpposite(Facing $dir1, Facing $dir2) : void{ self::assertEquals($dir2, Facing::opposite($dir1)); self::assertEquals($dir1, Facing::opposite($dir2)); } @@ -73,10 +73,10 @@ public function positiveProvider() : \Generator{ /** * @dataProvider positiveProvider * - * @param int $facing + * @param Facing $facing * @param bool $positive */ - public function testIsPositive(int $facing, bool $positive) : void{ + public function testIsPositive(Facing $facing, bool $positive) : void{ self::assertEquals($positive, Facing::isPositive($facing)); } @@ -117,12 +117,12 @@ public function rotateProvider() : \Generator{ /** * @dataProvider rotateProvider * - * @param int $direction - * @param int $axis + * @param Facing $direction + * @param Axis $axis * @param bool $clockwise - * @param int $expected + * @param Facing $expected */ - public function testRotate(int $direction, int $axis, bool $clockwise, int $expected) : void{ + public function testRotate(Facing $direction, Axis $axis, bool $clockwise, Facing $expected) : void{ self::assertEquals($expected, Facing::rotate($direction, $axis, $clockwise)); } }