Plex-FAWE/worldedit-core/src/main/java/com/boydti/fawe/object/brush/CatenaryBrush.java
Jesse Boyd a629d15c74
Copy paste/merge FAWE classes to this WorldEdit fork
- so certain people can look at the diff and complain about my sloppy code :(

Signed-off-by: Jesse Boyd <jessepaleg@gmail.com>
2018-08-13 00:03:07 +10:00

96 lines
3.4 KiB
Java

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.WorldEditException;
import com.sk89q.worldedit.command.tool.brush.Brush;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.Location;
import java.util.Arrays;
import java.util.List;
public class CatenaryBrush implements Brush, ResettableTool {
private final boolean shell, select, direction;
private final double slack;
private Vector pos1;
private Vector pos2;
private Vector vertex;
public CatenaryBrush(boolean shell, boolean select, boolean direction, double lengthFactor) {
this.shell = shell;
this.select = select;
this.direction = direction;
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;
}
if (this.vertex == null) {
vertex = getVertex(pos1, pos2, slack);
if (this.direction) {
BBC.BRUSH_CATENARY_DIRECTION.send(editSession.getPlayer(), 2);
return;
}
} else if (this.direction) {
Location loc = editSession.getPlayer().getPlayer().getLocation();
Vector facing = loc.getDirection().normalize();
Vector midpoint = pos1.add(pos2).divide(2);
Vector offset = midpoint.subtract(vertex);
vertex = midpoint.add(facing.multiply(offset.length()));
}
List<Vector> nodes = Arrays.asList(pos1, vertex, pos2);
vertex = null;
try {
editSession.drawSpline(pattern, nodes, 0, 0, 0, 10, size, !shell);
} catch (WorldEditException e) {
e.printStackTrace();
}
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 static Vector getVertex(Vector pos1, Vector pos2, double lenPercent) {
if (lenPercent <= 1) return Vector.getMidpoint(pos1, pos2);
double curveLen = pos1.distance(pos2) * lenPercent;
double dy = pos2.getY() - pos1.getY();
double dx = pos2.getX() - pos1.getX();
double dz = pos2.getZ() - pos1.getZ();
double dh = Math.sqrt(dx * dx + dz * dz);
double g = Math.sqrt(curveLen * curveLen - dy * dy) / 2;
double a = 0.00001;
for (;g < a * Math.sinh(dh/(2 * a)); a *= 1.00001);
double vertX = (dh-a*Math.log((curveLen + dy)/(curveLen - dy)))/2.0;
double z = (dh/2)/a;
double oY = (dy - curveLen * (Math.cosh(z) / Math.sinh(z))) / 2;
double vertY = a * 1 + oY;
return pos1.add(pos2.subtract(pos1).multiply(vertX / dh).add(0, vertY, 0)).round();
}
}