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"));
}
}
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);
}
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;
}
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;
}
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;
}
Aggregations