Search in sources :

Example 1 with SurfaceMask

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);
}
Also used : MaskIntersection(com.sk89q.worldedit.function.mask.MaskIntersection) RadiusMask(com.fastasyncworldedit.core.function.mask.RadiusMask) LocalBlockVectorSet(com.fastasyncworldedit.core.math.LocalBlockVectorSet) RecursiveVisitor(com.sk89q.worldedit.function.visitor.RecursiveVisitor) BlockVector3(com.sk89q.worldedit.math.BlockVector3) BlockVectorSet(com.fastasyncworldedit.core.math.BlockVectorSet) LocalBlockVectorSet(com.fastasyncworldedit.core.math.LocalBlockVectorSet) SurfaceMask(com.fastasyncworldedit.core.function.mask.SurfaceMask)

Example 2 with SurfaceMask

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);
}
Also used : Pattern(com.sk89q.worldedit.function.pattern.Pattern) RecursiveVisitor(com.sk89q.worldedit.function.visitor.RecursiveVisitor) SplatterBrushMask(com.fastasyncworldedit.core.function.mask.SplatterBrushMask) SurfaceMask(com.fastasyncworldedit.core.function.mask.SurfaceMask)

Example 3 with SurfaceMask

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();
        }
    }
}
Also used : LocalBlockVectorSet(com.fastasyncworldedit.core.math.LocalBlockVectorSet) Mask(com.sk89q.worldedit.function.mask.Mask) SurfaceMask(com.fastasyncworldedit.core.function.mask.SurfaceMask) BlockVector3(com.sk89q.worldedit.math.BlockVector3) MutableBlockVector3(com.fastasyncworldedit.core.math.MutableBlockVector3) SurfaceMask(com.fastasyncworldedit.core.function.mask.SurfaceMask)

Example 4 with SurfaceMask

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);
}
Also used : MaskIntersection(com.sk89q.worldedit.function.mask.MaskIntersection) RadiusMask(com.fastasyncworldedit.core.function.mask.RadiusMask) RecursiveVisitor(com.sk89q.worldedit.function.visitor.RecursiveVisitor) SurfaceMask(com.fastasyncworldedit.core.function.mask.SurfaceMask)

Aggregations

SurfaceMask (com.fastasyncworldedit.core.function.mask.SurfaceMask)4 RecursiveVisitor (com.sk89q.worldedit.function.visitor.RecursiveVisitor)3 RadiusMask (com.fastasyncworldedit.core.function.mask.RadiusMask)2 LocalBlockVectorSet (com.fastasyncworldedit.core.math.LocalBlockVectorSet)2 MaskIntersection (com.sk89q.worldedit.function.mask.MaskIntersection)2 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)2 SplatterBrushMask (com.fastasyncworldedit.core.function.mask.SplatterBrushMask)1 BlockVectorSet (com.fastasyncworldedit.core.math.BlockVectorSet)1 MutableBlockVector3 (com.fastasyncworldedit.core.math.MutableBlockVector3)1 Mask (com.sk89q.worldedit.function.mask.Mask)1 Pattern (com.sk89q.worldedit.function.pattern.Pattern)1