BlockUtil.java
net.minecraft.util.BlockUtil
信息
- 全限定名:net.minecraft.util.BlockUtil
- 类型:public class
- 包:net.minecraft.util
- 源码路径:src/main/java/net/minecraft/util/BlockUtil.java
- 起始行号:L15
- 职责:
TODO
字段/常量
- 无
内部类/嵌套类型
-
net.minecraft.util.BlockUtil.FoundRectangle- 类型:
class - 修饰符:
public static - 源码定位:
L135 - 说明:
TODO
- 类型:
-
net.minecraft.util.BlockUtil.IntBounds- 类型:
class - 修饰符:
public static - 源码定位:
L147 - 说明:
TODO
- 类型:
构造器
- 无
方法
下面的方法块按源码顺序生成。
public static BlockUtil.FoundRectangle getLargestRectangleAround(BlockPos center, Direction.Axis axis1, int limit1, Direction.Axis axis2, int limit2, Predicate<BlockPos> test) @ L16
- 方法名:getLargestRectangleAround
- 源码定位:L16
- 返回类型:BlockUtil.FoundRectangle
- 修饰符:public static
参数:
- center: BlockPos
- axis1: Direction.Axis
- limit1: int
- axis2: Direction.Axis
- limit2: int
- test: Predicate
说明:
TODO
private static int getLimit(Predicate<BlockPos> test, BlockPos.MutableBlockPos pos, Direction direction, int limit) @ L78
- 方法名:getLimit
- 源码定位:L78
- 返回类型:int
- 修饰符:private static
参数:
- test: Predicate
- pos: BlockPos.MutableBlockPos
- direction: Direction
- limit: int
说明:
TODO
static Pair<BlockUtil.IntBounds,Integer> getMaxRectangleLocation(int[] columns) @ L88
- 方法名:getMaxRectangleLocation
- 源码定位:L88
- 返回类型:Pair<BlockUtil.IntBounds,Integer>
- 修饰符:static
参数:
- columns: int[]
说明:
TODO
public static Optional<BlockPos> getTopConnectedBlock(BlockGetter level, BlockPos pos, Block bodyBlock, Direction growthDirection, Block headBlock) @ L123
- 方法名:getTopConnectedBlock
- 源码定位:L123
- 返回类型:Optional
- 修饰符:public static
参数:
- level: BlockGetter
- pos: BlockPos
- bodyBlock: Block
- growthDirection: Direction
- headBlock: Block
说明:
TODO
代码
public class BlockUtil {
public static BlockUtil.FoundRectangle getLargestRectangleAround(
BlockPos center, Direction.Axis axis1, int limit1, Direction.Axis axis2, int limit2, Predicate<BlockPos> test
) {
BlockPos.MutableBlockPos pos = center.mutable();
Direction negativeDirection1 = Direction.get(Direction.AxisDirection.NEGATIVE, axis1);
Direction positiveDirection1 = negativeDirection1.getOpposite();
Direction negativeDirection2 = Direction.get(Direction.AxisDirection.NEGATIVE, axis2);
Direction positiveDirection2 = negativeDirection2.getOpposite();
int negativeDelta1 = getLimit(test, pos.set(center), negativeDirection1, limit1);
int positiveDelta1 = getLimit(test, pos.set(center), positiveDirection1, limit1);
int centerIndex1 = negativeDelta1;
BlockUtil.IntBounds[] boundsByAxis1 = new BlockUtil.IntBounds[negativeDelta1 + 1 + positiveDelta1];
boundsByAxis1[negativeDelta1] = new BlockUtil.IntBounds(
getLimit(test, pos.set(center), negativeDirection2, limit2), getLimit(test, pos.set(center), positiveDirection2, limit2)
);
int centerIndex2 = boundsByAxis1[negativeDelta1].min;
for (int i = 1; i <= negativeDelta1; i++) {
BlockUtil.IntBounds lastBounds = boundsByAxis1[centerIndex1 - (i - 1)];
boundsByAxis1[centerIndex1 - i] = new BlockUtil.IntBounds(
getLimit(test, pos.set(center).move(negativeDirection1, i), negativeDirection2, lastBounds.min),
getLimit(test, pos.set(center).move(negativeDirection1, i), positiveDirection2, lastBounds.max)
);
}
for (int i = 1; i <= positiveDelta1; i++) {
BlockUtil.IntBounds lastBounds = boundsByAxis1[centerIndex1 + i - 1];
boundsByAxis1[centerIndex1 + i] = new BlockUtil.IntBounds(
getLimit(test, pos.set(center).move(positiveDirection1, i), negativeDirection2, lastBounds.min),
getLimit(test, pos.set(center).move(positiveDirection1, i), positiveDirection2, lastBounds.max)
);
}
int minAxis1 = 0;
int minAxis2 = 0;
int sizeAxis1 = 0;
int sizeAxis2 = 0;
int[] columns = new int[boundsByAxis1.length];
for (int i2 = centerIndex2; i2 >= 0; i2--) {
for (int i1 = 0; i1 < boundsByAxis1.length; i1++) {
BlockUtil.IntBounds bounds2 = boundsByAxis1[i1];
int min2 = centerIndex2 - bounds2.min;
int max2 = centerIndex2 + bounds2.max;
columns[i1] = i2 >= min2 && i2 <= max2 ? max2 + 1 - i2 : 0;
}
Pair<BlockUtil.IntBounds, Integer> rectangle = getMaxRectangleLocation(columns);
BlockUtil.IntBounds boundsAxis1 = rectangle.getFirst();
int newSizeAxis1 = 1 + boundsAxis1.max - boundsAxis1.min;
int newSizeAxis2 = rectangle.getSecond();
if (newSizeAxis1 * newSizeAxis2 > sizeAxis1 * sizeAxis2) {
minAxis1 = boundsAxis1.min;
minAxis2 = i2;
sizeAxis1 = newSizeAxis1;
sizeAxis2 = newSizeAxis2;
}
}
return new BlockUtil.FoundRectangle(center.relative(axis1, minAxis1 - centerIndex1).relative(axis2, minAxis2 - centerIndex2), sizeAxis1, sizeAxis2);
}
private static int getLimit(Predicate<BlockPos> test, BlockPos.MutableBlockPos pos, Direction direction, int limit) {
int max = 0;
while (max < limit && test.test(pos.move(direction))) {
max++;
}
return max;
}
@VisibleForTesting
static Pair<BlockUtil.IntBounds, Integer> getMaxRectangleLocation(int[] columns) {
int maxStart = 0;
int maxEnd = 0;
int maxHeight = 0;
IntStack stack = new IntArrayList();
stack.push(0);
for (int column = 1; column <= columns.length; column++) {
int height = column == columns.length ? 0 : columns[column];
while (!stack.isEmpty()) {
int stackHeight = columns[stack.topInt()];
if (height >= stackHeight) {
stack.push(column);
break;
}
stack.popInt();
int start = stack.isEmpty() ? 0 : stack.topInt() + 1;
if (stackHeight * (column - start) > maxHeight * (maxEnd - maxStart)) {
maxEnd = column;
maxStart = start;
maxHeight = stackHeight;
}
}
if (stack.isEmpty()) {
stack.push(column);
}
}
return new Pair<>(new BlockUtil.IntBounds(maxStart, maxEnd - 1), maxHeight);
}
public static Optional<BlockPos> getTopConnectedBlock(BlockGetter level, BlockPos pos, Block bodyBlock, Direction growthDirection, Block headBlock) {
BlockPos.MutableBlockPos forwardPos = pos.mutable();
BlockState forwardState;
do {
forwardPos.move(growthDirection);
forwardState = level.getBlockState(forwardPos);
} while (forwardState.is(bodyBlock));
return forwardState.is(headBlock) ? Optional.of(forwardPos) : Optional.empty();
}
public static class FoundRectangle {
public final BlockPos minCorner;
public final int axis1Size;
public final int axis2Size;
public FoundRectangle(BlockPos minCorner, int axis1Size, int axis2Size) {
this.minCorner = minCorner;
this.axis1Size = axis1Size;
this.axis2Size = axis2Size;
}
}
public static class IntBounds {
public final int min;
public final int max;
public IntBounds(int min, int max) {
this.min = min;
this.max = max;
}
@Override
public String toString() {
return "IntBounds{min=" + this.min + ", max=" + this.max + "}";
}
}
}引用的其他类
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
Direction.get()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置: