From dc813c92095ff9f427cd199e4fe143ffea95e458 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 22 Mar 2018 16:24:01 +1100 Subject: [PATCH] apparently I deleted this file when rebasing? --- ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs | 124 +++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs diff --git a/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs b/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs new file mode 100644 index 000000000..7e1b05bfa --- /dev/null +++ b/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs @@ -0,0 +1,124 @@ +// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 +using System; +using OpenTK; +using ClassicalSharp; + +#if USE16_BIT +using BlockID = System.UInt16; +#else +using BlockID = System.Byte; +#endif + +namespace ClassicalSharp { + + /// Stores various properties about the blocks in Minecraft Classic. + public static partial class BlockInfo { + + public static Vector3[] MinBB = new Vector3[Block.Count]; + public static Vector3[] MaxBB = new Vector3[Block.Count]; + public static Vector3[] RenderMinBB = new Vector3[Block.Count]; + public static Vector3[] RenderMaxBB = new Vector3[Block.Count]; + + internal static void CalcRenderBounds(BlockID block) { + Vector3 min = MinBB[block], max = MaxBB[block]; + + if (IsLiquid[block]) { + min.X -= 0.1f/16f; max.X -= 0.1f/16f; + min.Z -= 0.1f/16f; max.Z -= 0.1f/16f; + min.Y -= 1.5f/16f; max.Y -= 1.5f/16f; + } else if (Draw[block] == DrawType.Translucent && Collide[block] != CollideType.Solid) { + min.X += 0.1f/16f; max.X += 0.1f/16f; + min.Z += 0.1f/16f; max.Z += 0.1f/16f; + min.Y -= 0.1f/16f; max.Y -= 0.1f/16f; + } + + RenderMinBB[block] = min; RenderMaxBB[block] = max; + } + + internal static byte CalcLightOffset(BlockID block) { + int flags = 0xFF; + Vector3 min = MinBB[block], max = MaxBB[block]; + + if (min.X != 0) flags &= ~(1 << Side.Left); + if (max.X != 1) flags &= ~(1 << Side.Right); + if (min.Z != 0) flags &= ~(1 << Side.Front); + if (max.Z != 1) flags &= ~(1 << Side.Back); + + if ((min.Y != 0 && max.Y == 1) && Draw[block] != DrawType.Gas) { + flags &= ~(1 << Side.Top); + flags &= ~(1 << Side.Bottom); + } + return (byte)flags; + } + + internal static void RecalculateSpriteBB() { + using (FastBitmap fastBmp = new FastBitmap(TerrainAtlas2D.Atlas, true, true)) { + for (int i = 0; i < Block.Count; i++) { + if (Draw[i] != DrawType.Sprite) continue; + RecalculateBB((BlockID)i, fastBmp); + } + } + } + + const float angle = 45f * Utils.Deg2Rad; + static readonly Vector3 centre = new Vector3(0.5f, 0, 0.5f); + internal static void RecalculateBB(BlockID block, FastBitmap fastBmp) { + int elemSize = fastBmp.Width / 16; + int texId = GetTextureLoc(block, Side.Right); + int texX = texId & 0x0F, texY = texId >> 4; + + float topY = GetSpriteBB_TopY(elemSize, texX, texY, fastBmp); + float bottomY = GetSpriteBB_BottomY(elemSize, texX, texY, fastBmp); + float leftX = GetSpriteBB_LeftX(elemSize, texX, texY, fastBmp); + float rightX = GetSpriteBB_RightX(elemSize, texX, texY, fastBmp); + + MinBB[block] = Utils.RotateY(leftX - 0.5f, bottomY, 0, angle) + centre; + MaxBB[block] = Utils.RotateY(rightX - 0.5f, topY, 0, angle) + centre; + CalcRenderBounds(block); + } + + unsafe static float GetSpriteBB_TopY(int size, int tileX, int tileY, FastBitmap fastBmp) { + for (int y = 0; y < size; y++) { + int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); + for (int x = 0; x < size; x++) { + if ((byte)(row[x] >> 24) != 0) + return 1 - (float)y / size; + } + } + return 0; + } + + unsafe static float GetSpriteBB_BottomY(int size, int tileX, int tileY, FastBitmap fastBmp) { + for (int y = size - 1; y >= 0; y--) { + int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); + for (int x = 0; x < size; x++) { + if ((byte)(row[x] >> 24) != 0) + return 1 - (float)(y + 1) / size; + } + } + return 1; + } + + unsafe static float GetSpriteBB_LeftX(int size, int tileX, int tileY, FastBitmap fastBmp) { + for (int x = 0; x < size; x++) { + for (int y = 0; y < size; y++) { + int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); + if ((byte)(row[x] >> 24) != 0) + return (float)x / size; + } + } + return 1; + } + + unsafe static float GetSpriteBB_RightX(int size, int tileX, int tileY, FastBitmap fastBmp) { + for (int x = size - 1; x >= 0; x--) { + for (int y = 0; y < size; y++) { + int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size); + if ((byte)(row[x] >> 24) != 0) + return (float)(x + 1) / size; + } + } + return 0; + } + } +} \ No newline at end of file