Search in sources :

Example 6 with LocalBlockVectorSet

use of com.fastasyncworldedit.core.math.LocalBlockVectorSet in project FastAsyncWorldEdit by IntellectualSites.

the class SurfaceSpline method build.

@Override
public void build(EditSession editSession, BlockVector3 pos, Pattern pattern, double radius) throws MaxChangedBlocksException {
    int maxY = editSession.getMaxY();
    int minY = editSession.getMinY();
    if (path.isEmpty() || !pos.equals(path.get(path.size() - 1))) {
        int max = editSession.getNearestSurfaceTerrainBlock(pos.getBlockX(), pos.getBlockZ(), pos.getBlockY(), minY, maxY);
        if (max == -1) {
            return;
        }
        path.add(BlockVector3.at(pos.getBlockX(), max, pos.getBlockZ()));
        if (editSession.getActor() != null) {
            editSession.getActor().print(Caption.of("fawe.worldedit.brush.spline.primary.2"));
        }
        return;
    }
    final List<Node> nodes = new ArrayList<>(path.size());
    final KochanekBartelsInterpolation interpol = new KochanekBartelsInterpolation();
    for (BlockVector3 nodevector : path) {
        final Node n = new Node(nodevector.toVector3());
        n.setTension(tension);
        n.setBias(bias);
        n.setContinuity(continuity);
        nodes.add(n);
    }
    MutableBlockVector3 mutable = MutableBlockVector3.at(0, 0, 0);
    interpol.setNodes(nodes);
    final double splinelength = interpol.arcLength(0, 1);
    LocalBlockVectorSet vset = new LocalBlockVectorSet();
    for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) {
        final Vector3 tipv = interpol.getPosition(loop);
        final int tipx = MathMan.roundInt(tipv.getX());
        final int tipz = (int) tipv.getZ();
        int tipy = MathMan.roundInt(tipv.getY());
        tipy = editSession.getNearestSurfaceTerrainBlock(tipx, tipz, tipy, minY, maxY, Integer.MIN_VALUE, Integer.MAX_VALUE);
        if (tipy == Integer.MIN_VALUE || tipy == Integer.MAX_VALUE) {
            continue;
        }
        if (radius == 0) {
            BlockVector3 set = mutable.setComponents(tipx, tipy, tipz);
            pattern.apply(editSession, set, set);
        } else {
            vset.add(tipx, tipy, tipz);
        }
    }
    if (radius != 0) {
        double radius2 = radius * radius;
        LocalBlockVectorSet newSet = new LocalBlockVectorSet();
        final int ceilrad = (int) Math.ceil(radius);
        for (BlockVector3 v : vset) {
            final int tipx = v.getBlockX();
            final int tipz = v.getBlockZ();
            for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) {
                for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) {
                    if (MathMan.hypot2(loopx - tipx, 0, loopz - tipz) <= radius2) {
                        int y = editSession.getNearestSurfaceTerrainBlock(loopx, loopz, v.getBlockY(), minY, maxY, Integer.MIN_VALUE, Integer.MAX_VALUE);
                        if (y == Integer.MIN_VALUE || y == Integer.MAX_VALUE) {
                            continue;
                        }
                        newSet.add(loopx, y, loopz);
                    }
                }
            }
        }
        editSession.setBlocks(newSet, pattern);
    }
    path.clear();
    if (editSession.getActor() != null) {
        editSession.getActor().print(Caption.of("fawe.worldedit.brush.spline.secondary"));
    }
}
Also used : MutableBlockVector3(com.fastasyncworldedit.core.math.MutableBlockVector3) LocalBlockVectorSet(com.fastasyncworldedit.core.math.LocalBlockVectorSet) Node(com.sk89q.worldedit.math.interpolation.Node) KochanekBartelsInterpolation(com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation) ArrayList(java.util.ArrayList) BlockVector3(com.sk89q.worldedit.math.BlockVector3) Vector3(com.sk89q.worldedit.math.Vector3) MutableBlockVector3(com.fastasyncworldedit.core.math.MutableBlockVector3) BlockVector3(com.sk89q.worldedit.math.BlockVector3) MutableBlockVector3(com.fastasyncworldedit.core.math.MutableBlockVector3)

Example 7 with LocalBlockVectorSet

use of com.fastasyncworldedit.core.math.LocalBlockVectorSet 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 8 with LocalBlockVectorSet

use of com.fastasyncworldedit.core.math.LocalBlockVectorSet in project FastAsyncWorldEdit by IntellectualSites.

the class FloatingTreeRemover method bfs.

/**
 * Helper method.
 *
 * @param world  the world that contains the tree
 * @param origin any point contained in the floating tree
 * @return a set containing all blocks in the tree/shroom or null if this is not a floating tree/shroom.
 */
private Set<BlockVector3> bfs(World world, BlockVector3 origin) {
    // FAWE start - Use a LBVS over a HashMap & LinkedList
    final LocalBlockVectorSet visited = new LocalBlockVectorSet();
    final LocalBlockVectorSet queue = new LocalBlockVectorSet();
    // FAWE end
    queue.add(origin);
    visited.add(origin);
    while (!queue.isEmpty()) {
        Iterator<BlockVector3> iter = queue.iterator();
        while (iter.hasNext()) {
            final BlockVector3 current = iter.next();
            iter.remove();
            for (BlockVector3 recurseDirection : recurseDirections) {
                final BlockVector3 next = current.add(recurseDirection);
                if (origin.distanceSq(next) > rangeSq) {
                    // Maximum range exceeded => stop walking
                    continue;
                }
                if (visited.add(next)) {
                    BlockState state = world.getBlock(next);
                    if (state.getBlockType().getMaterial().isAir() || state.getBlockType() == BlockTypes.SNOW) {
                        continue;
                    }
                    if (isTreeBlock(state.getBlockType())) {
                        queue.add(next);
                    } else {
                        // we hit something solid - evaluate where we came from
                        final BlockType currentType = world.getBlock(current).getBlockType();
                        if (!BlockCategories.LEAVES.contains(currentType) && currentType != BlockTypes.VINE) {
                            // log/shroom touching a wall/the ground => this is not a floating tree, bail out
                            return null;
                        }
                    }
                }
            }
        }
    }
    return visited;
}
Also used : BlockState(com.sk89q.worldedit.world.block.BlockState) BlockType(com.sk89q.worldedit.world.block.BlockType) LocalBlockVectorSet(com.fastasyncworldedit.core.math.LocalBlockVectorSet) BlockVector3(com.sk89q.worldedit.math.BlockVector3)

Example 9 with LocalBlockVectorSet

use of com.fastasyncworldedit.core.math.LocalBlockVectorSet in project FastAsyncWorldEdit by IntellectualSites.

the class EditSession method getBallooned.

private static Set<BlockVector3> getBallooned(Set<BlockVector3> vset, double radius) {
    if (radius < 1) {
        return vset;
    }
    LocalBlockVectorSet returnset = new LocalBlockVectorSet();
    int ceilrad = (int) Math.ceil(radius);
    for (BlockVector3 v : vset) {
        int tipx = v.getBlockX();
        int tipy = v.getBlockY();
        int tipz = v.getBlockZ();
        for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) {
            for (int loopy = tipy - ceilrad; loopy <= tipy + ceilrad; loopy++) {
                for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) {
                    if (MathMan.hypot(loopx - tipx, loopy - tipy, loopz - tipz) <= radius) {
                        returnset.add(loopx, loopy, loopz);
                    }
                }
            }
        }
    }
    return returnset;
}
Also used : LocalBlockVectorSet(com.fastasyncworldedit.core.math.LocalBlockVectorSet) MutableBlockVector3(com.fastasyncworldedit.core.math.MutableBlockVector3) BlockVector3(com.sk89q.worldedit.math.BlockVector3)

Example 10 with LocalBlockVectorSet

use of com.fastasyncworldedit.core.math.LocalBlockVectorSet in project FastAsyncWorldEdit by IntellectualSites.

the class EditSession method getOutline.

public Set<BlockVector3> getOutline(Set<BlockVector3> vset) {
    final LocalBlockVectorSet returnset = new LocalBlockVectorSet();
    final LocalBlockVectorSet newset = new LocalBlockVectorSet();
    newset.addAll(vset);
    for (BlockVector3 v : newset) {
        final int x = v.getX();
        final int y = v.getY();
        final int z = v.getZ();
        if (!(newset.contains(x + 1, y, z) && newset.contains(x - 1, y, z) && newset.contains(x, y, z + 1) && newset.contains(x, y, z - 1))) {
            returnset.add(v);
        }
    }
    return returnset;
}
Also used : LocalBlockVectorSet(com.fastasyncworldedit.core.math.LocalBlockVectorSet) MutableBlockVector3(com.fastasyncworldedit.core.math.MutableBlockVector3) BlockVector3(com.sk89q.worldedit.math.BlockVector3)

Aggregations

LocalBlockVectorSet (com.fastasyncworldedit.core.math.LocalBlockVectorSet)12 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)11 MutableBlockVector3 (com.fastasyncworldedit.core.math.MutableBlockVector3)8 SurfaceMask (com.fastasyncworldedit.core.function.mask.SurfaceMask)2 BlockVectorSet (com.fastasyncworldedit.core.math.BlockVectorSet)2 KochanekBartelsInterpolation (com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation)2 Node (com.sk89q.worldedit.math.interpolation.Node)2 ArrayList (java.util.ArrayList)2 RadiusMask (com.fastasyncworldedit.core.function.mask.RadiusMask)1 Mask (com.sk89q.worldedit.function.mask.Mask)1 MaskIntersection (com.sk89q.worldedit.function.mask.MaskIntersection)1 RecursiveVisitor (com.sk89q.worldedit.function.visitor.RecursiveVisitor)1 BlockVector2 (com.sk89q.worldedit.math.BlockVector2)1 Vector3 (com.sk89q.worldedit.math.Vector3)1 Interpolation (com.sk89q.worldedit.math.interpolation.Interpolation)1 BlockState (com.sk89q.worldedit.world.block.BlockState)1 BlockType (com.sk89q.worldedit.world.block.BlockType)1