Merge branch 'dev_kitty' into dev

dsg
Huaiyu (Kitty) Liu 2011-02-14 11:36:57 -08:00
commit 2b2eb4dbe3
26 changed files with 1276 additions and 804 deletions

View File

@ -591,7 +591,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
} }
so.AbsolutePosition = AttachOffset; so.AbsolutePosition = AttachOffset;
so.RootPart.AttachedPos = AttachOffset; so.RootPart.AttachedPos = AttachOffset;
so.RootPart.IsAttachment = true; so.RootPart.IsAttachment = true;
so.RootPart.SetParentLocalId(avatar.LocalId); so.RootPart.SetParentLocalId(avatar.LocalId);
@ -611,7 +611,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
} }
so.IsSelected = false; // fudge.... so.IsSelected = false; // fudge....
so.ScheduleGroupForFullUpdate(); //so.ScheduleGroupForFullUpdate();
so.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //just force it to sychronize all properties
} }
// In case it is later dropped again, don't let // In case it is later dropped again, don't let

View File

@ -352,7 +352,8 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps
rootGroup.LinkToGroup(allparts[j]); rootGroup.LinkToGroup(allparts[j]);
} }
rootGroup.ScheduleGroupForFullUpdate(); //rootGroup.ScheduleGroupForFullUpdate();
rootGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //seems like new object
pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false); pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false);
responsedata["int_response_code"] = 200; //501; //410; //404; responsedata["int_response_code"] = 200; //501; //410; //404;

View File

@ -1581,7 +1581,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, silent)) if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, silent))
{ {
grp.OffsetForNewRegion(oldGroupPosition); grp.OffsetForNewRegion(oldGroupPosition);
grp.ScheduleGroupForFullUpdate(); //grp.ScheduleGroupForFullUpdate();
grp.ScheduleGroupForFullUpdate(SceneObjectPartProperties.Position);
} }
} }

View File

@ -600,7 +600,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// if not, we set it's position in world. // if not, we set it's position in world.
if (!attachment) if (!attachment)
{ {
group.ScheduleGroupForFullUpdate(); //group.ScheduleGroupForFullUpdate();
group.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object
float offsetHeight = 0; float offsetHeight = 0;
pos = m_Scene.GetNewRezLocation( pos = m_Scene.GetNewRezLocation(
@ -698,7 +699,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
rootPart.ParentGroup.ResumeScripts(); rootPart.ParentGroup.ResumeScripts();
rootPart.ScheduleFullUpdate(); //rootPart.ScheduleFullUpdate();
rootPart.ScheduleFullUpdate(SceneObjectPartProperties.FullUpdate);
} }
if (!m_Scene.Permissions.BypassPermissions()) if (!m_Scene.Permissions.BypassPermissions())

View File

@ -321,7 +321,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) updated.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString())); //RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) updated.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()));
//else //else
//RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) added.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString())); //RegionSyncMessage.HandleSuccess(LogHeader(), msg, String.Format("Object \"{0}\" ({1}) ({1}) added.", sog.Name, sog.UUID.ToString(), sog.LocalId.ToString()));
sog.ScheduleGroupForFullUpdate(); //sog.ScheduleGroupForFullUpdate();
} }
return; return;
} }

View File

@ -550,7 +550,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//the prim is not the root-part, set the offset position //the prim is not the root-part, set the offset position
primToUpdate.OffsetPosition = pos; primToUpdate.OffsetPosition = pos;
parent.HasGroupChanged = true; parent.HasGroupChanged = true;
parent.ScheduleGroupForTerseUpdate(); //parent.ScheduleGroupForTerseUpdate();
parent.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.OffsetPosition);
} }
} }

View File

@ -182,8 +182,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
get { return m_isSyncRelay; } get { return m_isSyncRelay; }
} }
private Dictionary<string, string> m_primPropertyBucketMap = new Dictionary<string, string>(); private Dictionary<SceneObjectPartProperties, string> m_primPropertyBucketMap = new Dictionary<SceneObjectPartProperties, string>();
public Dictionary<string, string> PrimPropertyBucketMap public Dictionary<SceneObjectPartProperties, string> PrimPropertyBucketMap
{ {
get { return m_primPropertyBucketMap; } get { return m_primPropertyBucketMap; }
} }
@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
PupolatePropertyBuketMapByDefault(); PupolatePropertyBuketMapByDefault();
//Pass the bucket information to SceneObjectPart. //Pass the bucket information to SceneObjectPart.
SceneObjectPart.InitializeBucketInfo(m_primPropertyBucketMap, m_propertyBucketDescription, m_actorID); SceneObjectPart.InitializePropertyBucketInfo(m_primPropertyBucketMap, m_propertyBucketDescription, m_actorID);
} }
@ -226,6 +226,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
m_propertyBucketDescription.Add(physicsBucketName); m_propertyBucketDescription.Add(physicsBucketName);
m_maxNumOfPropertyBuckets = 2; m_maxNumOfPropertyBuckets = 2;
/*
foreach (string pName in SceneObjectPart.PropertyList) foreach (string pName in SceneObjectPart.PropertyList)
{ {
switch (pName){ switch (pName){
@ -253,6 +254,36 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
break; break;
} }
} }
* */
foreach (SceneObjectPartProperties property in Enum.GetValues(typeof(SceneObjectPartProperties)))
{
switch (property)
{
case SceneObjectPartProperties.GroupPosition:
case SceneObjectPartProperties.OffsetPosition:
case SceneObjectPartProperties.Scale:
case SceneObjectPartProperties.Velocity:
case SceneObjectPartProperties.AngularVelocity:
case SceneObjectPartProperties.RotationOffset:
case SceneObjectPartProperties.Position:
case SceneObjectPartProperties.Size:
case SceneObjectPartProperties.Force:
case SceneObjectPartProperties.RotationalVelocity:
case SceneObjectPartProperties.PA_Acceleration:
case SceneObjectPartProperties.Torque:
case SceneObjectPartProperties.Orientation:
case SceneObjectPartProperties.IsPhysical:
case SceneObjectPartProperties.Flying:
case SceneObjectPartProperties.Buoyancy:
m_primPropertyBucketMap.Add(property, physicsBucketName);
break;
default:
//all other properties belong to the "General" bucket.
m_primPropertyBucketMap.Add(property, generalBucketName);
break;
}
}
} }
private bool IsSyncingWithOtherActors() private bool IsSyncingWithOtherActors()
@ -263,7 +294,28 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
public void QueueSceneObjectPartForUpdate(SceneObjectPart part) public void QueueSceneObjectPartForUpdate(SceneObjectPart part)
{ {
//if the last update of the prim is caused by this actor itself, or if the actor is a relay node, then enqueue the update //if the last update of the prim is caused by this actor itself, or if the actor is a relay node, then enqueue the update
if (part.LastUpdateActorID.Equals(m_actorID) || m_isSyncRelay) //if (part.LastUpdateActorID.Equals(m_actorID) || m_isSyncRelay)
bool updated = m_isSyncRelay;
if (!updated)
{
/*
foreach (KeyValuePair<string, BucketSyncInfo> pair in part.BucketSyncInfoList)
{
if (pair.Value.LastUpdateActorID.Equals(m_actorID))
{
updated = true;
break;
}
}
* */
if (part.HasPropertyUpdatedLocally())
{
updated = true;
}
}
if(updated)
{ {
lock (m_updateSceneObjectPartLock) lock (m_updateSceneObjectPartLock)
{ {
@ -274,10 +326,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
public void QueueScenePresenceForTerseUpdate(ScenePresence presence) public void QueueScenePresenceForTerseUpdate(ScenePresence presence)
{ {
/*
lock (m_updateScenePresenceLock) lock (m_updateScenePresenceLock)
{ {
m_presenceUpdates[presence.UUID] = presence; m_presenceUpdates[presence.UUID] = presence;
} }
* */
} }
//SendSceneUpdates put each update into an outgoing queue of each SyncConnector //SendSceneUpdates put each update into an outgoing queue of each SyncConnector
@ -321,6 +375,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
if (primUpdates != null || presenceUpdates != null) if (primUpdates != null || presenceUpdates != null)
{ {
long timeStamp = DateTime.Now.Ticks;
// This could be another thread for sending outgoing messages or just have the Queue functions // This could be another thread for sending outgoing messages or just have the Queue functions
// create and queue the messages directly into the outgoing server thread. // create and queue the messages directly into the outgoing server thread.
System.Threading.ThreadPool.QueueUserWorkItem(delegate System.Threading.ThreadPool.QueueUserWorkItem(delegate
@ -333,6 +389,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
foreach (SceneObjectGroup sog in primUpdates) foreach (SceneObjectGroup sog in primUpdates)
{ {
//If this is a relay node, or at least one part of the object has the last update caused by this actor, then send the update //If this is a relay node, or at least one part of the object has the last update caused by this actor, then send the update
sog.UpdateTaintedBucketSyncInfo(timeStamp);
if (m_isSyncRelay || (!sog.IsDeleted && CheckObjectForSendingUpdate(sog))) if (m_isSyncRelay || (!sog.IsDeleted && CheckObjectForSendingUpdate(sog)))
{ {
//send //send
@ -459,6 +516,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
return; return;
} }
//First, make sure the linked group has updated timestamp info for synchronization
linkedGroup.BucketSyncInfoUpdate();
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);
@ -517,6 +577,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
groupNum++; groupNum++;
} }
//make sure the newly delinked objects have the updated timestamp information
foreach (SceneObjectGroup sog in afterDelinkGroups)
{
sog.BucketSyncInfoUpdate();
}
SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.DelinkObject, OSDParser.SerializeJsonString(data)); SymmetricSyncMessage rsm = new SymmetricSyncMessage(SymmetricSyncMessage.MsgType.DelinkObject, OSDParser.SerializeJsonString(data));
SendDelinkObjectToRelevantSyncConnectors(beforeDelinkGroups, rsm); SendDelinkObjectToRelevantSyncConnectors(beforeDelinkGroups, rsm);
} }
@ -741,7 +807,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
} }
/// <summary> /// <summary>
/// Check if we need to send out an update message for the given object. /// Check if we need to send out an update message for the given object. For now, we have a very inefficient solution:
/// If any synchronization bucket in any part shows a property in that bucket has changed, we'll serialize and ship the whole object.
/// </summary> /// </summary>
/// <param name="sog"></param> /// <param name="sog"></param>
/// <returns></returns> /// <returns></returns>
@ -750,10 +817,20 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//If any part in the object has the last update caused by this actor itself, then send the update //If any part in the object has the last update caused by this actor itself, then send the update
foreach (SceneObjectPart part in sog.Parts) foreach (SceneObjectPart part in sog.Parts)
{ {
/*
if (part.LastUpdateActorID.Equals(m_actorID)) if (part.LastUpdateActorID.Equals(m_actorID))
{ {
return true; return true;
} }
* */
foreach (KeyValuePair<string, BucketSyncInfo> pair in part.BucketSyncInfoList)
{
if (pair.Value.LastUpdateActorID.Equals(m_actorID))
{
return true;
}
}
} }
return false; return false;
@ -991,6 +1068,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
//save script state and stop script instances //save script state and stop script instances
m_scene.EventManager.TriggerOnSymmetricSyncStop(); m_scene.EventManager.TriggerOnSymmetricSyncStop();
} }
m_synced = true;
} }
else else
{ {
@ -1072,11 +1150,10 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
{ {
syncConnector.StartCommThreads(); syncConnector.StartCommThreads();
AddSyncConnector(syncConnector); AddSyncConnector(syncConnector);
m_synced = true;
} }
} }
m_synced = true;
return true; return true;
} }

View File

@ -236,7 +236,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
part.Shape.Media[face] = me; part.Shape.Media[face] = me;
UpdateMediaUrl(part, UUID.Zero); UpdateMediaUrl(part, UUID.Zero);
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.MediaUrl);
part.TriggerScriptChangedEvent(Changed.MEDIA); part.TriggerScriptChangedEvent(Changed.MEDIA);
} }
@ -421,7 +422,9 @@ namespace OpenSim.Region.CoreModules.Media.Moap
UpdateMediaUrl(part, agentId); UpdateMediaUrl(part, agentId);
// Arguably, we could avoid sending a full update to the avatar that just changed the texture. // Arguably, we could avoid sending a full update to the avatar that just changed the texture.
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.Shape);
part.ScheduleFullUpdate(SceneObjectPartProperties.MediaUrl); //not an efficient way to taint two properties, but should not have bad side effects
part.TriggerScriptChangedEvent(Changed.MEDIA); part.TriggerScriptChangedEvent(Changed.MEDIA);
@ -499,7 +502,8 @@ namespace OpenSim.Region.CoreModules.Media.Moap
UpdateMediaUrl(part, agentId); UpdateMediaUrl(part, agentId);
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.MediaUrl);
part.TriggerScriptChangedEvent(Changed.MEDIA); part.TriggerScriptChangedEvent(Changed.MEDIA);

View File

@ -148,7 +148,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
part.GetProperties(remoteClient); part.GetProperties(remoteClient);
part.TriggerScriptChangedEvent(Changed.OWNER); part.TriggerScriptChangedEvent(Changed.OWNER);
group.ResumeScripts(); group.ResumeScripts();
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.FullUpdate); //quite some properties changed, let's just force all to be synchronized
break; break;

View File

@ -56,6 +56,15 @@ namespace OpenSim.Region.Framework.Interfaces
DSGActorTypes DSGActorType { get; set; } DSGActorTypes DSGActorType { get; set; }
bool IsSyncRelay { get; } bool IsSyncRelay { get; }
/// <summary>
/// The mapping of a property (identified by its name) to the index of a bucket.
/// </summary>
Dictionary<SceneObjectPartProperties, string> PrimPropertyBucketMap { get; }
/// <summary>
/// The text description of the properties in each bucket, e.g. "General", "Physics"
/// </summary>
List<string> PropertyBucketDescription { get; }
//Enqueue updates for scene-objects and scene-presences //Enqueue updates for scene-objects and scene-presences
void QueueSceneObjectPartForUpdate(SceneObjectPart part); void QueueSceneObjectPartForUpdate(SceneObjectPart part);
void QueueScenePresenceForTerseUpdate(ScenePresence presence); void QueueScenePresenceForTerseUpdate(ScenePresence presence);

View File

@ -34,7 +34,8 @@ namespace OpenSim.Region.Framework.Interfaces
{ {
void Reset(); void Reset();
void Close(); void Close();
void QueuePartForUpdate(SceneObjectPart part); //void QueuePartForUpdate(SceneObjectPart part);
void QueuePartForUpdate(SceneObjectPartBase part);
void SendPrimUpdates(); void SendPrimUpdates();
} }
} }

View File

@ -1720,7 +1720,7 @@ namespace OpenSim.Region.Framework.Scenes
* */ * */
if (RegionSyncModule != null) if (RegionSyncModule != null)
{ {
part.SyncInfoUpdate(); //part.SyncInfoUpdate();
EventManager.TriggerNewScript(remoteClient.AgentId, part, copyID); EventManager.TriggerNewScript(remoteClient.AgentId, part, copyID);
} }
else else
@ -1798,7 +1798,7 @@ namespace OpenSim.Region.Framework.Scenes
//part.ParentGroup.ResumeScripts(); //part.ParentGroup.ResumeScripts();
if (RegionSyncModule != null) if (RegionSyncModule != null)
{ {
part.SyncInfoUpdate(); //part.SyncInfoUpdate();
EventManager.TriggerNewScript(remoteClient.AgentId, part, taskItem.ItemID); EventManager.TriggerNewScript(remoteClient.AgentId, part, taskItem.ItemID);
} }
else else
@ -2197,7 +2197,8 @@ namespace OpenSim.Region.Framework.Scenes
// to find out if scripts should be activated at all. // to find out if scripts should be activated at all.
group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
group.ScheduleGroupForFullUpdate(); //group.ScheduleGroupForFullUpdate();
group.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object, all properties have new value
return group; return group;
} }
@ -2262,7 +2263,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
sog.SetOwnerId(ownerID); sog.SetOwnerId(ownerID);
sog.SetGroup(groupID, remoteClient); sog.SetGroup(groupID, remoteClient);
sog.ScheduleGroupForFullUpdate(); //sog.ScheduleGroupForFullUpdate();
sog.ScheduleGroupForFullUpdate(SceneObjectPartProperties.OwnerID);
SceneObjectPart[] partList = sog.Parts; SceneObjectPart[] partList = sog.Parts;

View File

@ -208,11 +208,12 @@ namespace OpenSim.Region.Framework.Scenes
// TODO: Make selection flagging per prim! // TODO: Make selection flagging per prim!
// //
part.ParentGroup.IsSelected = false; part.ParentGroup.IsSelected = false;
if (part.ParentGroup.IsAttachment) if (part.ParentGroup.IsAttachment)
isAttachment = true; isAttachment = true;
else else
part.ParentGroup.ScheduleGroupForFullUpdate(); //part.ParentGroup.ScheduleGroupForFullUpdate();
part.ParentGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.IsSelected);
// If it's not an attachment, and we are allowed to move it, // If it's not an attachment, and we are allowed to move it,
// then we might have done so. If we moved across a parcel // then we might have done so. If we moved across a parcel

View File

@ -795,7 +795,7 @@ namespace OpenSim.Region.Framework.Scenes
//Set the property values as in the incoming copy of the object group //Set the property values as in the incoming copy of the object group
SceneObjectGroup localGroup = root.ParentGroup; SceneObjectGroup localGroup = root.ParentGroup;
localGroup.UpdateObjectProperties(linkedGroup); localGroup.UpdateObjectGroupBySync(linkedGroup);
//debug //debug
/* /*
@ -2391,7 +2391,8 @@ namespace OpenSim.Region.Framework.Scenes
sceneObject.SetGroup(groupID, null); sceneObject.SetGroup(groupID, null);
} }
sceneObject.ScheduleGroupForFullUpdate(); //sceneObject.ScheduleGroupForFullUpdate();
sceneObject.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object, all properties have new value
return sceneObject; return sceneObject;
} }
@ -2560,16 +2561,6 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
//SYMMETRIC SYNC
//Set the ActorID and TimeStamp info for this latest update
/*
foreach (SceneObjectPart part in group.Parts)
{
part.SyncInfoUpdate();
}
*
* */
//Propagate the RemovedObject message //Propagate the RemovedObject message
if (RegionSyncModule != null) if (RegionSyncModule != null)
{ {
@ -4500,7 +4491,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); //((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); //This is not due to property being updated, hence passing "None" property.
} }
} }
} }

View File

@ -374,7 +374,8 @@ namespace OpenSim.Region.Framework.Scenes
if (scale.Z > m_parentScene.m_maxNonphys) if (scale.Z > m_parentScene.m_maxNonphys)
scale.Z = m_parentScene.m_maxNonphys; scale.Z = m_parentScene.m_maxNonphys;
part.Shape.Scale = scale; //part.Shape.Scale = scale;
part.Scale = scale;
} }
} }
m_numPrim += children.Length; m_numPrim += children.Length;
@ -382,7 +383,8 @@ namespace OpenSim.Region.Framework.Scenes
sceneObject.AttachToScene(m_parentScene); sceneObject.AttachToScene(m_parentScene);
if (sendClientUpdates) if (sendClientUpdates)
sceneObject.ScheduleGroupForFullUpdate(); //sceneObject.ScheduleGroupForFullUpdate();
sceneObject.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None);
Entities.Add(sceneObject); Entities.Add(sceneObject);
@ -1599,7 +1601,6 @@ namespace OpenSim.Region.Framework.Scenes
if (m_parentScene.RegionSyncModule != null) if (m_parentScene.RegionSyncModule != null)
{ {
//Tell other actors to link the SceneObjectParts together as a new group. //Tell other actors to link the SceneObjectParts together as a new group.
parentGroup.SyncInfoUpdate();
m_parentScene.RegionSyncModule.SendLinkObject(parentGroup, root, children); m_parentScene.RegionSyncModule.SendLinkObject(parentGroup, root, children);
} }
@ -1746,20 +1747,11 @@ namespace OpenSim.Region.Framework.Scenes
} }
//SYMMETRIC SYNC //SYMMETRIC SYNC
//set timestamp
long timeStamp = DateTime.Now.Ticks;
string actorID = m_parentScene.GetSyncActorID();
foreach (SceneObjectGroup sog in afterDelinkGroups)
{
if (m_parentScene.RegionSyncModule != null)
{
sog.SyncInfoUpdate(timeStamp, actorID); ;
}
}
//Send out DelinkObject message to other actors to sychronize their object list //Send out DelinkObject message to other actors to sychronize their object list
m_parentScene.RegionSyncModule.SendDeLinkObject(prims, beforeDelinkGroups, afterDelinkGroups); if (m_parentScene.RegionSyncModule != null)
{
m_parentScene.RegionSyncModule.SendDeLinkObject(prims, beforeDelinkGroups, afterDelinkGroups);
}
//Schedule updates as in legacy OpenSim code, to send updates to viewers connected to this actor (at least needed for client managers). //Schedule updates as in legacy OpenSim code, to send updates to viewers connected to this actor (at least needed for client managers).
//But timestamp won't be changed, so that when other actors get the update, they's simple ignore the updates since they already get them //But timestamp won't be changed, so that when other actors get the update, they's simple ignore the updates since they already get them
foreach (SceneObjectGroup sog in afterDelinkGroups) foreach (SceneObjectGroup sog in afterDelinkGroups)
@ -1902,7 +1894,8 @@ namespace OpenSim.Region.Framework.Scenes
copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1); copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1);
copy.HasGroupChanged = true; copy.HasGroupChanged = true;
copy.ScheduleGroupForFullUpdate(); //copy.ScheduleGroupForFullUpdate();
copy.ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //new object, all property values are new
copy.ResumeScripts(); copy.ResumeScripts();
// required for physics to update it's position // required for physics to update it's position
@ -1971,7 +1964,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
//if we need to debug the script engine with a viewer attaching to it, //if we need to debug the script engine with a viewer attaching to it,
//we need to schedule updates to be sent to the viewer //we need to schedule updates to be sent to the viewer
oldSog.ScheduleGroupForFullUpdate(); oldSog.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None);
} }
} }
else else
@ -2051,7 +2044,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
foreach (SceneObjectPart part in children) foreach (SceneObjectPart part in children)
{ {
Vector3 scale = part.Shape.Scale; SceneObjectPartBase partBase = (SceneObjectPartBase)part;
Vector3 scale = partBase.Scale;
if (scale.X > m_parentScene.m_maxNonphys) if (scale.X > m_parentScene.m_maxNonphys)
scale.X = m_parentScene.m_maxNonphys; scale.X = m_parentScene.m_maxNonphys;
@ -2060,12 +2054,15 @@ namespace OpenSim.Region.Framework.Scenes
if (scale.Z > m_parentScene.m_maxNonphys) if (scale.Z > m_parentScene.m_maxNonphys)
scale.Z = m_parentScene.m_maxNonphys; scale.Z = m_parentScene.m_maxNonphys;
part.Shape.Scale = scale; part.Scale = scale;
} }
} }
m_numPrim += children.Length; m_numPrim += children.Length;
//SYMMETRIC SYNC,
sceneObject.AttachToScene(m_parentScene); sceneObject.AttachToScene(m_parentScene);
//sceneObject.AttachToSceneBySync(m_parentScene);
//end of SYMMETRIC SYNC,
//SYMMETRIC SYNC, //SYMMETRIC SYNC,
sceneObject.ScheduleGroupForFullUpdate_SyncInfoUnchanged(); sceneObject.ScheduleGroupForFullUpdate_SyncInfoUnchanged();
@ -2140,8 +2137,18 @@ namespace OpenSim.Region.Framework.Scenes
// Make sure no child prim is set for sale // Make sure no child prim is set for sale
// So that, on delink, no prims are unwittingly // So that, on delink, no prims are unwittingly
// left for sale and sold off // left for sale and sold off
child.RootPart.ObjectSaleType = 0; //SYMMETRIC SYNC: need to copy value w/o trigger UpdateBucketSyncInfo
child.RootPart.SalePrice = 10; //child.RootPart.ObjectSaleType = 0;
//child.RootPart.SalePrice = 10;
//child.RootPart.SetObjectSaleType(0);
//child.RootPart.SetSalePrice(10);
//child.RootPart.SetProperty("ObjectSaleType", 0);
//child.RootPart.SetProperty("SalePrice", 10);
//casting SOP to SOPBase to make sure we call SOPBase.Property set function, not the SOP.Property set function
SceneObjectPartBase rootPart = (SceneObjectPartBase)child.RootPart;
rootPart.ObjectSaleType = 0;
rootPart.SalePrice = 10;
childGroups.Add(child); childGroups.Add(child);
} }
} }
@ -2291,7 +2298,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
localAfterGroup.UpdateObjectProperties(incomingAfterDelinkGroupsDictionary[localAfterGroup.UUID]); localAfterGroup.UpdateObjectGroupBySync(incomingAfterDelinkGroupsDictionary[localAfterGroup.UUID]);
} }
} }
} }

View File

@ -294,6 +294,12 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_rootPart.GroupPosition; } get { return m_rootPart.GroupPosition; }
set set
{ {
/*
SetAbsolutePosition(value);
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
parts[i].UpdateBucketSyncInfo("GroupPosition");
*/
Vector3 val = value; Vector3 val = value;
//REGION SYNC touched //REGION SYNC touched
@ -328,6 +334,39 @@ namespace OpenSim.Region.Framework.Scenes
//m_rootPart.GroupPosition.Z); //m_rootPart.GroupPosition.Z);
//m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
//} //}
}
}
public void SetAbsolutePosition(Vector3 value)
{
Vector3 val = value;
//REGION SYNC touched
//if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
// || m_scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || m_scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
// && !IsAttachmentCheckFull())
if (m_scene.IsBorderCrossing(LocX, LocY, val) && !IsAttachmentCheckFull() && (!m_scene.LoadingPrims))
{
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
}
//end REGION SYNC touched
if (RootPart.GetStatusSandbox())
{
if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
{
RootPart.ScriptSetPhysicsStatus(false);
Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"),
ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false);
return;
}
}
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
{
parts[i].GroupPosition = val;
//parts[i].SetGroupPosition(val);
} }
} }
@ -465,6 +504,20 @@ namespace OpenSim.Region.Framework.Scenes
#region Constructors #region Constructors
//SYMMETRIC SYNC
public SceneObjectGroup(SceneObjectPart part, bool newGroupBySync)
{
if (!newGroupBySync)
{
SetRootPart(part);
}
else
{
SetRootPartBySync(part);
}
}
/// <summary> /// <summary>
/// Constructor /// Constructor
/// </summary> /// </summary>
@ -969,7 +1022,8 @@ namespace OpenSim.Region.Framework.Scenes
RootPart.RemFlag(PrimFlags.TemporaryOnRez); RootPart.RemFlag(PrimFlags.TemporaryOnRez);
AttachToBackup(); AttachToBackup();
m_scene.EventManager.TriggerParcelPrimCountTainted(); m_scene.EventManager.TriggerParcelPrimCountTainted();
m_rootPart.ScheduleFullUpdate(); //m_rootPart.ScheduleFullUpdate();
m_rootPart.ScheduleFullUpdate(SceneObjectPartProperties.AttachmentPoint); //Physics properties, such as Position, OffsetPosition, etc, should be tainted in ApplyPhysics()
m_rootPart.ClearUndoState(); m_rootPart.ClearUndoState();
} }
@ -1242,7 +1296,8 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.RemoveGroupTarget(this); m_scene.RemoveGroupTarget(this);
} }
ScheduleGroupForFullUpdate(); //ScheduleGroupForFullUpdate();
ScheduleGroupForFullUpdate(SceneObjectPartProperties.Flags);
} }
public void SetText(string text, Vector3 color, double alpha) public void SetText(string text, Vector3 color, double alpha)
@ -1254,7 +1309,8 @@ namespace OpenSim.Region.Framework.Scenes
Text = text; Text = text;
HasGroupChanged = true; HasGroupChanged = true;
m_rootPart.ScheduleFullUpdate(); //m_rootPart.ScheduleFullUpdate();
m_rootPart.ScheduleFullUpdate(SceneObjectPartProperties.Text);
} }
/// <summary> /// <summary>
@ -1488,7 +1544,8 @@ namespace OpenSim.Region.Framework.Scenes
dupe.HasGroupChanged = true; dupe.HasGroupChanged = true;
dupe.AttachToBackup(); dupe.AttachToBackup();
ScheduleGroupForFullUpdate(); //ScheduleGroupForFullUpdate();
ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); //This full-update is triggered by copying, no property changed
} }
return dupe; return dupe;
@ -1741,7 +1798,8 @@ namespace OpenSim.Region.Framework.Scenes
ApplyNextOwnerPermissions(); ApplyNextOwnerPermissions();
} }
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.OwnerID);
} }
/// <summary> /// <summary>
@ -1866,33 +1924,38 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Schedule a full update for this scene object /// Schedule a full update for this scene object
/// </summary> /// </summary>
public void ScheduleGroupForFullUpdate() //public void ScheduleGroupForFullUpdate()
public void ScheduleGroupForFullUpdate(SceneObjectPartProperties property)
{ {
// if (IsAttachment) // if (IsAttachment)
// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId); // m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId);
checkAtTargets(); checkAtTargets();
RootPart.ScheduleFullUpdate(); //RootPart.ScheduleFullUpdate();
RootPart.ScheduleFullUpdate(property);
SceneObjectPart[] parts = m_parts.GetArray(); SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
{ {
SceneObjectPart part = parts[i]; SceneObjectPart part = parts[i];
if (part != RootPart) if (part != RootPart)
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(property);
} }
} }
/// <summary> /// <summary>
/// Schedule a terse update for this scene object /// Schedule a terse update for this scene object
/// </summary> /// </summary>
public void ScheduleGroupForTerseUpdate() //public void ScheduleGroupForTerseUpdate()
public void ScheduleGroupForTerseUpdate(SceneObjectPartProperties property)
{ {
// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID);
SceneObjectPart[] parts = m_parts.GetArray(); SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
parts[i].ScheduleTerseUpdate(); //parts[i].ScheduleTerseUpdate();
parts[i].ScheduleTerseUpdate(property);
} }
/// <summary> /// <summary>
@ -2650,7 +2713,8 @@ namespace OpenSim.Region.Framework.Scenes
HasGroupChanged = true; HasGroupChanged = true;
part.TriggerScriptChangedEvent(Changed.SCALE); part.TriggerScriptChangedEvent(Changed.SCALE);
ScheduleGroupForFullUpdate(); //ScheduleGroupForFullUpdate();
ScheduleGroupForFullUpdate(SceneObjectPartProperties.None); //above actions only update Scale for the given part, and part.Resize() will taint Scale as updated
//if (part.UUID == m_rootPart.UUID) //if (part.UUID == m_rootPart.UUID)
//{ //{
@ -2802,7 +2866,8 @@ namespace OpenSim.Region.Framework.Scenes
part.StoreUndoState(); part.StoreUndoState();
HasGroupChanged = true; HasGroupChanged = true;
m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
ScheduleGroupForTerseUpdate(); //ScheduleGroupForTerseUpdate();
ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Scale);
} }
} }
@ -2843,7 +2908,8 @@ namespace OpenSim.Region.Framework.Scenes
//we need to do a terse update even if the move wasn't allowed //we need to do a terse update even if the move wasn't allowed
// so that the position is reset in the client (the object snaps back) // so that the position is reset in the client (the object snaps back)
ScheduleGroupForTerseUpdate(); //ScheduleGroupForTerseUpdate();
ScheduleGroupForTerseUpdate(SceneObjectPartProperties.GroupPosition);
} }
/// <summary> /// <summary>
@ -2906,7 +2972,8 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = newPos; AbsolutePosition = newPos;
HasGroupChanged = true; HasGroupChanged = true;
ScheduleGroupForTerseUpdate(); //ScheduleGroupForTerseUpdate();
ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Position);
} }
public void OffsetForNewRegion(Vector3 offset) public void OffsetForNewRegion(Vector3 offset)
@ -2938,7 +3005,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
HasGroupChanged = true; HasGroupChanged = true;
ScheduleGroupForTerseUpdate(); //ScheduleGroupForTerseUpdate();
ScheduleGroupForTerseUpdate(SceneObjectPartProperties.None); //Above actions only update m_rootPart's RotationOffset, and m_rootPart.UpdateRotation will taint RotationOffset as updated
} }
/// <summary> /// <summary>
@ -2964,7 +3032,8 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = pos; AbsolutePosition = pos;
HasGroupChanged = true; HasGroupChanged = true;
ScheduleGroupForTerseUpdate(); //ScheduleGroupForTerseUpdate();
ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Position); //RotationOffset is only updated for m_rootPart, and m_rootPart.UpdateRotation should already taint RotationOffset as updated
} }
/// <summary> /// <summary>
@ -3051,7 +3120,8 @@ namespace OpenSim.Region.Framework.Scenes
Quaternion newRot = primsRot * oldParentRot; Quaternion newRot = primsRot * oldParentRot;
newRot *= Quaternion.Inverse(axRot); newRot *= Quaternion.Inverse(axRot);
prim.RotationOffset = newRot; prim.RotationOffset = newRot;
prim.ScheduleTerseUpdate(); //prim.ScheduleTerseUpdate();
prim.ScheduleTerseUpdate(SceneObjectPartProperties.RotationOffset | SceneObjectPartProperties.OffsetPosition);
} }
} }
@ -3065,7 +3135,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
m_rootPart.ScheduleTerseUpdate(); //m_rootPart.ScheduleTerseUpdate();
m_rootPart.ScheduleTerseUpdate(SceneObjectPartProperties.RotationOffset);
} }
#endregion #endregion
@ -3694,12 +3765,16 @@ namespace OpenSim.Region.Framework.Scenes
} }
//Similar actions with DelinkFromGroup, except that m_scene.AddNewSceneObjectBySync is called //Similar actions with DelinkFromGroup, except that m_scene.AddNewSceneObjectBySync is called
public SceneObjectGroup DelinkFromGroupBySync(SceneObjectPart linkPart, bool sendEvents) //!!!!!!!!!!!!!!!!!!NOTE!!!!!!!!!!!!!!!
//All SOP properties below is set through calling SetXXX(value) instead of by "XXX=value", as such a value is being changed due to sync (
//i.e. triggered by remote operation instead of by local operation
public SceneObjectGroup DelinkFromGroupBySync(SceneObjectPart delinkPart, bool sendEvents)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}", // "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID); // linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);
SceneObjectPartBase linkPart = (SceneObjectPartBase)delinkPart;
linkPart.ClearUndoState(); linkPart.ClearUndoState();
Quaternion worldRot = linkPart.GetWorldRotation(); Quaternion worldRot = linkPart.GetWorldRotation();
@ -3714,21 +3789,28 @@ namespace OpenSim.Region.Framework.Scenes
if (parts.Length == 1 && RootPart != null) if (parts.Length == 1 && RootPart != null)
{ {
// Single prim left // Single prim left
RootPart.LinkNum = 0; //RootPart.LinkNum = 0;
//RootPart.SetProperty("LinkNum", 0);
((SceneObjectPartBase)RootPart).LinkNum = 0;
} }
else else
{ {
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
{ {
SceneObjectPart part = parts[i]; SceneObjectPartBase part = (SceneObjectPartBase)parts[i];
if (part.LinkNum > linkPart.LinkNum) if (part.LinkNum > linkPart.LinkNum)
{
part.LinkNum--; part.LinkNum--;
//int linkNum = part.LinkNum - 1;
//part.SetProperty("LinkNum", linkNum);
}
} }
} }
} }
linkPart.ParentID = 0; linkPart.ParentID = 0; //ParentID is a value set only locally and ignored in synchronization, so no need to call SetProperty to set its value
linkPart.LinkNum = 0; linkPart.LinkNum = 0;
//linkPart.SetParentID(0);
if (linkPart.PhysActor != null) if (linkPart.PhysActor != null)
{ {
@ -3745,10 +3827,20 @@ namespace OpenSim.Region.Framework.Scenes
linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z); linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z);
linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition; linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition;
linkPart.OffsetPosition = new Vector3(0, 0, 0); linkPart.OffsetPosition = new Vector3(0, 0, 0);
linkPart.RotationOffset = worldRot; linkPart.RotationOffset = worldRot;
SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart); //linkPart.SetOffsetPosition(new Vector3(axPos.X, axPos.Y, axPos.Z));
//linkPart.SetGroupPosition(AbsolutePosition + linkPart.OffsetPosition);
//linkPart.SetOffsetPosition(new Vector3(0, 0, 0));
//linkPart.SetRotationOffset(worldRot);
//linkPart.SetProperty("OffsetPosition", new Vector3(axPos.X, axPos.Y, axPos.Z));
//linkPart.SetProperty("GroupPosition", AbsolutePosition + linkPart.OffsetPosition);
//linkPart.SetProperty("OffsetPosition", new Vector3(0, 0, 0));
//linkPart.SetProperty("RotationOffset", worldRot);
//SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart);
bool newGroupBySync = true;
SceneObjectGroup objectGroup = new SceneObjectGroup(delinkPart, newGroupBySync);
m_scene.AddNewSceneObjectBySync(objectGroup, true); m_scene.AddNewSceneObjectBySync(objectGroup, true);
@ -3764,7 +3856,24 @@ namespace OpenSim.Region.Framework.Scenes
return objectGroup; return objectGroup;
} }
/// <summary>
/// Set a part to act as the root part for this scene object, in which SetProperty("LinkNum",) is called instead of "LinkNum=".
/// </summary>
/// <param name="part"></param>
public void SetRootPartBySync(SceneObjectPart part)
{
if (part == null)
throw new ArgumentNullException("Cannot give SceneObjectGroup a null root SceneObjectPart");
part.SetParent(this);
m_rootPart = part;
if (!IsAttachment)
part.ParentID = 0;
// part.SetProperty("LinkNum", 0);
((SceneObjectPartBase)part).LinkNum = 0;
m_parts.Add(m_rootPart.UUID, m_rootPart);
}
public void ScheduleGroupForFullUpdate_SyncInfoUnchanged() public void ScheduleGroupForFullUpdate_SyncInfoUnchanged()
{ {
@ -3788,30 +3897,40 @@ namespace OpenSim.Region.Framework.Scenes
public void LinkToGroupBySync(SceneObjectGroup objectGroup) public void LinkToGroupBySync(SceneObjectGroup objectGroup)
{ {
SceneObjectPart linkPart = objectGroup.m_rootPart; SceneObjectPartBase linkPart = (SceneObjectPartBase)objectGroup.m_rootPart;
Vector3 oldGroupPosition = linkPart.GroupPosition; Vector3 oldGroupPosition = linkPart.GroupPosition;
Quaternion oldRootRotation = linkPart.RotationOffset; Quaternion oldRootRotation = linkPart.RotationOffset;
linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition; linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition;
linkPart.GroupPosition = AbsolutePosition; linkPart.GroupPosition = AbsolutePosition;
//linkPart.SetOffsetPosition(linkPart.GroupPosition - AbsolutePosition);
//linkPart.SetGroupPosition(AbsolutePosition);
//linkPart.SetProperty("OffsetPosition", linkPart.GroupPosition - AbsolutePosition);
//linkPart.SetProperty("GroupPosition", AbsolutePosition);
Vector3 axPos = linkPart.OffsetPosition; Vector3 axPos = linkPart.OffsetPosition;
Quaternion parentRot = m_rootPart.RotationOffset; Quaternion parentRot = m_rootPart.RotationOffset;
axPos *= Quaternion.Inverse(parentRot); axPos *= Quaternion.Inverse(parentRot);
linkPart.OffsetPosition = axPos; linkPart.OffsetPosition = axPos;
//linkPart.SetOffsetPosition(axPos);
//linkPart.SetProperty("OffsetPosition", axPos);
Quaternion oldRot = linkPart.RotationOffset; Quaternion oldRot = linkPart.RotationOffset;
Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot;
linkPart.RotationOffset = newRot; linkPart.RotationOffset = newRot;
//linkPart.SetRotationOffset(newRot);
//linkPart.SetProperty("RotationOffset", newRot);
//ParentID is only valid locally, so remote value is ignored and no syncinfo will be modified
linkPart.ParentID = m_rootPart.LocalId; linkPart.ParentID = m_rootPart.LocalId;
if (m_rootPart.LinkNum == 0) if (m_rootPart.LinkNum == 0)
m_rootPart.LinkNum = 1; ((SceneObjectPartBase)m_rootPart).LinkNum = 1;
//m_rootPart.SetProperty("LinkNum",1);
lock (m_parts.SyncRoot) lock (m_parts.SyncRoot)
{ {
m_parts.Add(linkPart.UUID, linkPart); m_parts.Add(linkPart.UUID, (SceneObjectPart) linkPart);
// Insert in terms of link numbers, the new links // Insert in terms of link numbers, the new links
// before the current ones (with the exception of // before the current ones (with the exception of
@ -3819,15 +3938,17 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart[] parts = m_parts.GetArray(); SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
{ {
SceneObjectPart part = parts[i]; SceneObjectPartBase part = (SceneObjectPartBase)parts[i];
if (part.LinkNum != 1) if (part.LinkNum != 1)
{ {
// Don't update root prim link number // Don't update root prim link number
part.LinkNum += objectGroup.PrimCount; part.LinkNum += objectGroup.PrimCount;
//part.SetProperty("LinkNum",objectGroup.PrimCount);
} }
} }
linkPart.LinkNum = 2; linkPart.LinkNum = 2;
//linkPart.SetProperty("LinkNum",2);
linkPart.SetParent(this); linkPart.SetParent(this);
linkPart.CreateSelected = true; linkPart.CreateSelected = true;
@ -3846,7 +3967,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
SceneObjectPart part = ogParts[i]; SceneObjectPart part = ogParts[i];
if (part.UUID != objectGroup.m_rootPart.UUID) if (part.UUID != objectGroup.m_rootPart.UUID)
LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); LinkNonRootPartBySync(part, oldGroupPosition, oldRootRotation, linkNum++);
part.ClearUndoState(); part.ClearUndoState();
} }
} }
@ -3864,20 +3985,80 @@ namespace OpenSim.Region.Framework.Scenes
// Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the // 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 // position of linkset prims. IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and
// unmoved prims! // unmoved prims!
ResetChildPrimPhysicsPositions(); //ResetChildPrimPhysicsPositions();
//EntityBase sogBase = (EntityBase)this;
//sogBase.AbsolutePosition = AbsolutePosition;
SetAbsolutePosition(AbsolutePosition);
} }
public void SyncInfoUpdate() private void LinkNonRootPartBySync(SceneObjectPart linkPart, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum)
{
Quaternion parentRot = oldGroupRotation;
Quaternion oldRot = linkPart.RotationOffset;
Quaternion worldRot = parentRot * oldRot;
parentRot = oldGroupRotation;
Vector3 axPos = linkPart.OffsetPosition;
SceneObjectPartBase part = (SceneObjectPartBase)linkPart;
axPos *= parentRot;
part.OffsetPosition = axPos;
part.GroupPosition = oldGroupPosition + part.OffsetPosition;
part.OffsetPosition = Vector3.Zero;
part.RotationOffset = worldRot;
//part.SetOffsetPosition(axPos);
//part.SetGroupPosition(oldGroupPosition + part.OffsetPosition);
//part.SetOffsetPosition(Vector3.Zero);
//part.SetRotationOffset(worldRot);
//part.SetProperty("OffsetPosition", axPos);
//part.SetProperty("GroupPosition", oldGroupPosition + part.OffsetPosition);
//part.SetProperty("OffsetPosition", Vector3.Zero);
//part.SetProperty("RotationOffset", worldRot);
part.SetParent(this);
part.ParentID = m_rootPart.LocalId;
m_parts.Add(part.UUID, linkPart);
part.LinkNum = linkNum;
//part.SetProperty("LinkNum",linkNum);
part.OffsetPosition = part.GroupPosition - AbsolutePosition;
//part.SetOffsetPosition(part.GroupPosition - AbsolutePosition);
//part.SetProperty("OffsetPosition", part.GroupPosition - AbsolutePosition);
Quaternion rootRotation = m_rootPart.RotationOffset;
Vector3 pos = part.OffsetPosition;
pos *= Quaternion.Inverse(rootRotation);
part.OffsetPosition = pos;
//part.SetOffsetPosition(pos);
//part.SetProperty("OffsetPosition", pos);
parentRot = m_rootPart.RotationOffset;
oldRot = part.RotationOffset;
Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot;
part.RotationOffset = newRot;
//part.SetRotationOffset(newRot);
//part.SetProperty("RotationOffset", newRot);
}
public void BucketSyncInfoUpdate()
{ {
long timeStamp = DateTime.Now.Ticks; long timeStamp = DateTime.Now.Ticks;
string actorID = m_scene.GetSyncActorID(); string actorID = m_scene.GetSyncActorID();
foreach (SceneObjectPart part in Parts) foreach (SceneObjectPart part in Parts)
{ {
part.SyncInfoUpdate(timeStamp, actorID); //part.SyncInfoUpdate(timeStamp, actorID);
part.UpdateAllBucketSyncInfo(timeStamp);
} }
} }
/*
public void SyncInfoUpdate(long timeStamp, string actorID) public void SyncInfoUpdate(long timeStamp, string actorID)
{ {
foreach (SceneObjectPart part in Parts) foreach (SceneObjectPart part in Parts)
@ -3885,6 +4066,53 @@ namespace OpenSim.Region.Framework.Scenes
part.SyncInfoUpdate(timeStamp, actorID); part.SyncInfoUpdate(timeStamp, actorID);
} }
} }
* */
/// <summary>
/// Attach this object to a scene after a new object is created due to receiving a sync message.
/// Code similar to AttachToScene, except that this does not invoke InitializeBucketSyncInfo of each part,
/// as that information is included in the incoming message.
/// </summary>
/// <param name="scene"></param>
public void AttachToSceneBySync(Scene scene)
{
m_scene = scene;
RegionHandle = m_scene.RegionInfo.RegionHandle;
if (m_rootPart.Shape.PCode != 9 || m_rootPart.Shape.State == 0)
m_rootPart.ParentID = 0;
if (m_rootPart.LocalId == 0)
m_rootPart.LocalId = m_scene.AllocateLocalId();
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart part = parts[i];
if (Object.ReferenceEquals(part, m_rootPart))
continue;
if (part.LocalId == 0)
part.LocalId = m_scene.AllocateLocalId();
part.ParentID = m_rootPart.LocalId;
//m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
}
ApplyPhysics(m_scene.m_physicalPrim);
// 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.
//ScheduleGroupForFullUpdate();
}
public void UpdateTaintedBucketSyncInfo(long timeStamp)
{
foreach (SceneObjectPart part in Parts)
{
part.UpdateTaintedBucketSyncInfo(timeStamp);
}
}
#endregion #endregion
} }

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,8 @@ using OpenSim.Region.Framework.Scenes.Serialization;
namespace OpenSim.Region.Framework.Scenes namespace OpenSim.Region.Framework.Scenes
{ {
public class SceneObjectPartInventory : IEntityInventory //public class SceneObjectPartInventory : IEntityInventory
public class SceneObjectPartInventoryBase : IEntityInventory
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -52,7 +53,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <value> /// <value>
/// The part to which the inventory belongs. /// The part to which the inventory belongs.
/// </value> /// </value>
private SceneObjectPart m_part; //private SceneObjectPart m_part;
private SceneObjectPartBase m_part;
/// <summary> /// <summary>
/// Serial count for inventory file , used to tell if inventory has changed /// Serial count for inventory file , used to tell if inventory has changed
@ -98,7 +100,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="part"> /// <param name="part">
/// A <see cref="SceneObjectPart"/> /// A <see cref="SceneObjectPart"/>
/// </param> /// </param>
public SceneObjectPartInventory(SceneObjectPart part) //public SceneObjectPartInventory(SceneObjectPart part)
public SceneObjectPartInventoryBase(SceneObjectPartBase part)
{ {
m_part = part; m_part = part;
} }
@ -291,7 +294,7 @@ namespace OpenSim.Region.Framework.Scenes
m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
m_part.ParentGroup.AddActiveScriptCount(1); m_part.ParentGroup.AddActiveScriptCount(1);
m_part.ScheduleFullUpdate(); m_part.ScheduleFullUpdate(SceneObjectPartProperties.Flags | SceneObjectPartProperties.TaskInventory);
return; return;
} }
@ -319,7 +322,7 @@ namespace OpenSim.Region.Framework.Scenes
m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
m_part.ParentGroup.AddActiveScriptCount(1); m_part.ParentGroup.AddActiveScriptCount(1);
m_part.ScheduleFullUpdate(); m_part.ScheduleFullUpdate(SceneObjectPartProperties.Flags | SceneObjectPartProperties.TaskInventory);
} }
} }
} }
@ -543,7 +546,7 @@ namespace OpenSim.Region.Framework.Scenes
m_part.ParentGroup.HasGroupChanged = true; m_part.ParentGroup.HasGroupChanged = true;
//SYMMETRIC SYNC: add ScheduleFullUpdate to enable synchronization across actors //SYMMETRIC SYNC: add ScheduleFullUpdate to enable synchronization across actors
m_part.ScheduleFullUpdate(); m_part.ScheduleFullUpdate(SceneObjectPartProperties.TaskInventory | SceneObjectPartProperties.InventorySerial);
} }
/// <summary> /// <summary>
@ -763,7 +766,7 @@ namespace OpenSim.Region.Framework.Scenes
if (!ContainsScripts()) if (!ContainsScripts())
m_part.RemFlag(PrimFlags.Scripted); m_part.RemFlag(PrimFlags.Scripted);
m_part.ScheduleFullUpdate(); m_part.ScheduleFullUpdate(SceneObjectPartProperties.TaskInventory);
return type; return type;
@ -1172,4 +1175,25 @@ namespace OpenSim.Region.Framework.Scenes
} }
#endregion REGION SYNC #endregion REGION SYNC
} }
#region SYMMETRIC SYNC
public class SceneObjectPartInventory : SceneObjectPartInventoryBase
{
private SceneObjectPart m_part;
public SceneObjectPartInventory(SceneObjectPart part):base((SceneObjectPartBase) part)
{
m_part = part;
}
new protected internal uint Serial
{
get { return base.Serial; }
set
{
base.Serial = value;
//m_part.UpdateBucketSyncInfo("InventorySerial");
}
}
}
#endregion
} }

View File

@ -57,11 +57,12 @@ namespace OpenSim.Region.Framework.Scenes
/// Add the part to the queue of parts for which we need to send an update to the client /// Add the part to the queue of parts for which we need to send an update to the client
/// </summary> /// </summary>
/// <param name="part"></param> /// <param name="part"></param>
public void QueuePartForUpdate(SceneObjectPart part) //public void QueuePartForUpdate(SceneObjectPart part)
public void QueuePartForUpdate(SceneObjectPartBase part)
{ {
lock (m_partsUpdateQueue) lock (m_partsUpdateQueue)
{ {
m_partsUpdateQueue.Enqueue(part); m_partsUpdateQueue.Enqueue((SceneObjectPart)part);
} }
} }

View File

@ -330,8 +330,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem); m_SOPXmlProcessors.Add("ParticleSystem", ProcessParticleSystem);
//SYMMETRIC SYNC //SYMMETRIC SYNC
m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp); m_SOPXmlProcessors.Add("LocalFlags", ProcessLocalFlags);
m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID); //m_SOPXmlProcessors.Add("LastUpdateTimeStamp", ProcessUpdateTimeStamp);
//m_SOPXmlProcessors.Add("LastUpdateActorID", ProcessLastUpdateActorID);
m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo); m_SOPXmlProcessors.Add("BucketSyncInfoList", ProcessBucketSyncInfo);
//end of SYMMETRIC SYNC //end of SYMMETRIC SYNC
@ -422,8 +423,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
//That is, calling SetXXX(value) instead of using "XXX = value". //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)); //obj.SetAllowedDrop(Util.ReadBoolean(reader));
} }
private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader) private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader)
@ -488,32 +489,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")); //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")); //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")); //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")); //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")); //obj.SetVelocity(Util.ReadVector(reader, "AngularVelocity"));
} }
private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader) private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader)
@ -572,8 +573,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")); //obj.SetScale(Util.ReadVector(reader, "Scale"));
} }
private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader) private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader)
@ -703,6 +704,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
//SYMMETRIC SYNC //SYMMETRIC SYNC
/*
private static void ProcessUpdateTimeStamp(SceneObjectPart obj, XmlTextReader reader) private static void ProcessUpdateTimeStamp(SceneObjectPart obj, XmlTextReader reader)
{ {
obj.LastUpdateTimeStamp = reader.ReadElementContentAsLong("LastUpdateTimeStamp", string.Empty); obj.LastUpdateTimeStamp = reader.ReadElementContentAsLong("LastUpdateTimeStamp", string.Empty);
@ -712,6 +714,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
{ {
obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty); obj.LastUpdateActorID = reader.ReadElementContentAsString("LastUpdateActorID", string.Empty);
} }
* */
private static void ProcessLocalFlags(SceneObjectPart obj, XmlTextReader reader)
{
obj.LocalFlags = Util.ReadEnum<PrimFlags>(reader, "LocalFlags");
}
public static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader) public static void ProcessBucketSyncInfo(SceneObjectPart obj, XmlTextReader reader)
{ {
@ -1234,8 +1242,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteElementString("EveryoneMask", sop.EveryoneMask.ToString()); writer.WriteElementString("EveryoneMask", sop.EveryoneMask.ToString());
writer.WriteElementString("NextOwnerMask", sop.NextOwnerMask.ToString()); writer.WriteElementString("NextOwnerMask", sop.NextOwnerMask.ToString());
//SYMMETRIC SYNC: also serialize SceneObjectPart:LocalFlags, so that it can be propogated across actors //SYMMETRIC SYNC: also serialize SceneObjectPart:LocalFlags, so that it can be propogated across actors
//WriteFlags(writer, "Flags", sop.Flags.ToString(), options); WriteFlags(writer, "Flags", sop.Flags.ToString(), options);
WriteFlags(writer, "Flags", sop.GetEffectiveObjectFlags().ToString(), options); WriteFlags(writer, "LocalFlags", sop.LocalFlags.ToString(), options);
//writer.WriteElementString("Flags", sop.Flags.ToString());
//writer.WriteElementString("LocalFlags", sop.Flags.ToString());
//end SYMMETRIC SYNC //end SYMMETRIC SYNC
WriteUUID(writer, "CollisionSound", sop.CollisionSound, options); WriteUUID(writer, "CollisionSound", sop.CollisionSound, options);
writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString()); writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString());
@ -1245,8 +1255,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
WriteBytes(writer, "ParticleSystem", sop.ParticleSystem); WriteBytes(writer, "ParticleSystem", sop.ParticleSystem);
//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); WriteBucketSyncInfo(writer, sop.BucketSyncInfoList);
//end of SYMMETRIC SYNC //end of SYMMETRIC SYNC

View File

@ -62,7 +62,7 @@ namespace OpenSim.Region.Framework.Scenes.Types
} }
} }
public void Enqueue(SceneObjectPart part) public void Enqueue(SceneObjectPart part)
{ {
lock (m_syncObject) lock (m_syncObject)
{ {

View File

@ -91,7 +91,8 @@ namespace OpenSim.Region.Framework.Scenes
part.RotationOffset = Rotation; part.RotationOffset = Rotation;
if (Scale != Vector3.Zero) if (Scale != Vector3.Zero)
part.Resize(Scale); part.Resize(Scale);
part.ParentGroup.ScheduleGroupForTerseUpdate(); //part.ParentGroup.ScheduleGroupForTerseUpdate();
part.ParentGroup.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Scale);
} }
else else
{ {
@ -99,7 +100,8 @@ namespace OpenSim.Region.Framework.Scenes
part.OffsetPosition = Position; part.OffsetPosition = Position;
part.UpdateRotation(Rotation); part.UpdateRotation(Rotation);
if (Scale != Vector3.Zero) if (Scale != Vector3.Zero)
part.Resize(Scale); part.ScheduleTerseUpdate(); part.Resize(Scale); //part.ScheduleTerseUpdate();
part.ScheduleTerseUpdate(SceneObjectPartProperties.Scale);
} }
part.Undoing = false; part.Undoing = false;
@ -119,7 +121,8 @@ namespace OpenSim.Region.Framework.Scenes
part.UpdateRotation(Rotation); part.UpdateRotation(Rotation);
if (Scale != Vector3.Zero) if (Scale != Vector3.Zero)
part.Resize(Scale); part.Resize(Scale);
part.ParentGroup.ScheduleGroupForTerseUpdate(); //part.ParentGroup.ScheduleGroupForTerseUpdate();
part.ParentGroup.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.Scale);
} }
else else
{ {
@ -129,7 +132,9 @@ namespace OpenSim.Region.Framework.Scenes
part.UpdateRotation(Rotation); part.UpdateRotation(Rotation);
if (Scale != Vector3.Zero) if (Scale != Vector3.Zero)
part.Resize(Scale); part.Resize(Scale);
part.ScheduleTerseUpdate(); //part.ScheduleTerseUpdate();
part.ScheduleTerseUpdate(SceneObjectPartProperties.Scale);
} }
part.Undoing = false; part.Undoing = false;

View File

@ -290,7 +290,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
((SceneObjectGroup)ent).ApplyPhysics(true); ((SceneObjectGroup)ent).ApplyPhysics(true);
((SceneObjectGroup)ent).AttachToBackup(); ((SceneObjectGroup)ent).AttachToBackup();
((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected. ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected.
((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(); //((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
((SceneObjectGroup)ent).ScheduleGroupForFullUpdate(SceneObjectPartProperties.FullUpdate); //don't know what properties to taint, so just taint all
} }
catch(Exception e) catch(Exception e)
{ {

View File

@ -640,7 +640,8 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
{ {
s_tree.Scale += copse.m_rate; s_tree.Scale += copse.m_rate;
s_tree.ParentGroup.HasGroupChanged = true; s_tree.ParentGroup.HasGroupChanged = true;
s_tree.ScheduleFullUpdate(); //s_tree.ScheduleFullUpdate();
s_tree.ScheduleFullUpdate(SceneObjectPartProperties.Scale);
} }
} }
else else

View File

@ -1411,7 +1411,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
m_host.ClickAction = (byte)action; m_host.ClickAction = (byte)action;
if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true; if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true;
m_host.ScheduleFullUpdate(); //m_host.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.ClickAction);
return; return;
} }
@ -1679,7 +1680,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
part.ParentGroup.HasGroupChanged = true; part.ParentGroup.HasGroupChanged = true;
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.Shape);
} }
/// <summary> /// <summary>
@ -1714,7 +1716,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
part.ParentGroup.HasGroupChanged = true; part.ParentGroup.HasGroupChanged = true;
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
part.ScheduleFullUpdate(SceneObjectPartProperties.Shape);
} }
public LSL_Vector llGetColor(int face) public LSL_Vector llGetColor(int face)
@ -1982,40 +1985,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
targetPos.z = ground; targetPos.z = ground;
SceneObjectGroup parent = part.ParentGroup; SceneObjectGroup parent = part.ParentGroup;
LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos);
//KittyL: edited below parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
if ((World.ScriptEngineToSceneConnectorModule == null))
{
parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
}
else
{
object[] valParams = new object[1];
Vector3 pos = new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z);
valParams[0] = (Vector3)pos;
World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "pos", (object)valParams);
}
} }
else else
{ {
LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos);
part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
//KittyL: edited below SceneObjectGroup parent = part.ParentGroup;
if ((World.ScriptEngineToSceneConnectorModule == null)) parent.HasGroupChanged = true;
{ //parent.ScheduleGroupForTerseUpdate();
part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); parent.ScheduleGroupForTerseUpdate(SceneObjectPartProperties.OffsetPosition);
SceneObjectGroup parent = part.ParentGroup;
parent.HasGroupChanged = true;
parent.ScheduleGroupForTerseUpdate();
}
else
{
object[] valParams = new object[3];
valParams[0] = (object)rel_vec.x;
valParams[1] = (object)rel_vec.y;
valParams[2] = (object)rel_vec.z;
World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "pos", (object)valParams);
}
} }
} }
@ -2361,7 +2340,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.SoundFlags = 1; // looping m_host.SoundFlags = 1; // looping
m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable?
m_host.ScheduleFullUpdate(); //m_host.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
m_host.SendFullUpdateToAllClients(); m_host.SendFullUpdateToAllClients();
} }
@ -2381,7 +2361,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
prim.SoundFlags = 1; // looping prim.SoundFlags = 1; // looping
prim.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? prim.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable?
prim.ScheduleFullUpdate(); //prim.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
prim.SendFullUpdateToAllClients(); prim.SendFullUpdateToAllClients();
} }
} }
@ -2393,7 +2374,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.SoundFlags = 1; // looping m_host.SoundFlags = 1; // looping
m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable? m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable?
m_host.ScheduleFullUpdate(); //m_host.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
m_host.SendFullUpdateToAllClients(); m_host.SendFullUpdateToAllClients();
} }
@ -2435,7 +2417,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
part.SoundGain = 0; part.SoundGain = 0;
part.SoundFlags = 0; part.SoundFlags = 0;
part.SoundRadius = 0; part.SoundRadius = 0;
part.ScheduleFullUpdate(); //part.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
part.SendFullUpdateToAllClients(); part.SendFullUpdateToAllClients();
} }
m_host.ParentGroup.LoopSoundMasterPrim = null; m_host.ParentGroup.LoopSoundMasterPrim = null;
@ -2447,7 +2430,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.SoundGain = 0; m_host.SoundGain = 0;
m_host.SoundFlags = 0; m_host.SoundFlags = 0;
m_host.SoundRadius = 0; m_host.SoundRadius = 0;
m_host.ScheduleFullUpdate(); //m_host.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
m_host.SendFullUpdateToAllClients(); m_host.SendFullUpdateToAllClients();
} }
} }
@ -2457,7 +2441,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.SoundGain = 0; m_host.SoundGain = 0;
m_host.SoundFlags = 0; m_host.SoundFlags = 0;
m_host.SoundRadius = 0; m_host.SoundRadius = 0;
m_host.ScheduleFullUpdate(); //m_host.ScheduleFullUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.Sound);
m_host.SendFullUpdateToAllClients(); m_host.SendFullUpdateToAllClients();
} }
} }
@ -3384,7 +3369,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
m_host.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)); m_host.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate));
m_host.ScheduleTerseUpdate(); //m_host.ScheduleTerseUpdate();
m_host.ScheduleFullUpdate(SceneObjectPartProperties.AngularVelocity);
m_host.SendTerseUpdateToAllClients(); m_host.SendTerseUpdateToAllClients();
m_host.ParentGroup.HasGroupChanged = true; m_host.ParentGroup.HasGroupChanged = true;
} }
@ -3664,7 +3650,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);
parentPrim.RootPart.CreateSelected = true; parentPrim.RootPart.CreateSelected = true;
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); //parentPrim.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC
//Schedule a LinkObject message for synchronization purpose. This will lead to enqueue a LinkObject message in SyncConnector's outgoingQueue,
//so should return quickly.
if (World.RegionSyncModule != null)
{
//Tell other actors to link the SceneObjectParts together as a new group.
//parentGroup.SyncInfoUpdate();
World.RegionSyncModule.SendLinkObject(parentPrim, parentPrim.RootPart, new List<SceneObjectPart>(childPrim.Parts));
}
m_host.ScheduleFullUpdate(SceneObjectPartProperties.None); //SendLinkObject above will synchronize the link operation, no need to taint updates here
//end of SYMMETRIC SYNC
if (client != null) if (client != null)
parentPrim.GetProperties(client); parentPrim.GetProperties(client);
@ -3722,15 +3719,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (linknum == ScriptBaseClass.LINK_ROOT) if (linknum == ScriptBaseClass.LINK_ROOT)
{ {
//SYMMETRIC SYNC
List<SceneObjectGroup> beforeDelinkGroups = new List<SceneObjectGroup>();
beforeDelinkGroups.Add(parentPrim);
List<SceneObjectGroup> afterDelinkGroups = new List<SceneObjectGroup>();
//end of SYMMETRIC SYNC
// Restructuring Multiple Prims. // Restructuring Multiple Prims.
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
parts.Remove(parentPrim.RootPart); parts.Remove(parentPrim.RootPart);
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
{ {
parentPrim.DelinkFromGroup(part.LocalId, true); parentPrim.DelinkFromGroup(part.LocalId, true);
//SYMMETRIC SYNC
afterDelinkGroups.Add(part.ParentGroup);
} }
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); //parentPrim.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC
//Send out DelinkObject message to other actors to sychronize their object list
if (World.RegionSyncModule != null)
{
World.RegionSyncModule.SendDeLinkObject(parts, beforeDelinkGroups, afterDelinkGroups);
}
parentPrim.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None);
//end of SYMMETRIC SYNC
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);
if (parts.Count > 0) if (parts.Count > 0)
@ -3743,7 +3756,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
newRoot.ParentGroup.LinkToGroup(part.ParentGroup); newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
} }
newRoot.ParentGroup.HasGroupChanged = true; newRoot.ParentGroup.HasGroupChanged = true;
newRoot.ParentGroup.ScheduleGroupForFullUpdate(); //newRoot.ParentGroup.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC
if (World.RegionSyncModule != null)
{
World.RegionSyncModule.SendLinkObject(newRoot.ParentGroup, newRoot, new List<SceneObjectPart>(newRoot.ParentGroup.Parts));
}
newRoot.ParentGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None);
//end of SYMMETRIC SYNC
} }
} }
else else
@ -3753,7 +3774,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
parentPrim.DelinkFromGroup(childPrim.LocalId, true); parentPrim.DelinkFromGroup(childPrim.LocalId, true);
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); //parentPrim.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNC
//Send out DelinkObject message to other actors to sychronize their object list
if (World.RegionSyncModule != null)
{
List<SceneObjectGroup> beforeDelinkGroups = new List<SceneObjectGroup>();
beforeDelinkGroups.Add(parentPrim);
List<SceneObjectGroup> afterDelinkGroups = new List<SceneObjectGroup>();
afterDelinkGroups.Add(childPrim.ParentGroup);
World.RegionSyncModule.SendDeLinkObject(new List<SceneObjectPart>(parentPrim.Parts), beforeDelinkGroups, afterDelinkGroups);
}
//end of SYMMETRIC SYNC
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);
} }
} }
@ -3765,6 +3798,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (parentPrim.RootPart.AttachmentPoint != 0) if (parentPrim.RootPart.AttachmentPoint != 0)
return; // Fail silently if attached return; // Fail silently if attached
//SYMMETRIC SYNC
List<SceneObjectGroup> beforeDelinkGroups = new List<SceneObjectGroup>();
beforeDelinkGroups.Add(parentPrim);
List<SceneObjectGroup> afterDelinkGroups = new List<SceneObjectGroup>();
SceneObjectPart rootPart = parentPrim.RootPart;
//end of SYMMETRIC SYNC
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
parts.Remove(parentPrim.RootPart); parts.Remove(parentPrim.RootPart);
@ -3772,9 +3812,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
parentPrim.DelinkFromGroup(part.LocalId, true); parentPrim.DelinkFromGroup(part.LocalId, true);
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);
//SYMMETRIC SYNC
afterDelinkGroups.Add(part.ParentGroup);
} }
parentPrim.HasGroupChanged = true; parentPrim.HasGroupChanged = true;
parentPrim.ScheduleGroupForFullUpdate(); //parentPrim.ScheduleGroupForFullUpdate();
//SYMMETRIC SYNCF
if (World.RegionSyncModule != null)
{
parts.Add(rootPart);
afterDelinkGroups.Add(rootPart.ParentGroup);
World.RegionSyncModule.SendDeLinkObject(parts, beforeDelinkGroups, afterDelinkGroups);
}
parentPrim.ScheduleGroupForFullUpdate(SceneObjectPartProperties.None);
//end of SYMMETRIC SYNC
} }
public LSL_String llGetLinkKey(int linknum) public LSL_String llGetLinkKey(int linknum)
@ -4012,7 +4063,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
Util.Clip((float)color.z, 0.0f, 1.0f)); Util.Clip((float)color.z, 0.0f, 1.0f));
m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
m_host.ParentGroup.HasGroupChanged = true; m_host.ParentGroup.HasGroupChanged = true;
m_host.ParentGroup.ScheduleGroupForFullUpdate(); //m_host.ParentGroup.ScheduleGroupForFullUpdate();
m_host.ParentGroup.ScheduleGroupForFullUpdate(SceneObjectPartProperties.Text);
} }
public LSL_Float llWater(LSL_Vector offset) public LSL_Float llWater(LSL_Vector offset)

View File

@ -2349,7 +2349,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
obj.ParentGroup.HasGroupChanged = true; obj.ParentGroup.HasGroupChanged = true;
obj.ScheduleFullUpdate(); //obj.ScheduleFullUpdate();
obj.ScheduleFullUpdate(SceneObjectPartProperties.Shape);
} }