aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs17
-rw-r--r--OpenSim/Framework/WearableCacheItem.cs60
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs187
3 files changed, 167 insertions, 97 deletions
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index c384336..25ae0ec 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -183,7 +183,7 @@ namespace OpenSim.Framework
183 m_attachments = new Dictionary<int, List<AvatarAttachment>>(); 183 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
184 } 184 }
185 185
186 public AvatarAppearance(AvatarAppearance appearance) : this(appearance, true) 186 public AvatarAppearance(AvatarAppearance appearance): this(appearance, true)
187 { 187 {
188 } 188 }
189 189
@@ -221,6 +221,8 @@ namespace OpenSim.Framework
221 { 221 {
222 byte[] tbytes = appearance.Texture.GetBytes(); 222 byte[] tbytes = appearance.Texture.GetBytes();
223 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length); 223 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
224 if (appearance.m_cacheitems != null)
225 m_cacheitems = (WearableCacheItem[]) appearance.m_cacheitems.Clone();
224 } 226 }
225 227
226 m_visualparams = null; 228 m_visualparams = null;
@@ -723,6 +725,13 @@ namespace OpenSim.Framework
723 } 725 }
724 data["textures"] = textures; 726 data["textures"] = textures;
725 727
728 if (m_cacheitems != null)
729 {
730 OSDArray baked = WearableCacheItem.BakedToOSD(m_cacheitems);
731 if (baked != null)
732 data["bakedcache"] = baked;
733 }
734
726 // Visual Parameters 735 // Visual Parameters
727 OSDBinary visualparams = new OSDBinary(m_visualparams); 736 OSDBinary visualparams = new OSDBinary(m_visualparams);
728 data["visualparams"] = visualparams; 737 data["visualparams"] = visualparams;
@@ -789,6 +798,12 @@ namespace OpenSim.Framework
789 m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures"); 798 m_log.Warn("[AVATAR APPEARANCE]: failed to unpack textures");
790 } 799 }
791 800
801 if ((data != null) && (data["bakedcache"] != null) && (data["bakedcache"]).Type == OSDType.Array)
802 {
803 OSDArray bakedOSDArray = (OSDArray)(data["bakedcache"]);
804 m_cacheitems = WearableCacheItem.BakedFromOSD(bakedOSDArray);
805 }
806
792 // Visual Parameters 807 // Visual Parameters
793 SetDefaultParams(); 808 SetDefaultParams();
794 if ((data != null) && (data["visualparams"] != null)) 809 if ((data != null) && (data["visualparams"] != null))
diff --git a/OpenSim/Framework/WearableCacheItem.cs b/OpenSim/Framework/WearableCacheItem.cs
index a890d3b..f49697d 100644
--- a/OpenSim/Framework/WearableCacheItem.cs
+++ b/OpenSim/Framework/WearableCacheItem.cs
@@ -49,7 +49,6 @@ namespace OpenSim.Framework
49 retitems[i] = new WearableCacheItem() {CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i}; 49 retitems[i] = new WearableCacheItem() {CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i};
50 return retitems; 50 return retitems;
51 } 51 }
52
53 52
54 public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache) 53 public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache)
55 { 54 {
@@ -100,6 +99,7 @@ namespace OpenSim.Framework
100 return ret.ToArray(); 99 return ret.ToArray();
101 100
102 } 101 }
102
103 public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache) 103 public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache)
104 { 104 {
105 OSDArray arr = new OSDArray(); 105 OSDArray arr = new OSDArray();
@@ -126,6 +126,64 @@ namespace OpenSim.Framework
126 } 126 }
127 return arr; 127 return arr;
128 } 128 }
129
130 public static OSDArray BakedToOSD(WearableCacheItem[] pcacheItems)
131 {
132 if (pcacheItems.Length < AvatarAppearance.BAKE_INDICES[AvatarAppearance.BAKE_INDICES.Length - 1])
133 return null;
134
135 OSDArray arr = new OSDArray();
136
137 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
138 {
139 int idx = AvatarAppearance.BAKE_INDICES[i];
140
141 WearableCacheItem item = pcacheItems[idx];
142
143 OSDMap itemmap = new OSDMap();
144 itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex));
145 itemmap.Add("cacheid", OSD.FromUUID(item.CacheId));
146 itemmap.Add("textureid", OSD.FromUUID(item.TextureID));
147 if (item.TextureAsset != null)
148 {
149 itemmap.Add("assetdata", OSD.FromBinary(item.TextureAsset.Data));
150 itemmap.Add("assetcreator", OSD.FromString(item.TextureAsset.CreatorID));
151 itemmap.Add("assetname", OSD.FromString(item.TextureAsset.Name));
152 }
153 arr.Add(itemmap);
154 }
155 return arr;
156 }
157
158 public static WearableCacheItem[] BakedFromOSD(OSD pInput)
159 {
160 WearableCacheItem[] pcache = WearableCacheItem.GetDefaultCacheItem();
161
162 if (pInput.Type == OSDType.Array)
163 {
164 OSDArray itemarray = (OSDArray)pInput;
165 foreach (OSDMap item in itemarray)
166 {
167 int idx = (int)item["textureindex"].AsUInteger();
168 if (idx < 0 || idx > pcache.Length)
169 continue;
170 pcache[idx].CacheId = item["cacheid"].AsUUID();
171 pcache[idx].TextureID = item["textureid"].AsUUID();
172 if (item.ContainsKey("assetdata"))
173 {
174 AssetBase asset = new AssetBase(item["textureid"].AsUUID(), "BakedTexture", (sbyte)AssetType.Texture, UUID.Zero.ToString());
175 asset.Temporary = true;
176 asset.Local = true;
177 asset.Data = item["assetdata"].AsBinary();
178 pcache[idx].TextureAsset = asset;
179 }
180 else
181 pcache[idx].TextureAsset = null;
182 }
183 }
184 return pcache;
185 }
186
129 public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems) 187 public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems)
130 { 188 {
131 for (int i = 0; i < pcacheItems.Length; i++) 189 for (int i = 0; i < pcacheItems.Length; i++)
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index e34bac9..186d82b 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -487,140 +487,137 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
487 { 487 {
488 IAssetService cache = m_scene.AssetService; 488 IAssetService cache = m_scene.AssetService;
489 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); 489 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
490 WearableCacheItem[] wearableCache = null;
491 WearableCacheItem[] bakedModuleCache = null; 490 WearableCacheItem[] bakedModuleCache = null;
492 491
493 wearableCache = WearableCacheItem.GetDefaultCacheItem(); 492 if (cache == null)
493 return false;
494 494
495 WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems;
495 496
497 // big debug
496 m_log.DebugFormat("[AVFACTORY]: ValidateBakedTextureCache start for {0} {1}", sp.Name, sp.UUID); 498 m_log.DebugFormat("[AVFACTORY]: ValidateBakedTextureCache start for {0} {1}", sp.Name, sp.UUID);
497 // debug
498 for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) 499 for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++)
499 { 500 {
500 int j = AvatarAppearance.BAKE_INDICES[iter]; 501 int j = AvatarAppearance.BAKE_INDICES[iter];
501 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[iter]; 502 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[j];
502 if (face != null) 503 if (wearableCache == null)
503 m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - " + face.TextureID);
504 else
505 m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - No texture");
506 }
507
508 bool gotbacked = false;
509
510 // Cache wearable data for teleport.
511 // Only makes sense if there's a bake module and a cache module
512 if (bakedModule != null && cache != null)
513 {
514 m_log.Debug("[ValidateBakedCache] calling bakedModule");
515 try
516 { 504 {
517 bakedModuleCache = bakedModule.Get(sp.UUID); 505 if (face != null)
506 m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t- " + face.TextureID);
507 else
508 m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t- No texture");
518 } 509 }
519 catch (Exception) 510 else
520 { 511 {
521 bakedModuleCache = null; 512 if (face != null)
513 m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " ft- " + face.TextureID +
514 "}: cc-" +
515 wearableCache[j].CacheId + ", ct-" +
516 wearableCache[j].TextureID
517 );
518 else
519 m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - No texture" +
520 "}: cc-" +
521 wearableCache[j].CacheId + ", ct-" +
522 wearableCache[j].TextureID
523 );
522 } 524 }
525 }
523 526
524 if (bakedModuleCache != null) 527 bool wearableCacheValid = false;
528 if (wearableCache == null)
529 {
530 wearableCache = WearableCacheItem.GetDefaultCacheItem();
531 }
532 else
533 {
534 // we may have received a full cache
535 // check same coerence and store
536 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
525 { 537 {
526 m_log.Debug("[ValidateBakedCache] got bakedModule cache " + bakedModuleCache.Length); 538 int idx = AvatarAppearance.BAKE_INDICES[i];
527 539 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
528 for (int i = 0; i < bakedModuleCache.Length; i++) 540 if (face != null && face.TextureID == wearableCache[idx].TextureID && wearableCache[idx].TextureAsset != null)
529 { 541 {
530 int j = (int)bakedModuleCache[i].TextureIndex; 542 hits++;
531 543 wearableCache[idx].TextureAsset.Temporary = true;
532 if (bakedModuleCache[i].TextureAsset != null) 544 wearableCache[idx].TextureAsset.Local = true;
533 { 545 cache.Store(wearableCache[idx].TextureAsset);
534 wearableCache[j].TextureID = bakedModuleCache[i].TextureID;
535 wearableCache[j].CacheId = bakedModuleCache[i].CacheId;
536 wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset;
537 bakedModuleCache[i].TextureAsset.Temporary = true;
538 bakedModuleCache[i].TextureAsset.Local = true;
539 cache.Store(bakedModuleCache[i].TextureAsset);
540
541 }
542 } 546 }
543 gotbacked = true;
544 } 547 }
548
549 wearableCacheValid = (hits >= AvatarAppearance.BAKE_INDICES.Length - 1); // skirt is optional
550 if (wearableCacheValid)
551 m_log.Debug("[ValidateBakedCache] have valid local cache");
545 } 552 }
546 553
547 // Process the baked textures 554 if (!wearableCacheValid)
548 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
549 { 555 {
550 int idx = AvatarAppearance.BAKE_INDICES[i]; 556 hits = 0;
551 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 557 bool gotbacked = false;
552 558
553 // on tp viewer assumes servers did the cache work 559 if (bakedModule != null)
554 // and tp propagation of baked textures is broken somewhere
555 // so make grid cache be mandatory
556 if (gotbacked)
557 { 560 {
558 // m_log.Debug("[ValidateBakedCache] bakedModule cache override"); 561 m_log.Debug("[ValidateBakedCache] local cache invalid, calling bakedModule");
559 if (sp.Appearance.Texture.FaceTextures[idx] == null) 562 try
560 sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint)idx);
561 sp.Appearance.Texture.FaceTextures[idx].TextureID = wearableCache[idx].TextureID;
562 face = sp.Appearance.Texture.FaceTextures[idx];
563
564 // this should be removed
565 if (face.TextureID != UUID.Zero && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
566 hits++;
567
568 continue;
569 }
570 else
571 {
572 // No face, so lets check our cache
573 if (face == null || face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
574 { 563 {
575 sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint)idx); 564 bakedModuleCache = bakedModule.Get(sp.UUID);
576 if (wearableCache[idx].TextureID != UUID.Zero)
577 {
578 sp.Appearance.Texture.FaceTextures[idx].TextureID = wearableCache[idx].TextureID;
579 face = sp.Appearance.Texture.FaceTextures[idx];
580 // let run to end of loop to check cache
581 }
582 else
583 {
584 sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
585 face = sp.Appearance.Texture.FaceTextures[idx];
586 // lets try not invalidating the cache entry
587 // wearableCache[idx].CacheId = UUID.Zero;
588 // wearableCache[idx].TextureAsset = null;
589 continue;
590 }
591 } 565 }
592 566 catch (Exception)
593 if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
594 continue;
595
596 if (wearableCache[idx].TextureID != face.TextureID)
597 { 567 {
598 wearableCache[idx].CacheId = UUID.Zero; 568 bakedModuleCache = null;
599 wearableCache[idx].TextureID = UUID.Zero;
600 wearableCache[idx].TextureAsset = null;
601 continue;
602 } 569 }
603 570
604 wearableCache[idx].TextureAsset = null; 571 if (bakedModuleCache != null)
605 if (cache != null)
606 { 572 {
607 wearableCache[idx].TextureAsset = m_scene.AssetService.GetCached(face.TextureID.ToString()); 573 m_log.Debug("[ValidateBakedCache] got bakedModule cache " + bakedModuleCache.Length);
608 if (wearableCache[idx].TextureAsset == null) 574
575 for (int i = 0; i < bakedModuleCache.Length; i++)
609 { 576 {
610 wearableCache[idx].CacheId = UUID.Zero; 577 int j = (int)bakedModuleCache[i].TextureIndex;
611 wearableCache[idx].TextureID = UUID.Zero; 578
579 if (bakedModuleCache[i].TextureAsset != null)
580 {
581 wearableCache[j].TextureID = bakedModuleCache[i].TextureID;
582 wearableCache[j].CacheId = bakedModuleCache[i].CacheId;
583 wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset;
584 bakedModuleCache[i].TextureAsset.Temporary = true;
585 bakedModuleCache[i].TextureAsset.Local = true;
586 cache.Store(bakedModuleCache[i].TextureAsset);
587
588 }
612 } 589 }
613 else 590 gotbacked = true;
591 }
592 }
593
594 if (gotbacked)
595 {
596 // force the ones we got
597 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
598 {
599 int idx = AvatarAppearance.BAKE_INDICES[i];
600 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
601
602 if (sp.Appearance.Texture.FaceTextures[idx] == null)
603 sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint)idx);
604 sp.Appearance.Texture.FaceTextures[idx].TextureID = wearableCache[idx].TextureID;
605 face = sp.Appearance.Texture.FaceTextures[idx];
606
607 // this should be removed
608 if (face.TextureID != UUID.Zero && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
614 hits++; 609 hits++;
610 continue;
615 } 611 }
616 } 612 }
617 } 613 }
618 614
619 sp.Appearance.WearableCacheItems = wearableCache; 615 sp.Appearance.WearableCacheItems = wearableCache;
616
620 } 617 }
621 618
622 m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1} {2}", sp.Name, sp.UUID, hits);
623 // debug 619 // debug
620 m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1} {2}", sp.Name, sp.UUID, hits);
624 for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) 621 for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++)
625 { 622 {
626 int j = AvatarAppearance.BAKE_INDICES[iter]; 623 int j = AvatarAppearance.BAKE_INDICES[iter];