package tc.oc.pgm.regions; import java.util.Random; import java.util.stream.Stream; import javax.annotation.Nullable; import org.bukkit.geometry.Cuboid; import org.bukkit.util.Vector; public abstract class TransformedRegion extends Region.Impl { protected final @Inspect Region region; protected @Nullable Cuboid bounds; public TransformedRegion(Region region) { this.region = region; } @Override public Stream<? extends Region> dependencies() { return Stream.of(region); } @Override public boolean isBlockBounded() { return this.region.isBlockBounded(); } @Override public boolean isEmpty() { return this.region.isEmpty(); } @Override public boolean isEverywhere() { return region.isEverywhere(); } @Override public Cuboid getBounds() { if(this.bounds == null) { this.bounds = this.getTransformedBounds(); } return this.bounds; } /** * Generic bounding box transform - transform all 8 vertices * and find the minimum bounding box containing them. */ protected Cuboid getTransformedBounds() { Vector[] oldVertices = this.region.getBounds().vertices(); Vector[] newVertices = new Vector[8]; for(int i = 0; i < oldVertices.length; i++) { newVertices[i] = this.transform(oldVertices[i]); } return Cuboid.enclosing(newVertices); } @Override public boolean contains(Vector point) { return this.region.contains(this.untransform(point)); } @Override public boolean canGetRandom() { return this.region.canGetRandom(); } /** * Generic random point generator that simply transforms a point generated by * the transformed region. This will work at least with affine transformations, * but other types may make the random distribution uneven. */ @Override public Vector getRandom(Random random) { return this.transform(this.region.getRandom(random)); } protected abstract Vector transform(Vector point); protected abstract Vector untransform(Vector point); }