diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 616 |
1 files changed, 402 insertions, 214 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index cfb082b..4abac43 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
75 | m_savetime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); | 75 | m_savetime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); |
76 | m_sendtime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); | 76 | m_sendtime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); |
77 | m_reusetextures = appearanceConfig.GetBoolean("ReuseTextures",m_reusetextures); | 77 | m_reusetextures = appearanceConfig.GetBoolean("ReuseTextures",m_reusetextures); |
78 | 78 | ||
79 | // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime); | 79 | // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime); |
80 | } | 80 | } |
81 | 81 | ||
@@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
166 | } | 166 | } |
167 | 167 | ||
168 | /// <summary> | 168 | /// <summary> |
169 | /// Set appearance data (texture asset IDs and slider settings) | 169 | /// Set appearance data (texture asset IDs and slider settings) |
170 | /// </summary> | 170 | /// </summary> |
171 | /// <param name="sp"></param> | 171 | /// <param name="sp"></param> |
172 | /// <param name="texture"></param> | 172 | /// <param name="texture"></param> |
@@ -188,29 +188,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
188 | // Process the visual params, this may change height as well | 188 | // Process the visual params, this may change height as well |
189 | if (visualParams != null) | 189 | if (visualParams != null) |
190 | { | 190 | { |
191 | // string[] visualParamsStrings = new string[visualParams.Length]; | ||
192 | // for (int i = 0; i < visualParams.Length; i++) | ||
193 | // visualParamsStrings[i] = visualParams[i].ToString(); | ||
194 | // m_log.DebugFormat( | ||
195 | // "[AVFACTORY]: Setting visual params for {0} to {1}", | ||
196 | // client.Name, string.Join(", ", visualParamsStrings)); | ||
197 | /* | ||
198 | float oldHeight = sp.Appearance.AvatarHeight; | ||
199 | changed = sp.Appearance.SetVisualParams(visualParams); | ||
200 | |||
201 | if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) | ||
202 | ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); | ||
203 | */ | ||
204 | // float oldoff = sp.Appearance.AvatarFeetOffset; | ||
205 | // Vector3 oldbox = sp.Appearance.AvatarBoxSize; | ||
206 | changed = sp.Appearance.SetVisualParams(visualParams); | 191 | changed = sp.Appearance.SetVisualParams(visualParams); |
207 | // float off = sp.Appearance.AvatarFeetOffset; | ||
208 | // Vector3 box = sp.Appearance.AvatarBoxSize; | ||
209 | // if(oldoff != off || oldbox != box) | ||
210 | // ((ScenePresence)sp).SetSize(box,off); | ||
211 | |||
212 | } | 192 | } |
213 | 193 | ||
214 | // Process the baked texture array | 194 | // Process the baked texture array |
215 | if (textureEntry != null) | 195 | if (textureEntry != null) |
216 | { | 196 | { |
@@ -222,9 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
222 | 202 | ||
223 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | 203 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); |
224 | 204 | ||
225 | // If bake textures are missing and this is not an NPC, request a rebake from client | 205 | UpdateBakedTextureCache(sp, cacheItems); |
226 | if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) | ||
227 | RequestRebake(sp, true); | ||
228 | 206 | ||
229 | // This appears to be set only in the final stage of the appearance | 207 | // This appears to be set only in the final stage of the appearance |
230 | // update transaction. In theory, we should be able to do an immediate | 208 | // update transaction. In theory, we should be able to do an immediate |
@@ -251,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
251 | private void SendAppearance(ScenePresence sp) | 229 | private void SendAppearance(ScenePresence sp) |
252 | { | 230 | { |
253 | // Send the appearance to everyone in the scene | 231 | // Send the appearance to everyone in the scene |
254 | sp.SendAppearanceToAllOtherClients(); | 232 | sp.SendAppearanceToAllOtherAgents(); |
255 | 233 | ||
256 | // Send animations back to the avatar as well | 234 | // Send animations back to the avatar as well |
257 | sp.Animator.SendAnimPack(); | 235 | sp.Animator.SendAnimPack(); |
@@ -289,7 +267,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
289 | WearableCacheItem[] items = sp.Appearance.WearableCacheItems; | 267 | WearableCacheItem[] items = sp.Appearance.WearableCacheItems; |
290 | //foreach (WearableCacheItem item in items) | 268 | //foreach (WearableCacheItem item in items) |
291 | //{ | 269 | //{ |
292 | 270 | ||
293 | //} | 271 | //} |
294 | return items; | 272 | return items; |
295 | } | 273 | } |
@@ -310,23 +288,25 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
310 | if (bakedTextures.Count == 0) | 288 | if (bakedTextures.Count == 0) |
311 | return false; | 289 | return false; |
312 | 290 | ||
291 | IAssetCache cache = sp.Scene.RequestModuleInterface<IAssetCache>(); | ||
292 | if(cache == null) | ||
293 | return true; // no baked local caching so nothing to do | ||
294 | |||
313 | foreach (BakeType bakeType in bakedTextures.Keys) | 295 | foreach (BakeType bakeType in bakedTextures.Keys) |
314 | { | 296 | { |
315 | Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType]; | 297 | Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType]; |
316 | 298 | ||
317 | if (bakedTextureFace == null) | 299 | if (bakedTextureFace == null) |
318 | { | ||
319 | // This can happen legitimately, since some baked textures might not exist | ||
320 | //m_log.WarnFormat( | ||
321 | // "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently", | ||
322 | // bakeType, sp.Name, m_scene.RegionInfo.RegionName); | ||
323 | continue; | 300 | continue; |
324 | } | ||
325 | 301 | ||
326 | AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString()); | 302 | AssetBase asset; |
303 | cache.Get(bakedTextureFace.TextureID.ToString(), out asset); | ||
327 | 304 | ||
328 | if (asset != null) | 305 | if (asset != null && asset.Local) |
329 | { | 306 | { |
307 | // cache does not update asset contents | ||
308 | cache.Expire(bakedTextureFace.TextureID.ToString()); | ||
309 | |||
330 | // Replace an HG ID with the simple asset ID so that we can persist textures for foreign HG avatars | 310 | // Replace an HG ID with the simple asset ID so that we can persist textures for foreign HG avatars |
331 | asset.ID = asset.FullID.ToString(); | 311 | asset.ID = asset.FullID.ToString(); |
332 | 312 | ||
@@ -334,7 +314,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
334 | asset.Local = false; | 314 | asset.Local = false; |
335 | m_scene.AssetService.Store(asset); | 315 | m_scene.AssetService.Store(asset); |
336 | } | 316 | } |
337 | else | 317 | |
318 | if (asset == null) | ||
338 | { | 319 | { |
339 | m_log.WarnFormat( | 320 | m_log.WarnFormat( |
340 | "[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently", | 321 | "[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently", |
@@ -377,116 +358,366 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
377 | } | 358 | } |
378 | } | 359 | } |
379 | 360 | ||
380 | public bool ValidateBakedTextureCache(IScenePresence sp) | 361 | // called on textures update |
362 | public bool UpdateBakedTextureCache(IScenePresence sp, WearableCacheItem[] cacheItems) | ||
381 | { | 363 | { |
382 | bool defonly = true; // are we only using default textures | 364 | if(cacheItems == null) |
383 | IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); | 365 | return false; |
384 | IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | 366 | |
385 | WearableCacheItem[] wearableCache = null; | 367 | // npcs dont have baked cache |
386 | 368 | if (((ScenePresence)sp).IsNPC) | |
387 | // Cache wearable data for teleport. | 369 | return true; |
388 | // Only makes sense if there's a bake module and a cache module | 370 | |
389 | if (bakedModule != null && cache != null) | 371 | // uploaded baked textures will be in assets local cache |
372 | IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>(); | ||
373 | IBakedTextureModule m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
374 | |||
375 | int validDirtyBakes = 0; | ||
376 | int hits = 0; | ||
377 | |||
378 | // our main cacheIDs mapper is p.Appearance.WearableCacheItems | ||
379 | WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems; | ||
380 | |||
381 | if (wearableCache == null) | ||
382 | { | ||
383 | wearableCache = WearableCacheItem.GetDefaultCacheItem(); | ||
384 | } | ||
385 | |||
386 | List<UUID> missing = new List<UUID>(); | ||
387 | |||
388 | bool haveSkirt = (wearableCache[19].TextureID != UUID.Zero); | ||
389 | bool haveNewSkirt = false; | ||
390 | |||
391 | // Process received baked textures | ||
392 | for (int i = 0; i < cacheItems.Length; i++) | ||
390 | { | 393 | { |
391 | try | 394 | int idx = (int)cacheItems[i].TextureIndex; |
395 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | ||
396 | |||
397 | // No face | ||
398 | if (face == null) | ||
392 | { | 399 | { |
393 | wearableCache = bakedModule.Get(sp.UUID); | 400 | // for some reason viewer is cleaning this |
401 | if(idx != 19) // skirt is optional | ||
402 | { | ||
403 | sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx); | ||
404 | sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; | ||
405 | } | ||
406 | wearableCache[idx].CacheId = UUID.Zero; | ||
407 | wearableCache[idx].TextureID = UUID.Zero; | ||
408 | wearableCache[idx].TextureAsset = null; | ||
409 | continue; | ||
394 | } | 410 | } |
395 | catch (Exception) | 411 | else |
396 | { | 412 | { |
413 | if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
414 | { | ||
415 | wearableCache[idx].CacheId = UUID.Zero; | ||
416 | wearableCache[idx].TextureID = UUID.Zero; | ||
417 | wearableCache[idx].TextureAsset = null; | ||
418 | continue; | ||
419 | } | ||
397 | 420 | ||
398 | } | 421 | if(idx == 19) |
399 | if (wearableCache != null) | 422 | haveNewSkirt = true; |
400 | { | 423 | /* |
401 | for (int i = 0; i < wearableCache.Length; i++) | 424 | if (face.TextureID == wearableCache[idx].TextureID && m_BakedTextureModule != null) |
402 | { | 425 | { |
403 | cache.Cache(wearableCache[i].TextureAsset); | 426 | if (wearableCache[idx].CacheId != cacheItems[i].CacheId) |
427 | { | ||
428 | wearableCache[idx].CacheId = cacheItems[i].CacheId; | ||
429 | validDirtyBakes++; | ||
430 | |||
431 | //assuming this can only happen if asset is in cache | ||
432 | } | ||
433 | hits++; | ||
434 | continue; | ||
435 | } | ||
436 | */ | ||
437 | wearableCache[idx].TextureAsset = null; | ||
438 | if (cache != null) | ||
439 | { | ||
440 | AssetBase asb = null; | ||
441 | cache.Get(face.TextureID.ToString(), out asb); | ||
442 | wearableCache[idx].TextureAsset = asb; | ||
443 | } | ||
444 | |||
445 | if (wearableCache[idx].TextureAsset != null) | ||
446 | { | ||
447 | if ( wearableCache[idx].TextureID != face.TextureID || | ||
448 | wearableCache[idx].CacheId != cacheItems[i].CacheId) | ||
449 | validDirtyBakes++; | ||
450 | |||
451 | wearableCache[idx].TextureID = face.TextureID; | ||
452 | wearableCache[idx].CacheId = cacheItems[i].CacheId; | ||
453 | hits++; | ||
454 | } | ||
455 | else | ||
456 | { | ||
457 | wearableCache[idx].CacheId = UUID.Zero; | ||
458 | wearableCache[idx].TextureID = UUID.Zero; | ||
459 | wearableCache[idx].TextureAsset = null; | ||
460 | missing.Add(face.TextureID); | ||
461 | continue; | ||
404 | } | 462 | } |
405 | } | 463 | } |
406 | } | 464 | } |
407 | /* | 465 | |
408 | IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | 466 | // handle optional skirt case |
409 | if (invService.GetRootFolder(userID) != null) | 467 | if(!haveNewSkirt && haveSkirt) |
468 | { | ||
469 | wearableCache[19].CacheId = UUID.Zero; | ||
470 | wearableCache[19].TextureID = UUID.Zero; | ||
471 | wearableCache[19].TextureAsset = null; | ||
472 | validDirtyBakes++; | ||
473 | } | ||
474 | |||
475 | sp.Appearance.WearableCacheItems = wearableCache; | ||
476 | |||
477 | if (missing.Count > 0) | ||
410 | { | 478 | { |
411 | WearableCacheItem[] wearableCache = null; | 479 | foreach (UUID id in missing) |
412 | if (bakedModule != null) | 480 | sp.ControllingClient.SendRebakeAvatarTextures(id); |
481 | } | ||
482 | |||
483 | if (validDirtyBakes > 0 && hits == cacheItems.Length) | ||
484 | { | ||
485 | // if we got a full set of baked textures save all in BakedTextureModule | ||
486 | if (m_BakedTextureModule != null) | ||
413 | { | 487 | { |
414 | try | 488 | m_log.DebugFormat("[UpdateBakedCache] Uploading to Bakes Server: cache hits: {0} changed entries: {1} rebakes {2}", |
489 | hits.ToString(), validDirtyBakes.ToString(), missing.Count); | ||
490 | |||
491 | m_BakedTextureModule.Store(sp.UUID, wearableCache); | ||
492 | } | ||
493 | } | ||
494 | else | ||
495 | m_log.DebugFormat("[UpdateBakedCache] cache hits: {0} changed entries: {1} rebakes {2}", | ||
496 | hits.ToString(), validDirtyBakes.ToString(), missing.Count); | ||
497 | |||
498 | for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) | ||
499 | { | ||
500 | int j = AvatarAppearance.BAKE_INDICES[iter]; | ||
501 | sp.Appearance.WearableCacheItems[j].TextureAsset = null; | ||
502 | // m_log.Debug("[UpdateBCache] {" + iter + "/" + | ||
503 | // sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" + | ||
504 | // sp.Appearance.WearableCacheItems[j].CacheId + ", t-" + | ||
505 | // sp.Appearance.WearableCacheItems[j].TextureID); | ||
506 | } | ||
507 | |||
508 | return (hits == cacheItems.Length); | ||
509 | } | ||
510 | |||
511 | // called when we get a new root avatar | ||
512 | public bool ValidateBakedTextureCache(IScenePresence sp) | ||
513 | { | ||
514 | int hits = 0; | ||
515 | |||
516 | if (((ScenePresence)sp).IsNPC) | ||
517 | return true; | ||
518 | |||
519 | lock (m_setAppearanceLock) | ||
520 | { | ||
521 | IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>(); | ||
522 | IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>(); | ||
523 | WearableCacheItem[] bakedModuleCache = null; | ||
524 | |||
525 | if (cache == null) | ||
526 | return false; | ||
527 | |||
528 | WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems; | ||
529 | |||
530 | // big debug | ||
531 | //m_log.DebugFormat("[AVFACTORY]: ValidateBakedTextureCache start for {0} {1}", sp.Name, sp.UUID); | ||
532 | /* | ||
533 | for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) | ||
534 | { | ||
535 | int j = AvatarAppearance.BAKE_INDICES[iter]; | ||
536 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[j]; | ||
537 | if (wearableCache == null) | ||
538 | { | ||
539 | if (face != null) | ||
540 | m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t- " + face.TextureID); | ||
541 | else | ||
542 | m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t- No texture"); | ||
543 | } | ||
544 | else | ||
545 | { | ||
546 | if (face != null) | ||
547 | m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " ft- " + face.TextureID + | ||
548 | "}: cc-" + | ||
549 | wearableCache[j].CacheId + ", ct-" + | ||
550 | wearableCache[j].TextureID | ||
551 | ); | ||
552 | else | ||
553 | m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - No texture" + | ||
554 | "}: cc-" + | ||
555 | wearableCache[j].CacheId + ", ct-" + | ||
556 | wearableCache[j].TextureID | ||
557 | ); | ||
558 | } | ||
559 | } | ||
560 | */ | ||
561 | |||
562 | bool wearableCacheValid = false; | ||
563 | if (wearableCache == null) | ||
564 | { | ||
565 | wearableCache = WearableCacheItem.GetDefaultCacheItem(); | ||
566 | } | ||
567 | else | ||
568 | { | ||
569 | // we may have received a full cache | ||
570 | // check same coerence and store | ||
571 | wearableCacheValid = true; | ||
572 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | ||
415 | { | 573 | { |
416 | wearableCache = bakedModule.Get(userID); | 574 | int idx = AvatarAppearance.BAKE_INDICES[i]; |
417 | appearance.WearableCacheItems = wearableCache; | 575 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; |
418 | appearance.WearableCacheItemsDirty = false; | 576 | if (face != null) |
419 | foreach (WearableCacheItem item in wearableCache) | ||
420 | { | 577 | { |
421 | appearance.Texture.FaceTextures[item.TextureIndex].TextureID = item.TextureID; | 578 | if (face.TextureID == wearableCache[idx].TextureID && |
579 | face.TextureID != UUID.Zero) | ||
580 | { | ||
581 | if (wearableCache[idx].TextureAsset != null) | ||
582 | { | ||
583 | hits++; | ||
584 | wearableCache[idx].TextureAsset.Temporary = true; | ||
585 | wearableCache[idx].TextureAsset.Local = true; | ||
586 | cache.Cache(wearableCache[idx].TextureAsset); | ||
587 | wearableCache[idx].TextureAsset = null; | ||
588 | continue; | ||
589 | } | ||
590 | |||
591 | if (cache.Check((wearableCache[idx].TextureID).ToString())) | ||
592 | { | ||
593 | hits++; | ||
594 | continue; | ||
595 | } | ||
596 | } | ||
597 | wearableCacheValid = false; | ||
422 | } | 598 | } |
423 | } | 599 | } |
424 | catch (Exception) | 600 | |
601 | wearableCacheValid = (wearableCacheValid && (hits >= AvatarAppearance.BAKE_INDICES.Length - 1)); | ||
602 | if (wearableCacheValid) | ||
425 | { | 603 | { |
426 | 604 | //m_log.Debug("[ValidateBakedCache] have valid local cache"); | |
427 | } | 605 | } |
606 | else | ||
607 | wearableCache[19].TextureAsset = null; // clear optional skirt | ||
428 | } | 608 | } |
429 | */ | ||
430 | 609 | ||
431 | // Process the texture entry | 610 | bool checkExternal = false; |
432 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | ||
433 | { | ||
434 | int idx = AvatarAppearance.BAKE_INDICES[i]; | ||
435 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | ||
436 | 611 | ||
437 | // No face, so lets check our baked service cache, teleport or login. | 612 | if (!wearableCacheValid) |
438 | if (face == null) | ||
439 | { | 613 | { |
440 | if (wearableCache != null) | 614 | hits = 0; |
615 | // only use external bake module on login condition check | ||
616 | // ScenePresence ssp = null; | ||
617 | // if (sp is ScenePresence) | ||
441 | { | 618 | { |
442 | // If we find the an appearance item, set it as the textureentry and the face | 619 | // ssp = (ScenePresence)sp; |
443 | WearableCacheItem searchitem = WearableCacheItem.SearchTextureIndex((uint) idx, wearableCache); | 620 | // checkExternal = (((uint)ssp.TeleportFlags & (uint)TeleportFlags.ViaLogin) != 0) && |
444 | if (searchitem != null) | 621 | // bakedModule != null; |
445 | { | 622 | |
446 | sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx); | 623 | // or do it anytime we dont have the cache |
447 | sp.Appearance.Texture.FaceTextures[idx].TextureID = searchitem.TextureID; | 624 | checkExternal = bakedModule != null; |
448 | face = sp.Appearance.Texture.FaceTextures[idx]; | 625 | } |
449 | } | 626 | } |
450 | else | 627 | |
628 | if (checkExternal) | ||
629 | { | ||
630 | bool gotbacked = false; | ||
631 | |||
632 | m_log.Debug("[ValidateBakedCache] local cache invalid, checking bakedModule"); | ||
633 | try | ||
634 | { | ||
635 | bakedModuleCache = bakedModule.Get(sp.UUID); | ||
636 | } | ||
637 | catch (Exception e) | ||
638 | { | ||
639 | m_log.ErrorFormat(e.ToString()); | ||
640 | bakedModuleCache = null; | ||
641 | } | ||
642 | |||
643 | if (bakedModuleCache != null) | ||
644 | { | ||
645 | //m_log.Debug("[ValidateBakedCache] got bakedModule " + bakedModuleCache.Length + " cached textures"); | ||
646 | |||
647 | for (int i = 0; i < bakedModuleCache.Length; i++) | ||
451 | { | 648 | { |
452 | // if there is no texture entry and no baked cache, skip it | 649 | int j = (int)bakedModuleCache[i].TextureIndex; |
453 | continue; | 650 | |
651 | if (bakedModuleCache[i].TextureAsset != null) | ||
652 | { | ||
653 | wearableCache[j].TextureID = bakedModuleCache[i].TextureID; | ||
654 | wearableCache[j].CacheId = bakedModuleCache[i].CacheId; | ||
655 | wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset; | ||
656 | bakedModuleCache[i].TextureAsset.Temporary = true; | ||
657 | bakedModuleCache[i].TextureAsset.Local = true; | ||
658 | cache.Cache(bakedModuleCache[i].TextureAsset); | ||
659 | } | ||
454 | } | 660 | } |
661 | gotbacked = true; | ||
455 | } | 662 | } |
456 | else | 663 | |
664 | if (gotbacked) | ||
457 | { | 665 | { |
458 | //No texture entry face and no cache. Skip this face. | 666 | // force the ones we got |
459 | continue; | 667 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) |
668 | { | ||
669 | int idx = AvatarAppearance.BAKE_INDICES[i]; | ||
670 | if(wearableCache[idx].TextureAsset == null) | ||
671 | { | ||
672 | if(idx == 19) | ||
673 | { | ||
674 | sp.Appearance.Texture.FaceTextures[idx] = null; | ||
675 | hits++; | ||
676 | } | ||
677 | continue; | ||
678 | } | ||
679 | |||
680 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | ||
681 | |||
682 | if (face == null) | ||
683 | { | ||
684 | face = sp.Appearance.Texture.CreateFace((uint)idx); | ||
685 | sp.Appearance.Texture.FaceTextures[idx] = face; | ||
686 | } | ||
687 | |||
688 | face.TextureID = wearableCache[idx].TextureID; | ||
689 | hits++; | ||
690 | wearableCache[idx].TextureAsset = null; | ||
691 | } | ||
460 | } | 692 | } |
461 | } | 693 | } |
462 | |||
463 | // m_log.DebugFormat( | ||
464 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", | ||
465 | // face.TextureID, idx, client.Name, client.AgentId); | ||
466 | 694 | ||
467 | // if the texture is one of the "defaults" then skip it | 695 | sp.Appearance.WearableCacheItems = wearableCache; |
468 | // this should probably be more intelligent (skirt texture doesnt matter | ||
469 | // if the avatar isnt wearing a skirt) but if any of the main baked | ||
470 | // textures is default then the rest should be as well | ||
471 | if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
472 | continue; | ||
473 | |||
474 | defonly = false; // found a non-default texture reference | ||
475 | 696 | ||
476 | if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) | ||
477 | return false; | ||
478 | } | 697 | } |
479 | 698 | ||
480 | // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); | 699 | // debug |
481 | 700 | //m_log.DebugFormat("[ValidateBakedCache]: Completed texture check for {0} {1} with {2} hits", sp.Name, sp.UUID, hits); | |
482 | // If we only found default textures, then the appearance is not cached | 701 | /* |
483 | return (defonly ? false : true); | 702 | for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) |
703 | { | ||
704 | int j = AvatarAppearance.BAKE_INDICES[iter]; | ||
705 | m_log.Debug("[ValidateBakedCache] {" + iter + "/" + | ||
706 | sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" + | ||
707 | sp.Appearance.WearableCacheItems[j].CacheId + ", t-" + | ||
708 | sp.Appearance.WearableCacheItems[j].TextureID); | ||
709 | } | ||
710 | */ | ||
711 | return (hits >= AvatarAppearance.BAKE_INDICES.Length - 1); // skirt is optional | ||
484 | } | 712 | } |
485 | 713 | ||
486 | public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) | 714 | public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) |
487 | { | 715 | { |
716 | if (((ScenePresence)sp).IsNPC) | ||
717 | return 0; | ||
718 | |||
488 | int texturesRebaked = 0; | 719 | int texturesRebaked = 0; |
489 | // IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); | 720 | IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>(); |
490 | 721 | ||
491 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | 722 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) |
492 | { | 723 | { |
@@ -497,31 +728,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
497 | if (face == null) | 728 | if (face == null) |
498 | continue; | 729 | continue; |
499 | 730 | ||
500 | // m_log.DebugFormat( | ||
501 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", | ||
502 | // face.TextureID, idx, client.Name, client.AgentId); | ||
503 | |||
504 | // if the texture is one of the "defaults" then skip it | ||
505 | // this should probably be more intelligent (skirt texture doesnt matter | ||
506 | // if the avatar isnt wearing a skirt) but if any of the main baked | ||
507 | // textures is default then the rest should be as well | ||
508 | if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) | 731 | if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) |
509 | continue; | 732 | continue; |
510 | 733 | ||
511 | if (missingTexturesOnly) | 734 | if (missingTexturesOnly) |
512 | { | 735 | { |
513 | if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) | 736 | if (cache != null && cache.Check(face.TextureID.ToString())) |
514 | { | 737 | { |
515 | continue; | 738 | continue; |
516 | } | 739 | } |
517 | else | 740 | else |
518 | { | 741 | { |
519 | // On inter-simulator teleports, this occurs if baked textures are not being stored by the | ||
520 | // grid asset service (which means that they are not available to the new region and so have | ||
521 | // to be re-requested from the client). | ||
522 | // | ||
523 | // The only available core OpenSimulator behaviour right now | ||
524 | // is not to store these textures, temporarily or otherwise. | ||
525 | m_log.DebugFormat( | 742 | m_log.DebugFormat( |
526 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", | 743 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", |
527 | face.TextureID, idx, sp.Name); | 744 | face.TextureID, idx, sp.Name); |
@@ -605,7 +822,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
605 | foreach (KeyValuePair<UUID, long> kvp in saves) | 822 | foreach (KeyValuePair<UUID, long> kvp in saves) |
606 | { | 823 | { |
607 | // We have to load the key and value into local parameters to avoid a race condition if we loop | 824 | // We have to load the key and value into local parameters to avoid a race condition if we loop |
608 | // around and load kvp with a different value before FireAndForget has launched its thread. | 825 | // around and load kvp with a different value before FireAndForget has launched its thread. |
609 | UUID avatarID = kvp.Key; | 826 | UUID avatarID = kvp.Key; |
610 | long sendTime = kvp.Value; | 827 | long sendTime = kvp.Value; |
611 | 828 | ||
@@ -658,13 +875,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
658 | 875 | ||
659 | m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); | 876 | m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); |
660 | 877 | ||
661 | // Trigger this here because it's the final step in the set/queue/save process for appearance setting. | 878 | // Trigger this here because it's the final step in the set/queue/save process for appearance setting. |
662 | // Everything has been updated and stored. Ensures bakes have been persisted (if option is set to persist bakes). | 879 | // Everything has been updated and stored. Ensures bakes have been persisted (if option is set to persist bakes). |
663 | m_scene.EventManager.TriggerAvatarAppearanceChanged(sp); | 880 | m_scene.EventManager.TriggerAvatarAppearanceChanged(sp); |
664 | } | 881 | } |
665 | 882 | ||
666 | /// <summary> | 883 | /// <summary> |
667 | /// For a given set of appearance items, check whether the items are valid and add their asset IDs to | 884 | /// For a given set of appearance items, check whether the items are valid and add their asset IDs to |
668 | /// appearance data. | 885 | /// appearance data. |
669 | /// </summary> | 886 | /// </summary> |
670 | /// <param name='userID'></param> | 887 | /// <param name='userID'></param> |
@@ -675,25 +892,27 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
675 | 892 | ||
676 | if (invService.GetRootFolder(userID) != null) | 893 | if (invService.GetRootFolder(userID) != null) |
677 | { | 894 | { |
678 | for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) | 895 | for (int i = 0; i < appearance.Wearables.Length; i++) |
679 | { | 896 | { |
680 | for (int j = 0; j < appearance.Wearables[i].Count; j++) | 897 | for (int j = 0; j < appearance.Wearables[i].Count; j++) |
681 | { | 898 | { |
682 | if (appearance.Wearables[i][j].ItemID == UUID.Zero) | 899 | if (appearance.Wearables[i][j].ItemID == UUID.Zero) |
683 | { | 900 | { |
684 | m_log.WarnFormat( | 901 | m_log.WarnFormat( |
685 | "[AVFACTORY]: Wearable item {0}:{1} for user {2} unexpectedly UUID.Zero. Ignoring.", | 902 | "[AVFACTORY]: Wearable item {0}:{1} for user {2} unexpectedly UUID.Zero. Ignoring.", |
686 | i, j, userID); | 903 | i, j, userID); |
687 | 904 | ||
688 | continue; | 905 | continue; |
689 | } | 906 | } |
690 | 907 | ||
691 | // Ignore ruth's assets | 908 | // Ignore ruth's assets |
692 | if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) | 909 | if (i < AvatarWearable.DefaultWearables.Length) |
693 | continue; | 910 | { |
911 | if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) | ||
912 | continue; | ||
913 | } | ||
694 | 914 | ||
695 | InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); | 915 | InventoryItemBase baseItem = invService.GetItem(userID, appearance.Wearables[i][j].ItemID); |
696 | baseItem = invService.GetItem(baseItem); | ||
697 | 916 | ||
698 | if (baseItem != null) | 917 | if (baseItem != null) |
699 | { | 918 | { |
@@ -754,7 +973,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
754 | // case WearableType.Skin: | 973 | // case WearableType.Skin: |
755 | // //case WearableType.Underpants: | 974 | // //case WearableType.Underpants: |
756 | // TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); | 975 | // TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); |
757 | // | 976 | // |
758 | // m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i); | 977 | // m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i); |
759 | // resetwearable = true; | 978 | // resetwearable = true; |
760 | // break; | 979 | // break; |
@@ -762,7 +981,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
762 | // } | 981 | // } |
763 | // continue; | 982 | // continue; |
764 | // } | 983 | // } |
765 | // | 984 | // |
766 | // InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); | 985 | // InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); |
767 | // baseItem = invService.GetItem(baseItem); | 986 | // baseItem = invService.GetItem(baseItem); |
768 | // | 987 | // |
@@ -789,7 +1008,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
789 | // | 1008 | // |
790 | // TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); | 1009 | // TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); |
791 | // resetwearable = true; | 1010 | // resetwearable = true; |
792 | // | 1011 | // |
793 | // } | 1012 | // } |
794 | // } | 1013 | // } |
795 | // } | 1014 | // } |
@@ -798,7 +1017,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
798 | // if (appearance.Wearables[(int) WearableType.Eyes] == null) | 1017 | // if (appearance.Wearables[(int) WearableType.Eyes] == null) |
799 | // { | 1018 | // { |
800 | // m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes)); | 1019 | // m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes)); |
801 | // | 1020 | // |
802 | // TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance); | 1021 | // TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance); |
803 | // resetwearable = true; | 1022 | // resetwearable = true; |
804 | // } | 1023 | // } |
@@ -902,85 +1121,45 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
902 | { | 1121 | { |
903 | UUID newInvItem = UUID.Random(); | 1122 | UUID newInvItem = UUID.Random(); |
904 | InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID) | 1123 | InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID) |
905 | { | 1124 | { |
906 | AssetID = | 1125 | AssetID = defaultwearable, |
907 | defaultwearable, | 1126 | AssetType = (int)FolderType.BodyPart, |
908 | AssetType | 1127 | CreatorId = userID.ToString(), |
909 | = | 1128 | //InvType = (int)InventoryType.Wearable, |
910 | (int) | 1129 | Description = "Failed Wearable Replacement", |
911 | FolderType | 1130 | Folder = invService.GetFolderForType(userID, FolderType.BodyPart).ID, |
912 | .BodyPart, | 1131 | Flags = (uint) type, Name = Enum.GetName(typeof (WearableType), type), |
913 | CreatorId | 1132 | BasePermissions = (uint) PermissionMask.Copy, |
914 | = | 1133 | CurrentPermissions = (uint) PermissionMask.Copy, |
915 | userID | 1134 | EveryOnePermissions = (uint) PermissionMask.Copy, |
916 | .ToString | 1135 | GroupPermissions = (uint) PermissionMask.Copy, |
917 | (), | 1136 | NextPermissions = (uint) PermissionMask.Copy |
918 | //InvType = (int)InventoryType.Wearable, | 1137 | }; |
919 | |||
920 | Description | ||
921 | = | ||
922 | "Failed Wearable Replacement", | ||
923 | Folder = | ||
924 | invService | ||
925 | .GetFolderForType | ||
926 | (userID, | ||
927 | FolderType | ||
928 | .BodyPart) | ||
929 | .ID, | ||
930 | Flags = (uint) type, | ||
931 | Name = Enum.GetName(typeof (WearableType), type), | ||
932 | BasePermissions = (uint) PermissionMask.Copy, | ||
933 | CurrentPermissions = (uint) PermissionMask.Copy, | ||
934 | EveryOnePermissions = (uint) PermissionMask.Copy, | ||
935 | GroupPermissions = (uint) PermissionMask.Copy, | ||
936 | NextPermissions = (uint) PermissionMask.Copy | ||
937 | }; | ||
938 | invService.AddItem(itembase); | 1138 | invService.AddItem(itembase); |
939 | UUID LinkInvItem = UUID.Random(); | 1139 | UUID LinkInvItem = UUID.Random(); |
940 | itembase = new InventoryItemBase(LinkInvItem, userID) | 1140 | itembase = new InventoryItemBase(LinkInvItem, userID) |
941 | { | 1141 | { |
942 | AssetID = | 1142 | AssetID = newInvItem, |
943 | newInvItem, | 1143 | AssetType = (int)AssetType.Link, |
944 | AssetType | 1144 | CreatorId = userID.ToString(), |
945 | = | 1145 | InvType = (int) InventoryType.Wearable, |
946 | (int) | 1146 | Description = "Failed Wearable Replacement", |
947 | AssetType | 1147 | Folder = invService.GetFolderForType(userID, FolderType.CurrentOutfit).ID, |
948 | .Link, | 1148 | Flags = (uint) type, |
949 | CreatorId | 1149 | Name = Enum.GetName(typeof (WearableType), type), |
950 | = | 1150 | BasePermissions = (uint) PermissionMask.Copy, |
951 | userID | 1151 | CurrentPermissions = (uint) PermissionMask.Copy, |
952 | .ToString | 1152 | EveryOnePermissions = (uint) PermissionMask.Copy, |
953 | (), | 1153 | GroupPermissions = (uint) PermissionMask.Copy, |
954 | InvType = (int) InventoryType.Wearable, | 1154 | NextPermissions = (uint) PermissionMask.Copy |
955 | 1155 | }; | |
956 | Description | ||
957 | = | ||
958 | "Failed Wearable Replacement", | ||
959 | Folder = | ||
960 | invService | ||
961 | .GetFolderForType | ||
962 | (userID, | ||
963 | FolderType | ||
964 | .CurrentOutfit) | ||
965 | .ID, | ||
966 | Flags = (uint) type, | ||
967 | Name = Enum.GetName(typeof (WearableType), type), | ||
968 | BasePermissions = (uint) PermissionMask.Copy, | ||
969 | CurrentPermissions = (uint) PermissionMask.Copy, | ||
970 | EveryOnePermissions = (uint) PermissionMask.Copy, | ||
971 | GroupPermissions = (uint) PermissionMask.Copy, | ||
972 | NextPermissions = (uint) PermissionMask.Copy | ||
973 | }; | ||
974 | invService.AddItem(itembase); | 1156 | invService.AddItem(itembase); |
975 | appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type)); | 1157 | appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type)); |
976 | ScenePresence presence = null; | 1158 | ScenePresence presence = null; |
977 | if (m_scene.TryGetScenePresence(userID, out presence)) | 1159 | if (m_scene.TryGetScenePresence(userID, out presence)) |
978 | { | 1160 | { |
979 | m_scene.SendInventoryUpdate(presence.ControllingClient, | 1161 | m_scene.SendInventoryUpdate(presence.ControllingClient, |
980 | invService.GetFolderForType(userID, | 1162 | invService.GetFolderForType(userID, FolderType.CurrentOutfit), false, true); |
981 | FolderType | ||
982 | .CurrentOutfit), | ||
983 | false, true); | ||
984 | } | 1163 | } |
985 | } | 1164 | } |
986 | } | 1165 | } |
@@ -1040,7 +1219,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1040 | m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); | 1219 | m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); |
1041 | }, null, "AvatarFactoryModule.OnClientRequestWearables"); | 1220 | }, null, "AvatarFactoryModule.OnClientRequestWearables"); |
1042 | } | 1221 | } |
1043 | 1222 | ||
1044 | /// <summary> | 1223 | /// <summary> |
1045 | /// Set appearance data (texture asset IDs and slider settings) received from a client | 1224 | /// Set appearance data (texture asset IDs and slider settings) received from a client |
1046 | /// </summary> | 1225 | /// </summary> |
@@ -1080,8 +1259,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1080 | 1259 | ||
1081 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) | 1260 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) |
1082 | { | 1261 | { |
1083 | if (wear.Type < AvatarWearable.MAX_WEARABLES) | 1262 | // If the wearable type is larger than the current array, expand it |
1084 | avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero); | 1263 | if (avatAppearance.Wearables.Length <= wear.Type) |
1264 | { | ||
1265 | int currentLength = avatAppearance.Wearables.Length; | ||
1266 | AvatarWearable[] wears = avatAppearance.Wearables; | ||
1267 | Array.Resize(ref wears, wear.Type + 1); | ||
1268 | for (int i = currentLength ; i <= wear.Type ; i++) | ||
1269 | wears[i] = new AvatarWearable(); | ||
1270 | avatAppearance.Wearables = wears; | ||
1271 | } | ||
1272 | avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero); | ||
1085 | } | 1273 | } |
1086 | 1274 | ||
1087 | avatAppearance.GetAssetsFrom(sp.Appearance); | 1275 | avatAppearance.GetAssetsFrom(sp.Appearance); |
@@ -1117,12 +1305,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1117 | { | 1305 | { |
1118 | UUID texture = UUID.Zero; | 1306 | UUID texture = UUID.Zero; |
1119 | int index = request.BakedTextureIndex; | 1307 | int index = request.BakedTextureIndex; |
1120 | 1308 | ||
1121 | if (m_reusetextures) | 1309 | if (m_reusetextures) |
1122 | { | 1310 | { |
1123 | // this is the most insanely dumb way to do this... however it seems to | 1311 | // this is the most insanely dumb way to do this... however it seems to |
1124 | // actually work. if the appearance has been reset because wearables have | 1312 | // actually work. if the appearance has been reset because wearables have |
1125 | // changed then the texture entries are zero'd out until the bakes are | 1313 | // changed then the texture entries are zero'd out until the bakes are |
1126 | // uploaded. on login, if the textures exist in the cache (eg if you logged | 1314 | // uploaded. on login, if the textures exist in the cache (eg if you logged |
1127 | // into the simulator recently, then the appearance will pull those and send | 1315 | // into the simulator recently, then the appearance will pull those and send |
1128 | // them back in the packet and you won't have to rebake. if the textures aren't | 1316 | // them back in the packet and you won't have to rebake. if the textures aren't |
@@ -1138,7 +1326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1138 | 1326 | ||
1139 | // m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index); | 1327 | // m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index); |
1140 | } | 1328 | } |
1141 | 1329 | ||
1142 | CachedTextureResponseArg response = new CachedTextureResponseArg(); | 1330 | CachedTextureResponseArg response = new CachedTextureResponseArg(); |
1143 | response.BakedTextureIndex = index; | 1331 | response.BakedTextureIndex = index; |
1144 | response.BakedTextureID = texture; | 1332 | response.BakedTextureID = texture; |
@@ -1146,7 +1334,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1146 | 1334 | ||
1147 | cachedTextureResponse.Add(response); | 1335 | cachedTextureResponse.Add(response); |
1148 | } | 1336 | } |
1149 | 1337 | ||
1150 | // m_log.WarnFormat("[AVFACTORY]: serial is {0}",serial); | 1338 | // m_log.WarnFormat("[AVFACTORY]: serial is {0}",serial); |
1151 | // The serial number appears to be used to match requests and responses | 1339 | // The serial number appears to be used to match requests and responses |
1152 | // in the texture transaction. We just send back the serial number | 1340 | // in the texture transaction. We just send back the serial number |