mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 12:05:51 -04:00
Add a basic rotate transform.
This commit is contained in:
parent
bbf8eeb3df
commit
6d2ab937ce
75
Drawing/Transform/RotateTransform.cs
Normal file
75
Drawing/Transform/RotateTransform.cs
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using MCGalaxy.Drawing.Brushes;
|
||||
using MCGalaxy.Drawing.Ops;
|
||||
|
||||
namespace MCGalaxy.Drawing.Transforms {
|
||||
|
||||
public sealed class RotateTransform : Transform {
|
||||
|
||||
public override string Name { get { return "Rotate"; } }
|
||||
public bool CentreOrigin;
|
||||
double cosX, cosY, cosZ, sinX, sinY, sinZ;
|
||||
int width, height, length;
|
||||
Vec3S32 P;
|
||||
|
||||
public void SetAngles(double xDeg, double yDeg, double zDeg) {
|
||||
cosX = Math.Cos(xDeg * Math.PI / 180.0);
|
||||
cosY = Math.Cos(yDeg * Math.PI / 180.0);
|
||||
cosZ = Math.Cos(zDeg * Math.PI / 180.0);
|
||||
|
||||
sinX = Math.Sin(xDeg * Math.PI / 180.0);
|
||||
sinY = Math.Sin(yDeg * Math.PI / 180.0);
|
||||
sinZ = Math.Sin(zDeg * Math.PI / 180.0);
|
||||
}
|
||||
|
||||
public override void Perform(Vec3S32[] marks, Player p, Level lvl,
|
||||
DrawOp op, Brush brush, Action<DrawOpBlock> output) {
|
||||
P = (op.Min + op.Max) / 2;
|
||||
width = lvl.Width; height = lvl.Height; length = lvl.Length;
|
||||
if (!CentreOrigin) P = op.Origin;
|
||||
op.Perform(marks, p, lvl, brush, b => OutputBlock(b, output));
|
||||
}
|
||||
|
||||
void OutputBlock(DrawOpBlock b, Action<DrawOpBlock> output) {
|
||||
double dx = b.X - P.X, dy = b.Y - P.Y, dz = b.Z - P.Z;
|
||||
double rotX = 0, rotY = 0, rotZ = 0;
|
||||
|
||||
// Rotate X
|
||||
rotY = cosX * dy - sinX * dz;
|
||||
rotZ = sinX * dy + cosX * dz;
|
||||
dy = rotY; dz = rotZ;
|
||||
|
||||
// Rotate Y
|
||||
rotX = cosY * dx + sinY * dz;
|
||||
rotZ = -sinY * dx + cosY * dz;
|
||||
dx = rotX; dz = rotZ;
|
||||
|
||||
// Rotate Z
|
||||
rotX = cosZ * dx - sinZ * dy;
|
||||
rotY = sinZ * dx + cosZ * dy;
|
||||
dx = rotX; dy = rotY;
|
||||
|
||||
b.X = (ushort)(dx + P.X + ((dx % 1) >= 0.5 ? 1 : 0));
|
||||
b.Y = (ushort)(dy + P.Y + ((dy % 1) >= 0.5 ? 1 : 0));
|
||||
b.Z = (ushort)(dz + P.Z + ((dz % 1) >= 0.5 ? 1 : 0));
|
||||
output(b);
|
||||
}
|
||||
}
|
||||
}
|
62
Drawing/TransformFactories/RotateTransform.cs
Normal file
62
Drawing/TransformFactories/RotateTransform.cs
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using MCGalaxy.Commands.Building;
|
||||
|
||||
namespace MCGalaxy.Drawing.Transforms {
|
||||
|
||||
public sealed class RotateTransformFactory : TransformFactory {
|
||||
public override string Name { get { return "Rotate"; } }
|
||||
public override string[] Help { get { return HelpString; } }
|
||||
|
||||
static string[] HelpString = new [] {
|
||||
"%TArguments: [angleX] [angleY] [angleZ] <centre>",
|
||||
"%H[angle] values are values in degrees.",
|
||||
"%H[centre] if given, indicates to scale from the centre of a draw operation, " +
|
||||
"instead of outwards from the first mark. Recommended for cuboid and cylinder.",
|
||||
};
|
||||
|
||||
public override Transform Construct(Player p, string message) {
|
||||
string[] args = message.Split(' ');
|
||||
if (args.Length < 3 || args.Length > 4) { Player.MessageLines(p, Help); return null; }
|
||||
double angleX, angleY, angleZ;
|
||||
RotateTransform rotater = new RotateTransform();
|
||||
|
||||
if (!ParseAngle(p, args[0], out angleX)) return null;
|
||||
if (!ParseAngle(p, args[1], out angleY)) return null;
|
||||
if (!ParseAngle(p, args[2], out angleZ)) return null;
|
||||
rotater.SetAngles(angleX, angleY, angleZ);
|
||||
|
||||
if (args.Length == 3) return rotater; // no centre argument
|
||||
if (!args[args.Length - 1].CaselessEq("centre")) {
|
||||
Player.Message(p, "The mode must be either \"centre\", or not given."); return null;
|
||||
}
|
||||
return rotater;
|
||||
}
|
||||
|
||||
static bool ParseAngle(Player p, string input, out double angle) {
|
||||
if (!Double.TryParse(input, out angle)) {
|
||||
Player.MessageLines(p, HelpString); return false;
|
||||
}
|
||||
if (angle < -360 || angle > 360) {
|
||||
Player.Message(p, "Angle must be between -360 and 360."); return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -35,6 +35,7 @@ namespace MCGalaxy.Drawing.Transforms {
|
||||
|
||||
public static List<TransformFactory> Transforms = new List<TransformFactory>() {
|
||||
new NoTransformFactory(), new ScaleTransformFactory(),
|
||||
new RotateTransformFactory(),
|
||||
};
|
||||
|
||||
public static string Available { get { return Transforms.Join(b => b.Name); } }
|
||||
|
@ -455,8 +455,10 @@
|
||||
<Compile Include="Drawing\Image\ImagePrintDrawOp.cs" />
|
||||
<Compile Include="Drawing\Image\IPalette.cs" />
|
||||
<Compile Include="Drawing\Image\PixelGetter.cs" />
|
||||
<Compile Include="Drawing\TransformFactories\RotateTransform.cs" />
|
||||
<Compile Include="Drawing\TransformFactories\SimpleTransforms.cs" />
|
||||
<Compile Include="Drawing\TransformFactories\TransformFactory.cs" />
|
||||
<Compile Include="Drawing\Transform\RotateTransform.cs" />
|
||||
<Compile Include="Drawing\Transform\SimpleTransforms.cs" />
|
||||
<Compile Include="Drawing\Transform\Transform.cs" />
|
||||
<Compile Include="Economy\Awards.cs" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user