|
23 | 23 |
|
24 | 24 | namespace pocketmine\math;
|
25 | 25 |
|
| 26 | +use function floatval; |
26 | 27 | use function floor;
|
27 | 28 | use const INF;
|
28 | 29 |
|
@@ -80,14 +81,14 @@ public static function betweenPoints(Vector3 $start, Vector3 $end) : \Generator{
|
80 | 81 |
|
81 | 82 | //Initialize the step accumulation variables depending how far into the current block the start position is. If
|
82 | 83 | //the start position is on the corner of the block, these will be zero.
|
83 |
| - $tMaxX = self::rayTraceDistanceToBoundary($start->x, $directionVector->x); |
84 |
| - $tMaxY = self::rayTraceDistanceToBoundary($start->y, $directionVector->y); |
85 |
| - $tMaxZ = self::rayTraceDistanceToBoundary($start->z, $directionVector->z); |
| 84 | + $tMaxX = self::distanceFactorToBoundary($start->x, $directionVector->x); |
| 85 | + $tMaxY = self::distanceFactorToBoundary($start->y, $directionVector->y); |
| 86 | + $tMaxZ = self::distanceFactorToBoundary($start->z, $directionVector->z); |
86 | 87 |
|
87 | 88 | //The change in t on each axis when taking a step on that axis (always positive).
|
88 |
| - $tDeltaX = $directionVector->x == 0 ? 0 : $stepX / $directionVector->x; |
89 |
| - $tDeltaY = $directionVector->y == 0 ? 0 : $stepY / $directionVector->y; |
90 |
| - $tDeltaZ = $directionVector->z == 0 ? 0 : $stepZ / $directionVector->z; |
| 89 | + $tDeltaX = floatval($directionVector->x) === 0.0 ? 0 : $stepX / $directionVector->x; |
| 90 | + $tDeltaY = floatval($directionVector->y) === 0.0 ? 0 : $stepY / $directionVector->y; |
| 91 | + $tDeltaZ = floatval($directionVector->z) === 0.0 ? 0 : $stepZ / $directionVector->z; |
91 | 92 |
|
92 | 93 | while(true){
|
93 | 94 | yield $currentBlock;
|
@@ -118,34 +119,26 @@ public static function betweenPoints(Vector3 $start, Vector3 $end) : \Generator{
|
118 | 119 | }
|
119 | 120 |
|
120 | 121 | /**
|
121 |
| - * Returns the distance that must be travelled on an axis from the start point with the direction vector component to |
122 |
| - * cross a block boundary. |
| 122 | + * Used to decide which direction to move in first when beginning a ray trace. |
123 | 123 | *
|
124 |
| - * For example, given an X coordinate inside a block and the X component of a direction vector, will return the distance |
125 |
| - * travelled by that direction component to reach a block with a different X coordinate. |
126 |
| - * |
127 |
| - * Find the smallest positive t such that s+t*ds is an integer. |
| 124 | + * Examples: |
| 125 | + * s=0.25, ds=0.5 -> 0.25 + 1.5(0.5) = 1 -> returns 1.5 |
| 126 | + * s=0.25, ds=-0.5 -> 0.25 + 0.5(-0.5) = 0 -> returns 0.5 |
| 127 | + * s=1 ds=0.5 -> 1 + 2(0.5) = 2 -> returns 2 |
| 128 | + * s=1 ds=-0.5 -> 1 + 0(-0.5) = 1 -> returns 0 (ds is negative and any subtraction will change 1 to 0.x) |
128 | 129 | *
|
129 | 130 | * @param float $s Starting coordinate
|
130 | 131 | * @param float $ds Direction vector component of the relevant axis
|
131 | 132 | *
|
132 |
| - * @return float Distance along the ray trace that must be travelled to cross a boundary. |
| 133 | + * @return float Number of times $ds must be added to $s to change its whole-number component. |
133 | 134 | */
|
134 |
| - private static function rayTraceDistanceToBoundary(float $s, float $ds) : float{ |
135 |
| - if($ds == 0){ |
| 135 | + private static function distanceFactorToBoundary(float $s, float $ds) : float{ |
| 136 | + if($ds === 0.0){ |
136 | 137 | return INF;
|
137 | 138 | }
|
138 | 139 |
|
139 |
| - if($ds < 0){ |
140 |
| - $s = -$s; |
141 |
| - $ds = -$ds; |
142 |
| - |
143 |
| - if(floor($s) == $s){ //exactly at coordinate, will leave the coordinate immediately by moving negatively |
144 |
| - return 0; |
145 |
| - } |
146 |
| - } |
147 |
| - |
148 |
| - // problem is now s+t*ds = 1 |
149 |
| - return (1 - ($s - floor($s))) / $ds; |
| 140 | + return $ds < 0 ? |
| 141 | + ($s - floor($s)) / -$ds : |
| 142 | + (1 - ($s - floor($s))) / $ds; |
150 | 143 | }
|
151 | 144 | }
|
0 commit comments