Refactor appearance and avatar data sending code. Paritioning the routines into "one-to-many" and "many-to-one" makes it possible to call the right function on presence creation (both child and root) and when a child agent is promoted to root. This brings the total number of appearance sends down to one or two on login.
Cleaned up the avatar update calls in the groups code. Cleaned up some commented and debugging code, and a few formating fixes.viewer-2-initial-appearance
parent
7c02d5cec5
commit
541a7660e0
|
@ -302,31 +302,26 @@ namespace OpenSim.Framework
|
|||
if (args["start_pos"] != null)
|
||||
Vector3.TryParse(args["start_pos"].AsString(), out startpos);
|
||||
|
||||
// DEBUG ON
|
||||
m_log.WarnFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString());
|
||||
// DEBUG OFF
|
||||
m_log.InfoFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString());
|
||||
|
||||
try {
|
||||
// Unpack various appearance elements
|
||||
Appearance = new AvatarAppearance(AgentID);
|
||||
// Unpack various appearance elements
|
||||
Appearance = new AvatarAppearance(AgentID);
|
||||
|
||||
// Eventually this code should be deprecated, use full appearance
|
||||
// packing in packed_appearance
|
||||
if (args["appearance_serial"] != null)
|
||||
Appearance.Serial = args["appearance_serial"].AsInteger();
|
||||
// Eventually this code should be deprecated, use full appearance
|
||||
// packing in packed_appearance
|
||||
if (args["appearance_serial"] != null)
|
||||
Appearance.Serial = args["appearance_serial"].AsInteger();
|
||||
|
||||
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map))
|
||||
{
|
||||
Appearance.Unpack((OSDMap)args["packed_appearance"]);
|
||||
// DEBUG ON
|
||||
m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance");
|
||||
// DEBUG OFF
|
||||
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map))
|
||||
{
|
||||
Appearance.Unpack((OSDMap)args["packed_appearance"]);
|
||||
m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance");
|
||||
}
|
||||
else
|
||||
m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance");
|
||||
}
|
||||
// DEBUG ON
|
||||
else
|
||||
m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance");
|
||||
// DEBUG OFF
|
||||
} catch (Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}",e.Message);
|
||||
}
|
||||
|
|
|
@ -331,9 +331,7 @@ namespace OpenSim.Framework
|
|||
|
||||
public virtual OSDMap Pack()
|
||||
{
|
||||
// DEBUG ON
|
||||
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Pack data");
|
||||
// DEBUG OFF
|
||||
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
|
||||
|
||||
OSDMap args = new OSDMap();
|
||||
args["message_type"] = OSD.FromString("AgentData");
|
||||
|
@ -454,9 +452,7 @@ namespace OpenSim.Framework
|
|||
/// <param name="hash"></param>
|
||||
public virtual void Unpack(OSDMap args)
|
||||
{
|
||||
// DEBUG ON
|
||||
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Unpack data");
|
||||
// DEBUG OFF
|
||||
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data");
|
||||
|
||||
if (args.ContainsKey("region_id"))
|
||||
UUID.TryParse(args["region_id"].AsString(), out RegionID);
|
||||
|
@ -613,10 +609,8 @@ namespace OpenSim.Framework
|
|||
|
||||
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
|
||||
Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]);
|
||||
// DEBUG ON
|
||||
else
|
||||
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
|
||||
// DEBUG OFF
|
||||
|
||||
if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
|
||||
{
|
||||
|
|
|
@ -183,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
});
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId);
|
||||
m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId);
|
||||
}
|
||||
|
||||
// Process the visual params, this may change height as well
|
||||
|
@ -196,12 +196,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
sp.SetHeight(sp.Appearance.AvatarHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// Send the appearance back to the avatar, not clear that this is needed
|
||||
sp.ControllingClient.SendAvatarDataImmediate(sp);
|
||||
// AvatarAppearance avp = sp.Appearance;
|
||||
// sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -274,21 +268,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
|
||||
// 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.SendAppearance(avp.Owner, avp.VisualParams, avp.Texture.GetBytes());
|
||||
|
||||
/*
|
||||
// this needs to be fixed, the flag should be on scene presence not the region module
|
||||
// Start the animations if necessary
|
||||
if (!m_startAnimationSet)
|
||||
{
|
||||
sp.Animator.UpdateMovementAnimations();
|
||||
m_startAnimationSet = true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private void HandleAppearanceSave(UUID agentid)
|
||||
|
@ -374,6 +353,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
|
||||
// m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
|
||||
|
||||
// operate on a copy of the appearance so we don't have to lock anything
|
||||
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
|
||||
|
||||
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
|
||||
|
@ -388,9 +368,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
SetAppearanceAssets(sp.UUID, ref avatAppearance);
|
||||
|
||||
// could get fancier with the locks here, but in the spirit of "last write wins"
|
||||
// this should work correctly
|
||||
// this should work correctly, also, we don't need to send the appearance here
|
||||
// since the "iswearing" will trigger a new set of visual param and baked texture changes
|
||||
// when those complete, the new appearance will be sent
|
||||
sp.Appearance = avatAppearance;
|
||||
m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance);
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
}
|
||||
|
||||
private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
|
||||
|
|
|
@ -903,8 +903,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
}
|
||||
|
||||
agent.MakeChildAgent();
|
||||
|
||||
// now we have a child agent in this region. Request all interesting data about other (root) agents
|
||||
agent.SendInitialFullUpdateToAllClients();
|
||||
agent.SendOtherAgentsAvatarDataToMe();
|
||||
agent.SendOtherAgentsAppearanceToMe();
|
||||
|
||||
CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
|
||||
|
||||
|
|
|
@ -703,7 +703,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// Note: This won't send data *to* other clients in that region (children don't send)
|
||||
|
||||
// MIC: This gets called again in CompleteMovement
|
||||
SendInitialFullUpdateToAllClients();
|
||||
// SendInitialFullUpdateToAllClients();
|
||||
SendOtherAgentsAvatarDataToMe();
|
||||
SendOtherAgentsAppearanceToMe();
|
||||
|
||||
RegisterToEvents();
|
||||
SetDirectionVectors();
|
||||
|
@ -1613,7 +1615,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
AbsolutePosition = part.AbsolutePosition;
|
||||
Velocity = Vector3.Zero;
|
||||
SendFullUpdateToAllClients();
|
||||
SendAvatarDataToAllAgents();
|
||||
|
||||
//HandleAgentSit(ControllingClient, m_requestedSitTargetUUID);
|
||||
}
|
||||
|
@ -1688,7 +1690,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_parentPosition = Vector3.Zero;
|
||||
|
||||
m_parentID = 0;
|
||||
SendFullUpdateToAllClients();
|
||||
SendAvatarDataToAllAgents();
|
||||
m_requestedSitTargetID = 0;
|
||||
if (m_physicsActor != null && m_appearance != null)
|
||||
{
|
||||
|
@ -2154,7 +2156,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
RemoveFromPhysicalScene();
|
||||
|
||||
Animator.TrySetMovementAnimation(sitAnimation);
|
||||
SendFullUpdateToAllClients();
|
||||
SendAvatarDataToAllAgents();
|
||||
// This may seem stupid, but Our Full updates don't send avatar rotation :P
|
||||
// So we're also sending a terse update (which has avatar rotation)
|
||||
// [Update] We do now.
|
||||
|
@ -2379,165 +2381,169 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar)
|
||||
/// Do everything required once a client completes its movement into a region and becomes
|
||||
/// a root agent.
|
||||
/// </summary>
|
||||
/// <param name="remoteAvatar"></param>
|
||||
public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar)
|
||||
{
|
||||
// 2 stage check is needed.
|
||||
if (remoteAvatar == null)
|
||||
return;
|
||||
|
||||
IClientAPI cl = remoteAvatar.ControllingClient;
|
||||
if (cl == null)
|
||||
return;
|
||||
|
||||
if (m_appearance.Texture == null)
|
||||
return;
|
||||
|
||||
// MT: This is needed for sit. It's legal to send it to oneself, and the name
|
||||
// of the method is a misnomer
|
||||
//
|
||||
// if (LocalId == remoteAvatar.LocalId)
|
||||
// {
|
||||
// m_log.WarnFormat("[SCENEPRESENCE]: An agent is attempting to send avatar data to itself; {0}", UUID);
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (IsChildAgent)
|
||||
{
|
||||
m_log.WarnFormat("[SCENEPRESENCE]: A child agent is attempting to send out avatar data; {0}", UUID);
|
||||
return;
|
||||
}
|
||||
|
||||
remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this);
|
||||
m_scene.StatsReporter.AddAgentUpdates(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell *ALL* agents about this agent
|
||||
/// </summary>
|
||||
public void SendInitialFullUpdateToAllClients()
|
||||
{
|
||||
m_perfMonMS = Util.EnvironmentTickCount();
|
||||
int avUpdates = 0;
|
||||
m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
||||
{
|
||||
++avUpdates;
|
||||
|
||||
// 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 the other avatar is a root
|
||||
if (!avatar.IsChildAgent)
|
||||
{
|
||||
avatar.SendFullUpdateToOtherClient(this);
|
||||
avatar.SendAppearanceToOtherAgent(this);
|
||||
avatar.Animator.SendAnimPackToClient(ControllingClient);
|
||||
}
|
||||
});
|
||||
|
||||
m_scene.StatsReporter.AddAgentUpdates(avUpdates);
|
||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||
|
||||
//Animator.SendAnimPack();
|
||||
}
|
||||
|
||||
public void SendFullUpdateToAllClients()
|
||||
{
|
||||
m_perfMonMS = Util.EnvironmentTickCount();
|
||||
|
||||
// only send update from root agents to other clients; children are only "listening posts"
|
||||
if (IsChildAgent)
|
||||
{
|
||||
m_log.Warn("[SCENEPRESENCE] attempt to send update from a childagent");
|
||||
return;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
m_scene.ForEachScenePresence(delegate(ScenePresence sp)
|
||||
{
|
||||
if (sp.IsChildAgent)
|
||||
return;
|
||||
SendFullUpdateToOtherClient(sp);
|
||||
++count;
|
||||
});
|
||||
m_scene.StatsReporter.AddAgentUpdates(count);
|
||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||
|
||||
Animator.SendAnimPack();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do everything required once a client completes its movement into a region
|
||||
/// </summary>
|
||||
public void SendInitialData()
|
||||
private void SendInitialData()
|
||||
{
|
||||
// Moved this into CompleteMovement to ensure that m_appearance is initialized before
|
||||
// the inventory arrives
|
||||
// m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
|
||||
|
||||
m_controllingClient.SendAvatarDataImmediate(this);
|
||||
// This agent just became root. We are going to tell everyone about it. The process of
|
||||
// getting other avatars information was initiated in the constructor... don't do it
|
||||
// again here...
|
||||
SendAvatarDataToAllAgents();
|
||||
|
||||
// We have an appearance but we may not have the baked textures. Check the asset cache
|
||||
// to see if all the baked textures are already here.
|
||||
if (m_scene.AvatarFactory != null)
|
||||
{
|
||||
if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient))
|
||||
{
|
||||
// m_log.WarnFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name);
|
||||
m_controllingClient.SendAppearance(
|
||||
m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes());
|
||||
SendAppearanceToAgent(this);
|
||||
|
||||
// If the avatars baked textures are all in the cache, then we have a
|
||||
// complete appearance... send it out, if not, then we'll send it when
|
||||
// the avatar finishes updating its appearance
|
||||
SendAppearanceToAllOtherAgents();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name);
|
||||
}
|
||||
|
||||
SendInitialFullUpdateToAllClients();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Send this agent's avatar data to all other root and child agents in the scene
|
||||
/// This agent must be root. This avatar will receive its own update.
|
||||
/// </summary>
|
||||
public void SendAppearanceToAllOtherAgents()
|
||||
public void SendAvatarDataToAllAgents()
|
||||
{
|
||||
// DEBUG ON
|
||||
// m_log.WarnFormat("[SCENEPRESENCE]: Send appearance from {0} to all other agents", m_uuid);
|
||||
// DEBUG OFF
|
||||
// only send update from root agents to other clients; children are only "listening posts"
|
||||
if (IsChildAgent)
|
||||
{
|
||||
m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent");
|
||||
return;
|
||||
}
|
||||
|
||||
m_perfMonMS = Util.EnvironmentTickCount();
|
||||
|
||||
int count = 0;
|
||||
m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
|
||||
{
|
||||
if (scenePresence.UUID != UUID)
|
||||
{
|
||||
SendAppearanceToOtherAgent(scenePresence);
|
||||
}
|
||||
SendAvatarDataToAgent(scenePresence);
|
||||
count++;
|
||||
});
|
||||
|
||||
m_scene.StatsReporter.AddAgentUpdates(count);
|
||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send appearance data to an agent that isn't this one.
|
||||
/// Send avatar data for all other root agents to this agent, this agent
|
||||
/// can be either a child or root
|
||||
/// </summary>
|
||||
public void SendOtherAgentsAvatarDataToMe()
|
||||
{
|
||||
m_perfMonMS = Util.EnvironmentTickCount();
|
||||
|
||||
int count = 0;
|
||||
m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
|
||||
{
|
||||
// only send information about root agents
|
||||
if (scenePresence.IsChildAgent)
|
||||
return;
|
||||
|
||||
// only send information about other root agents
|
||||
if (scenePresence.UUID == UUID)
|
||||
return;
|
||||
|
||||
scenePresence.SendAvatarDataToAgent(this);
|
||||
count++;
|
||||
});
|
||||
|
||||
m_scene.StatsReporter.AddAgentUpdates(count);
|
||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send avatar data to an agent.
|
||||
/// </summary>
|
||||
/// <param name="avatar"></param>
|
||||
public void SendAppearanceToOtherAgent(ScenePresence avatar)
|
||||
private void SendAvatarDataToAgent(ScenePresence avatar)
|
||||
{
|
||||
if (LocalId == avatar.LocalId)
|
||||
// m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
|
||||
|
||||
avatar.ControllingClient.SendAvatarDataImmediate(this);
|
||||
Animator.SendAnimPackToClient(avatar.ControllingClient);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send this agent's appearance to all other root and child agents in the scene
|
||||
/// This agent must be root.
|
||||
/// </summary>
|
||||
public void SendAppearanceToAllOtherAgents()
|
||||
{
|
||||
// only send update from root agents to other clients; children are only "listening posts"
|
||||
if (IsChildAgent)
|
||||
{
|
||||
m_log.WarnFormat("[SCENE PRESENCE]: An agent is attempting to send appearance data to itself; {0}", UUID);
|
||||
m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent");
|
||||
return;
|
||||
}
|
||||
|
||||
// DEBUG ON
|
||||
m_perfMonMS = Util.EnvironmentTickCount();
|
||||
|
||||
int count = 0;
|
||||
m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
|
||||
{
|
||||
if (scenePresence.UUID == UUID)
|
||||
return;
|
||||
|
||||
SendAppearanceToAgent(scenePresence);
|
||||
count++;
|
||||
});
|
||||
|
||||
m_scene.StatsReporter.AddAgentUpdates(count);
|
||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send appearance from all other root agents to this agent. this agent
|
||||
/// can be either root or child
|
||||
/// </summary>
|
||||
public void SendOtherAgentsAppearanceToMe()
|
||||
{
|
||||
m_perfMonMS = Util.EnvironmentTickCount();
|
||||
|
||||
int count = 0;
|
||||
m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
|
||||
{
|
||||
// only send information about root agents
|
||||
if (scenePresence.IsChildAgent)
|
||||
return;
|
||||
|
||||
// only send information about other root agents
|
||||
if (scenePresence.UUID == UUID)
|
||||
return;
|
||||
|
||||
scenePresence.SendAppearanceToAgent(this);
|
||||
count++;
|
||||
});
|
||||
|
||||
m_scene.StatsReporter.AddAgentUpdates(count);
|
||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send appearance data to an agent.
|
||||
/// </summary>
|
||||
/// <param name="avatar"></param>
|
||||
private void SendAppearanceToAgent(ScenePresence avatar)
|
||||
{
|
||||
// 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());
|
||||
|
@ -3050,9 +3056,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public void CopyFrom(AgentData cAgent)
|
||||
{
|
||||
// DEBUG ON
|
||||
m_log.ErrorFormat("[SCENEPRESENCE] CALLING COPYFROM");
|
||||
// DEBUG OFF
|
||||
m_originRegionID = cAgent.RegionID;
|
||||
|
||||
m_callbackURI = cAgent.CallbackURI;
|
||||
|
|
|
@ -1173,10 +1173,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
|||
presence = scene.GetScenePresence(AgentID);
|
||||
if (presence != null)
|
||||
{
|
||||
presence.Grouptitle = Title;
|
||||
if (presence.Grouptitle != Title)
|
||||
{
|
||||
presence.Grouptitle = Title;
|
||||
|
||||
// FixMe: Ter suggests a "Schedule" method that I can't find.
|
||||
presence.SendFullUpdateToAllClients();
|
||||
if (! presence.IsChildAgent)
|
||||
presence.SendAvatarDataToAllAgents();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue