use of gnu.trove.map.hash.TObjectDoubleHashMap in project RecurrentComplex by Ivorforce.
the class TransformerAbstractCloud method buildCloud.
public TObjectDoubleMap<BlockPos> buildCloud(S instanceData, IvWorldData worldData, StructurePrepareContext context, TransformerMulti transformer, TransformerMulti.InstanceData transformerInstanceData) {
Random random = context.random;
Environment environment = context.environment;
BlockPos lowerCoord = StructureBoundingBoxes.min(context.boundingBox);
int[] strucSize = new int[] { worldData.blockCollection.width, worldData.blockCollection.height, worldData.blockCollection.length };
TObjectDoubleMap<BlockPos> cloud = new TObjectDoubleHashMap<>();
BlurredValueField blurredValueField = new BlurredValueField(strucSize);
int gridCoords = 1;
for (int d : strucSize) gridCoords *= d;
int values = MathHelper.floor(gridCoords * (1f / 25f) + 0.5f);
for (int i = 0; i < values; i++) blurredValueField.addValue(1 + (random.nextFloat() - random.nextFloat()) * (float) cloudExpansionRandomization() / 100f, random);
BlockAreas.mutablePositions(worldData.blockCollection.area()).forEach(pos -> {
IBlockState state = worldData.blockCollection.getBlockState(pos);
BlockPos worldCoord = context.transform.apply(pos, strucSize).add(lowerCoord);
if (matches(instanceData, state) && canPenetrate(environment, worldData, worldCoord, 1, transformer, transformerInstanceData))
cloud.put(pos.toImmutable(), 1);
});
double expansionDistance = cloudExpansionDistance();
BlockPos.MutableBlockPos sidePos = new BlockPos.MutableBlockPos();
BlockPos.MutableBlockPos sideWorldCoord = new BlockPos.MutableBlockPos();
if (expansionDistance > 0.000001) {
// The code below will be called _often_, so let's cache the divisions
double[] sideFalloffs = new double[6];
List<EnumFacing> checkSides = new ArrayList<>();
for (EnumFacing side : EnumFacing.values()) {
double sideExpansionDistance = cloudExpansionDistance(side);
double sideFalloff = sideExpansionDistance > 0.000001 ? 1.0f / sideExpansionDistance / expansionDistance : 0;
if (sideFalloff > 0) {
checkSides.add(side);
sideFalloffs[side.getIndex()] = sideFalloff;
}
}
visitRecursively(Sets.newHashSet(cloud.keySet()), (changed, pos) -> {
double density = cloud.get(pos);
for (EnumFacing side : checkSides) {
double sideFalloff = sideFalloffs[side.getIndex()];
IvMutableBlockPos.offset(pos, sidePos, side);
double sideDensity = density - sideFalloff * blurredValueField.getValue(sidePos.getX(), sidePos.getY(), sidePos.getZ());
if (sideDensity <= 0 || cloud.get(sidePos) >= sideDensity - 0.00001)
continue;
IvMutableBlockPos.add(context.transform.applyOn(sidePos, sideWorldCoord, strucSize), lowerCoord);
if (!canPenetrate(environment, worldData, sideWorldCoord, sideDensity, transformer, transformerInstanceData))
continue;
BlockPos immutableSidePos = sidePos.toImmutable();
cloud.put(immutableSidePos, sideDensity);
changed.add(immutableSidePos);
}
return true;
});
}
return cloud;
}
Aggregations