diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 407 |
1 files changed, 265 insertions, 142 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index af70848..0e7ac58 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -538,7 +538,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
538 | 538 | ||
539 | 539 | ||
540 | public bool inTransit = false; | 540 | public bool inTransit = false; |
541 | public delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos); | 541 | private delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos, TeleportObjectData tpData); |
542 | 542 | ||
543 | /// <summary> | 543 | /// <summary> |
544 | /// The absolute position of this scene object in the scene | 544 | /// The absolute position of this scene object in the scene |
@@ -560,7 +560,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
560 | { | 560 | { |
561 | inTransit = true; | 561 | inTransit = true; |
562 | SOGCrossDelegate d = CrossAsync; | 562 | SOGCrossDelegate d = CrossAsync; |
563 | d.BeginInvoke(this, val, CrossAsyncCompleted, d); | 563 | d.BeginInvoke(this, val, null, CrossAsyncCompleted, d); |
564 | } | 564 | } |
565 | return; | 565 | return; |
566 | } | 566 | } |
@@ -601,7 +601,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
601 | av.sitSOGmoved(); | 601 | av.sitSOGmoved(); |
602 | } | 602 | } |
603 | 603 | ||
604 | |||
605 | // now that position is changed tell it to scripts | 604 | // now that position is changed tell it to scripts |
606 | if (triggerScriptEvent) | 605 | if (triggerScriptEvent) |
607 | { | 606 | { |
@@ -617,64 +616,75 @@ namespace OpenSim.Region.Framework.Scenes | |||
617 | } | 616 | } |
618 | } | 617 | } |
619 | 618 | ||
620 | public SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val) | 619 | private SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val, TeleportObjectData tpdata) |
621 | { | 620 | { |
622 | Scene sogScene = sog.m_scene; | 621 | Scene sogScene = sog.m_scene; |
623 | IEntityTransferModule entityTransfer = sogScene.RequestModuleInterface<IEntityTransferModule>(); | 622 | SceneObjectPart root = sog.RootPart; |
624 | 623 | ||
625 | Vector3 newpos = Vector3.Zero; | 624 | bool isTeleport = tpdata != null; |
626 | OpenSim.Services.Interfaces.GridRegion destination = null; | ||
627 | 625 | ||
628 | if (sog.RootPart.DIE_AT_EDGE) | 626 | if(!isTeleport) |
629 | { | 627 | { |
630 | try | 628 | if (root.DIE_AT_EDGE) |
631 | { | ||
632 | sogScene.DeleteSceneObject(sog, false); | ||
633 | } | ||
634 | catch (Exception) | ||
635 | { | 629 | { |
636 | m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border."); | 630 | try |
631 | { | ||
632 | sogScene.DeleteSceneObject(sog, false); | ||
633 | } | ||
634 | catch (Exception) | ||
635 | { | ||
636 | m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border."); | ||
637 | } | ||
638 | return sog; | ||
637 | } | 639 | } |
638 | return sog; | ||
639 | } | ||
640 | 640 | ||
641 | if (sog.RootPart.RETURN_AT_EDGE) | 641 | if (root.RETURN_AT_EDGE) |
642 | { | ||
643 | // We remove the object here | ||
644 | try | ||
645 | { | 642 | { |
646 | List<uint> localIDs = new List<uint>(); | 643 | // We remove the object here |
647 | localIDs.Add(sog.RootPart.LocalId); | 644 | try |
648 | sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition, | 645 | { |
649 | "Returned at region cross"); | 646 | List<uint> localIDs = new List<uint>(); |
650 | sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero, false); | 647 | localIDs.Add(root.LocalId); |
651 | } | 648 | sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition, |
652 | catch (Exception) | 649 | "Returned at region cross"); |
653 | { | 650 | sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero, false); |
654 | m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border."); | 651 | } |
652 | catch (Exception) | ||
653 | { | ||
654 | m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border."); | ||
655 | } | ||
656 | return sog; | ||
655 | } | 657 | } |
656 | return sog; | ||
657 | } | 658 | } |
658 | 659 | ||
659 | if (sog.m_rootPart.KeyframeMotion != null) | 660 | if (root.KeyframeMotion != null) |
660 | sog.m_rootPart.KeyframeMotion.StartCrossingCheck(); | 661 | root.KeyframeMotion.StartCrossingCheck(); |
662 | |||
663 | if(root.PhysActor != null) | ||
664 | root.PhysActor.CrossingStart(); | ||
665 | |||
666 | IEntityTransferModule entityTransfer = sogScene.RequestModuleInterface<IEntityTransferModule>(); | ||
661 | 667 | ||
662 | if (entityTransfer == null) | 668 | if (entityTransfer == null) |
663 | return sog; | 669 | return sog; |
664 | 670 | ||
671 | Vector3 newpos = Vector3.Zero; | ||
672 | OpenSim.Services.Interfaces.GridRegion destination = null; | ||
673 | |||
665 | destination = entityTransfer.GetObjectDestination(sog, val, out newpos); | 674 | destination = entityTransfer.GetObjectDestination(sog, val, out newpos); |
666 | if (destination == null) | 675 | if (destination == null) |
667 | return sog; | 676 | return sog; |
668 | 677 | ||
669 | if (sog.m_sittingAvatars.Count == 0) | 678 | if (sog.m_sittingAvatars.Count == 0) |
670 | { | 679 | { |
671 | entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, true); | 680 | entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, !isTeleport, true); |
672 | return sog; | 681 | return sog; |
673 | } | 682 | } |
674 | 683 | ||
675 | string reason = String.Empty; | 684 | string reason = String.Empty; |
676 | EntityTransferContext ctx = new EntityTransferContext(); | 685 | EntityTransferContext ctx = new EntityTransferContext(); |
677 | 686 | ||
687 | Vector3 curPos = root.GroupPosition; | ||
678 | foreach (ScenePresence av in sog.m_sittingAvatars) | 688 | foreach (ScenePresence av in sog.m_sittingAvatars) |
679 | { | 689 | { |
680 | // We need to cross these agents. First, let's find | 690 | // We need to cross these agents. First, let's find |
@@ -685,10 +695,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
685 | 695 | ||
686 | // We set the avatar position as being the object | 696 | // We set the avatar position as being the object |
687 | // position to get the region to send to | 697 | // position to get the region to send to |
698 | if(av.IsNPC) | ||
699 | continue; | ||
700 | |||
701 | if(av.IsInTransit) | ||
702 | return sog; | ||
703 | |||
688 | if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, ctx, out reason)) | 704 | if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, ctx, out reason)) |
689 | { | ||
690 | return sog; | 705 | return sog; |
691 | } | 706 | |
692 | m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName); | 707 | m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName); |
693 | } | 708 | } |
694 | 709 | ||
@@ -696,8 +711,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
696 | // be made to stand up | 711 | // be made to stand up |
697 | 712 | ||
698 | List<avtocrossInfo> avsToCross = new List<avtocrossInfo>(); | 713 | List<avtocrossInfo> avsToCross = new List<avtocrossInfo>(); |
699 | 714 | List<ScenePresence> avsToCrossFar = new List<ScenePresence>(); | |
700 | foreach (ScenePresence av in sog.m_sittingAvatars) | 715 | ulong destHandle = destination.RegionHandle; |
716 | List<ScenePresence> sittingAvatars = GetSittingAvatars(); | ||
717 | foreach (ScenePresence av in sittingAvatars) | ||
701 | { | 718 | { |
702 | byte cflags = 1; | 719 | byte cflags = 1; |
703 | 720 | ||
@@ -711,68 +728,175 @@ namespace OpenSim.Region.Framework.Scenes | |||
711 | else | 728 | else |
712 | cflags = 3; | 729 | cflags = 3; |
713 | } | 730 | } |
731 | if(!av.knowsNeighbourRegion(destHandle)) | ||
732 | cflags |= 8; | ||
714 | 733 | ||
715 | // 1 is crossing | 734 | // 1 is crossing |
716 | // 2 is sitting | 735 | // 2 is sitting |
717 | // 4 is sitting at sittarget | 736 | // 4 is sitting at sittarget |
718 | av.crossingFlags = cflags; | 737 | // 8 far crossing |
719 | 738 | ||
720 | avinfo.av = av; | 739 | avinfo.av = av; |
721 | avinfo.ParentID = av.ParentID; | 740 | avinfo.ParentID = av.ParentID; |
722 | avsToCross.Add(avinfo); | 741 | avsToCross.Add(avinfo); |
723 | 742 | ||
743 | if(!av.knowsNeighbourRegion(destHandle)) | ||
744 | { | ||
745 | cflags |= 8; | ||
746 | avsToCrossFar.Add(av); | ||
747 | } | ||
748 | |||
749 | if(av.IsNPC) | ||
750 | av.crossingFlags = 0; | ||
751 | else | ||
752 | av.crossingFlags = cflags; | ||
753 | |||
724 | av.PrevSitOffset = av.OffsetPosition; | 754 | av.PrevSitOffset = av.OffsetPosition; |
725 | av.ParentID = 0; | 755 | av.ParentID = 0; |
726 | } | 756 | } |
727 | 757 | ||
758 | Vector3 vel = root.Velocity; | ||
759 | Vector3 avel = root.AngularVelocity; | ||
760 | Vector3 acc = root.Acceleration; | ||
761 | Quaternion ori = root.RotationOffset; | ||
762 | |||
763 | if(isTeleport) | ||
764 | { | ||
765 | root.Stop(); | ||
766 | sogScene.ForEachScenePresence(delegate(ScenePresence av) | ||
767 | { | ||
768 | av.ControllingClient.SendEntityUpdate(root,PrimUpdateFlags.SendInTransit); | ||
769 | av.ControllingClient.SendEntityTerseUpdateImmediate(root); | ||
770 | }); | ||
771 | |||
772 | root.Velocity = tpdata.vel; | ||
773 | root.AngularVelocity = tpdata.avel; | ||
774 | root.Acceleration = tpdata.acc; | ||
775 | root.RotationOffset = tpdata.ori; | ||
776 | } | ||
777 | |||
728 | if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, false)) | 778 | if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, false)) |
729 | { | 779 | { |
780 | if(isTeleport) | ||
781 | { | ||
782 | sogScene.ForEachScenePresence(delegate(ScenePresence oav) | ||
783 | { | ||
784 | if(sittingAvatars.Contains(oav)) | ||
785 | return; | ||
786 | if(oav.knowsNeighbourRegion(destHandle)) | ||
787 | return; | ||
788 | oav.ControllingClient.SendEntityUpdate(root, PrimUpdateFlags.Kill); | ||
789 | foreach (ScenePresence sav in sittingAvatars) | ||
790 | { | ||
791 | sav.SendKillTo(oav); | ||
792 | } | ||
793 | }); | ||
794 | } | ||
795 | bool crossedfar = false; | ||
796 | foreach (ScenePresence av in avsToCrossFar) | ||
797 | { | ||
798 | if(entityTransfer.CrossAgentCreateFarChild(av,destination, newpos, ctx)) | ||
799 | crossedfar = true; | ||
800 | else | ||
801 | av.crossingFlags = 0; | ||
802 | } | ||
803 | |||
804 | if(crossedfar) | ||
805 | Thread.Sleep(1000); | ||
806 | |||
730 | foreach (avtocrossInfo avinfo in avsToCross) | 807 | foreach (avtocrossInfo avinfo in avsToCross) |
731 | { | 808 | { |
732 | ScenePresence av = avinfo.av; | 809 | ScenePresence av = avinfo.av; |
733 | if (!av.IsInTransit) // just in case... | 810 | av.IsInTransit = true; |
734 | { | 811 | m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); |
735 | m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); | ||
736 | 812 | ||
737 | av.IsInTransit = true; | 813 | if(av.crossingFlags > 0) |
814 | entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, false, ctx); | ||
738 | 815 | ||
739 | // CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; | 816 | if (av.IsChildAgent) |
740 | // d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); | 817 | { |
741 | entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, av.Flying, ctx); | 818 | // avatar crossed do some extra cleanup |
742 | if (av.IsChildAgent) | 819 | if (av.ParentUUID != UUID.Zero) |
743 | { | ||
744 | // avatar crossed do some extra cleanup | ||
745 | if (av.ParentUUID != UUID.Zero) | ||
746 | { | ||
747 | av.ClearControls(); | ||
748 | av.ParentPart = null; | ||
749 | } | ||
750 | } | ||
751 | else | ||
752 | { | 820 | { |
753 | // avatar cross failed we need do dedicated standUp | 821 | av.ClearControls(); |
754 | // part of it was done at CrossAgentToNewRegionAsync | 822 | av.ParentPart = null; |
755 | // so for now just remove the sog controls | ||
756 | // this may need extra care | ||
757 | av.UnRegisterSeatControls(sog.UUID); | ||
758 | } | 823 | } |
759 | |||
760 | av.ParentUUID = UUID.Zero; | 824 | av.ParentUUID = UUID.Zero; |
825 | av.ParentPart = null; | ||
761 | // In any case | 826 | // In any case |
762 | av.IsInTransit = false; | 827 | av.IsInTransit = false; |
763 | av.crossingFlags = 0; | 828 | av.crossingFlags = 0; |
764 | m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname); | 829 | m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname); |
765 | } | 830 | } |
766 | else | 831 | else |
767 | m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar already in transit {0} to {1}", av.Name, val); | 832 | { |
833 | // avatar cross failed we need do dedicated standUp | ||
834 | // part of it was done at CrossAgentToNewRegionAsync | ||
835 | // so for now just remove the sog controls | ||
836 | // this may need extra care | ||
837 | av.UnRegisterSeatControls(sog.UUID); | ||
838 | av.ParentUUID = UUID.Zero; | ||
839 | av.ParentPart = null; | ||
840 | Vector3 oldp = curPos; | ||
841 | oldp.X = Util.Clamp<float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f); | ||
842 | oldp.Y = Util.Clamp<float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f); | ||
843 | av.AbsolutePosition = oldp; | ||
844 | av.crossingFlags = 0; | ||
845 | av.sitAnimation = "SIT"; | ||
846 | av.IsInTransit = false; | ||
847 | if(av.Animator!= null) | ||
848 | av.Animator.SetMovementAnimations("STAND"); | ||
849 | av.AddToPhysicalScene(false); | ||
850 | sogScene.ForEachScenePresence(delegate(ScenePresence oav) | ||
851 | { | ||
852 | if(sittingAvatars.Contains(oav)) | ||
853 | return; | ||
854 | if(oav.knowsNeighbourRegion(destHandle)) | ||
855 | av.SendAvatarDataToAgent(oav); | ||
856 | else | ||
857 | { | ||
858 | av.SendAvatarDataToAgent(oav); | ||
859 | av.SendAppearanceToAgent(oav); | ||
860 | if (av.Animator != null) | ||
861 | av.Animator.SendAnimPackToClient(oav.ControllingClient); | ||
862 | av.SendAttachmentsToAgentNF(oav); // not ok | ||
863 | } | ||
864 | }); | ||
865 | m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} failed.", av.Firstname, av.Lastname); | ||
866 | } | ||
768 | } | 867 | } |
868 | |||
869 | if(crossedfar) | ||
870 | { | ||
871 | Thread.Sleep(10000); | ||
872 | foreach (ScenePresence av in avsToCrossFar) | ||
873 | { | ||
874 | if(av.IsChildAgent) | ||
875 | { | ||
876 | av.Scene.CloseAgent(av.UUID, false); | ||
877 | } | ||
878 | else | ||
879 | av.RemoveNeighbourRegion(destHandle); | ||
880 | } | ||
881 | } | ||
882 | avsToCrossFar.Clear(); | ||
769 | avsToCross.Clear(); | 883 | avsToCross.Clear(); |
770 | sog.RemoveScriptInstances(true); | 884 | sog.RemoveScriptInstances(true); |
771 | sog.Clear(); | 885 | sog.Clear(); |
772 | return sog; | 886 | return sog; |
773 | } | 887 | } |
774 | else // cross failed, put avas back ?? | 888 | else |
775 | { | 889 | { |
890 | if(isTeleport) | ||
891 | { | ||
892 | if((tpdata.flags & OSTPOBJ_STOPONFAIL) == 0) | ||
893 | { | ||
894 | root.Velocity = vel; | ||
895 | root.AngularVelocity = avel; | ||
896 | root.Acceleration = acc; | ||
897 | } | ||
898 | root.RotationOffset = ori; | ||
899 | } | ||
776 | foreach (avtocrossInfo avinfo in avsToCross) | 900 | foreach (avtocrossInfo avinfo in avsToCross) |
777 | { | 901 | { |
778 | ScenePresence av = avinfo.av; | 902 | ScenePresence av = avinfo.av; |
@@ -782,7 +906,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
782 | } | 906 | } |
783 | } | 907 | } |
784 | avsToCross.Clear(); | 908 | avsToCross.Clear(); |
785 | |||
786 | return sog; | 909 | return sog; |
787 | } | 910 | } |
788 | 911 | ||
@@ -794,11 +917,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
794 | if (!sog.IsDeleted) | 917 | if (!sog.IsDeleted) |
795 | { | 918 | { |
796 | SceneObjectPart rootp = sog.m_rootPart; | 919 | SceneObjectPart rootp = sog.m_rootPart; |
920 | |||
797 | Vector3 oldp = rootp.GroupPosition; | 921 | Vector3 oldp = rootp.GroupPosition; |
798 | oldp.X = Util.Clamp<float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f); | 922 | oldp.X = Util.Clamp<float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f); |
799 | oldp.Y = Util.Clamp<float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f); | 923 | oldp.Y = Util.Clamp<float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f); |
800 | rootp.GroupPosition = oldp; | 924 | rootp.GroupPosition = oldp; |
801 | 925 | ||
926 | rootp.Stop(); | ||
927 | |||
802 | SceneObjectPart[] parts = sog.m_parts.GetArray(); | 928 | SceneObjectPart[] parts = sog.m_parts.GetArray(); |
803 | 929 | ||
804 | foreach (SceneObjectPart part in parts) | 930 | foreach (SceneObjectPart part in parts) |
@@ -812,57 +938,37 @@ namespace OpenSim.Region.Framework.Scenes | |||
812 | av.sitSOGmoved(); | 938 | av.sitSOGmoved(); |
813 | } | 939 | } |
814 | 940 | ||
815 | sog.Velocity = Vector3.Zero; | ||
816 | |||
817 | if (sog.m_rootPart.KeyframeMotion != null) | 941 | if (sog.m_rootPart.KeyframeMotion != null) |
818 | sog.m_rootPart.KeyframeMotion.CrossingFailure(); | 942 | sog.m_rootPart.KeyframeMotion.CrossingFailure(); |
819 | 943 | ||
820 | if (sog.RootPart.PhysActor != null) | 944 | if (sog.RootPart.PhysActor != null) |
821 | { | ||
822 | sog.RootPart.PhysActor.CrossingFailure(); | 945 | sog.RootPart.PhysActor.CrossingFailure(); |
823 | } | ||
824 | 946 | ||
825 | sog.inTransit = false; | 947 | sog.inTransit = false; |
948 | AttachToBackup(); | ||
826 | sog.ScheduleGroupForFullUpdate(); | 949 | sog.ScheduleGroupForFullUpdate(); |
827 | } | 950 | } |
828 | } | 951 | } |
829 | 952 | ||
830 | /* outdated | 953 | private class TeleportObjectData |
831 | private void CrossAgentToNewRegionCompleted(ScenePresence agent) | ||
832 | { | 954 | { |
833 | //// If the cross was successful, this agent is a child agent | 955 | public int flags; |
834 | if (agent.IsChildAgent) | 956 | public Vector3 vel; |
835 | { | 957 | public Vector3 avel; |
836 | if (agent.ParentUUID != UUID.Zero) | 958 | public Vector3 acc; |
837 | { | 959 | public Quaternion ori; |
838 | agent.HandleForceReleaseControls(agent.ControllingClient,agent.UUID); | 960 | public UUID sourceID; |
839 | agent.ParentPart = null; | ||
840 | // agent.ParentPosition = Vector3.Zero; | ||
841 | // agent.ParentUUID = UUID.Zero; | ||
842 | } | ||
843 | } | ||
844 | |||
845 | agent.ParentUUID = UUID.Zero; | ||
846 | // agent.Reset(); | ||
847 | // else // Not successful | ||
848 | // agent.RestoreInCurrentScene(); | ||
849 | |||
850 | // In any case | ||
851 | agent.IsInTransit = false; | ||
852 | |||
853 | m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); | ||
854 | } | 961 | } |
855 | */ | ||
856 | 962 | ||
857 | // copy from LSL_constants.cs | 963 | // copy from LSL_constants.cs |
858 | const int OSTPOBJ_STOPATTARRGET = 0x1; // stops at destination | 964 | const int OSTPOBJ_STOPATTARGET = 0x1; // stops at destination |
859 | const int OSTPOBJ_STOPONFAIL = 0x2; // stops at start if tp fails | 965 | const int OSTPOBJ_STOPONFAIL = 0x2; // stops at start if tp fails |
860 | const int OSTPOBJ_SETROT = 0x4; // the rotation is the final rotation, otherwise is a added rotation | 966 | const int OSTPOBJ_SETROT = 0x4; // the rotation is the final rotation, otherwise is a added rotation |
861 | 967 | ||
862 | public void TeleportObject(UUID sourceID, Vector3 targetPosition, Quaternion rotation, int flags) | 968 | public int TeleportObject(UUID sourceID, Vector3 targetPosition, Quaternion rotation, int flags) |
863 | { | 969 | { |
864 | if(inTransit || IsDeleted || IsAttachmentCheckFull() || IsSelected || Scene == null) | 970 | if(inTransit || IsDeleted || IsAttachmentCheckFull() || IsSelected || Scene == null) |
865 | return; | 971 | return -1; |
866 | 972 | ||
867 | inTransit = true; | 973 | inTransit = true; |
868 | 974 | ||
@@ -870,7 +976,41 @@ namespace OpenSim.Region.Framework.Scenes | |||
870 | if(pa == null || RootPart.KeyframeMotion != null /*|| m_sittingAvatars.Count == 0*/) | 976 | if(pa == null || RootPart.KeyframeMotion != null /*|| m_sittingAvatars.Count == 0*/) |
871 | { | 977 | { |
872 | inTransit = false; | 978 | inTransit = false; |
873 | return; | 979 | return -1; |
980 | } | ||
981 | |||
982 | bool stop = (flags & OSTPOBJ_STOPATTARGET) != 0; | ||
983 | bool setrot = (flags & OSTPOBJ_SETROT) != 0; | ||
984 | |||
985 | rotation.Normalize(); | ||
986 | |||
987 | Quaternion currentRot = RootPart.RotationOffset; | ||
988 | if(setrot) | ||
989 | rotation = Quaternion.Conjugate(currentRot) * rotation; | ||
990 | |||
991 | bool dorot = setrot | (Math.Abs(rotation.W) < 0.99999); | ||
992 | |||
993 | Vector3 vel = Vector3.Zero; | ||
994 | Vector3 avel = Vector3.Zero; | ||
995 | Vector3 acc = Vector3.Zero; | ||
996 | |||
997 | if(!stop) | ||
998 | { | ||
999 | vel = RootPart.Velocity; | ||
1000 | avel = RootPart.AngularVelocity; | ||
1001 | acc = RootPart.Acceleration; | ||
1002 | } | ||
1003 | Quaternion ori = RootPart.RotationOffset; | ||
1004 | |||
1005 | if(dorot) | ||
1006 | { | ||
1007 | if(!stop) | ||
1008 | { | ||
1009 | vel *= rotation; | ||
1010 | avel *= rotation; | ||
1011 | acc *= rotation; | ||
1012 | } | ||
1013 | ori *= rotation; | ||
874 | } | 1014 | } |
875 | 1015 | ||
876 | if(Scene.PositionIsInCurrentRegion(targetPosition)) | 1016 | if(Scene.PositionIsInCurrentRegion(targetPosition)) |
@@ -878,7 +1018,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
878 | if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 1.0)) | 1018 | if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 1.0)) |
879 | { | 1019 | { |
880 | inTransit = false; | 1020 | inTransit = false; |
881 | return; | 1021 | return -2; |
882 | } | 1022 | } |
883 | 1023 | ||
884 | Vector3 curPos = AbsolutePosition; | 1024 | Vector3 curPos = AbsolutePosition; |
@@ -891,7 +1031,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
891 | if(!Scene.Permissions.CanObjectEnterWithScripts(this, land)) | 1031 | if(!Scene.Permissions.CanObjectEnterWithScripts(this, land)) |
892 | { | 1032 | { |
893 | inTransit = false; | 1033 | inTransit = false; |
894 | return; | 1034 | return -3; |
895 | } | 1035 | } |
896 | 1036 | ||
897 | UUID agentID; | 1037 | UUID agentID; |
@@ -901,49 +1041,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
901 | if(land.IsRestrictedFromLand(agentID) || land.IsBannedFromLand(agentID)) | 1041 | if(land.IsRestrictedFromLand(agentID) || land.IsBannedFromLand(agentID)) |
902 | { | 1042 | { |
903 | inTransit = false; | 1043 | inTransit = false; |
904 | return; | 1044 | return -4; |
905 | } | 1045 | } |
906 | } | 1046 | } |
907 | } | 1047 | } |
908 | 1048 | ||
909 | bool stop = (flags & OSTPOBJ_STOPATTARRGET) != 0; | 1049 | RootPart.Velocity = vel; |
910 | bool setrot = (flags & OSTPOBJ_SETROT) != 0; | 1050 | RootPart.AngularVelocity = avel; |
911 | 1051 | RootPart.Acceleration = acc; | |
912 | rotation.Normalize(); | 1052 | RootPart.RotationOffset = ori; |
913 | Quaternion currentRot = RootPart.RotationOffset; | ||
914 | |||
915 | if(setrot) | ||
916 | rotation = Quaternion.Conjugate(currentRot) * rotation; | ||
917 | |||
918 | bool dorot = setrot | (Math.Abs(rotation.W) < 0.999); | ||
919 | |||
920 | if(stop) | ||
921 | { | ||
922 | RootPart.Stop(); | ||
923 | } | ||
924 | else | ||
925 | { | ||
926 | if(dorot) | ||
927 | { | ||
928 | Vector3 vel = RootPart.Velocity; | ||
929 | Vector3 avel = RootPart.AngularVelocity; | ||
930 | Vector3 acc = RootPart.Acceleration; | ||
931 | |||
932 | vel *= rotation; | ||
933 | avel *= rotation; | ||
934 | acc *= rotation; | ||
935 | |||
936 | RootPart.Velocity = vel; | ||
937 | RootPart.AngularVelocity = avel; | ||
938 | RootPart.Acceleration = acc; | ||
939 | } | ||
940 | } | ||
941 | |||
942 | if(dorot) | ||
943 | { | ||
944 | currentRot *= rotation; | ||
945 | RootPart.RotationOffset = currentRot; | ||
946 | } | ||
947 | 1053 | ||
948 | Vector3 s = RootPart.Scale * RootPart.RotationOffset; | 1054 | Vector3 s = RootPart.Scale * RootPart.RotationOffset; |
949 | float h = Scene.GetGroundHeight(posX, posY) + 0.5f * (float)Math.Abs(s.Z) + 0.01f; | 1055 | float h = Scene.GetGroundHeight(posX, posY) + 0.5f * (float)Math.Abs(s.Z) + 0.01f; |
@@ -953,10 +1059,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
953 | inTransit = false; | 1059 | inTransit = false; |
954 | AbsolutePosition = targetPosition; | 1060 | AbsolutePosition = targetPosition; |
955 | RootPart.ScheduleTerseUpdate(); | 1061 | RootPart.ScheduleTerseUpdate(); |
956 | return; | 1062 | return 1; |
957 | } | 1063 | } |
958 | 1064 | ||
959 | inTransit = false; | 1065 | if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 20.0)) |
1066 | { | ||
1067 | inTransit = false; | ||
1068 | return -1; | ||
1069 | } | ||
1070 | |||
1071 | TeleportObjectData tdata = new TeleportObjectData(); | ||
1072 | tdata.flags = flags; | ||
1073 | tdata.vel = vel; | ||
1074 | tdata.avel = avel; | ||
1075 | tdata.acc = acc; | ||
1076 | tdata.ori = ori; | ||
1077 | tdata.sourceID = sourceID; | ||
1078 | |||
1079 | |||
1080 | SOGCrossDelegate d = CrossAsync; | ||
1081 | d.BeginInvoke(this, targetPosition, tdata, CrossAsyncCompleted, d); | ||
1082 | return 0; | ||
960 | } | 1083 | } |
961 | 1084 | ||
962 | public override Vector3 Velocity | 1085 | public override Vector3 Velocity |
@@ -5398,9 +5521,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
5398 | { | 5521 | { |
5399 | if (avs[i].Name == name) | 5522 | if (avs[i].Name == name) |
5400 | { | 5523 | { |
5401 | GetLinkNumber_lastname = name; | 5524 | GetLinkNumber_lastname = name; |
5402 | GetLinkNumber_lastnumber = j; | 5525 | GetLinkNumber_lastnumber = j; |
5403 | return j; | 5526 | return j; |
5404 | } | 5527 | } |
5405 | } | 5528 | } |
5406 | } | 5529 | } |