From f5c9a56c8b73ef93db712fefe9f0366c4983e04f Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Fri, 29 Oct 2010 13:37:13 -0700 Subject: [PATCH] Bunch of fixes that reduce the number of times appearance and avatar data are sent. And the number of times they are stored. --- OpenSim/Framework/AvatarAppearance.cs | 35 +++++---- .../Avatar/Attachments/AttachmentsModule.cs | 32 ++++---- .../AvatarFactory/AvatarFactoryModule.cs | 73 +++++++++++++------ OpenSim/Region/Framework/Scenes/Scene.cs | 7 ++ .../Region/Framework/Scenes/ScenePresence.cs | 66 ++++++++++++----- 5 files changed, 132 insertions(+), 81 deletions(-) diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index e66a1e7390..17e4eb4371 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -45,6 +45,7 @@ namespace OpenSim.Framework public readonly static int VISUALPARAM_COUNT = 218; public readonly static int TEXTURE_COUNT = 21; + public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; protected UUID m_owner; protected int m_serial = 1; @@ -347,14 +348,8 @@ namespace OpenSim.Framework protected virtual void SetDefaultTexture() { m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); - // The initialization of these seems to force a rebake regardless of whether it is needed - // m_textures.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012"); - // m_textures.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID; - // m_textures.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID; - // m_textures.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77"); - // m_textures.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B"); - // m_textures.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010"); - // m_textures.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011"); + for (uint i = 0; i < TEXTURE_COUNT; i++) + m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE); } /// @@ -371,7 +366,7 @@ namespace OpenSim.Framework // made. We determine if any of the textures actually // changed to know if the appearance should be saved later bool changed = false; - for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) + for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) { Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i]; Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i]; @@ -385,7 +380,6 @@ namespace OpenSim.Framework if (oldface != null && oldface.TextureID == newface.TextureID) continue; } - m_texture.FaceTextures[i] = (newface != null) ? new Primitive.TextureEntryFace(newface) : null; changed = true; // DEBUG ON if (newface != null) @@ -393,6 +387,7 @@ namespace OpenSim.Framework // DEBUG OFF } + m_texture = textureEntry; return changed; } @@ -415,8 +410,8 @@ namespace OpenSim.Framework if (visualParams[i] != m_visualparams[i]) { // DEBUG ON - m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}", - i,m_visualparams[i],visualParams[i]); +// m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}", +// i,m_visualparams[i],visualParams[i]); // DEBUG OFF m_visualparams[i] = visualParams[i]; changed = true; @@ -581,6 +576,8 @@ namespace OpenSim.Framework m_attachments.Clear(); } + #region Packing Functions + /// /// Create an OSDMap from the appearance data /// @@ -605,7 +602,7 @@ namespace OpenSim.Framework if (m_texture.FaceTextures[i] != null) textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID)); else - textures.Add(OSD.FromUUID(UUID.Zero)); + textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE)); } data["textures"] = textures; @@ -657,12 +654,10 @@ namespace OpenSim.Framework OSDArray textures = (OSDArray)(data["textures"]); for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++) { + UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; if (textures[i] != null) - { - UUID textureID = textures[i].AsUUID(); - if (textureID != UUID.Zero) - m_texture.CreateFace((uint)i).TextureID = textureID; - } + textureID = textures[i].AsUUID(); + m_texture.CreateFace((uint)i).TextureID = new UUID(textureID); } } else @@ -697,6 +692,9 @@ namespace OpenSim.Framework } } + #endregion + + #region VPElement /// /// Viewer Params Array Element for AgentSetAppearance @@ -1460,5 +1458,6 @@ namespace OpenSim.Framework SKIRT_SKIRT_GREEN = 216, SKIRT_SKIRT_BLUE = 217 } + #endregion } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ad6b1deba4..e89368a4b6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -123,15 +123,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); // Save avatar attachment information - ScenePresence presence; - if (m_scene.AvatarService != null && m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) - { - m_log.Info( - "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId - + ", AttachmentPoint: " + AttachmentPt); + m_log.Info( + "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + + ", AttachmentPoint: " + AttachmentPt); - m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); - } + if (m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); } } catch (Exception e) @@ -382,8 +379,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments item = m_scene.InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); - if (m_scene.AvatarService != null) - m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); + if (m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); } } @@ -405,11 +402,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments presence.Appearance.DetachAttachment(itemID); // Save avatar attachment information - if (m_scene.AvatarService != null) - { - m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); - m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); - } + m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); + if (m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); } DetachSingleAttachmentToInv(itemID, remoteClient); @@ -435,10 +430,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments presence.Appearance.DetachAttachment(itemID); - if (m_scene.AvatarService != null) - { - m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); - } + if (m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); + part.ParentGroup.DetachToGround(); List uuids = new List(); diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 5f8b4f6b0c..bfbbcf84f1 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -42,10 +42,9 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { - public class AvatarFactoryModule : IRegionModule + public class AvatarFactoryModule : IAvatarFactory, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; private Scene m_scene = null; private int m_savetime = 5; // seconds to wait before saving changed appearance @@ -60,8 +59,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public void Initialise(Scene scene, IConfigSource config) { + scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += NewClient; - + if (config != null) { IConfig sconfig = config.Configs["Startup"]; @@ -112,6 +112,34 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory #endregion + public bool ValidateBakedTextureCache(IClientAPI client) + { + ScenePresence sp = m_scene.GetScenePresence(client.AgentId); + if (sp == null) + { + m_log.WarnFormat("[AVFACTORY] SetAppearance unable to find presence for {0}",client.AgentId); + return false; + } + + bool cached = true; + + // Process the texture entry + for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) + { + int idx = AvatarAppearance.BAKE_INDICES[i]; + Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; + if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) + if (! CheckBakedTextureAsset(client,face.TextureID,idx)) + { + sp.Appearance.Texture.FaceTextures[idx] = null; + cached = false; + } + } + + return cached; + } + + /// /// Set appearance data (textureentry and slider settings) received from the client /// @@ -137,12 +165,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { changed = sp.Appearance.SetTextureEntries(textureEntry); - for (int i = 0; i < BAKE_INDICES.Length; i++) + for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) { - int idx = BAKE_INDICES[i]; + int idx = AvatarAppearance.BAKE_INDICES[i]; Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) - Util.FireAndForget(delegate(object o) { CheckBakedTextureAssets(client,face.TextureID,idx); }); + Util.FireAndForget(delegate(object o) { + if (! CheckBakedTextureAsset(client,face.TextureID,idx)) + client.SendRebakeAvatarTextures(face.TextureID); + }); } } @@ -165,9 +196,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory QueueAppearanceSend(client.AgentId); // Send the appearance back to the avatar - AvatarAppearance avp = sp.Appearance; - sp.ControllingClient.SendAvatarDataImmediate(sp); - sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); + // AvatarAppearance avp = sp.Appearance; + // sp.ControllingClient.SendAvatarDataImmediate(sp); + // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); } /// @@ -177,14 +208,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// /// /// - private void CheckBakedTextureAssets(IClientAPI client, UUID textureID, int idx) + private bool CheckBakedTextureAsset(IClientAPI client, UUID textureID, int idx) { if (m_scene.AssetService.Get(textureID.ToString()) == null) { m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}", textureID,idx,client.Name); - client.SendRebakeAvatarTextures(textureID); + return false; } + return true; } #region UpdateAppearanceTimer @@ -229,16 +261,16 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } // DEBUG ON - m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}\n{1}",agentid,sp.Appearance.ToString()); + m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}",agentid); // DEBUG OFF // Send the appearance to everyone in the scene sp.SendAppearanceToAllOtherAgents(); + sp.ControllingClient.SendAvatarDataImmediate(sp); // Send the appearance back to the avatar - AvatarAppearance avp = sp.Appearance; - sp.ControllingClient.SendAvatarDataImmediate(sp); - sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); + // AvatarAppearance avp = sp.Appearance; + // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); /* // this needs to be fixed, the flag should be on scene presence not the region module @@ -337,14 +369,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance); - //if (!TryGetAvatarAppearance(client.AgentId, out avatAppearance)) - //{ - // m_log.Warn("[AVFACTORY]: We didn't seem to find the appearance, falling back to ScenePresence"); - // avatAppearance = sp.Appearance; - //} - - //m_log.DebugFormat("[AVFACTORY]: Received wearables for {0}", client.Name); - foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) { if (wear.Type < AvatarWearable.MAX_WEARABLES) @@ -354,10 +378,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } } + // This could take awhile since it needs to pull inventory SetAppearanceAssets(sp.UUID, ref avatAppearance); - m_scene.AvatarService.SetAppearance(client.AgentId, avatAppearance); sp.Appearance = avatAppearance; + m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); } private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6367fcf641..3343d081ab 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -119,6 +119,7 @@ namespace OpenSim.Region.Framework.Scenes protected IXMLRPC m_xmlrpcModule; protected IWorldComm m_worldCommModule; + protected IAvatarFactory m_AvatarFactory; protected IConfigSource m_config; protected IRegionSerialiserModule m_serialiser; protected IDialogModule m_dialogModule; @@ -398,6 +399,11 @@ namespace OpenSim.Region.Framework.Scenes public IAttachmentsModule AttachmentsModule { get; set; } + public IAvatarFactory AvatarFactory + { + get { return m_AvatarFactory; } + } + public ICapabilitiesModule CapsModule { get { return m_capsModule; } @@ -1153,6 +1159,7 @@ namespace OpenSim.Region.Framework.Scenes m_xmlrpcModule = RequestModuleInterface(); m_worldCommModule = RequestModuleInterface(); XferManager = RequestModuleInterface(); + m_AvatarFactory = RequestModuleInterface(); AttachmentsModule = RequestModuleInterface(); m_serialiser = RequestModuleInterface(); m_dialogModule = RequestModuleInterface(); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f828a2d45a..7d9c8e51bb 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -704,20 +704,14 @@ namespace OpenSim.Region.Framework.Scenes // we created a new ScenePresence (a new child agent) in a fresh region. // Request info about all the (root) agents in this region // Note: This won't send data *to* other clients in that region (children don't send) - SendInitialFullUpdateToAllClients(); + +// MIC: This should be called by OnCompleteMovement +// SendInitialFullUpdateToAllClients(); RegisterToEvents(); SetDirectionVectors(); } -/* - public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, - AvatarWearable[] wearables) - : this(client, world, reginfo) - { - m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); - } -*/ public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) : this(client, world, reginfo) { @@ -1081,7 +1075,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void CompleteMovement(IClientAPI client) { - //m_log.Debug("[SCENE PRESENCE]: CompleteMovement"); +// DEBUG ON + m_log.WarnFormat("[SCENE PRESENCE]: CompleteMovement for {0}",UUID); +// DEBUG OFF Vector3 look = Velocity; if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) @@ -2381,12 +2377,20 @@ namespace OpenSim.Region.Framework.Scenes // 2 stage check is needed. if (remoteAvatar == null) return; + IClientAPI cl=remoteAvatar.ControllingClient; if (cl == null) return; + if (m_appearance.Texture == null) return; + if (LocalId == remoteAvatar.LocalId) + { + m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID); + return; + } + if (IsChildAgent) { m_log.WarnFormat("[SCENEPRESENCE] A child agent is attempting to send out avatar data"); @@ -2407,20 +2411,23 @@ namespace OpenSim.Region.Framework.Scenes m_scene.ForEachScenePresence(delegate(ScenePresence avatar) { ++avUpdates; - // only send if this is the root (children are only "listening posts" in a foreign region) + + // Don't update ourselves + if (avatar.LocalId == LocalId) + return; + + // If this is a root agent, then get info about the avatar if (!IsChildAgent) { SendFullUpdateToOtherClient(avatar); } - if (avatar.LocalId != LocalId) + // If the other avatar is a root + if (!avatar.IsChildAgent) { - if (!avatar.IsChildAgent) - { - avatar.SendFullUpdateToOtherClient(this); - avatar.SendAppearanceToOtherAgent(this); - avatar.Animator.SendAnimPackToClient(ControllingClient); - } + avatar.SendFullUpdateToOtherClient(this); + avatar.SendAppearanceToOtherAgent(this); + avatar.Animator.SendAnimPackToClient(ControllingClient); } }); @@ -2465,7 +2472,19 @@ namespace OpenSim.Region.Framework.Scenes // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); m_controllingClient.SendAvatarDataImmediate(this); - m_controllingClient.SendAppearance(m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); + if (m_scene.AvatarFactory != null) + { + if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) + { + m_log.WarnFormat("[SP] baked textures are in the ache for {0}",Name); + m_controllingClient.SendAppearance( + m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); + } + } + else + { + m_log.WarnFormat("[SP] AvatarFactory not set"); + } SendInitialFullUpdateToAllClients(); } @@ -2497,9 +2516,16 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendAppearanceToOtherAgent(ScenePresence avatar) { + if (LocalId == avatar.LocalId) + { + m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID); + return; + } + // DEBUG ON - m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); +// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); // DEBUG OFF + avatar.ControllingClient.SendAppearance( m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); }