check in updates in enabling bucket based synchronization.
parent
a7d4c974dd
commit
97b01dcf75
|
@ -19,6 +19,8 @@ using System.Net.Sockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
|
@ -61,6 +63,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
m_isSyncRelay = m_sysConfig.GetBoolean("IsSyncRelay", false);
|
m_isSyncRelay = m_sysConfig.GetBoolean("IsSyncRelay", false);
|
||||||
m_isSyncListenerLocal = m_sysConfig.GetBoolean("IsSyncListenerLocal", false);
|
m_isSyncListenerLocal = m_sysConfig.GetBoolean("IsSyncListenerLocal", false);
|
||||||
|
|
||||||
|
//Setup the PropertyBucketMap
|
||||||
|
PupolatePropertyBucketMap(m_sysConfig);
|
||||||
|
|
||||||
m_active = true;
|
m_active = true;
|
||||||
|
|
||||||
LogHeader += "-Actor " + m_actorID;
|
LogHeader += "-Actor " + m_actorID;
|
||||||
|
@ -176,6 +181,17 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
get { return m_isSyncRelay; }
|
get { return m_isSyncRelay; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, string> m_primPropertyBucketMap = new Dictionary<string, string>();
|
||||||
|
public Dictionary<string, string> PrimPropertyBucketMap
|
||||||
|
{
|
||||||
|
get { return m_primPropertyBucketMap; }
|
||||||
|
}
|
||||||
|
private List<string> m_propertyBucketDescription = new List<string>();
|
||||||
|
public List<string> PropertyBucketDescription
|
||||||
|
{
|
||||||
|
get { return m_propertyBucketDescription; }
|
||||||
|
}
|
||||||
|
|
||||||
private RegionSyncListener m_localSyncListener = null;
|
private RegionSyncListener m_localSyncListener = null;
|
||||||
private bool m_synced = false;
|
private bool m_synced = false;
|
||||||
|
|
||||||
|
@ -184,7 +200,64 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
private Dictionary<UUID, SceneObjectGroup> m_primUpdates = new Dictionary<UUID, SceneObjectGroup>();
|
private Dictionary<UUID, SceneObjectGroup> m_primUpdates = new Dictionary<UUID, SceneObjectGroup>();
|
||||||
private object m_updateScenePresenceLock = new object();
|
private object m_updateScenePresenceLock = new object();
|
||||||
private Dictionary<UUID, ScenePresence> m_presenceUpdates = new Dictionary<UUID, ScenePresence>();
|
private Dictionary<UUID, ScenePresence> m_presenceUpdates = new Dictionary<UUID, ScenePresence>();
|
||||||
private int m_sendingUpdates;
|
private int m_sendingUpdates=0;
|
||||||
|
|
||||||
|
private int m_maxNumOfPropertyBuckets;
|
||||||
|
|
||||||
|
//Read in configuration for which property-bucket each property belongs to, and the description of each bucket
|
||||||
|
private void PupolatePropertyBucketMap(IConfig config)
|
||||||
|
{
|
||||||
|
//We start with a default bucket map. Will add the code to read in configuration from config files later.
|
||||||
|
PupolatePropertyBuketMapByDefault();
|
||||||
|
|
||||||
|
//Pass the bucket information to SceneObjectPart.
|
||||||
|
SceneObjectPart.InitializeBucketInfo(m_primPropertyBucketMap, m_propertyBucketDescription, m_actorID);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//If nothing configured in the config file, this is the default settings for grouping properties into different bucket
|
||||||
|
private void PupolatePropertyBuketMapByDefault()
|
||||||
|
{
|
||||||
|
//by default, there are two property buckets: the "General" bucket and the "Physics" bucket.
|
||||||
|
string generalBucketName = "General";
|
||||||
|
string physicsBucketName = "Physics";
|
||||||
|
m_propertyBucketDescription.Add(generalBucketName);
|
||||||
|
m_propertyBucketDescription.Add(physicsBucketName);
|
||||||
|
m_maxNumOfPropertyBuckets = 2;
|
||||||
|
|
||||||
|
foreach (string pName in SceneObjectPart.PropertyList)
|
||||||
|
{
|
||||||
|
switch (pName){
|
||||||
|
case "GroupPosition":
|
||||||
|
case "OffsetPosition":
|
||||||
|
case "Scale":
|
||||||
|
case "Velocity":
|
||||||
|
case "AngularVelocity":
|
||||||
|
case "RotationOffset":
|
||||||
|
case "Position":
|
||||||
|
case "Size":
|
||||||
|
case "Force":
|
||||||
|
case "RotationalVelocity":
|
||||||
|
case "PA_Acceleration":
|
||||||
|
case "Torque":
|
||||||
|
case "Orientation":
|
||||||
|
case "IsPhysical":
|
||||||
|
case "Flying":
|
||||||
|
case "Buoyancy":
|
||||||
|
m_primPropertyBucketMap.Add(pName, physicsBucketName);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//all other properties belong to the "General" bucket.
|
||||||
|
m_primPropertyBucketMap.Add(pName, generalBucketName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsSyncingWithOtherActors()
|
||||||
|
{
|
||||||
|
return (m_syncConnectors.Count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
public void QueueSceneObjectPartForUpdate(SceneObjectPart part)
|
public void QueueSceneObjectPartForUpdate(SceneObjectPart part)
|
||||||
{
|
{
|
||||||
|
@ -209,6 +282,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
//SendSceneUpdates put each update into an outgoing queue of each SyncConnector
|
//SendSceneUpdates put each update into an outgoing queue of each SyncConnector
|
||||||
public void SendSceneUpdates()
|
public void SendSceneUpdates()
|
||||||
{
|
{
|
||||||
|
if (!IsSyncingWithOtherActors())
|
||||||
|
{
|
||||||
|
//no SyncConnector connected. Do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
if (Interlocked.Exchange(ref m_sendingUpdates, 1) == 1)
|
if (Interlocked.Exchange(ref m_sendingUpdates, 1) == 1)
|
||||||
{
|
{
|
||||||
|
@ -323,6 +402,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
|
|
||||||
public void SendTerrainUpdates(string lastUpdateActorID)
|
public void SendTerrainUpdates(string lastUpdateActorID)
|
||||||
{
|
{
|
||||||
|
if (!IsSyncingWithOtherActors())
|
||||||
|
{
|
||||||
|
//no SyncConnector connected. Do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(m_isSyncRelay || m_actorID.Equals(lastUpdateActorID))
|
if(m_isSyncRelay || m_actorID.Equals(lastUpdateActorID))
|
||||||
{
|
{
|
||||||
//m_scene.Heightmap should have been updated already by the caller, send it out
|
//m_scene.Heightmap should have been updated already by the caller, send it out
|
||||||
|
@ -340,7 +424,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
//private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog)
|
//private void RegionSyncModule_OnObjectBeingRemovedFromScene(SceneObjectGroup sog)
|
||||||
public void SendDeleteObject(SceneObjectGroup sog, bool softDelete)
|
public void SendDeleteObject(SceneObjectGroup sog, bool softDelete)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("SendDeleteObject called for object {0}", sog.UUID);
|
if (!IsSyncingWithOtherActors())
|
||||||
|
{
|
||||||
|
//no SyncConnector connected. Do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.DebugFormat(LogHeader+"SendDeleteObject called for object {0}", sog.UUID);
|
||||||
|
|
||||||
//Only send the message out if this is a relay node for sync messages, or this actor caused deleting the object
|
//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))
|
//if (m_isSyncRelay || CheckObjectForSendingUpdate(sog))
|
||||||
|
@ -362,6 +452,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
{
|
{
|
||||||
if(children.Count==0) return;
|
if(children.Count==0) return;
|
||||||
|
|
||||||
|
if (!IsSyncingWithOtherActors())
|
||||||
|
{
|
||||||
|
//no SyncConnector connected. Do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OSDMap data = new OSDMap();
|
OSDMap data = new OSDMap();
|
||||||
string sogxml = SceneObjectSerializer.ToXml2Format(linkedGroup);
|
string sogxml = SceneObjectSerializer.ToXml2Format(linkedGroup);
|
||||||
data["linkedGroup"]=OSD.FromString(sogxml);
|
data["linkedGroup"]=OSD.FromString(sogxml);
|
||||||
|
@ -383,6 +479,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
{
|
{
|
||||||
if (prims.Count==0 || beforeDelinkGroups.Count==0) return;
|
if (prims.Count==0 || beforeDelinkGroups.Count==0) return;
|
||||||
|
|
||||||
|
if (!IsSyncingWithOtherActors())
|
||||||
|
{
|
||||||
|
//no SyncConnector connected. Do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
OSDMap data = new OSDMap();
|
OSDMap data = new OSDMap();
|
||||||
data["partCount"] = OSD.FromInteger(prims.Count);
|
data["partCount"] = OSD.FromInteger(prims.Count);
|
||||||
int partNum = 0;
|
int partNum = 0;
|
||||||
|
@ -420,6 +522,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
|
|
||||||
public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs)
|
public void PublishSceneEvent(EventManager.EventNames ev, Object[] evArgs)
|
||||||
{
|
{
|
||||||
|
if (!IsSyncingWithOtherActors())
|
||||||
|
{
|
||||||
|
//no SyncConnector connected. Do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (ev)
|
switch (ev)
|
||||||
{
|
{
|
||||||
case EventManager.EventNames.NewScript:
|
case EventManager.EventNames.NewScript:
|
||||||
|
@ -500,9 +608,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
|
|
||||||
Command cmdSyncStatus = new Command("status", CommandIntentions.COMMAND_HAZARDOUS, SyncStatus, "Displays synchronization status.");
|
Command cmdSyncStatus = new Command("status", CommandIntentions.COMMAND_HAZARDOUS, SyncStatus, "Displays synchronization status.");
|
||||||
|
|
||||||
|
//for debugging purpose
|
||||||
|
Command cmdSyncDebug = new Command("debug", CommandIntentions.COMMAND_HAZARDOUS, SyncDebug, "Trigger some debugging functions");
|
||||||
|
|
||||||
m_commander.RegisterCommand("start", cmdSyncStart);
|
m_commander.RegisterCommand("start", cmdSyncStart);
|
||||||
m_commander.RegisterCommand("stop", cmdSyncStop);
|
m_commander.RegisterCommand("stop", cmdSyncStop);
|
||||||
m_commander.RegisterCommand("status", cmdSyncStatus);
|
m_commander.RegisterCommand("status", cmdSyncStatus);
|
||||||
|
m_commander.RegisterCommand("debug", cmdSyncDebug);
|
||||||
|
|
||||||
lock (m_scene)
|
lock (m_scene)
|
||||||
{
|
{
|
||||||
|
@ -864,6 +976,38 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
m_log.Warn("[REGION SYNC MODULE]: SyncStatus() TO BE IMPLEMENTED !!!");
|
m_log.Warn("[REGION SYNC MODULE]: SyncStatus() TO BE IMPLEMENTED !!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SyncDebug(Object[] args)
|
||||||
|
{
|
||||||
|
if (m_scene != null)
|
||||||
|
{
|
||||||
|
EntityBase[] entities = m_scene.GetEntities();
|
||||||
|
foreach (EntityBase entity in entities)
|
||||||
|
{
|
||||||
|
if (entity is SceneObjectGroup)
|
||||||
|
{
|
||||||
|
//first test serialization
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
XmlTextWriter writer = new XmlTextWriter(sw);
|
||||||
|
Dictionary<string, BucketSyncInfo> bucketSyncInfoList = new Dictionary<string,BucketSyncInfo>();
|
||||||
|
BucketSyncInfo generalBucket = new BucketSyncInfo(DateTime.Now.Ticks, m_actorID, "General");
|
||||||
|
bucketSyncInfoList.Add("General", generalBucket);
|
||||||
|
BucketSyncInfo physicsBucket = new BucketSyncInfo(DateTime.Now.Ticks, m_actorID, "Physics");
|
||||||
|
bucketSyncInfoList.Add("Physics", physicsBucket);
|
||||||
|
SceneObjectSerializer.WriteBucketSyncInfo(writer, bucketSyncInfoList);
|
||||||
|
|
||||||
|
string xmlString = sw.ToString();
|
||||||
|
m_log.Debug("Serialized xml string: " + xmlString);
|
||||||
|
|
||||||
|
//second, test de-serialization
|
||||||
|
XmlTextReader reader = new XmlTextReader(new StringReader(xmlString));
|
||||||
|
SceneObjectPart part = new SceneObjectPart();
|
||||||
|
SceneObjectSerializer.ProcessBucketSyncInfo(part, reader);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Start connections to each remote listener.
|
//Start connections to each remote listener.
|
||||||
//For now, there is only one remote listener.
|
//For now, there is only one remote listener.
|
||||||
private bool StartSyncConnections()
|
private bool StartSyncConnections()
|
||||||
|
|
|
@ -110,7 +110,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("{0} [Start] Could not connect to RegionSyncServer at {1}:{2}", LogHeader, m_remoteListenerInfo.Addr, m_remoteListenerInfo.Port);
|
m_log.WarnFormat("{0} [Start] Could not connect to RegionSyncModule at {1}:{2}", LogHeader, m_remoteListenerInfo.Addr, m_remoteListenerInfo.Port);
|
||||||
m_log.Warn(e.Message);
|
m_log.Warn(e.Message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -579,6 +579,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
|
// Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
|
||||||
// for the same object with very different properties. The caller must schedule the update.
|
// for the same object with very different properties. The caller must schedule the update.
|
||||||
//ScheduleGroupForFullUpdate();
|
//ScheduleGroupForFullUpdate();
|
||||||
|
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
if (m_scene.RegionSyncModule != null)
|
||||||
|
{
|
||||||
|
foreach (SceneObjectPart part in Parts)
|
||||||
|
{
|
||||||
|
part.InitializeBucketSyncInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 GroupScale()
|
public Vector3 GroupScale()
|
||||||
|
|
|
@ -107,6 +107,56 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#endregion Enumerations
|
#endregion Enumerations
|
||||||
|
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
|
||||||
|
//Information for concurrency control of one bucket of prim proproperties.
|
||||||
|
public class BucketSyncInfo
|
||||||
|
{
|
||||||
|
private long m_lastUpdateTimeStamp;
|
||||||
|
private string m_lastUpdateActorID;
|
||||||
|
//lock for concurrent updates of the timestamp and actorID.
|
||||||
|
private Object m_updateLock = new Object();
|
||||||
|
private string m_bucketName;
|
||||||
|
|
||||||
|
public long LastUpdateTimeStamp
|
||||||
|
{
|
||||||
|
get { return m_lastUpdateTimeStamp; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string LastUpdateActorID
|
||||||
|
{
|
||||||
|
get { return m_lastUpdateActorID; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string BucketName
|
||||||
|
{
|
||||||
|
get { return m_bucketName; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public BucketSyncInfo(string bucketName)
|
||||||
|
{
|
||||||
|
m_bucketName = bucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BucketSyncInfo(long timeStamp, string actorID, string bucketName)
|
||||||
|
{
|
||||||
|
m_lastUpdateTimeStamp = timeStamp;
|
||||||
|
m_lastUpdateActorID = actorID;
|
||||||
|
m_bucketName = bucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSyncInfo(long timeStamp, string actorID)
|
||||||
|
{
|
||||||
|
lock (m_updateLock)
|
||||||
|
{
|
||||||
|
m_lastUpdateTimeStamp = timeStamp;
|
||||||
|
m_lastUpdateActorID = actorID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//end of SYMMETRIC SYNC
|
||||||
|
|
||||||
public class SceneObjectPart : IScriptHost, ISceneEntity
|
public class SceneObjectPart : IScriptHost, ISceneEntity
|
||||||
{
|
{
|
||||||
/// <value>
|
/// <value>
|
||||||
|
@ -127,7 +177,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#region Fields
|
#region Fields
|
||||||
|
|
||||||
public bool AllowedDrop;
|
//SYMMETRIC SYNC
|
||||||
|
//public bool AllowedDrop;
|
||||||
|
private bool m_allowedDrop;
|
||||||
|
public bool AllowedDrop
|
||||||
|
{
|
||||||
|
get { return m_allowedDrop; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
//m_allowedDrop = value;
|
||||||
|
SetAllowedDrop(value);
|
||||||
|
UpdateBucketSyncInfo("AllowedDrop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void SetAllowedDrop(bool value)
|
||||||
|
{
|
||||||
|
m_allowedDrop = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool DIE_AT_EDGE;
|
public bool DIE_AT_EDGE;
|
||||||
|
@ -732,6 +798,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
SetGroupPosition(value);
|
||||||
|
UpdateBucketSyncInfo("GroupPosition");
|
||||||
|
|
||||||
|
/*
|
||||||
|
//Legacy Opensim code
|
||||||
m_groupPosition = value;
|
m_groupPosition = value;
|
||||||
|
|
||||||
PhysicsActor actor = PhysActor;
|
PhysicsActor actor = PhysActor;
|
||||||
|
@ -772,14 +843,63 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
public void SetGroupPosition(Vector3 value)
|
||||||
|
{
|
||||||
|
m_groupPosition = value;
|
||||||
|
|
||||||
|
PhysicsActor actor = PhysActor;
|
||||||
|
if (actor != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Root prim actually goes at Position
|
||||||
|
if (_parentID == 0)
|
||||||
|
{
|
||||||
|
actor.Position = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// To move the child prim in respect to the group position and rotation we have to calculate
|
||||||
|
actor.Position = GetWorldPosition();
|
||||||
|
actor.Orientation = GetWorldRotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the physics engines that this prim changed.
|
||||||
|
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
|
||||||
|
if (m_sitTargetAvatar != UUID.Zero)
|
||||||
|
{
|
||||||
|
if (m_parentGroup != null) // TODO can there be a SOP without a SOG?
|
||||||
|
{
|
||||||
|
ScenePresence avatar;
|
||||||
|
if (m_parentGroup.Scene.TryGetScenePresence(m_sitTargetAvatar, out avatar))
|
||||||
|
{
|
||||||
|
avatar.ParentPosition = GetWorldPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Vector3 OffsetPosition
|
public Vector3 OffsetPosition
|
||||||
{
|
{
|
||||||
get { return m_offsetPosition; }
|
get { return m_offsetPosition; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
SetOffsetPosition(value);
|
||||||
|
UpdateBucketSyncInfo("OffsetPosition");
|
||||||
|
/*
|
||||||
StoreUndoState();
|
StoreUndoState();
|
||||||
m_offsetPosition = value;
|
m_offsetPosition = value;
|
||||||
|
|
||||||
|
@ -795,6 +915,26 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
* */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
public void SetOffsetPosition(Vector3 value)
|
||||||
|
{
|
||||||
|
StoreUndoState();
|
||||||
|
m_offsetPosition = value;
|
||||||
|
|
||||||
|
if (ParentGroup != null && !ParentGroup.IsDeleted)
|
||||||
|
{
|
||||||
|
PhysicsActor actor = PhysActor;
|
||||||
|
if (_parentID != 0 && actor != null)
|
||||||
|
{
|
||||||
|
actor.Position = GetWorldPosition();
|
||||||
|
actor.Orientation = GetWorldRotation();
|
||||||
|
|
||||||
|
// Tell the physics engines that this prim changed.
|
||||||
|
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,6 +976,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
SetRotationOffset(value);
|
||||||
|
UpdateBucketSyncInfo("RotationOffset");
|
||||||
|
/*
|
||||||
StoreUndoState();
|
StoreUndoState();
|
||||||
m_rotationOffset = value;
|
m_rotationOffset = value;
|
||||||
|
|
||||||
|
@ -865,9 +1008,43 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message);
|
m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
* */
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
public void SetRotationOffset(Quaternion value)
|
||||||
|
{
|
||||||
|
StoreUndoState();
|
||||||
|
m_rotationOffset = value;
|
||||||
|
|
||||||
|
PhysicsActor actor = PhysActor;
|
||||||
|
if (actor != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Root prim gets value directly
|
||||||
|
if (_parentID == 0)
|
||||||
|
{
|
||||||
|
actor.Orientation = value;
|
||||||
|
//m_log.Info("[PART]: RO1:" + actor.Orientation.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Child prim we have to calculate it's world rotationwel
|
||||||
|
Quaternion resultingrotation = GetWorldRotation();
|
||||||
|
actor.Orientation = resultingrotation;
|
||||||
|
//m_log.Info("[PART]: RO2:" + actor.Orientation.ToString());
|
||||||
|
}
|
||||||
|
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary></summary>
|
/// <summary></summary>
|
||||||
public Vector3 Velocity
|
public Vector3 Velocity
|
||||||
|
@ -888,6 +1065,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
SetVelocity(value);
|
||||||
|
UpdateBucketSyncInfo("Velocity");
|
||||||
|
/*
|
||||||
m_velocity = value;
|
m_velocity = value;
|
||||||
|
|
||||||
PhysicsActor actor = PhysActor;
|
PhysicsActor actor = PhysActor;
|
||||||
|
@ -899,6 +1079,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
* */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
public void SetVelocity(Vector3 value)
|
||||||
|
{
|
||||||
|
m_velocity = value;
|
||||||
|
|
||||||
|
PhysicsActor actor = PhysActor;
|
||||||
|
if (actor != null)
|
||||||
|
{
|
||||||
|
if (actor.IsPhysical)
|
||||||
|
{
|
||||||
|
actor.Velocity = value;
|
||||||
|
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,7 +1110,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
return m_angularVelocity;
|
return m_angularVelocity;
|
||||||
}
|
}
|
||||||
set { m_angularVelocity = value; }
|
set
|
||||||
|
{
|
||||||
|
SetAngularVelocity(value);
|
||||||
|
UpdateBucketSyncInfo("AngularVelocity");
|
||||||
|
//m_angularVelocity = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
public void SetAngularVelocity(Vector3 value)
|
||||||
|
{
|
||||||
|
m_angularVelocity = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary></summary>
|
/// <summary></summary>
|
||||||
|
@ -1011,6 +1217,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
get { return m_shape.Scale; }
|
get { return m_shape.Scale; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
SetScale(value);
|
||||||
|
UpdateBucketSyncInfo("Scale");
|
||||||
|
/*
|
||||||
StoreUndoState();
|
StoreUndoState();
|
||||||
if (m_shape != null)
|
if (m_shape != null)
|
||||||
{
|
{
|
||||||
|
@ -1030,8 +1239,33 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TriggerScriptChangedEvent(Changed.SCALE);
|
TriggerScriptChangedEvent(Changed.SCALE);
|
||||||
|
* */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
public void SetScale(Vector3 value)
|
||||||
|
{
|
||||||
|
StoreUndoState();
|
||||||
|
if (m_shape != null)
|
||||||
|
{
|
||||||
|
m_shape.Scale = value;
|
||||||
|
|
||||||
|
PhysicsActor actor = PhysActor;
|
||||||
|
if (actor != null && m_parentGroup != null)
|
||||||
|
{
|
||||||
|
if (m_parentGroup.Scene != null)
|
||||||
|
{
|
||||||
|
if (m_parentGroup.Scene.PhysicsScene != null)
|
||||||
|
{
|
||||||
|
actor.Size = m_shape.Scale;
|
||||||
|
m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TriggerScriptChangedEvent(Changed.SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public byte UpdateFlag
|
public byte UpdateFlag
|
||||||
{
|
{
|
||||||
|
@ -4971,10 +5205,88 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//The list of each prim's properties. This is the list of properties that matter in synchronizing prim copies on different actors.
|
||||||
|
//This list is created based on properties included in the serialization/deserialization process (see SceneObjectSerializer()) and the
|
||||||
|
//properties Physics Engine needs to synchronize to other actors.
|
||||||
|
public static List<string> PropertyList = new List<string>()
|
||||||
|
{
|
||||||
|
//Following properties copied from SceneObjectSerializer()
|
||||||
|
"AllowedDrop",
|
||||||
|
"CreatorID",
|
||||||
|
"CreatorData",
|
||||||
|
"FolderID",
|
||||||
|
"InventorySerial",
|
||||||
|
"TaskInventory",
|
||||||
|
"UUID",
|
||||||
|
"LocalId",
|
||||||
|
"Name",
|
||||||
|
"Material",
|
||||||
|
"PassTouches",
|
||||||
|
"RegionHandle",
|
||||||
|
"ScriptAccessPin",
|
||||||
|
"GroupPosition",
|
||||||
|
"OffsetPosition",
|
||||||
|
"RotationOffset",
|
||||||
|
"Velocity",
|
||||||
|
"AngularVelocity",
|
||||||
|
//"Acceleration",
|
||||||
|
"SOP_Acceleration", //SOP and PA read/write their own local copies of acceleration, so we distinguish the copies
|
||||||
|
"Description",
|
||||||
|
"Color",
|
||||||
|
"Text",
|
||||||
|
"SitName",
|
||||||
|
"TouchName",
|
||||||
|
"LinkNum",
|
||||||
|
"ClickAction",
|
||||||
|
"Shape",
|
||||||
|
"Scale",
|
||||||
|
"UpdateFlag",
|
||||||
|
"SitTargetOrientation",
|
||||||
|
"SitTargetPosition",
|
||||||
|
"SitTargetPositionLL",
|
||||||
|
"SitTargetOrientationLL",
|
||||||
|
"ParentID",
|
||||||
|
"CreationDate",
|
||||||
|
"Category",
|
||||||
|
"SalePrice",
|
||||||
|
"ObjectSaleType",
|
||||||
|
"OwnershipCost",
|
||||||
|
"GroupID",
|
||||||
|
"OwnerID",
|
||||||
|
"LastOwnerID",
|
||||||
|
"BaseMask",
|
||||||
|
"OwnerMask",
|
||||||
|
"GroupMask",
|
||||||
|
"EveryoneMask",
|
||||||
|
"NextOwnerMask",
|
||||||
|
"Flags",
|
||||||
|
"CollisionSound",
|
||||||
|
"CollisionSoundVolume",
|
||||||
|
"MediaUrl",
|
||||||
|
"TextureAnimation",
|
||||||
|
"ParticleSystem",
|
||||||
|
//Property names below copied from PhysicsActor, they are necessary in synchronization, but not covered the above properties
|
||||||
|
//Physics properties "Velocity" is covered above
|
||||||
|
"Position",
|
||||||
|
"Size",
|
||||||
|
"Force",
|
||||||
|
"RotationalVelocity",
|
||||||
|
"PA_Acceleration",
|
||||||
|
"Torque",
|
||||||
|
"Orientation",
|
||||||
|
"IsPhysical",
|
||||||
|
"Flying",
|
||||||
|
"Buoyancy",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Object propertyUpdateLock = new Object();
|
private Object propertyUpdateLock = new Object();
|
||||||
|
|
||||||
//!!!!!! -- TODO:
|
//!!!!!! -- TODO:
|
||||||
//!!!!!! -- We should call UpdateXXX functions to update each property, cause some of such updates involves sanity checking.
|
//!!!!!! -- We should call UpdateXXX functions to update each property, cause some of such updates involves sanity checking.
|
||||||
|
|
||||||
public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart)
|
public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart)
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -5098,6 +5410,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return partUpdateResult;
|
return partUpdateResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private bool UpdateCollisionSound(UUID updatedCollisionSound)
|
private bool UpdateCollisionSound(UUID updatedCollisionSound)
|
||||||
{
|
{
|
||||||
if (this.CollisionSound != updatedCollisionSound)
|
if (this.CollisionSound != updatedCollisionSound)
|
||||||
|
@ -5150,6 +5464,197 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//The following variables should be initialized when this SceneObjectPart is added into the local Scene.
|
||||||
|
//private List<BucketSyncInfo> SynchronizeUpdatesToScene = null;
|
||||||
|
//public List<BucketSyncInfo> BucketSyncInfoList
|
||||||
|
private Dictionary<string, BucketSyncInfo> m_bucketSyncInfoList = new Dictionary<string, BucketSyncInfo>();
|
||||||
|
public Dictionary<string, BucketSyncInfo> BucketSyncInfoList
|
||||||
|
{
|
||||||
|
get { return m_bucketSyncInfoList; }
|
||||||
|
set { m_bucketSyncInfoList = value; }
|
||||||
|
}
|
||||||
|
//TODO: serialization and deserialization processors to be added in SceneObjectSerializer
|
||||||
|
|
||||||
|
//The following variables are initialized when RegionSyncModule reads the config file for mapping of properties and buckets
|
||||||
|
private static Dictionary<string, string> m_primPropertyBucketMap = null;
|
||||||
|
private static List<string> m_propertyBucketNames = null;
|
||||||
|
//private static List<Object> m_bucketUpdateLocks = null;
|
||||||
|
private static Dictionary<string, Object> m_bucketUpdateLocks = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
private static string m_localActorID = "";
|
||||||
|
//private static int m_bucketCount = 0;
|
||||||
|
//private delegate void BucketUpdateProcessor(int bucketIndex);
|
||||||
|
private delegate void BucketUpdateProcessor(string bucketName);
|
||||||
|
|
||||||
|
private static Dictionary<string, BucketUpdateProcessor> m_bucketUpdateProcessors = new Dictionary<string, BucketUpdateProcessor>();
|
||||||
|
|
||||||
|
public static void InitializeBucketInfo(Dictionary<string, string> propertyBucketMap, List<string> bucketNames, string actorID)
|
||||||
|
{
|
||||||
|
m_primPropertyBucketMap = propertyBucketMap;
|
||||||
|
m_propertyBucketNames = bucketNames;
|
||||||
|
m_localActorID = actorID;
|
||||||
|
//m_bucketCount = bucketNames.Count;
|
||||||
|
|
||||||
|
RegisterBucketUpdateProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Link each bucket with the function that applies updates to properties in the bucket. This is the "hard-coded" part
|
||||||
|
/// in the property-buckets implementation. When new buckets are implemented, the processing functions need to be modified accordingly.
|
||||||
|
/// </summary>
|
||||||
|
private static void RegisterBucketUpdateProcessor()
|
||||||
|
{
|
||||||
|
foreach (string bucketName in m_propertyBucketNames)
|
||||||
|
{
|
||||||
|
switch (bucketName)
|
||||||
|
{
|
||||||
|
case "General":
|
||||||
|
m_bucketUpdateProcessors.Add(bucketName, GeneralBucketUpdateProcessor);
|
||||||
|
break;
|
||||||
|
case "Physics":
|
||||||
|
m_bucketUpdateProcessors.Add(bucketName, PhysicsBucketUpdateProcessor);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_log.Warn("Bucket " + bucketName + "'s update processing function not defined yet");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GeneralBucketUpdateProcessor(string bucketName)
|
||||||
|
{
|
||||||
|
lock (m_bucketUpdateLocks[bucketName])
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PhysicsBucketUpdateProcessor(string bucketName)
|
||||||
|
{
|
||||||
|
lock (m_bucketUpdateLocks[bucketName])
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Initialize and set the values of timestamp and actorID for each synchronization bucket.
|
||||||
|
//Should be called when the SceneObjectGroup this part is in is added to scene, see SceneObjectGroup.AttachToScene.
|
||||||
|
public void InitializeBucketSyncInfo()
|
||||||
|
{
|
||||||
|
if (m_primPropertyBucketMap == null)
|
||||||
|
{
|
||||||
|
m_log.Error("Bucket Information has not been initilized. Return.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long timeStamp = DateTime.Now.Ticks;
|
||||||
|
|
||||||
|
m_log.Debug("InitializeBucketSyncInfo called at " + timeStamp);
|
||||||
|
|
||||||
|
for (int i = 0; i < m_propertyBucketNames.Count; i++)
|
||||||
|
{
|
||||||
|
string bucketName = m_propertyBucketNames[i];
|
||||||
|
BucketSyncInfo syncInfo = new BucketSyncInfo(timeStamp, m_localActorID, bucketName);
|
||||||
|
|
||||||
|
//If the object is created by de-serialization, then it already has m_bucketSyncInfoList populated with the right number of buckets
|
||||||
|
if (m_bucketSyncInfoList.ContainsKey(bucketName))
|
||||||
|
{
|
||||||
|
m_bucketSyncInfoList[bucketName] = syncInfo;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_bucketSyncInfoList.Add(bucketName, syncInfo);
|
||||||
|
}
|
||||||
|
if (!m_bucketSyncInfoList.ContainsKey(bucketName))
|
||||||
|
{
|
||||||
|
m_bucketUpdateLocks.Add(bucketName, new Object());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the timestamp and actorID information of the bucket the given property belongs to.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="propertyName">Name of the property. Make sure the spelling is consistent with what are defined in PropertyList</param>
|
||||||
|
private void UpdateBucketSyncInfo(string propertyName)
|
||||||
|
{
|
||||||
|
if (m_bucketSyncInfoList != null && m_bucketSyncInfoList.Count>0)
|
||||||
|
{
|
||||||
|
//int bucketIndex = m_primPropertyBucketMap[propertyName];
|
||||||
|
string bucketName = m_primPropertyBucketMap[propertyName];
|
||||||
|
long timeStamp = DateTime.Now.Ticks;
|
||||||
|
if (m_bucketSyncInfoList.ContainsKey(bucketName))
|
||||||
|
{
|
||||||
|
m_bucketSyncInfoList[bucketName].UpdateSyncInfo(timeStamp, m_localActorID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.Warn("No SyncInfo of bucket (name: " + bucketName + ") found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
public Scene.ObjectUpdateResult UpdateAllProperties(SceneObjectPart updatedPart)
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////Assumptions: ////////////////////
|
||||||
|
//(1) prim's UUID and LocalID shall not change (UUID is the unique identifies, LocalID is used to refer to the prim by, say scripts)
|
||||||
|
//(2) RegionHandle won't be updated -- each copy of Scene is hosted on a region with different region handle
|
||||||
|
//(3) ParentID won't be updated -- if the rootpart of the SceneObjectGroup changed, that will be updated in SceneObjectGroup.UpdateObjectProperties
|
||||||
|
|
||||||
|
////////////////////Furture enhancements:////////////////////
|
||||||
|
//For now, we only update the set of properties that are included in serialization, and some PhysicsActor properties
|
||||||
|
//See RegionSyncModule.PupolatePropertyBuketMapByDefault for the properties that are handled.
|
||||||
|
|
||||||
|
if (updatedPart == null)
|
||||||
|
return Scene.ObjectUpdateResult.Error;
|
||||||
|
|
||||||
|
//Compate the timestamp of each bucket and update the properties if needed
|
||||||
|
|
||||||
|
Scene.ObjectUpdateResult partUpdateResult = Scene.ObjectUpdateResult.Unchanged;
|
||||||
|
|
||||||
|
for (int i=0; i<m_bucketCount; i++){
|
||||||
|
string bucketName = m_propertyBucketNames[i];
|
||||||
|
//First, compare the bucket's timestamp and actorID
|
||||||
|
if (m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp > updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp)
|
||||||
|
{
|
||||||
|
//Our timestamp is more update to date, keep our values of the properties. Do not update anything.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_bucketSyncInfoList[bucketName].LastUpdateTimeStamp == updatedPart.BucketSyncInfoList[bucketName].LastUpdateTimeStamp)
|
||||||
|
{
|
||||||
|
if (!m_bucketSyncInfoList[bucketName].LastUpdateActorID.Equals(updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID))
|
||||||
|
{
|
||||||
|
m_log.Warn("Different actors modified SceneObjetPart " + UUID + " with the same TimeStamp (" + m_bucketSyncInfoList[bucketName].LastUpdateActorID
|
||||||
|
+ "," + updatedPart.BucketSyncInfoList[bucketName].LastUpdateActorID + ", CONFLICT RESOLUTION TO BE IMPLEMENTED!!!!");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Second, if need to update local properties, call each bucket's update process
|
||||||
|
if (m_bucketUpdateProcessors.ContainsKey(bucketName))
|
||||||
|
{
|
||||||
|
m_bucketUpdateProcessors[bucketName](bucketName);
|
||||||
|
partUpdateResult = Scene.ObjectUpdateResult.Updated;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.Warn("No update processor for property bucket " + bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return partUpdateResult;
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//private void UpdateBucketProperties(string bucketDescription,
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,6 +332,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
//SYMMETRIC SYNC
|
//SYMMETRIC SYNC
|
||||||
m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp);
|
m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp);
|
||||||
m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID);
|
m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID);
|
||||||
|
m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo);
|
||||||
//end of SYMMETRIC SYNC
|
//end of SYMMETRIC SYNC
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -417,9 +418,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
}
|
}
|
||||||
|
|
||||||
#region SOPXmlProcessors
|
#region SOPXmlProcessors
|
||||||
|
//SYMMETRIC SYNC NOTE: -- assignments in de-serialization should directly set the values w/o triggering SceneObjectPart.UpdateBucketSyncInfo;
|
||||||
|
//That is, calling SetXXX(value) instead of using "XXX = value".
|
||||||
private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader)
|
||||||
{
|
{
|
||||||
obj.AllowedDrop = Util.ReadBoolean(reader);
|
//obj.AllowedDrop = Util.ReadBoolean(reader);
|
||||||
|
obj.SetAllowedDrop(Util.ReadBoolean(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader)
|
||||||
|
@ -484,27 +488,32 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
|
|
||||||
private static void ProcessGroupPosition(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessGroupPosition(SceneObjectPart obj, XmlTextReader reader)
|
||||||
{
|
{
|
||||||
obj.GroupPosition = Util.ReadVector(reader, "GroupPosition");
|
//obj.GroupPosition = Util.ReadVector(reader, "GroupPosition");
|
||||||
|
obj.SetGroupPosition(Util.ReadVector(reader, "GroupPosition"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessOffsetPosition(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessOffsetPosition(SceneObjectPart obj, XmlTextReader reader)
|
||||||
{
|
{
|
||||||
obj.OffsetPosition = Util.ReadVector(reader, "OffsetPosition"); ;
|
//obj.OffsetPosition = Util.ReadVector(reader, "OffsetPosition"); ;
|
||||||
|
obj.SetOffsetPosition(Util.ReadVector(reader, "OffsetPosition"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessRotationOffset(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessRotationOffset(SceneObjectPart obj, XmlTextReader reader)
|
||||||
{
|
{
|
||||||
obj.RotationOffset = Util.ReadQuaternion(reader, "RotationOffset");
|
//obj.RotationOffset = Util.ReadQuaternion(reader, "RotationOffset");
|
||||||
|
obj.SetRotationOffset(Util.ReadQuaternion(reader, "RotationOffset"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessVelocity(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessVelocity(SceneObjectPart obj, XmlTextReader reader)
|
||||||
{
|
{
|
||||||
obj.Velocity = Util.ReadVector(reader, "Velocity");
|
//obj.Velocity = Util.ReadVector(reader, "Velocity");
|
||||||
|
obj.SetVelocity(Util.ReadVector(reader, "Velocity"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessAngularVelocity(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessAngularVelocity(SceneObjectPart obj, XmlTextReader reader)
|
||||||
{
|
{
|
||||||
obj.AngularVelocity = Util.ReadVector(reader, "AngularVelocity");
|
//obj.AngularVelocity = Util.ReadVector(reader, "AngularVelocity");
|
||||||
|
obj.SetVelocity(Util.ReadVector(reader, "AngularVelocity"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader)
|
||||||
|
@ -563,7 +572,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
|
|
||||||
private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
|
||||||
{
|
{
|
||||||
obj.Scale = Util.ReadVector(reader, "Scale");
|
//obj.Scale = Util.ReadVector(reader, "Scale");
|
||||||
|
obj.SetScale(Util.ReadVector(reader, "Scale"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader)
|
private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader)
|
||||||
|
@ -702,6 +712,55 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
{
|
{
|
||||||
obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty);
|
obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader)
|
||||||
|
{
|
||||||
|
obj.BucketSyncInfoList = new Dictionary<string, BucketSyncInfo>();
|
||||||
|
|
||||||
|
if (reader.IsEmptyElement)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string elementName = "BucketSyncInfoList";
|
||||||
|
reader.ReadStartElement(elementName, String.Empty);
|
||||||
|
|
||||||
|
while (reader.Name == "Bucket")
|
||||||
|
{
|
||||||
|
reader.ReadStartElement("Bucket", String.Empty); // Bucket
|
||||||
|
string bucketName="";
|
||||||
|
long timeStamp = 0;
|
||||||
|
string actorID = "";
|
||||||
|
while (reader.NodeType != XmlNodeType.EndElement)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (reader.Name)
|
||||||
|
{
|
||||||
|
case "Name":
|
||||||
|
bucketName = reader.ReadElementContentAsString("Name", String.Empty);
|
||||||
|
break;
|
||||||
|
case "TimeStamp":
|
||||||
|
timeStamp = reader.ReadElementContentAsLong("TimeStamp", String.Empty);
|
||||||
|
break;
|
||||||
|
case "ActorID":
|
||||||
|
actorID = reader.ReadElementContentAsString("ActorID", String.Empty);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reader.ReadOuterXml();
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
reader.ReadEndElement();
|
||||||
|
BucketSyncInfo bucketSyncInfo = new BucketSyncInfo(timeStamp, actorID, bucketName);
|
||||||
|
obj.BucketSyncInfoList.Add(bucketName, bucketSyncInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reader.NodeType == XmlNodeType.EndElement)
|
||||||
|
reader.ReadEndElement(); // BucketSyncInfoList
|
||||||
|
}
|
||||||
|
|
||||||
//end of SYMMETRIC SYNC
|
//end of SYMMETRIC SYNC
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -1188,11 +1247,36 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||||
//SYMMETRIC SYNC
|
//SYMMETRIC SYNC
|
||||||
writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString());
|
writer.WriteElementString("LastUpdateTimeStamp", sop.LastUpdateTimeStamp.ToString());
|
||||||
writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID);
|
writer.WriteElementString("LastUpdateActorID", sop.LastUpdateActorID);
|
||||||
|
WriteBucketSyncInfo(writer, sop.BucketSyncInfoList);
|
||||||
//end of SYMMETRIC SYNC
|
//end of SYMMETRIC SYNC
|
||||||
|
|
||||||
writer.WriteEndElement();
|
writer.WriteEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SYMMETRIC SYNC
|
||||||
|
public static void WriteBucketSyncInfo(XmlTextWriter writer, Dictionary<string, BucketSyncInfo> bucketSyncInfoList)
|
||||||
|
{
|
||||||
|
if (bucketSyncInfoList!=null || bucketSyncInfoList.Count > 0) // otherwise skip this
|
||||||
|
{
|
||||||
|
|
||||||
|
writer.WriteStartElement("BucketSyncInfoList");
|
||||||
|
foreach (KeyValuePair<string, BucketSyncInfo> pair in bucketSyncInfoList)
|
||||||
|
{
|
||||||
|
BucketSyncInfo bucketSyncInfo = pair.Value;
|
||||||
|
writer.WriteStartElement("Bucket");
|
||||||
|
writer.WriteElementString("Name", bucketSyncInfo.BucketName);
|
||||||
|
writer.WriteElementString("TimeStamp", bucketSyncInfo.LastUpdateTimeStamp.ToString());
|
||||||
|
writer.WriteElementString("ActorID", bucketSyncInfo.LastUpdateActorID);
|
||||||
|
writer.WriteEndElement(); // Bucket
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndElement(); // BucketSyncInfo
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//end of SYMMETRIC SYNC
|
||||||
|
|
||||||
static void WriteUUID(XmlTextWriter writer, string name, UUID id, Dictionary<string, object> options)
|
static void WriteUUID(XmlTextWriter writer, string name, UUID id, Dictionary<string, object> options)
|
||||||
{
|
{
|
||||||
writer.WriteStartElement(name);
|
writer.WriteStartElement(name);
|
||||||
|
|
Loading…
Reference in New Issue