In SceneGraph.LinkObjects, call RegionSyncModule.SendLinkObject before parentGroup.LinkToGroup is called,
so that the actors who receive LinkObject message will get it before the soft-delete messages of the linked-in parts.dsg
parent
ea2dc04bac
commit
4860eba0ba
|
@ -206,6 +206,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SendSceneUpdates put each update into an outgoing queue of each SyncConnector
|
||||||
public void SendSceneUpdates()
|
public void SendSceneUpdates()
|
||||||
{
|
{
|
||||||
// Existing value of 1 indicates that updates are currently being sent so skip updates this pass
|
// Existing value of 1 indicates that updates are currently being sent so skip updates this pass
|
||||||
|
@ -310,6 +311,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//The following Sendxxx calls,send out a message immediately, w/o putting it in the SyncConnector's outgoing queue.
|
||||||
|
//May need some optimization there on the priorities.
|
||||||
|
|
||||||
public void SendTerrainUpdates(string lastUpdateActorID)
|
public void SendTerrainUpdates(string lastUpdateActorID)
|
||||||
{
|
{
|
||||||
if(m_isSyncRelay || m_actorID.Equals(lastUpdateActorID))
|
if(m_isSyncRelay || m_actorID.Equals(lastUpdateActorID))
|
||||||
|
@ -320,6 +324,114 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send a sync message to remove the given objects in all connected actors.
|
||||||
|
/// UUID is used for identified a removed object. This function now should
|
||||||
|
/// only be triggered by an object removal that is initiated locally.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sog"></param>
|
||||||
|
//private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog)
|
||||||
|
public void SendDeleteObject(SceneObjectGroup sog, bool softDelete)
|
||||||
|
{
|
||||||
|
//m_log.DebugFormat("RegionSyncModule_OnObjectBeingRemovedFromScene called at time {0}:{1}:{2}", DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond);
|
||||||
|
|
||||||
|
//Only send the message out if this is a relay node for sync messages, or this actor caused deleting the object
|
||||||
|
//if (m_isSyncRelay || CheckObjectForSendingUpdate(sog))
|
||||||
|
|
||||||
|
|
||||||
|
OSDMap data = new OSDMap();
|
||||||
|
//data["regionHandle"] = OSD.FromULong(regionHandle);
|
||||||
|
//data["localID"] = OSD.FromUInteger(sog.LocalId);
|
||||||
|
data["UUID"] = OSD.FromUUID(sog.UUID);
|
||||||
|
data["actorID"] = OSD.FromString(m_actorID);
|
||||||
|
data["softDelete"] = OSD.FromBoolean(softDelete);
|
||||||
|
|
||||||
|
SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data));
|
||||||
|
SendObjectUpdateToRelevantSyncConnectors(sog, rsm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SendLinkObject(SceneObjectPart root, List<SceneObjectPart> children)
|
||||||
|
{
|
||||||
|
if(children.Count==0) return;
|
||||||
|
|
||||||
|
OSDMap data = new OSDMap();
|
||||||
|
//string sogxml = SceneObjectSerializer.ToXml2Format(linkedGroup);
|
||||||
|
//data["linkedGroup"]=OSD.FromString(sogxml);
|
||||||
|
data["root"] = OSD.FromUUID(root.UUID);
|
||||||
|
data["partCount"] = OSD.FromInteger(children.Count);
|
||||||
|
data["actorID"] = OSD.FromString(m_actorID);
|
||||||
|
int partNum = 0;
|
||||||
|
foreach(SceneObjectPart part in children){
|
||||||
|
string partTempID = "part"+partNum;
|
||||||
|
data[partTempID] = OSD.FromUUID(part.UUID);
|
||||||
|
partNum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.LinkObject, OSDParser.SerializeJsonString(data));
|
||||||
|
SendObjectUpdateToRelevantSyncConnectors(root.ParentGroup, rsm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs)
|
||||||
|
{
|
||||||
|
switch (ev)
|
||||||
|
{
|
||||||
|
case EventManager.EventNames.NewScript:
|
||||||
|
if (evArgs.Length < 3)
|
||||||
|
{
|
||||||
|
m_log.Error(LogHeader + " not enough event args for NewScript");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OnLocalNewScript((UUID)evArgs[0], (SceneObjectPart)evArgs[1], (UUID)evArgs[2]);
|
||||||
|
return;
|
||||||
|
case EventManager.EventNames.UpdateScript:
|
||||||
|
if (evArgs.Length < 5)
|
||||||
|
{
|
||||||
|
m_log.Error(LogHeader + " not enough event args for UpdateScript");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OnLocalUpdateScript((UUID)evArgs[0], (UUID)evArgs[1], (UUID)evArgs[2], (bool)evArgs[3], (UUID)evArgs[4]);
|
||||||
|
return;
|
||||||
|
case EventManager.EventNames.ScriptReset:
|
||||||
|
if (evArgs.Length < 2)
|
||||||
|
{
|
||||||
|
m_log.Error(LogHeader + " not enough event args for ScriptReset");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OnLocalScriptReset((uint)evArgs[0], (UUID)evArgs[1]);
|
||||||
|
return;
|
||||||
|
case EventManager.EventNames.ChatFromClient:
|
||||||
|
if (evArgs.Length < 2)
|
||||||
|
{
|
||||||
|
m_log.Error(LogHeader + " not enough event args for ChatFromClient");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OnLocalChatFromClient(evArgs[0], (OSChatMessage)evArgs[1]);
|
||||||
|
return;
|
||||||
|
case EventManager.EventNames.ChatFromWorld:
|
||||||
|
if (evArgs.Length < 2)
|
||||||
|
{
|
||||||
|
m_log.Error(LogHeader + " not enough event args for ChatFromWorld");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OnLocalChatFromWorld(evArgs[0], (OSChatMessage)evArgs[1]);
|
||||||
|
return;
|
||||||
|
case EventManager.EventNames.ObjectGrab:
|
||||||
|
OnLocalGrabObject((uint)evArgs[0], (uint)evArgs[1], (Vector3)evArgs[2], (IClientAPI)evArgs[3], (SurfaceTouchEventArgs)evArgs[4]);
|
||||||
|
return;
|
||||||
|
case EventManager.EventNames.ObjectGrabbing:
|
||||||
|
OnLocalObjectGrabbing((uint)evArgs[0], (uint)evArgs[1], (Vector3)evArgs[2], (IClientAPI)evArgs[3], (SurfaceTouchEventArgs)evArgs[4]);
|
||||||
|
return;
|
||||||
|
case EventManager.EventNames.ObjectDeGrab:
|
||||||
|
OnLocalDeGrabObject((uint)evArgs[0], (uint)evArgs[1], (IClientAPI)evArgs[2], (SurfaceTouchEventArgs)evArgs[3]);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion //IRegionSyncModule
|
#endregion //IRegionSyncModule
|
||||||
|
|
||||||
#region ICommandableModule Members
|
#region ICommandableModule Members
|
||||||
|
@ -855,7 +967,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
/// The handler for processing incoming sync messages.
|
/// The handler for processing incoming sync messages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="msg"></param>
|
/// <param name="msg"></param>
|
||||||
public void HandleIncomingMessage(SymmetricSyncMessage msg)
|
public void HandleIncomingMessage(SymmetricSyncMessage msg, string senderActorID)
|
||||||
{
|
{
|
||||||
switch (msg.Type)
|
switch (msg.Type)
|
||||||
{
|
{
|
||||||
|
@ -903,6 +1015,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
HandleRemovedObject(msg);
|
HandleRemovedObject(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case SymmetricSyncMessage.MsgType.LinkObject:
|
||||||
|
{
|
||||||
|
HandleLinkObject(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
//EVENTS PROCESSING
|
//EVENTS PROCESSING
|
||||||
case SymmetricSyncMessage.MsgType.NewScript:
|
case SymmetricSyncMessage.MsgType.NewScript:
|
||||||
case SymmetricSyncMessage.MsgType.UpdateScript:
|
case SymmetricSyncMessage.MsgType.UpdateScript:
|
||||||
|
@ -1059,6 +1176,38 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleLinkObject(SymmetricSyncMessage msg)
|
||||||
|
{
|
||||||
|
// Get the data from message and error check
|
||||||
|
OSDMap data = DeserializeMessage(msg);
|
||||||
|
if (data == null)
|
||||||
|
{
|
||||||
|
SymmetricSyncMessage.HandleError(LogHeader, msg, "Could not deserialize JSON data.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string init_actorID = data["actorID"].AsString();
|
||||||
|
//string sogxml = data["linkedGroup"].AsString();
|
||||||
|
//SceneObjectGroup linkedGroup = SceneObjectSerializer.FromXml2Format(sogxml);
|
||||||
|
UUID rootID = data["root"].AsUUID();
|
||||||
|
int partCount = data["partCount"].AsInteger();
|
||||||
|
List<UUID> childrenIDs = new List<UUID>();
|
||||||
|
|
||||||
|
for (int i = 0; i < partCount; i++)
|
||||||
|
{
|
||||||
|
string partTempID = "part" + i;
|
||||||
|
childrenIDs.Add(data[partTempID].AsUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scene.LinkObjectBySync(rootID, childrenIDs);
|
||||||
|
|
||||||
|
//if this is a relay node, forwards the event
|
||||||
|
if (m_isSyncRelay)
|
||||||
|
{
|
||||||
|
SendSceneEventToRelevantSyncConnectors(init_actorID, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The common actions for handling remote events (event initiated at other actors and propogated here)
|
/// The common actions for handling remote events (event initiated at other actors and propogated here)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1346,89 +1495,6 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
m_scene.EventManager.TriggerObjectDeGrabLocally(part.LocalId, originalID, remoteClinet, surfaceArgs);
|
m_scene.EventManager.TriggerObjectDeGrabLocally(part.LocalId, originalID, remoteClinet, surfaceArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Send a sync message to remove the given objects in all connected actors.
|
|
||||||
/// UUID is used for identified a removed object. This function now should
|
|
||||||
/// only be triggered by an object removal that is initiated locally.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sog"></param>
|
|
||||||
//private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog)
|
|
||||||
public void SendDeleteObject(SceneObjectGroup sog, bool softDelete)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("RegionSyncModule_OnObjectBeingRemovedFromScene called at time {0}:{1}:{2}", DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond);
|
|
||||||
|
|
||||||
//Only send the message out if this is a relay node for sync messages, or this actor caused deleting the object
|
|
||||||
//if (m_isSyncRelay || CheckObjectForSendingUpdate(sog))
|
|
||||||
|
|
||||||
|
|
||||||
OSDMap data = new OSDMap(1);
|
|
||||||
//data["regionHandle"] = OSD.FromULong(regionHandle);
|
|
||||||
//data["localID"] = OSD.FromUInteger(sog.LocalId);
|
|
||||||
data["UUID"] = OSD.FromUUID(sog.UUID);
|
|
||||||
data["actorID"] = OSD.FromString(m_actorID);
|
|
||||||
data["softDelete"] = OSD.FromBoolean(softDelete);
|
|
||||||
|
|
||||||
SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data));
|
|
||||||
SendObjectUpdateToRelevantSyncConnectors(sog, rsm);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs)
|
|
||||||
{
|
|
||||||
switch (ev)
|
|
||||||
{
|
|
||||||
case EventManager.EventNames.NewScript:
|
|
||||||
if (evArgs.Length < 3)
|
|
||||||
{
|
|
||||||
m_log.Error(LogHeader + " not enough event args for NewScript");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OnLocalNewScript((UUID)evArgs[0], (SceneObjectPart)evArgs[1], (UUID)evArgs[2]);
|
|
||||||
return;
|
|
||||||
case EventManager.EventNames.UpdateScript:
|
|
||||||
if (evArgs.Length < 5)
|
|
||||||
{
|
|
||||||
m_log.Error(LogHeader + " not enough event args for UpdateScript");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OnLocalUpdateScript((UUID)evArgs[0], (UUID)evArgs[1], (UUID)evArgs[2], (bool)evArgs[3], (UUID)evArgs[4]);
|
|
||||||
return;
|
|
||||||
case EventManager.EventNames.ScriptReset:
|
|
||||||
if (evArgs.Length < 2)
|
|
||||||
{
|
|
||||||
m_log.Error(LogHeader + " not enough event args for ScriptReset");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OnLocalScriptReset((uint)evArgs[0], (UUID)evArgs[1]);
|
|
||||||
return;
|
|
||||||
case EventManager.EventNames.ChatFromClient:
|
|
||||||
if (evArgs.Length < 2)
|
|
||||||
{
|
|
||||||
m_log.Error(LogHeader + " not enough event args for ChatFromClient");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OnLocalChatFromClient(evArgs[0], (OSChatMessage)evArgs[1]);
|
|
||||||
return;
|
|
||||||
case EventManager.EventNames.ChatFromWorld:
|
|
||||||
if (evArgs.Length < 2)
|
|
||||||
{
|
|
||||||
m_log.Error(LogHeader + " not enough event args for ChatFromWorld");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OnLocalChatFromWorld(evArgs[0], (OSChatMessage)evArgs[1]);
|
|
||||||
return;
|
|
||||||
case EventManager.EventNames.ObjectGrab:
|
|
||||||
OnLocalGrabObject((uint)evArgs[0], (uint)evArgs[1], (Vector3) evArgs[2], (IClientAPI) evArgs[3], (SurfaceTouchEventArgs)evArgs[4]);
|
|
||||||
return;
|
|
||||||
case EventManager.EventNames.ObjectGrabbing:
|
|
||||||
OnLocalObjectGrabbing((uint)evArgs[0], (uint)evArgs[1], (Vector3)evArgs[2], (IClientAPI)evArgs[3], (SurfaceTouchEventArgs)evArgs[4]);
|
|
||||||
return;
|
|
||||||
case EventManager.EventNames.ObjectDeGrab:
|
|
||||||
OnLocalDeGrabObject((uint)evArgs[0], (uint)evArgs[1], (IClientAPI)evArgs[2], (SurfaceTouchEventArgs)evArgs[3]);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The handler for (locally initiated) event OnNewScript: triggered by client's RezSript packet, publish it to other actors.
|
/// The handler for (locally initiated) event OnNewScript: triggered by client's RezSript packet, publish it to other actors.
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
NewObject, // objects
|
NewObject, // objects
|
||||||
UpdatedObject, // objects
|
UpdatedObject, // objects
|
||||||
RemovedObject, // objects
|
RemovedObject, // objects
|
||||||
|
LinkObject,
|
||||||
RegionName,
|
RegionName,
|
||||||
//RegionStatus,
|
//RegionStatus,
|
||||||
ActorID,
|
ActorID,
|
||||||
|
|
|
@ -292,7 +292,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
|
|
||||||
//For any other messages, we simply deliver the message to RegionSyncModule for now.
|
//For any other messages, we simply deliver the message to RegionSyncModule for now.
|
||||||
//Later on, we may deliver messages to different modules, say sync message to RegionSyncModule and event message to ActorSyncModule.
|
//Later on, we may deliver messages to different modules, say sync message to RegionSyncModule and event message to ActorSyncModule.
|
||||||
m_regionSyncModule.HandleIncomingMessage(msg);
|
m_regionSyncModule.HandleIncomingMessage(msg, m_syncOtherSideActorID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -60,10 +60,15 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
void QueueSceneObjectPartForUpdate(SceneObjectPart part);
|
void QueueSceneObjectPartForUpdate(SceneObjectPart part);
|
||||||
void QueueScenePresenceForTerseUpdate(ScenePresence presence);
|
void QueueScenePresenceForTerseUpdate(ScenePresence presence);
|
||||||
|
|
||||||
//void SendUpdatesToSynchronizeState(List<SceneObjectGroup> sog);
|
//SendSceneUpdates put each update into an outgoing queue of each SyncConnector
|
||||||
void SendSceneUpdates();
|
void SendSceneUpdates();
|
||||||
|
|
||||||
|
//In RegionSyncModule's implementation,
|
||||||
|
//The following calls send out a message immediately, w/o putting it in the SyncConnector's outgoing queue.
|
||||||
|
//May need some optimization there on the priorities.
|
||||||
void SendTerrainUpdates(string lastUpdateActorID);
|
void SendTerrainUpdates(string lastUpdateActorID);
|
||||||
void SendDeleteObject(SceneObjectGroup sog, bool softDelete);
|
void SendDeleteObject(SceneObjectGroup sog, bool softDelete);
|
||||||
|
void SendLinkObject(SceneObjectPart root, List<SceneObjectPart> children);
|
||||||
|
|
||||||
//For propogating scene events to other actors
|
//For propogating scene events to other actors
|
||||||
void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs);
|
void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs);
|
||||||
|
|
|
@ -725,6 +725,74 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_sceneGraph.AddSceneObjectByStateSynch(group);
|
m_sceneGraph.AddSceneObjectByStateSynch(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DebugSceneObjectGroups()
|
||||||
|
{
|
||||||
|
EntityBase[] entities = Entities.GetEntities();
|
||||||
|
List<SceneObjectGroup> groups = new List<SceneObjectGroup>();
|
||||||
|
|
||||||
|
foreach (EntityBase ent in entities)
|
||||||
|
{
|
||||||
|
if (ent is SceneObjectGroup)
|
||||||
|
{
|
||||||
|
SceneObjectGroup sog = (SceneObjectGroup)ent;
|
||||||
|
groups.Add(sog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.Debug("Scene " + m_regInfo.RegionName + " has " + groups.Count + " SOGs");
|
||||||
|
foreach (SceneObjectGroup sog in groups)
|
||||||
|
{
|
||||||
|
string sogDebug = sog.DebugObjectUpdateResult();
|
||||||
|
m_log.Debug(sogDebug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Assuming that the permission and owner checking is done at the actor that initiates the link operation, so
|
||||||
|
//no checking of permissions here.
|
||||||
|
/// <summary>
|
||||||
|
/// Update the grouping relations of the SceneObjectParts as identified by the rootID and childrenIDs, and update the properties of all the parts in the new object group.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="linkedGroup"></param>
|
||||||
|
/// <param name="rootID"></param>
|
||||||
|
/// <param name="childrenIDs"></param>
|
||||||
|
public void LinkObjectBySync(UUID rootID, List<UUID> childrenIDs)
|
||||||
|
{
|
||||||
|
m_log.Debug("Start to LinkObjectBySync");
|
||||||
|
DebugSceneObjectGroups();
|
||||||
|
|
||||||
|
List<SceneObjectPart> children = new List<SceneObjectPart>();
|
||||||
|
SceneObjectPart root = GetSceneObjectPart(rootID);
|
||||||
|
|
||||||
|
if (root == null)
|
||||||
|
{
|
||||||
|
m_log.Warn("LinkObjectBySync: root part " + rootID + " not found at local Scene copy");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (UUID childID in childrenIDs)
|
||||||
|
{
|
||||||
|
SceneObjectPart part = GetSceneObjectPart(childID);
|
||||||
|
|
||||||
|
if (part == null)
|
||||||
|
{
|
||||||
|
m_log.Warn("LinkObjectBySync: child part " + rootID + " not found at local Scene copy");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
children.Add(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Leverage the LinkObject implementation to get the book keeping of Group and Parts relations right
|
||||||
|
m_sceneGraph.LinkObjectsBySync(root, children);
|
||||||
|
|
||||||
|
//The properties of the newly linked object should be updated later with another UpdatedObject message.
|
||||||
|
|
||||||
|
//Set the property values as in the incoming copy of the object group
|
||||||
|
//SceneObjectGroup localGroup = root.ParentGroup;
|
||||||
|
//localGroup.UpdateObjectProperties(linkedGroup);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endregion //SYMMETRIC SYNC
|
#endregion //SYMMETRIC SYNC
|
||||||
|
|
||||||
public ICapabilitiesModule CapsModule
|
public ICapabilitiesModule CapsModule
|
||||||
|
|
|
@ -1576,6 +1576,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return; // parent is null so not in this region
|
return; // parent is null so not in this region
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
//Send out a LinkObject message for synchronization purpose, before other object-update sync messages are sent out.
|
||||||
|
//We need to do this before the calling to parentGroup.LinkToGroup() below, as LinkToGroup will trigger
|
||||||
|
//SendDeleteObject message to be sent out.
|
||||||
|
|
||||||
|
// ------------- NOTE: This needs further optimization, as we don't want to block on sending messages while inside the lock. -------------
|
||||||
|
// However, we also want to make sure that the LinkObject message is sent out with high priority and sent
|
||||||
|
// earlier than the object update message triggered by the ScheduleGroupForFullUpdate() function below
|
||||||
|
if (m_parentScene.RegionSyncModule != null)
|
||||||
|
{
|
||||||
|
//Tell other actors to link the SceneObjectParts together as a new group. But not updating the properties yet.
|
||||||
|
//The properties will be updated later when parentGroup.ScheduleGroupForFullUpdate() is called below.
|
||||||
|
m_parentScene.RegionSyncModule.SendLinkObject(root, children);
|
||||||
|
}
|
||||||
|
|
||||||
|
//end of SYMMETRIC SYNC
|
||||||
|
|
||||||
foreach (SceneObjectGroup child in childGroups)
|
foreach (SceneObjectGroup child in childGroups)
|
||||||
{
|
{
|
||||||
parentGroup.LinkToGroup(child);
|
parentGroup.LinkToGroup(child);
|
||||||
|
@ -1585,6 +1603,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
child.AbsolutePosition = child.AbsolutePosition;
|
child.AbsolutePosition = child.AbsolutePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// We need to explicitly resend the newly link prim's object properties since no other actions
|
// We need to explicitly resend the newly link prim's object properties since no other actions
|
||||||
// occur on link to invoke this elsewhere (such as object selection)
|
// occur on link to invoke this elsewhere (such as object selection)
|
||||||
parentGroup.RootPart.CreateSelected = true;
|
parentGroup.RootPart.CreateSelected = true;
|
||||||
|
@ -1946,6 +1965,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public Scene.ObjectUpdateResult AddOrUpdateObjectBySynchronization(SceneObjectGroup updatedSog)
|
public Scene.ObjectUpdateResult AddOrUpdateObjectBySynchronization(SceneObjectGroup updatedSog)
|
||||||
{
|
{
|
||||||
UUID sogID = updatedSog.UUID;
|
UUID sogID = updatedSog.UUID;
|
||||||
|
Scene.ObjectUpdateResult updateResult = Scene.ObjectUpdateResult.Unchanged;
|
||||||
|
|
||||||
if (Entities.ContainsKey(sogID))
|
if (Entities.ContainsKey(sogID))
|
||||||
{
|
{
|
||||||
|
@ -1954,22 +1974,27 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (entity is SceneObjectGroup)
|
if (entity is SceneObjectGroup)
|
||||||
{
|
{
|
||||||
SceneObjectGroup localSog = (SceneObjectGroup)entity;
|
SceneObjectGroup localSog = (SceneObjectGroup)entity;
|
||||||
Scene.ObjectUpdateResult updateResult = localSog.UpdateObjectGroupBySync(updatedSog);
|
updateResult = localSog.UpdateObjectGroupBySync(updatedSog);
|
||||||
return updateResult;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.Warn("Entity with " + sogID + " is not of type SceneObjectGroup");
|
m_log.Warn("Entity with " + sogID + " is not of type SceneObjectGroup");
|
||||||
//return false;
|
//return false;
|
||||||
return Scene.ObjectUpdateResult.Error;
|
updateResult = Scene.ObjectUpdateResult.Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.Debug("AddSceneObjectByStateSynch to be called");
|
m_log.Debug("AddSceneObjectByStateSynch to be called");
|
||||||
AddSceneObjectByStateSynch(updatedSog);
|
AddSceneObjectByStateSynch(updatedSog);
|
||||||
return Scene.ObjectUpdateResult.New;
|
updateResult = Scene.ObjectUpdateResult.New;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Debug
|
||||||
|
m_log.Debug("after AddOrUpdateObjectBySynchronization");
|
||||||
|
m_parentScene.DebugSceneObjectGroups();
|
||||||
|
|
||||||
|
return updateResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is called when an object is added due to receiving a state synchronization message from Scene or an actor. Do similar things as the original AddSceneObject(),
|
//This is called when an object is added due to receiving a state synchronization message from Scene or an actor. Do similar things as the original AddSceneObject(),
|
||||||
|
@ -2058,6 +2083,62 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LinkObjectsBySync(SceneObjectPart root, List<SceneObjectPart> children)
|
||||||
|
{
|
||||||
|
Monitor.Enter(m_updateLock);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SceneObjectGroup parentGroup = root.ParentGroup;
|
||||||
|
|
||||||
|
List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
|
||||||
|
if (parentGroup != null)
|
||||||
|
{
|
||||||
|
// We do this in reverse to get the link order of the prims correct
|
||||||
|
for (int i = children.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
SceneObjectGroup child = children[i].ParentGroup;
|
||||||
|
|
||||||
|
if (child != null)
|
||||||
|
{
|
||||||
|
// Make sure no child prim is set for sale
|
||||||
|
// So that, on delink, no prims are unwittingly
|
||||||
|
// left for sale and sold off
|
||||||
|
child.RootPart.ObjectSaleType = 0;
|
||||||
|
child.RootPart.SalePrice = 10;
|
||||||
|
childGroups.Add(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return; // parent is null so not in this region
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (SceneObjectGroup child in childGroups)
|
||||||
|
{
|
||||||
|
parentGroup.LinkToGroupBySync(child);
|
||||||
|
|
||||||
|
// this is here so physics gets updated!
|
||||||
|
// Don't remove! Bad juju! Stay away! or fix physics!
|
||||||
|
child.AbsolutePosition = child.AbsolutePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// We need to explicitly resend the newly link prim's object properties since no other actions
|
||||||
|
// occur on link to invoke this elsewhere (such as object selection)
|
||||||
|
parentGroup.RootPart.CreateSelected = true;
|
||||||
|
parentGroup.TriggerScriptChangedEvent(Changed.LINK);
|
||||||
|
parentGroup.HasGroupChanged = true;
|
||||||
|
//Do not change the timestamp and actorID values
|
||||||
|
parentGroup.ScheduleGroupForFullUpdate_SyncInfoUnchanged();
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Monitor.Exit(m_updateLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion //SYMMETRIC SYNC
|
#endregion //SYMMETRIC SYNC
|
||||||
}
|
}
|
||||||
|
|
|
@ -2127,6 +2127,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
//ScheduleGroupForFullUpdate();
|
//ScheduleGroupForFullUpdate();
|
||||||
|
|
||||||
//SYMMETRIC SYNC
|
//SYMMETRIC SYNC
|
||||||
|
//The DeleteObject message will be enqueued to be sent out by another thread, and the call will return quickly.
|
||||||
if (m_scene.RegionSyncModule != null)
|
if (m_scene.RegionSyncModule != null)
|
||||||
m_scene.RegionSyncModule.SendDeleteObject(objectGroup, true);
|
m_scene.RegionSyncModule.SendDeleteObject(objectGroup, true);
|
||||||
//end of SYMMETRIC SYNC
|
//end of SYMMETRIC SYNC
|
||||||
|
@ -3648,9 +3649,33 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ScheduleGroupForFullUpdate_SyncInfoUnchanged();
|
ScheduleGroupForFullUpdate_SyncInfoUnchanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//debug the update result
|
||||||
|
if (groupUpdateResult == Scene.ObjectUpdateResult.Updated)
|
||||||
|
{
|
||||||
|
DebugObjectUpdateResult();
|
||||||
|
}
|
||||||
|
|
||||||
return groupUpdateResult;
|
return groupUpdateResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string DebugObjectUpdateResult()
|
||||||
|
{
|
||||||
|
//m_log.Debug("ObjectGroup " + UUID + " updated. Rootpart: " +m_rootPart.DebugObjectPartProperties());
|
||||||
|
string sogDebug = "ObjectGroup " + UUID + ".\n Rootpart: " + m_rootPart.DebugObjectPartProperties();
|
||||||
|
|
||||||
|
int partNum = 1;
|
||||||
|
foreach (SceneObjectPart part in Parts)
|
||||||
|
{
|
||||||
|
if (part.UUID != m_rootPart.UUID)
|
||||||
|
{
|
||||||
|
//m_log.Debug("part " + partNum + ", " + part.DebugObjectPartProperties());
|
||||||
|
sogDebug += "\n"+part.DebugObjectPartProperties();
|
||||||
|
partNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sogDebug;
|
||||||
|
}
|
||||||
|
|
||||||
private void AddNewPart(SceneObjectPart newPart)
|
private void AddNewPart(SceneObjectPart newPart)
|
||||||
{
|
{
|
||||||
//set the parent relationship
|
//set the parent relationship
|
||||||
|
@ -3750,6 +3775,91 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Similar to LinkToGroup(), except that not calling RegionSyncModule.SendDeleteObject
|
||||||
|
public void LinkToGroupBySync(SceneObjectGroup objectGroup)
|
||||||
|
{
|
||||||
|
|
||||||
|
SceneObjectPart linkPart = objectGroup.m_rootPart;
|
||||||
|
|
||||||
|
Vector3 oldGroupPosition = linkPart.GroupPosition;
|
||||||
|
Quaternion oldRootRotation = linkPart.RotationOffset;
|
||||||
|
|
||||||
|
linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition;
|
||||||
|
linkPart.GroupPosition = AbsolutePosition;
|
||||||
|
Vector3 axPos = linkPart.OffsetPosition;
|
||||||
|
|
||||||
|
Quaternion parentRot = m_rootPart.RotationOffset;
|
||||||
|
axPos *= Quaternion.Inverse(parentRot);
|
||||||
|
|
||||||
|
linkPart.OffsetPosition = axPos;
|
||||||
|
Quaternion oldRot = linkPart.RotationOffset;
|
||||||
|
Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot;
|
||||||
|
linkPart.RotationOffset = newRot;
|
||||||
|
|
||||||
|
linkPart.ParentID = m_rootPart.LocalId;
|
||||||
|
if (m_rootPart.LinkNum == 0)
|
||||||
|
m_rootPart.LinkNum = 1;
|
||||||
|
|
||||||
|
lock (m_parts.SyncRoot)
|
||||||
|
{
|
||||||
|
m_parts.Add(linkPart.UUID, linkPart);
|
||||||
|
|
||||||
|
// Insert in terms of link numbers, the new links
|
||||||
|
// before the current ones (with the exception of
|
||||||
|
// the root prim. Shuffle the old ones up
|
||||||
|
SceneObjectPart[] parts = m_parts.GetArray();
|
||||||
|
for (int i = 0; i < parts.Length; i++)
|
||||||
|
{
|
||||||
|
SceneObjectPart part = parts[i];
|
||||||
|
if (part.LinkNum != 1)
|
||||||
|
{
|
||||||
|
// Don't update root prim link number
|
||||||
|
part.LinkNum += objectGroup.PrimCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
linkPart.LinkNum = 2;
|
||||||
|
|
||||||
|
linkPart.SetParent(this);
|
||||||
|
linkPart.CreateSelected = true;
|
||||||
|
|
||||||
|
//if (linkPart.PhysActor != null)
|
||||||
|
//{
|
||||||
|
// m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
|
||||||
|
|
||||||
|
//linkPart.PhysActor = null;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//TODO: rest of parts
|
||||||
|
int linkNum = 3;
|
||||||
|
SceneObjectPart[] ogParts = objectGroup.Parts;
|
||||||
|
for (int i = 0; i < ogParts.Length; i++)
|
||||||
|
{
|
||||||
|
SceneObjectPart part = ogParts[i];
|
||||||
|
if (part.UUID != objectGroup.m_rootPart.UUID)
|
||||||
|
LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
|
||||||
|
part.ClearUndoState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scene.UnlinkSceneObject(objectGroup, true);
|
||||||
|
objectGroup.m_isDeleted = true;
|
||||||
|
|
||||||
|
objectGroup.m_parts.Clear();
|
||||||
|
|
||||||
|
// Can't do this yet since backup still makes use of the root part without any synchronization
|
||||||
|
// objectGroup.m_rootPart = null;
|
||||||
|
|
||||||
|
AttachToBackup();
|
||||||
|
|
||||||
|
// Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the
|
||||||
|
// position of linkset prims. IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and
|
||||||
|
// unmoved prims!
|
||||||
|
ResetChildPrimPhysicsPositions();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5084,6 +5084,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_parentGroup.Scene.EventManager.TriggerAggregateScriptEvents(this);
|
m_parentGroup.Scene.EventManager.TriggerAggregateScriptEvents(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_log.Debug("SceneObjectPart Name-" +Name+", localID-" + m_localId + " updated");
|
||||||
|
|
||||||
return partUpdateResult;
|
return partUpdateResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5097,6 +5099,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string DebugObjectPartProperties()
|
||||||
|
{
|
||||||
|
string debugMsg = "UUID " + UUID + ", Name " + Name + ", localID " + LocalId + ", lastUpdateActorID " + LastUpdateActorID + ", lastUpdateTimeStamp " + LastUpdateTimeStamp;
|
||||||
|
return debugMsg;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Schedules this prim for a full update, without changing the timestamp or actorID (info on when and who modified any property).
|
/// Schedules this prim for a full update, without changing the timestamp or actorID (info on when and who modified any property).
|
||||||
/// NOTE: this is the same as the original SceneObjectPart.ScheduleFullUpdate().
|
/// NOTE: this is the same as the original SceneObjectPart.ScheduleFullUpdate().
|
||||||
|
|
|
@ -654,6 +654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
if (m_Suspended)
|
if (m_Suspended)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
lock (m_Script)
|
lock (m_Script)
|
||||||
{
|
{
|
||||||
EventParams data = null;
|
EventParams data = null;
|
||||||
|
@ -674,6 +675,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_log.DebugFormat("[Script] processing event {2} in state {3} to {0}.{1}, localID -{4}", m_PrimName, m_ScriptName, data.EventName, m_State, m_LocalID);
|
||||||
|
|
||||||
|
|
||||||
if (data.EventName == "timer")
|
if (data.EventName == "timer")
|
||||||
m_TimerQueued = false;
|
m_TimerQueued = false;
|
||||||
if (data.EventName == "control")
|
if (data.EventName == "control")
|
||||||
|
@ -712,8 +716,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
{
|
{
|
||||||
SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
|
SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
|
||||||
m_LocalID);
|
m_LocalID);
|
||||||
// m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
|
|
||||||
// m_PrimName, m_ScriptName, data.EventName, m_State);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -786,6 +788,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_log.DebugFormat("[Script] processing event {2} in state {3} to {0}.{1}, localID -{4}; to trigger QueueEventHandler", m_PrimName, m_ScriptName, data.EventName, m_State, m_LocalID);
|
||||||
|
|
||||||
lock (m_EventQueue)
|
lock (m_EventQueue)
|
||||||
{
|
{
|
||||||
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
|
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
|
||||||
|
|
Loading…
Reference in New Issue