-
Notifications
You must be signed in to change notification settings - Fork 3
/
rotpaste.js
106 lines (106 loc) · 4.78 KB
/
rotpaste.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
importPackage(Packages.com.sk89q.worldedit);
importPackage(Packages.com.sk89q.worldedit.math);
importPackage(Packages.com.sk89q.worldedit.blocks);
importPackage(Packages.com.sk89q.worldedit.session);
importPackage(Packages.com.sk89q.worldedit.regions);
importPackage(Packages.com.sk89q.worldedit.extent.clipboard);
context.checkArgs(1, 3, "<rotateY> [rotateX] [rotateZ] [-a]");
var blocks = context.remember();
var session = context.getSession();
var clipBoardHolder = session.getClipboard();
var clipBoard = clipBoardHolder.getClipboard();
var player = context.getPlayer();
var region = clipBoard.getRegion();
var minP = region.getMinimumPoint();
var maxP = region.getMaximumPoint();
var deg2rad = Math.PI / 180;
var yy = !isNaN(argv[1]) ? -argv[1] * deg2rad : 0;
var xx = !isNaN(argv[2]) ? argv[2] * deg2rad : 0;
var zz = !isNaN(argv[3]) ? argv[3] * deg2rad : 0;
var ignoreAir = false;
if (argv[1] == "-a" || argv[2] == "-a" || argv[3] == "-a" || argv[4] == "-a") {
ignoreAir = true;
}
var cx = Math.cos(xx), cy = Math.cos(yy), cz = Math.cos(zz);
var sx = Math.sin(xx), sy = Math.sin(yy), sz = Math.sin(zz);
// deal y axis with facing change, clamp dfacing to 0-3
var dfacing = (Math.round(yy / Math.PI * 2) + 40000) % 4;
var changeDir = function (block) {
if (!dfacing) return block;
var str = block.toString();
if (str.match(/facing=/)) {
switch (dfacing) {
case 1: return context.getBlock(str.replace("axis=x", "axis=@z").replace("axis=z", "axis=@x").replace("south", "eas@t").replace("west", "south").replace("north", "west").replace("east", "north").replace("@", ""));
case 2: return context.getBlock(str.replace("south", "nor@th").replace("east", "wes@t").replace("north", "sout@h").replace("west", "eas@t").replace("@", ""));
case 3: return context.getBlock(str.replace("axis=x", "axis=@z").replace("axis=z", "axis=@x").replace("south", "wes@t").replace("east", "south").replace("north", "east").replace("west", "north").replace("@", ""));
}
} else {
return block;
}
}
// Euler角转矩阵,顺序:my.mx.mz
var matrix = [
cy * cz + sx * sy * sz, -cz * sx * sy + cy * sz, cx * sy,
-cx * sz, cx * cz, sx,
-cz * sy + cy * sx * sz, -cy * cz * sx - sy * sz, cx * cy
];
// var matrix = [
// cy * cz - sx * sy * sz, cx * sz, cz * sy + cy * sx * sz,
// -cz * sx * sy - cy * sz, cx * cz, cy * cz * sx - sy * sz,
// -cx * sy, -sx, cx * cy
// ];
var rotfn = function (vIn) {
return Vector3.at(
vIn.getX() * matrix[0] + vIn.getY() * matrix[1] + vIn.getZ() * matrix[2],
vIn.getX() * matrix[3] + vIn.getY() * matrix[4] + vIn.getZ() * matrix[5],
vIn.getX() * matrix[6] + vIn.getY() * matrix[7] + vIn.getZ() * matrix[8]
);
};
var rotinvfn = function (vIn) {
return Vector3.at(
vIn.getX() * matrix[0] + vIn.getY() * matrix[3] + vIn.getZ() * matrix[6],
vIn.getX() * matrix[1] + vIn.getY() * matrix[4] + vIn.getZ() * matrix[7],
vIn.getX() * matrix[2] + vIn.getY() * matrix[5] + vIn.getZ() * matrix[8]
);
};
// rot: R(x-b) + b + (b' - b) => Rx + (b' - Rb) => offset = b' - Rb
var offset = player.getBlockLocation().toVector().subtract(
rotfn(clipBoard.getOrigin().toVector3())
);
var ps = [
Vector3.at(minP.getX(), minP.getY(), minP.getZ()),
Vector3.at(maxP.getX(), minP.getY(), minP.getZ()),
Vector3.at(minP.getX(), maxP.getY(), minP.getZ()),
Vector3.at(maxP.getX(), maxP.getY(), minP.getZ()),
Vector3.at(minP.getX(), minP.getY(), maxP.getZ()),
Vector3.at(maxP.getX(), minP.getY(), maxP.getZ()),
Vector3.at(minP.getX(), maxP.getY(), maxP.getZ()),
Vector3.at(maxP.getX(), maxP.getY(), maxP.getZ())
];
// calculate new AABB
var nminX = Infinity, nmaxX = -Infinity;
var nminY = Infinity, nmaxY = -Infinity;
var nminZ = Infinity, nmaxZ = -Infinity;
for (var i = 0; i < 8; i++) {
var p = rotfn(ps[i]);
nminX = Math.min(nminX, p.getX()); nmaxX = Math.max(nmaxX, p.getX());
nminY = Math.min(nminY, p.getY()); nmaxY = Math.max(nmaxY, p.getY());
nminZ = Math.min(nminZ, p.getZ()); nmaxZ = Math.max(nmaxZ, p.getZ());
}
nminX += offset.getX(); nmaxX += offset.getX() + 1;
nminY += offset.getY(); nmaxY += offset.getY() + 1;
nminZ += offset.getZ(); nmaxZ += offset.getZ() + 1;
for (var x = nminX; x <= nmaxX; x++) {
for (var y = nminY; y <= nmaxY; y++) {
for (var z = nminZ; z <= nmaxZ; z++) {
var oldP = rotinvfn(Vector3.at(x, y, z).subtract(offset)).toBlockPoint();
if (region.contains(oldP)) {
var oldBlock = clipBoard.getBlock(oldP);
if (!(ignoreAir && (oldBlock.toString() == "minecraft:air" || oldBlock.toString() == "minecraft:cave_air"))) {
blocks.setBlock(BlockVector3.at(x, y, z), changeDir(oldBlock));
}
}
}
}
}
player.print("Rotated and Pasted");