public ForgeContentsRenderer(BlockPos pos, ICoreClientAPI capi) { this.pos = pos; this.capi = capi; metals = capi.Assets.TryGet("worldproperties/block/metal.json").ToObject <MetalProperty>(); Block block = capi.World.GetBlock(new AssetLocation("forge")); coaltexpos = capi.BlockTextureAtlas.GetPosition(block, "coal"); embertexpos = capi.BlockTextureAtlas.GetPosition(block, "ember"); MeshData emberMesh = QuadMeshUtil.GetCustomQuadHorizontal(3 / 16f, 0, 3 / 16f, 10 / 16f, 10 / 16f, 255, 255, 255, 255); for (int i = 0; i < emberMesh.Uv.Length; i += 2) { emberMesh.Uv[i + 0] = embertexpos.x1 + emberMesh.Uv[i + 0] * 32f / AtlasSize; emberMesh.Uv[i + 1] = embertexpos.y1 + emberMesh.Uv[i + 1] * 32f / AtlasSize; } emberMesh.Flags = new int[] { 128, 128, 128, 128 }; MeshData coalMesh = QuadMeshUtil.GetCustomQuadHorizontal(3 / 16f, 0, 3 / 16f, 10 / 16f, 10 / 16f, 255, 255, 255, 255); for (int i = 0; i < coalMesh.Uv.Length; i += 2) { coalMesh.Uv[i + 0] = coaltexpos.x1 + coalMesh.Uv[i + 0] * 32f / AtlasSize;; coalMesh.Uv[i + 1] = coaltexpos.y1 + coalMesh.Uv[i + 1] * 32f / AtlasSize;; } emberQuadRef = capi.Render.UploadMesh(emberMesh); coalQuadRef = capi.Render.UploadMesh(coalMesh); }
public void RegenMesh() { ICoreClientAPI capi = api as ICoreClientAPI; mesh = new MeshData(24, 36, false).WithTints().WithRenderpasses(); float subPixelPadding = capi.BlockTextureAtlas.SubPixelPadding; MeshData[] meshesByFace = new MeshData[6]; // North meshesByFace[0] = QuadMeshUtil.GetCustomQuad(0, 0, 0, 1 / 16f, 1 / 16f, 255, 255, 255, 255); meshesByFace[0].Rotate(new Vec3f(1 / 32f, 1 / 32f, 1 / 32f), 0, GameMath.PI, 0); meshesByFace[0].Translate(0, 0, -1 / 16f); // East meshesByFace[1] = QuadMeshUtil.GetCustomQuad(0, 0, 0, 1 / 16f, 1 / 16f, 255, 255, 255, 255); meshesByFace[1].Rotate(new Vec3f(1 / 32f, 1 / 32f, 1 / 32f), 0, GameMath.PIHALF, 0); meshesByFace[1].Translate(1 / 16f, 0, 0); // South meshesByFace[2] = QuadMeshUtil.GetCustomQuad(0, 0, 1 / 16f, 1 / 16f, 1 / 16f, 255, 255, 255, 255); // West meshesByFace[3] = QuadMeshUtil.GetCustomQuad(0, 0, 0, 1 / 16f, 1 / 16f, 255, 255, 255, 255); meshesByFace[3].Rotate(new Vec3f(1 / 32f, 1 / 32f, 1 / 32f), 0, -GameMath.PIHALF, 0); meshesByFace[3].Translate(-1 / 16f, 0, 0); // Up meshesByFace[4] = QuadMeshUtil.GetCustomQuadHorizontal(0, 1 / 16f, 0, 1 / 16f, 1 / 16f, 255, 255, 255, 255); meshesByFace[4].Rotate(new Vec3f(1 / 32f, 1 / 32f, 1 / 32f), GameMath.PI, 0, 0); meshesByFace[4].Translate(0, 1 / 16f, 0); // Down meshesByFace[5] = QuadMeshUtil.GetCustomQuadHorizontal(0, 0, 0, 1 / 16f, 1 / 16f, 255, 255, 255, 255); float[] sideShadings = CubeMeshUtil.DefaultBlockSideShadingsByFacing; for (int i = 0; i < meshesByFace.Length; i++) { MeshData mesh = meshesByFace[i]; mesh.Rgba = new byte[16]; mesh.Rgba.Fill((byte)(255 * sideShadings[i])); mesh.rgba2 = new byte[16]; mesh.rgba2.Fill((byte)(255 * sideShadings[i])); mesh.Flags = new int[4]; mesh.Flags.Fill(0); mesh.RenderPasses = new int[1]; mesh.RenderPassCount = 1; mesh.Tints = new int[1]; mesh.TintsCount = 1; mesh.XyzFaces = new int[] { i }; mesh.XyzFacesCount = 1; TextureAtlasPosition tpos = capi.BlockTextureAtlas.GetPosition(block, BlockFacing.ALLFACES[i].Code); for (int j = 0; j < mesh.Uv.Length; j++) { mesh.Uv[j] = (j % 2 > 0 ? tpos.y1 : tpos.x1) + mesh.Uv[j] * 32f / capi.BlockTextureAtlas.Size - subPixelPadding; } } MeshData[] voxelMeshesOffset = new MeshData[6]; for (int i = 0; i < meshesByFace.Length; i++) { voxelMeshesOffset[i] = meshesByFace[i].Clone(); } // North: Negative Z // East: Positive X // South: Positive Z // West: Negative X bool[] sideVisible = new bool[6]; int[] coords = new int[3]; int[][] coordIndexByFace = new int[][] { // N new int[] { 0, 1 }, // E new int[] { 2, 1 }, // S new int[] { 0, 1 }, // W new int[] { 2, 1 }, // U new int[] { 0, 2 }, // D new int[] { 0, 2 } }; for (int x = 0; x < 16; x++) { coords[0] = x; for (int y = 0; y < 16; y++) { coords[1] = y; for (int z = 0; z < 16; z++) { if (!Voxels[x, y, z]) { continue; } coords[2] = z; float px = x / 16f; float py = y / 16f; float pz = z / 16f; sideVisible[0] = z == 0 || !Voxels[x, y, z - 1]; sideVisible[1] = x == 15 || !Voxels[x + 1, y, z]; sideVisible[2] = z == 15 || !Voxels[x, y, z + 1]; sideVisible[3] = x == 0 || !Voxels[x - 1, y, z]; sideVisible[4] = y == 15 || !Voxels[x, y + 1, z]; sideVisible[5] = y == 0 || !Voxels[x, y - 1, z]; for (int f = 0; f < 6; f++) { if (!sideVisible[f]) { continue; } MeshData facerefmesh = meshesByFace[f]; MeshData faceoffsetmesh = voxelMeshesOffset[f]; for (int i = 0; i < facerefmesh.xyz.Length; i += 3) { faceoffsetmesh.xyz[i] = px + facerefmesh.xyz[i]; faceoffsetmesh.xyz[i + 1] = py + facerefmesh.xyz[i + 1]; faceoffsetmesh.xyz[i + 2] = pz + facerefmesh.xyz[i + 2]; } float offsetX = (coords[coordIndexByFace[f][0]] * 2f) / capi.BlockTextureAtlas.Size; float offsetZ = (coords[coordIndexByFace[f][1]] * 2f) / capi.BlockTextureAtlas.Size; for (int i = 0; i < facerefmesh.Uv.Length; i += 2) { faceoffsetmesh.Uv[i] = facerefmesh.Uv[i] + offsetX; faceoffsetmesh.Uv[i + 1] = facerefmesh.Uv[i + 1] + offsetZ; } mesh.AddMeshData(faceoffsetmesh); } } } } }