diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/AvatarAppearance.cs | 17 | ||||
-rw-r--r-- | OpenSim/Framework/WearableCacheItem.cs | 60 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 187 |
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]; |