mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-06 16:37:38 +01:00
Blockiterator fix 4 (#1513)
This commit is contained in:
parent
d496fcfe4a
commit
1a013728fd
@ -14,18 +14,84 @@ import java.util.NoSuchElementException;
|
|||||||
* This class performs ray tracing and iterates along blocks on a line
|
* This class performs ray tracing and iterates along blocks on a line
|
||||||
*/
|
*/
|
||||||
public class BlockIterator implements Iterator<Point> {
|
public class BlockIterator implements Iterator<Point> {
|
||||||
private final Vec direction;
|
|
||||||
private final Point start;
|
|
||||||
|
|
||||||
private final Point[] points = new Point[3];
|
|
||||||
private final double[] distances = new double[3];
|
|
||||||
private final short[] signums = new short[3];
|
private final short[] signums = new short[3];
|
||||||
|
|
||||||
private final Vec end;
|
private final Vec end;
|
||||||
|
private final boolean smooth;
|
||||||
|
|
||||||
private boolean foundEnd = false;
|
private boolean foundEnd = false;
|
||||||
|
|
||||||
|
//length of ray from current position to next x or y-side
|
||||||
|
double sideDistX;
|
||||||
|
double sideDistY;
|
||||||
|
double sideDistZ;
|
||||||
|
|
||||||
|
//length of ray from one x or y-side to next x or y-side
|
||||||
|
private final double deltaDistX;
|
||||||
|
private final double deltaDistY;
|
||||||
|
private final double deltaDistZ;
|
||||||
|
|
||||||
|
//which box of the map we're in
|
||||||
|
int mapX;
|
||||||
|
int mapY;
|
||||||
|
int mapZ;
|
||||||
|
|
||||||
private final ArrayDeque<Point> extraPoints = new ArrayDeque<>();
|
private final ArrayDeque<Point> extraPoints = new ArrayDeque<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the BlockIterator.
|
||||||
|
* <p>
|
||||||
|
* This considers all blocks as 1x1x1 in size.
|
||||||
|
*
|
||||||
|
* @param start A Vector giving the initial position for the trace
|
||||||
|
* @param direction A Vector pointing in the direction for the trace
|
||||||
|
* @param yOffset The trace begins vertically offset from the start vector
|
||||||
|
* by this value
|
||||||
|
* @param smooth A boolean indicating whether the cast should be smooth.
|
||||||
|
* Smooth casts will only include one block when intersecting multiple axis lines.
|
||||||
|
* @param maxDistance This is the maximum distance in blocks for the
|
||||||
|
* trace. Setting this value above 140 may lead to problems with
|
||||||
|
* unloaded chunks. A value of 0 indicates no limit
|
||||||
|
*/
|
||||||
|
public BlockIterator(@NotNull Vec start, @NotNull Vec direction, double yOffset, double maxDistance, boolean smooth) {
|
||||||
|
start = start.add(0, yOffset, 0);
|
||||||
|
end = start.add(direction.normalize().mul(maxDistance));
|
||||||
|
if (direction.isZero()) this.foundEnd = true;
|
||||||
|
|
||||||
|
this.smooth = smooth;
|
||||||
|
|
||||||
|
Vec ray = direction.normalize();
|
||||||
|
|
||||||
|
//which box of the map we're in
|
||||||
|
mapX = start.blockX();
|
||||||
|
mapY = start.blockY();
|
||||||
|
mapZ = start.blockZ();
|
||||||
|
|
||||||
|
signums[0] = (short) Math.signum(direction.x());
|
||||||
|
signums[1] = (short) Math.signum(direction.y());
|
||||||
|
signums[2] = (short) Math.signum(direction.z());
|
||||||
|
|
||||||
|
deltaDistX = (ray.x() == 0) ? 1e30 : Math.abs(1 / ray.x());
|
||||||
|
deltaDistY = (ray.y() == 0) ? 1e30 : Math.abs(1 / ray.y()); // Find grid intersections for x, y, z
|
||||||
|
deltaDistZ = (ray.z() == 0) ? 1e30 : Math.abs(1 / ray.z()); // This works by calculating and storing the distance to the next grid intersection on the x, y and z axis
|
||||||
|
|
||||||
|
//calculate step and initial sideDist
|
||||||
|
if (ray.x() < 0) {
|
||||||
|
sideDistX = (start.x() - mapX) * deltaDistX;
|
||||||
|
} else {
|
||||||
|
sideDistX = (mapX + 1.0 - start.x()) * deltaDistX;
|
||||||
|
}
|
||||||
|
if (ray.y() < 0) {
|
||||||
|
sideDistY = (start.y() - mapY) * deltaDistY;
|
||||||
|
} else {
|
||||||
|
sideDistY = (mapY + 1.0 - start.y()) * deltaDistY;
|
||||||
|
}
|
||||||
|
if (ray.z() < 0) {
|
||||||
|
sideDistZ = (start.z() - mapZ) * deltaDistZ;
|
||||||
|
} else {
|
||||||
|
sideDistZ = (mapZ + 1.0 - start.z()) * deltaDistZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the BlockIterator.
|
* Constructs the BlockIterator.
|
||||||
* <p>
|
* <p>
|
||||||
@ -40,27 +106,7 @@ public class BlockIterator implements Iterator<Point> {
|
|||||||
* unloaded chunks. A value of 0 indicates no limit
|
* unloaded chunks. A value of 0 indicates no limit
|
||||||
*/
|
*/
|
||||||
public BlockIterator(@NotNull Vec start, @NotNull Vec direction, double yOffset, double maxDistance) {
|
public BlockIterator(@NotNull Vec start, @NotNull Vec direction, double yOffset, double maxDistance) {
|
||||||
this.direction = direction;
|
this(start, direction, yOffset, maxDistance, false);
|
||||||
this.start = start.add(0, yOffset, 0);
|
|
||||||
this.end = start.add(0, yOffset, 0).add(direction.normalize().mul(maxDistance)).apply(Vec.Operator.FLOOR);
|
|
||||||
|
|
||||||
if (this.direction.isZero()) this.foundEnd = true;
|
|
||||||
|
|
||||||
signums[0] = (short) Math.signum(direction.x());
|
|
||||||
signums[1] = (short) Math.signum(direction.y());
|
|
||||||
signums[2] = (short) Math.signum(direction.z());
|
|
||||||
|
|
||||||
// Find grid intersections for x, y, z
|
|
||||||
// This works by calculating and storing the distance to the next grid intersection on the x, y and z axis
|
|
||||||
// On every iteration, we return the nearest grid intersection and update it
|
|
||||||
calculateIntersectionX(start, direction, signums[0] > 0 ? 1 : 0);
|
|
||||||
calculateIntersectionY(start, direction, signums[1] > 0 ? 1 : 0);
|
|
||||||
calculateIntersectionZ(start, direction, signums[2] > 0 ? 1 : 0);
|
|
||||||
|
|
||||||
// If directions are 0, set distances to max to stop the intersection point from being used
|
|
||||||
if (direction.x() == 0) distances[0] = Double.MAX_VALUE;
|
|
||||||
if (direction.y() == 0) distances[1] = Double.MAX_VALUE;
|
|
||||||
if (direction.z() == 0) distances[2] = Double.MAX_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +123,7 @@ public class BlockIterator implements Iterator<Point> {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public BlockIterator(@NotNull Pos pos, double yOffset, int maxDistance) {
|
public BlockIterator(@NotNull Pos pos, double yOffset, int maxDistance) {
|
||||||
this(pos.asVec(), pos.direction(), yOffset, maxDistance);
|
this(pos.asVec(), pos.direction(), yOffset, maxDistance, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,7 +137,7 @@ public class BlockIterator implements Iterator<Point> {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public BlockIterator(@NotNull Pos pos, double yOffset) {
|
public BlockIterator(@NotNull Pos pos, double yOffset) {
|
||||||
this(pos.asVec(), pos.direction(), yOffset, 0);
|
this(pos.asVec(), pos.direction(), yOffset, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,89 +202,54 @@ public class BlockIterator implements Iterator<Point> {
|
|||||||
@Override
|
@Override
|
||||||
public Point next() {
|
public Point next() {
|
||||||
if (foundEnd) throw new NoSuchElementException();
|
if (foundEnd) throw new NoSuchElementException();
|
||||||
|
if (!extraPoints.isEmpty()) {
|
||||||
// If we have entries in the extra points queue, return those first
|
var res = extraPoints.poll();
|
||||||
var res = extraPoints.isEmpty() ? updateClosest() : extraPoints.poll();
|
if (res.sameBlock(end)) foundEnd = true;
|
||||||
// If we have reached the end, set the flag
|
return res;
|
||||||
if (res.sameBlock(end)) foundEnd = true;
|
|
||||||
return new Vec(res.blockX(), res.blockY(), res.blockZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void calculateIntersectionX(Point start, Vec direction, int signum) {
|
|
||||||
double x = Math.floor(start.x()) + signum;
|
|
||||||
double y = start.y() + (x - start.x()) * direction.y() / direction.x();
|
|
||||||
double z = start.z() + (x - start.x()) * direction.z() / direction.x();
|
|
||||||
points[0] = new Vec(x, y, z);
|
|
||||||
distances[0] = this.start.distance(points[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void calculateIntersectionY(Point start, Vec direction, int signum) {
|
|
||||||
double y = Math.floor(start.y()) + signum;
|
|
||||||
double x = start.x() + (y - start.y()) * direction.x() / direction.y();
|
|
||||||
double z = start.z() + (y - start.y()) * direction.z() / direction.y();
|
|
||||||
points[1] = new Vec(x, y, z);
|
|
||||||
distances[1] = this.start.distance(points[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void calculateIntersectionZ(Point start, Vec direction, int signum) {
|
|
||||||
double z = Math.floor(start.z()) + signum;
|
|
||||||
double x = start.x() + (z - start.z()) * direction.x() / direction.z();
|
|
||||||
double y = start.y() + (z - start.z()) * direction.y() / direction.z();
|
|
||||||
points[2] = new Vec(x, y, z);
|
|
||||||
distances[2] = this.start.distance(points[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point updateClosest() {
|
|
||||||
// Find minimum distance
|
|
||||||
double minDistance = Double.MAX_VALUE;
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
if (distances[i] < minDistance) {
|
|
||||||
minDistance = distances[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] sub = new int[3];
|
var current = new Vec(mapX, mapY, mapZ);
|
||||||
boolean needsX = Math.abs(distances[0] - minDistance) <= Vec.EPSILON;
|
if (current.sameBlock(end)) foundEnd = true;
|
||||||
boolean needsY = Math.abs(distances[1] - minDistance) <= Vec.EPSILON;
|
|
||||||
boolean needsZ = Math.abs(distances[2] - minDistance) <= Vec.EPSILON;
|
double closest = Math.min(sideDistX, Math.min(sideDistY, sideDistZ));
|
||||||
|
boolean needsX = sideDistX - closest < 1e-10;
|
||||||
|
boolean needsY = sideDistY - closest < 1e-10;
|
||||||
|
boolean needsZ = sideDistZ - closest < 1e-10;
|
||||||
|
|
||||||
// Update all points that are minimum distance
|
|
||||||
Point closest = null;
|
|
||||||
if (needsX) {
|
|
||||||
closest = points[0];
|
|
||||||
if (signums[0] == 1) sub[0] = 1;
|
|
||||||
calculateIntersectionX(points[0], direction, signums[0]);
|
|
||||||
}
|
|
||||||
if (needsY) {
|
|
||||||
closest = points[1];
|
|
||||||
if (signums[1] == 1) sub[1] = 1;
|
|
||||||
calculateIntersectionY(points[1], direction, signums[1]);
|
|
||||||
}
|
|
||||||
if (needsZ) {
|
if (needsZ) {
|
||||||
closest = points[2];
|
sideDistZ += deltaDistZ;
|
||||||
if (signums[2] == 1) sub[2] = 1;
|
mapZ += signums[2];
|
||||||
calculateIntersectionZ(points[2], direction, signums[2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we pass a grid line in the positive direction, we subtract 1 to get the block we just passed over
|
if (needsX) {
|
||||||
closest = closest.sub(sub[0], sub[1], sub[2]);
|
sideDistX += deltaDistX;
|
||||||
|
mapX += signums[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsY) {
|
||||||
|
sideDistY += deltaDistY;
|
||||||
|
mapY += signums[1];
|
||||||
|
}
|
||||||
|
|
||||||
// If multiple grid lines are cross at the same time, we need to add the blocks that are missed
|
|
||||||
if (needsX && needsY && needsZ) {
|
if (needsX && needsY && needsZ) {
|
||||||
extraPoints.add(closest.add(signums[0], 0, 0));
|
extraPoints.add(new Vec(signums[0] + current.x(), current.y(), current.z()));
|
||||||
extraPoints.add(closest.add(0, signums[1], 0));
|
if (smooth) return current;
|
||||||
extraPoints.add(closest.add(0, 0, signums[2]));
|
extraPoints.add(new Vec(current.x(), signums[1] + current.y(), current.z()));
|
||||||
|
extraPoints.add(new Vec(current.x(), current.y(), signums[2] + current.z()));
|
||||||
} else if (needsX && needsY) {
|
} else if (needsX && needsY) {
|
||||||
extraPoints.add(closest.add(signums[0], 0, 0));
|
extraPoints.add(new Vec(signums[0] + current.x(), current.y(), current.z()));
|
||||||
extraPoints.add(closest.add(0, signums[1], 0));
|
if (smooth) return current;
|
||||||
|
extraPoints.add(new Vec(current.x(), signums[1] + current.y(), current.z()));
|
||||||
} else if (needsX && needsZ) {
|
} else if (needsX && needsZ) {
|
||||||
extraPoints.add(closest.add(signums[0], 0, 0));
|
extraPoints.add(new Vec(signums[0] + current.x(), current.y(), current.z()));
|
||||||
extraPoints.add(closest.add(0, 0, signums[2]));
|
if (smooth) return current;
|
||||||
|
extraPoints.add(new Vec(current.x(), current.y(), signums[2] + current.z()));
|
||||||
} else if (needsY && needsZ) {
|
} else if (needsY && needsZ) {
|
||||||
extraPoints.add(closest.add(0, signums[1], 0));
|
extraPoints.add(new Vec(current.x(), signums[1] + current.y(), current.z()));
|
||||||
extraPoints.add(closest.add(0, 0, signums[2]));
|
if (smooth) return current;
|
||||||
|
extraPoints.add(new Vec(current.x(), current.y(), signums[2] + current.z()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return closest;
|
return current;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -82,6 +82,158 @@ public class BlockIteratorTest {
|
|||||||
assertFalse(iterator.hasNext());
|
assertFalse(iterator.hasNext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLongDistance() {
|
||||||
|
Vec s = new Vec(42.5, 0, 51.5);
|
||||||
|
Vec e = new Vec(-12, 0, -36);
|
||||||
|
BlockIterator iterator = new BlockIterator(s, e, 0, 37);
|
||||||
|
|
||||||
|
List<Point> points = new ArrayList<>();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
points.add(iterator.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
Point[] validPoints = new Point[] {
|
||||||
|
new Vec(42.0, 0.0, 51.0),
|
||||||
|
new Vec(42.0, 0.0, 50.0),
|
||||||
|
new Vec(41.0, 0.0, 50.0),
|
||||||
|
new Vec(42.0, 0.0, 49.0),
|
||||||
|
new Vec(41.0, 0.0, 49.0),
|
||||||
|
new Vec(41.0, 0.0, 48.0),
|
||||||
|
new Vec(41.0, 0.0, 47.0),
|
||||||
|
new Vec(40.0, 0.0, 47.0),
|
||||||
|
new Vec(41.0, 0.0, 46.0),
|
||||||
|
new Vec(40.0, 0.0, 46.0),
|
||||||
|
new Vec(40.0, 0.0, 45.0),
|
||||||
|
new Vec(40.0, 0.0, 44.0),
|
||||||
|
new Vec(39.0, 0.0, 44.0),
|
||||||
|
new Vec(40.0, 0.0, 43.0),
|
||||||
|
new Vec(39.0, 0.0, 43.0),
|
||||||
|
new Vec(39.0, 0.0, 42.0),
|
||||||
|
new Vec(39.0, 0.0, 41.0),
|
||||||
|
new Vec(38.0, 0.0, 41.0),
|
||||||
|
new Vec(39.0, 0.0, 40.0),
|
||||||
|
new Vec(38.0, 0.0, 40.0),
|
||||||
|
new Vec(38.0, 0.0, 39.0),
|
||||||
|
new Vec(38.0, 0.0, 38.0),
|
||||||
|
new Vec(37.0, 0.0, 38.0),
|
||||||
|
new Vec(38.0, 0.0, 37.0),
|
||||||
|
new Vec(37.0, 0.0, 37.0),
|
||||||
|
new Vec(37.0, 0.0, 36.0),
|
||||||
|
new Vec(37.0, 0.0, 35.0),
|
||||||
|
new Vec(36.0, 0.0, 35.0),
|
||||||
|
new Vec(37.0, 0.0, 34.0),
|
||||||
|
new Vec(36.0, 0.0, 34.0),
|
||||||
|
new Vec(36.0, 0.0, 33.0),
|
||||||
|
new Vec(36.0, 0.0, 32.0),
|
||||||
|
new Vec(35.0, 0.0, 32.0),
|
||||||
|
new Vec(36.0, 0.0, 31.0),
|
||||||
|
new Vec(35.0, 0.0, 31.0),
|
||||||
|
new Vec(35.0, 0.0, 30.0),
|
||||||
|
new Vec(35.0, 0.0, 29.0),
|
||||||
|
new Vec(34.0, 0.0, 29.0),
|
||||||
|
new Vec(35.0, 0.0, 28.0),
|
||||||
|
new Vec(34.0, 0.0, 28.0),
|
||||||
|
new Vec(34.0, 0.0, 27.0),
|
||||||
|
new Vec(34.0, 0.0, 26.0),
|
||||||
|
new Vec(33.0, 0.0, 26.0),
|
||||||
|
new Vec(34.0, 0.0, 25.0),
|
||||||
|
new Vec(33.0, 0.0, 25.0),
|
||||||
|
new Vec(33.0, 0.0, 24.0),
|
||||||
|
new Vec(33.0, 0.0, 23.0),
|
||||||
|
new Vec(32.0, 0.0, 23.0),
|
||||||
|
new Vec(33.0, 0.0, 22.0),
|
||||||
|
new Vec(32.0, 0.0, 22.0),
|
||||||
|
new Vec(32.0, 0.0, 21.0),
|
||||||
|
new Vec(32.0, 0.0, 20.0),
|
||||||
|
new Vec(31.0, 0.0, 20.0),
|
||||||
|
new Vec(32.0, 0.0, 19.0),
|
||||||
|
new Vec(31.0, 0.0, 19.0),
|
||||||
|
new Vec(31.0, 0.0, 18.0),
|
||||||
|
new Vec(31.0, 0.0, 17.0),
|
||||||
|
new Vec(30.0, 0.0, 17.0),
|
||||||
|
new Vec(31.0, 0.0, 16.0),
|
||||||
|
new Vec(30.0, 0.0, 16.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (Point p : validPoints) {
|
||||||
|
assertContains(points, p);
|
||||||
|
}
|
||||||
|
assertEquals(validPoints.length, points.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSkipping() {
|
||||||
|
Vec s = new Vec(0.5, 40, 0.5);
|
||||||
|
Vec e = new Vec(27, 0, 21);
|
||||||
|
BlockIterator iterator = new BlockIterator(s, e, 0, 34);
|
||||||
|
|
||||||
|
List<Point> points = new ArrayList<>();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
points.add(iterator.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
Point[] validPoints = new Point[] {
|
||||||
|
new Vec(0.0, 40.0, 0.0),
|
||||||
|
new Vec(1.0, 40.0, 0.0),
|
||||||
|
new Vec(1.0, 40.0, 1.0),
|
||||||
|
new Vec(2.0, 40.0, 1.0),
|
||||||
|
new Vec(2.0, 40.0, 2.0),
|
||||||
|
new Vec(3.0, 40.0, 2.0),
|
||||||
|
new Vec(3.0, 40.0, 3.0),
|
||||||
|
new Vec(4.0, 40.0, 3.0),
|
||||||
|
new Vec(5.0, 40.0, 3.0),
|
||||||
|
new Vec(4.0, 40.0, 4.0),
|
||||||
|
new Vec(5.0, 40.0, 4.0),
|
||||||
|
new Vec(6.0, 40.0, 4.0),
|
||||||
|
new Vec(6.0, 40.0, 5.0),
|
||||||
|
new Vec(7.0, 40.0, 5.0),
|
||||||
|
new Vec(7.0, 40.0, 6.0),
|
||||||
|
new Vec(8.0, 40.0, 6.0),
|
||||||
|
new Vec(8.0, 40.0, 7.0),
|
||||||
|
new Vec(9.0, 40.0, 7.0),
|
||||||
|
new Vec(10.0, 40.0, 7.0),
|
||||||
|
new Vec(10.0, 40.0, 8.0),
|
||||||
|
new Vec(11.0, 40.0, 8.0),
|
||||||
|
new Vec(11.0, 40.0, 9.0),
|
||||||
|
new Vec(12.0, 40.0, 9.0),
|
||||||
|
new Vec(12.0, 40.0, 10.0),
|
||||||
|
new Vec(13.0, 40.0, 10.0),
|
||||||
|
new Vec(14.0, 40.0, 10.0),
|
||||||
|
new Vec(13.0, 40.0, 11.0),
|
||||||
|
new Vec(14.0, 40.0, 11.0),
|
||||||
|
new Vec(15.0, 40.0, 11.0),
|
||||||
|
new Vec(15.0, 40.0, 12.0),
|
||||||
|
new Vec(16.0, 40.0, 12.0),
|
||||||
|
new Vec(16.0, 40.0, 13.0),
|
||||||
|
new Vec(17.0, 40.0, 13.0),
|
||||||
|
new Vec(17.0, 40.0, 14.0),
|
||||||
|
new Vec(18.0, 40.0, 14.0),
|
||||||
|
new Vec(19.0, 40.0, 14.0),
|
||||||
|
new Vec(19.0, 40.0, 15.0),
|
||||||
|
new Vec(20.0, 40.0, 15.0),
|
||||||
|
new Vec(20.0, 40.0, 16.0),
|
||||||
|
new Vec(21.0, 40.0, 16.0),
|
||||||
|
new Vec(21.0, 40.0, 17.0),
|
||||||
|
new Vec(22.0, 40.0, 17.0),
|
||||||
|
new Vec(23.0, 40.0, 17.0),
|
||||||
|
new Vec(22.0, 40.0, 18.0),
|
||||||
|
new Vec(23.0, 40.0, 18.0),
|
||||||
|
new Vec(24.0, 40.0, 18.0),
|
||||||
|
new Vec(24.0, 40.0, 19.0),
|
||||||
|
new Vec(25.0, 40.0, 19.0),
|
||||||
|
new Vec(25.0, 40.0, 20.0),
|
||||||
|
new Vec(26.0, 40.0, 20.0),
|
||||||
|
new Vec(26.0, 40.0, 21.0),
|
||||||
|
new Vec(27.0, 40.0, 21.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (Point p : validPoints) {
|
||||||
|
assertContains(points, p);
|
||||||
|
}
|
||||||
|
assertEquals(validPoints.length, points.size());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExactEnd() {
|
public void testExactEnd() {
|
||||||
Vec s = new Vec(0.5, 0, 0.5);
|
Vec s = new Vec(0.5, 0, 0.5);
|
||||||
|
Loading…
Reference in New Issue
Block a user