Files
Applied-Energistics-2/src/main/java/appeng/parts/VoxelShapeCache.java
T
Sebastian Hartte 0be7322c2c Formatting Fixes.
2020-09-09 02:27:12 +02:00

83 lines
3.0 KiB
Java

/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.parts;
import java.util.List;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import net.minecraft.util.function.BooleanBiFunction;
import net.minecraft.util.math.Box;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
/**
* While creation of a {@link net.minecraft.util.shape.VoxelShape} with
* {@link net.minecraft.util.shape.VoxelShapes#cuboid(Box)} is fast enough,
* combining voxel shapes with
* {@link net.minecraft.util.shape.VoxelShapes#union(VoxelShape, VoxelShape)} or
* any other combination method, as well as {@link VoxelShape#simplify()} are
* <b>extremely slow</b>. For example: Creating a VoxelShape for a list of 5
* bounding boxes 10,000 times takes about 1.7 seconds.
*
* <p>
* To reduce the impact of this on cables, we introduce a global voxel shape
* cache so that cables can share their combined voxel shapes better.
*/
final class VoxelShapeCache {
// Why using a List here should not make much of a difference vs. using a Set:
// The part's bounding box depends on the side it is attached to, and the sides
// are iterated over in a fixed order, meaning the order of bounding boxes
// should
// be the same for a same set of parts.
private static final LoadingCache<List<Box>, VoxelShape> CACHE = CacheBuilder.newBuilder()//
.maximumSize(10000L)//
.build(new CacheLoader<List<Box>, VoxelShape>() {
@Override
public VoxelShape load(List<Box> key) {
return create(key);
}
});
private VoxelShapeCache() {
}
public static VoxelShape get(List<Box> boxes) {
return CACHE.getUnchecked(boxes);
}
private static VoxelShape create(List<Box> boxes) {
if (boxes.isEmpty()) {
return VoxelShapes.empty();
}
int i = 0;
VoxelShape shape = VoxelShapes.cuboid(boxes.get(i));
for (; i < boxes.size(); i++) {
Box box = boxes.get(i);
shape = VoxelShapes.combine(shape, VoxelShapes.cuboid(box), BooleanBiFunction.OR);
}
return shape.simplify();
}
}