From 45b02d92d4e24aad1fde3d51ecec8adf83773121 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 12 Jan 2018 14:28:41 +0000 Subject: [PATCH] Math: Added RayTraceResult, removed dependence on MovingObjectPosition MOP doesn't make any sense anyway. RayTraceResult is a container which represents the point at which a line hits a bounding box. No dependence on blocks or entities is wanted or needed. MovingObjectPosition has API changes to allow it to wrap RayTraceResult, but nothing uses MOP anymore anyway. This would allow modularisation of the pocketmine\\math namespace. --- src/pocketmine/block/Block.php | 14 +--- .../entity/projectile/Projectile.php | 17 ++--- src/pocketmine/level/MovingObjectPosition.php | 59 ++++++--------- src/pocketmine/math/AxisAlignedBB.php | 10 +-- src/pocketmine/math/RayTraceResult.php | 75 +++++++++++++++++++ 5 files changed, 109 insertions(+), 66 deletions(-) create mode 100644 src/pocketmine/math/RayTraceResult.php diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index b82936ba4..6c962356c 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -30,9 +30,9 @@ use pocketmine\entity\Entity; use pocketmine\item\Item; use pocketmine\item\ItemFactory; use pocketmine\level\Level; -use pocketmine\level\MovingObjectPosition; use pocketmine\level\Position; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\RayTraceResult; use pocketmine\math\Vector3; use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; @@ -615,15 +615,15 @@ class Block extends Position implements BlockIds, Metadatable{ * @param Vector3 $pos1 * @param Vector3 $pos2 * - * @return MovingObjectPosition|null + * @return RayTraceResult|null */ - public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?MovingObjectPosition{ + public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?RayTraceResult{ $bbs = $this->getCollisionBoxes(); if(empty($bbs)){ return null; } - /** @var MovingObjectPosition|null $currentHit */ + /** @var RayTraceResult|null $currentHit */ $currentHit = null; /** @var int|float $currentDistance */ $currentDistance = PHP_INT_MAX; @@ -641,12 +641,6 @@ class Block extends Position implements BlockIds, Metadatable{ } } - if($currentHit !== null){ - $currentHit->blockX = $this->x; - $currentHit->blockY = $this->y; - $currentHit->blockZ = $this->z; - } - return $currentHit; } diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/pocketmine/entity/projectile/Projectile.php index 0b7a4dd70..dc2043dbd 100644 --- a/src/pocketmine/entity/projectile/Projectile.php +++ b/src/pocketmine/entity/projectile/Projectile.php @@ -31,7 +31,6 @@ use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\ProjectileHitEvent; use pocketmine\level\Level; -use pocketmine\level\MovingObjectPosition; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; @@ -136,13 +135,13 @@ abstract class Projectile extends Entity{ } $axisalignedbb = $entity->boundingBox->grow(0.3, 0.3, 0.3); - $ob = $axisalignedbb->calculateIntercept($this, $moveVector); + $rayTraceResult = $axisalignedbb->calculateIntercept($this, $moveVector); - if($ob === null){ + if($rayTraceResult === null){ continue; } - $distance = $this->distanceSquared($ob->hitVector); + $distance = $this->distanceSquared($rayTraceResult->hitVector); if($distance < $nearDistance){ $nearDistance = $distance; @@ -151,14 +150,8 @@ abstract class Projectile extends Entity{ } if($nearEntity !== null){ - $movingObjectPosition = MovingObjectPosition::fromEntity($nearEntity); - } - - if($movingObjectPosition !== null){ - if($movingObjectPosition->entityHit !== null){ - $this->onCollideWithEntity($movingObjectPosition->entityHit); - return false; - } + $this->onCollideWithEntity($nearEntity); + return false; } if($this->isCollided and !$this->hadCollision){ //Collided with a block diff --git a/src/pocketmine/level/MovingObjectPosition.php b/src/pocketmine/level/MovingObjectPosition.php index 779bbd7d2..e76674d19 100644 --- a/src/pocketmine/level/MovingObjectPosition.php +++ b/src/pocketmine/level/MovingObjectPosition.php @@ -23,70 +23,53 @@ declare(strict_types=1); namespace pocketmine\level; +use pocketmine\block\Block; use pocketmine\entity\Entity; -use pocketmine\math\Vector3; +use pocketmine\math\RayTraceResult; class MovingObjectPosition{ public const TYPE_BLOCK_COLLISION = 0; public const TYPE_ENTITY_COLLISION = 1; + /** @var RayTraceResult */ + public $hitResult; + /** @var int */ public $typeOfHit; - /** @var int|null */ - public $blockX; - /** @var int|null */ - public $blockY; - /** @var int|null */ - public $blockZ; - - /** - * @var int|null - * Which side was hit. If its -1 then it went the full length of the ray trace. - * -1 or one of the Vector3::SIDE_* constants - */ - public $sideHit; - - /** @var Vector3 */ - public $hitVector; - /** @var Entity|null */ public $entityHit = null; + /** @var Block|null */ + public $blockHit = null; - protected function __construct(){ - + protected function __construct(int $hitType, RayTraceResult $hitResult){ + $this->typeOfHit = $hitType; + $this->hitResult = $hitResult; } /** - * @param int $x - * @param int $y - * @param int $z - * @param int $side - * @param Vector3 $hitVector + * @param Block $block + * @param RayTraceResult $result * * @return MovingObjectPosition */ - public static function fromBlock(int $x, int $y, int $z, int $side, Vector3 $hitVector) : MovingObjectPosition{ - $ob = new MovingObjectPosition; - $ob->typeOfHit = self::TYPE_BLOCK_COLLISION; - $ob->blockX = $x; - $ob->blockY = $y; - $ob->blockZ = $z; - $ob->sideHit = $side; - $ob->hitVector = $hitVector->asVector3(); + public static function fromBlock(Block $block, RayTraceResult $result) : MovingObjectPosition{ + $ob = new MovingObjectPosition(self::TYPE_BLOCK_COLLISION, $result); + $ob->blockHit = $block; return $ob; } /** - * @param Entity $entity + * @param Entity $entity + * + * @param RayTraceResult $result * * @return MovingObjectPosition */ - public static function fromEntity(Entity $entity) : MovingObjectPosition{ - $ob = new MovingObjectPosition; - $ob->typeOfHit = self::TYPE_ENTITY_COLLISION; + public static function fromEntity(Entity $entity, RayTraceResult $result) : MovingObjectPosition{ + $ob = new MovingObjectPosition(self::TYPE_ENTITY_COLLISION, $result); $ob->entityHit = $entity; - $ob->hitVector = $entity->asVector3(); + return $ob; } } diff --git a/src/pocketmine/math/AxisAlignedBB.php b/src/pocketmine/math/AxisAlignedBB.php index 93d91da3a..85eb2042e 100644 --- a/src/pocketmine/math/AxisAlignedBB.php +++ b/src/pocketmine/math/AxisAlignedBB.php @@ -23,8 +23,6 @@ declare(strict_types=1); namespace pocketmine\math; -use pocketmine\level\MovingObjectPosition; - class AxisAlignedBB{ /** @var float */ @@ -353,15 +351,15 @@ class AxisAlignedBB{ /** * Performs a ray-trace and calculates the point on the AABB's edge nearest the start position that the ray-trace - * collided with. Returns a MovingObjectPosition with colliding vector closest to the start position. + * collided with. Returns a RayTraceResult with colliding vector closest to the start position. * Returns null if no colliding point was found. * * @param Vector3 $pos1 * @param Vector3 $pos2 * - * @return MovingObjectPosition|null + * @return RayTraceResult|null */ - public function calculateIntercept(Vector3 $pos1, Vector3 $pos2){ + public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?RayTraceResult{ $v1 = $pos1->getIntermediateWithXValue($pos2, $this->minX); $v2 = $pos1->getIntermediateWithXValue($pos2, $this->maxX); $v3 = $pos1->getIntermediateWithYValue($pos2, $this->minY); @@ -423,7 +421,7 @@ class AxisAlignedBB{ $f = Vector3::SIDE_SOUTH; } - return MovingObjectPosition::fromBlock(0, 0, 0, $f, $vector); + return new RayTraceResult($this, $f, $vector); } public function __toString(){ diff --git a/src/pocketmine/math/RayTraceResult.php b/src/pocketmine/math/RayTraceResult.php new file mode 100644 index 000000000..b1ca11401 --- /dev/null +++ b/src/pocketmine/math/RayTraceResult.php @@ -0,0 +1,75 @@ +bb = $bb; + $this->hitFace = $hitFace; + $this->hitVector = $hitVector; + } + + /** + * @return AxisAlignedBB + */ + public function getBoundingBox() : AxisAlignedBB{ + return $this->bb; + } + + /** + * @return int + */ + public function getHitFace() : int{ + return $this->hitFace; + } + + /** + * @return Vector3 + */ + public function getHitVector() : Vector3{ + return $this->hitVector; + } +}