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