PocketMine-MP  1.4 - API 1.10.0
 All Classes Namespaces Functions Variables Pages
AxisAlignedBB.php
1 <?php
2 
3 /*
4  *
5  * ____ _ _ __ __ _ __ __ ____
6  * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7  * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8  * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9  * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * @author PocketMine Team
17  * @link http://www.pocketmine.net/
18  *
19  *
20 */
21 
22 namespace pocketmine\math;
23 
25 
27 
28  public $minX;
29  public $minY;
30  public $minZ;
31  public $maxX;
32  public $maxY;
33  public $maxZ;
34 
35  public function __construct($minX, $minY, $minZ, $maxX, $maxY, $maxZ){
36  $this->minX = $minX;
37  $this->minY = $minY;
38  $this->minZ = $minZ;
39  $this->maxX = $maxX;
40  $this->maxY = $maxY;
41  $this->maxZ = $maxZ;
42  }
43 
44  public function setBounds($minX, $minY, $minZ, $maxX, $maxY, $maxZ){
45  $this->minX = $minX;
46  $this->minY = $minY;
47  $this->minZ = $minZ;
48  $this->maxX = $maxX;
49  $this->maxY = $maxY;
50  $this->maxZ = $maxZ;
51 
52  return $this;
53  }
54 
55  public function addCoord($x, $y, $z){
56  $minX = $this->minX;
57  $minY = $this->minY;
58  $minZ = $this->minZ;
59  $maxX = $this->maxX;
60  $maxY = $this->maxY;
61  $maxZ = $this->maxZ;
62 
63  if($x < 0){
64  $minX += $x;
65  }elseif($x > 0){
66  $maxX += $x;
67  }
68 
69  if($y < 0){
70  $minY += $y;
71  }elseif($y > 0){
72  $maxY += $y;
73  }
74 
75  if($z < 0){
76  $minZ += $z;
77  }elseif($z > 0){
78  $maxZ += $z;
79  }
80 
81  return new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ);
82  }
83 
84  public function grow($x, $y, $z){
85  return new AxisAlignedBB($this->minX - $x, $this->minY - $y, $this->minZ - $z, $this->maxX + $x, $this->maxY + $y, $this->maxZ + $z);
86  }
87 
88  public function expand($x, $y, $z){
89  $this->minX -= $x;
90  $this->minY -= $y;
91  $this->minZ -= $z;
92  $this->maxX += $x;
93  $this->maxY += $y;
94  $this->maxZ += $z;
95 
96  return $this;
97  }
98 
99  public function offset($x, $y, $z){
100  $this->minX += $x;
101  $this->minY += $y;
102  $this->minZ += $z;
103  $this->maxX += $x;
104  $this->maxY += $y;
105  $this->maxZ += $z;
106 
107  return $this;
108  }
109 
110  public function shrink($x, $y, $z){
111  return new AxisAlignedBB($this->minX + $x, $this->minY + $y, $this->minZ + $z, $this->maxX - $x, $this->maxY - $y, $this->maxZ - $z);
112  }
113 
114  public function contract($x, $y, $z){
115  $this->minX += $x;
116  $this->minY += $y;
117  $this->minZ += $z;
118  $this->maxX -= $x;
119  $this->maxY -= $y;
120  $this->maxZ -= $z;
121 
122  return $this;
123  }
124 
125  public function setBB(AxisAlignedBB $bb){
126  $this->minX = $bb->minX;
127  $this->minY = $bb->minY;
128  $this->minZ = $bb->minZ;
129  $this->maxX = $bb->maxX;
130  $this->maxY = $bb->maxY;
131  $this->maxZ = $bb->maxZ;
132  return $this;
133  }
134 
135  public function getOffsetBoundingBox($x, $y, $z){
136  return new AxisAlignedBB($this->minX + $x, $this->minY + $y, $this->minZ + $z, $this->maxX + $x, $this->maxY + $y, $this->maxZ + $z);
137  }
138 
139  public function calculateXOffset(AxisAlignedBB $bb, $x){
140  if($bb->maxY <= $this->minY or $bb->minY >= $this->maxY){
141  return $x;
142  }
143  if($bb->maxZ <= $this->minZ or $bb->minZ >= $this->maxZ){
144  return $x;
145  }
146  if($x > 0 and $bb->maxX <= $this->minX){
147  $x1 = $this->minX - $bb->maxX;
148  if($x1 < $x){
149  $x = $x1;
150  }
151  }
152  if($x < 0 and $bb->minX >= $this->maxX){
153  $x2 = $this->maxX - $bb->minX;
154  if($x2 > $x){
155  $x = $x2;
156  }
157  }
158 
159  return $x;
160  }
161 
162  public function calculateYOffset(AxisAlignedBB $bb, $y){
163  if($bb->maxX <= $this->minX or $bb->minX >= $this->maxX){
164  return $y;
165  }
166  if($bb->maxZ <= $this->minZ or $bb->minZ >= $this->maxZ){
167  return $y;
168  }
169  if($y > 0 and $bb->maxY <= $this->minY){
170  $y1 = $this->minY - $bb->maxY;
171  if($y1 < $y){
172  $y = $y1;
173  }
174  }
175  if($y < 0 and $bb->minY >= $this->maxY){
176  $y2 = $this->maxY - $bb->minY;
177  if($y2 > $y){
178  $y = $y2;
179  }
180  }
181 
182  return $y;
183  }
184 
185  public function calculateZOffset(AxisAlignedBB $bb, $z){
186  if($bb->maxX <= $this->minX or $bb->minX >= $this->maxX){
187  return $z;
188  }
189  if($bb->maxY <= $this->minY or $bb->minY >= $this->maxY){
190  return $z;
191  }
192  if($z > 0 and $bb->maxZ <= $this->minZ){
193  $z1 = $this->minZ - $bb->maxZ;
194  if($z1 < $z){
195  $z = $z1;
196  }
197  }
198  if($z < 0 and $bb->minZ >= $this->maxZ){
199  $z2 = $this->maxZ - $bb->minZ;
200  if($z2 > $z){
201  $z = $z2;
202  }
203  }
204 
205  return $z;
206  }
207 
208  public function intersectsWith(AxisAlignedBB $bb){
209  if($bb->maxX > $this->minX and $bb->minX < $this->maxX){
210  if($bb->maxY > $this->minY and $bb->minY < $this->maxY){
211  return $bb->maxZ > $this->minZ and $bb->minZ < $this->maxZ;
212  }
213  }
214 
215  return false;
216  }
217 
218  public function isVectorInside(Vector3 $vector){
219  if($vector->x <= $this->minX or $vector->x >= $this->maxX){
220  return false;
221  }
222  if($vector->y <= $this->minY or $vector->y >= $this->maxY){
223  return false;
224  }
225 
226  return $vector->z > $this->minZ and $vector->z < $this->maxZ;
227  }
228 
229  public function getAverageEdgeLength(){
230  return ($this->maxX - $this->minX + $this->maxY - $this->minY + $this->maxZ - $this->minZ) / 3;
231  }
232 
233  public function isVectorInYZ(Vector3 $vector){
234  return $vector->y >= $this->minY and $vector->y <= $this->maxY and $vector->z >= $this->minZ and $vector->z <= $this->maxZ;
235  }
236 
237  public function isVectorInXZ(Vector3 $vector){
238  return $vector->x >= $this->minX and $vector->x <= $this->maxX and $vector->z >= $this->minZ and $vector->z <= $this->maxZ;
239  }
240 
241  public function isVectorInXY(Vector3 $vector){
242  return $vector->x >= $this->minX and $vector->x <= $this->maxX and $vector->y >= $this->minY and $vector->y <= $this->maxY;
243  }
244 
245  public function calculateIntercept(Vector3 $pos1, Vector3 $pos2){
246  $v1 = $pos1->getIntermediateWithXValue($pos2, $this->minX);
247  $v2 = $pos1->getIntermediateWithXValue($pos2, $this->maxX);
248  $v3 = $pos1->getIntermediateWithYValue($pos2, $this->minY);
249  $v4 = $pos1->getIntermediateWithYValue($pos2, $this->maxY);
250  $v5 = $pos1->getIntermediateWithZValue($pos2, $this->minZ);
251  $v6 = $pos1->getIntermediateWithZValue($pos2, $this->maxZ);
252 
253  if($v1 !== null and !$this->isVectorInYZ($v1)){
254  $v1 = null;
255  }
256 
257  if($v2 !== null and !$this->isVectorInYZ($v2)){
258  $v2 = null;
259  }
260 
261  if($v3 !== null and !$this->isVectorInXZ($v3)){
262  $v3 = null;
263  }
264 
265  if($v4 !== null and !$this->isVectorInXZ($v4)){
266  $v4 = null;
267  }
268 
269  if($v5 !== null and !$this->isVectorInXY($v5)){
270  $v5 = null;
271  }
272 
273  if($v6 !== null and !$this->isVectorInXY($v6)){
274  $v6 = null;
275  }
276 
277  $vector = $v1;
278 
279  if($v2 !== null and ($vector === null or $pos1->distanceSquared($v2) < $pos1->distanceSquared($vector))){
280  $vector = $v2;
281  }
282 
283  if($v3 !== null and ($vector === null or $pos1->distanceSquared($v3) < $pos1->distanceSquared($vector))){
284  $vector = $v3;
285  }
286 
287  if($v4 !== null and ($vector === null or $pos1->distanceSquared($v4) < $pos1->distanceSquared($vector))){
288  $vector = $v4;
289  }
290 
291  if($v5 !== null and ($vector === null or $pos1->distanceSquared($v5) < $pos1->distanceSquared($vector))){
292  $vector = $v5;
293  }
294 
295  if($v6 !== null and ($vector === null or $pos1->distanceSquared($v6) < $pos1->distanceSquared($vector))){
296  $vector = $v6;
297  }
298 
299  if($vector === null){
300  return null;
301  }
302 
303  $f = -1;
304 
305  if($vector === $v1){
306  $f = 4;
307  }elseif($vector === $v2){
308  $f = 5;
309  }elseif($vector === $v3){
310  $f = 0;
311  }elseif($vector === $v4){
312  $f = 1;
313  }elseif($vector === $v5){
314  $f = 2;
315  }elseif($vector === $v6){
316  $f = 3;
317  }
318 
319  return MovingObjectPosition::fromBlock(0, 0, 0, $f, $vector);
320  }
321 }
getIntermediateWithZValue(Vector3 $v, $z)
Definition: Vector3.php:295
static fromBlock($x, $y, $z, $side, Vector3 $hitVector)
getIntermediateWithYValue(Vector3 $v, $y)
Definition: Vector3.php:268
getIntermediateWithXValue(Vector3 $v, $x)
Definition: Vector3.php:241