diff --git a/EXITCODE.cs b/EXITCODE.cs index 19baba1..4d6e61a 100644 --- a/EXITCODE.cs +++ b/EXITCODE.cs @@ -9,9 +9,18 @@ namespace BuildPlate_Editor public enum EXITCODE : int { Normal = 0, + OpenGL_LowVersion = 1, - World_Load_TextureArray = 4, - World_ReLoad_TextureArray = 5, + + TexturesFile_Existance = 2, // doesn't exist + TexturesFile_Path = 3, + + Failed_BuildPlate_Existance = 4, // doesn't exist + Failed_BuildPlate_Extension = 5, + Failed_BuildPlate_Parse = 6, + + World_Load_TextureArray = 7, + World_ReLoad_TextureArray = 8, World_Render_Block = 10, World_Unknown = 20, } diff --git a/Program.cs b/Program.cs index e6f62d2..e72a02c 100644 --- a/Program.cs +++ b/Program.cs @@ -18,12 +18,8 @@ class Program public static Window Window; public static string baseDir; - static void Main(string[] args) + static int Main(string[] args) { - // this will run on console close - handler = new ConsoleEventDelegate(ConsoleEventCallback); - SetConsoleCtrlHandler(handler, true); - // Get base path (.exe location) string myExecutable = Assembly.GetEntryAssembly().Location; @@ -36,7 +32,7 @@ static void Main(string[] args) Console.WriteLine("You can also do this for .plate and .plate64"); Console.WriteLine("Press any key to continue..."); Console.ReadKey(true); - return; + return (int)EXITCODE.Normal; } baseDir = Path.GetDirectoryName(myExecutable) + "\\"; @@ -72,7 +68,7 @@ static void Main(string[] args) } } else - Console.WriteLine("Ok :(, I won't aks again"); + Console.WriteLine("Ok :(, I won't ask again"); File.WriteAllBytes(baseDir + "askedForDefault", new byte[0]); @@ -82,21 +78,21 @@ static void Main(string[] args) Console.WriteLine("texturesPath.txt doen't exist"); Console.WriteLine($"Extract mce resource pack 2 times and set path to {{path}}/textures/blocks/"); Console.ReadKey(true); - return; + return (int)EXITCODE.TexturesFile_Existance; } string texturesPath = File.ReadAllText(baseDir + "texturesPath.txt"); if (texturesPath == string.Empty || !Directory.Exists(texturesPath)) { Console.WriteLine($"path inside texturesPath.txt ({texturesPath}) doesn't exist"); Console.WriteLine($"Extract mce resource pack 2 times and set path to {{path}}/textures/blocks/"); Console.ReadKey(true); - return; + return (int)EXITCODE.TexturesFile_Path; } char lastChar = texturesPath[texturesPath.Length - 1]; if (lastChar != '\\' && lastChar != '/') texturesPath += '/'; World.textureBasePath = texturesPath; #if DEBUG - World.targetFilePath = @"C:\Users\Tomas\Desktop\Project Earth\Api\data\buildplates\buildplate (1).json"; + World.targetFilePath = @"C:\Users\Tomas\Desktop\Project Earth\Api\data\buildplates\c0eb3037-94c1-4a85-b0d7-7b8375c6f1b1.json"; //World.targetFilePath = @"C:\Users\Tomas\Desktop\Project Earth\Api\data\buildplates\411398a6-5810-43a0-824c-27a9077a9ac3.json"; // fancy //World.targetFilePath = @"C:\Users\Tomas\Desktop\Project Earth\Api\data\buildplates\c0eb3037-94c1-4a85-b0d7-7b8375c6f1b1.json"; // redstone //World.targetFilePath = @"C:\Users\Tomas\Desktop\Project Earth\Api\data\buildplates\c0f771f0-a5d6-4acc-bd35-055e52548a20.json"; // igloo super fancy secret base @@ -107,23 +103,24 @@ static void Main(string[] args) if (args != null && args.Length > 0 && File.Exists(string.Join(" ", args)) && string.Join(" ", args).Split('.').Length > 1) { string truePath = new FileInfo(string.Join(" ", args)).FullName; Console.WriteLine(truePath); - string extension = truePath.Split('.').Last(); - if (extension == "json" || extension == "plate" || extension == "plate64") { + string _extension = truePath.Split('.').Last(); + if (_extension == "json" || _extension == "plate" || _extension == "plate64") { World.targetFilePath = truePath; goto check; } } string buildPlate = Console.ReadLine(); + string extension = Path.GetExtension(buildPlate); if (!File.Exists(buildPlate)) { Console.WriteLine($"build plate \"{buildPlate}\" doesn't exist"); Console.ReadKey(true); - return; - } else if (Path.GetExtension(buildPlate) == ".json" || Path.GetExtension(buildPlate) == ".plate" - || Path.GetExtension(buildPlate) == ".plate64") { + return (int)EXITCODE.Failed_BuildPlate_Existance; + } else if (extension != ".json" && extension != ".plate" + && extension != ".plate64") { Console.WriteLine($"\"{Path.GetExtension(buildPlate)}\" isn't valid buildplate extension, valid: .json, .plate, .plate64"); Console.ReadKey(true); - return; + return (int)EXITCODE.Failed_BuildPlate_Extension; } World.targetFilePath = buildPlate; #endif @@ -135,7 +132,7 @@ static void Main(string[] args) Console.WriteLine($"Couldn't parse \"{World.targetFilePath}\", Make sure it's valid build plate file."); Console.WriteLine("Press any key to exit..."); Console.ReadKey(true); - return; + return (int)EXITCODE.Failed_BuildPlate_Parse; } Window = new Window(); @@ -148,6 +145,8 @@ static void Main(string[] args) else if (int.TryParse(version.Split(' ')[0].Split('.')[1], out int subVer) && mainVer == 4 && subVer < 5) LowVersion(); Window.Run(60d); + + return (int)EXITCODE.Normal; } private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) @@ -167,19 +166,5 @@ private static void LowVersion() if (Console.ReadKey(true).Key != ConsoleKey.Enter) Util.Exit(EXITCODE.OpenGL_LowVersion); } - - // Handle on close event - static bool ConsoleEventCallback(int eventType) - { - if (eventType == 2) { // on exit - Util.Exit(EXITCODE.Normal); - } - return false; - } - static ConsoleEventDelegate handler; // Keeps it from getting garbage collected - - private delegate bool ConsoleEventDelegate(int eventType); - [DllImport("kernel32.dll", SetLastError = true)] - private static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add); } } diff --git a/Util.cs b/Util.cs index 6792531..3a6267c 100644 --- a/Util.cs +++ b/Util.cs @@ -252,6 +252,91 @@ public static Vector2 PixelToGL(Vector2i pos) public static char ToLower(this char c) => c.ToString().ToLower()[0]; + public static void SetXLow(this Vector2[] array, float x) + { + for (int i = 0; i < array.Length; i++) + if (array[i].X < 0.5f) + array[i] = new Vector2(x, array[i].Y); + } + public static void SetXHigh(this Vector2[] array, float x) + { + for (int i = 0; i < array.Length; i++) + if (array[i].X >= 0.5f) + array[i] = new Vector2(x, array[i].Y); + } + public static void SetYLow(this Vector2[] array, float y) + { + for (int i = 0; i < array.Length; i++) + if (array[i].Y < 0.5f) + array[i] = new Vector2(array[i].X, y); + } + public static void SetYHigh(this Vector2[] array, float y) + { + for (int i = 0; i < array.Length; i++) + if (array[i].Y >= 0.5f) + array[i] = new Vector2(array[i].X, y); + } + + public static void SetXLow(this Vector3[] array, float x) + { + for (int i = 0; i < array.Length; i++) + if (array[i].X < 0.5f) + array[i] = new Vector3(x, array[i].Y, array[i].Z); + } + public static void SetXHigh(this Vector3[] array, float x) + { + for (int i = 0; i < array.Length; i++) + if (array[i].X >= 0.5f) + array[i] = new Vector3(x, array[i].Y, array[i].Z); + } + public static void SetZLow(this Vector3[] array, float z) + { + for (int i = 0; i < array.Length; i++) + if (array[i].Z < 0.5f) + array[i] = new Vector3(array[i].X, array[i].Y, z); + } + public static void SetZHigh(this Vector3[] array, float z) + { + for (int i = 0; i < array.Length; i++) + if (array[i].Z >= 0.5f) + array[i] = new Vector3(array[i].X, array[i].Y, z); + } + + public static void FlipX(this Vector2[] array) + { + float low = 0f; + float high = 1f; + + for (int i = 0; i < array.Length; i++) + if (array[i].X < 0.5f) + low = array[i].X; + else + high = array[i].X; + + for (int i = 0; i < array.Length; i++) + if (array[i].X < 0.5f) + array[i] = new Vector2(high, array[i].Y); + else + array[i] = new Vector2(low, array[i].Y); + } + public static void FlipY(this Vector2[] array) + { + float low = 0f; + float high = 1f; + + for (int i = 0; i < array.Length; i++) + if (array[i].Y < 0.5f) + low = array[i].Y; + else + high = array[i].Y; + + for (int i = 0; i < array.Length; i++) + if (array[i].Y < 0.5f) + array[i] = new Vector2(array[i].X, high); + else + array[i] = new Vector2(array[i].X, low); + } + // Set Foregroun [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] diff --git a/VoxelData.cs b/VoxelData.cs index d2b18b5..9f66b4e 100644 --- a/VoxelData.cs +++ b/VoxelData.cs @@ -412,30 +412,123 @@ public static class Rail } public static class Cobweb { - public static readonly Vector3[] verts = new Vector3[8] { - new Vector3(0.0f, 0.0f, 0.0f), // 0 - new Vector3(1.0f, 0.0f, 0.0f), // 1 - new Vector3(1.0f, 1.0f, 0.0f), // 2 - new Vector3(0.0f, 1.0f, 0.0f), // 3 - new Vector3(0.0f, 0.0f, 1.0f), // 4 - new Vector3(1.0f, 0.0f, 1.0f), // 5 - new Vector3(1.0f, 1.0f, 1.0f), // 6 - new Vector3(0.0f, 1.0f, 1.0f) // 7 - }; public static readonly int[,] tris = new int[,] { {0, 3, 5, 6}, {5, 6, 0, 3}, {1, 2, 4, 7}, {4, 7, 1, 2}, }; - /*public static readonly int[,] voxelTris = new int[6, 4] { - {0, 3, 1, 2}, // Back Face - {5, 6, 4, 7}, // Front Face - {3, 7, 2, 6}, // Top Face - {1, 5, 0, 4}, // Bottom Face - {4, 7, 0, 3}, // Left Face - {1, 2, 5, 6} // Right Face - };*/ + } + public static class Redstone + { + public const float DefaultOffset = 0.01f; + public const float toDot = 0.3125f; + public const float toDot2 = 1f - toDot; + public static readonly Vector3[] verts = new Vector3[] + { + new Vector3(0.0f, DefaultOffset, 0.0f), // 0 + new Vector3(1.0f, DefaultOffset, 0.0f), // 1 + new Vector3(0.0f, DefaultOffset, 1.0f), // 2 + new Vector3(1.0f, DefaultOffset, 1.0f), // 3 + }; + public static readonly Vector3[] vertsSide = new Vector3[] + { + new Vector3(DefaultOffset, 0.0f, 0.0f), + new Vector3(DefaultOffset, 1.0f, 0.0f), + new Vector3(DefaultOffset, 0.0f, 1.0f), + new Vector3(DefaultOffset, 1.0f, 1.0f) + }; + public static readonly int[,] tris = new int[2, 4] { + {0, 2, 1, 3}, // Top Face + {1, 3, 0, 2}, // Bottom Face + }; + public static readonly int[,] trisSide = new int[2, 4] { + {2, 3, 0, 1}, + {0, 1, 2, 3}, + }; + public static readonly Vector2[] uvsSide = new Vector2[4] { + new Vector2(1.0f, 0.0f), + new Vector2(0.0f, 0.0f), + new Vector2(1.0f, 1.0f), + new Vector2(0.0f, 1.0f) + }; + } + public static class Lever_Base + { + public const float X = 0.3125f; + public const float X2 = 1f - X; + public const float Y = 0f; + public const float Y2 = 0.1875f; + public const float Z = 0.25f; + public const float Z2 = 1f - Z; + public static readonly Vector3[] verts = new Vector3[8] { + new Vector3(X, Y, Z), // 0 + new Vector3(X2, Y, Z), // 1 + new Vector3(X2, Y2, Z), // 2 + new Vector3(X, Y2, Z), // 3 + new Vector3(X, Y, Z2), // 4 + new Vector3(X2, Y, Z2), // 5 + new Vector3(X2, Y2, Z2), // 6 + new Vector3(X, Y2, Z2) // 7 + }; + public static readonly Vector2[,] uvs = new Vector2[3,4] { // Z Y X + { + new Vector2(X, Y), + new Vector2(X, Y2), + new Vector2(X2, Y), + new Vector2(X2, Y2) + }, + { + new Vector2(X, Z), + new Vector2(X, Z2), + new Vector2(X2, Z), + new Vector2(X2, Z2) + }, + { + new Vector2(Z, Y), + new Vector2(Z, Y2), + new Vector2(Z2, Y), + new Vector2(Z2, Y2) + }, + }; + } + public static class Lever_Top + { + public const float X = 0.4375f; + public const float X2 = 1f - X; + public const float Y = 0f; + public const float Y2 = 0.625f; + public const float Y3 = Y2 - 0.125f; + public static readonly Vector3[] verts = new Vector3[8] { + new Vector3(X, Y, X), // 0 + new Vector3(X2, Y, X), // 1 + new Vector3(X2, Y2, X), // 2 + new Vector3(X, Y2, X), // 3 + new Vector3(X, Y, X2), // 4 + new Vector3(X2, Y, X2), // 5 + new Vector3(X2, Y2, X2), // 6 + new Vector3(X, Y2, X2) // 7 + }; + public static readonly Vector2[,] uvs = new Vector2[3, 4] { // Z Y X + { + new Vector2(X, Y), + new Vector2(X, Y2), + new Vector2(X2, Y), + new Vector2(X2, Y2) + }, + { + new Vector2(X, Y3), + new Vector2(X, Y2), + new Vector2(X2, Y3), + new Vector2(X2, Y2) + }, + { + new Vector2(X, Y), + new Vector2(X, Y2), + new Vector2(X2, Y), + new Vector2(X2, Y2) + }, + }; } } } diff --git a/World.cs b/World.cs index 2b0b438..a8f3548 100644 --- a/World.cs +++ b/World.cs @@ -10,6 +10,7 @@ using System.Text; using System.Threading.Tasks; using SystemPlus; +using SystemPlus.Utils; using static BuildPlate_Editor.Util; namespace BuildPlate_Editor @@ -62,7 +63,6 @@ public static class World { "hay_block", new []{ "hay_block_side" } }, { "melon_block", new []{ "melon_side" } }, { "pumpkin", new []{ "pumpkin_side" } }, - { "redstone_wire", new []{ "redstone_dust_line" } }, { "quartz_block", new []{ "quartz_block_side" } }, // todo { "redstone_dust_dot", new []{ "redstone_dust_cross" } }, { "golden_rail", new []{ "powered_rail" } }, @@ -101,6 +101,7 @@ public static class World { "unlit_redstone_torch", new []{ "redstone_torch_off" } }, { "cocoa", new []{ "cocoa_stage_2" } }, { "reeds", new []{ "reeds.tga" } }, + { "lever", new []{ "cobblestone", "lever" } }, { "smooth_stone", new []{ "stone_slab_top" } }, // maybe not idk // terracotta { "white_glazed_terracotta", new []{ "glazed_terracotta_white" } }, @@ -121,6 +122,7 @@ public static class World // button { "jungle_button", new []{ "planks_jungle" } }, { "wooden_button", new []{ "planks_oak" } }, + { "birch_button", new []{ "planks_birch" } }, }); public static readonly Dictionary> specialTextureLoad = new Dictionary>() // texture => { data, return final texture} @@ -872,6 +874,34 @@ public static class World } } }, + { "redstone_wire", (int data) => + { + int power = data & 0b_1111; + string crossName = $"redstone_dust_cross_{power}.png"; + string lineName = $"redstone_dust_line_{power}.png"; + Vector3 multiplier = Vector3.Lerp(new Vector3(0.25f, 0f, 0f), new Vector3(1f, 0f, 0f), power / 15f); + + DirectBitmap cross = DirectBitmap.Load(textureBasePath + "redstone_dust_cross.png", false); + DirectBitmap line = DirectBitmap.Load(textureBasePath + "redstone_dust_line.png", false); + for (int i = 0; i < cross.Data.Length; i++) + { + Color c = Color.FromArgb(cross.Data[i]); + cross.Data[i] = Color.FromArgb(c.A, (byte)(((c.R / 255f) * multiplier.X) * 255f), (byte)(((c.G / 255f) * multiplier.Y) * 255f), + (byte)(((c.B / 255f) * multiplier.Z) * 255f)).ToArgb(); + } + for (int i = 0; i < line.Data.Length; i++) + { + Color c = Color.FromArgb(line.Data[i]); + line.Data[i] = Color.FromArgb(c.A, (byte)(((c.R / 255f) * multiplier.X) * 255f), (byte)(((c.G / 255f) * multiplier.Y) * 255f), + (byte)(((c.B / 255f) * multiplier.Z) * 255f)).ToArgb(); + } + cross.Bitmap.Save(textureBasePath + crossName); + line.Bitmap.Save(textureBasePath + lineName); + cross.Dispose(); + line.Dispose(); + return new [] { crossName, lineName }; + } + }, // doors { "iron_door", (int data) => { @@ -1058,6 +1088,8 @@ public static class World { "water", 22 }, { "rail", 25 }, { "web", 27 }, + { "redstone_wire", 28 }, + { "lever", 29 }, }; public static readonly bool[] RendererIsFullBlockLookUp = new bool[] @@ -1090,6 +1122,7 @@ public static class World false, // rail false, // rail other false, + false, // redstone wire }; public delegate void RenderBlock(Vector3 pos, Vector3i cp/*chunk pos, pre multiplied*/, int[] tex, int data, ref List vertices, ref List triangles); @@ -1627,13 +1660,10 @@ public static class World } else if (dir == 1) { mat = Matrix3.CreateRotationY(1.5708f); // 90 degrees - offset.Z += 1f; } else if (dir == 2) { mat = Matrix3.CreateRotationY(3.14159f); // 180 degrees - offset.Z += 1f; } else { mat = Matrix3.CreateRotationY(4.71239f); // 270 degrees - offset.X += 1f; } uint tex = (uint)texA[0]; @@ -1641,15 +1671,15 @@ public static class World for (int p = 0; p < 6; p++) { uint firstVertIndex = (uint)verts.Count; if (p == 2 || p == 3) { // top/bottom - verts.Add(new Vertex(pos + VoxelData.Repeater.verts[VoxelData.voxelTris[p, 0]] * mat + offset, VoxelData.voxelUvs[0], tex)); - verts.Add(new Vertex(pos + VoxelData.Repeater.verts[VoxelData.voxelTris[p, 1]] * mat + offset, VoxelData.voxelUvs[1], tex)); - verts.Add(new Vertex(pos + VoxelData.Repeater.verts[VoxelData.voxelTris[p, 2]] * mat + offset, VoxelData.voxelUvs[2], tex)); - verts.Add(new Vertex(pos + VoxelData.Repeater.verts[VoxelData.voxelTris[p, 3]] * mat + offset, VoxelData.voxelUvs[3], tex)); + verts.Add(new Vertex(pos + (VoxelData.Repeater.verts[VoxelData.voxelTris[p, 0]] + offset) * mat, VoxelData.voxelUvs[0], tex)); + verts.Add(new Vertex(pos + (VoxelData.Repeater.verts[VoxelData.voxelTris[p, 1]] + offset) * mat, VoxelData.voxelUvs[1], tex)); + verts.Add(new Vertex(pos + (VoxelData.Repeater.verts[VoxelData.voxelTris[p, 2]] + offset) * mat, VoxelData.voxelUvs[2], tex)); + verts.Add(new Vertex(pos + (VoxelData.Repeater.verts[VoxelData.voxelTris[p, 3]] + offset) * mat, VoxelData.voxelUvs[3], tex)); } else { - verts.Add(new Vertex(pos + VoxelData.Repeater.verts[VoxelData.voxelTris[p, 0]] * mat + offset, VoxelData.Repeater.sideUvs[0], tex)); - verts.Add(new Vertex(pos + VoxelData.Repeater.verts[VoxelData.voxelTris[p, 1]] * mat + offset, VoxelData.Repeater.sideUvs[1], tex)); - verts.Add(new Vertex(pos + VoxelData.Repeater.verts[VoxelData.voxelTris[p, 2]] * mat + offset, VoxelData.Repeater.sideUvs[2], tex)); - verts.Add(new Vertex(pos + VoxelData.Repeater.verts[VoxelData.voxelTris[p, 3]] * mat + offset, VoxelData.Repeater.sideUvs[3], tex)); + verts.Add(new Vertex(pos + (VoxelData.Repeater.verts[VoxelData.voxelTris[p, 0]] + offset) * mat, VoxelData.Repeater.sideUvs[0], tex)); + verts.Add(new Vertex(pos + (VoxelData.Repeater.verts[VoxelData.voxelTris[p, 1]] + offset) * mat, VoxelData.Repeater.sideUvs[1], tex)); + verts.Add(new Vertex(pos + (VoxelData.Repeater.verts[VoxelData.voxelTris[p, 2]] + offset) * mat, VoxelData.Repeater.sideUvs[2], tex)); + verts.Add(new Vertex(pos + (VoxelData.Repeater.verts[VoxelData.voxelTris[p, 3]] + offset) * mat, VoxelData.Repeater.sideUvs[3], tex)); } tris.Add(firstVertIndex); tris.Add(firstVertIndex + 1); @@ -1659,25 +1689,63 @@ public static class World tris.Add(firstVertIndex + 3); } + // first torch offset = -Vector3.One / 2f; + offset.Z += 0.3125f; + for (int p = 0; p < 6; p++) { uint firstVertIndex = (uint)verts.Count; if (p == 2) { // top - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 0]] + offset, VoxelData.Torch.uVsTop[0], torchTex)); - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 1]] + offset, VoxelData.Torch.uVsTop[1], torchTex)); - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 2]] + offset, VoxelData.Torch.uVsTop[2], torchTex)); - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 3]] + offset, VoxelData.Torch.uVsTop[3], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 0]] + offset) * mat, VoxelData.Torch.uVsTop[0], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 1]] + offset) * mat, VoxelData.Torch.uVsTop[1], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 2]] + offset) * mat, VoxelData.Torch.uVsTop[2], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 3]] + offset) * mat, VoxelData.Torch.uVsTop[3], torchTex)); } else if (p == 3) { // bottom - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 0]] + offset, VoxelData.Torch.uVsBottom[0], torchTex)); - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 1]] + offset, VoxelData.Torch.uVsBottom[1], torchTex)); - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 2]] + offset, VoxelData.Torch.uVsBottom[2], torchTex)); - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 3]] + offset, VoxelData.Torch.uVsBottom[3], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 0]] + offset) * mat, VoxelData.Torch.uVsBottom[0], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 1]] + offset) * mat, VoxelData.Torch.uVsBottom[1], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 2]] + offset) * mat, VoxelData.Torch.uVsBottom[2], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 3]] + offset) * mat, VoxelData.Torch.uVsBottom[3], torchTex)); } else { - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 0]] + offset, VoxelData.Torch.uVsSide[0], torchTex)); - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 1]] + offset, VoxelData.Torch.uVsSide[1], torchTex)); - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 2]] + offset, VoxelData.Torch.uVsSide[2], torchTex)); - verts.Add(new Vertex(pos + VoxelData.Torch.verts[VoxelData.voxelTris[p, 3]] + offset, VoxelData.Torch.uVsSide[3], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 0]] + offset) * mat, VoxelData.Torch.uVsSide[0], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 1]] + offset) * mat, VoxelData.Torch.uVsSide[1], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 2]] + offset) * mat, VoxelData.Torch.uVsSide[2], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 3]] + offset) * mat, VoxelData.Torch.uVsSide[3], torchTex)); + } + tris.Add(firstVertIndex); + tris.Add(firstVertIndex + 1); + tris.Add(firstVertIndex + 2); + tris.Add(firstVertIndex + 2); + tris.Add(firstVertIndex + 1); + tris.Add(firstVertIndex + 3); + } + + // second torch + offset = -Vector3.One / 2f; + offset.Z += 0.0625f; + + int delay = (data & 0b_1100) >> 2; + + offset.Z -= 0.125f * delay; + + for (int p = 0; p < 6; p++) { + uint firstVertIndex = (uint)verts.Count; + if (p == 2) { // top + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 0]] + offset) * mat, VoxelData.Torch.uVsTop[0], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 1]] + offset) * mat, VoxelData.Torch.uVsTop[1], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 2]] + offset) * mat, VoxelData.Torch.uVsTop[2], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 3]] + offset) * mat, VoxelData.Torch.uVsTop[3], torchTex)); + } else if (p == 3) { // bottom + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 0]] + offset) * mat, VoxelData.Torch.uVsBottom[0], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 1]] + offset) * mat, VoxelData.Torch.uVsBottom[1], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 2]] + offset) * mat, VoxelData.Torch.uVsBottom[2], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 3]] + offset) * mat, VoxelData.Torch.uVsBottom[3], torchTex)); + } + else { + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 0]] + offset) * mat, VoxelData.Torch.uVsSide[0], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 1]] + offset) * mat, VoxelData.Torch.uVsSide[1], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 2]] + offset) * mat, VoxelData.Torch.uVsSide[2], torchTex)); + verts.Add(new Vertex(pos + (VoxelData.Torch.verts[VoxelData.voxelTris[p, 3]] + offset) * mat, VoxelData.Torch.uVsSide[3], torchTex)); } tris.Add(firstVertIndex); tris.Add(firstVertIndex + 1); @@ -2067,6 +2135,252 @@ public static class World } } }, + { 28, (Vector3 pos, Vector3i cp, int[] texA, int data, ref List vertices, ref List triangles) => // redstone wire + { + uint crossTex = (uint)texA[0]; + uint wireTex = (uint)texA[1]; + + Vector3i[] offsets = new Vector3i[4] { new Vector3i(-1, 0, 0), new Vector3i(1, 0, 0), new Vector3i(0, 0, -1), new Vector3i(0, 0, 1) }; + int[] presence = new int[4]; + int[] validRenderers = new int[] { 28, 14, 16, 23 }; + + Vector3i iPos = (Vector3i)pos; + + for (int i = 0; i < 4; i++) + if (GetRenderer(iPos + cp + offsets[i] + Vector3i.UnitY) == 28) + presence[i] = 2; + else if (GetRenderer(iPos + cp + offsets[i] - Vector3i.UnitY) == 28) + presence[i] = 1; + else { + int r = GetRenderer(iPos + cp + offsets[i]); + for (int j = 0; j < validRenderers.Length; j++) + if (r == validRenderers[j]) { + presence[i] = 1; + break; + } + } + + // if connected to one side or 2 opposite sides, draw wire + if (((presence[0] > 0 || presence[1] > 0) && presence[2] < 1 && presence[3] < 1) + || ((presence[2] > 0 || presence[3] > 0) && presence[0] < 1 && presence[1] < 1)) { + Vector3 offset = -Vector3.One / 2f; + Matrix3 transform = Matrix3.Identity; + if (presence[2] > 0 || presence[3] > 0) + transform = Matrix3.CreateRotationY(1.5708f); // 90 degrees + for (int p = 0; p < 2; p++) { + uint firstVertIndex = (uint)vertices.Count; + vertices.Add(new Vertex(pos + (VoxelData.Redstone.verts[VoxelData.Redstone.tris[p, 0]] + offset) * transform, VoxelData.voxelUvs[0], wireTex)); + vertices.Add(new Vertex(pos + (VoxelData.Redstone.verts[VoxelData.Redstone.tris[p, 1]] + offset) * transform, VoxelData.voxelUvs[1], wireTex)); + vertices.Add(new Vertex(pos + (VoxelData.Redstone.verts[VoxelData.Redstone.tris[p, 2]] + offset) * transform, VoxelData.voxelUvs[2], wireTex)); + vertices.Add(new Vertex(pos + (VoxelData.Redstone.verts[VoxelData.Redstone.tris[p, 3]] + offset) * transform, VoxelData.voxelUvs[3], wireTex)); + triangles.Add(firstVertIndex); + triangles.Add(firstVertIndex + 1); + triangles.Add(firstVertIndex + 2); + triangles.Add(firstVertIndex + 2); + triangles.Add(firstVertIndex + 1); + triangles.Add(firstVertIndex + 3); + } + } else { + Vector3[] verts = VoxelData.Redstone.verts.Cloned(); + Vector2[] uvs = VoxelData.voxelUvs.Cloned(); + + // if not connected on a side, crop verts and uvs + if (presence[0] < 1) { + verts.SetXLow(VoxelData.Redstone.toDot); + uvs.SetXLow(VoxelData.Redstone.toDot); + } + if (presence[1] < 1) { + verts.SetXHigh(VoxelData.Redstone.toDot2); + uvs.SetXHigh(VoxelData.Redstone.toDot2); + } + if (presence[2] < 1) { + verts.SetZLow(VoxelData.Redstone.toDot); + uvs.SetYLow(VoxelData.Redstone.toDot); + } + if (presence[3] < 1) { + verts.SetZHigh(VoxelData.Redstone.toDot2); + uvs.SetYHigh(VoxelData.Redstone.toDot2); + } + + Vector3 offset = -Vector3.One / 2f; + for (int p = 0; p < 2; p++) { + uint firstVertIndex = (uint)vertices.Count; + if (p == 1) + uvs.FlipX(); + vertices.Add(new Vertex(pos + verts[VoxelData.Redstone.tris[p, 0]] + offset, uvs[0], crossTex)); + vertices.Add(new Vertex(pos + verts[VoxelData.Redstone.tris[p, 1]] + offset, uvs[1], crossTex)); + vertices.Add(new Vertex(pos + verts[VoxelData.Redstone.tris[p, 2]] + offset, uvs[2], crossTex)); + vertices.Add(new Vertex(pos + verts[VoxelData.Redstone.tris[p, 3]] + offset, uvs[3], crossTex)); + triangles.Add(firstVertIndex); + triangles.Add(firstVertIndex + 1); + triangles.Add(firstVertIndex + 2); + triangles.Add(firstVertIndex + 2); + triangles.Add(firstVertIndex + 1); + triangles.Add(firstVertIndex + 3); + } + } + + // draw redstone on side of blocks + for (int i = 0; i < presence.Length; i++) + { + if (presence[i] != 2) + continue; + Vector3 offset = -Vector3.One / 2f; + Matrix3 transform = Matrix3.Identity; + if (i == 1) + transform = Matrix3.CreateRotationY(3.14159f); // 180 degrees + else if (i == 2) + transform = Matrix3.CreateRotationY(-1.5708f); // -90 degrees + else if (i == 3) + transform = Matrix3.CreateRotationY(1.5708f); // 90 degrees + for (int p = 0; p < 2; p++) { + uint firstVertIndex = (uint)vertices.Count; + vertices.Add(new Vertex(pos + (VoxelData.Redstone.vertsSide[VoxelData.Redstone.trisSide[p, 0]] + offset) * transform, VoxelData.Redstone.uvsSide[0], wireTex)); + vertices.Add(new Vertex(pos + (VoxelData.Redstone.vertsSide[VoxelData.Redstone.trisSide[p, 1]] + offset) * transform, VoxelData.Redstone.uvsSide[1], wireTex)); + vertices.Add(new Vertex(pos + (VoxelData.Redstone.vertsSide[VoxelData.Redstone.trisSide[p, 2]] + offset) * transform, VoxelData.Redstone.uvsSide[2], wireTex)); + vertices.Add(new Vertex(pos + (VoxelData.Redstone.vertsSide[VoxelData.Redstone.trisSide[p, 3]] + offset) * transform, VoxelData.Redstone.uvsSide[3], wireTex)); + triangles.Add(firstVertIndex); + triangles.Add(firstVertIndex + 1); + triangles.Add(firstVertIndex + 2); + triangles.Add(firstVertIndex + 2); + triangles.Add(firstVertIndex + 1); + triangles.Add(firstVertIndex + 3); + } + } + } + }, + { 29, (Vector3 pos, Vector3i cp, int[] texA, int data, ref List verts, ref List tris) => // lever + { + Vector3 offset = -Vector3.One / 2f; + Matrix3 transform = Matrix3.Identity; + uint stoneTex = (uint)texA[0]; + uint leverTex = (uint)texA[1]; + + bool open = Convert.ToBoolean((data & 0b_1000) >> 3); + int dir = data & 0b_0111; + + if (dir == 5 || dir == 6) + transform = Matrix3.CreateRotationX(3.14159f); // 180 degrees + + if (dir == 1) + transform *= Matrix3.CreateRotationX(1.5708f); // -90 degrees + else if (dir == 2) + transform *= Matrix3.CreateRotationX(-1.5708f); // 90 degrees + else if (dir == 3) + transform *= Matrix3.CreateRotationX(1.5708f); // 90 degrees + else if (dir == 4) + transform *= Matrix3.CreateRotationX(-1.5708f); // -90 degrees + + if (dir < 3 || dir == 6) + transform *= Matrix3.CreateRotationY(1.5708f); // 90 degrees + + // when placed, facing towards player + for (int p = 0; p < 6; p++) { + uint firstVertIndex = (uint)verts.Count; + int uvIndex = p / 2; + verts.Add(new Vertex(pos + (VoxelData.Lever_Base.verts[VoxelData.voxelTris[p, 0]] + offset) * transform, VoxelData.Lever_Base.uvs[uvIndex, 0], stoneTex)); + verts.Add(new Vertex(pos + (VoxelData.Lever_Base.verts[VoxelData.voxelTris[p, 1]] + offset) * transform, VoxelData.Lever_Base.uvs[uvIndex, 1], stoneTex)); + verts.Add(new Vertex(pos + (VoxelData.Lever_Base.verts[VoxelData.voxelTris[p, 2]] + offset) * transform, VoxelData.Lever_Base.uvs[uvIndex, 2], stoneTex)); + verts.Add(new Vertex(pos + (VoxelData.Lever_Base.verts[VoxelData.voxelTris[p, 3]] + offset) * transform, VoxelData.Lever_Base.uvs[uvIndex, 3], stoneTex)); + tris.Add(firstVertIndex); + tris.Add(firstVertIndex + 1); + tris.Add(firstVertIndex + 2); + tris.Add(firstVertIndex + 2); + tris.Add(firstVertIndex + 1); + tris.Add(firstVertIndex + 3); + } + + if (dir >= 1 && dir <= 4) { + transform = Matrix3.Identity; + Vector3 offset2 = Vector3.Zero; + + if (open) { + if (dir == 2 || dir == 4) { + offset2.Y -= 0.25f; + transform *= Matrix3.CreateRotationX(-0.5235f); + } else { + offset2.Y -= 0.25f; + transform *= Matrix3.CreateRotationX(0.5235f); + } + } + else { + if (dir == 2 || dir == 4) { + offset2.Y += 0.25f; + transform *= Matrix3.CreateRotationX(0.5235f); + } else { + offset2.Y += 0.25f; + transform *= Matrix3.CreateRotationX(-0.5235f); + } + } + + if (dir < 3) + transform *= Matrix3.CreateRotationY(1.5708f); // 90 degrees + + if (dir == 1) + transform *= Matrix3.CreateRotationZ(-1.5708f); // -90 degrees + else if (dir == 2) + transform *= Matrix3.CreateRotationZ(1.5708f); // 90 degrees + else if (dir == 3) + transform *= Matrix3.CreateRotationX(1.5708f); // 90 degrees + else + transform *= Matrix3.CreateRotationX(-1.5708f); // -90 degrees + + for (int p = 0; p < 6; p++) { + uint firstVertIndex = (uint)verts.Count; + int uvIndex = p / 2; + verts.Add(new Vertex(pos + (VoxelData.Lever_Top.verts[VoxelData.voxelTris[p, 0]] + offset) * transform + offset2, VoxelData.Lever_Top.uvs[uvIndex, 0], leverTex)); + verts.Add(new Vertex(pos + (VoxelData.Lever_Top.verts[VoxelData.voxelTris[p, 1]] + offset) * transform + offset2, VoxelData.Lever_Top.uvs[uvIndex, 1], leverTex)); + verts.Add(new Vertex(pos + (VoxelData.Lever_Top.verts[VoxelData.voxelTris[p, 2]] + offset) * transform + offset2, VoxelData.Lever_Top.uvs[uvIndex, 2], leverTex)); + verts.Add(new Vertex(pos + (VoxelData.Lever_Top.verts[VoxelData.voxelTris[p, 3]] + offset) * transform + offset2, VoxelData.Lever_Top.uvs[uvIndex, 3], leverTex)); + tris.Add(firstVertIndex); + tris.Add(firstVertIndex + 1); + tris.Add(firstVertIndex + 2); + tris.Add(firstVertIndex + 2); + tris.Add(firstVertIndex + 1); + tris.Add(firstVertIndex + 3); + } + } else { + Vector3 offset2 = Vector3.Zero; + if (open) { + if (dir == 5) + offset2.Z -= 0.25f; + else + offset2.Z += 0.25f; + offset2 *= transform; + transform = Matrix3.CreateRotationX(0.5235f); + } + else { + if (dir == 5) + offset2.Z += 0.25f; + else + offset2.Z -= 0.25f; + offset2 *= transform; + transform = Matrix3.CreateRotationX(-0.5235f); + } + + if (dir == 0 || dir == 6) + transform *= Matrix3.CreateRotationY(1.5708f); // 90 degrees + + if (dir == 5 || dir == 6) + transform *= Matrix3.CreateRotationZ(3.14159f); // 180 degrees + + for (int p = 0; p < 6; p++) { + uint firstVertIndex = (uint)verts.Count; + int uvIndex = p / 2; + verts.Add(new Vertex(pos + (VoxelData.Lever_Top.verts[VoxelData.voxelTris[p, 0]] + offset) * transform + offset2, VoxelData.Lever_Top.uvs[uvIndex, 0], leverTex)); + verts.Add(new Vertex(pos + (VoxelData.Lever_Top.verts[VoxelData.voxelTris[p, 1]] + offset) * transform + offset2, VoxelData.Lever_Top.uvs[uvIndex, 1], leverTex)); + verts.Add(new Vertex(pos + (VoxelData.Lever_Top.verts[VoxelData.voxelTris[p, 2]] + offset) * transform + offset2, VoxelData.Lever_Top.uvs[uvIndex, 2], leverTex)); + verts.Add(new Vertex(pos + (VoxelData.Lever_Top.verts[VoxelData.voxelTris[p, 3]] + offset) * transform + offset2, VoxelData.Lever_Top.uvs[uvIndex, 3], leverTex)); + tris.Add(firstVertIndex); + tris.Add(firstVertIndex + 1); + tris.Add(firstVertIndex + 2); + tris.Add(firstVertIndex + 2); + tris.Add(firstVertIndex + 1); + tris.Add(firstVertIndex + 3); + } + } + } + }, }; public static BuildPlate plate;