diff --git a/Commands/building/CmdTriangle.cs b/Commands/building/CmdTriangle.cs new file mode 100644 index 000000000..91e741270 --- /dev/null +++ b/Commands/building/CmdTriangle.cs @@ -0,0 +1,65 @@ +/* + 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; +using MCGalaxy.Drawing.Ops; +using MCGalaxy.Drawing.Brushes; + +namespace MCGalaxy.Commands { + + /*public sealed class CmdTriangle : DrawCmd { TODO: why is this having issues? + public override string name { get { return "triangle"; } } + public override string shortcut { get { return "tri"; } } + protected override string PlaceMessage { + get { return "Place three blocks to determine the edges."; } + } + + protected override void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { + RevertAndClearState(p, x, y, z); + CatchPos bp = (CatchPos)p.blockchangeObject; + bp.x2 = x; bp.y2 = y; bp.z2 = z; + p.blockchangeObject = bp; + p.Blockchange += new Player.BlockchangeEventHandler(Blockchange3); + } + + void Blockchange3(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { + RevertAndClearState(p, x, y, z); + CatchPos cpos = (CatchPos)p.blockchangeObject; + GetRealBlock(type, extType, p, ref cpos); + Vector3U16[] marks = { new Vector3U16(cpos.x, cpos.y, cpos.z), + new Vector3U16(cpos.x2, cpos.y2, cpos.z2), new Vector3U16(x, y, z) }; + + Brush brush = GetBrush(p, cpos, 0, null); + if (brush == null) return; + if (!DrawOp.DoDrawOp(new TriangleDrawOp(), brush, p, marks)) + return; + if (p.staticCommands) + p.Blockchange += new Player.BlockchangeEventHandler(Blockchange1); + } + + protected override DrawMode ParseMode(string msg) { + return DrawMode.normal; + } + + public override void Help(Player p) { + Player.SendMessage(p, "%T/triangle [brush args]"); + Player.SendMessage(p, "%HDraws a triangle between three points."); + Player.SendMessage(p, " %HFor help about brushes, type %T/help brush%H."); + } + }*/ +} diff --git a/Commands/building/DrawCmd.cs b/Commands/building/DrawCmd.cs index e64e43fab..ff56fa79e 100644 --- a/Commands/building/DrawCmd.cs +++ b/Commands/building/DrawCmd.cs @@ -111,6 +111,7 @@ namespace MCGalaxy.Commands { public DrawMode mode; public byte type, extType; public ushort x, y, z; + public ushort x2, y2, z2; // for triangle public object data; public string message; } diff --git a/Drawing/DrawOps/TriangleDrawOp.cs b/Drawing/DrawOps/TriangleDrawOp.cs new file mode 100644 index 000000000..69fb7ffa8 --- /dev/null +++ b/Drawing/DrawOps/TriangleDrawOp.cs @@ -0,0 +1,58 @@ +/* + 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; + +namespace MCGalaxy.Drawing.Ops { + + public class TriangleDrawOp : DrawOp { + + public override string Name { get { return "Triangle"; } } + + public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) { + // Applying Heron's Formula + double a = (marks[0] - marks[2]).Length; + double b = (marks[1] - marks[2]).Length; + double c = (marks[0] - marks[1]).Length; + double s = (a + b + c) / 2; + return (int)Math.Sqrt(s * (s - a) * (s - b) * (s - c)); + } + + public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) { + Vector3U16 p1 = Min, p2 = Max, a = marks[0]; + Vector316 v0 = marks[1] - a, v1 = marks[2] - a; + float d00 = v0.Dot(v0), d01 = v0.Dot(v1), d11 = v1.Dot(v1); + float invDenom = 1f / (d00 * d11 - d01 * d01); + + for (ushort yy = p1.Y; yy <= p2.Y; yy++) + for (ushort zz = p1.Z; zz <= p2.Z; zz++) + for (ushort xx = p1.X; xx <= p2.X; xx++) + { + // Compute the barycentric coordinates of the point + Vector316 v2 = new Vector3U16(xx, yy, zz) - a; + float d20 = v2.Dot(v0), d21 = v2.Dot(v1); + float v = (d11 * d20 - d01 * d21) * invDenom; + float w = (d00 * d21 - d01 * d20) * invDenom; + float u = 1.0f - v - w; + + if (u >= 0 && u <= 1 && v >= 0 && v <= 1 && w >= 0 && w <= 1) + PlaceBlock(p, lvl, xx, yy, zz, brush); + } + } + } +} diff --git a/Drawing/Vector3U16.cs b/Drawing/Vectors.cs similarity index 60% rename from Drawing/Vector3U16.cs rename to Drawing/Vectors.cs index 594db502f..74245a3a0 100644 --- a/Drawing/Vector3U16.cs +++ b/Drawing/Vectors.cs @@ -1,86 +1,139 @@ -/* - Copyright 2015 MCGalaxy team - - 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; - -namespace MCGalaxy.Drawing { - - public struct Vector3U16 { - - public ushort X, Y, Z; - - public Vector3U16(ushort x, ushort y, ushort z) { - X = x; Y = y; Z = z; - } - - public Vector3U16(ushort value) { - X = value; Y = value; Z = value; - } - - public override bool Equals(object obj) { - return (obj is Vector3U16) && Equals((Vector3U16)obj); - } - - public bool Equals(Vector3U16 other) { - return X == other.X & Y == other.Y && Z == other.Z; - } - - public override int GetHashCode() { - int hashCode = 0; - hashCode += 1000000007 * X; - hashCode += 1000000009 * Y; - hashCode += 1000000021 * Z; - return hashCode; - } - - public static bool operator == (Vector3U16 a, Vector3U16 b) { - return a.X == b.X && a.Y == b.Y && a.Z == b.Z; - } - - public static bool operator != (Vector3U16 a, Vector3U16 b) { - return a.X != b.X || a.Y != b.Y || a.Z != b.Z; - } - - public static Vector3U16 Max(ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) { - return new Vector3U16(Math.Max(x1, x2), Math.Max(y1, y2), Math.Max(z1, z2)); - } - - public static Vector3U16 Min(ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) { - return new Vector3U16(Math.Min(x1, x2), Math.Min(y1, y2), Math.Min(z1, z2)); - } - - public static Vector3U16 Max(Vector3U16 a, Vector3U16 b) { - return new Vector3U16(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y), Math.Max(a.Z, b.Z)); - } - - public static Vector3U16 Min(Vector3U16 a, Vector3U16 b) { - return new Vector3U16(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Min(a.Z, b.Z)); - } - - public static Vector3U16 operator + (Vector3U16 a, Vector3U16 b) { - return new Vector3U16((ushort)(a.X + b.X), (ushort)(a.Y + b.Y), (ushort)(a.Z + b.Z)); - } - - public static Vector3U16 operator - (Vector3U16 a, Vector3U16 b) { - return new Vector3U16((ushort)(a.X - b.X), (ushort)(a.Y - b.Y), (ushort)(a.Z - b.Z)); - } - - public override string ToString() { - return X + "," + Y + "," + Z; - } - } -} +/* + Copyright 2015 MCGalaxy team + + 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; + +namespace MCGalaxy.Drawing { + + public struct Vector3U16 { + + public ushort X, Y, Z; + + public Vector3U16(ushort x, ushort y, ushort z) { + X = x; Y = y; Z = z; + } + + public Vector3U16(ushort value) { + X = value; Y = value; Z = value; + } + + public override bool Equals(object obj) { + return (obj is Vector3U16) && Equals((Vector3U16)obj); + } + + public bool Equals(Vector3U16 other) { + return X == other.X & Y == other.Y && Z == other.Z; + } + + public override int GetHashCode() { + int hashCode = 0; + hashCode += 1000000007 * X; + hashCode += 1000000009 * Y; + hashCode += 1000000021 * Z; + return hashCode; + } + + public int LengthSquared { get { return X * X + Y * Y + Z * Z; } } + + public double Length { get { return Math.Sqrt( X * X + Y * Y + Z * Z ); } } + + public float Dot(Vector3U16 b) { return X * b.X + Y * b.Y + Z * b.Z; } + + public Vector3U16 Max(Vector3U16 b) { return Max(this, b); } + + public Vector3U16 Min(Vector3U16 b) { return Min(this, b); } + + public static Vector3U16 Max(ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) { + return new Vector3U16(Math.Max(x1, x2), Math.Max(y1, y2), Math.Max(z1, z2)); + } + + public static Vector3U16 Min(ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) { + return new Vector3U16(Math.Min(x1, x2), Math.Min(y1, y2), Math.Min(z1, z2)); + } + + public static Vector3U16 Max(Vector3U16 a, Vector3U16 b) { + return new Vector3U16(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y), Math.Max(a.Z, b.Z)); + } + + public static Vector3U16 Min(Vector3U16 a, Vector3U16 b) { + return new Vector3U16(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Min(a.Z, b.Z)); + } + + public static bool operator == (Vector3U16 a, Vector3U16 b) { + return a.X == b.X && a.Y == b.Y && a.Z == b.Z; + } + + public static bool operator != (Vector3U16 a, Vector3U16 b) { + return a.X != b.X || a.Y != b.Y || a.Z != b.Z; + } + + public static Vector3U16 operator + (Vector3U16 a, Vector3U16 b) { + return new Vector3U16((ushort)(a.X + b.X), (ushort)(a.Y + b.Y), (ushort)(a.Z + b.Z)); + } + + public static Vector316 operator - (Vector3U16 a, Vector3U16 b) { + return new Vector316((short)(a.X - b.X), (short)(a.Y - b.Y), (short)(a.Z - b.Z)); + } + + public override string ToString() { + return X + "," + Y + "," + Z; + } + } + + public struct Vector316 { + + public short X, Y, Z; + + public Vector316(short x, short y, short z) { + X = x; Y = y; Z = z; + } + + public override bool Equals(object obj) { + return (obj is Vector316) && Equals((Vector316)obj); + } + + public bool Equals(Vector316 other) { + return X == other.X & Y == other.Y && Z == other.Z; + } + + public override int GetHashCode() { + int hashCode = 0; + hashCode += 1000000007 * X; + hashCode += 1000000009 * Y; + hashCode += 1000000021 * Z; + return hashCode; + } + + public int LengthSquared { get { return X * X + Y * Y + Z * Z; } } + + public double Length { get { return Math.Sqrt( X * X + Y * Y + Z * Z ); } } + + public float Dot(Vector316 b) { return X * b.X + Y * b.Y + Z * b.Z; } + + public static bool operator == (Vector316 a, Vector316 b) { + return a.X == b.X && a.Y == b.Y && a.Z == b.Z; + } + + public static bool operator != (Vector316 a, Vector316 b) { + return a.X != b.X || a.Y != b.Y || a.Z != b.Z; + } + + public override string ToString() { + return X + "," + Y + "," + Z; + } + } +} diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj index c89587cdd..49a8a56d8 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -128,6 +128,7 @@ + @@ -410,8 +411,9 @@ + - +