void RegenMesh()
        {
            workItemMeshRef?.Dispose();
            workItemMeshRef = null;
            if (stack == null)
            {
                return;
            }

            Shape shape;

            tmpMetal = stack.Collectible.LastCodePart();

            if (stack.Collectible.FirstCodePart() == "metalplate")
            {
                tmpTextureSource = capi.Tesselator.GetTexSource(capi.World.GetBlock(new AssetLocation("platepile")));
                shape            = capi.Assets.TryGet("shapes/block/stone/forge/platepile.json").ToObject <Shape>();
            }
            else
            {
                tmpTextureSource = capi.Tesselator.GetTexSource(capi.World.GetBlock(new AssetLocation("ingotpile")));
                shape            = capi.Assets.TryGet("shapes/block/stone/forge/ingotpile.json").ToObject <Shape>();
            }

            workItemTexPos = tmpTextureSource[tmpMetal];


            MeshData mesh;

            capi.Tesselator.TesselateShape("block-fcr", shape, out mesh, this, null, 0, 0, stack.StackSize);
            mesh.Rgba2 = null;

            workItemMeshRef = capi.Render.UploadMesh(mesh);
        }
        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);
        }
예제 #3
0
        public override void OnBeforeRender(ICoreClientAPI capi, ItemStack itemstack, EnumItemRenderTarget target, ref ItemRenderInfo renderinfo)
        {
            string blockMaterialCode = GetBlockMaterialCode(itemstack);

            if (blockMaterialCode == null)
            {
                return;
            }

            string key = "pan-filled-" + blockMaterialCode;

            renderinfo.ModelRef = ObjectCacheUtil.GetOrCreate <MeshRef>(capi, key, () =>
            {
                AssetLocation shapeloc = new AssetLocation("shapes/block/wood/pan/filled.json");
                Shape shape            = capi.Assets.TryGet(shapeloc).ToObject <Shape>();
                MeshData meshdata;

                Block block      = capi.World.GetBlock(new AssetLocation(blockMaterialCode));
                AtlasSize        = capi.BlockTextureAtlas.Size;
                matTexPosition   = capi.BlockTextureAtlas.GetPosition(block, "up");
                ownTextureSource = capi.Tesselator.GetTexSource(this);

                capi.Tesselator.TesselateShape("filledpan", shape, out meshdata, this);

                return(capi.Render.UploadMesh(meshdata));
            });
        }
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                if (contentTextPos == null)
                {
                    int textureSubId;

                    textureSubId = ObjectCacheUtil.GetOrCreate <int>(capi, "contenttexture-" + contentTexture.ToString() + "-" + contentTexture.Alpha, () =>
                    {
                        TextureAtlasPosition texPos;
                        int id = 0;

                        BitmapRef bmp = capi.Assets.TryGet(contentTexture.Base.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi);
                        if (bmp != null)
                        {
                            if (contentTexture.Alpha != 255)
                            {
                                bmp.MulAlpha(contentTexture.Alpha);
                            }
                            capi.BlockTextureAtlas.InsertTexture(bmp, out id, out texPos);
                            bmp.Dispose();
                        }

                        return(id);
                    });

                    contentTextPos = capi.BlockTextureAtlas.Positions[textureSubId];
                }

                return(contentTextPos);
            }
        }
 public TextureAtlasPosition this[string textureCode]
 {
     get
     {
         TextureAtlasPosition pos = capi.BlockTextureAtlas.GetPosition(block, "up");
         return(pos);
     }
 }
예제 #6
0
 public FlaskTextureSource(ICoreClientAPI capi, ItemStack forContents, CompositeTexture contentTexture, Block flask)
 {
     this.capi           = capi;
     this.forContents    = forContents;
     this.contentTexture = contentTexture;
     this.corkTextPos    = capi.BlockTextureAtlas.GetPosition(flask, "topper");
     this.blockTextPos   = capi.BlockTextureAtlas.GetPosition(flask, "glass");
     this.bracingTextPos = capi.BlockTextureAtlas.GetPosition(flask, "bracing");
 }
        protected override ITexPositionSource GetTextureSource()
        {
            TextureAtlasPosition origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.FirstTexture.Baked.TextureSubId];
            int width  = (int)((origTexPos.x2 - origTexPos.x1) * AtlasSize);
            int height = (int)((origTexPos.x2 - origTexPos.x1) * AtlasSize);

            capi.EntityTextureAtlas.AllocateTextureSpace(width, height, out skinTextureSubId, out skinTexPos);

            return(this);
        }
예제 #8
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                AssetLocation textureLoc = null;
                if (curContProps.Textures != null)
                {
                    CompositeTexture compTex;
                    if (curContProps.Textures.TryGetValue(textureCode, out compTex))
                    {
                        textureLoc = compTex.Base;
                    }
                }

                if (textureLoc == null && shapeTextures != null)
                {
                    shapeTextures.TryGetValue(textureCode, out textureLoc);
                }

                if (textureLoc != null)
                {
                    TextureAtlasPosition texPos = capi.BlockTextureAtlas[textureLoc];
                    if (texPos == null)
                    {
                        BitmapRef bmp = capi.Assets.TryGet(textureLoc.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi);
                        if (bmp != null)
                        {
                            capi.BlockTextureAtlas.InsertTextureCached(textureLoc, bmp, out _, out texPos);
                            bmp.Dispose();
                        }
                    }

                    return(texPos);
                }

                ItemStack content = GetContents();
                if (content.Class == EnumItemClass.Item)
                {
                    TextureAtlasPosition texPos;
                    textureLoc = content.Item.Textures[textureCode].Base;
                    BitmapRef bmp = capi.Assets.TryGet(textureLoc.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi);
                    if (bmp != null)
                    {
                        capi.BlockTextureAtlas.InsertTextureCached(textureLoc, bmp, out _, out texPos);
                        bmp.Dispose();
                        return(texPos);
                    }
                }

                return(contentTexSource[textureCode]);
            }
        }
예제 #9
0
        public static MeshData WithTexPos(this MeshData mesh, TextureAtlasPosition texPos)
        {
            MeshData meshClone = mesh.Clone();

            for (int i = 0; i < meshClone.Uv.Length; i++)
            {
                float x = texPos.x2 - texPos.x1;
                float y = texPos.y2 - texPos.y1;

                meshClone.Uv[i] = i % 2 == 0 ? (meshClone.Uv[i] * x) + texPos.x1 : (meshClone.Uv[i] * y) + texPos.y1;
            }
            return(meshClone);
        }
예제 #10
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                TextureAtlasPosition tp = contentsTexSource["inBucket"];
                if (tp != null)
                {
                    return(tp);
                }

                tp = contentsTexSource[forContents.Collectible.Code.Path.ToLowerInvariant()];
                return(tp == null ? contentsTexSource["up"] : tp);
            }
        }
예제 #11
0
        protected override ITexPositionSource GetTextureSource()
        {
            if (!textureSpaceAllocated)
            {
                TextureAtlasPosition origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.FirstTexture.Baked.TextureSubId];
                int width  = (int)((origTexPos.x2 - origTexPos.x1) * AtlasSize.Width);
                int height = (int)((origTexPos.y2 - origTexPos.y1) * AtlasSize.Height);

                capi.EntityTextureAtlas.AllocateTextureSpace(width, height, out skinTextureSubId, out skinTexPos);

                textureSpaceAllocated = true;
            }

            return(base.GetTextureSource());
        }
예제 #12
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                AssetLocation    texturePath = null;
                CompositeTexture tex;
                if (nowTesselatingItem.Textures.TryGetValue(textureCode, out tex))
                {
                    texturePath = tex.Baked.BakedName;
                }
                else
                {
                    if (nowTesselatingItem.Textures.TryGetValue("all", out tex))
                    {
                        texturePath = tex.Baked.BakedName;
                    }
                    else
                    {
                        nowTesselatingShape?.Textures.TryGetValue(textureCode, out texturePath);
                    }
                }

                if (texturePath == null)
                {
                    texturePath = new AssetLocation(textureCode);
                }

                TextureAtlasPosition texpos = capi.BlockTextureAtlas[texturePath];



                if (texpos == null)
                {
                    IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                    if (texAsset != null)
                    {
                        BitmapRef bmp = texAsset.ToBitmap(capi);
                        capi.BlockTextureAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos);
                    }
                    else
                    {
                        capi.World.Logger.Warning("For render in block " + Block.Code + ", item {0} defined texture {1}, not no such texture found.", nowTesselatingItem.Code, texturePath);
                    }
                }

                return(texpos);
            }
        }
        protected TextureAtlasPosition getOrCreateTexPos(AssetLocation texturePath)
        {
            TextureAtlasPosition texpos = capi.BlockTextureAtlas[texturePath];

            if (texpos == null)
            {
                IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                if (texAsset != null)
                {
                    BitmapRef bmp = texAsset.ToBitmap(capi);
                    capi.BlockTextureAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos);
                }
                else
                {
                    capi.World.Logger.Warning("For render in block " + Block.Code + ", item {0} defined texture {1}, not no such texture found.", nowTesselatingObj.Code, texturePath);
                }
            }

            return(texpos);
        }
예제 #14
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                if (textureCode == "topper" && corkTextPos != null)
                {
                    return(corkTextPos);
                }
                if (textureCode == "glass" && blockTextPos != null)
                {
                    return(blockTextPos);
                }
                if (textureCode == "bracing" && bracingTextPos != null)
                {
                    return(bracingTextPos);
                }
                if (contentTextPos == null)
                {
                    int textureSubId;

                    textureSubId = ObjectCacheUtil.GetOrCreate <int>(capi, "contenttexture-" + contentTexture.ToString(), () =>
                    {
                        TextureAtlasPosition texPos;
                        int id = 0;

                        BitmapRef bmp = capi.Assets.TryGet(contentTexture.Base.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi);
                        if (bmp != null)
                        {
                            capi.BlockTextureAtlas.InsertTexture(bmp, out id, out texPos);
                            bmp.Dispose();
                        }

                        return(id);
                    });

                    contentTextPos = capi.BlockTextureAtlas.Positions[textureSubId];
                }

                return(contentTextPos);
            }
        }
예제 #15
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                AssetLocation texturePath = crustTextureLoc;
                if (textureCode == "filling")
                {
                    texturePath = fillingTextureLoc;
                }
                if (textureCode == "topcrust")
                {
                    texturePath = topCrustTextureLoc;
                }

                if (texturePath == null)
                {
                    capi.World.Logger.Warning("Missing texture path for pie mesh texture code {0}, seems like a missing texture definition or invalid pie block.", textureCode);
                    return(capi.BlockTextureAtlas.UnknownTexturePosition);
                }

                TextureAtlasPosition texpos = capi.BlockTextureAtlas[texturePath];

                if (texpos == null)
                {
                    IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                    if (texAsset != null)
                    {
                        BitmapRef bmp = texAsset.ToBitmap(capi);
                        capi.BlockTextureAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos);
                    }
                    else
                    {
                        capi.World.Logger.Warning("Pie mesh texture {1} not found.", nowTesselatingBlock.Code, texturePath);
                        texpos = capi.BlockTextureAtlas.UnknownTexturePosition;
                    }
                }


                return(texpos);
            }
        }
예제 #16
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                if (nowTeselatingLabel != null)
                {
                    return(labelTexturePos);
                }

                TextureAtlasPosition pos = tmpTextureSource[curType + "-" + textureCode];
                if (pos == null)
                {
                    pos = tmpTextureSource[textureCode];
                }
                if (pos == null)
                {
                    pos = (api as ICoreClientAPI).BlockTextureAtlas.UnknownTexturePosition;
                }
                return(pos);
            }
        }
예제 #17
0
        public MeshData GenLabelMesh(ICoreClientAPI capi, string label, TextureAtlasPosition texPos, bool editableVariant, Vec3f rotation = null)
        {
            Props.Labels.TryGetValue(label, out var labelProps);
            if (Props == null)
            {
                throw new ArgumentException("No label props found for this label");
            }

            AssetLocation shapeloc = (editableVariant ? labelProps.EditableShape : labelProps.Shape).Base.Clone().WithPathAppendixOnce(".json").WithPathPrefixOnce("shapes/");
            Shape         shape    = capi.Assets.TryGet(shapeloc)?.ToObject <Shape>();

            var rot = rotation == null ? new Vec3f(labelProps.Shape.rotateX, labelProps.Shape.rotateY, labelProps.Shape.rotateZ) : rotation;

            nowTeselatingLabel = labelProps;
            labelTexturePos    = texPos;

            capi.Tesselator.TesselateShape("cratelabel", shape, out var meshLabel, this, rot);
            nowTeselatingLabel = null;

            return(meshLabel);
        }
예제 #18
0
        protected TextureAtlasPosition getOrCreateTexPos(AssetLocation texturePath)
        {
            var capi = api as ICoreClientAPI;
            TextureAtlasPosition texpos = curAtlas[texturePath];

            if (texpos == null)
            {
                IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                if (texAsset != null)
                {
                    BitmapRef bmp = texAsset.ToBitmap(capi);
                    curAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos, 0.1f);
                }
                else
                {
                    capi.World.Logger.Warning("Item {0} defined texture {1}, not no such texture found.", Code, texturePath);
                }
            }

            return(texpos);
        }
예제 #19
0
        protected override ITexPositionSource GetTextureSource()
        {
            if (!textureSpaceAllocated)
            {
                TextureAtlasPosition origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.FirstTexture.Baked.TextureSubId];
                string skinBaseTextureKey       = entity.Properties.Attributes?["skinBaseTextureKey"].AsString();
                if (skinBaseTextureKey != null)
                {
                    origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.Textures[skinBaseTextureKey].Baked.TextureSubId];
                }

                int width  = (int)((origTexPos.x2 - origTexPos.x1) * AtlasSize.Width);
                int height = (int)((origTexPos.y2 - origTexPos.y1) * AtlasSize.Height);

                capi.EntityTextureAtlas.AllocateTextureSpace(width, height, out skinTextureSubId, out skinTexPos);

                textureSpaceAllocated = true;
            }

            return(base.GetTextureSource());
        }
예제 #20
0
            public override void Initialize(ICoreAPI api)
            {
                base.Initialize(api);

                if (api.Side == EnumAppSide.Client)
                {
                    ICoreClientAPI capi     = api as ICoreClientAPI;
                    Block          ownBlock = api.World.BlockAccessor.GetBlock(Pos);

                    // Loads the mesh from a model created by VS Model Creator, but you could just as well create a mesh in code, e.g. via QuadMeshUtil.GetCustomQuad();
                    Shape shape = capi.Assets.TryGet(new AssetLocation("customshapeblock", "shapes/customshapes/plane.json")).ToObject <Shape>();
                    texPosition = capi.BlockTextureAtlas.GetPosition(ownBlock, "north");
                    capi.Tesselator.TesselateShape("customshape", shape, out plane, this);

                    // Alternatively you can also use the block itself as texture souce and not implement ITexPositionSource
                    //capi.Tesselator.TesselateShape(ownBlock, shape, out plane);

                    // Move the model up by half a block. Alternatively move it up by half a block in the VSMC model
                    plane.Translate(0, 0.5f, 0);
                }
            }
예제 #21
0
파일: TFForge.cs 프로젝트: Niker323/VS-mods
    public TFForgeContentsRenderer(BlockPos pos, ICoreClientAPI capi)
    {
        this.pos  = pos;
        this.capi = capi;

        Block block = capi.World.GetBlock(new AssetLocation("temporalengineering:tfforge"));

        hetexpos = capi.BlockTextureAtlas.GetPosition(block, "iron");

        MeshData heMesh;
        Shape    ovshape = capi.Assets.TryGet(new AssetLocation("temporalengineering:shapes/block/tfforge/heating_element.json")).ToObject <Shape>();

        capi.Tesselator.TesselateShape(block, ovshape, out heMesh);

        for (int i = 0; i < heMesh.Uv.Length; i += 2)
        {
            heMesh.Uv[i + 0] = hetexpos.x1 + heMesh.Uv[i + 0] * 32f / AtlasSize.Width;
            heMesh.Uv[i + 1] = hetexpos.y1 + heMesh.Uv[i + 1] * 32f / AtlasSize.Height;
        }

        heQuadRef = capi.Render.UploadMesh(heMesh);
    }
예제 #22
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);
        }
        private void Essr_OnReloadSkin(LoadedTexture atlas, TextureAtlasPosition skinTexPos)
        {
            ICoreClientAPI capi = entity.World.Api as ICoreClientAPI;

            foreach (var val in AppliedSkinParts)
            {
                SkinnablePart part = AvailableSkinPartsByCode[val.PartCode];

                if (part.Type != EnumSkinnableType.Texture)
                {
                    continue;
                }
                if (part.TextureTarget != null && part.TextureTarget != "seraph")
                {
                    continue;
                }

                LoadedTexture texture = new LoadedTexture(capi);

                capi.Render.GetOrLoadTexture(val.Texture.Clone().WithPathAppendixOnce(".png"), ref texture);


                int posx = part.TextureRenderTo.X;
                int posy = part.TextureRenderTo.Y;

                capi.EntityTextureAtlas.RenderTextureIntoAtlas(
                    texture,
                    0,
                    0,
                    texture.Width,
                    texture.Height,
                    skinTexPos.x1 * capi.EntityTextureAtlas.Size.Width + posx,
                    skinTexPos.y1 * capi.EntityTextureAtlas.Size.Height + posy
                    );
            }
        }
        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);
        }
예제 #25
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);
        }
예제 #26
0
 public static void SetUv(this MeshData mesh, TextureAtlasPosition texPos) => mesh.SetUv(new float[] { texPos.x1, texPos.y1, texPos.x2, texPos.y1, texPos.x2, texPos.y2, texPos.x1, texPos.y2 });
예제 #27
0
        public override void reloadSkin()
        {
            if (skinTexPos == null)
            {
                GetTextureSource();
            }

            TextureAtlasPosition origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.FirstTexture.Baked.TextureSubId];

            LoadedTexture entityAtlas = new LoadedTexture(null)
            {
                TextureId = origTexPos.atlasTextureId,
                Width     = capi.EntityTextureAtlas.Size.Width,
                Height    = capi.EntityTextureAtlas.Size.Height
            };

            capi.Render.GlToggleBlend(true, EnumBlendMode.Overlay);

            string componentPath = "characters:textures/entity/skin/";

            string[] skinParts = Enum.GetNames(typeof(EnumSkinPart));
            for (int x = 0; x < skinParts.Length; x++)
            {
                AssetLocation componentLoc;
                string        skinProperty = skinParts[x];
                float         alphaTest    = 0.005f;

                if (skinProperty == "hairtype" || skinProperty == "facialhair")
                {
                    if (entity.WatchedAttributes.GetString(skinProperty, "none") == "none")
                    {
                        continue;
                    }
                }

                switch (skinProperty)
                {
                case "skincolor":
                    componentLoc = new AssetLocation(
                        componentPath +
                        "skins/" +
                        entity.WatchedAttributes.GetString("sex", "male") +
                        "/" +
                        entity.WatchedAttributes.GetString("skincolor", "tan") +
                        ".png"
                        );
                    alphaTest = -1f;
                    break;

                case "eyecolor":
                    componentLoc = new AssetLocation(
                        componentPath +
                        "eyes/" +
                        entity.WatchedAttributes.GetString("eyecolor", "brown") +
                        ".png"
                        );
                    break;

                case "facialhair":
                    componentLoc = new AssetLocation(
                        componentPath +
                        "facialhairs/" +
                        entity.WatchedAttributes.GetString("facialhair", "full") +
                        "-" +
                        entity.WatchedAttributes.GetString("haircolor", "brown") +
                        ".png"
                        );
                    break;

                case "hairtype":
                    componentLoc = new AssetLocation(
                        componentPath +
                        "hairs/" +
                        entity.WatchedAttributes.GetString("hairtype", "m") +
                        "-" +
                        entity.WatchedAttributes.GetString("haircolor", "brown") +
                        ".png"
                        );
                    break;

                default:
                    componentLoc = new AssetLocation(
                        componentPath +
                        "hairs/" +
                        entity.WatchedAttributes.GetString("hairtype", "m") +
                        "-" +
                        entity.WatchedAttributes.GetString("haircolor", "brown") +
                        ".png"
                        );
                    break;
                }

                LoadedTexture componentTexture = new LoadedTexture(capi);
                BitmapRef     bitMap           = capi.Assets.Get(componentLoc).ToBitmap(capi);
                capi.Render.GetOrLoadTexture(componentLoc, bitMap, ref componentTexture);

                capi.Render.GlToggleBlend(false);

                capi.EntityTextureAtlas.RenderTextureIntoAtlas(
                    componentTexture,
                    0,
                    0,
                    128,
                    128,
                    skinTexPos.x1 * capi.EntityTextureAtlas.Size.Width,
                    skinTexPos.y1 * capi.EntityTextureAtlas.Size.Height, alphaTest
                    );

                capi.Render.GlToggleBlend(true, EnumBlendMode.Overlay);
            }

            // Standard

            int[] renderOrder = new int[]
            {
                (int)EnumCharacterDressType.LowerBody,
                (int)EnumCharacterDressType.Foot,
                (int)EnumCharacterDressType.UpperBody,
                (int)EnumCharacterDressType.UpperBodyOver,
                (int)EnumCharacterDressType.Waist,
                (int)EnumCharacterDressType.Shoulder,
                (int)EnumCharacterDressType.Emblem,
                (int)EnumCharacterDressType.Neck,
                (int)EnumCharacterDressType.Head,
                (int)EnumCharacterDressType.Hand,
                (int)EnumCharacterDressType.Arm,
                (int)EnumCharacterDressType.Face
            };

            if (gearInv == null && (eagent != null && eagent.GearInventory != null))
            {
                eagent.GearInventory.SlotModified += gearSlotModified;
                gearInv = eagent.GearInventory;
            }

            if (gearInv == null)
            {
                return;
            }

            for (int i = 0; i < renderOrder.Length; i++)
            {
                int slotid = renderOrder[i];

                if (gearInv[slotid] == null)
                {
                    continue;
                }
                ItemStack stack = gearInv[slotid].Itemstack;
                if (stack == null)
                {
                    continue;
                }

                int itemTextureSubId = stack.Item.FirstTexture.Baked.TextureSubId;

                TextureAtlasPosition itemTexPos = capi.ItemTextureAtlas.Positions[itemTextureSubId];

                LoadedTexture itemAtlas = new LoadedTexture(null)
                {
                    TextureId = itemTexPos.atlasTextureId,
                    Width     = capi.ItemTextureAtlas.Size.Width,
                    Height    = capi.ItemTextureAtlas.Size.Height
                };

                capi.EntityTextureAtlas.RenderTextureIntoAtlas(
                    itemAtlas,
                    itemTexPos.x1 * capi.ItemTextureAtlas.Size.Width,
                    itemTexPos.y1 * capi.ItemTextureAtlas.Size.Height,
                    (itemTexPos.x2 - itemTexPos.x1) * capi.ItemTextureAtlas.Size.Width,
                    (itemTexPos.y2 - itemTexPos.y1) * capi.ItemTextureAtlas.Size.Height,
                    skinTexPos.x1 * capi.EntityTextureAtlas.Size.Width,
                    skinTexPos.y1 * capi.EntityTextureAtlas.Size.Height
                    );
            }

            capi.Render.GlToggleBlend(true);
            capi.Render.BindTexture2d(skinTexPos.atlasTextureId);
            capi.Render.GlGenerateTex2DMipmaps();
        }
예제 #28
0
        public override void OnLoaded(ICoreAPI api)
        {
            paintableOnBlockMaterials = new EnumBlockMaterial[onmaterialsStrTmp.Length];
            for (int i = 0; i < onmaterialsStrTmp.Length; i++)
            {
                if (onmaterialsStrTmp[i] == null)
                {
                    continue;
                }
                try
                {
                    paintableOnBlockMaterials[i] = (EnumBlockMaterial)Enum.Parse(typeof(EnumBlockMaterial), onmaterialsStrTmp[i]);
                }
                catch (Exception)
                {
                    api.Logger.Warning("ArtPigment behavior for collectible {0}, paintable on material {1} is not a valid block material, will default to stone", collObj.Code, onmaterialsStrTmp[i]);
                    paintableOnBlockMaterials[i] = EnumBlockMaterial.Stone;
                }
            }
            onmaterialsStrTmp = null;

            var capi = api as ICoreClientAPI;

            foreach (var loc in decorCodesTmp)
            {
                if (loc.Path.Contains("*"))
                {
                    Block[] blocks = api.World.SearchBlocks(loc);
                    foreach (var block in blocks)
                    {
                        decorBlocks.Add(block);
                        //Console.WriteLine("\"/bir remapq " + block.Code.ToShortString() + " drawnart"+block.Variant["material"]+"-1-" + block.Variant["row"] +"-" + block.Variant["col"] + " force\",");
                    }
                    if (blocks.Length == 0)
                    {
                        api.Logger.Warning("ArtPigment behavior for collectible {0}, decor {1}, no such block using this wildcard found", collObj.Code, loc);
                    }
                }
                else
                {
                    Block block = api.World.GetBlock(loc);
                    if (block == null)
                    {
                        api.Logger.Warning("ArtPigment behavior for collectible {0}, decor {1} is not a loaded block", collObj.Code, loc);
                    }
                    else
                    {
                        decorBlocks.Add(block);
                    }
                }
            }

            if (api.Side == EnumAppSide.Client)
            {
                if (decorBlocks.Count > 0)
                {
                    BakedCompositeTexture tex = decorBlocks[0].Textures["up"].Baked;
                    texPos = capi.BlockTextureAtlas.Positions[tex.TextureSubId];
                }
                else
                {
                    texPos = capi.BlockTextureAtlas.UnknownTexturePosition;
                }
            }

            AssetLocation blockCode = collObj.Code;

            toolModes = new SkillItem[decorBlocks.Count];
            for (int i = 0; i < toolModes.Length; i++)
            {
                toolModes[i] = new SkillItem()
                {
                    Code          = blockCode.CopyWithPath("art" + i), // Unique code, it doesn't really matter what it is
                    Linebreak     = i % GlobalConstants.CaveArtColsPerRow == 0,
                    Name          = "",                                // No name - alternatively each icon could be given a name? But discussed in meeting on 6/6/21 and decided it is better for players to assign their own meanings to the icons
                    Data          = decorBlocks[i],
                    RenderHandler = (AssetLocation code, float dt, double atPosX, double atPosY) =>
                    {
                        float  wdt = (float)GuiElement.scaled(GuiElementPassiveItemSlot.unscaledSlotSize);
                        string id  = code.Path.Substring(3);
                        capi.Render.Render2DTexture(meshes[int.Parse(id)], texPos.atlasTextureId, (float)atPosX, (float)atPosY, wdt, wdt);
                    }
                };
            }


            if (capi != null)
            {
                meshes = new MeshRef[decorBlocks.Count];

                for (int i = 0; i < meshes.Length; i++)
                {
                    MeshData mesh = genMesh(i);
                    meshes[i] = capi.Render.UploadMesh(mesh);
                }
            }
        }
예제 #29
0
        public virtual void TesselateShape()
        {
            if (!loaded)
            {
                return;
            }

            shapeFresh = true;
            CompositeShape compositeShape = OverrideCompositeShape != null ? OverrideCompositeShape : entity.Properties.Client.Shape;

            Shape entityShape = OverrideEntityShape != null ? OverrideEntityShape : entity.Properties.Client.LoadedShapeForEntity;

            if (entityShape == null)
            {
                return;
            }

            OnTesselation?.Invoke(ref entityShape, compositeShape.Base.ToString());
            entity.OnTesselation(ref entityShape, compositeShape.Base.ToString());

            defaultTexSource = GetTextureSource();

            TyronThreadPool.QueueTask(() =>
            {
                MeshData meshdata;

                if (entity.Properties.Client.Shape.VoxelizeTexture)
                {
                    int altTexNumber = entity.WatchedAttributes.GetInt("textureIndex", 0);

                    TextureAtlasPosition pos      = defaultTexSource["all"];
                    CompositeTexture[] Alternates = entity.Properties.Client.FirstTexture.Alternates;

                    CompositeTexture tex = altTexNumber == 0 ? entity.Properties.Client.FirstTexture : Alternates[altTexNumber % Alternates.Length];
                    meshdata             = capi.Tesselator.VoxelizeTexture(tex, capi.EntityTextureAtlas.Size, pos);
                    for (int i = 0; i < meshdata.xyz.Length; i += 3)
                    {
                        meshdata.xyz[i]     -= 0.125f;
                        meshdata.xyz[i + 1] -= 0.5f;
                        meshdata.xyz[i + 2] += 0.125f / 2;
                    }
                }
                else
                {
                    try
                    {
                        TesselationMetaData meta = new TesselationMetaData()
                        {
                            quantityElements  = compositeShape.QuantityElements,
                            selectiveElements = compositeShape.SelectiveElements,
                            texSource         = this,
                            withJointIds      = true,
                            withDamageEffect  = true,
                            typeForLogging    = "entity"
                        };

                        capi.Tesselator.TesselateShape(meta, entityShape, out meshdata, new Vec3f(compositeShape.rotateX, compositeShape.rotateY, compositeShape.rotateZ));

                        meshdata.Translate(compositeShape.offsetX, compositeShape.offsetY, compositeShape.offsetZ);
                    }
                    catch (Exception e)
                    {
                        capi.World.Logger.Fatal("Failed tesselating entity {0} with id {1}. Entity will probably be invisible!. The teselator threw {2}", entity.Code, entity.EntityId, e);
                        return;
                    }
                }

                MeshData opaqueMesh = meshdata.Clone().Clear();
                MeshData oitMesh    = meshdata.Clone().Clear();
                opaqueMesh.AddMeshData(meshdata, EnumChunkRenderPass.Opaque);
                oitMesh.AddMeshData(meshdata, EnumChunkRenderPass.Transparent);

                capi.Event.EnqueueMainThreadTask(() =>
                {
                    if (meshRefOpaque != null)
                    {
                        meshRefOpaque.Dispose();
                        meshRefOpaque = null;
                    }
                    if (meshRefOit != null)
                    {
                        meshRefOit.Dispose();
                        meshRefOit = null;
                    }

                    if (capi.IsShuttingDown)
                    {
                        return;
                    }

                    if (opaqueMesh.VerticesCount > 0)
                    {
                        meshRefOpaque = capi.Render.UploadMesh(opaqueMesh);
                    }

                    if (oitMesh.VerticesCount > 0)
                    {
                        meshRefOit = capi.Render.UploadMesh(oitMesh);
                    }
                }, "uploadentitymesh");

                capi.TesselatorManager.ThreadDispose();
            });
        }
예제 #30
0
        protected void RenderHeldItem(float dt, bool isShadowPass, bool right)
        {
            IRenderAPI rapi  = capi.Render;
            ItemSlot   slot  = right ? eagent?.RightHandItemSlot : eagent?.LeftHandItemSlot;
            ItemStack  stack = slot?.Itemstack;

            AttachmentPointAndPose apap = entity.AnimManager.Animator.GetAttachmentPointPose(right ? "RightHand" : "LeftHand");

            if (apap == null || stack == null)
            {
                return;
            }

            AttachmentPoint        ap         = apap.AttachPoint;
            ItemRenderInfo         renderInfo = rapi.GetItemStackRenderInfo(slot, right ? EnumItemRenderTarget.HandTp : EnumItemRenderTarget.HandTpOff);
            IStandardShaderProgram prog       = null;

            if (renderInfo?.Transform == null)
            {
                return;                                // Happens with unknown items/blocks
            }
            ItemModelMat
            .Set(ModelMat)
            .Mul(apap.AnimModelMatrix)
            .Translate(renderInfo.Transform.Origin.X, renderInfo.Transform.Origin.Y, renderInfo.Transform.Origin.Z)
            .Scale(renderInfo.Transform.ScaleXYZ.X, renderInfo.Transform.ScaleXYZ.Y, renderInfo.Transform.ScaleXYZ.Z)
            .Translate(ap.PosX / 16f + renderInfo.Transform.Translation.X, ap.PosY / 16f + renderInfo.Transform.Translation.Y, ap.PosZ / 16f + renderInfo.Transform.Translation.Z)
            .RotateX((float)(ap.RotationX + renderInfo.Transform.Rotation.X) * GameMath.DEG2RAD)
            .RotateY((float)(ap.RotationY + renderInfo.Transform.Rotation.Y) * GameMath.DEG2RAD)
            .RotateZ((float)(ap.RotationZ + renderInfo.Transform.Rotation.Z) * GameMath.DEG2RAD)
            .Translate(-(renderInfo.Transform.Origin.X), -(renderInfo.Transform.Origin.Y), -(renderInfo.Transform.Origin.Z))
            ;


            if (isShadowPass)
            {
                rapi.CurrentActiveShader.BindTexture2D("tex2d", renderInfo.TextureId, 0);
                float[] mvpMat = Mat4f.Mul(ItemModelMat.Values, capi.Render.CurrentModelviewMatrix, ItemModelMat.Values);
                Mat4f.Mul(mvpMat, capi.Render.CurrentProjectionMatrix, mvpMat);

                capi.Render.CurrentActiveShader.UniformMatrix("mvpMatrix", mvpMat);
                capi.Render.CurrentActiveShader.Uniform("origin", new Vec3f());
            }
            else
            {
                prog = rapi.StandardShader;
                prog.Use();
                prog.DontWarpVertices = 0;
                prog.AddRenderFlags   = 0;
                prog.NormalShaded     = 1;
                prog.Tex2D            = renderInfo.TextureId;
                prog.RgbaTint         = ColorUtil.WhiteArgbVec;
                prog.AlphaTest        = renderInfo.AlphaTest;
                prog.DamageEffect     = renderInfo.DamageEffect;

                prog.OverlayOpacity = renderInfo.OverlayOpacity;
                if (renderInfo.OverlayTexture != null && renderInfo.OverlayOpacity > 0)
                {
                    prog.Tex2dOverlay2D     = renderInfo.OverlayTexture.TextureId;
                    prog.OverlayTextureSize = new Vec2f(renderInfo.OverlayTexture.Width, renderInfo.OverlayTexture.Height);
                    prog.BaseTextureSize    = new Vec2f(renderInfo.TextureSize.Width, renderInfo.TextureSize.Height);
                    TextureAtlasPosition texPos = rapi.GetTextureAtlasPosition(stack);
                    prog.BaseUvOrigin = new Vec2f(texPos.x1, texPos.y1);
                }


                int     temp      = (int)stack.Collectible.GetTemperature(capi.World, stack);
                float[] glowColor = ColorUtil.GetIncandescenceColorAsColor4f(temp);

                /*lightrgbs[0] += glowColor[0];
                *  lightrgbs[1] += glowColor[1];
                *  lightrgbs[2] += glowColor[2];*/

                var gi = GameMath.Clamp((temp - 500) / 3, 0, 255);
                prog.ExtraGlow     = gi;
                prog.RgbaAmbientIn = rapi.AmbientColor;
                prog.RgbaLightIn   = lightrgbs;
                prog.RgbaGlowIn    = new Vec4f(glowColor[0], glowColor[1], glowColor[2], gi / 255f);
                prog.RgbaFogIn     = rapi.FogColor;
                prog.FogMinIn      = rapi.FogMin;
                prog.FogDensityIn  = rapi.FogDensity;
                prog.NormalShaded  = renderInfo.NormalShaded ? 1 : 0;

                prog.ProjectionMatrix = rapi.CurrentProjectionMatrix;
                prog.ViewMatrix       = rapi.CameraMatrixOriginf;
                prog.ModelMatrix      = ItemModelMat.Values;
            }


            if (!renderInfo.CullFaces)
            {
                rapi.GlDisableCullFace();
            }

            rapi.RenderMesh(renderInfo.ModelRef);

            if (!renderInfo.CullFaces)
            {
                rapi.GlEnableCullFace();
            }

            if (!isShadowPass)
            {
                prog.DamageEffect = 0;
            }

            if (!isShadowPass)
            {
                prog.Stop();

                AdvancedParticleProperties[] ParticleProperties = stack.Collectible?.ParticleProperties;

                if (stack.Collectible != null && !capi.IsGamePaused)
                {
                    Vec4f        pos          = ItemModelMat.TransformVector(new Vec4f(stack.Collectible.TopMiddlePos.X, stack.Collectible.TopMiddlePos.Y, stack.Collectible.TopMiddlePos.Z, 1));
                    EntityPlayer entityPlayer = capi.World.Player.Entity;
                    accum += dt;
                    if (ParticleProperties != null && ParticleProperties.Length > 0 && accum > 0.025f)
                    {
                        accum = accum % 0.025f;

                        for (int i = 0; i < ParticleProperties.Length; i++)
                        {
                            AdvancedParticleProperties bps = ParticleProperties[i];
                            bps.basePos.X = pos.X + entity.Pos.X + -(entity.Pos.X - entityPlayer.CameraPos.X);
                            bps.basePos.Y = pos.Y + entity.Pos.Y + -(entity.Pos.Y - entityPlayer.CameraPos.Y);
                            bps.basePos.Z = pos.Z + entity.Pos.Z + -(entity.Pos.Z - entityPlayer.CameraPos.Z);

                            eagent.World.SpawnParticles(bps);
                        }
                    }
                }
            }
        }