Add catenary brush
This commit is contained in:
parent
f85a9f08d0
commit
8948645832
@ -128,6 +128,8 @@ public enum BBC {
|
|||||||
BRUSH_HEIGHT_INVALID("Invalid height map file (%s0)", "WorldEdit.Brush"),
|
BRUSH_HEIGHT_INVALID("Invalid height map file (%s0)", "WorldEdit.Brush"),
|
||||||
BRUSH_SMOOTH("Note: Use the blend brush if you want to smooth overhangs or caves.", "WorldEdit.Brush"),
|
BRUSH_SMOOTH("Note: Use the blend brush if you want to smooth overhangs or caves.", "WorldEdit.Brush"),
|
||||||
BRUSH_SPLINE("Click to add a point, click the same spot to finish", "WorldEdit.Brush"),
|
BRUSH_SPLINE("Click to add a point, click the same spot to finish", "WorldEdit.Brush"),
|
||||||
|
BRUSH_LINE_PRIMARY("Added point %s0, click another position to create the line", "WorldEdit.Brush"),
|
||||||
|
BRUSH_LINE_SECONDARY("Created pline", "WorldEdit.Brush"),
|
||||||
BRUSH_SPLINE_PRIMARY_2("Added position, Click the same spot to join!", "WorldEdit.Brush"),
|
BRUSH_SPLINE_PRIMARY_2("Added position, Click the same spot to join!", "WorldEdit.Brush"),
|
||||||
BRUSH_SPLINE_SECONDARY_ERROR("Not enough positions set!", "WorldEdit.Brush"),
|
BRUSH_SPLINE_SECONDARY_ERROR("Not enough positions set!", "WorldEdit.Brush"),
|
||||||
BRUSH_SPLINE_SECONDARY("Created spline", "WorldEdit.Brush"),
|
BRUSH_SPLINE_SECONDARY("Created spline", "WorldEdit.Brush"),
|
||||||
|
@ -0,0 +1,74 @@
|
|||||||
|
package com.boydti.fawe.object.brush;
|
||||||
|
|
||||||
|
import com.boydti.fawe.config.BBC;
|
||||||
|
import com.boydti.fawe.object.brush.visualization.VisualExtent;
|
||||||
|
import com.sk89q.worldedit.EditSession;
|
||||||
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||||
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CatenaryBrush implements Brush, ResettableTool {
|
||||||
|
|
||||||
|
private final boolean shell, select;
|
||||||
|
private final double slack;
|
||||||
|
private Vector pos1;
|
||||||
|
|
||||||
|
public CatenaryBrush(boolean shell, boolean select, double lengthFactor) {
|
||||||
|
this.shell = shell;
|
||||||
|
this.select = select;
|
||||||
|
this.slack = lengthFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(EditSession editSession, Vector pos2, final Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||||
|
boolean visual = (editSession.getExtent() instanceof VisualExtent);
|
||||||
|
if (pos1 == null || pos2.equals(pos1)) {
|
||||||
|
if (!visual) {
|
||||||
|
pos1 = pos2;
|
||||||
|
BBC.BRUSH_LINE_PRIMARY.send(editSession.getPlayer(), pos2);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Vector vertex = getVertex(pos1, pos2, slack);
|
||||||
|
List<Vector> nodes = Arrays.asList(pos1, vertex, pos2);
|
||||||
|
editSession.drawSpline(pattern, nodes, 0, 0, 0, 10, size, !shell);
|
||||||
|
if (!visual) {
|
||||||
|
BBC.BRUSH_LINE_SECONDARY.send(editSession.getPlayer());
|
||||||
|
if (!select) {
|
||||||
|
pos1 = null;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
pos1 = pos2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean reset() {
|
||||||
|
pos1 = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector getVertex(Vector pos1, Vector pos2, double lenPercent) {
|
||||||
|
double len = pos1.distance(pos2) * lenPercent;
|
||||||
|
|
||||||
|
double dy = pos2.getY() - pos1.getY();
|
||||||
|
double dx = pos2.getX() - pos1.getX();
|
||||||
|
double dz = pos2.getZ() - pos1.getZ();
|
||||||
|
double h = Math.sqrt(dx * dx + dz * dz);
|
||||||
|
|
||||||
|
double t = Math.sqrt(len * len - dy * dy) / h;
|
||||||
|
double z = 0.001;
|
||||||
|
for (; Math.sinh(z) < t*z; z += 0.001); // close enough
|
||||||
|
|
||||||
|
double a = (h / 2) / z;
|
||||||
|
double p = (h - a * Math.log((len + dy) / (len - dy)))/2;
|
||||||
|
double q = (dy - len * Math.cosh(z) / Math.sinh(z)) / 2;
|
||||||
|
double y = a * 1 + q;
|
||||||
|
|
||||||
|
return pos1.add(pos2.subtract(pos1).multiply(p / h).add(0, y, 0)).round();
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.boydti.fawe.object.brush;
|
package com.boydti.fawe.object.brush;
|
||||||
|
|
||||||
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.object.brush.visualization.VisualExtent;
|
import com.boydti.fawe.object.brush.visualization.VisualExtent;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
@ -22,11 +23,15 @@ public class LineBrush implements Brush, ResettableTool {
|
|||||||
public void build(EditSession editSession, Vector position, final Pattern pattern, double size) throws MaxChangedBlocksException {
|
public void build(EditSession editSession, Vector position, final Pattern pattern, double size) throws MaxChangedBlocksException {
|
||||||
boolean visual = (editSession.getExtent() instanceof VisualExtent);
|
boolean visual = (editSession.getExtent() instanceof VisualExtent);
|
||||||
if (pos1 == null) {
|
if (pos1 == null) {
|
||||||
if (!visual) pos1 = position;
|
if (!visual) {
|
||||||
|
pos1 = position;
|
||||||
|
BBC.BRUSH_LINE_PRIMARY.send(editSession.getPlayer(), position);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
editSession.drawLine(pattern, pos1, position, size, !shell, flat);
|
editSession.drawLine(pattern, pos1, position, size, !shell, flat);
|
||||||
if (!visual) {
|
if (!visual) {
|
||||||
|
BBC.BRUSH_LINE_SECONDARY.send(editSession.getPlayer());
|
||||||
if (!select) {
|
if (!select) {
|
||||||
pos1 = null;
|
pos1 = null;
|
||||||
return;
|
return;
|
||||||
|
@ -27,6 +27,7 @@ import com.boydti.fawe.object.FaweLimit;
|
|||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.brush.BlendBall;
|
import com.boydti.fawe.object.brush.BlendBall;
|
||||||
import com.boydti.fawe.object.brush.BrushSettings;
|
import com.boydti.fawe.object.brush.BrushSettings;
|
||||||
|
import com.boydti.fawe.object.brush.CatenaryBrush;
|
||||||
import com.boydti.fawe.object.brush.CircleBrush;
|
import com.boydti.fawe.object.brush.CircleBrush;
|
||||||
import com.boydti.fawe.object.brush.CommandBrush;
|
import com.boydti.fawe.object.brush.CommandBrush;
|
||||||
import com.boydti.fawe.object.brush.CopyPastaBrush;
|
import com.boydti.fawe.object.brush.CopyPastaBrush;
|
||||||
@ -84,6 +85,7 @@ import com.sk89q.worldedit.function.mask.Mask;
|
|||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.util.command.InvalidUsageException;
|
import com.sk89q.worldedit.util.command.InvalidUsageException;
|
||||||
|
import com.sk89q.worldedit.util.command.binding.Range;
|
||||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
@ -245,7 +247,25 @@ public class BrushCommands extends MethodCommands {
|
|||||||
.setFill(fill);
|
.setFill(fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
// final double tension, final double bias, final double continuity, final double quality
|
@Command(
|
||||||
|
aliases = {"catenary", "cat", "gravityline", "saggedline"},
|
||||||
|
usage = "<pattern> [length-factor=1.2] [size=0]",
|
||||||
|
desc = "Create a hanging line between two points",
|
||||||
|
help = "Create a hanging line between two points.\n" +
|
||||||
|
"The length-factor controls how long the line is\n" +
|
||||||
|
"The -h flag creates only a shell\n" +
|
||||||
|
"The -s flag selects the clicked point after drawing\n",
|
||||||
|
min = 1,
|
||||||
|
max = 3
|
||||||
|
)
|
||||||
|
@CommandPermissions("worldedit.brush.spline")
|
||||||
|
public BrushSettings catenaryBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("1.2") @Range(min=1) double lengthFactor, @Optional("0") double radius, @Switch('h') boolean shell, @Switch('s') boolean select, CommandContext context) throws WorldEditException {
|
||||||
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
|
return get(context)
|
||||||
|
.setBrush(new CatenaryBrush(shell, select, lengthFactor))
|
||||||
|
.setSize(radius)
|
||||||
|
.setFill(fill);
|
||||||
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = {"sspl", "sspline", "surfacespline"},
|
aliases = {"sspl", "sspline", "surfacespline"},
|
||||||
@ -254,7 +274,7 @@ public class BrushCommands extends MethodCommands {
|
|||||||
help = "Create a spline on the surface\n" +
|
help = "Create a spline on the surface\n" +
|
||||||
"Video: https://www.youtube.com/watch?v=zSN-2jJxXlM",
|
"Video: https://www.youtube.com/watch?v=zSN-2jJxXlM",
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2
|
max = 6
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.brush.surfacespline") // 0, 0, 0, 10, 0,
|
@CommandPermissions("worldedit.brush.surfacespline") // 0, 0, 0, 10, 0,
|
||||||
public BrushSettings surfaceSpline(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") double radius, @Optional("0") double tension, @Optional("0") double bias, @Optional("0") double continuity, @Optional("10") double quality, CommandContext context) throws WorldEditException {
|
public BrushSettings surfaceSpline(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("0") double radius, @Optional("0") double tension, @Optional("0") double bias, @Optional("0") double continuity, @Optional("10") double quality, CommandContext context) throws WorldEditException {
|
||||||
|
Loading…
Reference in New Issue
Block a user