下面列出了怎么用net.minecraft.util.math.shapes.VoxelShape的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
VoxelShape shape = TANK_SHAPE;
TileEntity t = worldIn.getTileEntity(pos);
if (t instanceof TileEnderTank) {
TileEnderTank tile = (TileEnderTank) t;
shape = SHAPES[tile.rotation];
}
return shape;
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
VoxelShape shape = CHEST_SHAPE;
TileEntity t = worldIn.getTileEntity(pos);
if (t instanceof TileEnderChest) {
TileEnderChest tile = (TileEnderChest) t;
shape = SHAPES[tile.rotation][tile.getRadianLidAngle(0) >= 0 ? 0 : 1];
}
return shape;
}
public VoxelShape update(Collection<T> things) {
partCache.clear();
for (T thing : things) {
partCache.add(extractor.apply(thing));
}
if (!partCache.equals(shapeParts) || mergedShape == null) {
shapeParts.clear();
shapeParts.addAll(partCache);
//Same as VoxelShapes.or(VoxelShapes.empty(), shapeParts.toArray()); Except we skip useless array creation.
VoxelShape merged = shapeParts.stream().reduce(VoxelShapes.empty(), VoxelShapes::or);
mergedShape = postProcess.apply(merged);
}
return mergedShape;
}
public static BlockRayTraceResult retraceBlock(IBlockReader world, PlayerEntity player, BlockPos pos) {
Vec3d startVec = getStartVec(player);
Vec3d endVec = getEndVec(player);
BlockState state = world.getBlockState(pos);
VoxelShape baseShape = state.getShape(world, pos);
BlockRayTraceResult baseTraceResult = baseShape.rayTrace(startVec, endVec, pos);
if (baseTraceResult != null) {
BlockRayTraceResult raytraceTraceShape = state.getRaytraceShape(world, pos).rayTrace(startVec, endVec, pos);
if (raytraceTraceShape != null) {
return raytraceTraceShape;
}
}
return baseTraceResult;
}
/**
* @param shape The base advertised VoxelShape. (Collision / w/e)
* @param cuboids Any SubHit's.
*/
public SubHitVoxelShape(VoxelShape shape, List<IndexedCuboid6> cuboids) {
super(shape.part);
this.shape = shape;
cuboidShapes = cuboids.stream()//
.map(e -> Pair.of(e, VoxelShapeCache.getShape(e)))//
.collect(Collectors.toList());
}
@Nullable
@Override
public BlockRayTraceResult rayTrace(Vec3d start, Vec3d end, BlockPos pos) {
CuboidRayTraceResult closest = null;
double dist = Double.MAX_VALUE;
for (Pair<IndexedCuboid6, VoxelShape> cuboidShape : cuboidShapes) {
CuboidRayTraceResult hit = rayTrace(start, end, pos, cuboidShape.getLeft(), cuboidShape.getRight());
if (hit != null && dist > hit.dist) {
closest = hit;
dist = hit.dist;
}
}
return closest;
}
private CuboidRayTraceResult rayTrace(Vec3d start, Vec3d end, BlockPos pos, IndexedCuboid6 cuboid, VoxelShape shape) {
BlockRayTraceResult hit = shape.rayTrace(start, end, pos);
if (hit != null) {
Vector3 hitVec = new Vector3(hit.getHitVec());
return new CuboidRayTraceResult(hitVec, hit.getFace(), pos, hit.isInside(), cuboid, hitVec.copy().subtract(start).magSquared());
}
return null;
}
public static VoxelShape getShape(AxisAlignedBB aabb) {
VoxelShape shape = bbToShapeCache.getIfPresent(aabb);
if (shape == null) {
shape = VoxelShapes.create(aabb);
bbToShapeCache.put(aabb, shape);
MutablePair<AxisAlignedBB, Cuboid6> entry = getReverse(shape);
if (entry.getLeft() == null) {
entry.setLeft(aabb);
}
}
return shape;
}
public static VoxelShape getShape(Cuboid6 cuboid) {
VoxelShape shape = cuboidToShapeCache.getIfPresent(cuboid);
if (shape == null) {
shape = VoxelShapes.create(cuboid.min.x, cuboid.min.y, cuboid.min.z, cuboid.max.x, cuboid.max.y, cuboid.max.z);
cuboidToShapeCache.put(cuboid, shape);
MutablePair<AxisAlignedBB, Cuboid6> entry = getReverse(shape);
if (entry.getRight() == null) {
entry.setRight(cuboid);
}
}
return shape;
}
public static AxisAlignedBB getAABB(VoxelShape shape) {
MutablePair<AxisAlignedBB, Cuboid6> entry = getReverse(shape);
if (entry.getLeft() == null) {
entry.setLeft(shape.getBoundingBox());
}
return entry.getLeft();
}
public static Cuboid6 getCuboid(VoxelShape shape) {
MutablePair<AxisAlignedBB, Cuboid6> entry = getReverse(shape);
if (entry.getRight() == null) {
entry.setRight(new Cuboid6(// I hope this is okay, don't want to rely on AABB cache.
shape.getStart(Direction.Axis.X), shape.getStart(Direction.Axis.Y), shape.getStart(Direction.Axis.Z),//
shape.getEnd(Direction.Axis.X), shape.getEnd(Direction.Axis.Y), shape.getEnd(Direction.Axis.Z)//
));
}
return entry.getRight();
}
private static MutablePair<AxisAlignedBB, Cuboid6> getReverse(VoxelShape shape) {
MutablePair<AxisAlignedBB, Cuboid6> entry = shapeToBBCuboid.getIfPresent(shape);
if (entry == null) {
entry = new MutablePair<>();
shapeToBBCuboid.put(shape, entry);
}
return entry;
}
static boolean isSpawnable(World world, BlockPos pos, BlockState spawnBlockState, BlockState upperBlockState) {
VoxelShape collisionShape = upperBlockState.getCollisionShape(world, pos);
boolean isNether = world.dimension.isNether();
return spawnBlockState.canEntitySpawn(world, pos.down(), isNether ? EntityType.ZOMBIE_PIGMAN : entityType) &&
!Block.doesSideFillSquare(collisionShape, Direction.UP) &&
!upperBlockState.canProvidePower() &&
!upperBlockState.isIn(BlockTags.RAILS) &&
collisionShape.getEnd(Direction.Axis.Y) <= 0 &&
upperBlockState.getFluidState().isEmpty() &&
(isNether || world.getLightFor(LightType.BLOCK, pos) <= 7);
}
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
return VoxelShapes.empty();
}
/**
* @deprecated call via {@link BlockState#getPushReaction()} whenever possible. Implementing/overriding is fine.
*/
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext selectionContext) {
return SHAPE;
}
public VoxelShape shape() {
return VoxelShapeCache.getShape(this);
}
public MergedVoxelShapeHolder<T> setExtractor(Function<T, VoxelShape> extractor) {
this.extractor = extractor;
return this;
}
public MergedVoxelShapeHolder<T> setPostProcessHook(Function<VoxelShape, VoxelShape> postProcess) {
this.postProcess = postProcess;
return this;
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context)
{
return SHAPE;
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context)
{
return (state.get(FACING).getHorizontalIndex() % 2) == 0 ? shape1 : shape2;
}