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

Vector3 is now immutable #90

Open
wants to merge 3 commits into
base: stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/AxisAlignedBB.php
Original file line number Diff line number Diff line change
Expand Up @@ -370,14 +370,14 @@ public function intersectsWith(AxisAlignedBB $bb, float $epsilon = 0.00001) : bo
* Returns whether the specified vector is within the bounds of this AABB on all axes.
*/
public function isVectorInside(Vector3 $vector) : bool{
if($vector->x <= $this->minX or $vector->x >= $this->maxX){
if($vector->getX() <= $this->minX or $vector->getX() >= $this->maxX){
return false;
}
if($vector->y <= $this->minY or $vector->y >= $this->maxY){
if($vector->getY() <= $this->minY or $vector->getY() >= $this->maxY){
return false;
}

return $vector->z > $this->minZ and $vector->z < $this->maxZ;
return $vector->getZ() > $this->minZ and $vector->getZ() < $this->maxZ;
}

/**
Expand Down Expand Up @@ -409,21 +409,21 @@ public function getVolume() : float{
* Returns whether the specified vector is within the Y and Z bounds of this AABB.
*/
public function isVectorInYZ(Vector3 $vector) : bool{
return $vector->y >= $this->minY and $vector->y <= $this->maxY and $vector->z >= $this->minZ and $vector->z <= $this->maxZ;
return $vector->getY() >= $this->minY and $vector->getY() <= $this->maxY and $vector->getZ() >= $this->minZ and $vector->getZ() <= $this->maxZ;
}

/**
* Returns whether the specified vector is within the X and Z bounds of this AABB.
*/
public function isVectorInXZ(Vector3 $vector) : bool{
return $vector->x >= $this->minX and $vector->x <= $this->maxX and $vector->z >= $this->minZ and $vector->z <= $this->maxZ;
return $vector->getX() >= $this->minX and $vector->getX() <= $this->maxX and $vector->getZ() >= $this->minZ and $vector->getZ() <= $this->maxZ;
}

/**
* Returns whether the specified vector is within the X and Y bounds of this AABB.
*/
public function isVectorInXY(Vector3 $vector) : bool{
return $vector->x >= $this->minX and $vector->x <= $this->maxX and $vector->y >= $this->minY and $vector->y <= $this->maxY;
return $vector->getX() >= $this->minX and $vector->getX() <= $this->maxX and $vector->getY() >= $this->minY and $vector->getY() <= $this->maxY;
}

/**
Expand Down
138 changes: 59 additions & 79 deletions src/Vector3.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,56 +33,57 @@
use function sqrt;
use const PHP_ROUND_HALF_UP;

class Vector3{
readonly class Vector3{

Check failure on line 36 in src/Vector3.php

View workflow job for this annotation

GitHub Actions / PHP 8.1

Readonly classes are supported only on PHP 8.2 and later.

public function __construct(
public float|int $x,
public float|int $y,
public float|int $z
protected float|int $x,
protected float|int $y,
protected float|int $z
){}

public static function zero() : Vector3{
//TODO: make this reuse a single object, once Vector3 becomes immutable
return new self(0, 0, 0);
}

public function getX() : float|int{
final public function getX() : float|int{
return $this->x;
}

public function getY() : float|int{
final public function getY() : float|int{
return $this->y;
}

public function getZ() : float|int{
final public function getZ() : float|int{
return $this->z;
}

public function getFloorX() : int{
final public function getFloorX() : int{
return (int) floor($this->x);
}

public function getFloorY() : int{
final public function getFloorY() : int{
return (int) floor($this->y);
}

public function getFloorZ() : int{
final public function getFloorZ() : int{
return (int) floor($this->z);
}

public function add(float|int $x, float|int $y, float|int $z) : Vector3{
return new Vector3($this->x + $x, $this->y + $y, $this->z + $z);
}

public function addVector(Vector3 $v) : Vector3{
return $this->add($v->x, $v->y, $v->z);
final public function addVector(Vector3 $v) : Vector3{
return $this->add($v->getX(), $v->getY(), $v->getZ());
}

public function subtract(float|int $x, float|int $y, float|int $z) : Vector3{
final public function subtract(float|int $x, float|int $y, float|int $z) : Vector3{
return $this->add(-$x, -$y, -$z);
}

public function subtractVector(Vector3 $v) : Vector3{
return $this->add(-$v->x, -$v->y, -$v->z);
final public function subtractVector(Vector3 $v) : Vector3{
return $this->add(-$v->getX(), -$v->getY(), -$v->getZ());
}

public function multiply(float $number) : Vector3{
Expand Down Expand Up @@ -114,54 +115,33 @@
return new Vector3(abs($this->x), abs($this->y), abs($this->z));
}

/**
* @return Vector3
*/
public function getSide(int $side, int $step = 1){
final public function getSide(int $side, int $step = 1) : Vector3{
[$offsetX, $offsetY, $offsetZ] = Facing::OFFSET[$side] ?? [0, 0, 0];

return $this->add($offsetX * $step, $offsetY * $step, $offsetZ * $step);
}

/**
* @return Vector3
*/
public function down(int $step = 1){
final public function down(int $step = 1) : Vector3{
return $this->getSide(Facing::DOWN, $step);
}

/**
* @return Vector3
*/
public function up(int $step = 1){
final public function up(int $step = 1) : Vector3{
return $this->getSide(Facing::UP, $step);
}

/**
* @return Vector3
*/
public function north(int $step = 1){
final public function north(int $step = 1) : Vector3{
return $this->getSide(Facing::NORTH, $step);
}

/**
* @return Vector3
*/
public function south(int $step = 1){
final public function south(int $step = 1) : Vector3{
return $this->getSide(Facing::SOUTH, $step);
}

/**
* @return Vector3
*/
public function west(int $step = 1){
final public function west(int $step = 1) : Vector3{
return $this->getSide(Facing::WEST, $step);
}

/**
* @return Vector3
*/
public function east(int $step = 1){
final public function east(int $step = 1) : Vector3{
return $this->getSide(Facing::EAST, $step);
}

Expand All @@ -173,7 +153,7 @@
* @return \Generator|Vector3[]
* @phpstan-return \Generator<int, Vector3, void, void>
*/
public function sides(int $step = 1) : \Generator{
final public function sides(int $step = 1) : \Generator{
foreach(Facing::ALL as $facing){
yield $facing => $this->getSide($facing, $step);
}
Expand All @@ -184,7 +164,7 @@
*
* @return Vector3[]
*/
public function sidesArray(bool $keys = false, int $step = 1) : array{
final public function sidesArray(bool $keys = false, int $step = 1) : array{
return iterator_to_array($this->sides($step), $keys);
}

Expand All @@ -196,7 +176,7 @@
* @return \Generator|Vector3[]
* @phpstan-return \Generator<int, Vector3, void, void>
*/
public function sidesAroundAxis(int $axis, int $step = 1) : \Generator{
final public function sidesAroundAxis(int $axis, int $step = 1) : \Generator{
foreach(Facing::ALL as $facing){
if(Facing::axis($facing) !== $axis){
yield $facing => $this->getSide($facing, $step);
Expand All @@ -207,33 +187,33 @@
/**
* Return a Vector3 instance
*/
public function asVector3() : Vector3{
final public function asVector3() : Vector3{
return new Vector3($this->x, $this->y, $this->z);
}

public function distance(Vector3 $pos) : float{
final public function distance(Vector3 $pos) : float{
return sqrt($this->distanceSquared($pos));
}

public function distanceSquared(Vector3 $pos) : float{
final public function distanceSquared(Vector3 $pos) : float{
return (($this->x - $pos->x) ** 2) + (($this->y - $pos->y) ** 2) + (($this->z - $pos->z) ** 2);
}

public function maxPlainDistance(Vector3|Vector2|float $x, float $z = 0) : float{
if($x instanceof Vector3){
return $this->maxPlainDistance($x->x, $x->z);
return $this->maxPlainDistance($x->getX(), $x->getZ());
}elseif($x instanceof Vector2){
return $this->maxPlainDistance($x->x, $x->y);
}else{
return max(abs($this->x - $x), abs($this->z - $z));
}
}

public function length() : float{
final public function length() : float{
return sqrt($this->lengthSquared());
}

public function lengthSquared() : float{
final public function lengthSquared() : float{
return $this->x * $this->x + $this->y * $this->y + $this->z * $this->z;
}

Expand All @@ -247,27 +227,27 @@
}

public function dot(Vector3 $v) : float{
return $this->x * $v->x + $this->y * $v->y + $this->z * $v->z;
return $this->x * $v->getX() + $this->y * $v->getY() + $this->z * $v->getZ();
}

public function cross(Vector3 $v) : Vector3{
return new Vector3(
$this->y * $v->z - $this->z * $v->y,
$this->z * $v->x - $this->x * $v->z,
$this->x * $v->y - $this->y * $v->x
$this->y * $v->getZ() - $this->z * $v->getY(),
$this->z * $v->getX() - $this->x * $v->getZ(),
$this->x * $v->getY() - $this->y * $v->getX()
);
}

public function equals(Vector3 $v) : bool{
return $this->x == $v->x and $this->y == $v->y and $this->z == $v->z;
return $this->x == $v->getX() and $this->y == $v->getY() and $this->z == $v->getZ();
}

/**
* Returns a new vector with x value equal to the second parameter, along the line between this vector and the
* passed in vector, or null if not possible.
*/
public function getIntermediateWithXValue(Vector3 $v, float $x) : ?Vector3{
$xDiff = $v->x - $this->x;
$xDiff = $v->getX() - $this->x;
if(($xDiff * $xDiff) < 0.0000001){
return null;
}
Expand All @@ -277,7 +257,7 @@
if($f < 0 or $f > 1){
return null;
}else{
return new Vector3($x, $this->y + ($v->y - $this->y) * $f, $this->z + ($v->z - $this->z) * $f);
return new Vector3($x, $this->y + ($v->getY() - $this->y) * $f, $this->z + ($v->getZ() - $this->z) * $f);
}
}

Expand All @@ -286,7 +266,7 @@
* passed in vector, or null if not possible.
*/
public function getIntermediateWithYValue(Vector3 $v, float $y) : ?Vector3{
$yDiff = $v->y - $this->y;
$yDiff = $v->getY() - $this->y;
if(($yDiff * $yDiff) < 0.0000001){
return null;
}
Expand All @@ -296,7 +276,7 @@
if($f < 0 or $f > 1){
return null;
}else{
return new Vector3($this->x + ($v->x - $this->x) * $f, $y, $this->z + ($v->z - $this->z) * $f);
return new Vector3($this->x + ($v->getX() - $this->x) * $f, $y, $this->z + ($v->getZ() - $this->z) * $f);
}
}

Expand All @@ -305,7 +285,7 @@
* passed in vector, or null if not possible.
*/
public function getIntermediateWithZValue(Vector3 $v, float $z) : ?Vector3{
$zDiff = $v->z - $this->z;
$zDiff = $v->getZ() - $this->z;
if(($zDiff * $zDiff) < 0.0000001){
return null;
}
Expand All @@ -315,7 +295,7 @@
if($f < 0 or $f > 1){
return null;
}else{
return new Vector3($this->x + ($v->x - $this->x) * $f, $this->y + ($v->y - $this->y) * $f, $z);
return new Vector3($this->x + ($v->getX() - $this->x) * $f, $this->y + ($v->getY() - $this->y) * $f, $z);
}
}

Expand All @@ -341,13 +321,13 @@
* @param Vector3 ...$vectors
*/
public static function maxComponents(Vector3 $vector, Vector3 ...$vectors) : Vector3{
$x = $vector->x;
$y = $vector->y;
$z = $vector->z;
$x = $vector->getX();
$y = $vector->getY();
$z = $vector->getZ();
foreach($vectors as $position){
$x = max($x, $position->x);
$y = max($y, $position->y);
$z = max($z, $position->z);
$x = max($x, $position->getX());
$y = max($y, $position->getY());
$z = max($z, $position->getZ());
}
return new Vector3($x, $y, $z);
}
Expand All @@ -358,24 +338,24 @@
* @param Vector3 ...$vectors
*/
public static function minComponents(Vector3 $vector, Vector3 ...$vectors) : Vector3{
$x = $vector->x;
$y = $vector->y;
$z = $vector->z;
$x = $vector->getX();
$y = $vector->getY();
$z = $vector->getZ();
foreach($vectors as $position){
$x = min($x, $position->x);
$y = min($y, $position->y);
$z = min($z, $position->z);
$x = min($x, $position->getX());
$y = min($y, $position->getY());
$z = min($z, $position->getZ());
}
return new Vector3($x, $y, $z);
}

public static function sum(Vector3 ...$vector3s) : Vector3{
$x = $y = $z = 0;
foreach($vector3s as $vector3){
$x += $vector3->x;
$y += $vector3->y;
$z += $vector3->z;
$x += $vector3->getX();
$y += $vector3->getY();
$z += $vector3->getZ();
}
return new Vector3($x, $y, $z);
}
}
}
Loading
Loading