233 lines
9.5 KiB
Java
233 lines
9.5 KiB
Java
|
package net.minecraft.world.phys.shapes;
|
||
|
|
||
|
import java.util.BitSet;
|
||
|
import net.minecraft.core.Direction;
|
||
|
|
||
|
public final class BitSetDiscreteVoxelShape extends DiscreteVoxelShape {
|
||
|
private final BitSet storage;
|
||
|
private int xMin;
|
||
|
private int yMin;
|
||
|
private int zMin;
|
||
|
private int xMax;
|
||
|
private int yMax;
|
||
|
private int zMax;
|
||
|
|
||
|
public BitSetDiscreteVoxelShape(int p_82588_, int p_82589_, int p_82590_) {
|
||
|
super(p_82588_, p_82589_, p_82590_);
|
||
|
this.storage = new BitSet(p_82588_ * p_82589_ * p_82590_);
|
||
|
this.xMin = p_82588_;
|
||
|
this.yMin = p_82589_;
|
||
|
this.zMin = p_82590_;
|
||
|
}
|
||
|
|
||
|
public static BitSetDiscreteVoxelShape withFilledBounds(
|
||
|
int p_165933_, int p_165934_, int p_165935_, int p_165936_, int p_165937_, int p_165938_, int p_165939_, int p_165940_, int p_165941_
|
||
|
) {
|
||
|
BitSetDiscreteVoxelShape bitsetdiscretevoxelshape = new BitSetDiscreteVoxelShape(p_165933_, p_165934_, p_165935_);
|
||
|
bitsetdiscretevoxelshape.xMin = p_165936_;
|
||
|
bitsetdiscretevoxelshape.yMin = p_165937_;
|
||
|
bitsetdiscretevoxelshape.zMin = p_165938_;
|
||
|
bitsetdiscretevoxelshape.xMax = p_165939_;
|
||
|
bitsetdiscretevoxelshape.yMax = p_165940_;
|
||
|
bitsetdiscretevoxelshape.zMax = p_165941_;
|
||
|
|
||
|
for (int i = p_165936_; i < p_165939_; i++) {
|
||
|
for (int j = p_165937_; j < p_165940_; j++) {
|
||
|
for (int k = p_165938_; k < p_165941_; k++) {
|
||
|
bitsetdiscretevoxelshape.fillUpdateBounds(i, j, k, false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bitsetdiscretevoxelshape;
|
||
|
}
|
||
|
|
||
|
public BitSetDiscreteVoxelShape(DiscreteVoxelShape p_82602_) {
|
||
|
super(p_82602_.xSize, p_82602_.ySize, p_82602_.zSize);
|
||
|
if (p_82602_ instanceof BitSetDiscreteVoxelShape) {
|
||
|
this.storage = (BitSet)((BitSetDiscreteVoxelShape)p_82602_).storage.clone();
|
||
|
} else {
|
||
|
this.storage = new BitSet(this.xSize * this.ySize * this.zSize);
|
||
|
|
||
|
for (int i = 0; i < this.xSize; i++) {
|
||
|
for (int j = 0; j < this.ySize; j++) {
|
||
|
for (int k = 0; k < this.zSize; k++) {
|
||
|
if (p_82602_.isFull(i, j, k)) {
|
||
|
this.storage.set(this.getIndex(i, j, k));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.xMin = p_82602_.firstFull(Direction.Axis.X);
|
||
|
this.yMin = p_82602_.firstFull(Direction.Axis.Y);
|
||
|
this.zMin = p_82602_.firstFull(Direction.Axis.Z);
|
||
|
this.xMax = p_82602_.lastFull(Direction.Axis.X);
|
||
|
this.yMax = p_82602_.lastFull(Direction.Axis.Y);
|
||
|
this.zMax = p_82602_.lastFull(Direction.Axis.Z);
|
||
|
}
|
||
|
|
||
|
protected int getIndex(int p_82605_, int p_82606_, int p_82607_) {
|
||
|
return (p_82605_ * this.ySize + p_82606_) * this.zSize + p_82607_;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean isFull(int p_82676_, int p_82677_, int p_82678_) {
|
||
|
return this.storage.get(this.getIndex(p_82676_, p_82677_, p_82678_));
|
||
|
}
|
||
|
|
||
|
private void fillUpdateBounds(int p_165943_, int p_165944_, int p_165945_, boolean p_165946_) {
|
||
|
this.storage.set(this.getIndex(p_165943_, p_165944_, p_165945_));
|
||
|
if (p_165946_) {
|
||
|
this.xMin = Math.min(this.xMin, p_165943_);
|
||
|
this.yMin = Math.min(this.yMin, p_165944_);
|
||
|
this.zMin = Math.min(this.zMin, p_165945_);
|
||
|
this.xMax = Math.max(this.xMax, p_165943_ + 1);
|
||
|
this.yMax = Math.max(this.yMax, p_165944_ + 1);
|
||
|
this.zMax = Math.max(this.zMax, p_165945_ + 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void fill(int p_165987_, int p_165988_, int p_165989_) {
|
||
|
this.fillUpdateBounds(p_165987_, p_165988_, p_165989_, true);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean isEmpty() {
|
||
|
return this.storage.isEmpty();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public int firstFull(Direction.Axis p_82674_) {
|
||
|
return p_82674_.choose(this.xMin, this.yMin, this.zMin);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public int lastFull(Direction.Axis p_82680_) {
|
||
|
return p_82680_.choose(this.xMax, this.yMax, this.zMax);
|
||
|
}
|
||
|
|
||
|
static BitSetDiscreteVoxelShape join(
|
||
|
DiscreteVoxelShape p_82642_, DiscreteVoxelShape p_82643_, IndexMerger p_82644_, IndexMerger p_82645_, IndexMerger p_82646_, BooleanOp p_82647_
|
||
|
) {
|
||
|
BitSetDiscreteVoxelShape bitsetdiscretevoxelshape = new BitSetDiscreteVoxelShape(p_82644_.size() - 1, p_82645_.size() - 1, p_82646_.size() - 1);
|
||
|
int[] aint = new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE};
|
||
|
p_82644_.forMergedIndexes((p_82670_, p_82671_, p_82672_) -> {
|
||
|
boolean[] aboolean = new boolean[]{false};
|
||
|
p_82645_.forMergedIndexes((p_165978_, p_165979_, p_165980_) -> {
|
||
|
boolean[] aboolean1 = new boolean[]{false};
|
||
|
p_82646_.forMergedIndexes((p_165960_, p_165961_, p_165962_) -> {
|
||
|
if (p_82647_.apply(p_82642_.isFullWide(p_82670_, p_165978_, p_165960_), p_82643_.isFullWide(p_82671_, p_165979_, p_165961_))) {
|
||
|
bitsetdiscretevoxelshape.storage.set(bitsetdiscretevoxelshape.getIndex(p_82672_, p_165980_, p_165962_));
|
||
|
aint[2] = Math.min(aint[2], p_165962_);
|
||
|
aint[5] = Math.max(aint[5], p_165962_);
|
||
|
aboolean1[0] = true;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
});
|
||
|
if (aboolean1[0]) {
|
||
|
aint[1] = Math.min(aint[1], p_165980_);
|
||
|
aint[4] = Math.max(aint[4], p_165980_);
|
||
|
aboolean[0] = true;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
});
|
||
|
if (aboolean[0]) {
|
||
|
aint[0] = Math.min(aint[0], p_82672_);
|
||
|
aint[3] = Math.max(aint[3], p_82672_);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
});
|
||
|
bitsetdiscretevoxelshape.xMin = aint[0];
|
||
|
bitsetdiscretevoxelshape.yMin = aint[1];
|
||
|
bitsetdiscretevoxelshape.zMin = aint[2];
|
||
|
bitsetdiscretevoxelshape.xMax = aint[3] + 1;
|
||
|
bitsetdiscretevoxelshape.yMax = aint[4] + 1;
|
||
|
bitsetdiscretevoxelshape.zMax = aint[5] + 1;
|
||
|
return bitsetdiscretevoxelshape;
|
||
|
}
|
||
|
|
||
|
protected static void forAllBoxes(DiscreteVoxelShape p_165964_, DiscreteVoxelShape.IntLineConsumer p_165965_, boolean p_165966_) {
|
||
|
BitSetDiscreteVoxelShape bitsetdiscretevoxelshape = new BitSetDiscreteVoxelShape(p_165964_);
|
||
|
|
||
|
for (int i = 0; i < bitsetdiscretevoxelshape.ySize; i++) {
|
||
|
for (int j = 0; j < bitsetdiscretevoxelshape.xSize; j++) {
|
||
|
int k = -1;
|
||
|
|
||
|
for (int l = 0; l <= bitsetdiscretevoxelshape.zSize; l++) {
|
||
|
if (bitsetdiscretevoxelshape.isFullWide(j, i, l)) {
|
||
|
if (p_165966_) {
|
||
|
if (k == -1) {
|
||
|
k = l;
|
||
|
}
|
||
|
} else {
|
||
|
p_165965_.consume(j, i, l, j + 1, i + 1, l + 1);
|
||
|
}
|
||
|
} else if (k != -1) {
|
||
|
int i1 = j;
|
||
|
int j1 = i;
|
||
|
bitsetdiscretevoxelshape.clearZStrip(k, l, j, i);
|
||
|
|
||
|
while (bitsetdiscretevoxelshape.isZStripFull(k, l, i1 + 1, i)) {
|
||
|
bitsetdiscretevoxelshape.clearZStrip(k, l, i1 + 1, i);
|
||
|
i1++;
|
||
|
}
|
||
|
|
||
|
while (bitsetdiscretevoxelshape.isXZRectangleFull(j, i1 + 1, k, l, j1 + 1)) {
|
||
|
for (int k1 = j; k1 <= i1; k1++) {
|
||
|
bitsetdiscretevoxelshape.clearZStrip(k, l, k1, j1 + 1);
|
||
|
}
|
||
|
|
||
|
j1++;
|
||
|
}
|
||
|
|
||
|
p_165965_.consume(j, i, k, i1 + 1, j1 + 1, l);
|
||
|
k = -1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private boolean isZStripFull(int p_82609_, int p_82610_, int p_82611_, int p_82612_) {
|
||
|
return p_82611_ < this.xSize && p_82612_ < this.ySize
|
||
|
? this.storage.nextClearBit(this.getIndex(p_82611_, p_82612_, p_82609_)) >= this.getIndex(p_82611_, p_82612_, p_82610_)
|
||
|
: false;
|
||
|
}
|
||
|
|
||
|
private boolean isXZRectangleFull(int p_165927_, int p_165928_, int p_165929_, int p_165930_, int p_165931_) {
|
||
|
for (int i = p_165927_; i < p_165928_; i++) {
|
||
|
if (!this.isZStripFull(p_165929_, p_165930_, i, p_165931_)) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
private void clearZStrip(int p_165982_, int p_165983_, int p_165984_, int p_165985_) {
|
||
|
this.storage.clear(this.getIndex(p_165984_, p_165985_, p_165982_), this.getIndex(p_165984_, p_165985_, p_165983_));
|
||
|
}
|
||
|
|
||
|
public boolean isInterior(int p_327963_, int p_332610_, int p_332051_) {
|
||
|
boolean flag = p_327963_ > 0
|
||
|
&& p_327963_ < this.xSize - 1
|
||
|
&& p_332610_ > 0
|
||
|
&& p_332610_ < this.ySize - 1
|
||
|
&& p_332051_ > 0
|
||
|
&& p_332051_ < this.zSize - 1;
|
||
|
return flag
|
||
|
&& this.isFull(p_327963_, p_332610_, p_332051_)
|
||
|
&& this.isFull(p_327963_ - 1, p_332610_, p_332051_)
|
||
|
&& this.isFull(p_327963_ + 1, p_332610_, p_332051_)
|
||
|
&& this.isFull(p_327963_, p_332610_ - 1, p_332051_)
|
||
|
&& this.isFull(p_327963_, p_332610_ + 1, p_332051_)
|
||
|
&& this.isFull(p_327963_, p_332610_, p_332051_ - 1)
|
||
|
&& this.isFull(p_327963_, p_332610_, p_332051_ + 1);
|
||
|
}
|
||
|
}
|