Calculates the intersection of this bounding box with the specified line segment. Intersections at edges and corners yield one of the affected block faces as hit result, but it is not defined which of them. @param start the start position @param direction the ray direction @param maxDistance th
(@NotNull Vector start, @NotNull Vector direction, double maxDistance)
| 830 | * @return the ray trace hit result, or <code>null</code> if there is no hit |
| 831 | */ |
| 832 | @Nullable |
| 833 | public RayTraceResult rayTrace(@NotNull Vector start, @NotNull Vector direction, double maxDistance) { |
| 834 | Validate.notNull(start, "Start is null!"); |
| 835 | start.checkFinite(); |
| 836 | Validate.notNull(direction, "Direction is null!"); |
| 837 | direction.checkFinite(); |
| 838 | Validate.isTrue(direction.lengthSquared() > 0, "Direction's magnitude is 0!"); |
| 839 | if (maxDistance < 0.0D) return null; |
| 840 | |
| 841 | // ray start: |
| 842 | double startX = start.getX(); |
| 843 | double startY = start.getY(); |
| 844 | double startZ = start.getZ(); |
| 845 | |
| 846 | // ray direction: |
| 847 | Vector dir = direction.clone().normalizeZeros().normalize(); |
| 848 | double dirX = dir.getX(); |
| 849 | double dirY = dir.getY(); |
| 850 | double dirZ = dir.getZ(); |
| 851 | |
| 852 | // saving a few divisions below: |
| 853 | // Note: If one of the direction vector components is 0.0, these |
| 854 | // divisions result in infinity. But this is not a problem. |
| 855 | double divX = 1.0D / dirX; |
| 856 | double divY = 1.0D / dirY; |
| 857 | double divZ = 1.0D / dirZ; |
| 858 | |
| 859 | double tMin; |
| 860 | double tMax; |
| 861 | BlockFace hitBlockFaceMin; |
| 862 | BlockFace hitBlockFaceMax; |
| 863 | |
| 864 | // intersections with x planes: |
| 865 | if (dirX >= 0.0D) { |
| 866 | tMin = (this.minX - startX) * divX; |
| 867 | tMax = (this.maxX - startX) * divX; |
| 868 | hitBlockFaceMin = BlockFace.WEST; |
| 869 | hitBlockFaceMax = BlockFace.EAST; |
| 870 | } else { |
| 871 | tMin = (this.maxX - startX) * divX; |
| 872 | tMax = (this.minX - startX) * divX; |
| 873 | hitBlockFaceMin = BlockFace.EAST; |
| 874 | hitBlockFaceMax = BlockFace.WEST; |
| 875 | } |
| 876 | |
| 877 | // intersections with y planes: |
| 878 | double tyMin; |
| 879 | double tyMax; |
| 880 | BlockFace hitBlockFaceYMin; |
| 881 | BlockFace hitBlockFaceYMax; |
| 882 | if (dirY >= 0.0D) { |
| 883 | tyMin = (this.minY - startY) * divY; |
| 884 | tyMax = (this.maxY - startY) * divY; |
| 885 | hitBlockFaceYMin = BlockFace.DOWN; |
| 886 | hitBlockFaceYMax = BlockFace.UP; |
| 887 | } else { |
| 888 | tyMin = (this.maxY - startY) * divY; |
| 889 | tyMax = (this.minY - startY) * divY; |
no test coverage detected