mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-06 04:46:40 +00:00
//[h]sphere can now generate ellipsoid (stretched sphere) shapes
This commit is contained in:
@ -1920,37 +1920,60 @@ public class EditSession {
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a sphere.
|
||||
* Makes a sphere or ellipsoid.
|
||||
*
|
||||
* @param pos
|
||||
* @param block
|
||||
* @param radius
|
||||
* @param filled
|
||||
* @param pos Center of the sphere or ellipsoid
|
||||
* @param block The block pattern to use
|
||||
* @param radiusX The sphere/ellipsoid's largest north/south extent
|
||||
* @param radiusY The sphere/ellipsoid's largest up/down extent
|
||||
* @param radiusZ The sphere/ellipsoid's largest east/west extent
|
||||
* @param filled If false, only a shell will be generated.
|
||||
* @return number of blocks changed
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public int makeSphere(Vector pos, Pattern block, double radius,
|
||||
boolean filled) throws MaxChangedBlocksException {
|
||||
public int makeSphere(Vector pos, Pattern block, double radiusX, double radiusY, double radiusZ, boolean filled) throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
radius += 0.5;
|
||||
final double radiusSq = radius*radius;
|
||||
final double radius1Sq = (radius - 1)*(radius - 1);
|
||||
radiusX += 0.5;
|
||||
radiusY += 0.5;
|
||||
radiusZ += 0.5;
|
||||
|
||||
final int ceilRadius = (int) Math.ceil(radius);
|
||||
for (int x = 0; x <= ceilRadius; ++x) {
|
||||
for (int y = 0; y <= ceilRadius; ++y) {
|
||||
for (int z = 0; z <= ceilRadius; ++z) {
|
||||
double dSq = lengthSq(x, y, z);
|
||||
final double invRadiusX = 1 / radiusX;
|
||||
final double invRadiusY = 1 / radiusY;
|
||||
final double invRadiusZ = 1 / radiusZ;
|
||||
|
||||
if (dSq > radiusSq)
|
||||
continue;
|
||||
final int ceilRadiusX = (int) Math.ceil(radiusX);
|
||||
final int ceilRadiusY = (int) Math.ceil(radiusY);
|
||||
final int ceilRadiusZ = (int) Math.ceil(radiusZ);
|
||||
|
||||
double nextXn = 0;
|
||||
forX:
|
||||
for (int x = 0; x <= ceilRadiusX; ++x) {
|
||||
final double xn = nextXn;
|
||||
nextXn = (x+1)*invRadiusX;
|
||||
double nextYn = 0;
|
||||
forY:
|
||||
for (int y = 0; y <= ceilRadiusY; ++y) {
|
||||
final double yn = nextYn;
|
||||
nextYn = (y+1)*invRadiusY;
|
||||
double nextZn = 0;
|
||||
forZ:
|
||||
for (int z = 0; z <= ceilRadiusZ; ++z) {
|
||||
final double zn = nextZn;
|
||||
nextZn = (z+1)*invRadiusZ;
|
||||
|
||||
double distanceSq = lengthSq(xn, yn, zn);
|
||||
if (distanceSq > 1) {
|
||||
if (z == 0) {
|
||||
if (y == 0)
|
||||
break forX;
|
||||
break forY;
|
||||
}
|
||||
break forZ;
|
||||
}
|
||||
|
||||
if (!filled) {
|
||||
if (dSq < radius1Sq)
|
||||
continue;
|
||||
|
||||
if (lengthSq(x+1, y, z) <= radiusSq && lengthSq(x, y+1, z) <= radiusSq && lengthSq(x, y, z+1) <= radiusSq)
|
||||
if (lengthSq(nextXn, yn, zn) <= 1 && lengthSq(xn, nextYn, zn) <= 1 && lengthSq(xn, yn, nextZn) <= 1)
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1985,7 +2008,7 @@ public class EditSession {
|
||||
return affected;
|
||||
}
|
||||
|
||||
private static final double lengthSq(int x, int y, int z) {
|
||||
private static final double lengthSq(double x, double y, double z) {
|
||||
return x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user