mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-08 01:17:47 +01:00
fix: bad collision shape parsing
This commit is contained in:
parent
d8ef618d08
commit
666bb98957
@ -25,6 +25,7 @@ public class Main {
|
|||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.setProperty("minestom.use-new-chunk-sending", "true");
|
System.setProperty("minestom.use-new-chunk-sending", "true");
|
||||||
|
System.setProperty("minestom.experiment.pose-updates", "true");
|
||||||
|
|
||||||
MinecraftServer minecraftServer = MinecraftServer.init();
|
MinecraftServer minecraftServer = MinecraftServer.init();
|
||||||
|
|
||||||
|
@ -161,27 +161,55 @@ public final class BoundingBox implements Shape {
|
|||||||
return relativeEnd().z();
|
return relativeEnd().z();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum AxisMask {
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
Z,
|
||||||
|
NONE
|
||||||
|
}
|
||||||
|
|
||||||
public Iterator<Point> getBlocks(Point point) {
|
public Iterator<Point> getBlocks(Point point) {
|
||||||
return new PointIterator(this, point);
|
return new PointIterator(this, point, AxisMask.NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<Point> getBlocks(Point point, AxisMask axisMask, double axis) {
|
||||||
|
return new PointIterator(this, point, axisMask, axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class PointIterator implements Iterator<Point> {
|
static class PointIterator implements Iterator<Point> {
|
||||||
int x = 0;
|
private final double sx, sy, sz;
|
||||||
int y = 0;
|
double x, y, z;
|
||||||
int z = 0;
|
private double minX, minY, minZ, maxX, maxY, maxZ;
|
||||||
|
|
||||||
private final int minX, minY, minZ, maxX, maxY, maxZ;
|
public PointIterator(BoundingBox boundingBox, Point p, AxisMask axisMask, double axis) {
|
||||||
|
|
||||||
public PointIterator(BoundingBox boundingBox, Point p) {
|
|
||||||
minX = (int) Math.floor(boundingBox.minX() + p.x());
|
minX = (int) Math.floor(boundingBox.minX() + p.x());
|
||||||
minY = (int) Math.floor(boundingBox.minY() + p.y());
|
minY = (int) Math.floor(boundingBox.minY() + p.y());
|
||||||
minZ = (int) Math.floor(boundingBox.minZ() + p.z());
|
minZ = (int) Math.floor(boundingBox.minZ() + p.z());
|
||||||
maxX = (int) Math.floor(boundingBox.maxX() + p.x());
|
maxX = (int) Math.floor(boundingBox.maxX() + p.x());
|
||||||
maxY = (int) Math.floor(boundingBox.maxY() + p.y());
|
maxY = (int) Math.floor(boundingBox.maxY() + p.y());
|
||||||
maxZ = (int) Math.floor(boundingBox.maxZ() + p.z());
|
maxZ = (int) Math.floor(boundingBox.maxZ() + p.z());
|
||||||
|
|
||||||
x = minX;
|
x = minX;
|
||||||
y = minY;
|
y = minY;
|
||||||
z = minZ;
|
z = minZ;
|
||||||
|
|
||||||
|
sx = boundingBox.minX() + p.x() - minX;
|
||||||
|
sy = boundingBox.minY() + p.y() - minY;
|
||||||
|
sz = boundingBox.minZ() + p.z() - minZ;
|
||||||
|
|
||||||
|
if (axisMask == AxisMask.X) {
|
||||||
|
x = axis + p.x();
|
||||||
|
minX = x;
|
||||||
|
maxX = x;
|
||||||
|
} else if (axisMask == AxisMask.Y) {
|
||||||
|
y = axis + p.y();
|
||||||
|
minY = y;
|
||||||
|
maxY = y;
|
||||||
|
} else if (axisMask == AxisMask.Z) {
|
||||||
|
z = axis + p.z();
|
||||||
|
minZ = z;
|
||||||
|
maxZ = z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -191,7 +219,7 @@ public final class BoundingBox implements Shape {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Point next() {
|
public Point next() {
|
||||||
var res = new Vec(x, y, z);
|
var res = new Vec(x + sx, y + sy, z + sz);
|
||||||
|
|
||||||
x++;
|
x++;
|
||||||
if (x > maxX) {
|
if (x > maxX) {
|
||||||
@ -202,7 +230,6 @@ public final class BoundingBox implements Shape {
|
|||||||
z++;
|
z++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ public final class ShapeImpl implements Shape {
|
|||||||
this.blockOcclusion = fullFaces;
|
this.blockOcclusion = fullFaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
static private BoundingBox[] parseRegistryBoundingBoxString(String str) {
|
private static BoundingBox[] parseRegistryBoundingBoxString(String str) {
|
||||||
final Matcher matcher = PATTERN.matcher(str);
|
final Matcher matcher = PATTERN.matcher(str);
|
||||||
DoubleList vals = new DoubleArrayList();
|
DoubleList vals = new DoubleArrayList();
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
|
@ -804,7 +804,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
|||||||
var pos = iter.next();
|
var pos = iter.next();
|
||||||
var hit = instance.getBlock(pos, Block.Getter.Condition.TYPE)
|
var hit = instance.getBlock(pos, Block.Getter.Condition.TYPE)
|
||||||
.registry().collisionShape()
|
.registry().collisionShape()
|
||||||
.intersectBox(position.sub(pos), bb);
|
.intersectBox(position.sub(pos.blockX(), pos.blockY(), pos.blockZ()), bb);
|
||||||
if (hit) return false;
|
if (hit) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,10 @@ public class BlockIterator implements Iterator<Point> {
|
|||||||
*/
|
*/
|
||||||
public BlockIterator(@NotNull Vec start, @NotNull Vec direction, double yOffset, double maxDistance, boolean smooth) {
|
public BlockIterator(@NotNull Vec start, @NotNull Vec direction, double yOffset, double maxDistance, boolean smooth) {
|
||||||
start = start.add(0, yOffset, 0);
|
start = start.add(0, yOffset, 0);
|
||||||
end = start.add(direction.normalize().mul(maxDistance));
|
|
||||||
|
if (maxDistance != 0) end = start.add(direction.normalize().mul(maxDistance));
|
||||||
|
else end = null;
|
||||||
|
|
||||||
if (direction.isZero()) this.foundEnd = true;
|
if (direction.isZero()) this.foundEnd = true;
|
||||||
|
|
||||||
this.smooth = smooth;
|
this.smooth = smooth;
|
||||||
@ -75,21 +78,17 @@ public class BlockIterator implements Iterator<Point> {
|
|||||||
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
|
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
|
//calculate step and initial sideDist
|
||||||
if (ray.x() < 0) {
|
if (ray.x() < 0) sideDistX = (start.x() - mapX) * deltaDistX;
|
||||||
sideDistX = (start.x() - mapX) * deltaDistX;
|
else if (ray.x() > 0) sideDistX = (mapX + signums[0] - start.x()) * deltaDistX;
|
||||||
} else {
|
else sideDistX = Double.MAX_VALUE;
|
||||||
sideDistX = (mapX + 1.0 - start.x()) * deltaDistX;
|
|
||||||
}
|
if (ray.y() < 0) sideDistY = (start.y() - mapY) * deltaDistY;
|
||||||
if (ray.y() < 0) {
|
else if (ray.y() > 0) sideDistY = (mapY + signums[1] - start.y()) * deltaDistY;
|
||||||
sideDistY = (start.y() - mapY) * deltaDistY;
|
else sideDistY = Double.MAX_VALUE;
|
||||||
} else {
|
|
||||||
sideDistY = (mapY + 1.0 - start.y()) * deltaDistY;
|
if (ray.z() < 0) sideDistZ = (start.z() - mapZ) * deltaDistZ;
|
||||||
}
|
else if (ray.z() > 0) sideDistZ = (mapZ + signums[2] - start.z()) * deltaDistZ;
|
||||||
if (ray.z() < 0) {
|
else sideDistZ = Double.MAX_VALUE;
|
||||||
sideDistZ = (start.z() - mapZ) * deltaDistZ;
|
|
||||||
} else {
|
|
||||||
sideDistZ = (mapZ + 1.0 - start.z()) * deltaDistZ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,17 +203,17 @@ public class BlockIterator implements Iterator<Point> {
|
|||||||
if (foundEnd) throw new NoSuchElementException();
|
if (foundEnd) throw new NoSuchElementException();
|
||||||
if (!extraPoints.isEmpty()) {
|
if (!extraPoints.isEmpty()) {
|
||||||
var res = extraPoints.poll();
|
var res = extraPoints.poll();
|
||||||
if (res.sameBlock(end)) foundEnd = true;
|
if (end != null && res.sameBlock(end)) foundEnd = true;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
var current = new Vec(mapX, mapY, mapZ);
|
var current = new Vec(mapX, mapY, mapZ);
|
||||||
if (current.sameBlock(end)) foundEnd = true;
|
if (end != null && current.sameBlock(end)) foundEnd = true;
|
||||||
|
|
||||||
double closest = Math.min(sideDistX, Math.min(sideDistY, sideDistZ));
|
double closest = Math.min(sideDistX, Math.min(sideDistY, sideDistZ));
|
||||||
boolean needsX = sideDistX - closest < 1e-10;
|
boolean needsX = sideDistX - closest < 1e-10 && signums[0] != 0;
|
||||||
boolean needsY = sideDistY - closest < 1e-10;
|
boolean needsY = sideDistY - closest < 1e-10 && signums[1] != 0;
|
||||||
boolean needsZ = sideDistZ - closest < 1e-10;
|
boolean needsZ = sideDistZ - closest < 1e-10 && signums[2] != 0;
|
||||||
|
|
||||||
if (needsZ) {
|
if (needsZ) {
|
||||||
sideDistZ += deltaDistZ;
|
sideDistZ += deltaDistZ;
|
||||||
@ -232,8 +231,13 @@ public class BlockIterator implements Iterator<Point> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needsX && needsY && needsZ) {
|
if (needsX && needsY && needsZ) {
|
||||||
extraPoints.add(new Vec(signums[0] + current.x(), current.y(), current.z()));
|
extraPoints.add(new Vec(signums[0] + current.x(), signums[1] + current.y(), current.z()));
|
||||||
if (smooth) return current;
|
if (smooth) return current;
|
||||||
|
|
||||||
|
extraPoints.add(new Vec(current.x(), signums[1] + current.y(), signums[2] + current.z()));
|
||||||
|
extraPoints.add(new Vec(signums[0] + current.x(), current.y(), signums[2] + current.z()));
|
||||||
|
|
||||||
|
extraPoints.add(new Vec(signums[0] + current.x(), current.y(), current.z()));
|
||||||
extraPoints.add(new Vec(current.x(), signums[1] + current.y(), current.z()));
|
extraPoints.add(new Vec(current.x(), signums[1] + current.y(), current.z()));
|
||||||
extraPoints.add(new Vec(current.x(), current.y(), signums[2] + current.z()));
|
extraPoints.add(new Vec(current.x(), current.y(), signums[2] + current.z()));
|
||||||
} else if (needsX && needsY) {
|
} else if (needsX && needsY) {
|
||||||
|
Loading…
Reference in New Issue
Block a user