*DANGER* make baked textures cross and make use of it * UNTESTED *

issue:  alll this seems to be sent back to childs, need to stop that
avinationmerge
UbitUmarov 2014-08-14 01:53:51 +01:00
parent 1bd13155e6
commit a1cc218f10
3 changed files with 172 additions and 102 deletions

View File

@ -183,7 +183,7 @@ namespace OpenSim.Framework
m_attachments = new Dictionary<int, List<AvatarAttachment>>(); m_attachments = new Dictionary<int, List<AvatarAttachment>>();
} }
public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true) public AvatarAppearance(AvatarAppearance appearance): this(appearance, true)
{ {
} }
@ -221,6 +221,8 @@ namespace OpenSim.Framework
{ {
byte[] tbytes = appearance.Texture.GetBytes(); byte[] tbytes = appearance.Texture.GetBytes();
m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length); m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
if (appearance.m_cacheitems != null)
m_cacheitems = (WearableCacheItem[]) appearance.m_cacheitems.Clone();
} }
m_visualparams = null; m_visualparams = null;
@ -723,6 +725,13 @@ namespace OpenSim.Framework
} }
data["textures"] = textures; data["textures"] = textures;
if (m_cacheitems != null)
{
OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems);
if (baked != null)
data["bakedcache"] = baked;
}
// Visual Parameters // Visual Parameters
OSDBinary visualparams = new OSDBinary(m_visualparams); OSDBinary visualparams = new OSDBinary(m_visualparams);
data["visualparams"] = visualparams; data["visualparams"] = visualparams;
@ -789,6 +798,12 @@ namespace OpenSim.Framework
m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures"); m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures");
} }
if ((data != null) && (data["bakedcache"] != null) && (data["bakedcache"]).Type == OSDType.Array)
{
OSDArray bakedOSDArray = (OSDArray)(data["bakedcache"]);
m_cacheitems = WearableCacheItem.BakedFromOSD(bakedOSDArray);
}
// Visual Parameters // Visual Parameters
SetDefaultParams(); SetDefaultParams();
if ((data != null) && (data["visualparams"] != null)) if ((data != null) && (data["visualparams"] != null))

View File

@ -50,7 +50,6 @@ namespace OpenSim.Framework
return retitems; return retitems;
} }
public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache) public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache)
{ {
List<WearableCacheItem> ret = new List<WearableCacheItem>(); List<WearableCacheItem> ret = new List<WearableCacheItem>();
@ -100,6 +99,7 @@ namespace OpenSim.Framework
return ret.ToArray(); return ret.ToArray();
} }
public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache) public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache)
{ {
OSDArray arr = new OSDArray(); OSDArray arr = new OSDArray();
@ -126,6 +126,64 @@ namespace OpenSim.Framework
} }
return arr; return arr;
} }
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 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 SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems) public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems)
{ {
for (int i = 0; i < pcacheItems.Length; i++) for (int i = 0; i < pcacheItems.Length; i++)

View File

@ -487,140 +487,137 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{ {
IAssetService cache = m_scene.AssetService; IAssetService cache = m_scene.AssetService;
IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
WearableCacheItem[] wearableCache = null;
WearableCacheItem[] bakedModuleCache = null; WearableCacheItem[] bakedModuleCache = null;
wearableCache = WearableCacheItem.GetDefaultCacheItem(); if (cache == null)
return false;
WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems;
// big debug
m_log.DebugFormat("[AVFACTORY]: ValidateBakedTextureCache start for {0} {1}", sp.Name, sp.UUID); m_log.DebugFormat("[AVFACTORY]: ValidateBakedTextureCache start for {0} {1}", sp.Name, sp.UUID);
// debug
for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++)
{ {
int j = AvatarAppearance.BAKE_INDICES[iter]; int j = AvatarAppearance.BAKE_INDICES[iter];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[iter]; Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[j];
if (face != null) if (wearableCache == null)
m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - " + face.TextureID); {
if (face != null)
m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t- " + face.TextureID);
else
m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t- No texture");
}
else else
m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - No texture"); {
if (face != null)
m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " ft- " + face.TextureID +
"}: cc-" +
wearableCache[j].CacheId + ", ct-" +
wearableCache[j].TextureID
);
else
m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - No texture" +
"}: cc-" +
wearableCache[j].CacheId + ", ct-" +
wearableCache[j].TextureID
);
}
} }
bool gotbacked = false; bool wearableCacheValid = false;
if (wearableCache == null)
// Cache wearable data for teleport.
// Only makes sense if there's a bake module and a cache module
if (bakedModule != null && cache != null)
{ {
m_log.Debug("[ValidateBakedCache] calling bakedModule"); wearableCache = WearableCacheItem.GetDefaultCacheItem();
try }
else
{
// we may have received a full cache
// check same coerence and store
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{ {
bakedModuleCache = bakedModule.Get(sp.UUID); int idx = AvatarAppearance.BAKE_INDICES[i];
} Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
catch (Exception) if (face != null && face.TextureID == wearableCache[idx].TextureID && wearableCache[idx].TextureAsset != null)
{
bakedModuleCache = null;
}
if (bakedModuleCache != null)
{
m_log.Debug("[ValidateBakedCache] got bakedModule cache " + bakedModuleCache.Length);
for (int i = 0; i < bakedModuleCache.Length; i++)
{ {
int j = (int)bakedModuleCache[i].TextureIndex; hits++;
wearableCache[idx].TextureAsset.Temporary = true;
if (bakedModuleCache[i].TextureAsset != null) wearableCache[idx].TextureAsset.Local = true;
{ cache.Store(wearableCache[idx].TextureAsset);
wearableCache[j].TextureID = bakedModuleCache[i].TextureID;
wearableCache[j].CacheId = bakedModuleCache[i].CacheId;
wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset;
bakedModuleCache[i].TextureAsset.Temporary = true;
bakedModuleCache[i].TextureAsset.Local = true;
cache.Store(bakedModuleCache[i].TextureAsset);
}
} }
gotbacked = true;
} }
wearableCacheValid = (hits >= AvatarAppearance.BAKE_INDICES.Length - 1); // skirt is optional
if (wearableCacheValid)
m_log.Debug("[ValidateBakedCache] have valid local cache");
} }
// Process the baked textures if (!wearableCacheValid)
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{ {
int idx = AvatarAppearance.BAKE_INDICES[i]; hits = 0;
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; bool gotbacked = false;
if (bakedModule != null)
{
m_log.Debug("[ValidateBakedCache] local cache invalid, calling bakedModule");
try
{
bakedModuleCache = bakedModule.Get(sp.UUID);
}
catch (Exception)
{
bakedModuleCache = null;
}
if (bakedModuleCache != null)
{
m_log.Debug("[ValidateBakedCache] got bakedModule cache " + bakedModuleCache.Length);
for (int i = 0; i < bakedModuleCache.Length; i++)
{
int j = (int)bakedModuleCache[i].TextureIndex;
if (bakedModuleCache[i].TextureAsset != null)
{
wearableCache[j].TextureID = bakedModuleCache[i].TextureID;
wearableCache[j].CacheId = bakedModuleCache[i].CacheId;
wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset;
bakedModuleCache[i].TextureAsset.Temporary = true;
bakedModuleCache[i].TextureAsset.Local = true;
cache.Store(bakedModuleCache[i].TextureAsset);
}
}
gotbacked = true;
}
}
// on tp viewer assumes servers did the cache work
// and tp propagation of baked textures is broken somewhere
// so make grid cache be mandatory
if (gotbacked) if (gotbacked)
{ {
// m_log.Debug("[ValidateBakedCache] bakedModule cache override"); // force the ones we got
if (sp.Appearance.Texture.FaceTextures[idx] == null) for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint)idx);
sp.Appearance.Texture.FaceTextures[idx].TextureID = wearableCache[idx].TextureID;
face = sp.Appearance.Texture.FaceTextures[idx];
// this should be removed
if (face.TextureID != UUID.Zero && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
hits++;
continue;
}
else
{
// No face, so lets check our cache
if (face == null || face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
{ {
sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint)idx); int idx = AvatarAppearance.BAKE_INDICES[i];
if (wearableCache[idx].TextureID != UUID.Zero) Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
{
sp.Appearance.Texture.FaceTextures[idx].TextureID = wearableCache[idx].TextureID;
face = sp.Appearance.Texture.FaceTextures[idx];
// let run to end of loop to check cache
}
else
{
sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
face = sp.Appearance.Texture.FaceTextures[idx];
// lets try not invalidating the cache entry
// wearableCache[idx].CacheId = UUID.Zero;
// wearableCache[idx].TextureAsset = null;
continue;
}
}
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) if (sp.Appearance.Texture.FaceTextures[idx] == null)
continue; sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint)idx);
sp.Appearance.Texture.FaceTextures[idx].TextureID = wearableCache[idx].TextureID;
face = sp.Appearance.Texture.FaceTextures[idx];
if (wearableCache[idx].TextureID != face.TextureID) // this should be removed
{ 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;
}
wearableCache[idx].TextureAsset = null;
if (cache != null)
{
wearableCache[idx].TextureAsset = m_scene.AssetService.GetCached(face.TextureID.ToString());
if (wearableCache[idx].TextureAsset == null)
{
wearableCache[idx].CacheId = UUID.Zero;
wearableCache[idx].TextureID = UUID.Zero;
}
else
hits++; hits++;
continue;
} }
} }
} }
sp.Appearance.WearableCacheItems = wearableCache; sp.Appearance.WearableCacheItems = wearableCache;
} }
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1} {2}", sp.Name, sp.UUID, hits);
// debug // debug
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1} {2}", sp.Name, sp.UUID, hits);
for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++)
{ {
int j = AvatarAppearance.BAKE_INDICES[iter]; int j = AvatarAppearance.BAKE_INDICES[iter];