aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs357
1 files changed, 199 insertions, 158 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 0eed64e..a7e7294 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -516,6 +516,10 @@ namespace OpenSim.Region.Framework.Scenes
516 public uint ParentID; 516 public uint ParentID;
517 } 517 }
518 518
519
520 public bool inTransit = false;
521 public delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos);
522
519 /// <summary> 523 /// <summary>
520 /// The absolute position of this scene object in the scene 524 /// The absolute position of this scene object in the scene
521 /// </summary> 525 /// </summary>
@@ -525,8 +529,8 @@ namespace OpenSim.Region.Framework.Scenes
525 set 529 set
526 { 530 {
527 Vector3 val = value; 531 Vector3 val = value;
528 532
529 if (Scene != null) 533 if (Scene != null && !inTransit)
530 { 534 {
531 if ( 535 if (
532 // (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) 536 // (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E)
@@ -543,130 +547,10 @@ namespace OpenSim.Region.Framework.Scenes
543 || Scene.TestBorderCross(val, Cardinals.S)) 547 || Scene.TestBorderCross(val, Cardinals.S))
544 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) 548 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
545 { 549 {
546 IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 550 inTransit = true;
547 uint x = 0; 551 SOGCrossDelegate d = CrossAsync;
548 uint y = 0; 552 d.BeginInvoke(this, val, CrossAsyncCompleted, d);
549 string version = String.Empty; 553 return;
550 Vector3 newpos = Vector3.Zero;
551 OpenSim.Services.Interfaces.GridRegion destination = null;
552
553 if (m_rootPart.DIE_AT_EDGE || m_rootPart.RETURN_AT_EDGE)
554 {
555 // this should delete the grp in this case
556 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
557 // actually assume this sog was removed from simulation
558 return;
559 }
560
561 if (m_rootPart.KeyframeMotion != null)
562 m_rootPart.KeyframeMotion.StartCrossingCheck();
563
564 bool canCross = true;
565
566 foreach (ScenePresence av in m_linkedAvatars)
567 {
568 // We need to cross these agents. First, let's find
569 // out if any of them can't cross for some reason.
570 // We have to deny the crossing entirely if any
571 // of them are banned. Alternatively, we could
572 // unsit banned agents....
573
574
575 // We set the avatar position as being the object
576 // position to get the region to send to
577 if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null)
578 {
579 canCross = false;
580 break;
581 }
582
583 m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
584 }
585
586 if (canCross)
587 {
588 // We unparent the SP quietly so that it won't
589 // be made to stand up
590
591 List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
592
593 foreach (ScenePresence av in m_linkedAvatars)
594 {
595 avtocrossInfo avinfo = new avtocrossInfo();
596 SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
597 if (parentPart != null)
598 av.ParentUUID = parentPart.UUID;
599
600 avinfo.av = av;
601 avinfo.ParentID = av.ParentID;
602 avsToCross.Add(avinfo);
603
604 av.PrevSitOffset = av.OffsetPosition;
605 av.ParentID = 0;
606 }
607
608 // m_linkedAvatars.Clear();
609 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
610
611 // Normalize
612 if (val.X >= Constants.RegionSize)
613 val.X -= Constants.RegionSize;
614 if (val.Y >= Constants.RegionSize)
615 val.Y -= Constants.RegionSize;
616 if (val.X < 0)
617 val.X += Constants.RegionSize;
618 if (val.Y < 0)
619 val.Y += Constants.RegionSize;
620
621 // If it's deleted, crossing was successful
622 if (IsDeleted)
623 {
624 // foreach (ScenePresence av in m_linkedAvatars)
625 foreach (avtocrossInfo avinfo in avsToCross)
626 {
627 ScenePresence av = avinfo.av;
628 if (!av.IsInTransit) // just in case...
629 {
630 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
631
632 av.IsInTransit = true;
633
634 CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
635 d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
636 }
637 else
638 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val);
639 }
640 avsToCross.Clear();
641 return;
642 }
643 else // cross failed, put avas back ??
644 {
645 foreach (avtocrossInfo avinfo in avsToCross)
646 {
647 ScenePresence av = avinfo.av;
648 av.ParentUUID = UUID.Zero;
649 av.ParentID = avinfo.ParentID;
650 // m_linkedAvatars.Add(av);
651 }
652 }
653 avsToCross.Clear();
654 }
655 else
656 {
657 if (m_rootPart.KeyframeMotion != null)
658 m_rootPart.KeyframeMotion.CrossingFailure();
659
660 if (RootPart.PhysActor != null)
661 {
662 RootPart.PhysActor.CrossingFailure();
663 }
664 }
665 Vector3 oldp = AbsolutePosition;
666 val.X = Util.Clamp<float>(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f);
667 val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
668 // dont crash land StarShips
669 // val.Z = Util.Clamp<float>(oldp.Z, 0.5f, 4096.0f);
670 } 554 }
671 } 555 }
672 556
@@ -714,46 +598,197 @@ namespace OpenSim.Region.Framework.Scenes
714 part.TriggerScriptChangedEvent(Changed.POSITION); 598 part.TriggerScriptChangedEvent(Changed.POSITION);
715 } 599 }
716 } 600 }
601
602 Scene.EventManager.TriggerParcelPrimCountTainted();
603 }
604 }
717 605
718/* 606 public SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val)
719 This seems not needed and should not be needed: 607 {
720 sp absolute position depends on sit part absolute position fixed above. 608 Scene sogScene = sog.m_scene;
721 sp ParentPosition is not used anywhere. 609 IEntityTransferModule entityTransfer = sogScene.RequestModuleInterface<IEntityTransferModule>();
722 Since presence is sitting, viewer considers it 'linked' to root prim, so it will move/rotate it 610
723 Sending a extra packet with avatar position is not only bandwidth waste, but may cause jitter in viewers due to UPD nature. 611 Vector3 newpos = Vector3.Zero;
724 612 OpenSim.Services.Interfaces.GridRegion destination = null;
725 if (!m_dupeInProgress) 613
614 if (sog.RootPart.DIE_AT_EDGE)
615 {
616 try
617 {
618 sogScene.DeleteSceneObject(sog, false);
619 }
620 catch (Exception)
621 {
622 m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border.");
623 }
624 return sog;
625 }
626
627 if (sog.RootPart.RETURN_AT_EDGE)
628 {
629 // We remove the object here
630 try
631 {
632 List<uint> localIDs = new List<uint>();
633 localIDs.Add(sog.RootPart.LocalId);
634 sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition,
635 "Returned at region cross");
636 sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero);
637 }
638 catch (Exception)
639 {
640 m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border.");
641 }
642 return sog;
643 }
644
645 if (sog.m_rootPart.KeyframeMotion != null)
646 sog.m_rootPart.KeyframeMotion.StartCrossingCheck();
647
648 if (entityTransfer == null)
649 return sog;
650
651 destination = entityTransfer.GetObjectDestination(sog, val, out newpos);
652 if (destination == null)
653 return sog;
654
655 if (sog.m_linkedAvatars.Count == 0)
656 {
657 entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true);
658 return sog;
659 }
660
661 string reason = String.Empty;
662 string version = String.Empty;
663
664 foreach (ScenePresence av in sog.m_linkedAvatars)
665 {
666 // We need to cross these agents. First, let's find
667 // out if any of them can't cross for some reason.
668 // We have to deny the crossing entirely if any
669 // of them are banned. Alternatively, we could
670 // unsit banned agents....
671
672 // We set the avatar position as being the object
673 // position to get the region to send to
674 if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, out version, out reason))
675 {
676 return sog;
677 }
678 m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
679 }
680
681 // We unparent the SP quietly so that it won't
682 // be made to stand up
683
684 List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
685
686 foreach (ScenePresence av in sog.m_linkedAvatars)
687 {
688 avtocrossInfo avinfo = new avtocrossInfo();
689 SceneObjectPart parentPart = sogScene.GetSceneObjectPart(av.ParentID);
690 if (parentPart != null)
691 av.ParentUUID = parentPart.UUID;
692
693 avinfo.av = av;
694 avinfo.ParentID = av.ParentID;
695 avsToCross.Add(avinfo);
696
697 av.PrevSitOffset = av.OffsetPosition;
698 av.ParentID = 0;
699 }
700
701 if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true))
702 {
703 foreach (avtocrossInfo avinfo in avsToCross)
726 { 704 {
727 foreach (ScenePresence av in m_linkedAvatars) 705 ScenePresence av = avinfo.av;
706 if (!av.IsInTransit) // just in case...
728 { 707 {
729 SceneObjectPart p = m_scene.GetSceneObjectPart(av.ParentID); 708 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
730 if (p != null && m_parts.TryGetValue(p.UUID, out p)) 709
710 av.IsInTransit = true;
711
712// CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
713// d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
714 entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, av.Flying, version);
715 if(av.IsChildAgent)
731 { 716 {
732 Vector3 offset = p.GetWorldPosition() - av.ParentPosition; 717 if (av.ParentUUID != UUID.Zero)
733 av.AbsolutePosition += offset; 718 {
734// av.ParentPosition = p.GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition 719 av.ClearControls();
735 av.SendAvatarDataToAllAgents(); 720 av.ParentPart = null;
721 }
736 } 722 }
723 av.ParentUUID = UUID.Zero;
724 // In any case
725 av.IsInTransit = false;
726
727 m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname);
737 } 728 }
729 else
730 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar already in transit {0} to {1}", av.Name, val);
731 }
732 avsToCross.Clear();
733 return sog;
734 }
735 else // cross failed, put avas back ??
736 {
737 foreach (avtocrossInfo avinfo in avsToCross)
738 {
739 ScenePresence av = avinfo.av;
740 av.ParentUUID = UUID.Zero;
741 av.ParentID = avinfo.ParentID;
738 } 742 }
739*/
740 //if (m_rootPart.PhysActor != null)
741 //{
742 //m_rootPart.PhysActor.Position =
743 //new PhysicsVector(m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y,
744 //m_rootPart.GroupPosition.Z);
745 //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
746 //}
747
748 if (Scene != null)
749 Scene.EventManager.TriggerParcelPrimCountTainted();
750 } 743 }
744 avsToCross.Clear();
745
746 return sog;
751 } 747 }
752 748
753 public override Vector3 Velocity 749 public void CrossAsyncCompleted(IAsyncResult iar)
754 { 750 {
755 get { return RootPart.Velocity; } 751 SOGCrossDelegate icon = (SOGCrossDelegate)iar.AsyncState;
756 set { RootPart.Velocity = value; } 752 SceneObjectGroup sog = icon.EndInvoke(iar);
753
754 if (sog.IsDeleted)
755 {
756 sog.inTransit = false; // just in case...
757 }
758 else
759 {
760 SceneObjectPart rootp = sog.m_rootPart;
761 Vector3 oldp = rootp.GroupPosition;
762 oldp.X = Util.Clamp<float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f);
763 oldp.Y = Util.Clamp<float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f);
764 rootp.GroupPosition = oldp;
765
766 SceneObjectPart[] parts = sog.m_parts.GetArray();
767
768 foreach (SceneObjectPart part in parts)
769 {
770 if (part != rootp)
771 part.GroupPosition = oldp;
772 }
773
774 foreach (ScenePresence av in sog.m_linkedAvatars)
775 {
776 av.sitSOGmoved();
777 }
778
779 sog.Velocity = Vector3.Zero;
780
781 if (sog.m_rootPart.KeyframeMotion != null)
782 sog.m_rootPart.KeyframeMotion.CrossingFailure();
783
784 if (sog.RootPart.PhysActor != null)
785 {
786 sog.RootPart.PhysActor.CrossingFailure();
787 }
788
789 sog.inTransit = false;
790 sog.ScheduleGroupForFullUpdate();
791 }
757 } 792 }
758 793
759 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 794 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -784,6 +819,12 @@ namespace OpenSim.Region.Framework.Scenes
784 m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); 819 m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
785 } 820 }
786 821
822 public override Vector3 Velocity
823 {
824 get { return RootPart.Velocity; }
825 set { RootPart.Velocity = value; }
826 }
827
787 public override uint LocalId 828 public override uint LocalId
788 { 829 {
789 get { return m_rootPart.LocalId; } 830 get { return m_rootPart.LocalId; }
@@ -2620,7 +2661,7 @@ namespace OpenSim.Region.Framework.Scenes
2620 // an object has been deleted from a scene before update was processed. 2661 // an object has been deleted from a scene before update was processed.
2621 // A more fundamental overhaul of the update mechanism is required to eliminate all 2662 // A more fundamental overhaul of the update mechanism is required to eliminate all
2622 // the race conditions. 2663 // the race conditions.
2623 if (IsDeleted) 2664 if (IsDeleted || inTransit)
2624 return; 2665 return;
2625 2666
2626 // Even temporary objects take part in physics (e.g. temp-on-rez bullets) 2667 // Even temporary objects take part in physics (e.g. temp-on-rez bullets)
@@ -2736,7 +2777,7 @@ namespace OpenSim.Region.Framework.Scenes
2736 /// </summary> 2777 /// </summary>
2737 public void SendGroupRootTerseUpdate() 2778 public void SendGroupRootTerseUpdate()
2738 { 2779 {
2739 if (IsDeleted) 2780 if (IsDeleted || inTransit)
2740 return; 2781 return;
2741 2782
2742 RootPart.SendTerseUpdateToAllClients(); 2783 RootPart.SendTerseUpdateToAllClients();
@@ -2755,7 +2796,7 @@ namespace OpenSim.Region.Framework.Scenes
2755 /// </summary> 2796 /// </summary>
2756 public void SendGroupTerseUpdate() 2797 public void SendGroupTerseUpdate()
2757 { 2798 {
2758 if (IsDeleted) 2799 if (IsDeleted || inTransit)
2759 return; 2800 return;
2760 2801
2761 if (IsAttachment) 2802 if (IsAttachment)