mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-07-08 18:00:04 +00:00
- so certain people can look at the diff and complain about my sloppy code :( Signed-off-by: Jesse Boyd <jessepaleg@gmail.com>
96 lines
3.4 KiB
Java
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();
|
|
}
|
|
}
|