aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/IClientAPI.cs3
-rw-r--r--OpenSim/Region/ClientStack/ClientView.API.cs1
-rw-r--r--OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs24
-rw-r--r--OpenSim/Region/Environment/Scenes/InnerScene.cs50
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs3
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs105
-rw-r--r--OpenSim/Region/Environment/Scenes/ScenePresence.cs21
-rw-r--r--OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs1
8 files changed, 194 insertions, 14 deletions
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index ed223f4..ab5dbb6 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -175,6 +175,8 @@ namespace OpenSim.Framework
175 public delegate void StartAnim(IClientAPI remoteClient, LLUUID animID, int seq); 175 public delegate void StartAnim(IClientAPI remoteClient, LLUUID animID, int seq);
176 176
177 public delegate void LinkObjects(uint parent, List<uint> children); 177 public delegate void LinkObjects(uint parent, List<uint> children);
178
179 public delegate void DelinkObjects(List<uint> primIds);
178 180
179 public delegate void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY); 181 public delegate void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY);
180 182
@@ -290,6 +292,7 @@ namespace OpenSim.Framework
290 event SetAppearance OnSetAppearance; 292 event SetAppearance OnSetAppearance;
291 event StartAnim OnStartAnim; 293 event StartAnim OnStartAnim;
292 event LinkObjects OnLinkObjects; 294 event LinkObjects OnLinkObjects;
295 event DelinkObjects OnDelinkObjects;
293 event RequestMapBlocks OnRequestMapBlocks; 296 event RequestMapBlocks OnRequestMapBlocks;
294 event TeleportLocationRequest OnTeleportLocationRequest; 297 event TeleportLocationRequest OnTeleportLocationRequest;
295 event DisconnectUser OnDisconnectUser; 298 event DisconnectUser OnDisconnectUser;
diff --git a/OpenSim/Region/ClientStack/ClientView.API.cs b/OpenSim/Region/ClientStack/ClientView.API.cs
index b18a844..b24b207 100644
--- a/OpenSim/Region/ClientStack/ClientView.API.cs
+++ b/OpenSim/Region/ClientStack/ClientView.API.cs
@@ -58,6 +58,7 @@ namespace OpenSim.Region.ClientStack
58 public event StartAnim OnStartAnim; 58 public event StartAnim OnStartAnim;
59 public event Action<IClientAPI> OnRequestAvatarsData; 59 public event Action<IClientAPI> OnRequestAvatarsData;
60 public event LinkObjects OnLinkObjects; 60 public event LinkObjects OnLinkObjects;
61 public event DelinkObjects OnDelinkObjects;
61 public event UpdateVector OnGrabObject; 62 public event UpdateVector OnGrabObject;
62 public event ObjectSelect OnDeGrabObject; 63 public event ObjectSelect OnDeGrabObject;
63 public event ObjectDuplicate OnObjectDuplicate; 64 public event ObjectDuplicate OnObjectDuplicate;
diff --git a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs
index f941d6c..82ad1c8 100644
--- a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs
+++ b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs
@@ -223,7 +223,7 @@ namespace OpenSim.Region.ClientStack
223 #region Objects/m_sceneObjects 223 #region Objects/m_sceneObjects
224 224
225 case PacketType.ObjectLink: 225 case PacketType.ObjectLink:
226 // OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString()); 226 //OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString());
227 ObjectLinkPacket link = (ObjectLinkPacket) Pack; 227 ObjectLinkPacket link = (ObjectLinkPacket) Pack;
228 uint parentprimid = 0; 228 uint parentprimid = 0;
229 List<uint> childrenprims = new List<uint>(); 229 List<uint> childrenprims = new List<uint>();
@@ -241,6 +241,26 @@ namespace OpenSim.Region.ClientStack
241 OnLinkObjects(parentprimid, childrenprims); 241 OnLinkObjects(parentprimid, childrenprims);
242 } 242 }
243 break; 243 break;
244 case PacketType.ObjectDelink:
245 //OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString());
246 ObjectDelinkPacket delink = (ObjectDelinkPacket) Pack;
247
248 // It appears the prim at index 0 is not always the root prim (for
249 // instance, when one prim of a link set has been edited independently
250 // of the others). Therefore, we'll pass all the ids onto the delink
251 // method for it to decide which is the root.
252 List<uint> prims = new List<uint>();
253 for (int i = 0; i < delink.ObjectData.Length; i++)
254 {
255 prims.Add(delink.ObjectData[i].ObjectLocalID);
256 }
257
258 if (OnDelinkObjects != null)
259 {
260 OnDelinkObjects(prims);
261 }
262
263 break;
244 case PacketType.ObjectAdd: 264 case PacketType.ObjectAdd:
245 if (OnAddPrim != null) 265 if (OnAddPrim != null)
246 { 266 {
@@ -775,4 +795,4 @@ namespace OpenSim.Region.ClientStack
775 OutPacket(logReply); 795 OutPacket(logReply);
776 } 796 }
777 } 797 }
778} \ No newline at end of file 798}
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs
index 90478c6..c8e9b73 100644
--- a/OpenSim/Region/Environment/Scenes/InnerScene.cs
+++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs
@@ -536,6 +536,56 @@ namespace OpenSim.Region.Environment.Scenes
536 parenPrim.LinkToGroup(sceneObj); 536 parenPrim.LinkToGroup(sceneObj);
537 } 537 }
538 } 538 }
539
540 /// <summary>
541 /// Delink a linkset
542 /// </summary>
543 /// <param name="prims"></param>
544 public void DelinkObjects(List<uint> primIds)
545 {
546 //OpenSim.Framework.Console.MainLog.Instance.Verbose("DelinkObjects()");
547
548 SceneObjectGroup parenPrim = null;
549
550 // Need a list of the SceneObjectGroup local ids
551 // XXX I'm anticipating that building this dictionary once is more efficient than
552 // repeated scanning of the Entity.Values for a large number of primIds. However, it might
553 // be more efficient yet to keep this dictionary permanently on hand.
554 Dictionary<uint, SceneObjectGroup> sceneObjects = new Dictionary<uint, SceneObjectGroup>();
555 foreach (EntityBase ent in Entities.Values)
556 {
557 if (ent is SceneObjectGroup)
558 {
559 SceneObjectGroup obj = (SceneObjectGroup)ent;
560 sceneObjects.Add(obj.LocalId, obj);
561 }
562 }
563
564 // Find the root prim among the prim ids we've been given
565 for (int i = 0; i < primIds.Count; i++)
566 {
567 if (sceneObjects.ContainsKey(primIds[i]))
568 {
569 parenPrim = sceneObjects[primIds[i]];
570 primIds.RemoveAt(i);
571 break;
572 }
573 }
574
575 if (parenPrim != null)
576 {
577 foreach (uint childPrimId in primIds)
578 {
579 parenPrim.DelinkFromGroup(childPrimId);
580 }
581 }
582 else
583 {
584 OpenSim.Framework.Console.MainLog.Instance.Verbose(
585 "DelinkObjects(): Could not find a root prim out of {0} as given to a delink request!",
586 primIds);
587 }
588 }
539 589
540 /// <summary> 590 /// <summary>
541 /// 591 ///
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 2d58b0e..bf56fe8 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -705,6 +705,7 @@ namespace OpenSim.Region.Environment.Scenes
705 client.OnObjectDescription += m_innerScene.PrimDescription; 705 client.OnObjectDescription += m_innerScene.PrimDescription;
706 client.OnObjectName += m_innerScene.PrimName; 706 client.OnObjectName += m_innerScene.PrimName;
707 client.OnLinkObjects += m_innerScene.LinkObjects; 707 client.OnLinkObjects += m_innerScene.LinkObjects;
708 client.OnDelinkObjects += m_innerScene.DelinkObjects;
708 client.OnObjectDuplicate += m_innerScene.DuplicateObject; 709 client.OnObjectDuplicate += m_innerScene.DuplicateObject;
709 client.OnUpdatePrimFlags += m_innerScene.UpdatePrimFlags; 710 client.OnUpdatePrimFlags += m_innerScene.UpdatePrimFlags;
710 711
@@ -1273,4 +1274,4 @@ namespace OpenSim.Region.Environment.Scenes
1273 1274
1274 #endregion 1275 #endregion
1275 } 1276 }
1276} \ No newline at end of file 1277}
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index e2415b9..a9f0bb3 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -222,6 +222,27 @@ namespace OpenSim.Region.Environment.Scenes
222 public SceneObjectGroup() 222 public SceneObjectGroup()
223 { 223 {
224 } 224 }
225
226 /// <summary>
227 /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart.
228 /// The original SceneObjectPart will be used rather than a copy, preserving
229 /// its existing localID and UUID.
230 /// </summary>
231 public SceneObjectGroup(Scene scene, ulong regionHandle, SceneObjectPart part)
232 {
233 m_scene = scene;
234 m_regionHandle = regionHandle;
235
236 part.SetParent(this);
237 part.ParentID = 0;
238
239 m_parts.Add(part.UUID, part);
240 SetPartAsRoot(part);
241
242 AttachToBackup();
243
244 ScheduleGroupForFullUpdate();
245 }
225 246
226 /// <summary> 247 /// <summary>
227 /// 248 ///
@@ -594,10 +615,10 @@ namespace OpenSim.Region.Environment.Scenes
594 #region SceneGroupPart Methods 615 #region SceneGroupPart Methods
595 616
596 /// <summary> 617 /// <summary>
597 /// 618 /// Get a child part with a given UUID
598 /// </summary> 619 /// </summary>
599 /// <param name="primID"></param> 620 /// <param name="primID"></param>
600 /// <returns></returns> 621 /// <returns>null if a child part with the primID was not found</returns>
601 public SceneObjectPart GetChildPart(LLUUID primID) 622 public SceneObjectPart GetChildPart(LLUUID primID)
602 { 623 {
603 SceneObjectPart childPart = null; 624 SceneObjectPart childPart = null;
@@ -609,10 +630,10 @@ namespace OpenSim.Region.Environment.Scenes
609 } 630 }
610 631
611 /// <summary> 632 /// <summary>
612 /// 633 /// Get a child part with a given local ID
613 /// </summary> 634 /// </summary>
614 /// <param name="localID"></param> 635 /// <param name="localID"></param>
615 /// <returns></returns> 636 /// <returns>null if a child part with the local ID was not found</returns>
616 public SceneObjectPart GetChildPart(uint localID) 637 public SceneObjectPart GetChildPart(uint localID)
617 { 638 {
618 foreach (SceneObjectPart part in m_parts.Values) 639 foreach (SceneObjectPart part in m_parts.Values)
@@ -717,13 +738,85 @@ namespace OpenSim.Region.Environment.Scenes
717 objectGroup.DeleteParts(); 738 objectGroup.DeleteParts();
718 ScheduleGroupForFullUpdate(); 739 ScheduleGroupForFullUpdate();
719 } 740 }
741
742 /// <summary>
743 /// Delink the given prim from this group. The delinked prim is established as
744 /// an independent SceneObjectGroup.
745 /// </summary>
746 /// <param name="partID"></param>
747 public void DelinkFromGroup(uint partID)
748 {
749 SceneObjectPart linkPart = GetChildPart(partID);
750
751 if (null != linkPart)
752 {
753 // Remove the part from this object
754 m_parts.Remove(linkPart.UUID);
755
756 // We need to reset the child part's position
757 // ready for life as a separate object after being a part of another object
758 Quaternion parentRot
759 = new Quaternion(
760 m_rootPart.RotationOffset.W,
761 m_rootPart.RotationOffset.X,
762 m_rootPart.RotationOffset.Y,
763 m_rootPart.RotationOffset.Z);
764
765 Vector3 axPos
766 = new Vector3(
767 linkPart.OffsetPosition.X,
768 linkPart.OffsetPosition.Y,
769 linkPart.OffsetPosition.Z);
770
771 axPos = parentRot * axPos;
772 linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
773 linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition;
774 linkPart.OffsetPosition = new LLVector3(0, 0, 0);
775
776 Quaternion oldRot
777 = new Quaternion(
778 linkPart.RotationOffset.W,
779 linkPart.RotationOffset.X,
780 linkPart.RotationOffset.Y,
781 linkPart.RotationOffset.Z);
782 Quaternion newRot = parentRot * oldRot;
783 linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
784
785 // Add physics information back to delinked part if appropriate
786 // XXX This is messy and should be refactorable with the similar section in
787 // SceneObjectPart.UpdatePrimFlags()
788 if (m_rootPart.PhysActor != null)
789 {
790 linkPart.PhysActor = m_scene.PhysScene.AddPrimShape(
791 linkPart.Name,
792 linkPart.Shape,
793 new PhysicsVector(linkPart.AbsolutePosition.X, linkPart.AbsolutePosition.Y,
794 linkPart.AbsolutePosition.Z),
795 new PhysicsVector(linkPart.Scale.X, linkPart.Scale.Y, linkPart.Scale.Z),
796 new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X,
797 linkPart.RotationOffset.Y, linkPart.RotationOffset.Z),
798 m_rootPart.PhysActor.IsPhysical);
799 }
800
801 SceneObjectGroup objectGroup = new SceneObjectGroup(m_scene, m_regionHandle, linkPart);
802
803 m_scene.AddEntity(objectGroup);
804
805 ScheduleGroupForFullUpdate();
806 }
807 else
808 {
809 OpenSim.Framework.Console.MainLog.Instance.Verbose(
810 "DelinkFromGroup(): Child prim local id {0} not found in object with root prim id {1}",
811 partID, LocalId);
812 }
813 }
720 814
721 private void DetachFromBackup(SceneObjectGroup objectGroup) 815 private void DetachFromBackup(SceneObjectGroup objectGroup)
722 { 816 {
723 m_scene.EventManager.OnBackup -= objectGroup.ProcessBackup; 817 m_scene.EventManager.OnBackup -= objectGroup.ProcessBackup;
724 } 818 }
725 819
726
727 private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation) 820 private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation)
728 { 821 {
729 part.SetParent(this); 822 part.SetParent(this);
@@ -1431,4 +1524,4 @@ namespace OpenSim.Region.Environment.Scenes
1431 Text = text; 1524 Text = text;
1432 } 1525 }
1433 } 1526 }
1434} \ No newline at end of file 1527}
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
index 20ec72e..c9c24fe 100644
--- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
@@ -328,17 +328,28 @@ namespace OpenSim.Region.Environment.Scenes
328 if (m_updateTimes.ContainsKey(part.UUID)) 328 if (m_updateTimes.ContainsKey(part.UUID))
329 { 329 {
330 ScenePartUpdate update = m_updateTimes[part.UUID]; 330 ScenePartUpdate update = m_updateTimes[part.UUID];
331 if (update.LastFullUpdateTime < part.TimeStampFull) 331
332 // Two updates can occur with the same timestamp (especially
333 // since our timestamp resolution is to the nearest second). The first
334 // could have been sent in the last update - we still need to send the
335 // second here.
336 if (update.LastFullUpdateTime <= part.TimeStampFull)
332 { 337 {
333 //need to do a full update 338 //need to do a full update
334 part.SendFullUpdate(ControllingClient); 339 part.SendFullUpdate(ControllingClient);
335 update.LastFullUpdateTime = (uint) Util.UnixTimeSinceEpoch(); 340
341 // We'll update to the part's timestamp rather than the current to
342 // avoid the race condition whereby the next tick occurs while we are
343 // doing this update. If this happened, then subsequent updates which occurred
344 // on the same tick or the next tick of the last update would be ignored.
345 update.LastFullUpdateTime = part.TimeStampFull;
346
336 updateCount++; 347 updateCount++;
337 } 348 }
338 else if (update.LastTerseUpdateTime < part.TimeStampTerse) 349 else if (update.LastTerseUpdateTime <= part.TimeStampTerse)
339 { 350 {
340 part.SendTerseUpdate(ControllingClient); 351 part.SendTerseUpdate(ControllingClient);
341 update.LastTerseUpdateTime = (uint) Util.UnixTimeSinceEpoch(); 352 update.LastTerseUpdateTime = part.TimeStampTerse;
342 updateCount++; 353 updateCount++;
343 } 354 }
344 } 355 }
@@ -348,7 +359,7 @@ namespace OpenSim.Region.Environment.Scenes
348 part.SendFullUpdate(ControllingClient); 359 part.SendFullUpdate(ControllingClient);
349 ScenePartUpdate update = new ScenePartUpdate(); 360 ScenePartUpdate update = new ScenePartUpdate();
350 update.FullID = part.UUID; 361 update.FullID = part.UUID;
351 update.LastFullUpdateTime = (uint) Util.UnixTimeSinceEpoch(); 362 update.LastFullUpdateTime = part.TimeStampFull;
352 m_updateTimes.Add(part.UUID, update); 363 m_updateTimes.Add(part.UUID, update);
353 updateCount++; 364 updateCount++;
354 } 365 }
diff --git a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs
index 0232b2d..86bb532 100644
--- a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs
@@ -57,6 +57,7 @@ namespace SimpleApp
57 public event SetAppearance OnSetAppearance; 57 public event SetAppearance OnSetAppearance;
58 public event StartAnim OnStartAnim; 58 public event StartAnim OnStartAnim;
59 public event LinkObjects OnLinkObjects; 59 public event LinkObjects OnLinkObjects;
60 public event DelinkObjects OnDelinkObjects;
60 public event RequestMapBlocks OnRequestMapBlocks; 61 public event RequestMapBlocks OnRequestMapBlocks;
61 public event TeleportLocationRequest OnTeleportLocationRequest; 62 public event TeleportLocationRequest OnTeleportLocationRequest;
62 public event DisconnectUser OnDisconnectUser; 63 public event DisconnectUser OnDisconnectUser;