Adding appearance and animations

dsg
Dan Lake 2010-05-18 09:05:13 -07:00
parent 2283b85bcf
commit 82a71fb7e2
20 changed files with 222 additions and 102 deletions

View File

@ -577,6 +577,7 @@ namespace OpenSim.Client.MXP.ClientStack
public event BakeTerrain OnBakeTerrain; public event BakeTerrain OnBakeTerrain;
public event EstateChangeInfo OnEstateChangeInfo; public event EstateChangeInfo OnEstateChangeInfo;
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event SetAppearanceRaw OnSetAppearanceRaw;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv; public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;

View File

@ -223,6 +223,7 @@ namespace OpenSim.Client.Sirikata.ClientStack
public event BakeTerrain OnBakeTerrain; public event BakeTerrain OnBakeTerrain;
public event EstateChangeInfo OnEstateChangeInfo; public event EstateChangeInfo OnEstateChangeInfo;
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event SetAppearanceRaw OnSetAppearanceRaw;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv; public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;

View File

@ -226,6 +226,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
public event BakeTerrain OnBakeTerrain = delegate { }; public event BakeTerrain OnBakeTerrain = delegate { };
public event EstateChangeInfo OnEstateChangeInfo = delegate { }; public event EstateChangeInfo OnEstateChangeInfo = delegate { };
public event SetAppearance OnSetAppearance = delegate { }; public event SetAppearance OnSetAppearance = delegate { };
public event SetAppearanceRaw OnSetAppearanceRaw = delegate { };
public event AvatarNowWearing OnAvatarNowWearing = delegate { }; public event AvatarNowWearing OnAvatarNowWearing = delegate { };
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv = delegate { return new UUID(); }; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv = delegate { return new UUID(); };
public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv = delegate { }; public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv = delegate { };

View File

@ -382,6 +382,8 @@ namespace OpenSim.Framework
m_texture = textureEntry; m_texture = textureEntry;
if (visualParams != null) if (visualParams != null)
m_visualparams = visualParams; m_visualparams = visualParams;
if (m_visualparams == null)
return;
m_avatarHeight = 1.23077f // Shortest possible avatar height m_avatarHeight = 1.23077f // Shortest possible avatar height
+ 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height

View File

@ -67,6 +67,7 @@ namespace OpenSim.Framework
public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes);
public delegate void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams); public delegate void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams);
public delegate void SetAppearanceRaw(IClientAPI sender, UUID agentID, byte[] vp, Primitive.TextureEntry te);
public delegate void StartAnim(IClientAPI remoteClient, UUID animID); public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
@ -865,6 +866,7 @@ namespace OpenSim.Framework
event EstateChangeInfo OnEstateChangeInfo; event EstateChangeInfo OnEstateChangeInfo;
// [Obsolete("LLClientView Specific.")] // [Obsolete("LLClientView Specific.")]
event SetAppearance OnSetAppearance; event SetAppearance OnSetAppearance;
event SetAppearanceRaw OnSetAppearanceRaw;
// [Obsolete("LLClientView Specific - Replace and rename OnAvatarUpdate. Difference from SetAppearance?")] // [Obsolete("LLClientView Specific - Replace and rename OnAvatarUpdate. Difference from SetAppearance?")]
event AvatarNowWearing OnAvatarNowWearing; event AvatarNowWearing OnAvatarNowWearing;
event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;

View File

@ -120,6 +120,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event Action<IClientAPI> OnRegionHandShakeReply; public event Action<IClientAPI> OnRegionHandShakeReply;
public event GenericCall2 OnRequestWearables; public event GenericCall2 OnRequestWearables;
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event SetAppearanceRaw OnSetAppearanceRaw;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv; public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;
@ -5606,7 +5607,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion #endregion
SetAppearance handlerSetAppearance = OnSetAppearance; SetAppearance handlerSetAppearance = OnSetAppearance;
if (handlerSetAppearance != null) SetAppearanceRaw handlerSetAppearanceRaw = OnSetAppearanceRaw;
//if (handlerSetAppearance != null)
{ {
// Temporarily protect ourselves from the mantis #951 failure. // Temporarily protect ourselves from the mantis #951 failure.
// However, we could do this for several other handlers where a failure isn't terminal // However, we could do this for several other handlers where a failure isn't terminal
@ -5622,7 +5624,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (appear.ObjectData.TextureEntry.Length > 1) if (appear.ObjectData.TextureEntry.Length > 1)
te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
handlerSetAppearance(te, visualparams); if (handlerSetAppearance != null)
handlerSetAppearance(te, visualparams);
if (handlerSetAppearanceRaw != null)
handlerSetAppearanceRaw(this, AgentId, visualparams, te);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -61,6 +61,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
public event ModifyTerrain OnModifyTerrain; public event ModifyTerrain OnModifyTerrain;
public event BakeTerrain OnBakeTerrain; public event BakeTerrain OnBakeTerrain;
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event SetAppearanceRaw OnSetAppearanceRaw;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv; public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;

View File

@ -121,6 +121,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
RemoveLocalClient(kvp.Key, m_scene); RemoveLocalClient(kvp.Key, m_scene);
// Remove the agent update handler from the client // Remove the agent update handler from the client
kvp.Value.OnAgentUpdateRaw -= HandleAgentUpdateRaw; kvp.Value.OnAgentUpdateRaw -= HandleAgentUpdateRaw;
kvp.Value.OnSetAppearanceRaw -= HandleSetAppearanceRaw;
} }
} }
// Close the connection // Close the connection
@ -515,6 +516,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
// Register for interesting client events which will be forwarded to auth sim // Register for interesting client events which will be forwarded to auth sim
// These are the raw packet data blocks from the client, intercepted and sent up to the sim // These are the raw packet data blocks from the client, intercepted and sent up to the sim
client.OnAgentUpdateRaw += HandleAgentUpdateRaw; client.OnAgentUpdateRaw += HandleAgentUpdateRaw;
client.OnSetAppearanceRaw += HandleSetAppearanceRaw;
client.OnChatFromClientRaw += HandleChatFromClientRaw; client.OnChatFromClientRaw += HandleChatFromClientRaw;
} }
@ -536,6 +538,18 @@ namespace OpenSim.Region.Examples.RegionSyncModule
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AgentUpdate, agentData)); Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AgentUpdate, agentData));
} }
public void HandleSetAppearanceRaw(object sender, UUID agentID, byte[] vp, Primitive.TextureEntry te)
{
if (te != null)
{
OSDMap data = new OSDMap(2);
data["id"] = OSDUUID.FromUUID(agentID);
data["vp"] = new OSDBinary(vp);
data["te"] = te.GetOSD();
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AvatarAppearance, OSDParser.SerializeJsonString(data)));
}
}
public void HandleChatFromClientRaw(object sender, byte[] chatData) public void HandleChatFromClientRaw(object sender, byte[] chatData)
{ {
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ChatFromClient, chatData)); Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ChatFromClient, chatData));

View File

@ -288,6 +288,44 @@ namespace OpenSim.Region.Examples.RegionSyncModule
} }
return HandlerFailure(msg, "Could not deserialize JSON data."); return HandlerFailure(msg, "Could not deserialize JSON data.");
}
case RegionSyncMessage.MsgType.AvatarAppearance:
{
OSDMap data = DeserializeMessage(msg);
if (data != null)
{
UUID agentID = data["id"].AsUUID();
if (agentID != null && agentID != UUID.Zero)
{
ScenePresence presence;
if (m_scene.TryGetScenePresence(agentID, out presence))
{
string name = presence.Name;
Primitive.TextureEntry te = Primitive.TextureEntry.FromOSD(data["te"]);
byte[] vp = data["vp"].AsBinary();
byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
for (int i = 0; i < BAKE_INDICES.Length; i++)
{
int j = BAKE_INDICES[i];
Primitive.TextureEntryFace face = te.FaceTextures[j];
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
HandlerDebug(msg, "Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + name);
}
presence.SetAppearance(te, vp);
return HandlerDebug(msg, String.Format("Agent \"{0}\" ({1}) updated their appearance.", name, agentID));
}
else
{
return HandlerFailure(msg, String.Format("Agent {0} not found in the scene.", agentID));
}
}
}
return HandlerFailure(msg, "Could not deserialize JSON data.");
} }
default: default:
{ {

View File

@ -33,6 +33,8 @@ namespace OpenSim.Region.Examples.RegionSyncModule
RemovedObject, // objects RemovedObject, // objects
NewAvatar, // avatars NewAvatar, // avatars
UpdatedAvatar, // avatars UpdatedAvatar, // avatars
AnimateAvatar,
AvatarAppearance,
RemovedAvatar, // avatars RemovedAvatar, // avatars
ChatFromSim, ChatFromSim,
// BIDIR // BIDIR

View File

@ -41,6 +41,7 @@ namespace OpenSim.Region.Examples.RegionSyncModule
// The list is read most of the time and only updated when a new client manager // The list is read most of the time and only updated when a new client manager
// connects, so we just replace the list when it changes. Iterators on this // connects, so we just replace the list when it changes. Iterators on this
// list need to be able to handle if an element is shutting down. // list need to be able to handle if an element is shutting down.
private object m_clientview_lock = new object();
private HashSet<RegionSyncClientView> m_client_views = new HashSet<RegionSyncClientView>(); private HashSet<RegionSyncClientView> m_client_views = new HashSet<RegionSyncClientView>();
// Check if any of the client views are in a connected state // Check if any of the client views are in a connected state
@ -55,27 +56,36 @@ namespace OpenSim.Region.Examples.RegionSyncModule
// Add the client view to the list and increment synced client counter // Add the client view to the list and increment synced client counter
public void AddSyncedClient(RegionSyncClientView rscv) public void AddSyncedClient(RegionSyncClientView rscv)
{ {
HashSet<RegionSyncClientView> newlist = new HashSet<RegionSyncClientView>(m_client_views); lock (m_clientview_lock)
newlist.Add(rscv); {
// Threads holding the previous version of the list can keep using it since HashSet<RegionSyncClientView> currentlist = m_client_views;
// they will not hold it for long and get a new copy next time they need to iterate HashSet<RegionSyncClientView> newlist = new HashSet<RegionSyncClientView>(currentlist);
Interlocked.Exchange<HashSet<RegionSyncClientView>>(ref m_client_views, newlist); newlist.Add(rscv);
// Threads holding the previous version of the list can keep using it since
// they will not hold it for long and get a new copy next time they need to iterate
m_client_views = newlist;
}
} }
// Remove the client view from the list and decrement synced client counter // Remove the client view from the list and decrement synced client counter
public void RemoveSyncedClient(RegionSyncClientView rscv) public void RemoveSyncedClient(RegionSyncClientView rscv)
{ {
HashSet<RegionSyncClientView> newlist = new HashSet<RegionSyncClientView>(m_client_views); lock (m_clientview_lock)
newlist.Remove(rscv); {
// Threads holding the previous version of the list can keep using it since HashSet<RegionSyncClientView> currentlist = m_client_views;
// they will not hold it for long and get a new copy next time they need to iterate HashSet<RegionSyncClientView> newlist = new HashSet<RegionSyncClientView>(currentlist);
Interlocked.Exchange<HashSet<RegionSyncClientView>>(ref m_client_views, newlist); newlist.Remove(rscv);
// Threads holding the previous version of the list can keep using it since
// they will not hold it for long and get a new copy next time they need to iterate
m_client_views = newlist;
}
} }
public void ReportStats() public void ReportStats()
{ {
// We should be able to safely iterate over our reference to the list since // We should be able to safely iterate over our reference to the list since
// the only places which change it will replace it with an updated version // the only places which change it will replace it with an updated version
m_log.Error("SERVER, MSGIN, MSGOUT, BYTESIN, BYTESOUT");
foreach (RegionSyncClientView rscv in m_client_views) foreach (RegionSyncClientView rscv in m_client_views)
{ {
m_log.ErrorFormat("{0}: {1}", rscv.Description, rscv.GetStats()); m_log.ErrorFormat("{0}: {1}", rscv.Description, rscv.GetStats());
@ -160,31 +170,27 @@ namespace OpenSim.Region.Examples.RegionSyncModule
public void Broadcast(RegionSyncMessage msg) public void Broadcast(RegionSyncMessage msg)
{ {
List<RegionSyncClientView> closed = null; List<RegionSyncClientView> closed = null;
//lock (m_client_views) foreach (RegionSyncClientView client in m_client_views)
{ {
//m_log.WarnFormat("[REGION SYNC SERVER] Broadcasting {0} to all connected RegionSyncClients", msg.ToString()); // If connected, send the message.
foreach (RegionSyncClientView client in m_client_views) if (client.Connected)
{ {
// If connected, send the message. client.Send(msg);
if (client.Connected)
{
client.Send(msg);
}
// Else, remove the client view from the list
else
{
if (closed == null)
closed = new List<RegionSyncClientView>();
closed.Add(client);
}
} }
if (closed != null) // Else, remove the client view from the list
else
{ {
foreach (RegionSyncClientView rscv in closed) if (closed == null)
RemoveSyncedClient(rscv); closed = new List<RegionSyncClientView>();
//m_client_views.Remove(rscv); closed.Add(client);
} }
} }
if (closed != null)
{
foreach (RegionSyncClientView rscv in closed)
RemoveSyncedClient(rscv);
//m_client_views.Remove(rscv);
}
} }
} }
} }

View File

@ -62,6 +62,7 @@ namespace OpenSim.Region.Examples.SimpleModule
public event ModifyTerrain OnModifyTerrain; public event ModifyTerrain OnModifyTerrain;
public event BakeTerrain OnBakeTerrain; public event BakeTerrain OnBakeTerrain;
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event SetAppearanceRaw OnSetAppearanceRaw;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv; public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;

View File

@ -724,6 +724,10 @@ namespace OpenSim.Region.Framework.Scenes
// TODO: Change default to true once the feature is supported // TODO: Change default to true once the feature is supported
m_usePreJump = startupConfig.GetBoolean("enableprejump", false); m_usePreJump = startupConfig.GetBoolean("enableprejump", false);
m_maxNonphys = 256f;
m_maxPhys = 256f;
/*
m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
if (RegionInfo.NonphysPrimMax > 0) if (RegionInfo.NonphysPrimMax > 0)
{ {
@ -736,6 +740,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_maxPhys = RegionInfo.PhysPrimMax; m_maxPhys = RegionInfo.PhysPrimMax;
} }
*/
// Here, if clamping is requested in either global or // Here, if clamping is requested in either global or
// local config, it will be used // local config, it will be used
@ -1595,7 +1600,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
List<UUID> resultIds = new List<UUID>(); List<UUID> resultIds = new List<UUID>();
List<Vector3> resultLocations = new List<Vector3>(); List<Vector3> resultLocations = new List<Vector3>();
/*
ForEachScenePresence(delegate(ScenePresence sp) ForEachScenePresence(delegate(ScenePresence sp)
{ {
if (sp.IsChildAgent) if (sp.IsChildAgent)
@ -1603,9 +1608,10 @@ namespace OpenSim.Region.Framework.Scenes
resultIds.Add(sp.UUID); resultIds.Add(sp.UUID);
resultLocations.Add(sp.AbsolutePosition); resultLocations.Add(sp.AbsolutePosition);
}); });
*/
ids = resultIds; ids = resultIds;
locations = resultLocations; locations = resultLocations;
/* /*
if (sp.ParentID != 0) if (sp.ParentID != 0)
{ {
@ -2704,6 +2710,10 @@ namespace OpenSim.Region.Framework.Scenes
GetAvatarAppearance(client, out appearance); GetAvatarAppearance(client, out appearance);
presence.Appearance = appearance; presence.Appearance = appearance;
// REGION SYNC
// The owner is not being set properly when there is no circuit. Hmmm
presence.Appearance.Owner = presence.UUID;
presence.initializeScenePresence(client, RegionInfo, this); presence.initializeScenePresence(client, RegionInfo, this);
m_sceneGraph.AddScenePresence(presence); m_sceneGraph.AddScenePresence(presence);

View File

@ -68,7 +68,8 @@ namespace OpenSim.Region.Framework.Scenes
#region Fields #region Fields
protected Dictionary<UUID, ScenePresence> m_scenePresences = new Dictionary<UUID, ScenePresence>(); protected object m_presenceLock = new object();
protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>();
protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0]; protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0];
// SceneObjects is not currently populated or used. // SceneObjects is not currently populated or used.
@ -132,10 +133,12 @@ namespace OpenSim.Region.Framework.Scenes
protected internal void Close() protected internal void Close()
{ {
lock (m_scenePresences) lock (m_presenceLock)
{ {
m_scenePresences.Clear(); Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
m_scenePresenceArray = new ScenePresence[0]; ScenePresence[] newarray = new ScenePresence[0];
m_scenePresenceMap = newmap;
m_scenePresenceArray = newarray;
} }
lock (m_dictionary_lock) lock (m_dictionary_lock)
@ -518,34 +521,39 @@ namespace OpenSim.Region.Framework.Scenes
Entities[presence.UUID] = presence; Entities[presence.UUID] = presence;
lock (m_scenePresences) lock (m_presenceLock)
{ {
if (!m_scenePresences.ContainsKey(presence.UUID)) // We are going to swap the map and array references with modified copies
Dictionary<UUID, ScenePresence> newmap;
ScenePresence[] newarray;
if (m_scenePresenceMap.ContainsKey(presence.UUID))
{ {
m_scenePresences.Add(presence.UUID, presence); // copy the map and update the presence reference
newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
// Create a new array of ScenePresence references m_scenePresenceMap[presence.UUID] = presence;
int oldLength = m_scenePresenceArray.Length; // copy the array and update the presence reference
ScenePresence[] newArray = new ScenePresence[oldLength + 1]; newarray = new ScenePresence[m_scenePresenceArray.Length];
Array.Copy(m_scenePresenceArray, newArray, oldLength); for(int i = 0; i < m_scenePresenceArray.Length; ++i)
newArray[oldLength] = presence; {
m_scenePresenceArray = newArray; if(m_scenePresenceArray[i].UUID == presence.UUID)
newarray[i] = presence;
else
newarray[i] = m_scenePresenceArray[i];
}
} }
else else
{ {
m_scenePresences[presence.UUID] = presence; // copy the map and add the new presence reference
newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
// Do a linear search through the array of ScenePresence references newmap[presence.UUID] = presence;
// and update the modified entry // Copy the array and add the new presence reference
for (int i = 0; i < m_scenePresenceArray.Length; i++) int oldLength = m_scenePresenceArray.Length;
{ newarray = new ScenePresence[oldLength+1];
if (m_scenePresenceArray[i].UUID == presence.UUID) Array.Copy(m_scenePresenceArray, newarray, oldLength);
{ newarray[oldLength] = presence;
m_scenePresenceArray[i] = presence;
break;
}
}
} }
m_scenePresenceMap = newmap;
m_scenePresenceArray = newarray;
} }
} }
@ -561,25 +569,30 @@ namespace OpenSim.Region.Framework.Scenes
agentID); agentID);
} }
lock (m_scenePresences) lock (m_presenceLock)
{ {
if (m_scenePresences.Remove(agentID)) // Copy the map
Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
// Remove the presence reference from the dictionary
if (newmap.Remove(agentID))
{ {
// Copy all of the elements from the previous array // Copy all of the elements from the previous array
// into the new array except the removed element // into the new array except the removed element
int oldLength = m_scenePresenceArray.Length; int oldLength = m_scenePresenceArray.Length;
ScenePresence[] newArray = new ScenePresence[oldLength - 1]; ScenePresence[] newarray = new ScenePresence[oldLength - 1];
int j = 0; int j = 0;
for (int i = 0; i < m_scenePresenceArray.Length; i++) for (int i = 0; i < oldLength; ++i)
{ {
ScenePresence presence = m_scenePresenceArray[i]; ScenePresence presence = m_scenePresenceArray[i];
if (presence.UUID != agentID) if (presence.UUID != agentID)
{ {
newArray[j] = presence; newarray[j] = presence;
++j; ++j;
} }
} }
m_scenePresenceArray = newArray; // Swap out the dictionary and list with new references
m_scenePresenceMap = newmap;
m_scenePresenceArray = newarray;
} }
else else
{ {
@ -698,16 +711,15 @@ namespace OpenSim.Region.Framework.Scenes
} }
/// <summary> /// <summary>
/// Request a copy of m_scenePresences in this World /// Get a reference to the scene presence list. Changes to the list will be done in a copy
/// There is no guarantee that presences will remain in the scene after the list is returned. /// There is no guarantee that presences will remain in the scene after the list is returned.
/// This list should remain private to SceneGraph. Callers wishing to iterate should instead /// This list should remain private to SceneGraph. Callers wishing to iterate should instead
/// pass a delegate to ForEachScenePresence. /// pass a delegate to ForEachScenePresence.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private List<ScenePresence> GetScenePresences() private ScenePresence[] GetScenePresences()
{ {
lock (m_scenePresences) return m_scenePresenceArray;
return new List<ScenePresence>(m_scenePresenceArray);
} }
/// <summary> /// <summary>
@ -717,12 +729,10 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>null if the presence was not found</returns> /// <returns>null if the presence was not found</returns>
protected internal ScenePresence GetScenePresence(UUID agentID) protected internal ScenePresence GetScenePresence(UUID agentID)
{ {
ScenePresence sp; Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap;
lock (m_scenePresences) ScenePresence presence;
{ presences.TryGetValue(agentID, out presence);
m_scenePresences.TryGetValue(agentID, out sp); return presence;
}
return sp;
} }
/// <summary> /// <summary>
@ -733,10 +743,11 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>null if the presence was not found</returns> /// <returns>null if the presence was not found</returns>
protected internal ScenePresence GetScenePresence(string firstName, string lastName) protected internal ScenePresence GetScenePresence(string firstName, string lastName)
{ {
foreach (ScenePresence presence in GetScenePresences()) ScenePresence[] presences = GetScenePresences();
for(int i = 0; i < presences.Length; ++i)
{ {
if (presence.Firstname == firstName && presence.Lastname == lastName) if (presences[i].Firstname == firstName && presences[i].Lastname == lastName)
return presence; return presences[i];
} }
return null; return null;
} }
@ -748,29 +759,31 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>null if the presence was not found</returns> /// <returns>null if the presence was not found</returns>
protected internal ScenePresence GetScenePresence(uint localID) protected internal ScenePresence GetScenePresence(uint localID)
{ {
foreach (ScenePresence presence in GetScenePresences()) ScenePresence[] presences = GetScenePresences();
if (presence.LocalId == localID) for (int i = 0; i < presences.Length; ++i)
return presence; {
if (presences[i].LocalId == localID)
return presences[i];
}
return null; return null;
} }
protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar)
{ {
lock (m_scenePresences) Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap;
{ presences.TryGetValue(agentID, out avatar);
m_scenePresences.TryGetValue(agentID, out avatar);
}
return (avatar != null); return (avatar != null);
} }
protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar) protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar)
{ {
avatar = null; avatar = null;
foreach (ScenePresence presence in GetScenePresences()) ScenePresence[] presences = GetScenePresences();
for(int i = 0; i < presences.Length; ++i )
{ {
if (String.Compare(name, presence.ControllingClient.Name, true) == 0) if (String.Compare(name, presences[i].ControllingClient.Name, true) == 0)
{ {
avatar = presence; avatar = presences[i];
break; break;
} }
} }
@ -1036,12 +1049,14 @@ namespace OpenSim.Region.Framework.Scenes
}); });
Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction); Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction);
*/ */
// For now, perform actiona serially // For now, perform actions serially
foreach (ScenePresence sp in GetScenePresences()) ScenePresence[] presences = GetScenePresences();
for(int i = 0; i < presences.Length; ++i)
{ {
ScenePresence presence = presences[i];
try try
{ {
action(sp); action(presence);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -77,7 +77,7 @@ namespace OpenSim.Region.Framework.Scenes
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 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 static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
@ -672,6 +672,11 @@ namespace OpenSim.Region.Framework.Scenes
m_sendCourseLocationsMethod = SendCoarseLocationsDefault; m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
CreateSceneViewer(); CreateSceneViewer();
m_animator = new ScenePresenceAnimator(this); m_animator = new ScenePresenceAnimator(this);
Primitive.TextureEntry te = AvatarAppearance.GetDefaultTexture();
byte[] vp = AvatarAppearance.GetDefaultVisualParams();
m_appearance = new AvatarAppearance(UUID);
m_appearance.SetAppearance(te, vp);
} }
private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
@ -707,7 +712,7 @@ namespace OpenSim.Region.Framework.Scenes
AdjustKnownSeeds(); AdjustKnownSeeds();
// TODO: I think, this won't send anything, as we are still a child here... // TODO: I think, this won't send anything, as we are still a child here...
Animator.TrySetMovementAnimation("STAND"); Animator.TrySetMovementAnimation("STAND");
// we created a new ScenePresence (a new child agent) in a fresh region. // we created a new ScenePresence (a new child agent) in a fresh region.
// Request info about all the (root) agents in this region // Request info about all the (root) agents in this region
@ -722,13 +727,13 @@ namespace OpenSim.Region.Framework.Scenes
AvatarWearable[] wearables) AvatarWearable[] wearables)
: this(client, world, reginfo) : this(client, world, reginfo)
{ {
m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); //m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams);
} }
public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
: this(client, world, reginfo) : this(client, world, reginfo)
{ {
m_appearance = appearance; //m_appearance = appearance;
} }
private void CreateSceneViewer() private void CreateSceneViewer()
@ -738,14 +743,17 @@ namespace OpenSim.Region.Framework.Scenes
public void RegisterToEvents() public void RegisterToEvents()
{ {
m_controllingClient.OnRequestWearables += SendWearables; // REGION SYNC
if (!m_scene.IsSyncedClient())
{
m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
}
m_controllingClient.OnSetAppearance += SetAppearance; m_controllingClient.OnSetAppearance += SetAppearance;
m_controllingClient.OnRequestWearables += SendWearables;
m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
//m_controllingClient.OnCompleteMovementToRegion += SendInitialData; //m_controllingClient.OnCompleteMovementToRegion += SendInitialData;
// REGION SYNC
if(!m_scene.IsSyncedClient())
m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit; m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit;
m_controllingClient.OnAgentSit += HandleAgentSit; m_controllingClient.OnAgentSit += HandleAgentSit;
m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
@ -2443,11 +2451,14 @@ namespace OpenSim.Region.Framework.Scenes
public void SendCoarseLocations() public void SendCoarseLocations()
{ {
SendCoarseLocationsDefault(m_scene.RegionInfo.originRegionID, this);
/*
SendCourseLocationsMethod d = m_sendCourseLocationsMethod; SendCourseLocationsMethod d = m_sendCourseLocationsMethod;
if (d != null) if (d != null)
{ {
d.Invoke(m_scene.RegionInfo.originRegionID, this); d.Invoke(m_scene.RegionInfo.originRegionID, this);
} }
* */
} }
public void SetSendCourseLocationMethod(SendCourseLocationsMethod d) public void SetSendCourseLocationMethod(SendCourseLocationsMethod d)
@ -2463,7 +2474,9 @@ namespace OpenSim.Region.Framework.Scenes
List<Vector3> CoarseLocations = new List<Vector3>(); List<Vector3> CoarseLocations = new List<Vector3>();
// This is not cheap to compile this list of locations. // This is not cheap to compile this list of locations.
// It should ideally be done once and then sent to every client rather than compiled for each client // It should ideally be done once and then sent to every client rather than compiled for each client
m_scene.GetCoarseLocations(out AvatarUUIDs, out CoarseLocations); //m_scene.GetCoarseLocations(out AvatarUUIDs, out CoarseLocations);
AvatarUUIDs.Add(UUID);
CoarseLocations.Add(AbsolutePosition);
m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations); m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations);
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
} }
@ -2602,6 +2615,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="avatar"></param> /// <param name="avatar"></param>
public void SendAppearanceToOtherAgent(ScenePresence avatar) public void SendAppearanceToOtherAgent(ScenePresence avatar)
{ {
//m_log.WarnFormat("{0} sending appearance to {1}, owner={2}", UUID, avatar.UUID, m_appearance.Owner);
m_appearance.Owner = UUID;
avatar.ControllingClient.SendAppearance( avatar.ControllingClient.SendAppearance(
m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
} }

View File

@ -659,6 +659,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public event BakeTerrain OnBakeTerrain; public event BakeTerrain OnBakeTerrain;
public event EstateChangeInfo OnEstateChangeInfo; public event EstateChangeInfo OnEstateChangeInfo;
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event SetAppearanceRaw OnSetAppearanceRaw;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv; public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;

View File

@ -168,6 +168,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public event RezObject OnRezObject; public event RezObject OnRezObject;
public event ModifyTerrain OnModifyTerrain; public event ModifyTerrain OnModifyTerrain;
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event SetAppearanceRaw OnSetAppearanceRaw;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv; public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;

View File

@ -204,6 +204,7 @@ namespace OpenSim.Services.Connectors
public string Store(AssetBase asset) public string Store(AssetBase asset)
{ {
/*
if (asset.Temporary || asset.Local) if (asset.Temporary || asset.Local)
{ {
if (m_Cache != null) if (m_Cache != null)
@ -211,6 +212,8 @@ namespace OpenSim.Services.Connectors
return asset.ID; return asset.ID;
} }
* */
m_Cache.Cache(asset);
string uri = m_ServerURI + "/assets/"; string uri = m_ServerURI + "/assets/";

View File

@ -257,7 +257,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
} }
// Local asset handling // Local asset handling
if (asset.Local) /*if (asset.Local)
{ {
if (!storedInCache) if (!storedInCache)
{ {
@ -267,7 +267,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
} }
return asset.ID; return asset.ID;
} }*/
// Distinguish public and private assets // Distinguish public and private assets
bool isPublic = true; bool isPublic = true;

View File

@ -74,6 +74,7 @@ namespace OpenSim.Tests.Common.Mock
public event ModifyTerrain OnModifyTerrain; public event ModifyTerrain OnModifyTerrain;
public event BakeTerrain OnBakeTerrain; public event BakeTerrain OnBakeTerrain;
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event SetAppearanceRaw OnSetAppearanceRaw;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv; public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;