Code/net/minecraft/world/phys/shapes/BitSetDiscreteVoxelShape.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);
}
}