mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-24 10:17:39 +00:00
//[h]sphere can now generate ellipsoid (stretched sphere) shapes
This commit is contained in:
parent
780d07a9ba
commit
8c0d0f9ed4
@ -1920,37 +1920,60 @@ public class EditSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a sphere.
|
* Makes a sphere or ellipsoid.
|
||||||
*
|
*
|
||||||
* @param pos
|
* @param pos Center of the sphere or ellipsoid
|
||||||
* @param block
|
* @param block The block pattern to use
|
||||||
* @param radius
|
* @param radiusX The sphere/ellipsoid's largest north/south extent
|
||||||
* @param filled
|
* @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
|
* @return number of blocks changed
|
||||||
* @throws MaxChangedBlocksException
|
* @throws MaxChangedBlocksException
|
||||||
*/
|
*/
|
||||||
public int makeSphere(Vector pos, Pattern block, double radius,
|
public int makeSphere(Vector pos, Pattern block, double radiusX, double radiusY, double radiusZ, boolean filled) throws MaxChangedBlocksException {
|
||||||
boolean filled) throws MaxChangedBlocksException {
|
|
||||||
int affected = 0;
|
int affected = 0;
|
||||||
|
|
||||||
radius += 0.5;
|
radiusX += 0.5;
|
||||||
final double radiusSq = radius*radius;
|
radiusY += 0.5;
|
||||||
final double radius1Sq = (radius - 1)*(radius - 1);
|
radiusZ += 0.5;
|
||||||
|
|
||||||
final int ceilRadius = (int) Math.ceil(radius);
|
final double invRadiusX = 1 / radiusX;
|
||||||
for (int x = 0; x <= ceilRadius; ++x) {
|
final double invRadiusY = 1 / radiusY;
|
||||||
for (int y = 0; y <= ceilRadius; ++y) {
|
final double invRadiusZ = 1 / radiusZ;
|
||||||
for (int z = 0; z <= ceilRadius; ++z) {
|
|
||||||
double dSq = lengthSq(x, y, z);
|
|
||||||
|
|
||||||
if (dSq > radiusSq)
|
final int ceilRadiusX = (int) Math.ceil(radiusX);
|
||||||
continue;
|
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 (!filled) {
|
||||||
if (dSq < radius1Sq)
|
if (lengthSq(nextXn, yn, zn) <= 1 && lengthSq(xn, nextYn, zn) <= 1 && lengthSq(xn, yn, nextZn) <= 1)
|
||||||
continue;
|
|
||||||
|
|
||||||
if (lengthSq(x+1, y, z) <= radiusSq && lengthSq(x, y+1, z) <= radiusSq && lengthSq(x, y, z+1) <= radiusSq)
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1985,7 +2008,7 @@ public class EditSession {
|
|||||||
return affected;
|
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;
|
return x*x + y*y + z*z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,8 +80,8 @@ public class GenerationCommands {
|
|||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = {"/hsphere"},
|
aliases = {"/hsphere"},
|
||||||
usage = "<block> <radius> [raised?] ",
|
usage = "<block> <radius>[,<radius>,<radius>] [raised?] ",
|
||||||
desc = "Generate a hollow sphere",
|
desc = "Generate a hollow sphere. If you specify 3 radiuses separated by commas, an ellipsoid with the dimensions x,y,z will be generated.",
|
||||||
min = 2,
|
min = 2,
|
||||||
max = 3
|
max = 3
|
||||||
)
|
)
|
||||||
@ -91,19 +91,36 @@ public class GenerationCommands {
|
|||||||
LocalSession session, LocalPlayer player, EditSession editSession)
|
LocalSession session, LocalPlayer player, EditSession editSession)
|
||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
Pattern block = we.getBlockPattern(player, args.getString(0));
|
final Pattern block = we.getBlockPattern(player, args.getString(0));
|
||||||
double radius = Math.max(1, args.getDouble(1));
|
String[] radiuses = args.getString(1).split(",");
|
||||||
boolean raised = args.argsLength() > 2
|
final double radiusX, radiusY, radiusZ;
|
||||||
? (args.getString(2).equalsIgnoreCase("true")
|
switch (radiuses.length) {
|
||||||
|| args.getString(2).equalsIgnoreCase("yes"))
|
case 1:
|
||||||
: false;
|
radiusX = radiusY = radiusZ = Math.max(1, Double.parseDouble(radiuses[0]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
radiusX = Math.max(1, Double.parseDouble(radiuses[0]));
|
||||||
|
radiusY = Math.max(1, Double.parseDouble(radiuses[1]));
|
||||||
|
radiusZ = Math.max(1, Double.parseDouble(radiuses[2]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
player.printError("You must either specify 1 or 3 radius values.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final boolean raised;
|
||||||
|
if (args.argsLength() > 2)
|
||||||
|
raised = args.getString(2).equalsIgnoreCase("true") || args.getString(2).equalsIgnoreCase("yes");
|
||||||
|
else
|
||||||
|
raised = false;
|
||||||
|
|
||||||
Vector pos = session.getPlacementPosition(player);
|
Vector pos = session.getPlacementPosition(player);
|
||||||
if (raised) {
|
if (raised) {
|
||||||
pos = pos.add(0, radius, 0);
|
pos = pos.add(0, radiusY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int affected = editSession.makeSphere(pos, block, radius, false);
|
int affected = editSession.makeSphere(pos, block, radiusX, radiusY, radiusZ, false);
|
||||||
player.findFreePosition();
|
player.findFreePosition();
|
||||||
player.print(affected + " block(s) have been created.");
|
player.print(affected + " block(s) have been created.");
|
||||||
}
|
}
|
||||||
@ -111,7 +128,7 @@ public class GenerationCommands {
|
|||||||
@Command(
|
@Command(
|
||||||
aliases = {"/sphere"},
|
aliases = {"/sphere"},
|
||||||
usage = "<block> <radius> [raised?] ",
|
usage = "<block> <radius> [raised?] ",
|
||||||
desc = "Generate a filled sphere",
|
desc = "Generate a filled sphere. If you specify 3 radiuses separated by commas, an ellipsoid with the dimensions x,y,z will be generated.",
|
||||||
min = 2,
|
min = 2,
|
||||||
max = 3
|
max = 3
|
||||||
)
|
)
|
||||||
@ -122,18 +139,35 @@ public class GenerationCommands {
|
|||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
Pattern block = we.getBlockPattern(player, args.getString(0));
|
Pattern block = we.getBlockPattern(player, args.getString(0));
|
||||||
double radius = Math.max(1, args.getDouble(1));
|
String[] radiuses = args.getString(1).split(",");
|
||||||
boolean raised = args.argsLength() > 2
|
final double radiusX, radiusY, radiusZ;
|
||||||
? (args.getString(2).equalsIgnoreCase("true")
|
switch (radiuses.length) {
|
||||||
|| args.getString(2).equalsIgnoreCase("yes"))
|
case 1:
|
||||||
: false;
|
radiusX = radiusY = radiusZ = Math.max(1, Double.parseDouble(radiuses[0]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
radiusX = Math.max(1, Double.parseDouble(radiuses[0]));
|
||||||
|
radiusY = Math.max(1, Double.parseDouble(radiuses[1]));
|
||||||
|
radiusZ = Math.max(1, Double.parseDouble(radiuses[2]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
player.printError("You must either specify 1 or 3 radius values.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final boolean raised;
|
||||||
|
if (args.argsLength() > 2)
|
||||||
|
raised = args.getString(2).equalsIgnoreCase("true") || args.getString(2).equalsIgnoreCase("yes");
|
||||||
|
else
|
||||||
|
raised = false;
|
||||||
|
|
||||||
Vector pos = session.getPlacementPosition(player);
|
Vector pos = session.getPlacementPosition(player);
|
||||||
if (raised) {
|
if (raised) {
|
||||||
pos = pos.add(0, radius, 0);
|
pos = pos.add(0, radiusY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int affected = editSession.makeSphere(pos, block, radius, true);
|
int affected = editSession.makeSphere(pos, block, radiusX, radiusY, radiusZ, true);
|
||||||
player.findFreePosition();
|
player.findFreePosition();
|
||||||
player.print(affected + " block(s) have been created.");
|
player.print(affected + " block(s) have been created.");
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,6 @@ public class HollowSphereBrush implements Brush {
|
|||||||
|
|
||||||
public void build(EditSession editSession, Vector pos, Pattern mat, double size)
|
public void build(EditSession editSession, Vector pos, Pattern mat, double size)
|
||||||
throws MaxChangedBlocksException {
|
throws MaxChangedBlocksException {
|
||||||
editSession.makeSphere(pos, mat, size, false);
|
editSession.makeSphere(pos, mat, size, size, size, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,6 @@ public class SphereBrush implements Brush {
|
|||||||
|
|
||||||
public void build(EditSession editSession, Vector pos, Pattern mat, double size)
|
public void build(EditSession editSession, Vector pos, Pattern mat, double size)
|
||||||
throws MaxChangedBlocksException {
|
throws MaxChangedBlocksException {
|
||||||
editSession.makeSphere(pos, mat, size, true);
|
editSession.makeSphere(pos, mat, size, size, size, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user