public void LoadCloudModel() { MeshData modeldata = new MeshData(4 * 6, 6 * 6, false, false, true); modeldata.Rgba2 = null; modeldata.Flags = new int[4 * 6]; float[] CloudSideShadings = new float[] { 1f, 0.9f, 0.9f, 0.7f }; MeshData tile = CloudMeshUtil.GetCubeModelDataForClouds( CloudTileSize / 2, CloudTileSize / 4, new Vec3f(0, 0, 0) ); byte[] rgba = CubeMeshUtil.GetShadedCubeRGBA(ColorUtil.WhiteArgb, CloudSideShadings, false); tile.SetRgba(rgba); tile.Flags = new int[] { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 }; modeldata.AddMeshData(tile); // modeldata will hold xyz (+offset), indices and cloud density InitCustomDataBuffers(modeldata); UpdateBufferContents(modeldata); cloudTilesMeshRef?.Dispose(); cloudTilesMeshRef = capi.Render.UploadMesh(modeldata); }
static MeshData genQuad(BlockFacing face, int voxelX, int voxelY, int voxelZ, int width, int height, ICoreClientAPI capi, Block block) { MeshData mesh = CubeMeshUtil.GetCubeFace(face, width / 32f, height / 32f, new Vec3f(voxelX / 16f, voxelY / 16f, voxelZ / 16f)); float[] sideShadings = CubeMeshUtil.DefaultBlockSideShadingsByFacing; int faceIndex = face.Index; mesh.Rgba = new byte[16]; mesh.Rgba.Fill((byte)(255 * sideShadings[faceIndex])); for (int j = 3; j < mesh.Rgba.Length; j += 4) { mesh.Rgba[j] = (byte)255; // Alpha value } mesh.Rgba2 = new byte[16]; mesh.Rgba2.Fill((byte)(255 * sideShadings[faceIndex])); for (int j = 3; j < mesh.Rgba2.Length; j += 4) { mesh.Rgba2[j] = (byte)255; // Alpha value } mesh.Flags = new int[4]; mesh.Flags.Fill(block.VertexFlags.All | face.NormalPackedFlags | (1 << 14)); mesh.RenderPasses = new int[1]; mesh.RenderPassCount = 1; mesh.RenderPasses[0] = (int)block.RenderPass; mesh.Tints = new int[1]; mesh.TintsCount = 1; mesh.XyzFaces = new int[] { faceIndex }; mesh.XyzFacesCount = 1; return(mesh); }
public void SetFillLevel(int voxelHeight) { if (this.voxelHeight == voxelHeight && cubeModelRef != null) { return; } this.voxelHeight = voxelHeight; if (cubeModelRef != null) { api.Render.DeleteMesh(cubeModelRef); } if (voxelHeight == 0) { return; } MeshData modeldata = CubeMeshUtil.GetCube(8 / 32f, voxelHeight / 24f, new Vec3f(0, 0, 0)); modeldata.Flags = new int[6 * 4]; cubeModelRef = api.Render.UploadMesh(modeldata); }
public override void UpdateVisuals() { CleanTile(); rend.material = ((WallTileVariant)tile.variant).mat; Mesh mesh = new Mesh(); mesh.vertices = CubeMeshUtil.verts; List <int> tris = new List <int>(); if (IsFaceVisible(CardinalDir.NORTH)) { tris.AddRange(CubeMeshUtil.faceNorth); } if (IsFaceVisible(CardinalDir.SOUTH)) { tris.AddRange(CubeMeshUtil.faceSouth); } if (IsFaceVisible(CardinalDir.EAST)) { tris.AddRange(CubeMeshUtil.faceEast); } if (IsFaceVisible(CardinalDir.WEST)) { tris.AddRange(CubeMeshUtil.faceWest); } if (IsFaceVisible(CardinalDir.UP)) { tris.AddRange(CubeMeshUtil.faceUp); } if (IsFaceVisible(CardinalDir.DOWN)) { tris.AddRange(CubeMeshUtil.faceDown); } mesh.triangles = tris.ToArray(); if (tris.Count == 0) { Destroy(gameObject); //Completely obscured wall } mesh.normals = CubeMeshUtil.Normals(); mesh.uv = CubeMeshUtil.UVs(); mesh.OptimizeReorderVertexBuffer(); meshFilter.mesh = mesh; }
protected void genMesh(List <Vec3d> points) { float[] data = new float[points.Count * 3]; for (int i = 0; i < points.Count; i++) { var point = points[i]; data[i * 3 + 0] = (float)point.X; data[i * 3 + 1] = (float)point.Y; data[i * 3 + 2] = (float)point.Z; } quadRef?.Dispose(); var quadMesh = CubeMeshUtil.GetCube(0.5f, 0.5f, 0.5f, new Vec3f(0f, 0f, 0f)); quadMesh.Flags = null; quadMesh.Rgba = null; quadMesh.CustomFloats = new CustomMeshDataPartFloat() { Instanced = true, InterleaveOffsets = new int[] { 0, 12 }, InterleaveSizes = new int[] { 3, 3 }, InterleaveStride = 12, StaticDraw = false, Values = data, Count = data.Length }; var updateMesh = new MeshData(false); updateMesh.CustomFloats = quadMesh.CustomFloats; quadRef = capi.Render.UploadMesh(quadMesh); capi.Render.UpdateMesh(quadRef, updateMesh); }
private MeshData getsimpleVoxelMesh() { Block wireblock = capi.World.GetBlock(new AssetLocation("signals:blockwire")); TextureAtlasPosition tpos = capi.BlockTextureAtlas.GetPosition(wireblock, wireblock.Textures.First().Key); texId = tpos.atlasTextureId; //We first generate a mesh for a single voxel MeshData singleVoxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f)); singleVoxelMesh.Rgba = new byte[6 * 4 * 4].Fill((byte)255); CubeMeshUtil.SetXyzFacesAndPacketNormals(singleVoxelMesh); float subPixelPaddingx = capi.BlockTextureAtlas.SubPixelPaddingX; float subPixelPaddingy = capi.BlockTextureAtlas.SubPixelPaddingY; for (int i = 0; i < singleVoxelMesh.Uv.Length; i++) { if (i % 2 > 0) { singleVoxelMesh.Uv[i] = tpos.y1 + singleVoxelMesh.Uv[i] * 2f / capi.BlockTextureAtlas.Size.Height - subPixelPaddingy; } else { singleVoxelMesh.Uv[i] = tpos.x1 + singleVoxelMesh.Uv[i] * 2f / capi.BlockTextureAtlas.Size.Width - subPixelPaddingx; } } singleVoxelMesh.XyzFaces = (byte[])CubeMeshUtil.CubeFaceIndices.Clone(); singleVoxelMesh.XyzFacesCount = 6; singleVoxelMesh.ClimateColorMapIds = new byte[6].Fill((byte)0); singleVoxelMesh.SeasonColorMapIds = new byte[6].Fill((byte)0); singleVoxelMesh.ColorMapIdsCount = 6; singleVoxelMesh.RenderPasses = new short[singleVoxelMesh.VerticesCount / 4].Fill((short)0); singleVoxelMesh.RenderPassCount = singleVoxelMesh.VerticesCount / 4; return(singleVoxelMesh); }
public void RegenMesh(ItemStack ingot, bool[,,] Voxels, SmithingRecipe recipeToOutline) { if (workItemMeshRef != null) { api.Render.DeleteMesh(workItemMeshRef); workItemMeshRef = null; } if (ingot == null) { return; } if (recipeToOutline != null) { RegenOutlineMesh(recipeToOutline); } this.ingot = ingot; MeshData workItemMesh = new MeshData(24, 36, false); TextureAtlasPosition tpos = api.BlockTextureAtlas.GetPosition(api.World.GetBlock(new AssetLocation("ingotpile")), ingot.Collectible.LastCodePart()); MeshData voxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f)); texId = tpos.atlasTextureId; for (int i = 0; i < voxelMesh.Uv.Length; i++) { voxelMesh.Uv[i] = (i % 2 > 0 ? tpos.y1 : tpos.x1) + voxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size; } voxelMesh.XyzFaces = (int[])CubeMeshUtil.CubeFaceIndices.Clone(); voxelMesh.XyzFacesCount = 6; voxelMesh.Tints = new int[6]; voxelMesh.Flags = new int[24]; voxelMesh.TintsCount = 6; for (int i = 0; i < voxelMesh.Rgba.Length; i++) { voxelMesh.Rgba[i] = 255; } voxelMesh.Rgba2 = voxelMesh.Rgba; MeshData voxelMeshOffset = voxelMesh.Clone(); for (int x = 0; x < 16; x++) { for (int y = 10; y < 16; y++) { for (int z = 0; z < 16; z++) { if (!Voxels[x, y, z]) { continue; } float px = x / 16f; float py = y / 16f; float pz = z / 16f; for (int i = 0; i < voxelMesh.xyz.Length; i += 3) { voxelMeshOffset.xyz[i] = px + voxelMesh.xyz[i]; voxelMeshOffset.xyz[i + 1] = py + voxelMesh.xyz[i + 1]; voxelMeshOffset.xyz[i + 2] = pz + voxelMesh.xyz[i + 2]; } float offsetX = (px * 32f) / api.BlockTextureAtlas.Size; float offsetZ = (pz * 32f) / api.BlockTextureAtlas.Size; for (int i = 0; i < voxelMesh.Uv.Length; i += 2) { voxelMeshOffset.Uv[i] = voxelMesh.Uv[i] + offsetX; voxelMeshOffset.Uv[i + 1] = voxelMesh.Uv[i + 1] + offsetZ; } workItemMesh.AddMeshData(voxelMeshOffset); } } } workItemMeshRef = api.Render.UploadMesh(workItemMesh); }
static MeshData genCube(int voxelX, int voxelY, int voxelZ, int width, int height, int length, ICoreClientAPI capi, ITexPositionSource texSource, float subPixelPadding, int renderpass, int renderFlags) { MeshData mesh = CubeMeshUtil.GetCube( width / 32f, height / 32f, length / 32f, new Vec3f(voxelX / 16f, voxelY / 16f, voxelZ / 16f) ); float[] sideShadings = CubeMeshUtil.DefaultBlockSideShadingsByFacing; for (int i = 0; i < mesh.Rgba.Length; i += 4) { int faceIndex = i / 4 / 4; // 4 rgba per vertex, 4 vertices per face byte b = (byte)(255 * sideShadings[faceIndex]); mesh.Rgba[i + 0] = mesh.Rgba[i + 1] = mesh.Rgba[i + 2] = b; } mesh.Flags = new int[mesh.VerticesCount]; mesh.Flags.Fill(renderFlags); mesh.RenderPasses = new int[mesh.VerticesCount / 4]; mesh.RenderPassCount = mesh.VerticesCount / 4; for (int i = 0; i < mesh.RenderPassCount; i++) { mesh.RenderPasses[i] = renderpass; } mesh.Tints = new int[mesh.VerticesCount / 4]; mesh.TintsCount = mesh.VerticesCount / 4; mesh.XyzFaces = new int[mesh.VerticesCount / 4]; mesh.XyzFacesCount = mesh.VerticesCount / 4; int k = 0; for (int i = 0; i < 6; i++) { mesh.XyzFaces[i] = i; BlockFacing facing = BlockFacing.ALLFACES[i]; bool isOutside = ( (facing == BlockFacing.NORTH && voxelZ == 0) || (facing == BlockFacing.EAST && voxelX + width == 16) || (facing == BlockFacing.SOUTH && voxelZ + length == 16) || (facing == BlockFacing.WEST && voxelX == 0) || (facing == BlockFacing.UP && voxelY + height == 16) || (facing == BlockFacing.DOWN && voxelY == 0) ) ; TextureAtlasPosition tpos = isOutside ? texSource[facing.Code] : texSource["inside-" + facing.Code]; if (tpos == null) { tpos = texSource[facing.Code]; } for (int j = 0; j < 2 * 4; j++) { mesh.Uv[k] = (j % 2 > 0 ? tpos.y1 : tpos.x1) + mesh.Uv[k] * 32f / texSource.AtlasSize - subPixelPadding; k++; } } return(mesh); }
public void RegenMesh(ItemStack workitem, bool[,,] Voxels, ClayFormingRecipe recipeToOutline, int recipeLayer) { workItemMeshRef?.Dispose(); workItemMeshRef = null; if (workitem == null) { return; } if (recipeToOutline != null) { RegenOutlineMesh(recipeToOutline, Voxels, recipeLayer); } this.workItem = workitem; MeshData workItemMesh = new MeshData(24, 36, false); float subPixelPaddingx = api.BlockTextureAtlas.SubPixelPaddingX; float subPixelPaddingy = api.BlockTextureAtlas.SubPixelPaddingY; TextureAtlasPosition tpos = api.BlockTextureAtlas.GetPosition(api.World.GetBlock(new AssetLocation("clayform")), workitem.Collectible.Code.ToShortString()); MeshData singleVoxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f)); singleVoxelMesh.Rgba = new byte[6 * 4 * 4].Fill((byte)255); CubeMeshUtil.SetXyzFacesAndPacketNormals(singleVoxelMesh); texId = tpos.atlasTextureId; for (int i = 0; i < singleVoxelMesh.Uv.Length; i++) { if (i % 2 > 0) { singleVoxelMesh.Uv[i] = tpos.y1 + singleVoxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size.Height - subPixelPaddingy; } else { singleVoxelMesh.Uv[i] = tpos.x1 + singleVoxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size.Width - subPixelPaddingx; } } singleVoxelMesh.XyzFaces = (byte[])CubeMeshUtil.CubeFaceIndices.Clone(); singleVoxelMesh.XyzFacesCount = 6; for (int i = 0; i < 6; i++) { singleVoxelMesh.Flags[i * 4] = singleVoxelMesh.Flags[i * 4 + 1] = singleVoxelMesh.Flags[i * 4 + 2] = singleVoxelMesh.Flags[i * 4 + 3] = VertexFlags.PackNormal(BlockFacing.ALLFACES[i].Normali); } singleVoxelMesh.SeasonColorMapIds = new byte[6]; singleVoxelMesh.ClimateColorMapIds = new byte[6]; singleVoxelMesh.ColorMapIdsCount = 6; MeshData voxelMeshOffset = singleVoxelMesh.Clone(); for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { if (!Voxels[x, y, z]) { continue; } float px = x / 16f; float py = y / 16f; float pz = z / 16f; for (int i = 0; i < singleVoxelMesh.xyz.Length; i += 3) { voxelMeshOffset.xyz[i] = px + singleVoxelMesh.xyz[i]; voxelMeshOffset.xyz[i + 1] = py + singleVoxelMesh.xyz[i + 1]; voxelMeshOffset.xyz[i + 2] = pz + singleVoxelMesh.xyz[i + 2]; } float offsetX = ((((x + 4 * y) % 16f / 16f)) * 32f) / api.BlockTextureAtlas.Size.Width; float offsetY = (pz * 32f) / api.BlockTextureAtlas.Size.Height; for (int i = 0; i < singleVoxelMesh.Uv.Length; i += 2) { voxelMeshOffset.Uv[i] = singleVoxelMesh.Uv[i] + offsetX; voxelMeshOffset.Uv[i + 1] = singleVoxelMesh.Uv[i + 1] + offsetY; } workItemMesh.AddMeshData(voxelMeshOffset); } } } workItemMeshRef = api.Render.UploadMesh(workItemMesh); }
public void RegenMesh(bool[,] Voxels, KnappingRecipe recipeToOutline) { if (workItemMeshRef != null) { api.Render.DeleteMesh(workItemMeshRef); workItemMeshRef = null; } workItem = new ItemStack(api.World.GetBlock(new AssetLocation("knappingsurface"))); if (workItem?.Block == null) { return; } if (recipeToOutline != null) { RegenOutlineMesh(recipeToOutline, Voxels); } MeshData workItemMesh = new MeshData(24, 36, false); workItemMesh.Flags = null; workItemMesh.Rgba2 = null; float subPixelPadding = api.BlockTextureAtlas.SubPixelPadding; TextureAtlasPosition tpos = api.BlockTextureAtlas.GetPosition(workItem.Block, Material); MeshData singleVoxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f)); singleVoxelMesh.Rgba = CubeMeshUtil.GetShadedCubeRGBA(ColorUtil.WhiteArgb, CubeMeshUtil.DefaultBlockSideShadings, false); texId = tpos.atlasTextureId; for (int i = 0; i < singleVoxelMesh.Uv.Length; i += 2) { singleVoxelMesh.Uv[i] = tpos.x1 + singleVoxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size - subPixelPadding; singleVoxelMesh.Uv[i + 1] = tpos.y1 + singleVoxelMesh.Uv[i + 1] * 2f / api.BlockTextureAtlas.Size - subPixelPadding; } singleVoxelMesh.XyzFaces = (int[])CubeMeshUtil.CubeFaceIndices.Clone(); singleVoxelMesh.XyzFacesCount = 6; singleVoxelMesh.Tints = new int[6]; singleVoxelMesh.Flags = null; singleVoxelMesh.TintsCount = 6; MeshData voxelMeshOffset = singleVoxelMesh.Clone(); for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { if (!Voxels[x, z]) { continue; } float px = x / 16f; float pz = z / 16f; for (int i = 0; i < singleVoxelMesh.xyz.Length; i += 3) { voxelMeshOffset.xyz[i] = px + singleVoxelMesh.xyz[i]; voxelMeshOffset.xyz[i + 1] = singleVoxelMesh.xyz[i + 1]; voxelMeshOffset.xyz[i + 2] = pz + singleVoxelMesh.xyz[i + 2]; } float offsetX = (px * 32f) / api.BlockTextureAtlas.Size; float offsetZ = (pz * 32f) / api.BlockTextureAtlas.Size; for (int i = 0; i < singleVoxelMesh.Uv.Length; i += 2) { voxelMeshOffset.Uv[i] = singleVoxelMesh.Uv[i] + offsetX; voxelMeshOffset.Uv[i + 1] = singleVoxelMesh.Uv[i + 1] + offsetZ; } workItemMesh.AddMeshData(voxelMeshOffset); } } workItemMeshRef = api.Render.UploadMesh(workItemMesh); }
public static MeshData GenMesh(ICoreClientAPI capi, ItemStack workitemStack, byte[,,] voxels, out int textureId) { textureId = 0; if (workitemStack == null) { return(null); } MeshData workItemMesh = new MeshData(24, 36, false); workItemMesh.CustomBytes = new CustomMeshDataPartByte() { Conversion = DataConversion.NormalizedFloat, Count = workItemMesh.VerticesCount, InterleaveSizes = new int[] { 1 }, Instanced = false, InterleaveOffsets = new int[] { 0 }, InterleaveStride = 1, Values = new byte[workItemMesh.VerticesCount] }; TextureAtlasPosition tposMetal; TextureAtlasPosition tposSlag; if (workitemStack.Collectible.FirstCodePart() == "ironbloom") { tposSlag = capi.BlockTextureAtlas.GetPosition(capi.World.GetBlock(new AssetLocation("anvil-copper")), "ironbloom"); tposMetal = capi.BlockTextureAtlas.GetPosition(capi.World.GetBlock(new AssetLocation("ingotpile")), "iron"); } else { tposMetal = capi.BlockTextureAtlas.GetPosition(capi.World.GetBlock(new AssetLocation("ingotpile")), workitemStack.Collectible.LastCodePart()); tposSlag = tposMetal; } MeshData metalVoxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f)); CubeMeshUtil.SetXyzFacesAndPacketNormals(metalVoxelMesh); metalVoxelMesh.CustomBytes = new CustomMeshDataPartByte() { Conversion = DataConversion.NormalizedFloat, Count = metalVoxelMesh.VerticesCount, Values = new byte[metalVoxelMesh.VerticesCount] }; textureId = tposMetal.atlasTextureId; metalVoxelMesh.XyzFaces = (byte[])CubeMeshUtil.CubeFaceIndices.Clone(); metalVoxelMesh.XyzFacesCount = 6; //metalVoxelMesh.ColorMapIds = new int[6]; //metalVoxelMesh.TintsCount = 6; for (int i = 0; i < metalVoxelMesh.Rgba.Length; i++) { metalVoxelMesh.Rgba[i] = 255; } //metalVoxelMesh.Rgba2 = null; MeshData slagVoxelMesh = metalVoxelMesh.Clone(); for (int i = 0; i < metalVoxelMesh.Uv.Length; i++) { if (i % 2 > 0) { metalVoxelMesh.Uv[i] = tposMetal.y1 + metalVoxelMesh.Uv[i] * 2f / capi.BlockTextureAtlas.Size.Height; slagVoxelMesh.Uv[i] = tposSlag.y1 + slagVoxelMesh.Uv[i] * 2f / capi.BlockTextureAtlas.Size.Height; } else { metalVoxelMesh.Uv[i] = tposMetal.x1 + metalVoxelMesh.Uv[i] * 2f / capi.BlockTextureAtlas.Size.Width; slagVoxelMesh.Uv[i] = tposSlag.x1 + slagVoxelMesh.Uv[i] * 2f / capi.BlockTextureAtlas.Size.Width; } } MeshData metVoxOffset = metalVoxelMesh.Clone(); MeshData slagVoxOffset = slagVoxelMesh.Clone(); for (int x = 0; x < 16; x++) { for (int y = 0; y < 6; y++) { for (int z = 0; z < 16; z++) { EnumVoxelMaterial mat = (EnumVoxelMaterial)voxels[x, y, z]; if (mat == EnumVoxelMaterial.Empty) { continue; } float px = x / 16f; float py = 10 / 16f + y / 16f; float pz = z / 16f; MeshData mesh = mat == EnumVoxelMaterial.Metal ? metalVoxelMesh : slagVoxelMesh; MeshData meshVoxOffset = mat == EnumVoxelMaterial.Metal ? metVoxOffset : slagVoxOffset; for (int i = 0; i < mesh.xyz.Length; i += 3) { meshVoxOffset.xyz[i] = px + mesh.xyz[i]; meshVoxOffset.xyz[i + 1] = py + mesh.xyz[i + 1]; meshVoxOffset.xyz[i + 2] = pz + mesh.xyz[i + 2]; } float textureSize = 32f / capi.BlockTextureAtlas.Size.Width; float offsetX = px * textureSize; float offsetY = (py * 32f) / capi.BlockTextureAtlas.Size.Width; float offsetZ = pz * textureSize; for (int i = 0; i < mesh.Uv.Length; i += 2) { meshVoxOffset.Uv[i] = mesh.Uv[i] + GameMath.Mod(offsetX + offsetY, textureSize); meshVoxOffset.Uv[i + 1] = mesh.Uv[i + 1] + GameMath.Mod(offsetZ + offsetY, textureSize); } for (int i = 0; i < meshVoxOffset.CustomBytes.Values.Length; i++) { byte glowSub = (byte)GameMath.Clamp(10 * (Math.Abs(x - 8) + Math.Abs(z - 8) + Math.Abs(y - 2)), 100, 250); meshVoxOffset.CustomBytes.Values[i] = (mat == EnumVoxelMaterial.Metal) ? (byte)0 : glowSub; } workItemMesh.AddMeshData(meshVoxOffset); } } } return(workItemMesh); }
public void RegenMesh(ItemStack workitem, bool[,,] Voxels, ClayFormingRecipe recipeToOutline, int recipeLayer) { if (workItemMeshRef != null) { api.Render.DeleteMesh(workItemMeshRef); workItemMeshRef = null; } if (workitem == null) { return; } if (recipeToOutline != null) { RegenOutlineMesh(recipeToOutline, Voxels, recipeLayer); } this.ingot = workitem; MeshData workItemMesh = new MeshData(24, 36, false); workItemMesh.Flags = null; workItemMesh.Rgba2 = null; float subPixelPadding = api.BlockTextureAtlas.SubPixelPadding; TextureAtlasPosition tpos = api.BlockTextureAtlas.GetPosition(api.World.GetBlock(new AssetLocation("clayform")), "clay"); MeshData singleVoxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f)); singleVoxelMesh.Rgba = CubeMeshUtil.GetShadedCubeRGBA(ColorUtil.WhiteArgb, CubeMeshUtil.DefaultBlockSideShadings, false); texId = tpos.atlasTextureId; for (int i = 0; i < singleVoxelMesh.Uv.Length; i++) { singleVoxelMesh.Uv[i] = (i % 2 > 0 ? tpos.y1 : tpos.x1) + singleVoxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size - subPixelPadding; } singleVoxelMesh.XyzFaces = (int[])CubeMeshUtil.CubeFaceIndices.Clone(); singleVoxelMesh.XyzFacesCount = 6; singleVoxelMesh.Tints = new int[6]; singleVoxelMesh.Flags = null; singleVoxelMesh.TintsCount = 6; MeshData voxelMeshOffset = singleVoxelMesh.Clone(); for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { if (!Voxels[x, y, z]) { continue; } float px = x / 16f; float py = y / 16f; float pz = z / 16f; for (int i = 0; i < singleVoxelMesh.xyz.Length; i += 3) { voxelMeshOffset.xyz[i] = px + singleVoxelMesh.xyz[i]; voxelMeshOffset.xyz[i + 1] = py + singleVoxelMesh.xyz[i + 1]; voxelMeshOffset.xyz[i + 2] = pz + singleVoxelMesh.xyz[i + 2]; } float offsetX = ((((x + 4 * y) % 16f / 16f)) * 32f) / api.BlockTextureAtlas.Size; float offsetZ = (pz * 32f) / api.BlockTextureAtlas.Size; for (int i = 0; i < singleVoxelMesh.Uv.Length; i += 2) { voxelMeshOffset.Uv[i] = singleVoxelMesh.Uv[i] + offsetX; voxelMeshOffset.Uv[i + 1] = singleVoxelMesh.Uv[i + 1] + offsetZ; } workItemMesh.AddMeshData(voxelMeshOffset); } } } workItemMeshRef = api.Render.UploadMesh(workItemMesh); }
public void RegenMesh(bool[,] Voxels, KnappingRecipe recipeToOutline) { workItemMeshRef?.Dispose(); workItemMeshRef = null; workItem = new ItemStack(api.World.GetBlock(new AssetLocation("knappingsurface"))); if (workItem?.Block == null) { return; } if (recipeToOutline != null) { RegenOutlineMesh(recipeToOutline, Voxels); } MeshData workItemMesh = new MeshData(24, 36, false); //workItemMesh.Rgba2 = null; float subPixelPaddingx = api.BlockTextureAtlas.SubPixelPaddingX; float subPixelPaddingy = api.BlockTextureAtlas.SubPixelPaddingY; TextureAtlasPosition tpos = api.BlockTextureAtlas.GetPosition(workItem.Block, Material); MeshData singleVoxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f)); singleVoxelMesh.Rgba = new byte[6 * 4 * 4].Fill((byte)255); CubeMeshUtil.SetXyzFacesAndPacketNormals(singleVoxelMesh); texId = tpos.atlasTextureId; for (int i = 0; i < singleVoxelMesh.Uv.Length; i += 2) { singleVoxelMesh.Uv[i] = tpos.x1 + singleVoxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size.Width - subPixelPaddingx; singleVoxelMesh.Uv[i + 1] = tpos.y1 + singleVoxelMesh.Uv[i + 1] * 2f / api.BlockTextureAtlas.Size.Height - subPixelPaddingy; } singleVoxelMesh.XyzFaces = (byte[])CubeMeshUtil.CubeFaceIndices.Clone(); singleVoxelMesh.XyzFacesCount = 6; singleVoxelMesh.ClimateColorMapIds = new byte[6]; singleVoxelMesh.SeasonColorMapIds = new byte[6]; singleVoxelMesh.ColorMapIdsCount = 6; MeshData voxelMeshOffset = singleVoxelMesh.Clone(); for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { if (!Voxels[x, z]) { continue; } float px = x / 16f; float pz = z / 16f; for (int i = 0; i < singleVoxelMesh.xyz.Length; i += 3) { voxelMeshOffset.xyz[i] = px + singleVoxelMesh.xyz[i]; voxelMeshOffset.xyz[i + 1] = singleVoxelMesh.xyz[i + 1]; voxelMeshOffset.xyz[i + 2] = pz + singleVoxelMesh.xyz[i + 2]; } float offsetX = (px * 32f) / api.BlockTextureAtlas.Size.Width; float offsetZ = (pz * 32f) / api.BlockTextureAtlas.Size.Height; for (int i = 0; i < singleVoxelMesh.Uv.Length; i += 2) { voxelMeshOffset.Uv[i] = singleVoxelMesh.Uv[i] + offsetX; voxelMeshOffset.Uv[i + 1] = singleVoxelMesh.Uv[i + 1] + offsetZ; } workItemMesh.AddMeshData(voxelMeshOffset); } } workItemMeshRef = api.Render.UploadMesh(workItemMesh); }
protected static MeshData genCube(int voxelX, int voxelY, int voxelZ, int width, int height, int length, ICoreClientAPI capi, ITexPositionSource texSource, float subPixelPaddingx, float subPixelPaddingy, Block block) { short renderpass = (short)block.RenderPass; int renderFlags = block.VertexFlags.All; MeshData mesh = CubeMeshUtil.GetCube( width / 32f, height / 32f, length / 32f, new Vec3f(voxelX / 16f, voxelY / 16f, voxelZ / 16f) ); mesh.Rgba.Fill((byte)255); mesh.Flags = new int[mesh.VerticesCount]; mesh.Flags.Fill(renderFlags); mesh.RenderPasses = new short[mesh.VerticesCount / 4]; mesh.RenderPassCount = mesh.VerticesCount / 4; for (int i = 0; i < mesh.RenderPassCount; i++) { mesh.RenderPasses[i] = renderpass; } mesh.ColorMapIdsCount = mesh.VerticesCount / 4; mesh.ClimateColorMapIds = new byte[mesh.VerticesCount / 4]; mesh.SeasonColorMapIds = new byte[mesh.VerticesCount / 4]; mesh.XyzFaces = new byte[mesh.VerticesCount / 4]; mesh.XyzFacesCount = mesh.VerticesCount / 4; int k = 0; for (int i = 0; i < 6; i++) { BlockFacing facing = BlockFacing.ALLFACES[i]; mesh.XyzFaces[i] = facing.MeshDataIndex; int normal = facing.NormalPackedFlags; mesh.Flags[i * 4 + 0] |= normal; mesh.Flags[i * 4 + 1] |= normal; mesh.Flags[i * 4 + 2] |= normal; mesh.Flags[i * 4 + 3] |= normal; bool isOutside = ( (facing == BlockFacing.NORTH && voxelZ == 0) || (facing == BlockFacing.EAST && voxelX + width == 16) || (facing == BlockFacing.SOUTH && voxelZ + length == 16) || (facing == BlockFacing.WEST && voxelX == 0) || (facing == BlockFacing.UP && voxelY + height == 16) || (facing == BlockFacing.DOWN && voxelY == 0) ) ; TextureAtlasPosition tpos = isOutside ? texSource[facing.Code] : texSource["inside-" + facing.Code]; if (tpos == null) { tpos = texSource[facing.Code]; } if (tpos == null && block.Textures.Count > 0) { tpos = texSource[block.Textures.First().Key]; } if (tpos == null) { tpos = capi.BlockTextureAtlas.UnknownTexturePosition; } float texWidth = tpos.x2 - tpos.x1; float texHeight = tpos.y2 - tpos.y1; for (int j = 0; j < 2 * 4; j++) { if (j % 2 > 0) { mesh.Uv[k] = tpos.y1 + mesh.Uv[k] * texHeight - subPixelPaddingy; } else { mesh.Uv[k] = tpos.x1 + mesh.Uv[k] * texWidth - subPixelPaddingx; } k++; } } return(mesh); }