Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Facing and Axis to enum #91

Open
wants to merge 18 commits into
base: stable
Choose a base branch
from
16 changes: 6 additions & 10 deletions src/Axis.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,20 @@

namespace pocketmine\math;

final class Axis{
private function __construct(){
//NOOP
}

public const Y = 0;
public const Z = 1;
public const X = 2;
enum Axis{
case Y;
case Z;
case X;

/**
* @deprecated use Axis->name
* 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")
};
}
}
35 changes: 12 additions & 23 deletions src/AxisAlignedBB.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,20 +136,18 @@
/**
* 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] = Facing::OFFSET[$face->value];

Check failure on line 142 in src/AxisAlignedBB.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Access to an undefined property pocketmine\math\Facing::$value.
Dhaiven marked this conversation as resolved.
Show resolved Hide resolved

return $this->offset($offsetX * $distance, $offsetY * $distance, $offsetZ * $distance);
}

/**
* 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);
}

Expand Down Expand Up @@ -184,15 +182,14 @@
* @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,
Facing::NORTH => $this->minZ -= $distance,
Facing::SOUTH => $this->maxZ += $distance,
Facing::WEST => $this->minX -= $distance,
Facing::EAST => $this->maxX += $distance,
default => throw new \InvalidArgumentException("Invalid face $face"),
};

return $this;
Expand All @@ -204,7 +201,7 @@
*
* @throws \InvalidArgumentException
*/
public function extendedCopy(int $face, float $distance) : AxisAlignedBB{
public function extendedCopy(Facing $face, float $distance) : AxisAlignedBB{
return (clone $this)->extend($face, $distance);
}

Expand All @@ -217,7 +214,7 @@
* @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);
}

Expand All @@ -227,20 +224,18 @@
*
* @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;
Expand All @@ -250,19 +245,16 @@
}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);
}

Expand All @@ -271,19 +263,16 @@
* @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);
}

Expand Down Expand Up @@ -468,12 +457,12 @@
$face = -1;

foreach([
Facing::WEST => $v1,

Check failure on line 460 in src/AxisAlignedBB.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Invalid array key type pocketmine\math\Facing::WEST.
Facing::EAST => $v2,

Check failure on line 461 in src/AxisAlignedBB.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Invalid array key type pocketmine\math\Facing::EAST.
Facing::DOWN => $v3,

Check failure on line 462 in src/AxisAlignedBB.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Invalid array key type pocketmine\math\Facing::DOWN.
Facing::UP => $v4,

Check failure on line 463 in src/AxisAlignedBB.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Invalid array key type pocketmine\math\Facing::UP.
Facing::NORTH => $v5,

Check failure on line 464 in src/AxisAlignedBB.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Invalid array key type pocketmine\math\Facing::NORTH.
Facing::SOUTH => $v6

Check failure on line 465 in src/AxisAlignedBB.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Invalid array key type pocketmine\math\Facing::SOUTH.
] as $f => $v){
if($v !== null and ($d = $pos1->distanceSquared($v)) < $distance){
$vector = $v;
Expand All @@ -486,7 +475,7 @@
return null;
}

return new RayTraceResult($this, $face, $vector);

Check failure on line 478 in src/AxisAlignedBB.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Parameter #2 $hitFace of class pocketmine\math\RayTraceResult constructor expects pocketmine\math\Facing, (int|string) given.
}

public function __toString() : string{
Expand Down
88 changes: 39 additions & 49 deletions src/Facing.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,17 @@

use function in_array;

final class Facing{
private function __construct(){
//NOOP
}

public 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;
enum Facing{
case DOWN;
case UP;
case NORTH;
case SOUTH;
case WEST;
case EAST;

/**
* @deprecated use Facing::cases()
*/
public const ALL = [
self::DOWN,
self::UP,
Expand All @@ -57,14 +53,17 @@
];

public const OFFSET = [
Dhaiven marked this conversation as resolved.
Show resolved Hide resolved
self::DOWN => [ 0, -1, 0],

Check failure on line 56 in src/Facing.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Invalid array key type pocketmine\math\Facing::DOWN.
self::UP => [ 0, +1, 0],

Check failure on line 57 in src/Facing.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Invalid array key type pocketmine\math\Facing::UP.
self::NORTH => [ 0, 0, -1],
self::SOUTH => [ 0, 0, +1],
self::WEST => [-1, 0, 0],
self::EAST => [+1, 0, 0]
];

/**
* @var Facing[][]
*/
private const CLOCKWISE = [
Axis::Y => [
self::NORTH => self::EAST,
Expand All @@ -89,67 +88,58 @@
/**
* 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 match ($direction) {
self::DOWN, self::UP => Axis::Y,
self::NORTH, self::SOUTH => Axis::Z,
self::WEST, self::EAST => Axis::X,
};
}

/**
* 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 in_array($direction, [self::UP, self::SOUTH, self::EAST]);
Dhaiven marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Returns the opposite Facing of the specified one.
*
* @param int $direction 0-5 one of the Facing::* constants
*/
public static function opposite(int $direction) : int{
return $direction ^ self::FLAG_AXIS_POSITIVE;
public static function opposite(Facing $direction) : Facing{
return match ($direction) {
self::DOWN => self::UP,
self::NORTH => self::SOUTH,
self::WEST => self::EAST,
self::UP => self::DOWN,
self::SOUTH => self::NORTH,
self::EAST => self::WEST,
Dhaiven marked this conversation as resolved.
Show resolved Hide resolved
};
}

/**
* 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];
Dhaiven marked this conversation as resolved.
Show resolved Hide resolved
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);
}

/**
* 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{
Expand All @@ -159,17 +149,17 @@
}
Dhaiven marked this conversation as resolved.
Show resolved Hide resolved

/**
* @deprecated use Facing->name
Dhaiven marked this conversation as resolved.
Show resolved Hide resolved
* Returns a human-readable string representation of the given Facing direction.
*/
public static function toString(int $facing) : string{
public static function toString(Facing $facing) : string{
return match($facing){
self::DOWN => "down",
self::UP => "up",
self::NORTH => "north",
self::SOUTH => "south",
self::WEST => "west",
self::EAST => "east",
default => throw new \InvalidArgumentException("Invalid facing $facing")
};
}
}
}
7 changes: 2 additions & 5 deletions src/RayTraceResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,17 @@
*/
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
){}

public function getBoundingBox() : AxisAlignedBB{
return $this->bb;
}

public function getHitFace() : int{
public function getHitFace() : Facing{
return $this->hitFace;
}

Expand Down
12 changes: 5 additions & 7 deletions src/Vector3.php
Original file line number Diff line number Diff line change
Expand Up @@ -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] = Facing::OFFSET[$side->value];

return $this->add($offsetX * $step, $offsetY * $step, $offsetZ * $step);
}
Expand Down Expand Up @@ -174,7 +174,7 @@ public function east(int $step = 1){
* @phpstan-return \Generator<int, Vector3, void, void>
*/
public function sides(int $step = 1) : \Generator{
foreach(Facing::ALL as $facing){
foreach(Facing::cases() as $facing){
yield $facing => $this->getSide($facing, $step);
}
}
Expand All @@ -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<int, Vector3, void, void>
*/
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);
}
Expand Down
Loading
Loading