// List<UUID> m_lastInventoryItemIDs = new List<UUID>(); public AvatarAppearance BakeAppearance(UUID agentID, int cof_version) { AvatarAppearance appearance = m_avatarService.GetAppearance(agentID); if (appearance == null) { MainConsole.Instance.Error("[ServerSide appearance]: Unable to retrieve avatar appearance for bake!"); return(new AvatarAppearance()); } List <BakeType> pendingBakes = new List <BakeType> (); InventoryFolderBase cof = m_inventoryService.GetFolderForType(agentID, InventoryType.Unknown, FolderType.CurrentOutfit); if (cof.Version < cof_version) { int i = 0; while (i < 10) { cof = m_inventoryService.GetFolderForType(agentID, InventoryType.Unknown, FolderType.CurrentOutfit); System.Threading.Thread.Sleep(100); if (cof.Version >= cof_version) { break; } i++; } } List <InventoryItemBase> items = m_inventoryService.GetFolderItems(agentID, cof.ID); foreach (InventoryItemBase itm in items) { MainConsole.Instance.Info("[ServerSide appearance]: Baking " + itm.Name); } for (int i = 0; i < Textures.Length; i++) { Textures [i] = new TextureData(); } WearableData alphaWearable = null; List <UUID> currentItemIDs = new List <UUID> (); foreach (InventoryItemBase itm in items) { if (itm.AssetType == (int)AssetType.Link) { UUID assetID = m_inventoryService.GetItemAssetID(agentID, itm.AssetID); if (appearance.Wearables.Any((w) => w.GetItem(assetID) != UUID.Zero)) { currentItemIDs.Add(assetID); //if (m_lastInventoryItemIDs.Contains(assetID)) // continue; WearableData wearable = new WearableData(); AssetBase asset = m_assetService.Get(assetID.ToString()); if (asset != null && asset.TypeAsset != AssetType.Object) { var assetData = new byte [asset.Data.Length]; asset.Data.CopyTo(assetData, 0); asset.Dispose(); wearable.Asset = new AssetClothing(assetID, assetData); if (wearable.Asset.Decode()) { wearable.AssetID = assetID; wearable.AssetType = wearable.Asset.AssetType; wearable.WearableType = wearable.Asset.WearableType; wearable.ItemID = itm.AssetID; if (wearable.WearableType == WearableType.Alpha) { alphaWearable = wearable; continue; } AppearanceManager.DecodeWearableParams(wearable, ref Textures); } } if (asset != null) // have asset but not an object { asset.Dispose(); } } } } /*foreach (UUID id in m_lastInventoryItemIDs) * { * if (!currentItemIDs.Contains(id)) * { * OpenMetaverse.AppearanceManager.WearableData wearable = new OpenMetaverse.AppearanceManager.WearableData(); * AssetBase asset = m_assetService.Get(id.ToString()); * if (asset != null && asset.TypeAsset != AssetType.Object) * { * wearable.Asset = new AssetClothing(id, asset.Data); * if (wearable.Asset.Decode()) * { * foreach (KeyValuePair<AvatarTextureIndex, UUID> entry in wearable.Asset.Textures) * { * int i = (int)entry.Key; * * Textures[i].Texture = null; * Textures[i].TextureID = UUID.Zero; * } * } * } * } * }*/ //m_lastInventoryItemIDs = currentItemIDs; for (int i = 0; i < Textures.Length; i++) { /*if (Textures[i].TextureID == UUID.Zero) * continue; * if (Textures[i].Texture != null) * continue;*/ AssetBase asset = m_assetService.Get(Textures [i].TextureID.ToString()); if (asset != null) { var assetData = new byte [asset.Data.Length]; asset.Data.CopyTo(assetData, 0); asset.Dispose(); Textures [i].Texture = new AssetTexture(Textures [i].TextureID, assetData); Textures [i].Texture.Decode(); } } for (int bakedIndex = 0; bakedIndex < AppearanceManager.BAKED_TEXTURE_COUNT; bakedIndex++) { AvatarTextureIndex textureIndex = AppearanceManager.BakeTypeToAgentTextureIndex((BakeType)bakedIndex); if (Textures [(int)textureIndex].TextureID == UUID.Zero) { // If this is the skirt layer and we're not wearing a skirt then skip it if (bakedIndex == (int)BakeType.Skirt && appearance.Wearables [(int)WearableType.Skirt].Count == 0) { continue; } pendingBakes.Add((BakeType)bakedIndex); } } int start = Environment.TickCount; List <UUID> newBakeIDs = new List <UUID> (); foreach (BakeType bakeType in pendingBakes) { UUID assetID = UUID.Zero; List <AvatarTextureIndex> textureIndices = AppearanceManager.BakeTypeToTextures(bakeType); Baker oven = new Baker(bakeType); for (int i = 0; i < textureIndices.Count; i++) { int textureIndex = (int)textureIndices [i]; TextureData texture = Textures [textureIndex]; texture.TextureIndex = (AvatarTextureIndex)textureIndex; if (alphaWearable != null) { if (alphaWearable.Asset.Textures.ContainsKey(texture.TextureIndex) && alphaWearable.Asset.Textures [texture.TextureIndex] != UUID.Parse("5748decc-f629-461c-9a36-a35a221fe21f")) { assetID = alphaWearable.Asset.Textures [texture.TextureIndex]; goto bake_complete; } } oven.AddTexture(texture); } oven.Bake(); byte [] assetData = oven.BakedTexture.AssetData; AssetBase newBakedAsset = new AssetBase(UUID.Random()); newBakedAsset.Data = assetData; newBakedAsset.TypeAsset = AssetType.Texture; newBakedAsset.Name = "ServerSideAppearance Texture"; newBakedAsset.Flags = AssetFlags.Deletable | AssetFlags.Collectable | AssetFlags.Rewritable | AssetFlags.Temporary; var faceTextureID = appearance.Texture.FaceTextures [(int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType)].TextureID; if (faceTextureID != UUID.Zero) { try { m_assetService.Delete(faceTextureID); } catch { MainConsole.Instance.ErrorFormat("[Serverside apperance]: Unable to delete asset {0} during bake", faceTextureID); } } assetID = m_assetService.Store(newBakedAsset); bake_complete: newBakeIDs.Add(assetID); MainConsole.Instance.WarnFormat("[ServerSide appearance]: Baked {0}", assetID); int place = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); appearance.Texture.FaceTextures [place].TextureID = assetID; } MainConsole.Instance.ErrorFormat("[ServerSide appearance]: Baking took {0} ms", (Environment.TickCount - start)); appearance.Serial = cof_version + 1; cof = m_inventoryService.GetFolderForType(agentID, InventoryType.Unknown, FolderType.CurrentOutfit); if (cof.Version > cof_version) { //it changed during the baking... kill it with fire! return(null); } m_avatarService.SetAppearance(agentID, appearance); return(appearance); }
private void pic_MouseClick(object sender, MouseEventArgs e) { PictureBox control = (PictureBox)sender; OpenFileDialog dialog = new OpenFileDialog(); // TODO: Setup a dialog.Filter for supported image types if (dialog.ShowDialog() == DialogResult.OK) { try { System.Drawing.Image image = System.Drawing.Image.FromFile(dialog.FileName); #region Dimensions Check if (control == picEyesBake) { // Eyes texture is 128x128 if (Width != 128 || Height != 128) { Bitmap resized = new Bitmap(128, 128, image.PixelFormat); Graphics graphics = Graphics.FromImage(resized); graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.DrawImage(image, 0, 0, 128, 128); image.Dispose(); image = resized; } } else { // Other textures are 512x512 if (Width != 128 || Height != 128) { Bitmap resized = new Bitmap(512, 512, image.PixelFormat); Graphics graphics = Graphics.FromImage(resized); graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphics.DrawImage(image, 0, 0, 512, 512); image.Dispose(); image = resized; } } #endregion Dimensions Check // Set the control image control.Image = image; } catch (Exception ex) { MessageBox.Show("Failed to load image: " + ex.Message); } } else { control.Image = null; } #region Baking Dictionary <int, float> paramValues = GetParamValues(); Dictionary <AvatarTextureIndex, AssetTexture> layers = new Dictionary <AvatarTextureIndex, AssetTexture>(); int textureCount = 0; if ((string)control.Tag == "Head") { if (picHair.Image != null) { layers.Add(AvatarTextureIndex.Hair, new AssetTexture(new ManagedImage((Bitmap)picHair.Image))); ++textureCount; } if (picHeadBodypaint.Image != null) { layers.Add(AvatarTextureIndex.HeadBodypaint, new AssetTexture(new ManagedImage((Bitmap)picHeadBodypaint.Image))); ++textureCount; } // Compute the head bake Baker baker = new Baker(BakeType.Head); foreach (KeyValuePair <AvatarTextureIndex, AssetTexture> kvp in layers) { AppearanceManager.TextureData tdata = new AppearanceManager.TextureData(); tdata.Texture = kvp.Value; baker.AddTexture(tdata); } baker.Bake(); if (baker.BakedTexture != null) { AssetTexture bakeAsset = baker.BakedTexture; // Baked textures use the alpha layer for other purposes, so we need to not use it bakeAsset.Image.Channels = ManagedImage.ImageChannels.Color; picHeadBake.Image = LoadTGAClass.LoadTGA(new MemoryStream(bakeAsset.Image.ExportTGA())); } else { MessageBox.Show("Failed to create the bake layer, unknown error"); } } else if ((string)control.Tag == "Upper") { if (picUpperBodypaint.Image != null) { layers.Add(AvatarTextureIndex.UpperBodypaint, new AssetTexture(new ManagedImage((Bitmap)picUpperBodypaint.Image))); ++textureCount; } if (picUpperGloves.Image != null) { layers.Add(AvatarTextureIndex.UpperGloves, new AssetTexture(new ManagedImage((Bitmap)picUpperGloves.Image))); ++textureCount; } if (picUpperUndershirt.Image != null) { layers.Add(AvatarTextureIndex.UpperUndershirt, new AssetTexture(new ManagedImage((Bitmap)picUpperUndershirt.Image))); ++textureCount; } if (picUpperShirt.Image != null) { layers.Add(AvatarTextureIndex.UpperShirt, new AssetTexture(new ManagedImage((Bitmap)picUpperShirt.Image))); ++textureCount; } if (picUpperJacket.Image != null) { layers.Add(AvatarTextureIndex.UpperJacket, new AssetTexture(new ManagedImage((Bitmap)picUpperJacket.Image))); ++textureCount; } // Compute the upper body bake Baker baker = new Baker(BakeType.UpperBody); foreach (KeyValuePair <AvatarTextureIndex, AssetTexture> kvp in layers) { AppearanceManager.TextureData tdata = new AppearanceManager.TextureData(); tdata.Texture = kvp.Value; baker.AddTexture(tdata); } baker.Bake(); if (baker.BakedTexture != null) { AssetTexture bakeAsset = baker.BakedTexture; // Baked textures use the alpha layer for other purposes, so we need to not use it bakeAsset.Image.Channels = ManagedImage.ImageChannels.Color; picUpperBodyBake.Image = LoadTGAClass.LoadTGA(new MemoryStream(bakeAsset.Image.ExportTGA())); } else { MessageBox.Show("Failed to create the bake layer, unknown error"); } } else if ((string)control.Tag == "Lower") { if (picLowerBodypaint.Image != null) { layers.Add(AvatarTextureIndex.LowerBodypaint, new AssetTexture(new ManagedImage((Bitmap)picLowerBodypaint.Image))); ++textureCount; } if (picLowerUnderpants.Image != null) { layers.Add(AvatarTextureIndex.LowerUnderpants, new AssetTexture(new ManagedImage((Bitmap)picLowerUnderpants.Image))); ++textureCount; } if (picLowerSocks.Image != null) { layers.Add(AvatarTextureIndex.LowerSocks, new AssetTexture(new ManagedImage((Bitmap)picLowerSocks.Image))); ++textureCount; } if (picLowerShoes.Image != null) { layers.Add(AvatarTextureIndex.LowerShoes, new AssetTexture(new ManagedImage((Bitmap)picLowerShoes.Image))); ++textureCount; } if (picLowerPants.Image != null) { layers.Add(AvatarTextureIndex.LowerPants, new AssetTexture(new ManagedImage((Bitmap)picLowerPants.Image))); ++textureCount; } // Compute the lower body bake Baker baker = new Baker(BakeType.LowerBody); foreach (KeyValuePair <AvatarTextureIndex, AssetTexture> kvp in layers) { AppearanceManager.TextureData tdata = new AppearanceManager.TextureData(); tdata.Texture = kvp.Value; baker.AddTexture(tdata); } baker.Bake(); if (baker.BakedTexture != null) { AssetTexture bakeAsset = baker.BakedTexture; // Baked textures use the alpha layer for other purposes, so we need to not use it bakeAsset.Image.Channels = ManagedImage.ImageChannels.Color; picLowerBodyBake.Image = LoadTGAClass.LoadTGA(new MemoryStream(bakeAsset.Image.ExportTGA())); } else { MessageBox.Show("Failed to create the bake layer, unknown error"); } } else if ((string)control.Tag == "Bake") { // Bake image has been set manually, no need to manually calculate a bake // FIXME: } #endregion Baking }