use of com.fastasyncworldedit.core.function.mask.SurfaceMask in project FastAsyncWorldEdit by IntellectualSites.
the class ScatterBrush method build.
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
this.mask = editSession.getMask();
if (this.mask == null) {
this.mask = Masks.alwaysTrue();
}
surface = new SurfaceMask(editSession);
final RadiusMask radius = new RadiusMask(0, (int) size);
final int distance = Math.min((int) size, this.distance);
RecursiveVisitor visitor = new RecursiveVisitor(new MaskIntersection(radius, surface), function -> true, Integer.MAX_VALUE, editSession.getMinY(), editSession.getMaxY());
visitor.visit(position);
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
Operations.completeBlindly(visitor);
BlockVectorSet visited = visitor.getVisited();
int length = visited.size();
if (size == 0) {
length = 1;
visited.add(position);
}
LocalBlockVectorSet placed = new LocalBlockVectorSet();
placed.setOffset(position.getX(), position.getZ());
int maxFails = 1000;
for (int i = 0; i < count; i++) {
int index = ThreadLocalRandom.current().nextInt(length);
BlockVector3 pos = visited.get(index);
if (pos != null && canApply(pos)) {
int x = pos.getBlockX();
int y = pos.getBlockY();
int z = pos.getBlockZ();
if (placed.containsRadius(x, y, z, distance)) {
if (maxFails-- <= 0) {
break;
}
i--;
continue;
}
placed.add(x, y, z);
apply(editSession, placed, pos, pattern, size);
}
}
finish(editSession, placed, position, pattern, size);
}
use of com.fastasyncworldedit.core.function.mask.SurfaceMask in project FastAsyncWorldEdit by IntellectualSites.
the class SplatterBrush method apply.
@Override
public void apply(final EditSession editSession, final LocalBlockVectorSet placed, final BlockVector3 position, Pattern p, double size) throws MaxChangedBlocksException {
final Pattern finalPattern;
if (solid) {
finalPattern = p.applyBlock(position);
} else {
finalPattern = p;
}
final int size2 = (int) (size * size);
SurfaceMask surface = new SurfaceMask(editSession);
RecursiveVisitor visitor = new RecursiveVisitor(new SplatterBrushMask(editSession, position, size2, surface, placed), vector -> editSession.setBlock(vector, finalPattern), recursion, editSession.getMinY(), editSession.getMaxY());
visitor.setMaxBranch(2);
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
visitor.visit(position);
Operations.completeBlindly(visitor);
}
use of com.fastasyncworldedit.core.function.mask.SurfaceMask in project FastAsyncWorldEdit by IntellectualSites.
the class ShatterBrush method finish.
@Override
public void finish(EditSession editSession, LocalBlockVectorSet placed, final BlockVector3 position, Pattern pattern, double size) {
int radius2 = (int) (size * size);
// Individual frontier for each point
LocalBlockVectorSet[] frontiers = new LocalBlockVectorSet[placed.size()];
// Keep track of where each frontier has visited
LocalBlockVectorSet[] frontiersVisited = new LocalBlockVectorSet[placed.size()];
// Initiate the frontier with the starting points
int i = 0;
for (BlockVector3 pos : placed) {
LocalBlockVectorSet set = new LocalBlockVectorSet();
set.add(pos);
frontiers[i] = set;
frontiersVisited[i] = set.clone();
i++;
}
// Mask
Mask mask = editSession.getMask();
if (mask == null) {
mask = Masks.alwaysTrue();
}
final Mask finalMask = mask;
final SurfaceMask surfaceTest = new SurfaceMask(editSession);
// Expand
boolean notEmpty = true;
// Keep track of where we've visited
LocalBlockVectorSet tmp = new LocalBlockVectorSet();
while (notEmpty) {
notEmpty = false;
for (i = 0; i < frontiers.length; i++) {
LocalBlockVectorSet frontier = frontiers[i];
notEmpty |= !frontier.isEmpty();
final LocalBlockVectorSet frontierVisited = frontiersVisited[i];
// This is a temporary set with the next blocks the frontier will visit
final LocalBlockVectorSet finalTmp = tmp;
frontier.forEach((x, y, z, index) -> {
if (ThreadLocalRandom.current().nextInt(2) == 0) {
finalTmp.add(x, y, z);
return;
}
for (int i1 = 0; i1 < BreadthFirstSearch.DIAGONAL_DIRECTIONS.length; i1++) {
BlockVector3 direction = BreadthFirstSearch.DIAGONAL_DIRECTIONS[i1];
int x2 = x + direction.getBlockX();
int y2 = y + direction.getBlockY();
int z2 = z + direction.getBlockZ();
// Check boundary
int dx = position.getBlockX() - x2;
int dy = position.getBlockY() - y2;
int dz = position.getBlockZ() - z2;
int dSqr = (dx * dx) + (dy * dy) + (dz * dz);
if (dSqr <= radius2) {
BlockVector3 bv = mutable.setComponents(x2, y2, z2);
if (surfaceTest.test(bv) && finalMask.test(bv)) {
// (collision) If it's visited and part of another frontier, set the block
if (!placed.add(x2, y2, z2)) {
if (!frontierVisited.contains(x2, y2, z2)) {
editSession.setBlock(x2, y2, z2, pattern);
}
} else {
// Hasn't visited and not a collision = add it
finalTmp.add(x2, y2, z2);
frontierVisited.add(x2, y2, z2);
}
}
}
}
});
// Swap the frontier with the temporary set
frontiers[i] = tmp;
tmp = frontier;
tmp.clear();
}
}
}
use of com.fastasyncworldedit.core.function.mask.SurfaceMask in project FastAsyncWorldEdit by IntellectualSites.
the class SurfaceSphereBrush method build.
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
SurfaceMask surface = new SurfaceMask(editSession);
final RadiusMask radius = new RadiusMask(0, (int) size);
RecursiveVisitor visitor = new RecursiveVisitor(new MaskIntersection(surface, radius), vector -> editSession.setBlock(vector, pattern), Integer.MAX_VALUE, editSession.getMinY(), editSession.getMaxY());
visitor.visit(position);
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
Operations.completeBlindly(visitor);
}
Aggregations