mirror of
https://github.com/opensim/opensim.git
synced 2026-08-08 10:15:33 +08:00
bad merge?
This commit is contained in:
@@ -41,6 +41,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
public delegate void PhysicsCrash();
|
||||
|
||||
public delegate void AttachToBackupDelegate(SceneObjectGroup sog);
|
||||
|
||||
public delegate void DetachFromBackupDelegate(SceneObjectGroup sog);
|
||||
|
||||
public delegate void ChangedBackupDelegate(SceneObjectGroup sog);
|
||||
|
||||
/// <summary>
|
||||
/// This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph components
|
||||
/// should be migrated out over time.
|
||||
@@ -54,11 +60,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
protected internal event PhysicsCrash UnRecoverableError;
|
||||
private PhysicsCrash handlerPhysicsCrash = null;
|
||||
|
||||
public event AttachToBackupDelegate OnAttachToBackup;
|
||||
public event DetachFromBackupDelegate OnDetachFromBackup;
|
||||
public event ChangedBackupDelegate OnChangeBackup;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
protected object m_presenceLock = new object();
|
||||
protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim();
|
||||
protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>();
|
||||
protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>();
|
||||
|
||||
@@ -129,13 +139,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
protected internal void Close()
|
||||
{
|
||||
lock (m_presenceLock)
|
||||
m_scenePresencesLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
|
||||
List<ScenePresence> newlist = new List<ScenePresence>();
|
||||
m_scenePresenceMap = newmap;
|
||||
m_scenePresenceArray = newlist;
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_scenePresencesLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
SceneObjectGroupsByFullID.Clear();
|
||||
@@ -256,13 +271,54 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
protected internal bool AddRestoredSceneObject(
|
||||
SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
|
||||
{
|
||||
if (!m_parentScene.CombineRegions)
|
||||
{
|
||||
// temporary checks to remove after varsize suport
|
||||
float regionSizeX = m_parentScene.RegionInfo.RegionSizeX;
|
||||
if (regionSizeX == 0)
|
||||
regionSizeX = Constants.RegionSize;
|
||||
float regionSizeY = m_parentScene.RegionInfo.RegionSizeY;
|
||||
if (regionSizeY == 0)
|
||||
regionSizeY = Constants.RegionSize;
|
||||
|
||||
// KF: Check for out-of-region, move inside and make static.
|
||||
Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
|
||||
sceneObject.RootPart.GroupPosition.Y,
|
||||
sceneObject.RootPart.GroupPosition.Z);
|
||||
if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 ||
|
||||
npos.X > regionSizeX ||
|
||||
npos.Y > regionSizeY))
|
||||
{
|
||||
if (npos.X < 0.0) npos.X = 1.0f;
|
||||
if (npos.Y < 0.0) npos.Y = 1.0f;
|
||||
if (npos.Z < 0.0) npos.Z = 0.0f;
|
||||
if (npos.X > regionSizeX) npos.X = regionSizeX - 1.0f;
|
||||
if (npos.Y > regionSizeY) npos.Y = regionSizeY - 1.0f;
|
||||
|
||||
SceneObjectPart rootpart = sceneObject.RootPart;
|
||||
rootpart.GroupPosition = npos;
|
||||
|
||||
foreach (SceneObjectPart part in sceneObject.Parts)
|
||||
{
|
||||
if (part == rootpart)
|
||||
continue;
|
||||
part.GroupPosition = npos;
|
||||
}
|
||||
rootpart.Velocity = Vector3.Zero;
|
||||
rootpart.AngularVelocity = Vector3.Zero;
|
||||
rootpart.Acceleration = Vector3.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
bool ret = AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
|
||||
|
||||
if (attachToBackup && (!alreadyPersisted))
|
||||
{
|
||||
sceneObject.ForceInventoryPersistence();
|
||||
sceneObject.HasGroupChanged = true;
|
||||
}
|
||||
|
||||
return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -279,12 +335,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </returns>
|
||||
protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
|
||||
{
|
||||
// Ensure that we persist this new scene object if it's not an
|
||||
|
||||
bool ret = AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
|
||||
|
||||
// Ensure that we persist this new scene object if it's not an
|
||||
// attachment
|
||||
|
||||
if (attachToBackup)
|
||||
sceneObject.HasGroupChanged = true;
|
||||
|
||||
return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -319,9 +379,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (pa != null && pa.IsPhysical && vel != Vector3.Zero)
|
||||
{
|
||||
sceneObject.RootPart.ApplyImpulse((vel * sceneObject.GetMass()), false);
|
||||
sceneObject.Velocity = vel;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -346,6 +405,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </returns>
|
||||
protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
|
||||
{
|
||||
if (sceneObject == null)
|
||||
{
|
||||
m_log.ErrorFormat("[SCENEGRAPH]: Tried to add null scene object");
|
||||
return false;
|
||||
}
|
||||
if (sceneObject.UUID == UUID.Zero)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
@@ -378,9 +442,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
Vector3 scale = part.Shape.Scale;
|
||||
|
||||
scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X));
|
||||
scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y));
|
||||
scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z));
|
||||
scale.X = Util.Clamp(scale.X, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys);
|
||||
scale.Y = Util.Clamp(scale.Y, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys);
|
||||
scale.Z = Util.Clamp(scale.Z, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys);
|
||||
|
||||
part.Shape.Scale = scale;
|
||||
}
|
||||
@@ -401,36 +465,39 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
sceneObject.AttachToScene(m_parentScene);
|
||||
|
||||
if (sendClientUpdates)
|
||||
sceneObject.ScheduleGroupForFullUpdate();
|
||||
|
||||
Entities.Add(sceneObject);
|
||||
|
||||
if (attachToBackup)
|
||||
sceneObject.AttachToBackup();
|
||||
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
|
||||
|
||||
lock (SceneObjectGroupsByFullPartID)
|
||||
foreach (SceneObjectPart part in parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in parts)
|
||||
lock (SceneObjectGroupsByFullPartID)
|
||||
SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
|
||||
}
|
||||
|
||||
lock (SceneObjectGroupsByLocalPartID)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}",
|
||||
// sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName);
|
||||
|
||||
foreach (SceneObjectPart part in parts)
|
||||
lock (SceneObjectGroupsByLocalPartID)
|
||||
SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
|
||||
}
|
||||
|
||||
if (sendClientUpdates)
|
||||
sceneObject.ScheduleGroupForFullUpdate();
|
||||
|
||||
if (attachToBackup)
|
||||
sceneObject.AttachToBackup();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp)
|
||||
{
|
||||
// no tests, caller has responsability...
|
||||
lock (SceneObjectGroupsByFullPartID)
|
||||
SceneObjectGroupsByFullPartID[part.UUID] = grp;
|
||||
|
||||
lock (SceneObjectGroupsByLocalPartID)
|
||||
SceneObjectGroupsByLocalPartID[part.LocalId] = grp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete an object from the scene
|
||||
/// </summary>
|
||||
@@ -471,25 +538,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
|
||||
RemovePhysicalPrim(grp.PrimCount);
|
||||
}
|
||||
|
||||
|
||||
bool ret = Entities.Remove(uuid);
|
||||
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
SceneObjectGroupsByFullID.Remove(grp.UUID);
|
||||
|
||||
lock (SceneObjectGroupsByFullPartID)
|
||||
SceneObjectPart[] parts = grp.Parts;
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
SceneObjectPart[] parts = grp.Parts;
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
lock (SceneObjectGroupsByFullPartID)
|
||||
SceneObjectGroupsByFullPartID.Remove(parts[i].UUID);
|
||||
}
|
||||
|
||||
lock (SceneObjectGroupsByLocalPartID)
|
||||
{
|
||||
SceneObjectPart[] parts = grp.Parts;
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
lock (SceneObjectGroupsByLocalPartID)
|
||||
SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId);
|
||||
}
|
||||
|
||||
return Entities.Remove(uuid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -504,6 +569,30 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_updateList[obj.UUID] = obj;
|
||||
}
|
||||
|
||||
public void FireAttachToBackup(SceneObjectGroup obj)
|
||||
{
|
||||
if (OnAttachToBackup != null)
|
||||
{
|
||||
OnAttachToBackup(obj);
|
||||
}
|
||||
}
|
||||
|
||||
public void FireDetachFromBackup(SceneObjectGroup obj)
|
||||
{
|
||||
if (OnDetachFromBackup != null)
|
||||
{
|
||||
OnDetachFromBackup(obj);
|
||||
}
|
||||
}
|
||||
|
||||
public void FireChangeBackup(SceneObjectGroup obj)
|
||||
{
|
||||
if (OnChangeBackup != null)
|
||||
{
|
||||
OnChangeBackup(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process all pending updates
|
||||
/// </summary>
|
||||
@@ -595,7 +684,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
Entities[presence.UUID] = presence;
|
||||
|
||||
lock (m_presenceLock)
|
||||
m_scenePresencesLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
m_numChildAgents++;
|
||||
|
||||
@@ -621,6 +711,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_scenePresenceMap = newmap;
|
||||
m_scenePresenceArray = newlist;
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_scenePresencesLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
return presence;
|
||||
}
|
||||
@@ -637,7 +731,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
agentID);
|
||||
}
|
||||
|
||||
lock (m_presenceLock)
|
||||
m_scenePresencesLock.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
|
||||
List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
|
||||
@@ -659,6 +754,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_scenePresencesLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
|
||||
@@ -887,7 +986,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_log.WarnFormat(
|
||||
"[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.",
|
||||
sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
|
||||
|
||||
m_log.WarnFormat("stack: {0}", Environment.StackTrace);
|
||||
SceneObjectGroupsByLocalPartID.Remove(localID);
|
||||
}
|
||||
}
|
||||
@@ -1223,6 +1322,52 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
#region Client Event handlers
|
||||
|
||||
protected internal void ClientChangeObject(uint localID, object odata, IClientAPI remoteClient)
|
||||
{
|
||||
SceneObjectPart part = GetSceneObjectPart(localID);
|
||||
ObjectChangeData data = (ObjectChangeData)odata;
|
||||
|
||||
if (part != null)
|
||||
{
|
||||
SceneObjectGroup grp = part.ParentGroup;
|
||||
if (grp != null)
|
||||
{
|
||||
if (m_parentScene.Permissions.CanEditObject(grp.UUID, remoteClient.AgentId))
|
||||
{
|
||||
// These two are exceptions SL makes in the interpretation
|
||||
// of the change flags. Must check them here because otherwise
|
||||
// the group flag (see below) would be lost
|
||||
if (data.change == ObjectChangeType.groupS)
|
||||
data.change = ObjectChangeType.primS;
|
||||
if (data.change == ObjectChangeType.groupPS)
|
||||
data.change = ObjectChangeType.primPS;
|
||||
part.StoreUndoState(data.change); // lets test only saving what we changed
|
||||
grp.doChangeObject(part, (ObjectChangeData)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is this any kind of group operation?
|
||||
if ((data.change & ObjectChangeType.Group) != 0)
|
||||
{
|
||||
// Is a move and/or rotation requested?
|
||||
if ((data.change & (ObjectChangeType.Position | ObjectChangeType.Rotation)) != 0)
|
||||
{
|
||||
// Are we allowed to move it?
|
||||
if (m_parentScene.Permissions.CanMoveObject(grp.UUID, remoteClient.AgentId))
|
||||
{
|
||||
// Strip all but move and rotation from request
|
||||
data.change &= (ObjectChangeType.Group | ObjectChangeType.Position | ObjectChangeType.Rotation);
|
||||
|
||||
part.StoreUndoState(data.change);
|
||||
grp.doChangeObject(part, (ObjectChangeData)data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the scale of an individual prim.
|
||||
/// </summary>
|
||||
@@ -1237,7 +1382,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId))
|
||||
{
|
||||
bool physbuild = false;
|
||||
if (part.ParentGroup.RootPart.PhysActor != null)
|
||||
{
|
||||
part.ParentGroup.RootPart.PhysActor.Building = true;
|
||||
physbuild = true;
|
||||
}
|
||||
|
||||
part.Resize(scale);
|
||||
|
||||
if (physbuild)
|
||||
part.ParentGroup.RootPart.PhysActor.Building = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1249,7 +1404,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
|
||||
{
|
||||
bool physbuild = false;
|
||||
if (group.RootPart.PhysActor != null)
|
||||
{
|
||||
group.RootPart.PhysActor.Building = true;
|
||||
physbuild = true;
|
||||
}
|
||||
|
||||
group.GroupResize(scale);
|
||||
|
||||
if (physbuild)
|
||||
group.RootPart.PhysActor.Building = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1388,8 +1553,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
|
||||
{
|
||||
if (m_parentScene.AttachmentsModule != null)
|
||||
m_parentScene.AttachmentsModule.UpdateAttachmentPosition(group, pos);
|
||||
// Set the new attachment point data in the object
|
||||
byte attachmentPoint = group.GetAttachmentPoint();
|
||||
group.UpdateGroupPosition(pos);
|
||||
group.IsAttachment = false;
|
||||
group.AbsolutePosition = group.RootPart.AttachedPos;
|
||||
group.AttachmentPoint = attachmentPoint;
|
||||
group.HasGroupChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1447,6 +1617,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// VolumeDetect can't be set via UI and will always be off when a change is made there
|
||||
// now only change volume dtc if phantom off
|
||||
|
||||
bool wantedPhys = UsePhysics;
|
||||
if (PhysData.PhysShapeType == PhysShapeType.invalid) // check for extraPhysics data
|
||||
{
|
||||
bool vdtc;
|
||||
@@ -1463,10 +1634,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (part != null)
|
||||
{
|
||||
part.UpdateExtraPhysics(PhysData);
|
||||
if (part.UpdatePhysRequired)
|
||||
if (part.UpdatePhysRequired && remoteClient != null)
|
||||
remoteClient.SendPartPhysicsProprieties(part);
|
||||
}
|
||||
}
|
||||
|
||||
if (wantedPhys != group.UsesPhysics && remoteClient != null)
|
||||
{
|
||||
remoteClient.SendAlertMessage("Object physics canceled because exceeds the limit of " +
|
||||
m_parentScene.m_linksetPhysCapacity + " physical prims with shape type not set to None");
|
||||
group.RootPart.ScheduleFullUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1611,6 +1789,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
part.Material = Convert.ToByte(material);
|
||||
group.HasGroupChanged = true;
|
||||
remoteClient.SendPartPhysicsProprieties(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1689,12 +1868,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return;
|
||||
|
||||
Monitor.Enter(m_updateLock);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
|
||||
|
||||
// We do this in reverse to get the link order of the prims correct
|
||||
for (int i = 0 ; i < children.Count ; i++)
|
||||
for (int i = 0; i < children.Count; i++)
|
||||
{
|
||||
SceneObjectGroup child = children[i].ParentGroup;
|
||||
|
||||
@@ -1705,9 +1886,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// Make sure no child prim is set for sale
|
||||
// So that, on delink, no prims are unwittingly
|
||||
// left for sale and sold off
|
||||
child.RootPart.ObjectSaleType = 0;
|
||||
child.RootPart.SalePrice = 10;
|
||||
childGroups.Add(child);
|
||||
|
||||
if (child != null)
|
||||
{
|
||||
child.RootPart.ObjectSaleType = 0;
|
||||
child.RootPart.SalePrice = 10;
|
||||
childGroups.Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SceneObjectGroup child in childGroups)
|
||||
@@ -1736,6 +1921,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
finally
|
||||
{
|
||||
/*
|
||||
lock (SceneObjectGroupsByLocalPartID)
|
||||
{
|
||||
foreach (SceneObjectPart part in parentGroup.Parts)
|
||||
SceneObjectGroupsByLocalPartID[part.LocalId] = parentGroup;
|
||||
}
|
||||
*/
|
||||
parentGroup.AdjustChildPrimPermissions();
|
||||
parentGroup.HasGroupChanged = true;
|
||||
parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
|
||||
parentGroup.ScheduleGroupForFullUpdate();
|
||||
Monitor.Exit(m_updateLock);
|
||||
}
|
||||
}
|
||||
@@ -1777,21 +1973,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
SceneObjectGroup group = part.ParentGroup;
|
||||
if (!affectedGroups.Contains(group))
|
||||
{
|
||||
affectedGroups.Add(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SceneObjectPart child in childParts)
|
||||
if (childParts.Count > 0)
|
||||
{
|
||||
// Unlink all child parts from their groups
|
||||
//
|
||||
child.ParentGroup.DelinkFromGroup(child, true);
|
||||
|
||||
// These are not in affected groups and will not be
|
||||
// handled further. Do the honors here.
|
||||
child.ParentGroup.HasGroupChanged = true;
|
||||
child.ParentGroup.ScheduleGroupForFullUpdate();
|
||||
foreach (SceneObjectPart child in childParts)
|
||||
{
|
||||
// Unlink all child parts from their groups
|
||||
//
|
||||
child.ParentGroup.DelinkFromGroup(child, true);
|
||||
child.ParentGroup.HasGroupChanged = true;
|
||||
child.ParentGroup.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SceneObjectPart root in rootParts)
|
||||
@@ -1805,52 +2003,58 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
|
||||
int numChildren = newSet.Count;
|
||||
|
||||
if (numChildren == 1)
|
||||
break;
|
||||
|
||||
// If there are prims left in a link set, but the root is
|
||||
// slated for unlink, we need to do this
|
||||
// Unlink the remaining set
|
||||
//
|
||||
if (numChildren != 1)
|
||||
bool sendEventsToRemainder = false;
|
||||
if (numChildren == 2) // only one child prim no re-link needed
|
||||
sendEventsToRemainder = true;
|
||||
|
||||
foreach (SceneObjectPart p in newSet)
|
||||
{
|
||||
// Unlink the remaining set
|
||||
//
|
||||
bool sendEventsToRemainder = true;
|
||||
if (numChildren > 1)
|
||||
sendEventsToRemainder = false;
|
||||
|
||||
foreach (SceneObjectPart p in newSet)
|
||||
if (p != group.RootPart)
|
||||
{
|
||||
if (p != group.RootPart)
|
||||
group.DelinkFromGroup(p, sendEventsToRemainder);
|
||||
group.DelinkFromGroup(p, sendEventsToRemainder);
|
||||
if (sendEventsToRemainder) // finish single child prim now
|
||||
{
|
||||
p.ParentGroup.HasGroupChanged = true;
|
||||
p.ParentGroup.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is more than one prim remaining, we
|
||||
// need to re-link
|
||||
// If there is more than one prim remaining, we
|
||||
// need to re-link
|
||||
//
|
||||
if (numChildren > 2)
|
||||
{
|
||||
// Remove old root
|
||||
//
|
||||
if (numChildren > 2)
|
||||
if (newSet.Contains(root))
|
||||
newSet.Remove(root);
|
||||
|
||||
// Preserve link ordering
|
||||
//
|
||||
newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
|
||||
{
|
||||
// Remove old root
|
||||
//
|
||||
if (newSet.Contains(root))
|
||||
newSet.Remove(root);
|
||||
return a.LinkNum.CompareTo(b.LinkNum);
|
||||
});
|
||||
|
||||
// Preserve link ordering
|
||||
//
|
||||
newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
|
||||
{
|
||||
return a.LinkNum.CompareTo(b.LinkNum);
|
||||
});
|
||||
|
||||
// Determine new root
|
||||
//
|
||||
SceneObjectPart newRoot = newSet[0];
|
||||
newSet.RemoveAt(0);
|
||||
// Determine new root
|
||||
//
|
||||
SceneObjectPart newRoot = newSet[0];
|
||||
newSet.RemoveAt(0);
|
||||
|
||||
foreach (SceneObjectPart newChild in newSet)
|
||||
newChild.ClearUpdateSchedule();
|
||||
|
||||
LinkObjects(newRoot, newSet);
|
||||
if (!affectedGroups.Contains(newRoot.ParentGroup))
|
||||
affectedGroups.Add(newRoot.ParentGroup);
|
||||
}
|
||||
LinkObjects(newRoot, newSet);
|
||||
// if (!affectedGroups.Contains(newRoot.ParentGroup))
|
||||
// affectedGroups.Add(newRoot.ParentGroup);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1858,6 +2062,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
//
|
||||
foreach (SceneObjectGroup g in affectedGroups)
|
||||
{
|
||||
// Child prims that have been unlinked and deleted will
|
||||
// return unless the root is deleted. This will remove them
|
||||
// from the database. They will be rewritten immediately,
|
||||
// minus the rows for the unlinked child prims.
|
||||
g.AdjustChildPrimPermissions();
|
||||
m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
|
||||
g.TriggerScriptChangedEvent(Changed.LINK);
|
||||
g.HasGroupChanged = true; // Persist
|
||||
g.ScheduleGroupForFullUpdate();
|
||||
@@ -1931,54 +2141,63 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="GroupID"></param>
|
||||
/// <param name="rot"></param>
|
||||
/// <returns>null if duplication fails, otherwise the duplicated object</returns>
|
||||
public SceneObjectGroup DuplicateObject(
|
||||
uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot)
|
||||
/// <summary>
|
||||
public SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot)
|
||||
{
|
||||
Monitor.Enter(m_updateLock);
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}",
|
||||
// originalPrimID, offset, AgentID);
|
||||
|
||||
try
|
||||
SceneObjectGroup original = GetGroupByPrim(originalPrimID);
|
||||
if (original != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}",
|
||||
// originalPrimID, offset, AgentID);
|
||||
|
||||
SceneObjectGroup original = GetGroupByPrim(originalPrimID);
|
||||
if (original == null)
|
||||
if (m_parentScene.Permissions.CanDuplicateObject(
|
||||
original.PrimCount, original.UUID, AgentID, original.AbsolutePosition))
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
m_log.WarnFormat(
|
||||
"[SCENEGRAPH]: Attempt to duplicate nonexistent prim id {0} by {1}", originalPrimID, AgentID);
|
||||
=======
|
||||
SceneObjectGroup copy = original.Copy(true);
|
||||
copy.AbsolutePosition = copy.AbsolutePosition + offset;
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!m_parentScene.Permissions.CanDuplicateObject(
|
||||
original.PrimCount, original.UUID, AgentID, original.AbsolutePosition))
|
||||
return null;
|
||||
|
||||
SceneObjectGroup copy = original.Copy(true);
|
||||
copy.AbsolutePosition = copy.AbsolutePosition + offset;
|
||||
|
||||
if (original.OwnerID != AgentID)
|
||||
{
|
||||
copy.SetOwnerId(AgentID);
|
||||
copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID);
|
||||
|
||||
SceneObjectPart[] partList = copy.Parts;
|
||||
|
||||
if (m_parentScene.Permissions.PropagatePermissions())
|
||||
if (original.OwnerID != AgentID)
|
||||
{
|
||||
foreach (SceneObjectPart child in partList)
|
||||
copy.SetOwnerId(AgentID);
|
||||
copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID);
|
||||
|
||||
SceneObjectPart[] partList = copy.Parts;
|
||||
|
||||
if (m_parentScene.Permissions.PropagatePermissions())
|
||||
{
|
||||
child.Inventory.ChangeInventoryOwner(AgentID);
|
||||
child.TriggerScriptChangedEvent(Changed.OWNER);
|
||||
child.ApplyNextOwnerPermissions();
|
||||
foreach (SceneObjectPart child in partList)
|
||||
{
|
||||
child.Inventory.ChangeInventoryOwner(AgentID);
|
||||
child.TriggerScriptChangedEvent(Changed.OWNER);
|
||||
child.ApplyNextOwnerPermissions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
copy.RootPart.ObjectSaleType = 0;
|
||||
copy.RootPart.SalePrice = 10;
|
||||
}
|
||||
// FIXME: This section needs to be refactored so that it just calls AddSceneObject()
|
||||
Entities.Add(copy);
|
||||
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
SceneObjectGroupsByFullID[copy.UUID] = copy;
|
||||
|
||||
SceneObjectPart[] parts = copy.Parts;
|
||||
foreach (SceneObjectPart part in parts)
|
||||
{
|
||||
lock (SceneObjectGroupsByFullPartID)
|
||||
SceneObjectGroupsByFullPartID[part.UUID] = copy;
|
||||
lock (SceneObjectGroupsByLocalPartID)
|
||||
SceneObjectGroupsByLocalPartID[part.LocalId] = copy;
|
||||
}
|
||||
|
||||
// PROBABLE END OF FIXME
|
||||
|
||||
<<<<<<< HEAD
|
||||
// FIXME: This section needs to be refactored so that it just calls AddSceneObject()
|
||||
Entities.Add(copy);
|
||||
|
||||
@@ -2027,24 +2246,41 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
copy.UpdateGroupRotationR(rot);
|
||||
}
|
||||
=======
|
||||
// Since we copy from a source group that is in selected
|
||||
// state, but the copy is shown deselected in the viewer,
|
||||
// We need to clear the selection flag here, else that
|
||||
// prim never gets persisted at all. The client doesn't
|
||||
// think it's selected, so it will never send a deselect...
|
||||
copy.IsSelected = false;
|
||||
>>>>>>> avn/ubitvar
|
||||
|
||||
copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1);
|
||||
copy.HasGroupChanged = true;
|
||||
copy.ScheduleGroupForFullUpdate();
|
||||
copy.ResumeScripts();
|
||||
m_numPrim += copy.Parts.Length;
|
||||
|
||||
// required for physics to update it's position
|
||||
copy.AbsolutePosition = copy.AbsolutePosition;
|
||||
if (rot != Quaternion.Identity)
|
||||
{
|
||||
copy.UpdateGroupRotationR(rot);
|
||||
}
|
||||
|
||||
return copy;
|
||||
copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1);
|
||||
copy.HasGroupChanged = true;
|
||||
copy.ScheduleGroupForFullUpdate();
|
||||
copy.ResumeScripts();
|
||||
|
||||
// required for physics to update it's position
|
||||
copy.AbsolutePosition = copy.AbsolutePosition;
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
finally
|
||||
else
|
||||
{
|
||||
Monitor.Exit(m_updateLock);
|
||||
m_log.WarnFormat("[SCENE]: Attempted to duplicate nonexistant prim id {0}", GroupID);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// Calculates the distance between two Vector3s
|
||||
/// </summary>
|
||||
/// <param name="v1"></param>
|
||||
|
||||
Reference in New Issue
Block a user