예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #4
0
    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;
    }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #8
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }