Code/net/minecraft/world/phys/shapes/DiscreteVoxelShape.java

278 lines
11 KiB
Java
Raw Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.world.phys.shapes;
import com.mojang.math.OctahedralGroup;
import net.minecraft.core.AxisCycle;
import net.minecraft.core.Direction;
public abstract class DiscreteVoxelShape {
private static final Direction.Axis[] AXIS_VALUES = Direction.Axis.values();
protected final int xSize;
protected final int ySize;
protected final int zSize;
protected DiscreteVoxelShape(int p_82787_, int p_82788_, int p_82789_) {
if (p_82787_ >= 0 && p_82788_ >= 0 && p_82789_ >= 0) {
this.xSize = p_82787_;
this.ySize = p_82788_;
this.zSize = p_82789_;
} else {
throw new IllegalArgumentException("Need all positive sizes: x: " + p_82787_ + ", y: " + p_82788_ + ", z: " + p_82789_);
}
}
public DiscreteVoxelShape rotate(OctahedralGroup p_393550_) {
if (p_393550_ == OctahedralGroup.IDENTITY) {
return this;
} else {
Direction.Axis direction$axis = p_393550_.permute(Direction.Axis.X);
Direction.Axis direction$axis1 = p_393550_.permute(Direction.Axis.Y);
Direction.Axis direction$axis2 = p_393550_.permute(Direction.Axis.Z);
int i = direction$axis.choose(this.xSize, this.ySize, this.zSize);
int j = direction$axis1.choose(this.xSize, this.ySize, this.zSize);
int k = direction$axis2.choose(this.xSize, this.ySize, this.zSize);
boolean flag = p_393550_.inverts(direction$axis);
boolean flag1 = p_393550_.inverts(direction$axis1);
boolean flag2 = p_393550_.inverts(direction$axis2);
boolean flag3 = direction$axis.choose(flag, flag1, flag2);
boolean flag4 = direction$axis1.choose(flag, flag1, flag2);
boolean flag5 = direction$axis2.choose(flag, flag1, flag2);
DiscreteVoxelShape discretevoxelshape = new BitSetDiscreteVoxelShape(i, j, k);
for (int l = 0; l < this.xSize; l++) {
for (int i1 = 0; i1 < this.ySize; i1++) {
for (int j1 = 0; j1 < this.zSize; j1++) {
if (this.isFull(l, i1, j1)) {
int k1 = direction$axis.choose(l, i1, j1);
int l1 = direction$axis1.choose(l, i1, j1);
int i2 = direction$axis2.choose(l, i1, j1);
discretevoxelshape.fill(flag3 ? i - 1 - k1 : k1, flag4 ? j - 1 - l1 : l1, flag5 ? k - 1 - i2 : i2);
}
}
}
}
return discretevoxelshape;
}
}
public boolean isFullWide(AxisCycle p_82823_, int p_82824_, int p_82825_, int p_82826_) {
return this.isFullWide(
p_82823_.cycle(p_82824_, p_82825_, p_82826_, Direction.Axis.X),
p_82823_.cycle(p_82824_, p_82825_, p_82826_, Direction.Axis.Y),
p_82823_.cycle(p_82824_, p_82825_, p_82826_, Direction.Axis.Z)
);
}
public boolean isFullWide(int p_82847_, int p_82848_, int p_82849_) {
if (p_82847_ < 0 || p_82848_ < 0 || p_82849_ < 0) {
return false;
} else {
return p_82847_ < this.xSize && p_82848_ < this.ySize && p_82849_ < this.zSize ? this.isFull(p_82847_, p_82848_, p_82849_) : false;
}
}
public boolean isFull(AxisCycle p_82836_, int p_82837_, int p_82838_, int p_82839_) {
return this.isFull(
p_82836_.cycle(p_82837_, p_82838_, p_82839_, Direction.Axis.X),
p_82836_.cycle(p_82837_, p_82838_, p_82839_, Direction.Axis.Y),
p_82836_.cycle(p_82837_, p_82838_, p_82839_, Direction.Axis.Z)
);
}
public abstract boolean isFull(int p_82829_, int p_82830_, int p_82831_);
public abstract void fill(int p_165998_, int p_165999_, int p_166000_);
public boolean isEmpty() {
for (Direction.Axis direction$axis : AXIS_VALUES) {
if (this.firstFull(direction$axis) >= this.lastFull(direction$axis)) {
return true;
}
}
return false;
}
public abstract int firstFull(Direction.Axis p_82827_);
public abstract int lastFull(Direction.Axis p_82840_);
public int firstFull(Direction.Axis p_165995_, int p_165996_, int p_165997_) {
int i = this.getSize(p_165995_);
if (p_165996_ >= 0 && p_165997_ >= 0) {
Direction.Axis direction$axis = AxisCycle.FORWARD.cycle(p_165995_);
Direction.Axis direction$axis1 = AxisCycle.BACKWARD.cycle(p_165995_);
if (p_165996_ < this.getSize(direction$axis) && p_165997_ < this.getSize(direction$axis1)) {
AxisCycle axiscycle = AxisCycle.between(Direction.Axis.X, p_165995_);
for (int j = 0; j < i; j++) {
if (this.isFull(axiscycle, j, p_165996_, p_165997_)) {
return j;
}
}
return i;
} else {
return i;
}
} else {
return i;
}
}
public int lastFull(Direction.Axis p_82842_, int p_82843_, int p_82844_) {
if (p_82843_ >= 0 && p_82844_ >= 0) {
Direction.Axis direction$axis = AxisCycle.FORWARD.cycle(p_82842_);
Direction.Axis direction$axis1 = AxisCycle.BACKWARD.cycle(p_82842_);
if (p_82843_ < this.getSize(direction$axis) && p_82844_ < this.getSize(direction$axis1)) {
int i = this.getSize(p_82842_);
AxisCycle axiscycle = AxisCycle.between(Direction.Axis.X, p_82842_);
for (int j = i - 1; j >= 0; j--) {
if (this.isFull(axiscycle, j, p_82843_, p_82844_)) {
return j + 1;
}
}
return 0;
} else {
return 0;
}
} else {
return 0;
}
}
public int getSize(Direction.Axis p_82851_) {
return p_82851_.choose(this.xSize, this.ySize, this.zSize);
}
public int getXSize() {
return this.getSize(Direction.Axis.X);
}
public int getYSize() {
return this.getSize(Direction.Axis.Y);
}
public int getZSize() {
return this.getSize(Direction.Axis.Z);
}
public void forAllEdges(DiscreteVoxelShape.IntLineConsumer p_82820_, boolean p_82821_) {
this.forAllAxisEdges(p_82820_, AxisCycle.NONE, p_82821_);
this.forAllAxisEdges(p_82820_, AxisCycle.FORWARD, p_82821_);
this.forAllAxisEdges(p_82820_, AxisCycle.BACKWARD, p_82821_);
}
private void forAllAxisEdges(DiscreteVoxelShape.IntLineConsumer p_82816_, AxisCycle p_82817_, boolean p_82818_) {
AxisCycle axiscycle = p_82817_.inverse();
int j = this.getSize(axiscycle.cycle(Direction.Axis.X));
int k = this.getSize(axiscycle.cycle(Direction.Axis.Y));
int l = this.getSize(axiscycle.cycle(Direction.Axis.Z));
for (int i1 = 0; i1 <= j; i1++) {
for (int j1 = 0; j1 <= k; j1++) {
int i = -1;
for (int k1 = 0; k1 <= l; k1++) {
int l1 = 0;
int i2 = 0;
for (int j2 = 0; j2 <= 1; j2++) {
for (int k2 = 0; k2 <= 1; k2++) {
if (this.isFullWide(axiscycle, i1 + j2 - 1, j1 + k2 - 1, k1)) {
l1++;
i2 ^= j2 ^ k2;
}
}
}
if (l1 == 1 || l1 == 3 || l1 == 2 && (i2 & 1) == 0) {
if (p_82818_) {
if (i == -1) {
i = k1;
}
} else {
p_82816_.consume(
axiscycle.cycle(i1, j1, k1, Direction.Axis.X),
axiscycle.cycle(i1, j1, k1, Direction.Axis.Y),
axiscycle.cycle(i1, j1, k1, Direction.Axis.Z),
axiscycle.cycle(i1, j1, k1 + 1, Direction.Axis.X),
axiscycle.cycle(i1, j1, k1 + 1, Direction.Axis.Y),
axiscycle.cycle(i1, j1, k1 + 1, Direction.Axis.Z)
);
}
} else if (i != -1) {
p_82816_.consume(
axiscycle.cycle(i1, j1, i, Direction.Axis.X),
axiscycle.cycle(i1, j1, i, Direction.Axis.Y),
axiscycle.cycle(i1, j1, i, Direction.Axis.Z),
axiscycle.cycle(i1, j1, k1, Direction.Axis.X),
axiscycle.cycle(i1, j1, k1, Direction.Axis.Y),
axiscycle.cycle(i1, j1, k1, Direction.Axis.Z)
);
i = -1;
}
}
}
}
}
public void forAllBoxes(DiscreteVoxelShape.IntLineConsumer p_82833_, boolean p_82834_) {
BitSetDiscreteVoxelShape.forAllBoxes(this, p_82833_, p_82834_);
}
public void forAllFaces(DiscreteVoxelShape.IntFaceConsumer p_82811_) {
this.forAllAxisFaces(p_82811_, AxisCycle.NONE);
this.forAllAxisFaces(p_82811_, AxisCycle.FORWARD);
this.forAllAxisFaces(p_82811_, AxisCycle.BACKWARD);
}
private void forAllAxisFaces(DiscreteVoxelShape.IntFaceConsumer p_82813_, AxisCycle p_82814_) {
AxisCycle axiscycle = p_82814_.inverse();
Direction.Axis direction$axis = axiscycle.cycle(Direction.Axis.Z);
int i = this.getSize(axiscycle.cycle(Direction.Axis.X));
int j = this.getSize(axiscycle.cycle(Direction.Axis.Y));
int k = this.getSize(direction$axis);
Direction direction = Direction.fromAxisAndDirection(direction$axis, Direction.AxisDirection.NEGATIVE);
Direction direction1 = Direction.fromAxisAndDirection(direction$axis, Direction.AxisDirection.POSITIVE);
for (int l = 0; l < i; l++) {
for (int i1 = 0; i1 < j; i1++) {
boolean flag = false;
for (int j1 = 0; j1 <= k; j1++) {
boolean flag1 = j1 != k && this.isFull(axiscycle, l, i1, j1);
if (!flag && flag1) {
p_82813_.consume(
direction,
axiscycle.cycle(l, i1, j1, Direction.Axis.X),
axiscycle.cycle(l, i1, j1, Direction.Axis.Y),
axiscycle.cycle(l, i1, j1, Direction.Axis.Z)
);
}
if (flag && !flag1) {
p_82813_.consume(
direction1,
axiscycle.cycle(l, i1, j1 - 1, Direction.Axis.X),
axiscycle.cycle(l, i1, j1 - 1, Direction.Axis.Y),
axiscycle.cycle(l, i1, j1 - 1, Direction.Axis.Z)
);
}
flag = flag1;
}
}
}
}
public interface IntFaceConsumer {
void consume(Direction p_82854_, int p_82855_, int p_82856_, int p_82857_);
}
public interface IntLineConsumer {
void consume(int p_82859_, int p_82860_, int p_82861_, int p_82862_, int p_82863_, int p_82864_);
}
}