コード例 #1
0
        public TattooSubBaker(Wearable tattoo)
        {
            if (tattoo.Type != WearableType.Tattoo)
            {
                throw new ArgumentException(nameof(tattoo));
            }

            m_TattooLowerColor = GetTattooLowerColor(tattoo);
            m_TattooUpperColor = GetTattooUpperColor(tattoo);
            tattoo.Textures.TryGetValue(AvatarTextureIndex.HeadTattoo, out m_HeadTattooId);
            tattoo.Textures.TryGetValue(AvatarTextureIndex.UpperTattoo, out m_UpperTattooId);
            tattoo.Textures.TryGetValue(AvatarTextureIndex.LowerTattoo, out m_LowerTattooId);
            if (m_HeadTattooId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_HeadTattooId = UUID.Zero;
            }
            if (m_UpperTattooId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_UpperTattooId = UUID.Zero;
            }
            if (m_LowerTattooId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_LowerTattooId = UUID.Zero;
            }
        }
コード例 #2
0
ファイル: SkinSubBaker.cs プロジェクト: ft-/silversim-testing
 public SkinSubBaker(Wearable skin)
 {
     if (skin.Type != WearableType.Skin)
     {
         throw new ArgumentException(nameof(skin));
     }
     m_SkinColor           = GetSkinColor(skin);
     m_RosyComplexionColor = GetRosyComplexionColor(skin);
     m_LipPinknessColor    = GetLipPinknessColor(skin);
     m_LipstickColor       = GetLipstickColor(skin);
     m_BlushColor          = GetBlushColor(skin);
     m_OutershadowColor    = GetOuterShadowColor(skin);
     m_InnershadowColor    = GetInnerShadowColor(skin);
     m_EyelinerColor       = GetEyelinerColor(skin);
     m_NailpolishColor     = GetNailPolishColor(skin);
     m_Innershadow         = skin.GetParamValueOrDefault(709, 0);
     m_Outershadow         = skin.GetParamValueOrDefault(707, 0);
     skin.Textures.TryGetValue(AvatarTextureIndex.HeadBodypaint, out m_HeadTextureId);
     skin.Textures.TryGetValue(AvatarTextureIndex.UpperBodypaint, out m_UpperTextureId);
     skin.Textures.TryGetValue(AvatarTextureIndex.LowerBodypaint, out m_LowerTextureId);
     if (m_HeadTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
     {
         m_HeadTextureId = UUID.Zero;
     }
     if (m_UpperTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
     {
         m_UpperTextureId = UUID.Zero;
     }
     if (m_LowerTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
     {
         m_LowerTextureId = UUID.Zero;
     }
 }
コード例 #3
0
        public AlphaMaskSubBaker(Wearable alpha)
        {
            if (alpha.Type != WearableType.Alpha)
            {
                throw new ArgumentException(nameof(alpha));
            }

            alpha.Textures.TryGetValue(AvatarTextureIndex.EyesAlpha, out m_EyesTextureId);
            alpha.Textures.TryGetValue(AvatarTextureIndex.HairAlpha, out m_HairTextureId);
            alpha.Textures.TryGetValue(AvatarTextureIndex.LowerAlpha, out m_LowerbodyTextureId);
            alpha.Textures.TryGetValue(AvatarTextureIndex.UpperAlpha, out m_UpperbodyTextureId);
            alpha.Textures.TryGetValue(AvatarTextureIndex.HeadAlpha, out m_HeadTextureId);
            if (m_EyesTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_EyesTextureId = UUID.Zero;
            }
            if (m_HairTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_HairTextureId = UUID.Zero;
            }
            if (m_LowerbodyTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_LowerbodyTextureId = UUID.Zero;
            }
            if (m_UpperbodyTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_UpperbodyTextureId = UUID.Zero;
            }
            if (m_HeadTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_HeadTextureId = UUID.Zero;
            }
        }
コード例 #4
0
        public EyeSubBaker(Wearable eyes)
        {
            if (eyes.Type != WearableType.Eyes)
            {
                throw new ArgumentException(nameof(eyes));
            }

            m_EyeColor = GetEyeColor(eyes);
            eyes.Textures.TryGetValue(AvatarTextureIndex.EyesIris, out m_EyeTextureId);
            if (m_EyeTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_EyeTextureId = UUID.Zero;
            }
        }
コード例 #5
0
ファイル: HairSubBaker.cs プロジェクト: ft-/silversim-testing
        public HairSubBaker(Wearable hair)
        {
            if (hair.Type != WearableType.Hair)
            {
                throw new ArgumentException(nameof(hair));
            }

            hair.Textures.TryGetValue(AvatarTextureIndex.Hair, out m_HairTextureId);
            if (m_HairTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_HairTextureId = UUID.Zero;
            }

            m_HairColor = (ColorAlpha)GetHairColor(hair);
        }
コード例 #6
0
 public ShoesSubBaker(Wearable shoes)
 {
     if (shoes.Type != WearableType.Shoes)
     {
         throw new ArgumentException(nameof(shoes));
     }
     m_Color          = GetShoeColor(shoes);
     m_ShoeHeight     = shoes.GetParamValueOrDefault(1052, 0.1);
     m_ShoeHeightBump = shoes.GetParamValueOrDefault(1055, 0.1);
     shoes.Textures.TryGetValue(AvatarTextureIndex.LowerShoes, out m_TextureId);
     if (m_TextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
     {
         m_TextureId = UUID.Zero;
     }
 }
コード例 #7
0
        public SocksSubBaker(Wearable socks)
        {
            if (socks.Type != WearableType.Socks)
            {
                throw new ArgumentException(nameof(socks));
            }

            m_Color           = GetSocksColor(socks);
            m_SocksLength     = socks.GetParamValueOrDefault(617, 0.35);
            m_SocksLengthBump = socks.GetMinParamOrDefault(0.35, 1050, 1051);
            socks.Textures.TryGetValue(AvatarTextureIndex.LowerSocks, out m_TextureId);
            if (m_TextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TextureId = UUID.Zero;
            }
        }
コード例 #8
0
 public UnderpantsSubBaker(Wearable underpants)
 {
     if (underpants.Type != WearableType.Underpants)
     {
         throw new ArgumentException(nameof(underpants));
     }
     m_Color           = GetUnderpantsColor(underpants);
     m_PantsLength     = underpants.GetParamValueOrDefault(1054, 0.3);
     m_PantsLengthBump = underpants.GetParamValueOrDefault(1055, 0.3);
     m_PantsWaist      = underpants.GetParamValueOrDefault(1056, 0.8);
     m_PantsWaistBump  = underpants.GetParamValueOrDefault(1057, 0.8);
     underpants.Textures.TryGetValue(AvatarTextureIndex.LowerUnderpants, out m_TextureId);
     if (m_TextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
     {
         m_TextureId = UUID.Zero;
     }
 }
コード例 #9
0
        public GlovesSubBaker(Wearable gloves)
        {
            if (gloves.Type != WearableType.Gloves)
            {
                throw new ArgumentException(nameof(gloves));
            }

            m_GlovesLength      = gloves.GetParamValueOrDefault(1058, 0.01);
            m_GlovesFingers     = gloves.GetParamValueOrDefault(1060, 1);
            m_GlovesFingersBump = gloves.GetParamValueOrDefault(1061, 1);
            m_GlovesLengthBump  = gloves.GetParamValueOrDefault(1059, 0.8);
            gloves.Textures.TryGetValue(AvatarTextureIndex.UpperGloves, out m_GlovesTextureId);
            if (m_GlovesTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_GlovesTextureId = UUID.Zero;
            }
            m_GlovesColor = GetGlovesColor(gloves);
        }
コード例 #10
0
 public SkirtSubBaker(Wearable skirt)
 {
     if (skirt.Type != WearableType.Skirt)
     {
         throw new ArgumentException(nameof(skirt));
     }
     m_Color       = GetSkirtColor(skirt);
     m_SkirtLength = skirt.GetParamValueOrDefault(858, 0.4);
     m_SlitFront   = skirt.GetParamValueOrDefault(859, 1);
     m_SlitBack    = skirt.GetParamValueOrDefault(860, 1);
     m_SlitLeft    = skirt.GetParamValueOrDefault(861, 1);
     m_SlitRight   = skirt.GetParamValueOrDefault(862, 1);
     skirt.Textures.TryGetValue(AvatarTextureIndex.Skirt, out m_TextureId);
     if (m_TextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
     {
         m_TextureId = UUID.Zero;
     }
 }
コード例 #11
0
        public PantsSubBaker(Wearable pants)
        {
            if (pants.Type != WearableType.Pants)
            {
                throw new ArgumentException(nameof(pants));
            }

            pants.Textures.TryGetValue(AvatarTextureIndex.LowerPants, out m_PantsTextureId);
            if (m_PantsTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_PantsTextureId = UUID.Zero;
            }
            m_PantsColor = GetPantColor(pants);
            m_Length     = pants.GetParamValueOrDefault(615, 0.8);
            m_Waist      = pants.GetParamValueOrDefault(614, 0.8);
            m_LengthBump = pants.GetMinParamOrDefault(0, 1018, 1036);
            m_WaistBump  = pants.GetMinParamOrDefault(0, 1017, 1035);
            m_Displace   = pants.GetParamValueOrDefault(516, 0);
        }
コード例 #12
0
        public bool TryGetBump(UUID textureID, BakeTarget bakeType, out byte[] bump)
        {
            if (textureID == UUID.Zero)
            {
                bump = null;
                return(false);
            }

            int targetDimension;
            Dictionary <UUID, byte[]> resizeCache;

            if (bakeType == BakeTarget.Eyes)
            {
                resizeCache     = m_BumpsResized128;
                targetDimension = 128;
            }
            else
            {
                resizeCache     = m_BumpsResized512;
                targetDimension = 512;
            }

            /* do not redo the hard work of rescaling images unnecessarily */
            if (resizeCache.TryGetValue(textureID, out bump))
            {
                return(true);
            }

            TryLoadTexture(textureID);

            if (m_Bumps.TryGetValue(textureID, out bump))
            {
                if (bump.Length != targetDimension * targetDimension)
                {
                    bump = ResizeBump(bump, targetDimension);
                    resizeCache.Add(textureID, bump);
                }
                return(true);
            }

            bump = null;
            return(false);
        }
コード例 #13
0
        public bool TryGetTexture(UUID textureID, BakeTarget bakeType, out Image img)
        {
            if (textureID == UUID.Zero)
            {
                img = null;
                return(false);
            }

            int targetDimension;
            Dictionary <UUID, Image> resizeCache;

            if (bakeType == BakeTarget.Eyes)
            {
                resizeCache     = m_TexturesResized128;
                targetDimension = 128;
            }
            else
            {
                resizeCache     = m_TexturesResized512;
                targetDimension = 512;
            }

            /* do not redo the hard work of rescaling images unnecessarily */
            if (resizeCache.TryGetValue(textureID, out img))
            {
                return(true);
            }

            TryLoadTexture(textureID);

            if (m_Textures.TryGetValue(textureID, out img))
            {
                if (img.Width != targetDimension || img.Height != targetDimension)
                {
                    img = new Bitmap(img, targetDimension, targetDimension);
                    resizeCache.Add(textureID, img);
                }
                return(true);
            }

            img = null;
            return(false);
        }
コード例 #14
0
        private void TryLoadTexture(UUID textureID)
        {
            AssetData data;

            if (m_ProcessedAssetIDs.Contains(textureID))
            {
                return;
            }
            m_ProcessedAssetIDs.Add(textureID);
            if (textureID == DefaultTransparentTextureId) /* we need to specifically recognize this texture */
            {
                var bmp = new Bitmap(512, 512, PixelFormat.Format32bppArgb);
                using (Graphics gfx = Graphics.FromImage(bmp))
                {
                    gfx.CompositingMode = CompositingMode.SourceOver;
                    using (var b = new SolidBrush(Color.FromArgb(0, 0, 0, 0)))
                    {
                        gfx.FillRectangle(b, 0, 0, 512, 512);
                    }
                }
                m_Textures.Add(textureID, bmp);
            }
            else if (m_AssetService.TryGetValue(textureID, out data))
            {
                byte[] bump = null;
                Image  img;
                try
                {
                    img = J2cDecoder.DecodeWithBump(data.Data, out bump);
                }
                catch
                {
                    img = new Bitmap(BaseBakes.UndefinedTexture);
                }
                m_Textures.Add(textureID, img);
                if (bump != null)
                {
                    m_Bumps.Add(textureID, bump);
                }
            }
        }
コード例 #15
0
 public UndershirtSubBaker(Wearable undershirt)
 {
     if (undershirt.Type != WearableType.Undershirt)
     {
         throw new ArgumentException(nameof(undershirt));
     }
     m_Color            = GetUndershirtColor(undershirt);
     m_SleeveLength     = undershirt.GetParamValueOrDefault(1042, 0.4);
     m_SleeveLengthBump = undershirt.GetParamValueOrDefault(1043, 0.4);
     m_BottomLength     = undershirt.GetParamValueOrDefault(1044, 0.8);
     m_BottomLengthBump = undershirt.GetParamValueOrDefault(1045, 0.8);
     m_CollarFront      = undershirt.GetParamValueOrDefault(1046, 0.8);
     m_CollarFrontBump  = undershirt.GetParamValueOrDefault(1047, 0.8);
     m_CollarBack       = undershirt.GetParamValueOrDefault(1048, 0.8);
     m_CollarBackBump   = undershirt.GetParamValueOrDefault(1049, 0.8);
     undershirt.Textures.TryGetValue(AvatarTextureIndex.UpperShirt, out m_TextureId);
     if (m_TextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
     {
         m_TextureId = UUID.Zero;
     }
 }
コード例 #16
0
        public JacketSubBaker(Wearable jacket)
        {
            if (jacket.Type != WearableType.Jacket)
            {
                throw new ArgumentException(nameof(jacket));
            }

            m_JacketUpperOpen    = jacket.GetParamValueOrDefault(622, 0.8);
            m_JacketLowerOpen    = jacket.GetParamValueOrDefault(623, 0.8);
            m_JacketUpperLength  = jacket.GetParamValueOrDefault(620, 0.8);
            m_JacketLowerLength  = jacket.GetParamValueOrDefault(621, 0.8);
            m_JacketSleeveLength = jacket.GetParamValueOrDefault(1020, 0);
            m_JacketCollarFront  = jacket.GetParamValueOrDefault(1022, 0);
            m_JacketCollarBack   = jacket.GetParamValueOrDefault(1024, 0);
            m_JacketUpperColor   = GetJacketUpperColor(jacket);
            m_JacketLowerColor   = GetJacketLowerColor(jacket);

            m_JacketSleeveLengthBump = jacket.GetParamValueOrDefault(1019, 0);
            m_JacketCollarFrontBump  = jacket.GetParamValueOrDefault(1021, 0);
            m_JacketCollarBackBump   = jacket.GetParamValueOrDefault(1023, 0);
            m_JacketLowerLengthBump  = jacket.GetMinParamOrDefault(0, 1033, 1025);
            m_JacketUpperLengthBump  = jacket.GetMinParamOrDefault(0, 1037, 1027);
            m_JacketUpperOpenBump    = jacket.GetMinParamOrDefault(0, 1026, 1038);
            m_JacketLowerOpenBump    = jacket.GetMinParamOrDefault(0, 1028, 1034);

            jacket.Textures.TryGetValue(AvatarTextureIndex.UpperJacket, out m_UpperTextureId);
            jacket.Textures.TryGetValue(AvatarTextureIndex.LowerJacket, out m_LowerTextureId);
            if (m_UpperTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_UpperTextureId = UUID.Zero;
            }
            if (m_LowerTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_LowerTextureId = UUID.Zero;
            }
        }
コード例 #17
0
        public ShirtSubBaker(Wearable shirt)
        {
            if (shirt.Type != WearableType.Shirt)
            {
                throw new ArgumentException(nameof(shirt));
            }

            m_ShirtColor = GetShirtColor(shirt);

            shirt.Textures.TryGetValue(AvatarTextureIndex.UpperShirt, out m_UpperTextureId);
            if (m_UpperTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_UpperTextureId = UUID.Zero;
            }
            m_SleeveLength          = shirt.GetParamValueOrDefault(600, 0.7);
            m_BottomLength          = shirt.GetParamValueOrDefault(601, 0.8);
            m_CollarFrontHeight     = shirt.GetParamValueOrDefault(602, 0.8);
            m_CollarBackHeight      = shirt.GetParamValueOrDefault(778, 0.8);
            m_BottomLengthBump      = shirt.GetMinParamOrDefault(0, 1014, 1030);
            m_SleeveLengthBump      = shirt.GetMinParamOrDefault(0, 1013, 1029);
            m_CollarFrontHeightBump = shirt.GetMinParamOrDefault(0, 1015, 1031);
            m_CollarBackHeightBump  = shirt.GetMinParamOrDefault(0, 1016, 1032);
            m_Displace = shirt.GetMinParamOrDefault(0, 628, 828);
        }
コード例 #18
0
        public UniversalSubBaker(Wearable universal)
        {
            if (universal.Type != WearableType.Universal)
            {
                throw new ArgumentException(nameof(universal));
            }
            m_TattooHairColor = GetTattooHairColor(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.HairTattoo, out m_TattooHairTextureId);
            if (m_TattooHairTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooHairTextureId = UUID.Zero;
            }

            m_TattooHeadColor = GetTattooHeadColor(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.HeadUniversalTattoo, out m_TattooHeadTextureId);
            if (m_TattooHeadTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooHeadTextureId = UUID.Zero;
            }

            m_TattooUpperColor = GetTattooUpperColor(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.UpperUniversalTattoo, out m_TattooUpperTextureId);
            if (m_TattooUpperTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooUpperTextureId = UUID.Zero;
            }

            m_TattooLowerColor = GetTattooLowerColor(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.LowerUniversalTattoo, out m_TattooLowerTextureId);
            if (m_TattooLowerTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooLowerTextureId = UUID.Zero;
            }

            m_TattooEyesColor = GetTattooEyesColor(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.EyesTattoo, out m_TattooEyesTextureId);
            if (m_TattooEyesTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooEyesTextureId = UUID.Zero;
            }

            m_TattooSkirtColor = GetTattooSkirtColor(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.SkirtTattoo, out m_TattooSkirtTextureId);
            if (m_TattooSkirtTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooSkirtTextureId = UUID.Zero;
            }

            m_TattooLeftArmColor = GetTattooLeftArmColor(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.LeftArmTattoo, out m_TattooLeftArmTextureId);
            if (m_TattooLeftArmTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooLeftArmTextureId = UUID.Zero;
            }

            m_TattooLeftLegColor = GetTattooLeftLegColor(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.LeftLegTattoo, out m_TattooLeftLegTextureId);
            if (m_TattooLeftLegTextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooLeftLegTextureId = UUID.Zero;
            }

            m_TattooAux1Color = GetTattooAux1Color(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.Aux1Tattoo, out m_TattooAux1TextureId);
            if (m_TattooAux1TextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooAux1TextureId = UUID.Zero;
            }

            m_TattooAux2Color = GetTattooAux2Color(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.Aux2Tattoo, out m_TattooAux2TextureId);
            if (m_TattooAux2TextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooAux2TextureId = UUID.Zero;
            }

            m_TattooAux3Color = GetTattooAux3Color(universal);
            universal.Textures.TryGetValue(AvatarTextureIndex.Aux3Tattoo, out m_TattooAux3TextureId);
            if (m_TattooAux3TextureId == AppearanceInfo.AvatarTextureData.DefaultAvatarTextureID)
            {
                m_TattooAux3TextureId = UUID.Zero;
            }
        }
コード例 #19
0
        public BakeOutput Process(BakeCache cache, AssetServiceInterface assetSource, Action <string> logOutput = null)
        {
            var output = new BakeOutput();

            if (cache.IsBaked)
            {
                throw new AlreadyBakedException();
            }

            m_AssetService = assetSource;

            output.VisualParams = VisualParamsMapper.CreateVisualParams(cache.Wearables, ref output.AvatarHeight);

            var Tgt          = new Targets();
            var SourceBakers = new Dictionary <WearableType, List <AbstractSubBaker> >();

            foreach (WearableType t in Enum.GetValues(typeof(WearableType)))
            {
                SourceBakers.Add(t, new List <AbstractSubBaker>());
            }

            foreach (AbstractSubBaker subbaker in cache.SubBakers)
            {
#if DEBUG
                logOutput?.Invoke(string.Format("Using subbaker {0}: baked={1}", subbaker.Type.ToString(), subbaker.IsBaked.ToString()));
#endif
                SourceBakers[subbaker.Type].Add(subbaker);
            }
#if DEBUG
            int subbakercount = 0;
            foreach (List <AbstractSubBaker> entrylist in SourceBakers.Values)
            {
                subbakercount += entrylist.Count;
            }
            logOutput?.Invoke(string.Format("Using {0} subbakers", subbakercount));
#endif

            try
            {
                foreach (BakeTarget idx in BakeIndices)
                {
                    int    dimensions = idx == BakeTarget.Eyes ? 128 : 512;
                    Bitmap bmp;
                    if (idx == BakeTarget.Skirt && SourceBakers[WearableType.Skirt].Count == 0)
                    {
                        continue;
                    }
                    bmp = new Bitmap(dimensions, dimensions, PixelFormat.Format32bppArgb);
                    Tgt.Images.Add(idx, bmp);
                    Graphics gfx = Graphics.FromImage(bmp);
                    if (idx == BakeTarget.Hair)
                    {
                        gfx.CompositingMode = CompositingMode.SourceCopy;
                        using (var b = new SolidBrush(Color.FromArgb(0, Color.White)))
                        {
                            gfx.FillRectangle(b, new Rectangle(0, 0, dimensions, dimensions));
                        }
                    }
                    gfx.CompositingMode = CompositingMode.SourceOver;
                    Tgt.Graphics.Add(idx, gfx);
                }

                logOutput?.Invoke("Processing R,G,B and bump parts");
                DrawSubBakers(Tgt, SourceBakers[WearableType.Skin], SkinIndices);

                DrawSubBakers(Tgt, SourceBakers[WearableType.Universal].OrderBy(item => item.Ordinal), UniversalIndices);

                DrawSubBakers(Tgt, SourceBakers[WearableType.Tattoo].OrderBy(item => item.Ordinal), SkinIndices);

                DrawSubBakers(Tgt, SourceBakers[WearableType.Hair], new BakeTarget[] { BakeTarget.Hair });
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Hair], new BakeTarget[] { BakeTarget.Hair });

                DrawSubBakers(Tgt, SourceBakers[WearableType.Eyes], new BakeTarget[] { BakeTarget.Eyes });
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Eyes], new BakeTarget[] { BakeTarget.Eyes });

                DrawSubBakers(Tgt, SourceBakers[WearableType.Underpants].OrderBy(item => item.Ordinal), new BakeTarget[] { BakeTarget.LowerBody });
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Underpants], new BakeTarget[] { BakeTarget.LowerBody });

                DrawSubBakers(Tgt, SourceBakers[WearableType.Undershirt].OrderBy(item => item.Ordinal), new BakeTarget[] { BakeTarget.UpperBody });
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Undershirt], new BakeTarget[] { BakeTarget.UpperBody });

                DrawSubBakers(Tgt, SourceBakers[WearableType.Socks].OrderBy(item => item.Ordinal), new BakeTarget[] { BakeTarget.LowerBody });
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Socks], new BakeTarget[] { BakeTarget.LowerBody });

                DrawSubBakers(Tgt, SourceBakers[WearableType.Shoes].OrderBy(item => item.Ordinal), new BakeTarget[] { BakeTarget.LowerBody });
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Shoes], new BakeTarget[] { BakeTarget.LowerBody });

                DrawSubBakers(Tgt, SourceBakers[WearableType.Pants].OrderBy(item => item.Ordinal), new BakeTarget[] { BakeTarget.LowerBody });
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Pants], new BakeTarget[] { BakeTarget.LowerBody });

                DrawSubBakers(Tgt, SourceBakers[WearableType.Shirt].OrderBy(item => item.Ordinal), new BakeTarget[] { BakeTarget.UpperBody });
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Shirt], new BakeTarget[] { BakeTarget.UpperBody });

                DrawSubBakers(Tgt, SourceBakers[WearableType.Jacket].OrderBy(item => item.Ordinal), ClothingIndices);
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Jacket], ClothingIndices);

                DrawSubBakers(Tgt, SourceBakers[WearableType.Gloves].OrderBy(item => item.Ordinal), new BakeTarget[] { BakeTarget.UpperBody });
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Gloves], new BakeTarget[] { BakeTarget.UpperBody });

                DrawSubBakers(Tgt, SourceBakers[WearableType.Skirt].OrderBy(item => item.Ordinal), new BakeTarget[] { BakeTarget.Skirt });
                DrawBumpMaps(Tgt, SourceBakers[WearableType.Skirt], new BakeTarget[] { BakeTarget.Skirt });

                /* for alpha masks we have to get rid of the Graphics */
                foreach (Graphics gfx in Tgt.Graphics.Values)
                {
                    gfx.Dispose();
                }
                Tgt.Graphics.Clear();

                logOutput?.Invoke("Processing alpha mask");
                /* clean out alpha channel. the ones we used before are not necessary anymore */
                foreach (KeyValuePair <BakeTarget, Bitmap> kvp in Tgt.Images)
                {
                    if (kvp.Key == BakeTarget.Hair)
                    {
                        /* skip hair */
                        continue;
                    }
                    int        byteSize = kvp.Value.Width * kvp.Value.Height * 4;
                    BitmapData lockBits = kvp.Value.LockBits(Tgt.Rectangles[kvp.Key], ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                    var        rawdata  = new byte[byteSize];
                    Marshal.Copy(lockBits.Scan0, rawdata, 0, byteSize);
                    for (int bytePos = byteSize; bytePos-- != 0; bytePos -= 3)
                    {
                        rawdata[bytePos] = 255;
                    }
                    Marshal.Copy(rawdata, 0, lockBits.Scan0, byteSize);
                    kvp.Value.UnlockBits(lockBits);
                }

                if (SourceBakers[WearableType.Alpha].Count != 0)
                {
                    var AlphaMaskBakes = new Dictionary <BakeTarget, byte[]>();

                    foreach (AbstractSubBaker baker in SourceBakers[WearableType.Alpha])
                    {
                        foreach (BakeTarget tgt in BakeIndices)
                        {
                            Image  srcimg;
                            Bitmap tgtimg;
                            byte[] dstAlphaMask;
                            byte[] srcAlphaMask;
                            int    dimensions = tgt == BakeTarget.Eyes ? 128 : 512;
                            int    imagebytes = dimensions * dimensions * 4;

                            srcimg = baker.BakeAlphaMaskOutput(this, tgt);
                            if (srcimg == null)
                            {
                                continue;
                            }

                            if (!AlphaMaskBakes.TryGetValue(tgt, out dstAlphaMask))
                            {
                                if (!Tgt.Images.TryGetValue(tgt, out tgtimg))
                                {
                                    continue;
                                }
                                dstAlphaMask        = GetRawData(tgtimg);
                                AlphaMaskBakes[tgt] = dstAlphaMask;
                            }

                            using (var srcbmp = new Bitmap(srcimg))
                            {
                                srcAlphaMask = GetRawData(srcbmp);
                            }

                            for (int idx = imagebytes; idx-- != 0; idx -= 3)
                            {
                                dstAlphaMask[idx] = Math.Min(dstAlphaMask[idx], srcAlphaMask[idx]);
                            }
                        }
                    }

                    foreach (KeyValuePair <BakeTarget, byte[]> kvp in AlphaMaskBakes)
                    {
                        UpdateRawData(Tgt.Images[kvp.Key], kvp.Value);
                    }
                }

                logOutput?.Invoke("Compressing bakes");
                byte[] finalbump;
                output.HairBake = new AssetData
                {
                    ID        = UUID.RandomFixedFirst(0xffffffff),
                    Type      = AssetType.Texture,
                    Temporary = true,
                    Data      = J2cEncoder.EncodeWithBump(Tgt.Images[BakeTarget.Hair], true, Tgt.Bumps[BakeTarget.Hair]),
                    Name      = "Bake Texture Hair"
                };
                output.HeadBake = new AssetData
                {
                    ID        = UUID.RandomFixedFirst(0xffffffff),
                    Type      = AssetType.Texture,
                    Temporary = true,
                    Data      = J2cEncoder.EncodeWithBump(Tgt.Images[BakeTarget.Head], true, Tgt.Bumps[BakeTarget.Head]),
                    Name      = "Bake Texture Head"
                };

                output.UpperBake = new AssetData
                {
                    ID        = UUID.RandomFixedFirst(0xffffffff),
                    Type      = AssetType.Texture,
                    Temporary = true,
                    Data      = J2cEncoder.EncodeWithBump(Tgt.Images[BakeTarget.UpperBody], true, Tgt.Bumps[BakeTarget.UpperBody]),
                    Name      = "Bake Texture Upperbody"
                };

                output.LowerBake = new AssetData
                {
                    ID        = UUID.RandomFixedFirst(0xffffffff),
                    Type      = AssetType.Texture,
                    Temporary = true,
                    Data      = J2cEncoder.EncodeWithBump(Tgt.Images[BakeTarget.LowerBody], true, Tgt.Bumps[BakeTarget.LowerBody]),
                    Name      = "Bake Texture Lowerbody"
                };

                output.EyeBake = new AssetData
                {
                    ID        = UUID.RandomFixedFirst(0xffffffff),
                    Type      = AssetType.Texture,
                    Temporary = true,
                    Data      = J2cEncoder.EncodeWithBump(Tgt.Images[BakeTarget.Eyes], true, Tgt.Bumps[BakeTarget.Eyes]),
                    Name      = "Bake Texture Eyes"
                };

                Bitmap finalSkirt;
                if (Tgt.Images.TryGetValue(BakeTarget.Skirt, out finalSkirt))
                {
                    output.SkirtBake = new AssetData
                    {
                        ID        = UUID.RandomFixedFirst(0xffffffff),
                        Type      = AssetType.Texture,
                        Temporary = true,
                        Data      = Tgt.Bumps.TryGetValue(BakeTarget.Skirt, out finalbump) ?
                                    J2cEncoder.EncodeWithBump(finalSkirt, true, finalbump) :
                                    J2cEncoder.Encode(finalSkirt, true),
                        Name = "Bake Texture Skirt"
                    };
                }

                Bitmap finalLeftArm;
                if (Tgt.Images.TryGetValue(BakeTarget.LeftArm, out finalLeftArm))
                {
                    output.LeftArmBake = new AssetData
                    {
                        ID        = UUID.RandomFixedFirst(0xffffffff),
                        Type      = AssetType.Texture,
                        Temporary = true,
                        Data      = J2cEncoder.Encode(finalLeftArm, true),
                        Name      = "Bake Texture LeftArm"
                    };
                }

                Bitmap finalLeftLeg;
                if (Tgt.Images.TryGetValue(BakeTarget.LeftLeg, out finalLeftLeg))
                {
                    output.LeftLegBake = new AssetData
                    {
                        ID        = UUID.RandomFixedFirst(0xffffffff),
                        Type      = AssetType.Texture,
                        Temporary = true,
                        Data      = J2cEncoder.Encode(finalLeftLeg, true),
                        Name      = "Bake Texture LeftLeg"
                    };
                }

                Bitmap finalAux1;
                if (Tgt.Images.TryGetValue(BakeTarget.Aux1, out finalAux1))
                {
                    output.Aux1Bake = new AssetData
                    {
                        ID        = UUID.RandomFixedFirst(0xffffffff),
                        Type      = AssetType.Texture,
                        Temporary = true,
                        Data      = J2cEncoder.Encode(finalAux1, true),
                        Name      = "Bake Texture Aux1"
                    };
                }

                Bitmap finalAux2;
                if (Tgt.Images.TryGetValue(BakeTarget.Aux1, out finalAux2))
                {
                    output.Aux2Bake = new AssetData
                    {
                        ID        = UUID.RandomFixedFirst(0xffffffff),
                        Type      = AssetType.Texture,
                        Temporary = true,
                        Data      = J2cEncoder.Encode(finalAux2, true),
                        Name      = "Bake Texture Aux2"
                    };
                }

                Bitmap finalAux3;
                if (Tgt.Images.TryGetValue(BakeTarget.Aux1, out finalAux3))
                {
                    output.Aux3Bake = new AssetData
                    {
                        ID        = UUID.RandomFixedFirst(0xffffffff),
                        Type      = AssetType.Texture,
                        Temporary = true,
                        Data      = J2cEncoder.Encode(finalAux3, true),
                        Name      = "Bake Texture Aux3"
                    };
                }
            }
            finally
            {
                foreach (Graphics gfx in Tgt.Graphics.Values)
                {
                    gfx.Dispose();
                }
                foreach (Bitmap bmp in Tgt.Images.Values)
                {
                    bmp.Dispose();
                }
            }

            return(output);
        }