public static OSDArray BakedToOSD(WearableCacheItem[] pcacheItems) { if (pcacheItems.Length < AvatarAppearance.BAKE_INDICES[AvatarAppearance.BAKE_INDICES.Length - 1]) { return(null); } OSDArray arr = new OSDArray(); for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) { int idx = AvatarAppearance.BAKE_INDICES[i]; WearableCacheItem item = pcacheItems[idx]; OSDMap itemmap = new OSDMap(); itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex)); itemmap.Add("cacheid", OSD.FromUUID(item.CacheId)); itemmap.Add("textureid", OSD.FromUUID(item.TextureID)); /* * if (item.TextureAsset != null) * { * itemmap.Add("assetdata", OSD.FromBinary(item.TextureAsset.Data)); * itemmap.Add("assetcreator", OSD.FromString(item.TextureAsset.CreatorID)); * itemmap.Add("assetname", OSD.FromString(item.TextureAsset.Name)); * } */ arr.Add(itemmap); } return(arr); }
public static OSDArray BakedToOSD(WearableCacheItem[] pcacheItems, int start, int end) { OSDArray arr = new OSDArray(); if (start < 0) { start = 0; } if (end < 0 || end > AvatarAppearance.BAKE_INDICES.Length) { end = AvatarAppearance.BAKE_INDICES.Length; } if (start > end) { return(null); } for (int i = start; i < end; i++) { int idx = AvatarAppearance.BAKE_INDICES[i]; if (idx >= pcacheItems.Length) { continue; } WearableCacheItem item = pcacheItems[idx]; OSDMap itemmap = new OSDMap(); itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex)); itemmap.Add("cacheid", OSD.FromUUID(item.CacheId)); itemmap.Add("textureid", OSD.FromUUID(item.TextureID)); arr.Add(itemmap); } return(arr); }
public static WearableCacheItem[] BakedFromOSD(OSD pInput) { WearableCacheItem[] pcache = WearableCacheItem.GetDefaultCacheItem(); if (pInput.Type == OSDType.Array) { OSDArray itemarray = (OSDArray)pInput; foreach (OSDMap item in itemarray) { int idx = (int)item["textureindex"].AsUInteger(); if (idx < 0 || idx > pcache.Length) { continue; } pcache[idx].CacheId = item["cacheid"].AsUUID(); pcache[idx].TextureID = item["textureid"].AsUUID(); /* * if (item.ContainsKey("assetdata")) * { * AssetBase asset = new AssetBase(item["textureid"].AsUUID(), "BakedTexture", (sbyte)AssetType.Texture, UUID.Zero.ToString()); * asset.Temporary = true; * asset.Local = true; * asset.Data = item["assetdata"].AsBinary(); * pcache[idx].TextureAsset = asset; * } * else */ pcache[idx].TextureAsset = null; } } return(pcache); }
public static WearableCacheItem[] GetDefaultCacheItem() { int itemmax = 21; WearableCacheItem[] retitems = new WearableCacheItem[itemmax]; for (uint i=0;i<itemmax;i++) retitems[i] = new WearableCacheItem() {CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i + 1}; return retitems; }
public static WearableCacheItem[] GetDefaultCacheItem() { int itemmax = AvatarAppearance.TEXTURE_COUNT; WearableCacheItem[] retitems = new WearableCacheItem[itemmax]; for (uint i=0;i<itemmax;i++) retitems[i] = new WearableCacheItem() {CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i}; return retitems; }
public static WearableCacheItem[] GetDefaultCacheItem() { int itemmax = AvatarAppearance.TEXTURE_COUNT; WearableCacheItem[] retitems = new WearableCacheItem[itemmax]; for (uint i = 0; i < itemmax; i++) { retitems[i] = new WearableCacheItem() { CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i } } ; return(retitems); }
public static WearableCacheItem[] GetDefaultCacheItem() { int itemmax = 21; WearableCacheItem[] retitems = new WearableCacheItem[itemmax]; for (uint i = 0; i < itemmax; i++) { retitems[i] = new WearableCacheItem() { CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i + 1 } } ; return(retitems); }
public static WearableCacheItem[] BakedFromOSD(OSD pInput) { WearableCacheItem[] pcache = WearableCacheItem.GetDefaultCacheItem(); if (pInput.Type == OSDType.Array) { OSDArray itemarray = (OSDArray)pInput; foreach (OSDMap item in itemarray) { int idx = item["textureindex"].AsInteger(); if (idx < 0 || idx >= pcache.Length) { continue; } pcache[idx].CacheId = item["cacheid"].AsUUID(); pcache[idx].TextureID = item["textureid"].AsUUID(); pcache[idx].TextureAsset = null; } } return(pcache); }
public void Store(UUID agentId, WearableCacheItem[] data) { if (m_URL == String.Empty) return; MemoryStream reqStream; using (MemoryStream bakeStream = new MemoryStream()) using (XmlTextWriter bakeWriter = new XmlTextWriter(bakeStream, null)) { bakeWriter.WriteStartElement(String.Empty, "BakedAppearance", String.Empty); for (int i = 0; i < data.Length; i++) { if (data[i] != null) { bakeWriter.WriteStartElement(String.Empty, "BakedTexture", String.Empty); bakeWriter.WriteAttributeString(String.Empty, "TextureIndex", String.Empty, data[i].TextureIndex.ToString()); bakeWriter.WriteAttributeString(String.Empty, "CacheId", String.Empty, data[i].CacheId.ToString()); if (data[i].TextureAsset != null) m_serializer.Serialize(bakeWriter, data[i].TextureAsset); bakeWriter.WriteEndElement(); } } bakeWriter.WriteEndElement(); bakeWriter.Flush(); reqStream = new MemoryStream(bakeStream.ToArray()); } RestClient rc = new RestClient(m_URL); rc.AddResourcePath("bakes"); rc.AddResourcePath(agentId.ToString()); rc.RequestMethod = "POST"; Util.FireAndForget( delegate { rc.Request(reqStream, m_Auth); m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", data.Length, agentId); }, null, "XBakesModule.Store" ); }
public static WearableCacheItem SearchTextureTextureId(UUID pTextureId, WearableCacheItem[] pcacheItems) { for (int i = 0; i < pcacheItems.Length; i++) { if (pcacheItems[i].TextureID == pTextureId) return pcacheItems[i]; } return null; }
public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems) { for (int i = 0; i < pcacheItems.Length; i++) { if (pcacheItems[i].TextureIndex == pTextureIndex) return pcacheItems[i]; } return null; }
public static OSDArray BakedToOSD(WearableCacheItem[] pcacheItems) { if (pcacheItems.Length < AvatarAppearance.BAKE_INDICES[AvatarAppearance.BAKE_INDICES.Length - 1]) return null; OSDArray arr = new OSDArray(); for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) { int idx = AvatarAppearance.BAKE_INDICES[i]; WearableCacheItem item = pcacheItems[idx]; OSDMap itemmap = new OSDMap(); itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex)); itemmap.Add("cacheid", OSD.FromUUID(item.CacheId)); itemmap.Add("textureid", OSD.FromUUID(item.TextureID)); /* if (item.TextureAsset != null) { itemmap.Add("assetdata", OSD.FromBinary(item.TextureAsset.Data)); itemmap.Add("assetcreator", OSD.FromString(item.TextureAsset.CreatorID)); itemmap.Add("assetname", OSD.FromString(item.TextureAsset.Name)); } */ arr.Add(itemmap); } return arr; }
public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache) { OSDArray arr = new OSDArray(); foreach (WearableCacheItem item in pcacheItems) { OSDMap itemmap = new OSDMap(); itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex)); itemmap.Add("cacheid", OSD.FromUUID(item.CacheId)); itemmap.Add("textureid", OSD.FromUUID(item.TextureID)); if (dataCache != null) { if (dataCache.Check(item.TextureID.ToString())) { AssetBase assetItem = dataCache.Get(item.TextureID.ToString()); if (assetItem != null) { itemmap.Add("assetdata", OSD.FromBinary(assetItem.Data)); itemmap.Add("assetcreator", OSD.FromString(assetItem.CreatorID)); itemmap.Add("assetname", OSD.FromString(assetItem.Name)); } } } arr.Add(itemmap); } return arr; }
/// <summary> /// Set appearance data (texture asset IDs and slider settings) /// </summary> /// <param name="sp"></param> /// <param name="texture"></param> /// <param name="visualParam"></param> public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems) { // m_log.DebugFormat( // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", // sp.Name, textureEntry, visualParams); // TODO: This is probably not necessary any longer, just assume the // textureEntry set implies that the appearance transaction is complete bool changed = false; // Process the texture entry transactionally, this doesn't guarantee that Appearance is // going to be handled correctly but it does serialize the updates to the appearance lock (m_setAppearanceLock) { // Process the visual params, this may change height as well if (visualParams != null) { // string[] visualParamsStrings = new string[visualParams.Length]; // for (int i = 0; i < visualParams.Length; i++) // visualParamsStrings[i] = visualParams[i].ToString(); // m_log.DebugFormat( // "[AVFACTORY]: Setting visual params for {0} to {1}", // client.Name, string.Join(", ", visualParamsStrings)); /* float oldHeight = sp.Appearance.AvatarHeight; changed = sp.Appearance.SetVisualParams(visualParams); if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); */ // float oldoff = sp.Appearance.AvatarFeetOffset; // Vector3 oldbox = sp.Appearance.AvatarBoxSize; changed = sp.Appearance.SetVisualParams(visualParams); // float off = sp.Appearance.AvatarFeetOffset; // Vector3 box = sp.Appearance.AvatarBoxSize; // if(oldoff != off || oldbox != box) // ((ScenePresence)sp).SetSize(box,off); } // Process the baked texture array if (textureEntry != null) { m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); // WriteBakedTexturesReport(sp, m_log.DebugFormat); changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; // WriteBakedTexturesReport(sp, m_log.DebugFormat); // If bake textures are missing and this is not an NPC, request a rebake from client if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) RequestRebake(sp, true); // This appears to be set only in the final stage of the appearance // update transaction. In theory, we should be able to do an immediate // appearance send and save here. } // NPC should send to clients immediately and skip saving appearance if (((ScenePresence)sp).PresenceType == PresenceType.Npc) { SendAppearance((ScenePresence)sp); return; } // save only if there were changes, send no matter what (doesn't hurt to send twice) if (changed) QueueAppearanceSave(sp.ControllingClient.AgentId); QueueAppearanceSend(sp.ControllingClient.AgentId); } // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); }
private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) { int maxCacheitemsLoop = cacheItems.Length; if (maxCacheitemsLoop > AvatarWearable.MAX_WEARABLES) { maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES; m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES); } m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); if (cacheItems.Length > 0) { // m_log.Debug("[Cacheitems]: " + cacheItems.Length); // for (int iter = 0; iter < maxCacheitemsLoop; iter++) // { // m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + // cacheItems[iter].TextureID); // } ScenePresence p = null; if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) { WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; if (existingitems == null) { if (m_BakedTextureModule != null) { WearableCacheItem[] savedcache = null; try { if (p.Appearance.WearableCacheItemsDirty) { savedcache = m_BakedTextureModule.Get(p.UUID); p.Appearance.WearableCacheItems = savedcache; p.Appearance.WearableCacheItemsDirty = false; } } /* * The following Catch types DO NOT WORK with m_BakedTextureModule.Get * it jumps to the General Packet Exception Handler if you don't catch Exception! * catch (System.Net.Sockets.SocketException) { cacheItems = null; } catch (WebException) { cacheItems = null; } catch (InvalidOperationException) { cacheItems = null; } */ catch (Exception) { // The service logs a sufficient error message. } if (savedcache != null) existingitems = savedcache; } } // Existing items null means it's a fully new appearance if (existingitems == null) { for (int i = 0; i < maxCacheitemsLoop; i++) { if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) { Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; if (face == null) { textureEntry.CreateFace(cacheItems[i].TextureIndex); textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; continue; } cacheItems[i].TextureID =face.TextureID; if (m_scene.AssetService != null) cacheItems[i].TextureAsset = m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); } else { m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); } } } else { // for each uploaded baked texture for (int i = 0; i < maxCacheitemsLoop; i++) { if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) { Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; if (face == null) { textureEntry.CreateFace(cacheItems[i].TextureIndex); textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; continue; } cacheItems[i].TextureID = face.TextureID; } else { m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); } } for (int i = 0; i < maxCacheitemsLoop; i++) { if (cacheItems[i].TextureAsset == null) { cacheItems[i].TextureAsset = m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); } } } p.Appearance.WearableCacheItems = cacheItems; if (m_BakedTextureModule != null) { m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems); p.Appearance.WearableCacheItemsDirty = true; } } } }
// called on textures update public bool UpdateBakedTextureCache(IScenePresence sp, WearableCacheItem[] cacheItems) { if(cacheItems == null) return false; // npcs dont have baked cache if (((ScenePresence)sp).isNPC) return true; // uploaded baked textures will be in assets local cache IAssetService cache = m_scene.AssetService; IBakedTextureModule m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); int validDirtyBakes = 0; int hits = 0; // our main cacheIDs mapper is p.Appearance.WearableCacheItems WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems; if (wearableCache == null) { wearableCache = WearableCacheItem.GetDefaultCacheItem(); } List<UUID> missing = new List<UUID>(); bool haveSkirt = (wearableCache[19].TextureAsset != null); bool haveNewSkirt = false; // Process received baked textures for (int i = 0; i < cacheItems.Length; i++) { int idx = (int)cacheItems[i].TextureIndex; Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; // No face if (face == null) { // for some reason viewer is cleaning this if(idx != 19) // skirt is optional { sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx); sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; } wearableCache[idx].CacheId = UUID.Zero; wearableCache[idx].TextureID = UUID.Zero; wearableCache[idx].TextureAsset = null; continue; } else { if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) { wearableCache[idx].CacheId = UUID.Zero; wearableCache[idx].TextureID = UUID.Zero; wearableCache[idx].TextureAsset = null; continue; } if(idx == 19) haveNewSkirt = true; /* if (face.TextureID == wearableCache[idx].TextureID && m_BakedTextureModule != null) { if (wearableCache[idx].CacheId != cacheItems[i].CacheId) { wearableCache[idx].CacheId = cacheItems[i].CacheId; validDirtyBakes++; //assuming this can only happen if asset is in cache } hits++; continue; } */ wearableCache[idx].TextureAsset = null; if (cache != null) wearableCache[idx].TextureAsset = cache.GetCached(face.TextureID.ToString()); if (wearableCache[idx].TextureAsset != null) { if ( wearableCache[idx].TextureID != face.TextureID || wearableCache[idx].CacheId != cacheItems[i].CacheId) validDirtyBakes++; wearableCache[idx].TextureID = face.TextureID; wearableCache[idx].CacheId = cacheItems[i].CacheId; hits++; } else { wearableCache[idx].CacheId = UUID.Zero; wearableCache[idx].TextureID = UUID.Zero; wearableCache[idx].TextureAsset = null; missing.Add(face.TextureID); continue; } } } // handle optional skirt case if(!haveNewSkirt && haveSkirt) { wearableCache[19].CacheId = UUID.Zero; wearableCache[19].TextureID = UUID.Zero; wearableCache[19].TextureAsset = null; validDirtyBakes++; } sp.Appearance.WearableCacheItems = wearableCache; if (missing.Count > 0) { foreach (UUID id in missing) sp.ControllingClient.SendRebakeAvatarTextures(id); } if (validDirtyBakes > 0 && hits == cacheItems.Length) { // if we got a full set of baked textures save all in BakedTextureModule if (m_BakedTextureModule != null) { m_log.Debug("[UpdateBakedCache] start async uploading to bakedModule cache"); m_BakedTextureModule.Store(sp.UUID, wearableCache); } } // debug m_log.Debug("[UpdateBakedCache] cache hits: " + hits.ToString() + " changed entries: " + validDirtyBakes.ToString() + " rebakes " + missing.Count); /* for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) { int j = AvatarAppearance.BAKE_INDICES[iter]; m_log.Debug("[UpdateBCache] {" + iter + "/" + sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" + sp.Appearance.WearableCacheItems[j].CacheId + ", t-" + sp.Appearance.WearableCacheItems[j].TextureID); } */ return (hits == cacheItems.Length); }
/// <summary> /// Set appearance data (texture asset IDs and slider settings) /// </summary> /// <param name="sp"></param> /// <param name="texture"></param> /// <param name="visualParam"></param> public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems) { // m_log.DebugFormat( // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", // sp.Name, textureEntry, visualParams); // TODO: This is probably not necessary any longer, just assume the // textureEntry set implies that the appearance transaction is complete bool changed = false; // Process the texture entry transactionally, this doesn't guarantee that Appearance is // going to be handled correctly but it does serialize the updates to the appearance lock (m_setAppearanceLock) { // Process the visual params, this may change height as well if (visualParams != null) { changed = sp.Appearance.SetVisualParams(visualParams); } // Process the baked texture array if (textureEntry != null) { m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); // WriteBakedTexturesReport(sp, m_log.DebugFormat); changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; // WriteBakedTexturesReport(sp, m_log.DebugFormat); UpdateBakedTextureCache(sp, cacheItems); // This appears to be set only in the final stage of the appearance // update transaction. In theory, we should be able to do an immediate // appearance send and save here. } // NPC should send to clients immediately and skip saving appearance if (((ScenePresence)sp).PresenceType == PresenceType.Npc) { SendAppearance((ScenePresence)sp); return; } // save only if there were changes, send no matter what (doesn't hurt to send twice) if (changed) QueueAppearanceSave(sp.ControllingClient.AgentId); QueueAppearanceSend(sp.ControllingClient.AgentId); } // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); }
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) { float oldoff = sp.Appearance.AvatarFeetOffset; Vector3 oldbox = sp.Appearance.AvatarBoxSize; SetAppearance(sp, textureEntry, visualParams, cacheItems); sp.Appearance.SetSize(avSize); float off = sp.Appearance.AvatarFeetOffset; Vector3 box = sp.Appearance.AvatarBoxSize; if (oldoff != off || oldbox != box) ((ScenePresence)sp).SetSize(box, off); }
/// </summary> /// <param name="sp"></param> /// <param name="texture"></param> /// <param name="visualParam"></param> public void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems) { SetAppearance(sp, appearance.Texture, appearance.VisualParams, cacheItems); }
/// <summary> /// Set appearance data (texture asset IDs and slider settings) received from a client /// </summary> /// <param name="client"></param> /// <param name="texture"></param> /// <param name="visualParam"></param> private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) { // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp != null) SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems); else m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); }