From 6779f41e217ac2d401c3adf319ff307c46bc4dd3 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 24 Sep 2016 22:21:51 +0100 Subject: fix linknumbers when unlink the root prim --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 111 ++++++++++++++++++++- 1 file changed, 108 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 17dfb85..53a9441 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3168,10 +3168,11 @@ namespace OpenSim.Region.Framework.Scenes if (insert) { linkNum = 2; + int insertSize = objectGroup.PrimCount; foreach (SceneObjectPart part in Parts) { if (part.LinkNum > 1) - part.LinkNum++; + part.LinkNum += insertSize; } } else @@ -3200,14 +3201,14 @@ namespace OpenSim.Region.Framework.Scenes linkPart.LinkNum = linkNum++; linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false); - // Get a list of the SOP's in the old group in order of their linknum's. + // Get a list of the SOP's in the source group in order of their linknum's. SceneObjectPart[] ogParts = objectGroup.Parts; Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b) { return a.LinkNum - b.LinkNum; }); - // Add each of the SOP's from the old linkset to our linkset + // Add each of the SOP's from the source linkset to our linkset for (int i = 0; i < ogParts.Length; i++) { SceneObjectPart part = ogParts[i]; @@ -3415,6 +3416,110 @@ namespace OpenSim.Region.Framework.Scenes return objectGroup; } +/* working on it + public void DelinkFromGroup(List linkParts, bool sendEvents) + { +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}", +// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID); + + if(PrimCount == 1) + return; + + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = true; + + bool unlinkroot = false; + foreach(SceneObjectPart linkPart in linkParts) + { + // first we only remove child parts + if(linkPart.LocalId == m_rootPart.LocalId) + { + unlinkroot = true; + continue; + } + + lock (m_parts.SyncRoot) + if(!m_parts.Remove(linkPart.UUID)) + continue; + + linkPart.ClearUndoState(); + + Vector3 worldPos = linkPart.GetWorldPosition(); + Quaternion worldRot = linkPart.GetWorldRotation(); + + linkPart.ParentID = 0; + linkPart.LinkNum = 0; + + PhysicsActor linkPartPa = linkPart.PhysActor; + + // Remove the SOP from the physical scene. + // If the new SOG is physical, it is re-created later. + // (There is a problem here in that we have not yet told the physics + // engine about the delink. Someday, linksets should be made first + // class objects in the physics engine interface). + if (linkPartPa != null) + { + m_scene.PhysicsScene.RemovePrim(linkPartPa); + linkPart.PhysActor = null; + } + + linkPart.setGroupPosition(worldPos); + linkPart.setOffsetPosition(Vector3.Zero); + linkPart.setRotationOffset(worldRot); + + // Create a new SOG to go around this unlinked and unattached SOP + SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart); + + m_scene.AddNewSceneObject(objectGroup, true); + + linkPart.Rezzed = RootPart.Rezzed; + + // this is as it seems to be in sl now + if(linkPart.PhysicsShapeType == (byte)PhysShapeType.none) + linkPart.PhysicsShapeType = linkPart.DefaultPhysicsShapeType(); // root prims can't have type none for now + + objectGroup.HasGroupChangedDueToDelink = true; + if (sendEvents) + linkPart.TriggerScriptChangedEvent(Changed.LINK); + } + + if(unlinkroot) + { + //TODO + } + + lock (m_parts.SyncRoot) + { + SceneObjectPart[] parts = m_parts.GetArray(); + if (parts.Length == 1) + { + // Single prim left + m_rootPart.LinkNum = 0; + } + else + { + m_rootPart.LinkNum = 1; + int linknum = 2; + for (int i = 1; i < parts.Length; i++) + parts[i].LinkNum = linknum++; + } + } + + InvalidBoundsRadius(); + + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = false; + + // When we delete a group, we currently have to force persist to the database if the object id has changed + // (since delete works by deleting all rows which have a given object id) + + Scene.SimulationDataService.RemoveObject(UUID, Scene.RegionInfo.RegionID); + HasGroupChangedDueToDelink = true; + TriggerScriptChangedEvent(Changed.LINK); + return; + } +*/ /// /// Stop this object from being persisted over server restarts. /// -- cgit v1.1