aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs1072
1 files changed, 759 insertions, 313 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 6979c33..c2ff110 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -63,6 +63,7 @@ namespace OpenSim.Region.Framework.Scenes
63 63
64 struct ScriptControllers 64 struct ScriptControllers
65 { 65 {
66 public UUID objectID;
66 public UUID itemID; 67 public UUID itemID;
67 public ScriptControlled ignoreControls; 68 public ScriptControlled ignoreControls;
68 public ScriptControlled eventControls; 69 public ScriptControlled eventControls;
@@ -99,7 +100,7 @@ namespace OpenSim.Region.Framework.Scenes
99 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 100 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
100 /// issue #1716 101 /// issue #1716
101 /// </summary> 102 /// </summary>
102 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 103 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
103 104
104 /// <summary> 105 /// <summary>
105 /// Movement updates for agents in neighboring regions are sent directly to clients. 106 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -139,6 +140,8 @@ namespace OpenSim.Region.Framework.Scenes
139 private Vector3 m_lastPosition; 140 private Vector3 m_lastPosition;
140 private Quaternion m_lastRotation; 141 private Quaternion m_lastRotation;
141 private Vector3 m_lastVelocity; 142 private Vector3 m_lastVelocity;
143 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
144
142 145
143 private Vector3? m_forceToApply; 146 private Vector3? m_forceToApply;
144 private int m_userFlags; 147 private int m_userFlags;
@@ -171,6 +174,7 @@ namespace OpenSim.Region.Framework.Scenes
171// private int m_lastColCount = -1; //KF: Look for Collision chnages 174// private int m_lastColCount = -1; //KF: Look for Collision chnages
172// private int m_updateCount = 0; //KF: Update Anims for a while 175// private int m_updateCount = 0; //KF: Update Anims for a while
173// private static readonly int UPDATE_COUNT = 10; // how many frames to update for 176// private static readonly int UPDATE_COUNT = 10; // how many frames to update for
177 private List<uint> m_lastColliders = new List<uint>();
174 178
175 private TeleportFlags m_teleportFlags; 179 private TeleportFlags m_teleportFlags;
176 public TeleportFlags TeleportFlags 180 public TeleportFlags TeleportFlags
@@ -221,8 +225,6 @@ namespace OpenSim.Region.Framework.Scenes
221 /// </summary> 225 /// </summary>
222 public bool LandAtTarget { get; private set; } 226 public bool LandAtTarget { get; private set; }
223 227
224 private bool m_followCamAuto;
225
226 private int m_movementUpdateCount; 228 private int m_movementUpdateCount;
227 private const int NumMovementsBetweenRayCast = 5; 229 private const int NumMovementsBetweenRayCast = 5;
228 230
@@ -230,6 +232,13 @@ namespace OpenSim.Region.Framework.Scenes
230 //private int m_moveToPositionStateStatus; 232 //private int m_moveToPositionStateStatus;
231 //***************************************************** 233 //*****************************************************
232 234
235 private bool m_collisionEventFlag = false;
236 private object m_collisionEventLock = new Object();
237
238 private int m_movementAnimationUpdateCounter = 0;
239
240 private Vector3 m_prevSitOffset;
241
233 protected AvatarAppearance m_appearance; 242 protected AvatarAppearance m_appearance;
234 243
235 public AvatarAppearance Appearance 244 public AvatarAppearance Appearance
@@ -344,6 +353,9 @@ namespace OpenSim.Region.Framework.Scenes
344 /// </summary> 353 /// </summary>
345 protected Vector3 m_lastCameraPosition; 354 protected Vector3 m_lastCameraPosition;
346 355
356 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
357 private bool m_doingCamRayCast = false;
358
347 public Vector3 CameraPosition { get; set; } 359 public Vector3 CameraPosition { get; set; }
348 360
349 public Quaternion CameraRotation 361 public Quaternion CameraRotation
@@ -424,7 +436,7 @@ namespace OpenSim.Region.Framework.Scenes
424 get { return (IClientCore)ControllingClient; } 436 get { return (IClientCore)ControllingClient; }
425 } 437 }
426 438
427 public Vector3 ParentPosition { get; set; } 439// public Vector3 ParentPosition { get; set; }
428 440
429 /// <summary> 441 /// <summary>
430 /// Position of this avatar relative to the region the avatar is in 442 /// Position of this avatar relative to the region the avatar is in
@@ -482,7 +494,7 @@ namespace OpenSim.Region.Framework.Scenes
482 if (ParentID == 0) 494 if (ParentID == 0)
483 { 495 {
484 m_pos = value; 496 m_pos = value;
485 ParentPosition = Vector3.Zero; 497// ParentPosition = Vector3.Zero;
486 } 498 }
487 499
488 //m_log.DebugFormat( 500 //m_log.DebugFormat(
@@ -551,7 +563,24 @@ namespace OpenSim.Region.Framework.Scenes
551// Scene.RegionInfo.RegionName, Name, m_velocity); 563// Scene.RegionInfo.RegionName, Name, m_velocity);
552 } 564 }
553 } 565 }
566/*
567 public override Vector3 AngularVelocity
568 {
569 get
570 {
571 if (PhysicsActor != null)
572 {
573 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
574
575 // m_log.DebugFormat(
576 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
577 // m_velocity, Name, Scene.RegionInfo.RegionName);
578 }
554 579
580 return m_rotationalvelocity;
581 }
582 }
583*/
555 private Quaternion m_bodyRot = Quaternion.Identity; 584 private Quaternion m_bodyRot = Quaternion.Identity;
556 585
557 public Quaternion Rotation 586 public Quaternion Rotation
@@ -562,19 +591,34 @@ namespace OpenSim.Region.Framework.Scenes
562 m_bodyRot = value; 591 m_bodyRot = value;
563 if (PhysicsActor != null) 592 if (PhysicsActor != null)
564 { 593 {
565 PhysicsActor.Orientation = m_bodyRot; 594 try
595 {
596 PhysicsActor.Orientation = m_bodyRot;
597 }
598 catch (Exception e)
599 {
600 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
601 }
566 } 602 }
567// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 603// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
568 } 604 }
569 } 605 }
570 606
571 public bool IsChildAgent { get; set; } 607 public bool IsChildAgent { get; set; }
608 public bool IsLoggingIn { get; set; }
572 609
573 /// <summary> 610 /// <summary>
574 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 611 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
575 /// </summary> 612 /// </summary>
576 public uint ParentID { get; set; } 613 public uint ParentID { get; set; }
577 614
615 public UUID ParentUUID
616 {
617 get { return m_parentUUID; }
618 set { m_parentUUID = value; }
619 }
620 private UUID m_parentUUID = UUID.Zero;
621
578 /// <summary> 622 /// <summary>
579 /// Are we sitting on an object? 623 /// Are we sitting on an object?
580 /// </summary> 624 /// </summary>
@@ -698,6 +742,7 @@ namespace OpenSim.Region.Framework.Scenes
698 AttachmentsSyncLock = new Object(); 742 AttachmentsSyncLock = new Object();
699 AllowMovement = true; 743 AllowMovement = true;
700 IsChildAgent = true; 744 IsChildAgent = true;
745 IsLoggingIn = false;
701 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 746 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
702 Animator = new ScenePresenceAnimator(this); 747 Animator = new ScenePresenceAnimator(this);
703 PresenceType = type; 748 PresenceType = type;
@@ -741,6 +786,33 @@ namespace OpenSim.Region.Framework.Scenes
741 Appearance = appearance; 786 Appearance = appearance;
742 } 787 }
743 788
789 private void RegionHeartbeatEnd(Scene scene)
790 {
791 if (IsChildAgent)
792 return;
793
794 m_movementAnimationUpdateCounter ++;
795 if (m_movementAnimationUpdateCounter >= 2)
796 {
797 m_movementAnimationUpdateCounter = 0;
798 if (Animator != null)
799 {
800 // If the parentID == 0 we are not sitting
801 // if !SitGournd then we are not sitting on the ground
802 // Fairly straightforward, now here comes the twist
803 // if ParentUUID is NOT UUID.Zero, we are looking to
804 // be sat on an object that isn't there yet. Should
805 // be treated as if sat.
806 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
807 Animator.UpdateMovementAnimations();
808 }
809 else
810 {
811 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
812 }
813 }
814 }
815
744 public void RegisterToEvents() 816 public void RegisterToEvents()
745 { 817 {
746 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 818 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -750,8 +822,10 @@ namespace OpenSim.Region.Framework.Scenes
750 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 822 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
751 ControllingClient.OnStartAnim += HandleStartAnim; 823 ControllingClient.OnStartAnim += HandleStartAnim;
752 ControllingClient.OnStopAnim += HandleStopAnim; 824 ControllingClient.OnStopAnim += HandleStopAnim;
825 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
753 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 826 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
754 ControllingClient.OnAutoPilotGo += MoveToTarget; 827 ControllingClient.OnAutoPilotGo += MoveToTarget;
828 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
755 829
756 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 830 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
757 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 831 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -810,10 +884,40 @@ namespace OpenSim.Region.Framework.Scenes
810 "[SCENE]: Upgrading child to root agent for {0} in {1}", 884 "[SCENE]: Upgrading child to root agent for {0} in {1}",
811 Name, m_scene.RegionInfo.RegionName); 885 Name, m_scene.RegionInfo.RegionName);
812 886
813 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
814
815 bool wasChild = IsChildAgent; 887 bool wasChild = IsChildAgent;
816 IsChildAgent = false; 888
889 if (ParentUUID != UUID.Zero)
890 {
891 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
892 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
893 if (part == null)
894 {
895 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
896 }
897 else
898 {
899 part.ParentGroup.AddAvatar(UUID);
900 if (part.SitTargetPosition != Vector3.Zero)
901 part.SitTargetAvatar = UUID;
902// ParentPosition = part.GetWorldPosition();
903 ParentID = part.LocalId;
904 ParentPart = part;
905 m_pos = m_prevSitOffset;
906// pos = ParentPosition;
907 pos = part.GetWorldPosition();
908 }
909 ParentUUID = UUID.Zero;
910
911 IsChildAgent = false;
912
913// Animator.TrySetMovementAnimation("SIT");
914 }
915 else
916 {
917 IsChildAgent = false;
918 IsLoggingIn = false;
919 }
920
817 921
818 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); 922 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
819 if (gm != null) 923 if (gm != null)
@@ -823,62 +927,99 @@ namespace OpenSim.Region.Framework.Scenes
823 927
824 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 928 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
825 929
826 // Moved this from SendInitialData to ensure that Appearance is initialized 930 UUID groupUUID = UUID.Zero;
827 // before the inventory is processed in MakeRootAgent. This fixes a race condition 931 string GroupName = string.Empty;
828 // related to the handling of attachments 932 ulong groupPowers = 0;
829 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance); 933
830 if (m_scene.TestBorderCross(pos, Cardinals.E)) 934 // ----------------------------------
935 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
936 try
831 { 937 {
832 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 938 if (gm != null)
833 pos.X = crossedBorder.BorderLine.Z - 1; 939 {
940 groupUUID = ControllingClient.ActiveGroupId;
941 GroupRecord record = gm.GetGroupRecord(groupUUID);
942 if (record != null)
943 GroupName = record.GroupName;
944 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
945 if (groupMembershipData != null)
946 groupPowers = groupMembershipData.GroupPowers;
947 }
948 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
949 Grouptitle);
834 } 950 }
835 951 catch (Exception e)
836 if (m_scene.TestBorderCross(pos, Cardinals.N))
837 { 952 {
838 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 953 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
839 pos.Y = crossedBorder.BorderLine.Z - 1;
840 } 954 }
955 // ------------------------------------
841 956
842 CheckAndAdjustLandingPoint(ref pos); 957 if (ParentID == 0)
843
844 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
845 { 958 {
846 m_log.WarnFormat( 959 // Moved this from SendInitialData to ensure that Appearance is initialized
847 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 960 // before the inventory is processed in MakeRootAgent. This fixes a race condition
848 pos, Name, UUID); 961 // related to the handling of attachments
962 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
963 if (m_scene.TestBorderCross(pos, Cardinals.E))
964 {
965 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
966 pos.X = crossedBorder.BorderLine.Z - 1;
967 }
849 968
850 if (pos.X < 0f) pos.X = 0f; 969 if (m_scene.TestBorderCross(pos, Cardinals.N))
851 if (pos.Y < 0f) pos.Y = 0f; 970 {
852 if (pos.Z < 0f) pos.Z = 0f; 971 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
853 } 972 pos.Y = crossedBorder.BorderLine.Z - 1;
973 }
854 974
855 float localAVHeight = 1.56f; 975 CheckAndAdjustLandingPoint(ref pos);
856 if (Appearance.AvatarHeight > 0)
857 localAVHeight = Appearance.AvatarHeight;
858 976
859 float posZLimit = 0; 977 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
978 {
979 m_log.WarnFormat(
980 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
981 pos, Name, UUID);
860 982
861 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 983 if (pos.X < 0f) pos.X = 0f;
862 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 984 if (pos.Y < 0f) pos.Y = 0f;
863 985 if (pos.Z < 0f) pos.Z = 0f;
864 float newPosZ = posZLimit + localAVHeight / 2; 986 }
865 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
866 {
867 pos.Z = newPosZ;
868 }
869 AbsolutePosition = pos;
870 987
871 AddToPhysicalScene(isFlying); 988 float localAVHeight = 1.56f;
989 if (Appearance.AvatarHeight > 0)
990 localAVHeight = Appearance.AvatarHeight;
872 991
873 if (ForceFly) 992 float posZLimit = 0;
874 {
875 Flying = true;
876 }
877 else if (FlyDisabled)
878 {
879 Flying = false;
880 }
881 993
994 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
995 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
996
997 float newPosZ = posZLimit + localAVHeight / 2;
998 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
999 {
1000 pos.Z = newPosZ;
1001 }
1002 AbsolutePosition = pos;
1003
1004 if (m_teleportFlags == TeleportFlags.Default)
1005 {
1006 Vector3 vel = Velocity;
1007 AddToPhysicalScene(isFlying);
1008 if (PhysicsActor != null)
1009 PhysicsActor.SetMomentum(vel);
1010 }
1011 else
1012 AddToPhysicalScene(isFlying);
1013
1014 if (ForceFly)
1015 {
1016 Flying = true;
1017 }
1018 else if (FlyDisabled)
1019 {
1020 Flying = false;
1021 }
1022 }
882 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1023 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
883 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1024 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
884 // elsewhere anyway 1025 // elsewhere anyway
@@ -898,14 +1039,19 @@ namespace OpenSim.Region.Framework.Scenes
898 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); 1039 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
899 1040
900 // Resume scripts 1041 // Resume scripts
901 foreach (SceneObjectGroup sog in m_attachments) 1042 Util.FireAndForget(delegate(object x) {
902 { 1043 foreach (SceneObjectGroup sog in m_attachments)
903 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1044 {
904 sog.ResumeScripts(); 1045 sog.ScheduleGroupForFullUpdate();
905 } 1046 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1047 sog.ResumeScripts();
1048 }
1049 });
906 } 1050 }
907 } 1051 }
908 1052
1053 SendAvatarDataToAllAgents();
1054
909 // send the animations of the other presences to me 1055 // send the animations of the other presences to me
910 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1056 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
911 { 1057 {
@@ -916,9 +1062,12 @@ namespace OpenSim.Region.Framework.Scenes
916 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1062 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
917 // stall on the border crossing since the existing child agent will still have the last movement 1063 // stall on the border crossing since the existing child agent will still have the last movement
918 // recorded, which stops the input from being processed. 1064 // recorded, which stops the input from being processed.
1065
919 MovementFlag = 0; 1066 MovementFlag = 0;
920 1067
921 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1068 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1069
1070 m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
922 } 1071 }
923 1072
924 public int GetStateSource() 1073 public int GetStateSource()
@@ -946,12 +1095,16 @@ namespace OpenSim.Region.Framework.Scenes
946 /// </remarks> 1095 /// </remarks>
947 public void MakeChildAgent() 1096 public void MakeChildAgent()
948 { 1097 {
1098 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1099
949 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1100 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
950 1101
951 // Reset these so that teleporting in and walking out isn't seen 1102 // Reset these so that teleporting in and walking out isn't seen
952 // as teleporting back 1103 // as teleporting back
953 TeleportFlags = TeleportFlags.Default; 1104 TeleportFlags = TeleportFlags.Default;
954 1105
1106 MovementFlag = 0;
1107
955 // It looks like Animator is set to null somewhere, and MakeChild 1108 // It looks like Animator is set to null somewhere, and MakeChild
956 // is called after that. Probably in aborted teleports. 1109 // is called after that. Probably in aborted teleports.
957 if (Animator == null) 1110 if (Animator == null)
@@ -959,6 +1112,7 @@ namespace OpenSim.Region.Framework.Scenes
959 else 1112 else
960 Animator.ResetAnimations(); 1113 Animator.ResetAnimations();
961 1114
1115
962// m_log.DebugFormat( 1116// m_log.DebugFormat(
963// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1117// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
964// Name, UUID, m_scene.RegionInfo.RegionName); 1118// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -970,6 +1124,7 @@ namespace OpenSim.Region.Framework.Scenes
970 IsChildAgent = true; 1124 IsChildAgent = true;
971 m_scene.SwapRootAgentCount(true); 1125 m_scene.SwapRootAgentCount(true);
972 RemoveFromPhysicalScene(); 1126 RemoveFromPhysicalScene();
1127 ParentID = 0; // Child agents can't be sitting
973 1128
974 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1129 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
975 1130
@@ -985,9 +1140,9 @@ namespace OpenSim.Region.Framework.Scenes
985 { 1140 {
986// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1141// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
987 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1142 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
988 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
989 PhysicsActor.UnSubscribeEvents();
990 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1143 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1144 PhysicsActor.UnSubscribeEvents();
1145 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
991 PhysicsActor = null; 1146 PhysicsActor = null;
992 } 1147 }
993// else 1148// else
@@ -1004,7 +1159,7 @@ namespace OpenSim.Region.Framework.Scenes
1004 /// <param name="pos"></param> 1159 /// <param name="pos"></param>
1005 public void Teleport(Vector3 pos) 1160 public void Teleport(Vector3 pos)
1006 { 1161 {
1007 TeleportWithMomentum(pos, null); 1162 TeleportWithMomentum(pos, Vector3.Zero);
1008 } 1163 }
1009 1164
1010 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1165 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1028,6 +1183,41 @@ namespace OpenSim.Region.Framework.Scenes
1028 SendTerseUpdateToAllClients(); 1183 SendTerseUpdateToAllClients();
1029 } 1184 }
1030 1185
1186 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1187 {
1188 CheckLandingPoint(ref newpos);
1189 AbsolutePosition = newpos;
1190
1191 if (newvel.HasValue)
1192 {
1193 if ((Vector3)newvel == Vector3.Zero)
1194 {
1195 if (PhysicsActor != null)
1196 PhysicsActor.SetMomentum(Vector3.Zero);
1197 m_velocity = Vector3.Zero;
1198 }
1199 else
1200 {
1201 if (PhysicsActor != null)
1202 PhysicsActor.SetMomentum((Vector3)newvel);
1203 m_velocity = (Vector3)newvel;
1204
1205 if (rotateToVelXY)
1206 {
1207 Vector3 lookAt = (Vector3)newvel;
1208 lookAt.Z = 0;
1209 lookAt.Normalize();
1210 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1211 return;
1212 }
1213 }
1214 }
1215
1216 SendTerseUpdateToAllClients();
1217 }
1218
1219
1220
1031 public void StopFlying() 1221 public void StopFlying()
1032 { 1222 {
1033 ControllingClient.StopFlying(this); 1223 ControllingClient.StopFlying(this);
@@ -1118,6 +1308,13 @@ namespace OpenSim.Region.Framework.Scenes
1118 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1308 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1119 } 1309 }
1120 1310
1311 public void SetSize(Vector3 size, float feetoffset)
1312 {
1313 if (PhysicsActor != null && !IsChildAgent)
1314 PhysicsActor.setAvatarSize(size, feetoffset);
1315
1316 }
1317
1121 /// <summary> 1318 /// <summary>
1122 /// Complete Avatar's movement into the region. 1319 /// Complete Avatar's movement into the region.
1123 /// </summary> 1320 /// </summary>
@@ -1137,7 +1334,8 @@ namespace OpenSim.Region.Framework.Scenes
1137 1334
1138 Vector3 look = Velocity; 1335 Vector3 look = Velocity;
1139 1336
1140 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1337 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1338 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1141 { 1339 {
1142 look = new Vector3(0.99f, 0.042f, 0); 1340 look = new Vector3(0.99f, 0.042f, 0);
1143 } 1341 }
@@ -1187,13 +1385,15 @@ namespace OpenSim.Region.Framework.Scenes
1187 // Create child agents in neighbouring regions 1385 // Create child agents in neighbouring regions
1188 if (openChildAgents && !IsChildAgent) 1386 if (openChildAgents && !IsChildAgent)
1189 { 1387 {
1388
1190 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1389 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1191 if (m_agentTransfer != null) 1390 if (m_agentTransfer != null)
1192 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1391 m_agentTransfer.EnableChildAgents(this);
1193 1392
1194 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1393 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1195 if (friendsModule != null) 1394 if (friendsModule != null)
1196 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1395 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1396
1197 } 1397 }
1198 1398
1199// m_log.DebugFormat( 1399// m_log.DebugFormat(
@@ -1209,35 +1409,43 @@ namespace OpenSim.Region.Framework.Scenes
1209 /// <param name="collisionPoint"></param> 1409 /// <param name="collisionPoint"></param>
1210 /// <param name="localid"></param> 1410 /// <param name="localid"></param>
1211 /// <param name="distance"></param> 1411 /// <param name="distance"></param>
1412 ///
1413
1414 private void UpdateCameraCollisionPlane(Vector4 plane)
1415 {
1416 if (m_lastCameraCollisionPlane != plane)
1417 {
1418 m_lastCameraCollisionPlane = plane;
1419 ControllingClient.SendCameraConstraint(plane);
1420 }
1421 }
1422
1212 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1423 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1213 { 1424 {
1214 const float POSITION_TOLERANCE = 0.02f; 1425 const float POSITION_TOLERANCE = 0.02f;
1215 const float VELOCITY_TOLERANCE = 0.02f;
1216 const float ROTATION_TOLERANCE = 0.02f; 1426 const float ROTATION_TOLERANCE = 0.02f;
1217 1427
1218 if (m_followCamAuto) 1428 m_doingCamRayCast = false;
1429 if (hitYN && localid != LocalId)
1219 { 1430 {
1220 if (hitYN) 1431 CameraConstraintActive = true;
1221 { 1432 pNormal.X = (float)Math.Round(pNormal.X, 2);
1222 CameraConstraintActive = true; 1433 pNormal.Y = (float)Math.Round(pNormal.Y, 2);
1223 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1434 pNormal.Z = (float)Math.Round(pNormal.Z, 2);
1224 1435 pNormal.Normalize();
1225 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1436 collisionPoint.X = (float)Math.Round(collisionPoint.X, 1);
1226 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1437 collisionPoint.Y = (float)Math.Round(collisionPoint.Y, 1);
1227 } 1438 collisionPoint.Z = (float)Math.Round(collisionPoint.Z, 1);
1228 else 1439
1229 { 1440 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z, Vector3.Dot(collisionPoint, pNormal));
1230 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1441 UpdateCameraCollisionPlane(plane);
1231 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1442 }
1232 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1443 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1233 { 1444 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1234 if (CameraConstraintActive) 1445 {
1235 { 1446 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1236 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1447 UpdateCameraCollisionPlane(plane);
1237 CameraConstraintActive = false; 1448 CameraConstraintActive = false;
1238 }
1239 }
1240 }
1241 } 1449 }
1242 } 1450 }
1243 1451
@@ -1312,12 +1520,6 @@ namespace OpenSim.Region.Framework.Scenes
1312 // DrawDistance = agentData.Far; 1520 // DrawDistance = agentData.Far;
1313 DrawDistance = Scene.DefaultDrawDistance; 1521 DrawDistance = Scene.DefaultDrawDistance;
1314 1522
1315 // Check if Client has camera in 'follow cam' or 'build' mode.
1316 Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
1317
1318 m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
1319 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
1320
1321 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; 1523 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
1322 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; 1524 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
1323 1525
@@ -1337,14 +1539,38 @@ namespace OpenSim.Region.Framework.Scenes
1337 StandUp(); 1539 StandUp();
1338 } 1540 }
1339 1541
1340 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
1341 // Raycast from the avatar's head to the camera to see if there's anything blocking the view 1542 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1342 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) 1543 // this exclude checks may not be complete
1544
1545 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1343 { 1546 {
1344 if (m_followCamAuto) 1547 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1548 {
1549 Vector3 posAdjusted = AbsolutePosition;
1550// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1551 posAdjusted.Z += 1.0f; // viewer current camera focus point
1552 Vector3 tocam = CameraPosition - posAdjusted;
1553 tocam.X = (float)Math.Round(tocam.X, 1);
1554 tocam.Y = (float)Math.Round(tocam.Y, 1);
1555 tocam.Z = (float)Math.Round(tocam.Z, 1);
1556
1557 float distTocamlen = tocam.Length();
1558 if (distTocamlen > 0.3f)
1559 {
1560 tocam *= (1.0f / distTocamlen);
1561 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1562 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1563 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1564
1565 m_doingCamRayCast = true;
1566 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1567 }
1568 }
1569 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1345 { 1570 {
1346 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; 1571 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1347 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback); 1572 UpdateCameraCollisionPlane(plane);
1573 CameraConstraintActive = false;
1348 } 1574 }
1349 } 1575 }
1350 1576
@@ -1782,7 +2008,8 @@ namespace OpenSim.Region.Framework.Scenes
1782// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2008// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1783 2009
1784 MovingToTarget = false; 2010 MovingToTarget = false;
1785 MoveToPositionTarget = Vector3.Zero; 2011// MoveToPositionTarget = Vector3.Zero;
2012 m_forceToApply = null; // cancel possible last action
1786 2013
1787 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2014 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
1788 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2015 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -1800,12 +2027,17 @@ namespace OpenSim.Region.Framework.Scenes
1800// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2027// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
1801 2028
1802 SitGround = false; 2029 SitGround = false;
2030
2031/* move this down so avatar gets physical in the new position and not where it is siting
1803 if (PhysicsActor == null) 2032 if (PhysicsActor == null)
1804 AddToPhysicalScene(false); 2033 AddToPhysicalScene(false);
2034 */
1805 2035
1806 if (ParentID != 0) 2036 if (ParentID != 0)
1807 { 2037 {
1808 SceneObjectPart part = ParentPart; 2038 SceneObjectPart part = ParentPart;
2039 UnRegisterSeatControls(part.ParentGroup.UUID);
2040
1809 TaskInventoryDictionary taskIDict = part.TaskInventory; 2041 TaskInventoryDictionary taskIDict = part.TaskInventory;
1810 if (taskIDict != null) 2042 if (taskIDict != null)
1811 { 2043 {
@@ -1821,14 +2053,22 @@ namespace OpenSim.Region.Framework.Scenes
1821 } 2053 }
1822 } 2054 }
1823 2055
1824 ParentPosition = part.GetWorldPosition(); 2056 part.ParentGroup.DeleteAvatar(UUID);
2057// ParentPosition = part.GetWorldPosition();
1825 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2058 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1826 2059
1827 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 2060// m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
1828 ParentPosition = Vector3.Zero; 2061// ParentPosition = Vector3.Zero;
2062 m_pos = part.AbsolutePosition + (m_pos * part.GetWorldRotation()) + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2063 if (part.SitTargetAvatar == UUID)
2064 m_bodyRot = part.GetWorldRotation() * part.SitTargetOrientation;
1829 2065
1830 ParentID = 0; 2066 ParentID = 0;
1831 ParentPart = null; 2067 ParentPart = null;
2068
2069 if (PhysicsActor == null)
2070 AddToPhysicalScene(false);
2071
1832 SendAvatarDataToAllAgents(); 2072 SendAvatarDataToAllAgents();
1833 m_requestedSitTargetID = 0; 2073 m_requestedSitTargetID = 0;
1834 2074
@@ -1838,6 +2078,9 @@ namespace OpenSim.Region.Framework.Scenes
1838 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2078 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1839 } 2079 }
1840 2080
2081 else if (PhysicsActor == null)
2082 AddToPhysicalScene(false);
2083
1841 Animator.TrySetMovementAnimation("STAND"); 2084 Animator.TrySetMovementAnimation("STAND");
1842 } 2085 }
1843 2086
@@ -1885,11 +2128,8 @@ namespace OpenSim.Region.Framework.Scenes
1885 if (part == null) 2128 if (part == null)
1886 return; 2129 return;
1887 2130
1888 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1889 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1890
1891 if (PhysicsActor != null) 2131 if (PhysicsActor != null)
1892 m_sitAvatarHeight = PhysicsActor.Size.Z; 2132 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
1893 2133
1894 bool canSit = false; 2134 bool canSit = false;
1895 Vector3 pos = part.AbsolutePosition + offset; 2135 Vector3 pos = part.AbsolutePosition + offset;
@@ -1906,31 +2146,31 @@ namespace OpenSim.Region.Framework.Scenes
1906 } 2146 }
1907 else 2147 else
1908 { 2148 {
2149 if (PhysicsSit(part,offset)) // physics engine
2150 return;
2151
1909 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2152 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
1910 { 2153 {
1911// m_log.DebugFormat(
1912// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
1913// Name, part.Name, part.LocalId);
1914 2154
1915 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2155 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1916 canSit = true; 2156 canSit = true;
1917 } 2157 }
1918// else
1919// {
1920// m_log.DebugFormat(
1921// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
1922// Name, part.Name, part.LocalId);
1923// }
1924 } 2158 }
1925 2159
1926 if (canSit) 2160 if (canSit)
1927 { 2161 {
2162
1928 if (PhysicsActor != null) 2163 if (PhysicsActor != null)
1929 { 2164 {
1930 // We can remove the physicsActor until they stand up. 2165 // We can remove the physicsActor until they stand up.
1931 RemoveFromPhysicalScene(); 2166 RemoveFromPhysicalScene();
1932 } 2167 }
1933 2168
2169 if (MovingToTarget)
2170 ResetMoveToTarget();
2171
2172 Velocity = Vector3.Zero;
2173
1934 part.AddSittingAvatar(UUID); 2174 part.AddSittingAvatar(UUID);
1935 2175
1936 cameraAtOffset = part.GetCameraAtOffset(); 2176 cameraAtOffset = part.GetCameraAtOffset();
@@ -1938,7 +2178,7 @@ namespace OpenSim.Region.Framework.Scenes
1938 forceMouselook = part.GetForceMouselook(); 2178 forceMouselook = part.GetForceMouselook();
1939 2179
1940 ControllingClient.SendSitResponse( 2180 ControllingClient.SendSitResponse(
1941 targetID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 2181 part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
1942 2182
1943 m_requestedSitTargetUUID = targetID; 2183 m_requestedSitTargetUUID = targetID;
1944 2184
@@ -1952,6 +2192,9 @@ namespace OpenSim.Region.Framework.Scenes
1952 2192
1953 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2193 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
1954 { 2194 {
2195 if (IsChildAgent)
2196 return;
2197
1955 if (ParentID != 0) 2198 if (ParentID != 0)
1956 { 2199 {
1957 var targetPart = m_scene.GetSceneObjectPart(targetID); 2200 var targetPart = m_scene.GetSceneObjectPart(targetID);
@@ -1968,14 +2211,6 @@ namespace OpenSim.Region.Framework.Scenes
1968 m_requestedSitTargetID = part.LocalId; 2211 m_requestedSitTargetID = part.LocalId;
1969 m_requestedSitTargetUUID = targetID; 2212 m_requestedSitTargetUUID = targetID;
1970 2213
1971// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
1972
1973 if (m_scene.PhysicsScene.SupportsRayCast())
1974 {
1975 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
1976 //SitRayCastAvatarPosition(part);
1977 //return;
1978 }
1979 } 2214 }
1980 else 2215 else
1981 { 2216 {
@@ -1985,197 +2220,111 @@ namespace OpenSim.Region.Framework.Scenes
1985 SendSitResponse(targetID, offset, Quaternion.Identity); 2220 SendSitResponse(targetID, offset, Quaternion.Identity);
1986 } 2221 }
1987 2222
1988 /* 2223 // returns false if does not suport so older sit can be tried
1989 public void SitRayCastAvatarPosition(SceneObjectPart part) 2224 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
1990 { 2225 {
1991 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2226 if (part == null || part.ParentGroup.IsAttachment)
1992 Vector3 StartRayCastPosition = AbsolutePosition;
1993 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
1994 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
1995 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
1996 }
1997
1998 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
1999 {
2000 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2001 if (part != null)
2002 {
2003 if (hitYN)
2004 {
2005 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2006 {
2007 SitRaycastFindEdge(collisionPoint, normal);
2008 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2009 }
2010 else
2011 {
2012 SitRayCastAvatarPositionCameraZ(part);
2013 }
2014 }
2015 else
2016 {
2017 SitRayCastAvatarPositionCameraZ(part);
2018 }
2019 }
2020 else
2021 { 2227 {
2022 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2228 return true;
2023 m_requestedSitTargetUUID = UUID.Zero;
2024 m_requestedSitTargetID = 0;
2025 m_requestedSitOffset = Vector3.Zero;
2026 } 2229 }
2027 2230
2028 } 2231 if ( m_scene.PhysicsScene == null)
2029 2232 return false;
2030 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2031 {
2032 // Next, try to raycast from the camera Z position
2033 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2034 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2035 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2036 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2037 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2038 }
2039 2233
2040 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2234 if (part.PhysActor == null)
2041 {
2042 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2043 if (part != null)
2044 { 2235 {
2045 if (hitYN) 2236 // none physcis shape
2046 { 2237 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2047 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2238 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2048 {
2049 SitRaycastFindEdge(collisionPoint, normal);
2050 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2051 }
2052 else
2053 {
2054 SitRayCastCameraPosition(part);
2055 }
2056 }
2057 else 2239 else
2058 { 2240 { // non physical phantom TODO
2059 SitRayCastCameraPosition(part); 2241 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2242 return false;
2060 } 2243 }
2061 } 2244 return true;
2062 else
2063 {
2064 ControllingClient.SendAlertMessage("Sit position no longer exists");
2065 m_requestedSitTargetUUID = UUID.Zero;
2066 m_requestedSitTargetID = 0;
2067 m_requestedSitOffset = Vector3.Zero;
2068 } 2245 }
2069 2246
2070 }
2071 2247
2072 public void SitRayCastCameraPosition(SceneObjectPart part) 2248 // not doing autopilot
2073 { 2249 m_requestedSitTargetID = 0;
2074 // Next, try to raycast from the camera position
2075 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2076 Vector3 StartRayCastPosition = CameraPosition;
2077 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2078 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2079 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2080 }
2081 2250
2082 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2251 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2083 { 2252 return true;
2084 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2085 if (part != null)
2086 {
2087 if (hitYN)
2088 {
2089 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2090 {
2091 SitRaycastFindEdge(collisionPoint, normal);
2092 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2093 }
2094 else
2095 {
2096 SitRayHorizontal(part);
2097 }
2098 }
2099 else
2100 {
2101 SitRayHorizontal(part);
2102 }
2103 }
2104 else
2105 {
2106 ControllingClient.SendAlertMessage("Sit position no longer exists");
2107 m_requestedSitTargetUUID = UUID.Zero;
2108 m_requestedSitTargetID = 0;
2109 m_requestedSitOffset = Vector3.Zero;
2110 }
2111 2253
2254 return false;
2112 } 2255 }
2113 2256
2114 public void SitRayHorizontal(SceneObjectPart part) 2257
2258 private bool CanEnterLandPosition(Vector3 testPos)
2115 { 2259 {
2116 // Next, try to raycast from the avatar position to fwd 2260 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2117 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2261
2118 Vector3 StartRayCastPosition = CameraPosition; 2262 if (land == null || land.LandData.Name == "NO_LAND")
2119 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2263 return true;
2120 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2264
2121 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2265 return land.CanBeOnThisLand(UUID,testPos.Z);
2122 } 2266 }
2123 2267
2124 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2268 // status
2269 // < 0 ignore
2270 // 0 bad sit spot
2271 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2125 { 2272 {
2126 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2273 if (status < 0)
2127 if (part != null) 2274 return;
2275
2276 if (status == 0)
2128 { 2277 {
2129 if (hitYN) 2278 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2130 { 2279 return;
2131 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2132 {
2133 SitRaycastFindEdge(collisionPoint, normal);
2134 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2135 // Next, try to raycast from the camera position
2136 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2137 Vector3 StartRayCastPosition = CameraPosition;
2138 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2139 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2140 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2141 }
2142 else
2143 {
2144 ControllingClient.SendAlertMessage("Sit position not accessable.");
2145 m_requestedSitTargetUUID = UUID.Zero;
2146 m_requestedSitTargetID = 0;
2147 m_requestedSitOffset = Vector3.Zero;
2148 }
2149 }
2150 else
2151 {
2152 ControllingClient.SendAlertMessage("Sit position not accessable.");
2153 m_requestedSitTargetUUID = UUID.Zero;
2154 m_requestedSitTargetID = 0;
2155 m_requestedSitOffset = Vector3.Zero;
2156 }
2157 } 2280 }
2158 else 2281
2282 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2283 if (part == null)
2284 return;
2285
2286 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2287 if(!CanEnterLandPosition(targetPos))
2159 { 2288 {
2160 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2289 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2161 m_requestedSitTargetUUID = UUID.Zero; 2290 return;
2162 m_requestedSitTargetID = 0;
2163 m_requestedSitOffset = Vector3.Zero;
2164 } 2291 }
2165 2292
2166 } 2293 RemoveFromPhysicalScene();
2167 2294
2168 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2295 if (MovingToTarget)
2169 { 2296 ResetMoveToTarget();
2170 int i = 0; 2297
2171 //throw new NotImplementedException(); 2298 Velocity = Vector3.Zero;
2172 //m_requestedSitTargetUUID = UUID.Zero; 2299
2173 //m_requestedSitTargetID = 0; 2300 part.AddSittingAvatar(UUID);
2174 //m_requestedSitOffset = Vector3.Zero;
2175 2301
2176 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2302 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2303 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2304 bool forceMouselook = part.GetForceMouselook();
2305
2306 ControllingClient.SendSitResponse(
2307 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2308
2309 // not using autopilot
2310
2311 Rotation = Orientation;
2312 m_pos = offset;
2313
2314 m_requestedSitTargetID = 0;
2315 part.ParentGroup.AddAvatar(UUID);
2316
2317 ParentPart = part;
2318 ParentID = part.LocalId;
2319 if(status == 3)
2320 Animator.TrySetMovementAnimation("SIT_GROUND");
2321 else
2322 Animator.TrySetMovementAnimation("SIT");
2323 SendAvatarDataToAllAgents();
2324
2325 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2177 } 2326 }
2178 */ 2327
2179 2328
2180 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2329 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2181 { 2330 {
@@ -2192,6 +2341,7 @@ namespace OpenSim.Region.Framework.Scenes
2192 return; 2341 return;
2193 } 2342 }
2194 2343
2344
2195 if (part.SitTargetAvatar == UUID) 2345 if (part.SitTargetAvatar == UUID)
2196 { 2346 {
2197 Vector3 sitTargetPos = part.SitTargetPosition; 2347 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2206,14 +2356,39 @@ namespace OpenSim.Region.Framework.Scenes
2206 2356
2207 //Quaternion result = (sitTargetOrient * vq) * nq; 2357 //Quaternion result = (sitTargetOrient * vq) * nq;
2208 2358
2209 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2359 double x, y, z, m;
2360
2361 Quaternion r = sitTargetOrient;
2362 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2363
2364 if (Math.Abs(1.0 - m) > 0.000001)
2365 {
2366 m = 1.0 / Math.Sqrt(m);
2367 r.X *= (float)m;
2368 r.Y *= (float)m;
2369 r.Z *= (float)m;
2370 r.W *= (float)m;
2371 }
2372
2373 x = 2 * (r.X * r.Z + r.Y * r.W);
2374 y = 2 * (-r.X * r.W + r.Y * r.Z);
2375 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2376
2377 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2378 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2379
2380 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2381
2382// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2210 Rotation = sitTargetOrient; 2383 Rotation = sitTargetOrient;
2211 ParentPosition = part.AbsolutePosition; 2384// ParentPosition = part.AbsolutePosition;
2385 part.ParentGroup.AddAvatar(UUID);
2212 } 2386 }
2213 else 2387 else
2214 { 2388 {
2215 m_pos -= part.AbsolutePosition; 2389 m_pos -= part.AbsolutePosition;
2216 ParentPosition = part.AbsolutePosition; 2390// ParentPosition = part.AbsolutePosition;
2391 part.ParentGroup.AddAvatar(UUID);
2217 2392
2218// m_log.DebugFormat( 2393// m_log.DebugFormat(
2219// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2394// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2263,6 +2438,13 @@ namespace OpenSim.Region.Framework.Scenes
2263 Animator.RemoveAnimation(animID); 2438 Animator.RemoveAnimation(animID);
2264 } 2439 }
2265 2440
2441 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
2442 {
2443 Animator.avnChangeAnim(animID, addRemove, sendPack);
2444 }
2445
2446
2447
2266 /// <summary> 2448 /// <summary>
2267 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2449 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2268 /// </summary> 2450 /// </summary>
@@ -2316,14 +2498,15 @@ namespace OpenSim.Region.Framework.Scenes
2316 direc.Z *= 2.6f; 2498 direc.Z *= 2.6f;
2317 2499
2318 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2500 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2319 Animator.TrySetMovementAnimation("PREJUMP"); 2501// Animator.TrySetMovementAnimation("PREJUMP");
2320 Animator.TrySetMovementAnimation("JUMP"); 2502// Animator.TrySetMovementAnimation("JUMP");
2321 } 2503 }
2322 } 2504 }
2323 } 2505 }
2324 2506
2325 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2507 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2326 m_forceToApply = direc; 2508 m_forceToApply = direc;
2509 Animator.UpdateMovementAnimations();
2327 } 2510 }
2328 2511
2329 #endregion 2512 #endregion
@@ -2341,16 +2524,12 @@ namespace OpenSim.Region.Framework.Scenes
2341 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 2524 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2342 // grab the latest PhysicsActor velocity, whereas m_velocity is often 2525 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2343 // storing a requested force instead of an actual traveling velocity 2526 // storing a requested force instead of an actual traveling velocity
2527 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
2528 SendAvatarDataToAllAgents();
2344 2529
2345 // Throw away duplicate or insignificant updates 2530 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2346 if ( 2531 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2347 // If the velocity has become zero, send it no matter what. 2532 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2348 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2349 // otherwise, if things have changed reasonably, send the update
2350 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2351 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2352 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2353
2354 { 2533 {
2355 SendTerseUpdateToAllClients(); 2534 SendTerseUpdateToAllClients();
2356 2535
@@ -2539,6 +2718,8 @@ namespace OpenSim.Region.Framework.Scenes
2539 return; 2718 return;
2540 } 2719 }
2541 2720
2721 m_lastSize = Appearance.AvatarSize;
2722
2542 int count = 0; 2723 int count = 0;
2543 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2724 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2544 { 2725 {
@@ -2646,6 +2827,8 @@ namespace OpenSim.Region.Framework.Scenes
2646 2827
2647 avatar.ControllingClient.SendAppearance( 2828 avatar.ControllingClient.SendAppearance(
2648 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 2829 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
2830
2831
2649 } 2832 }
2650 2833
2651 #endregion 2834 #endregion
@@ -2720,8 +2903,9 @@ namespace OpenSim.Region.Framework.Scenes
2720 2903
2721 // If we don't have a PhysActor, we can't cross anyway 2904 // If we don't have a PhysActor, we can't cross anyway
2722 // Also don't do this while sat, sitting avatars cross with the 2905 // Also don't do this while sat, sitting avatars cross with the
2723 // object they sit on. 2906 // object they sit on. ParentUUID denoted a pending sit, don't
2724 if (ParentID != 0 || PhysicsActor == null) 2907 // interfere with it.
2908 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
2725 return; 2909 return;
2726 2910
2727 if (!IsInTransit) 2911 if (!IsInTransit)
@@ -2982,6 +3166,10 @@ namespace OpenSim.Region.Framework.Scenes
2982 } 3166 }
2983 3167
2984 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3168 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3169 private void RaiseUpdateThrottles()
3170 {
3171 m_scene.EventManager.TriggerThrottleUpdate(this);
3172 }
2985 /// <summary> 3173 /// <summary>
2986 /// This updates important decision making data about a child agent 3174 /// This updates important decision making data about a child agent
2987 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3175 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3062,6 +3250,9 @@ namespace OpenSim.Region.Framework.Scenes
3062 cAgent.AlwaysRun = SetAlwaysRun; 3250 cAgent.AlwaysRun = SetAlwaysRun;
3063 3251
3064 cAgent.Appearance = new AvatarAppearance(Appearance); 3252 cAgent.Appearance = new AvatarAppearance(Appearance);
3253
3254 cAgent.ParentPart = ParentUUID;
3255 cAgent.SitOffset = m_pos;
3065 3256
3066 lock (scriptedcontrols) 3257 lock (scriptedcontrols)
3067 { 3258 {
@@ -3070,7 +3261,7 @@ namespace OpenSim.Region.Framework.Scenes
3070 3261
3071 foreach (ScriptControllers c in scriptedcontrols.Values) 3262 foreach (ScriptControllers c in scriptedcontrols.Values)
3072 { 3263 {
3073 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3264 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3074 } 3265 }
3075 cAgent.Controllers = controls; 3266 cAgent.Controllers = controls;
3076 } 3267 }
@@ -3103,6 +3294,8 @@ namespace OpenSim.Region.Framework.Scenes
3103 CameraAtAxis = cAgent.AtAxis; 3294 CameraAtAxis = cAgent.AtAxis;
3104 CameraLeftAxis = cAgent.LeftAxis; 3295 CameraLeftAxis = cAgent.LeftAxis;
3105 CameraUpAxis = cAgent.UpAxis; 3296 CameraUpAxis = cAgent.UpAxis;
3297 ParentUUID = cAgent.ParentPart;
3298 m_prevSitOffset = cAgent.SitOffset;
3106 3299
3107 // When we get to the point of re-computing neighbors everytime this 3300 // When we get to the point of re-computing neighbors everytime this
3108 // changes, then start using the agent's drawdistance rather than the 3301 // changes, then start using the agent's drawdistance rather than the
@@ -3140,6 +3333,7 @@ namespace OpenSim.Region.Framework.Scenes
3140 foreach (ControllerData c in cAgent.Controllers) 3333 foreach (ControllerData c in cAgent.Controllers)
3141 { 3334 {
3142 ScriptControllers sc = new ScriptControllers(); 3335 ScriptControllers sc = new ScriptControllers();
3336 sc.objectID = c.ObjectID;
3143 sc.itemID = c.ItemID; 3337 sc.itemID = c.ItemID;
3144 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3338 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3145 sc.eventControls = (ScriptControlled)c.EventControls; 3339 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3207,20 +3401,27 @@ namespace OpenSim.Region.Framework.Scenes
3207 } 3401 }
3208 3402
3209 if (Appearance.AvatarHeight == 0) 3403 if (Appearance.AvatarHeight == 0)
3210 Appearance.SetHeight(); 3404// Appearance.SetHeight();
3405 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3211 3406
3212 PhysicsScene scene = m_scene.PhysicsScene; 3407 PhysicsScene scene = m_scene.PhysicsScene;
3213 3408
3214 Vector3 pVec = AbsolutePosition; 3409 Vector3 pVec = AbsolutePosition;
3215 3410
3411/*
3216 PhysicsActor = scene.AddAvatar( 3412 PhysicsActor = scene.AddAvatar(
3217 LocalId, Firstname + "." + Lastname, pVec, 3413 LocalId, Firstname + "." + Lastname, pVec,
3218 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3414 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3415*/
3416
3417 PhysicsActor = scene.AddAvatar(
3418 LocalId, Firstname + "." + Lastname, pVec,
3419 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
3219 3420
3220 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3421 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3221 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3422 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3222 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3423 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3223 PhysicsActor.SubscribeEvents(500); 3424 PhysicsActor.SubscribeEvents(100);
3224 PhysicsActor.LocalID = LocalId; 3425 PhysicsActor.LocalID = LocalId;
3225 } 3426 }
3226 3427
@@ -3234,6 +3435,7 @@ namespace OpenSim.Region.Framework.Scenes
3234 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3435 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3235 } 3436 }
3236 3437
3438
3237 /// <summary> 3439 /// <summary>
3238 /// Event called by the physics plugin to tell the avatar about a collision. 3440 /// Event called by the physics plugin to tell the avatar about a collision.
3239 /// </summary> 3441 /// </summary>
@@ -3247,7 +3449,7 @@ namespace OpenSim.Region.Framework.Scenes
3247 /// <param name="e"></param> 3449 /// <param name="e"></param>
3248 public void PhysicsCollisionUpdate(EventArgs e) 3450 public void PhysicsCollisionUpdate(EventArgs e)
3249 { 3451 {
3250 if (IsChildAgent) 3452 if (IsChildAgent || Animator == null)
3251 return; 3453 return;
3252 3454
3253 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3455 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3263,7 +3465,6 @@ namespace OpenSim.Region.Framework.Scenes
3263 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3465 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3264 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3466 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3265 3467
3266 CollisionPlane = Vector4.UnitW;
3267 3468
3268// // No collisions at all means we may be flying. Update always 3469// // No collisions at all means we may be flying. Update always
3269// // to make falling work 3470// // to make falling work
@@ -3275,6 +3476,7 @@ namespace OpenSim.Region.Framework.Scenes
3275 3476
3276 if (coldata.Count != 0) 3477 if (coldata.Count != 0)
3277 { 3478 {
3479/*
3278 switch (Animator.CurrentMovementAnimation) 3480 switch (Animator.CurrentMovementAnimation)
3279 { 3481 {
3280 case "STAND": 3482 case "STAND":
@@ -3283,24 +3485,38 @@ namespace OpenSim.Region.Framework.Scenes
3283 case "CROUCH": 3485 case "CROUCH":
3284 case "CROUCHWALK": 3486 case "CROUCHWALK":
3285 { 3487 {
3488 */
3286 ContactPoint lowest; 3489 ContactPoint lowest;
3287 lowest.SurfaceNormal = Vector3.Zero; 3490 lowest.SurfaceNormal = Vector3.Zero;
3288 lowest.Position = Vector3.Zero; 3491 lowest.Position = Vector3.Zero;
3289 lowest.Position.Z = Single.NaN; 3492 lowest.Position.Z = float.MaxValue;
3290 3493
3291 foreach (ContactPoint contact in coldata.Values) 3494 foreach (ContactPoint contact in coldata.Values)
3292 { 3495 {
3293 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 3496
3497 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3294 { 3498 {
3295 lowest = contact; 3499 lowest = contact;
3296 } 3500 }
3297 } 3501 }
3298 3502
3299 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 3503 if (lowest.Position.Z != float.MaxValue)
3504 {
3505 lowest.SurfaceNormal = -lowest.SurfaceNormal;
3506 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3507 }
3508 else
3509 CollisionPlane = Vector4.UnitW;
3510/*
3300 } 3511 }
3301 break; 3512 break;
3302 } 3513 }
3514*/
3303 } 3515 }
3516 else
3517 CollisionPlane = Vector4.UnitW;
3518
3519 RaiseCollisionScriptEvents(coldata);
3304 3520
3305 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3521 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3306 if (Invulnerable || GodLevel > 0) 3522 if (Invulnerable || GodLevel > 0)
@@ -3399,6 +3615,13 @@ namespace OpenSim.Region.Framework.Scenes
3399 // m_reprioritizationTimer.Dispose(); 3615 // m_reprioritizationTimer.Dispose();
3400 3616
3401 RemoveFromPhysicalScene(); 3617 RemoveFromPhysicalScene();
3618
3619 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
3620
3621// if (Animator != null)
3622// Animator.Close();
3623 Animator = null;
3624
3402 } 3625 }
3403 3626
3404 public void AddAttachment(SceneObjectGroup gobj) 3627 public void AddAttachment(SceneObjectGroup gobj)
@@ -3632,10 +3855,18 @@ namespace OpenSim.Region.Framework.Scenes
3632 3855
3633 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 3856 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
3634 { 3857 {
3858 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
3859 if (p == null)
3860 return;
3861
3862 ControllingClient.SendTakeControls(controls, false, false);
3863 ControllingClient.SendTakeControls(controls, true, false);
3864
3635 ScriptControllers obj = new ScriptControllers(); 3865 ScriptControllers obj = new ScriptControllers();
3636 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 3866 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
3637 obj.eventControls = ScriptControlled.CONTROL_ZERO; 3867 obj.eventControls = ScriptControlled.CONTROL_ZERO;
3638 3868
3869 obj.objectID = p.ParentGroup.UUID;
3639 obj.itemID = Script_item_UUID; 3870 obj.itemID = Script_item_UUID;
3640 if (pass_on == 0 && accept == 0) 3871 if (pass_on == 0 && accept == 0)
3641 { 3872 {
@@ -3684,6 +3915,21 @@ namespace OpenSim.Region.Framework.Scenes
3684 ControllingClient.SendTakeControls(int.MaxValue, false, false); 3915 ControllingClient.SendTakeControls(int.MaxValue, false, false);
3685 } 3916 }
3686 3917
3918 private void UnRegisterSeatControls(UUID obj)
3919 {
3920 List<UUID> takers = new List<UUID>();
3921
3922 foreach (ScriptControllers c in scriptedcontrols.Values)
3923 {
3924 if (c.objectID == obj)
3925 takers.Add(c.itemID);
3926 }
3927 foreach (UUID t in takers)
3928 {
3929 UnRegisterControlEventsToScript(0, t);
3930 }
3931 }
3932
3687 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 3933 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
3688 { 3934 {
3689 ScriptControllers takecontrols; 3935 ScriptControllers takecontrols;
@@ -4002,6 +4248,12 @@ namespace OpenSim.Region.Framework.Scenes
4002 4248
4003 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4249 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4004 { 4250 {
4251 string reason;
4252
4253 // Honor bans
4254 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4255 return;
4256
4005 SceneObjectGroup telehub = null; 4257 SceneObjectGroup telehub = null;
4006 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4258 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4007 { 4259 {
@@ -4041,11 +4293,206 @@ namespace OpenSim.Region.Framework.Scenes
4041 pos = land.LandData.UserLocation; 4293 pos = land.LandData.UserLocation;
4042 } 4294 }
4043 } 4295 }
4044 4296
4045 land.SendLandUpdateToClient(ControllingClient); 4297 land.SendLandUpdateToClient(ControllingClient);
4046 } 4298 }
4047 } 4299 }
4048 4300
4301 private DetectedObject CreateDetObject(SceneObjectPart obj)
4302 {
4303 DetectedObject detobj = new DetectedObject();
4304 detobj.keyUUID = obj.UUID;
4305 detobj.nameStr = obj.Name;
4306 detobj.ownerUUID = obj.OwnerID;
4307 detobj.posVector = obj.AbsolutePosition;
4308 detobj.rotQuat = obj.GetWorldRotation();
4309 detobj.velVector = obj.Velocity;
4310 detobj.colliderType = 0;
4311 detobj.groupUUID = obj.GroupID;
4312
4313 return detobj;
4314 }
4315
4316 private DetectedObject CreateDetObject(ScenePresence av)
4317 {
4318 DetectedObject detobj = new DetectedObject();
4319 detobj.keyUUID = av.UUID;
4320 detobj.nameStr = av.ControllingClient.Name;
4321 detobj.ownerUUID = av.UUID;
4322 detobj.posVector = av.AbsolutePosition;
4323 detobj.rotQuat = av.Rotation;
4324 detobj.velVector = av.Velocity;
4325 detobj.colliderType = 0;
4326 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4327
4328 return detobj;
4329 }
4330
4331 private DetectedObject CreateDetObjectForGround()
4332 {
4333 DetectedObject detobj = new DetectedObject();
4334 detobj.keyUUID = UUID.Zero;
4335 detobj.nameStr = "";
4336 detobj.ownerUUID = UUID.Zero;
4337 detobj.posVector = AbsolutePosition;
4338 detobj.rotQuat = Quaternion.Identity;
4339 detobj.velVector = Vector3.Zero;
4340 detobj.colliderType = 0;
4341 detobj.groupUUID = UUID.Zero;
4342
4343 return detobj;
4344 }
4345
4346 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4347 {
4348 ColliderArgs colliderArgs = new ColliderArgs();
4349 List<DetectedObject> colliding = new List<DetectedObject>();
4350 foreach (uint localId in colliders)
4351 {
4352 if (localId == 0)
4353 continue;
4354
4355 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4356 if (obj != null)
4357 {
4358 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4359 colliding.Add(CreateDetObject(obj));
4360 }
4361 else
4362 {
4363 ScenePresence av = m_scene.GetScenePresence(localId);
4364 if (av != null && (!av.IsChildAgent))
4365 {
4366 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4367 colliding.Add(CreateDetObject(av));
4368 }
4369 }
4370 }
4371
4372 colliderArgs.Colliders = colliding;
4373
4374 return colliderArgs;
4375 }
4376
4377 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4378
4379 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4380 {
4381 ColliderArgs CollidingMessage;
4382
4383 if (colliders.Count > 0)
4384 {
4385 if ((dest.RootPart.ScriptEvents & ev) != 0)
4386 {
4387 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4388
4389 if (CollidingMessage.Colliders.Count > 0)
4390 notify(dest.RootPart.LocalId, CollidingMessage);
4391 }
4392 }
4393 }
4394
4395 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4396 {
4397 if ((dest.RootPart.ScriptEvents & ev) != 0)
4398 {
4399 ColliderArgs LandCollidingMessage = new ColliderArgs();
4400 List<DetectedObject> colliding = new List<DetectedObject>();
4401
4402 colliding.Add(CreateDetObjectForGround());
4403 LandCollidingMessage.Colliders = colliding;
4404
4405 notify(dest.RootPart.LocalId, LandCollidingMessage);
4406 }
4407 }
4408
4409 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
4410 {
4411 try
4412 {
4413 List<uint> thisHitColliders = new List<uint>();
4414 List<uint> endedColliders = new List<uint>();
4415 List<uint> startedColliders = new List<uint>();
4416 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
4417 CollisionForSoundInfo soundinfo;
4418 ContactPoint curcontact;
4419
4420 if (coldata.Count == 0)
4421 {
4422 if (m_lastColliders.Count == 0)
4423 return; // nothing to do
4424
4425 foreach (uint localID in m_lastColliders)
4426 {
4427 endedColliders.Add(localID);
4428 }
4429 m_lastColliders.Clear();
4430 }
4431
4432 else
4433 {
4434 foreach (uint id in coldata.Keys)
4435 {
4436 thisHitColliders.Add(id);
4437 if (!m_lastColliders.Contains(id))
4438 {
4439 startedColliders.Add(id);
4440 curcontact = coldata[id];
4441 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
4442 {
4443 soundinfo = new CollisionForSoundInfo();
4444 soundinfo.colliderID = id;
4445 soundinfo.position = curcontact.Position;
4446 soundinfo.relativeVel = curcontact.RelativeSpeed;
4447 soundinfolist.Add(soundinfo);
4448 }
4449 }
4450 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
4451 }
4452
4453 // calculate things that ended colliding
4454 foreach (uint localID in m_lastColliders)
4455 {
4456 if (!thisHitColliders.Contains(localID))
4457 {
4458 endedColliders.Add(localID);
4459 }
4460 }
4461 //add the items that started colliding this time to the last colliders list.
4462 foreach (uint localID in startedColliders)
4463 {
4464 m_lastColliders.Add(localID);
4465 }
4466 // remove things that ended colliding from the last colliders list
4467 foreach (uint localID in endedColliders)
4468 {
4469 m_lastColliders.Remove(localID);
4470 }
4471
4472 if (soundinfolist.Count > 0)
4473 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
4474 }
4475
4476 foreach (SceneObjectGroup att in GetAttachments())
4477 {
4478 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
4479 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
4480 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
4481
4482 if (startedColliders.Contains(0))
4483 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
4484 if (m_lastColliders.Contains(0))
4485 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
4486 if (endedColliders.Contains(0))
4487 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
4488 }
4489 }
4490 finally
4491 {
4492 m_collisionEventFlag = false;
4493 }
4494 }
4495
4049 private void TeleportFlagsDebug() { 4496 private void TeleportFlagsDebug() {
4050 4497
4051 // Some temporary debugging help to show all the TeleportFlags we have... 4498 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4070,6 +4517,5 @@ namespace OpenSim.Region.Framework.Scenes
4070 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4517 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4071 4518
4072 } 4519 }
4073
4074 } 4520 }
4075} 4521}