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 e0dfb34..6005f07 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
@@ -226,8 +230,6 @@ namespace OpenSim.Region.Framework.Scenes
226 /// </summary> 230 /// </summary>
227 public bool LandAtTarget { get; private set; } 231 public bool LandAtTarget { get; private set; }
228 232
229 private bool m_followCamAuto;
230
231 private int m_movementUpdateCount; 233 private int m_movementUpdateCount;
232 private const int NumMovementsBetweenRayCast = 5; 234 private const int NumMovementsBetweenRayCast = 5;
233 235
@@ -235,6 +237,13 @@ namespace OpenSim.Region.Framework.Scenes
235 //private int m_moveToPositionStateStatus; 237 //private int m_moveToPositionStateStatus;
236 //***************************************************** 238 //*****************************************************
237 239
240 private bool m_collisionEventFlag = false;
241 private object m_collisionEventLock = new Object();
242
243 private int m_movementAnimationUpdateCounter = 0;
244
245 private Vector3 m_prevSitOffset;
246
238 protected AvatarAppearance m_appearance; 247 protected AvatarAppearance m_appearance;
239 248
240 public AvatarAppearance Appearance 249 public AvatarAppearance Appearance
@@ -349,6 +358,9 @@ namespace OpenSim.Region.Framework.Scenes
349 /// </summary> 358 /// </summary>
350 protected Vector3 m_lastCameraPosition; 359 protected Vector3 m_lastCameraPosition;
351 360
361 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
362 private bool m_doingCamRayCast = false;
363
352 public Vector3 CameraPosition { get; set; } 364 public Vector3 CameraPosition { get; set; }
353 365
354 public Quaternion CameraRotation 366 public Quaternion CameraRotation
@@ -429,7 +441,7 @@ namespace OpenSim.Region.Framework.Scenes
429 get { return (IClientCore)ControllingClient; } 441 get { return (IClientCore)ControllingClient; }
430 } 442 }
431 443
432 public Vector3 ParentPosition { get; set; } 444// public Vector3 ParentPosition { get; set; }
433 445
434 /// <summary> 446 /// <summary>
435 /// Position of this avatar relative to the region the avatar is in 447 /// Position of this avatar relative to the region the avatar is in
@@ -487,7 +499,7 @@ namespace OpenSim.Region.Framework.Scenes
487 if (ParentID == 0) 499 if (ParentID == 0)
488 { 500 {
489 m_pos = value; 501 m_pos = value;
490 ParentPosition = Vector3.Zero; 502// ParentPosition = Vector3.Zero;
491 } 503 }
492 504
493 //m_log.DebugFormat( 505 //m_log.DebugFormat(
@@ -556,7 +568,24 @@ namespace OpenSim.Region.Framework.Scenes
556// Scene.RegionInfo.RegionName, Name, m_velocity); 568// Scene.RegionInfo.RegionName, Name, m_velocity);
557 } 569 }
558 } 570 }
571/*
572 public override Vector3 AngularVelocity
573 {
574 get
575 {
576 if (PhysicsActor != null)
577 {
578 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
579
580 // m_log.DebugFormat(
581 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
582 // m_velocity, Name, Scene.RegionInfo.RegionName);
583 }
559 584
585 return m_rotationalvelocity;
586 }
587 }
588*/
560 private Quaternion m_bodyRot = Quaternion.Identity; 589 private Quaternion m_bodyRot = Quaternion.Identity;
561 590
562 public Quaternion Rotation 591 public Quaternion Rotation
@@ -567,7 +596,14 @@ namespace OpenSim.Region.Framework.Scenes
567 m_bodyRot = value; 596 m_bodyRot = value;
568 if (PhysicsActor != null) 597 if (PhysicsActor != null)
569 { 598 {
570 PhysicsActor.Orientation = m_bodyRot; 599 try
600 {
601 PhysicsActor.Orientation = m_bodyRot;
602 }
603 catch (Exception e)
604 {
605 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
606 }
571 } 607 }
572// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 608// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
573 } 609 }
@@ -582,12 +618,20 @@ namespace OpenSim.Region.Framework.Scenes
582 } 618 }
583 619
584 public bool IsChildAgent { get; set; } 620 public bool IsChildAgent { get; set; }
621 public bool IsLoggingIn { get; set; }
585 622
586 /// <summary> 623 /// <summary>
587 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 624 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
588 /// </summary> 625 /// </summary>
589 public uint ParentID { get; set; } 626 public uint ParentID { get; set; }
590 627
628 public UUID ParentUUID
629 {
630 get { return m_parentUUID; }
631 set { m_parentUUID = value; }
632 }
633 private UUID m_parentUUID = UUID.Zero;
634
591 /// <summary> 635 /// <summary>
592 /// Are we sitting on an object? 636 /// Are we sitting on an object?
593 /// </summary> 637 /// </summary>
@@ -713,6 +757,7 @@ namespace OpenSim.Region.Framework.Scenes
713 AttachmentsSyncLock = new Object(); 757 AttachmentsSyncLock = new Object();
714 AllowMovement = true; 758 AllowMovement = true;
715 IsChildAgent = true; 759 IsChildAgent = true;
760 IsLoggingIn = false;
716 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 761 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
717 Animator = new ScenePresenceAnimator(this); 762 Animator = new ScenePresenceAnimator(this);
718 PresenceType = type; 763 PresenceType = type;
@@ -756,6 +801,33 @@ namespace OpenSim.Region.Framework.Scenes
756 Appearance = appearance; 801 Appearance = appearance;
757 } 802 }
758 803
804 private void RegionHeartbeatEnd(Scene scene)
805 {
806 if (IsChildAgent)
807 return;
808
809 m_movementAnimationUpdateCounter ++;
810 if (m_movementAnimationUpdateCounter >= 2)
811 {
812 m_movementAnimationUpdateCounter = 0;
813 if (Animator != null)
814 {
815 // If the parentID == 0 we are not sitting
816 // if !SitGournd then we are not sitting on the ground
817 // Fairly straightforward, now here comes the twist
818 // if ParentUUID is NOT UUID.Zero, we are looking to
819 // be sat on an object that isn't there yet. Should
820 // be treated as if sat.
821 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
822 Animator.UpdateMovementAnimations();
823 }
824 else
825 {
826 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
827 }
828 }
829 }
830
759 public void RegisterToEvents() 831 public void RegisterToEvents()
760 { 832 {
761 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 833 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -765,8 +837,10 @@ namespace OpenSim.Region.Framework.Scenes
765 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 837 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
766 ControllingClient.OnStartAnim += HandleStartAnim; 838 ControllingClient.OnStartAnim += HandleStartAnim;
767 ControllingClient.OnStopAnim += HandleStopAnim; 839 ControllingClient.OnStopAnim += HandleStopAnim;
840 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
768 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 841 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
769 ControllingClient.OnAutoPilotGo += MoveToTarget; 842 ControllingClient.OnAutoPilotGo += MoveToTarget;
843 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
770 844
771 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 845 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
772 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 846 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -825,10 +899,40 @@ namespace OpenSim.Region.Framework.Scenes
825 "[SCENE]: Upgrading child to root agent for {0} in {1}", 899 "[SCENE]: Upgrading child to root agent for {0} in {1}",
826 Name, m_scene.RegionInfo.RegionName); 900 Name, m_scene.RegionInfo.RegionName);
827 901
828 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
829
830 bool wasChild = IsChildAgent; 902 bool wasChild = IsChildAgent;
831 IsChildAgent = false; 903
904 if (ParentUUID != UUID.Zero)
905 {
906 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
907 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
908 if (part == null)
909 {
910 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
911 }
912 else
913 {
914 part.ParentGroup.AddAvatar(UUID);
915 if (part.SitTargetPosition != Vector3.Zero)
916 part.SitTargetAvatar = UUID;
917// ParentPosition = part.GetWorldPosition();
918 ParentID = part.LocalId;
919 ParentPart = part;
920 m_pos = m_prevSitOffset;
921// pos = ParentPosition;
922 pos = part.GetWorldPosition();
923 }
924 ParentUUID = UUID.Zero;
925
926 IsChildAgent = false;
927
928// Animator.TrySetMovementAnimation("SIT");
929 }
930 else
931 {
932 IsChildAgent = false;
933 IsLoggingIn = false;
934 }
935
832 936
833 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); 937 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
834 if (gm != null) 938 if (gm != null)
@@ -838,62 +942,99 @@ namespace OpenSim.Region.Framework.Scenes
838 942
839 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 943 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
840 944
841 // Moved this from SendInitialData to ensure that Appearance is initialized 945 UUID groupUUID = UUID.Zero;
842 // before the inventory is processed in MakeRootAgent. This fixes a race condition 946 string GroupName = string.Empty;
843 // related to the handling of attachments 947 ulong groupPowers = 0;
844 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance); 948
845 if (m_scene.TestBorderCross(pos, Cardinals.E)) 949 // ----------------------------------
950 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
951 try
846 { 952 {
847 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 953 if (gm != null)
848 pos.X = crossedBorder.BorderLine.Z - 1; 954 {
955 groupUUID = ControllingClient.ActiveGroupId;
956 GroupRecord record = gm.GetGroupRecord(groupUUID);
957 if (record != null)
958 GroupName = record.GroupName;
959 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
960 if (groupMembershipData != null)
961 groupPowers = groupMembershipData.GroupPowers;
962 }
963 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
964 Grouptitle);
849 } 965 }
850 966 catch (Exception e)
851 if (m_scene.TestBorderCross(pos, Cardinals.N))
852 { 967 {
853 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 968 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
854 pos.Y = crossedBorder.BorderLine.Z - 1;
855 } 969 }
970 // ------------------------------------
856 971
857 CheckAndAdjustLandingPoint(ref pos); 972 if (ParentID == 0)
858
859 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
860 { 973 {
861 m_log.WarnFormat( 974 // Moved this from SendInitialData to ensure that Appearance is initialized
862 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 975 // before the inventory is processed in MakeRootAgent. This fixes a race condition
863 pos, Name, UUID); 976 // related to the handling of attachments
977 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
978 if (m_scene.TestBorderCross(pos, Cardinals.E))
979 {
980 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
981 pos.X = crossedBorder.BorderLine.Z - 1;
982 }
864 983
865 if (pos.X < 0f) pos.X = 0f; 984 if (m_scene.TestBorderCross(pos, Cardinals.N))
866 if (pos.Y < 0f) pos.Y = 0f; 985 {
867 if (pos.Z < 0f) pos.Z = 0f; 986 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
868 } 987 pos.Y = crossedBorder.BorderLine.Z - 1;
988 }
869 989
870 float localAVHeight = 1.56f; 990 CheckAndAdjustLandingPoint(ref pos);
871 if (Appearance.AvatarHeight > 0)
872 localAVHeight = Appearance.AvatarHeight;
873 991
874 float posZLimit = 0; 992 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
993 {
994 m_log.WarnFormat(
995 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
996 pos, Name, UUID);
875 997
876 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 998 if (pos.X < 0f) pos.X = 0f;
877 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 999 if (pos.Y < 0f) pos.Y = 0f;
878 1000 if (pos.Z < 0f) pos.Z = 0f;
879 float newPosZ = posZLimit + localAVHeight / 2; 1001 }
880 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
881 {
882 pos.Z = newPosZ;
883 }
884 AbsolutePosition = pos;
885 1002
886 AddToPhysicalScene(isFlying); 1003 float localAVHeight = 1.56f;
1004 if (Appearance.AvatarHeight > 0)
1005 localAVHeight = Appearance.AvatarHeight;
887 1006
888 if (ForceFly) 1007 float posZLimit = 0;
889 {
890 Flying = true;
891 }
892 else if (FlyDisabled)
893 {
894 Flying = false;
895 }
896 1008
1009 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
1010 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
1011
1012 float newPosZ = posZLimit + localAVHeight / 2;
1013 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
1014 {
1015 pos.Z = newPosZ;
1016 }
1017 AbsolutePosition = pos;
1018
1019 if (m_teleportFlags == TeleportFlags.Default)
1020 {
1021 Vector3 vel = Velocity;
1022 AddToPhysicalScene(isFlying);
1023 if (PhysicsActor != null)
1024 PhysicsActor.SetMomentum(vel);
1025 }
1026 else
1027 AddToPhysicalScene(isFlying);
1028
1029 if (ForceFly)
1030 {
1031 Flying = true;
1032 }
1033 else if (FlyDisabled)
1034 {
1035 Flying = false;
1036 }
1037 }
897 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1038 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
898 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1039 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
899 // elsewhere anyway 1040 // elsewhere anyway
@@ -913,14 +1054,19 @@ namespace OpenSim.Region.Framework.Scenes
913 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); 1054 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
914 1055
915 // Resume scripts 1056 // Resume scripts
916 foreach (SceneObjectGroup sog in m_attachments) 1057 Util.FireAndForget(delegate(object x) {
917 { 1058 foreach (SceneObjectGroup sog in m_attachments)
918 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1059 {
919 sog.ResumeScripts(); 1060 sog.ScheduleGroupForFullUpdate();
920 } 1061 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1062 sog.ResumeScripts();
1063 }
1064 });
921 } 1065 }
922 } 1066 }
923 1067
1068 SendAvatarDataToAllAgents();
1069
924 // send the animations of the other presences to me 1070 // send the animations of the other presences to me
925 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1071 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
926 { 1072 {
@@ -931,9 +1077,12 @@ namespace OpenSim.Region.Framework.Scenes
931 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1077 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
932 // stall on the border crossing since the existing child agent will still have the last movement 1078 // stall on the border crossing since the existing child agent will still have the last movement
933 // recorded, which stops the input from being processed. 1079 // recorded, which stops the input from being processed.
1080
934 MovementFlag = 0; 1081 MovementFlag = 0;
935 1082
936 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1083 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1084
1085 m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
937 } 1086 }
938 1087
939 public int GetStateSource() 1088 public int GetStateSource()
@@ -961,12 +1110,16 @@ namespace OpenSim.Region.Framework.Scenes
961 /// </remarks> 1110 /// </remarks>
962 public void MakeChildAgent() 1111 public void MakeChildAgent()
963 { 1112 {
1113 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1114
964 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1115 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
965 1116
966 // Reset these so that teleporting in and walking out isn't seen 1117 // Reset these so that teleporting in and walking out isn't seen
967 // as teleporting back 1118 // as teleporting back
968 TeleportFlags = TeleportFlags.Default; 1119 TeleportFlags = TeleportFlags.Default;
969 1120
1121 MovementFlag = 0;
1122
970 // It looks like Animator is set to null somewhere, and MakeChild 1123 // It looks like Animator is set to null somewhere, and MakeChild
971 // is called after that. Probably in aborted teleports. 1124 // is called after that. Probably in aborted teleports.
972 if (Animator == null) 1125 if (Animator == null)
@@ -974,6 +1127,7 @@ namespace OpenSim.Region.Framework.Scenes
974 else 1127 else
975 Animator.ResetAnimations(); 1128 Animator.ResetAnimations();
976 1129
1130
977// m_log.DebugFormat( 1131// m_log.DebugFormat(
978// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1132// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
979// Name, UUID, m_scene.RegionInfo.RegionName); 1133// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -985,6 +1139,7 @@ namespace OpenSim.Region.Framework.Scenes
985 IsChildAgent = true; 1139 IsChildAgent = true;
986 m_scene.SwapRootAgentCount(true); 1140 m_scene.SwapRootAgentCount(true);
987 RemoveFromPhysicalScene(); 1141 RemoveFromPhysicalScene();
1142 ParentID = 0; // Child agents can't be sitting
988 1143
989 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1144 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
990 1145
@@ -1000,9 +1155,9 @@ namespace OpenSim.Region.Framework.Scenes
1000 { 1155 {
1001// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1156// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1002 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1157 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1003 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1004 PhysicsActor.UnSubscribeEvents();
1005 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1158 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1159 PhysicsActor.UnSubscribeEvents();
1160 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1006 PhysicsActor = null; 1161 PhysicsActor = null;
1007 } 1162 }
1008// else 1163// else
@@ -1019,7 +1174,7 @@ namespace OpenSim.Region.Framework.Scenes
1019 /// <param name="pos"></param> 1174 /// <param name="pos"></param>
1020 public void Teleport(Vector3 pos) 1175 public void Teleport(Vector3 pos)
1021 { 1176 {
1022 TeleportWithMomentum(pos, null); 1177 TeleportWithMomentum(pos, Vector3.Zero);
1023 } 1178 }
1024 1179
1025 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1180 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1043,6 +1198,41 @@ namespace OpenSim.Region.Framework.Scenes
1043 SendTerseUpdateToAllClients(); 1198 SendTerseUpdateToAllClients();
1044 } 1199 }
1045 1200
1201 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1202 {
1203 CheckLandingPoint(ref newpos);
1204 AbsolutePosition = newpos;
1205
1206 if (newvel.HasValue)
1207 {
1208 if ((Vector3)newvel == Vector3.Zero)
1209 {
1210 if (PhysicsActor != null)
1211 PhysicsActor.SetMomentum(Vector3.Zero);
1212 m_velocity = Vector3.Zero;
1213 }
1214 else
1215 {
1216 if (PhysicsActor != null)
1217 PhysicsActor.SetMomentum((Vector3)newvel);
1218 m_velocity = (Vector3)newvel;
1219
1220 if (rotateToVelXY)
1221 {
1222 Vector3 lookAt = (Vector3)newvel;
1223 lookAt.Z = 0;
1224 lookAt.Normalize();
1225 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1226 return;
1227 }
1228 }
1229 }
1230
1231 SendTerseUpdateToAllClients();
1232 }
1233
1234
1235
1046 public void StopFlying() 1236 public void StopFlying()
1047 { 1237 {
1048 ControllingClient.StopFlying(this); 1238 ControllingClient.StopFlying(this);
@@ -1212,6 +1402,13 @@ namespace OpenSim.Region.Framework.Scenes
1212 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1402 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1213 } 1403 }
1214 1404
1405 public void SetSize(Vector3 size, float feetoffset)
1406 {
1407 if (PhysicsActor != null && !IsChildAgent)
1408 PhysicsActor.setAvatarSize(size, feetoffset);
1409
1410 }
1411
1215 /// <summary> 1412 /// <summary>
1216 /// Complete Avatar's movement into the region. 1413 /// Complete Avatar's movement into the region.
1217 /// </summary> 1414 /// </summary>
@@ -1231,7 +1428,8 @@ namespace OpenSim.Region.Framework.Scenes
1231 1428
1232 Vector3 look = Velocity; 1429 Vector3 look = Velocity;
1233 1430
1234 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1431 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1432 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1235 { 1433 {
1236 look = new Vector3(0.99f, 0.042f, 0); 1434 look = new Vector3(0.99f, 0.042f, 0);
1237 } 1435 }
@@ -1281,13 +1479,15 @@ namespace OpenSim.Region.Framework.Scenes
1281 // Create child agents in neighbouring regions 1479 // Create child agents in neighbouring regions
1282 if (openChildAgents && !IsChildAgent) 1480 if (openChildAgents && !IsChildAgent)
1283 { 1481 {
1482
1284 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1483 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1285 if (m_agentTransfer != null) 1484 if (m_agentTransfer != null)
1286 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1485 m_agentTransfer.EnableChildAgents(this);
1287 1486
1288 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1487 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1289 if (friendsModule != null) 1488 if (friendsModule != null)
1290 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1489 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1490
1291 } 1491 }
1292 1492
1293// m_log.DebugFormat( 1493// m_log.DebugFormat(
@@ -1303,35 +1503,43 @@ namespace OpenSim.Region.Framework.Scenes
1303 /// <param name="collisionPoint"></param> 1503 /// <param name="collisionPoint"></param>
1304 /// <param name="localid"></param> 1504 /// <param name="localid"></param>
1305 /// <param name="distance"></param> 1505 /// <param name="distance"></param>
1506 ///
1507
1508 private void UpdateCameraCollisionPlane(Vector4 plane)
1509 {
1510 if (m_lastCameraCollisionPlane != plane)
1511 {
1512 m_lastCameraCollisionPlane = plane;
1513 ControllingClient.SendCameraConstraint(plane);
1514 }
1515 }
1516
1306 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1517 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1307 { 1518 {
1308 const float POSITION_TOLERANCE = 0.02f; 1519 const float POSITION_TOLERANCE = 0.02f;
1309 const float VELOCITY_TOLERANCE = 0.02f;
1310 const float ROTATION_TOLERANCE = 0.02f; 1520 const float ROTATION_TOLERANCE = 0.02f;
1311 1521
1312 if (m_followCamAuto) 1522 m_doingCamRayCast = false;
1523 if (hitYN && localid != LocalId)
1313 { 1524 {
1314 if (hitYN) 1525 CameraConstraintActive = true;
1315 { 1526 pNormal.X = (float)Math.Round(pNormal.X, 2);
1316 CameraConstraintActive = true; 1527 pNormal.Y = (float)Math.Round(pNormal.Y, 2);
1317 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1528 pNormal.Z = (float)Math.Round(pNormal.Z, 2);
1318 1529 pNormal.Normalize();
1319 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1530 collisionPoint.X = (float)Math.Round(collisionPoint.X, 1);
1320 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1531 collisionPoint.Y = (float)Math.Round(collisionPoint.Y, 1);
1321 } 1532 collisionPoint.Z = (float)Math.Round(collisionPoint.Z, 1);
1322 else 1533
1323 { 1534 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z, Vector3.Dot(collisionPoint, pNormal));
1324 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1535 UpdateCameraCollisionPlane(plane);
1325 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1536 }
1326 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1537 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1327 { 1538 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1328 if (CameraConstraintActive) 1539 {
1329 { 1540 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1330 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1541 UpdateCameraCollisionPlane(plane);
1331 CameraConstraintActive = false; 1542 CameraConstraintActive = false;
1332 }
1333 }
1334 }
1335 } 1543 }
1336 } 1544 }
1337 1545
@@ -1406,12 +1614,6 @@ namespace OpenSim.Region.Framework.Scenes
1406 // DrawDistance = agentData.Far; 1614 // DrawDistance = agentData.Far;
1407 DrawDistance = Scene.DefaultDrawDistance; 1615 DrawDistance = Scene.DefaultDrawDistance;
1408 1616
1409 // Check if Client has camera in 'follow cam' or 'build' mode.
1410 Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
1411
1412 m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
1413 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
1414
1415 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; 1617 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
1416 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; 1618 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
1417 1619
@@ -1431,14 +1633,38 @@ namespace OpenSim.Region.Framework.Scenes
1431 StandUp(); 1633 StandUp();
1432 } 1634 }
1433 1635
1434 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
1435 // Raycast from the avatar's head to the camera to see if there's anything blocking the view 1636 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1436 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) 1637 // this exclude checks may not be complete
1638
1639 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1437 { 1640 {
1438 if (m_followCamAuto) 1641 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1642 {
1643 Vector3 posAdjusted = AbsolutePosition;
1644// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1645 posAdjusted.Z += 1.0f; // viewer current camera focus point
1646 Vector3 tocam = CameraPosition - posAdjusted;
1647 tocam.X = (float)Math.Round(tocam.X, 1);
1648 tocam.Y = (float)Math.Round(tocam.Y, 1);
1649 tocam.Z = (float)Math.Round(tocam.Z, 1);
1650
1651 float distTocamlen = tocam.Length();
1652 if (distTocamlen > 0.3f)
1653 {
1654 tocam *= (1.0f / distTocamlen);
1655 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1656 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1657 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1658
1659 m_doingCamRayCast = true;
1660 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1661 }
1662 }
1663 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1439 { 1664 {
1440 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; 1665 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1441 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback); 1666 UpdateCameraCollisionPlane(plane);
1667 CameraConstraintActive = false;
1442 } 1668 }
1443 } 1669 }
1444 1670
@@ -1903,7 +2129,8 @@ namespace OpenSim.Region.Framework.Scenes
1903// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2129// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1904 2130
1905 MovingToTarget = false; 2131 MovingToTarget = false;
1906 MoveToPositionTarget = Vector3.Zero; 2132// MoveToPositionTarget = Vector3.Zero;
2133 m_forceToApply = null; // cancel possible last action
1907 2134
1908 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2135 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
1909 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2136 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -1921,12 +2148,17 @@ namespace OpenSim.Region.Framework.Scenes
1921// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2148// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
1922 2149
1923 SitGround = false; 2150 SitGround = false;
2151
2152/* move this down so avatar gets physical in the new position and not where it is siting
1924 if (PhysicsActor == null) 2153 if (PhysicsActor == null)
1925 AddToPhysicalScene(false); 2154 AddToPhysicalScene(false);
2155 */
1926 2156
1927 if (ParentID != 0) 2157 if (ParentID != 0)
1928 { 2158 {
1929 SceneObjectPart part = ParentPart; 2159 SceneObjectPart part = ParentPart;
2160 UnRegisterSeatControls(part.ParentGroup.UUID);
2161
1930 TaskInventoryDictionary taskIDict = part.TaskInventory; 2162 TaskInventoryDictionary taskIDict = part.TaskInventory;
1931 if (taskIDict != null) 2163 if (taskIDict != null)
1932 { 2164 {
@@ -1942,14 +2174,22 @@ namespace OpenSim.Region.Framework.Scenes
1942 } 2174 }
1943 } 2175 }
1944 2176
1945 ParentPosition = part.GetWorldPosition(); 2177 part.ParentGroup.DeleteAvatar(UUID);
2178// ParentPosition = part.GetWorldPosition();
1946 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2179 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1947 2180
1948 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 2181// m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
1949 ParentPosition = Vector3.Zero; 2182// ParentPosition = Vector3.Zero;
2183 m_pos = part.AbsolutePosition + (m_pos * part.GetWorldRotation()) + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2184 if (part.SitTargetAvatar == UUID)
2185 m_bodyRot = part.GetWorldRotation() * part.SitTargetOrientation;
1950 2186
1951 ParentID = 0; 2187 ParentID = 0;
1952 ParentPart = null; 2188 ParentPart = null;
2189
2190 if (PhysicsActor == null)
2191 AddToPhysicalScene(false);
2192
1953 SendAvatarDataToAllAgents(); 2193 SendAvatarDataToAllAgents();
1954 m_requestedSitTargetID = 0; 2194 m_requestedSitTargetID = 0;
1955 2195
@@ -1959,6 +2199,9 @@ namespace OpenSim.Region.Framework.Scenes
1959 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2199 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1960 } 2200 }
1961 2201
2202 else if (PhysicsActor == null)
2203 AddToPhysicalScene(false);
2204
1962 Animator.TrySetMovementAnimation("STAND"); 2205 Animator.TrySetMovementAnimation("STAND");
1963 } 2206 }
1964 2207
@@ -2006,11 +2249,8 @@ namespace OpenSim.Region.Framework.Scenes
2006 if (part == null) 2249 if (part == null)
2007 return; 2250 return;
2008 2251
2009 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2010 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2011
2012 if (PhysicsActor != null) 2252 if (PhysicsActor != null)
2013 m_sitAvatarHeight = PhysicsActor.Size.Z; 2253 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2014 2254
2015 bool canSit = false; 2255 bool canSit = false;
2016 Vector3 pos = part.AbsolutePosition + offset; 2256 Vector3 pos = part.AbsolutePosition + offset;
@@ -2027,31 +2267,31 @@ namespace OpenSim.Region.Framework.Scenes
2027 } 2267 }
2028 else 2268 else
2029 { 2269 {
2270 if (PhysicsSit(part,offset)) // physics engine
2271 return;
2272
2030 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2273 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2031 { 2274 {
2032// m_log.DebugFormat(
2033// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2034// Name, part.Name, part.LocalId);
2035 2275
2036 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2276 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2037 canSit = true; 2277 canSit = true;
2038 } 2278 }
2039// else
2040// {
2041// m_log.DebugFormat(
2042// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2043// Name, part.Name, part.LocalId);
2044// }
2045 } 2279 }
2046 2280
2047 if (canSit) 2281 if (canSit)
2048 { 2282 {
2283
2049 if (PhysicsActor != null) 2284 if (PhysicsActor != null)
2050 { 2285 {
2051 // We can remove the physicsActor until they stand up. 2286 // We can remove the physicsActor until they stand up.
2052 RemoveFromPhysicalScene(); 2287 RemoveFromPhysicalScene();
2053 } 2288 }
2054 2289
2290 if (MovingToTarget)
2291 ResetMoveToTarget();
2292
2293 Velocity = Vector3.Zero;
2294
2055 part.AddSittingAvatar(UUID); 2295 part.AddSittingAvatar(UUID);
2056 2296
2057 cameraAtOffset = part.GetCameraAtOffset(); 2297 cameraAtOffset = part.GetCameraAtOffset();
@@ -2059,7 +2299,7 @@ namespace OpenSim.Region.Framework.Scenes
2059 forceMouselook = part.GetForceMouselook(); 2299 forceMouselook = part.GetForceMouselook();
2060 2300
2061 ControllingClient.SendSitResponse( 2301 ControllingClient.SendSitResponse(
2062 targetID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 2302 part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2063 2303
2064 m_requestedSitTargetUUID = targetID; 2304 m_requestedSitTargetUUID = targetID;
2065 2305
@@ -2073,6 +2313,9 @@ namespace OpenSim.Region.Framework.Scenes
2073 2313
2074 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2314 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2075 { 2315 {
2316 if (IsChildAgent)
2317 return;
2318
2076 if (ParentID != 0) 2319 if (ParentID != 0)
2077 { 2320 {
2078 if (ParentPart.UUID == targetID) 2321 if (ParentPart.UUID == targetID)
@@ -2088,14 +2331,6 @@ namespace OpenSim.Region.Framework.Scenes
2088 m_requestedSitTargetID = part.LocalId; 2331 m_requestedSitTargetID = part.LocalId;
2089 m_requestedSitTargetUUID = targetID; 2332 m_requestedSitTargetUUID = targetID;
2090 2333
2091// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2092
2093 if (m_scene.PhysicsScene.SupportsRayCast())
2094 {
2095 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2096 //SitRayCastAvatarPosition(part);
2097 //return;
2098 }
2099 } 2334 }
2100 else 2335 else
2101 { 2336 {
@@ -2105,197 +2340,111 @@ namespace OpenSim.Region.Framework.Scenes
2105 SendSitResponse(targetID, offset, Quaternion.Identity); 2340 SendSitResponse(targetID, offset, Quaternion.Identity);
2106 } 2341 }
2107 2342
2108 /* 2343 // returns false if does not suport so older sit can be tried
2109 public void SitRayCastAvatarPosition(SceneObjectPart part) 2344 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2110 { 2345 {
2111 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2346 if (part == null || part.ParentGroup.IsAttachment)
2112 Vector3 StartRayCastPosition = AbsolutePosition;
2113 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2114 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2115 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2116 }
2117
2118 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2119 {
2120 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2121 if (part != null)
2122 {
2123 if (hitYN)
2124 {
2125 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2126 {
2127 SitRaycastFindEdge(collisionPoint, normal);
2128 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2129 }
2130 else
2131 {
2132 SitRayCastAvatarPositionCameraZ(part);
2133 }
2134 }
2135 else
2136 {
2137 SitRayCastAvatarPositionCameraZ(part);
2138 }
2139 }
2140 else
2141 { 2347 {
2142 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2348 return true;
2143 m_requestedSitTargetUUID = UUID.Zero;
2144 m_requestedSitTargetID = 0;
2145 m_requestedSitOffset = Vector3.Zero;
2146 } 2349 }
2147 2350
2148 } 2351 if ( m_scene.PhysicsScene == null)
2149 2352 return false;
2150 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2151 {
2152 // Next, try to raycast from the camera Z position
2153 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2154 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2155 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2156 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2157 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2158 }
2159 2353
2160 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2354 if (part.PhysActor == null)
2161 {
2162 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2163 if (part != null)
2164 { 2355 {
2165 if (hitYN) 2356 // none physcis shape
2166 { 2357 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2167 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2358 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2168 {
2169 SitRaycastFindEdge(collisionPoint, normal);
2170 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2171 }
2172 else
2173 {
2174 SitRayCastCameraPosition(part);
2175 }
2176 }
2177 else 2359 else
2178 { 2360 { // non physical phantom TODO
2179 SitRayCastCameraPosition(part); 2361 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2362 return false;
2180 } 2363 }
2181 } 2364 return true;
2182 else
2183 {
2184 ControllingClient.SendAlertMessage("Sit position no longer exists");
2185 m_requestedSitTargetUUID = UUID.Zero;
2186 m_requestedSitTargetID = 0;
2187 m_requestedSitOffset = Vector3.Zero;
2188 } 2365 }
2189 2366
2190 }
2191 2367
2192 public void SitRayCastCameraPosition(SceneObjectPart part) 2368 // not doing autopilot
2193 { 2369 m_requestedSitTargetID = 0;
2194 // Next, try to raycast from the camera position
2195 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2196 Vector3 StartRayCastPosition = CameraPosition;
2197 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2198 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2199 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2200 }
2201 2370
2202 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2371 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2203 { 2372 return true;
2204 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2205 if (part != null)
2206 {
2207 if (hitYN)
2208 {
2209 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2210 {
2211 SitRaycastFindEdge(collisionPoint, normal);
2212 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2213 }
2214 else
2215 {
2216 SitRayHorizontal(part);
2217 }
2218 }
2219 else
2220 {
2221 SitRayHorizontal(part);
2222 }
2223 }
2224 else
2225 {
2226 ControllingClient.SendAlertMessage("Sit position no longer exists");
2227 m_requestedSitTargetUUID = UUID.Zero;
2228 m_requestedSitTargetID = 0;
2229 m_requestedSitOffset = Vector3.Zero;
2230 }
2231 2373
2374 return false;
2232 } 2375 }
2233 2376
2234 public void SitRayHorizontal(SceneObjectPart part) 2377
2378 private bool CanEnterLandPosition(Vector3 testPos)
2235 { 2379 {
2236 // Next, try to raycast from the avatar position to fwd 2380 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2237 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2381
2238 Vector3 StartRayCastPosition = CameraPosition; 2382 if (land == null || land.LandData.Name == "NO_LAND")
2239 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2383 return true;
2240 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2384
2241 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2385 return land.CanBeOnThisLand(UUID,testPos.Z);
2242 } 2386 }
2243 2387
2244 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2388 // status
2389 // < 0 ignore
2390 // 0 bad sit spot
2391 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2245 { 2392 {
2246 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2393 if (status < 0)
2247 if (part != null) 2394 return;
2395
2396 if (status == 0)
2248 { 2397 {
2249 if (hitYN) 2398 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2250 { 2399 return;
2251 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2252 {
2253 SitRaycastFindEdge(collisionPoint, normal);
2254 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2255 // Next, try to raycast from the camera position
2256 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2257 Vector3 StartRayCastPosition = CameraPosition;
2258 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2259 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2260 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2261 }
2262 else
2263 {
2264 ControllingClient.SendAlertMessage("Sit position not accessable.");
2265 m_requestedSitTargetUUID = UUID.Zero;
2266 m_requestedSitTargetID = 0;
2267 m_requestedSitOffset = Vector3.Zero;
2268 }
2269 }
2270 else
2271 {
2272 ControllingClient.SendAlertMessage("Sit position not accessable.");
2273 m_requestedSitTargetUUID = UUID.Zero;
2274 m_requestedSitTargetID = 0;
2275 m_requestedSitOffset = Vector3.Zero;
2276 }
2277 } 2400 }
2278 else 2401
2402 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2403 if (part == null)
2404 return;
2405
2406 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2407 if(!CanEnterLandPosition(targetPos))
2279 { 2408 {
2280 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2409 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2281 m_requestedSitTargetUUID = UUID.Zero; 2410 return;
2282 m_requestedSitTargetID = 0;
2283 m_requestedSitOffset = Vector3.Zero;
2284 } 2411 }
2285 2412
2286 } 2413 RemoveFromPhysicalScene();
2287 2414
2288 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2415 if (MovingToTarget)
2289 { 2416 ResetMoveToTarget();
2290 int i = 0; 2417
2291 //throw new NotImplementedException(); 2418 Velocity = Vector3.Zero;
2292 //m_requestedSitTargetUUID = UUID.Zero; 2419
2293 //m_requestedSitTargetID = 0; 2420 part.AddSittingAvatar(UUID);
2294 //m_requestedSitOffset = Vector3.Zero;
2295 2421
2296 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2422 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2423 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2424 bool forceMouselook = part.GetForceMouselook();
2425
2426 ControllingClient.SendSitResponse(
2427 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2428
2429 // not using autopilot
2430
2431 Rotation = Orientation;
2432 m_pos = offset;
2433
2434 m_requestedSitTargetID = 0;
2435 part.ParentGroup.AddAvatar(UUID);
2436
2437 ParentPart = part;
2438 ParentID = part.LocalId;
2439 if(status == 3)
2440 Animator.TrySetMovementAnimation("SIT_GROUND");
2441 else
2442 Animator.TrySetMovementAnimation("SIT");
2443 SendAvatarDataToAllAgents();
2444
2445 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2297 } 2446 }
2298 */ 2447
2299 2448
2300 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2449 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2301 { 2450 {
@@ -2312,6 +2461,7 @@ namespace OpenSim.Region.Framework.Scenes
2312 return; 2461 return;
2313 } 2462 }
2314 2463
2464
2315 if (part.SitTargetAvatar == UUID) 2465 if (part.SitTargetAvatar == UUID)
2316 { 2466 {
2317 Vector3 sitTargetPos = part.SitTargetPosition; 2467 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2326,14 +2476,39 @@ namespace OpenSim.Region.Framework.Scenes
2326 2476
2327 //Quaternion result = (sitTargetOrient * vq) * nq; 2477 //Quaternion result = (sitTargetOrient * vq) * nq;
2328 2478
2329 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2479 double x, y, z, m;
2480
2481 Quaternion r = sitTargetOrient;
2482 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2483
2484 if (Math.Abs(1.0 - m) > 0.000001)
2485 {
2486 m = 1.0 / Math.Sqrt(m);
2487 r.X *= (float)m;
2488 r.Y *= (float)m;
2489 r.Z *= (float)m;
2490 r.W *= (float)m;
2491 }
2492
2493 x = 2 * (r.X * r.Z + r.Y * r.W);
2494 y = 2 * (-r.X * r.W + r.Y * r.Z);
2495 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2496
2497 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2498 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2499
2500 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2501
2502// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2330 Rotation = sitTargetOrient; 2503 Rotation = sitTargetOrient;
2331 ParentPosition = part.AbsolutePosition; 2504// ParentPosition = part.AbsolutePosition;
2505 part.ParentGroup.AddAvatar(UUID);
2332 } 2506 }
2333 else 2507 else
2334 { 2508 {
2335 m_pos -= part.AbsolutePosition; 2509 m_pos -= part.AbsolutePosition;
2336 ParentPosition = part.AbsolutePosition; 2510// ParentPosition = part.AbsolutePosition;
2511 part.ParentGroup.AddAvatar(UUID);
2337 2512
2338// m_log.DebugFormat( 2513// m_log.DebugFormat(
2339// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2514// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2383,6 +2558,13 @@ namespace OpenSim.Region.Framework.Scenes
2383 Animator.RemoveAnimation(animID, false); 2558 Animator.RemoveAnimation(animID, false);
2384 } 2559 }
2385 2560
2561 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
2562 {
2563 Animator.avnChangeAnim(animID, addRemove, sendPack);
2564 }
2565
2566
2567
2386 /// <summary> 2568 /// <summary>
2387 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2569 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2388 /// </summary> 2570 /// </summary>
@@ -2436,14 +2618,15 @@ namespace OpenSim.Region.Framework.Scenes
2436 direc.Z *= 2.6f; 2618 direc.Z *= 2.6f;
2437 2619
2438 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2620 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2439 Animator.TrySetMovementAnimation("PREJUMP"); 2621// Animator.TrySetMovementAnimation("PREJUMP");
2440 Animator.TrySetMovementAnimation("JUMP"); 2622// Animator.TrySetMovementAnimation("JUMP");
2441 } 2623 }
2442 } 2624 }
2443 } 2625 }
2444 2626
2445 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2627 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2446 m_forceToApply = direc; 2628 m_forceToApply = direc;
2629 Animator.UpdateMovementAnimations();
2447 } 2630 }
2448 2631
2449 #endregion 2632 #endregion
@@ -2461,16 +2644,12 @@ namespace OpenSim.Region.Framework.Scenes
2461 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 2644 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2462 // grab the latest PhysicsActor velocity, whereas m_velocity is often 2645 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2463 // storing a requested force instead of an actual traveling velocity 2646 // storing a requested force instead of an actual traveling velocity
2647 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
2648 SendAvatarDataToAllAgents();
2464 2649
2465 // Throw away duplicate or insignificant updates 2650 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2466 if ( 2651 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2467 // If the velocity has become zero, send it no matter what. 2652 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2468 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2469 // otherwise, if things have changed reasonably, send the update
2470 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2471 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2472 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2473
2474 { 2653 {
2475 SendTerseUpdateToAllClients(); 2654 SendTerseUpdateToAllClients();
2476 2655
@@ -2659,6 +2838,8 @@ namespace OpenSim.Region.Framework.Scenes
2659 return; 2838 return;
2660 } 2839 }
2661 2840
2841 m_lastSize = Appearance.AvatarSize;
2842
2662 int count = 0; 2843 int count = 0;
2663 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2844 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2664 { 2845 {
@@ -2766,6 +2947,8 @@ namespace OpenSim.Region.Framework.Scenes
2766 2947
2767 avatar.ControllingClient.SendAppearance( 2948 avatar.ControllingClient.SendAppearance(
2768 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 2949 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
2950
2951
2769 } 2952 }
2770 2953
2771 #endregion 2954 #endregion
@@ -2840,8 +3023,9 @@ namespace OpenSim.Region.Framework.Scenes
2840 3023
2841 // If we don't have a PhysActor, we can't cross anyway 3024 // If we don't have a PhysActor, we can't cross anyway
2842 // Also don't do this while sat, sitting avatars cross with the 3025 // Also don't do this while sat, sitting avatars cross with the
2843 // object they sit on. 3026 // object they sit on. ParentUUID denoted a pending sit, don't
2844 if (ParentID != 0 || PhysicsActor == null) 3027 // interfere with it.
3028 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
2845 return; 3029 return;
2846 3030
2847 if (!IsInTransit) 3031 if (!IsInTransit)
@@ -3102,6 +3286,10 @@ namespace OpenSim.Region.Framework.Scenes
3102 } 3286 }
3103 3287
3104 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3288 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3289 private void RaiseUpdateThrottles()
3290 {
3291 m_scene.EventManager.TriggerThrottleUpdate(this);
3292 }
3105 /// <summary> 3293 /// <summary>
3106 /// This updates important decision making data about a child agent 3294 /// This updates important decision making data about a child agent
3107 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3295 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3182,6 +3370,9 @@ namespace OpenSim.Region.Framework.Scenes
3182 cAgent.AlwaysRun = SetAlwaysRun; 3370 cAgent.AlwaysRun = SetAlwaysRun;
3183 3371
3184 cAgent.Appearance = new AvatarAppearance(Appearance); 3372 cAgent.Appearance = new AvatarAppearance(Appearance);
3373
3374 cAgent.ParentPart = ParentUUID;
3375 cAgent.SitOffset = m_pos;
3185 3376
3186 lock (scriptedcontrols) 3377 lock (scriptedcontrols)
3187 { 3378 {
@@ -3190,7 +3381,7 @@ namespace OpenSim.Region.Framework.Scenes
3190 3381
3191 foreach (ScriptControllers c in scriptedcontrols.Values) 3382 foreach (ScriptControllers c in scriptedcontrols.Values)
3192 { 3383 {
3193 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3384 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3194 } 3385 }
3195 cAgent.Controllers = controls; 3386 cAgent.Controllers = controls;
3196 } 3387 }
@@ -3223,6 +3414,8 @@ namespace OpenSim.Region.Framework.Scenes
3223 CameraAtAxis = cAgent.AtAxis; 3414 CameraAtAxis = cAgent.AtAxis;
3224 CameraLeftAxis = cAgent.LeftAxis; 3415 CameraLeftAxis = cAgent.LeftAxis;
3225 CameraUpAxis = cAgent.UpAxis; 3416 CameraUpAxis = cAgent.UpAxis;
3417 ParentUUID = cAgent.ParentPart;
3418 m_prevSitOffset = cAgent.SitOffset;
3226 3419
3227 // When we get to the point of re-computing neighbors everytime this 3420 // When we get to the point of re-computing neighbors everytime this
3228 // changes, then start using the agent's drawdistance rather than the 3421 // changes, then start using the agent's drawdistance rather than the
@@ -3260,6 +3453,7 @@ namespace OpenSim.Region.Framework.Scenes
3260 foreach (ControllerData c in cAgent.Controllers) 3453 foreach (ControllerData c in cAgent.Controllers)
3261 { 3454 {
3262 ScriptControllers sc = new ScriptControllers(); 3455 ScriptControllers sc = new ScriptControllers();
3456 sc.objectID = c.ObjectID;
3263 sc.itemID = c.ItemID; 3457 sc.itemID = c.ItemID;
3264 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3458 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3265 sc.eventControls = (ScriptControlled)c.EventControls; 3459 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3327,20 +3521,27 @@ namespace OpenSim.Region.Framework.Scenes
3327 } 3521 }
3328 3522
3329 if (Appearance.AvatarHeight == 0) 3523 if (Appearance.AvatarHeight == 0)
3330 Appearance.SetHeight(); 3524// Appearance.SetHeight();
3525 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3331 3526
3332 PhysicsScene scene = m_scene.PhysicsScene; 3527 PhysicsScene scene = m_scene.PhysicsScene;
3333 3528
3334 Vector3 pVec = AbsolutePosition; 3529 Vector3 pVec = AbsolutePosition;
3335 3530
3531/*
3336 PhysicsActor = scene.AddAvatar( 3532 PhysicsActor = scene.AddAvatar(
3337 LocalId, Firstname + "." + Lastname, pVec, 3533 LocalId, Firstname + "." + Lastname, pVec,
3338 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3534 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3535*/
3536
3537 PhysicsActor = scene.AddAvatar(
3538 LocalId, Firstname + "." + Lastname, pVec,
3539 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
3339 3540
3340 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3541 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3341 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3542 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3342 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3543 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3343 PhysicsActor.SubscribeEvents(500); 3544 PhysicsActor.SubscribeEvents(100);
3344 PhysicsActor.LocalID = LocalId; 3545 PhysicsActor.LocalID = LocalId;
3345 } 3546 }
3346 3547
@@ -3354,6 +3555,7 @@ namespace OpenSim.Region.Framework.Scenes
3354 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3555 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3355 } 3556 }
3356 3557
3558
3357 /// <summary> 3559 /// <summary>
3358 /// Event called by the physics plugin to tell the avatar about a collision. 3560 /// Event called by the physics plugin to tell the avatar about a collision.
3359 /// </summary> 3561 /// </summary>
@@ -3367,7 +3569,7 @@ namespace OpenSim.Region.Framework.Scenes
3367 /// <param name="e"></param> 3569 /// <param name="e"></param>
3368 public void PhysicsCollisionUpdate(EventArgs e) 3570 public void PhysicsCollisionUpdate(EventArgs e)
3369 { 3571 {
3370 if (IsChildAgent) 3572 if (IsChildAgent || Animator == null)
3371 return; 3573 return;
3372 3574
3373 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3575 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3383,7 +3585,6 @@ namespace OpenSim.Region.Framework.Scenes
3383 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3585 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3384 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3586 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3385 3587
3386 CollisionPlane = Vector4.UnitW;
3387 3588
3388// // No collisions at all means we may be flying. Update always 3589// // No collisions at all means we may be flying. Update always
3389// // to make falling work 3590// // to make falling work
@@ -3395,6 +3596,7 @@ namespace OpenSim.Region.Framework.Scenes
3395 3596
3396 if (coldata.Count != 0) 3597 if (coldata.Count != 0)
3397 { 3598 {
3599/*
3398 switch (Animator.CurrentMovementAnimation) 3600 switch (Animator.CurrentMovementAnimation)
3399 { 3601 {
3400 case "STAND": 3602 case "STAND":
@@ -3403,24 +3605,38 @@ namespace OpenSim.Region.Framework.Scenes
3403 case "CROUCH": 3605 case "CROUCH":
3404 case "CROUCHWALK": 3606 case "CROUCHWALK":
3405 { 3607 {
3608 */
3406 ContactPoint lowest; 3609 ContactPoint lowest;
3407 lowest.SurfaceNormal = Vector3.Zero; 3610 lowest.SurfaceNormal = Vector3.Zero;
3408 lowest.Position = Vector3.Zero; 3611 lowest.Position = Vector3.Zero;
3409 lowest.Position.Z = Single.NaN; 3612 lowest.Position.Z = float.MaxValue;
3410 3613
3411 foreach (ContactPoint contact in coldata.Values) 3614 foreach (ContactPoint contact in coldata.Values)
3412 { 3615 {
3413 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 3616
3617 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3414 { 3618 {
3415 lowest = contact; 3619 lowest = contact;
3416 } 3620 }
3417 } 3621 }
3418 3622
3419 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 3623 if (lowest.Position.Z != float.MaxValue)
3624 {
3625 lowest.SurfaceNormal = -lowest.SurfaceNormal;
3626 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3627 }
3628 else
3629 CollisionPlane = Vector4.UnitW;
3630/*
3420 } 3631 }
3421 break; 3632 break;
3422 } 3633 }
3634*/
3423 } 3635 }
3636 else
3637 CollisionPlane = Vector4.UnitW;
3638
3639 RaiseCollisionScriptEvents(coldata);
3424 3640
3425 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3641 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3426 if (Invulnerable || GodLevel > 0) 3642 if (Invulnerable || GodLevel > 0)
@@ -3519,6 +3735,13 @@ namespace OpenSim.Region.Framework.Scenes
3519 // m_reprioritizationTimer.Dispose(); 3735 // m_reprioritizationTimer.Dispose();
3520 3736
3521 RemoveFromPhysicalScene(); 3737 RemoveFromPhysicalScene();
3738
3739 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
3740
3741// if (Animator != null)
3742// Animator.Close();
3743 Animator = null;
3744
3522 } 3745 }
3523 3746
3524 public void AddAttachment(SceneObjectGroup gobj) 3747 public void AddAttachment(SceneObjectGroup gobj)
@@ -3752,10 +3975,18 @@ namespace OpenSim.Region.Framework.Scenes
3752 3975
3753 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 3976 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
3754 { 3977 {
3978 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
3979 if (p == null)
3980 return;
3981
3982 ControllingClient.SendTakeControls(controls, false, false);
3983 ControllingClient.SendTakeControls(controls, true, false);
3984
3755 ScriptControllers obj = new ScriptControllers(); 3985 ScriptControllers obj = new ScriptControllers();
3756 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 3986 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
3757 obj.eventControls = ScriptControlled.CONTROL_ZERO; 3987 obj.eventControls = ScriptControlled.CONTROL_ZERO;
3758 3988
3989 obj.objectID = p.ParentGroup.UUID;
3759 obj.itemID = Script_item_UUID; 3990 obj.itemID = Script_item_UUID;
3760 if (pass_on == 0 && accept == 0) 3991 if (pass_on == 0 && accept == 0)
3761 { 3992 {
@@ -3804,6 +4035,21 @@ namespace OpenSim.Region.Framework.Scenes
3804 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4035 ControllingClient.SendTakeControls(int.MaxValue, false, false);
3805 } 4036 }
3806 4037
4038 private void UnRegisterSeatControls(UUID obj)
4039 {
4040 List<UUID> takers = new List<UUID>();
4041
4042 foreach (ScriptControllers c in scriptedcontrols.Values)
4043 {
4044 if (c.objectID == obj)
4045 takers.Add(c.itemID);
4046 }
4047 foreach (UUID t in takers)
4048 {
4049 UnRegisterControlEventsToScript(0, t);
4050 }
4051 }
4052
3807 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4053 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
3808 { 4054 {
3809 ScriptControllers takecontrols; 4055 ScriptControllers takecontrols;
@@ -4122,6 +4368,12 @@ namespace OpenSim.Region.Framework.Scenes
4122 4368
4123 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4369 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4124 { 4370 {
4371 string reason;
4372
4373 // Honor bans
4374 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4375 return;
4376
4125 SceneObjectGroup telehub = null; 4377 SceneObjectGroup telehub = null;
4126 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4378 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4127 { 4379 {
@@ -4161,11 +4413,206 @@ namespace OpenSim.Region.Framework.Scenes
4161 pos = land.LandData.UserLocation; 4413 pos = land.LandData.UserLocation;
4162 } 4414 }
4163 } 4415 }
4164 4416
4165 land.SendLandUpdateToClient(ControllingClient); 4417 land.SendLandUpdateToClient(ControllingClient);
4166 } 4418 }
4167 } 4419 }
4168 4420
4421 private DetectedObject CreateDetObject(SceneObjectPart obj)
4422 {
4423 DetectedObject detobj = new DetectedObject();
4424 detobj.keyUUID = obj.UUID;
4425 detobj.nameStr = obj.Name;
4426 detobj.ownerUUID = obj.OwnerID;
4427 detobj.posVector = obj.AbsolutePosition;
4428 detobj.rotQuat = obj.GetWorldRotation();
4429 detobj.velVector = obj.Velocity;
4430 detobj.colliderType = 0;
4431 detobj.groupUUID = obj.GroupID;
4432
4433 return detobj;
4434 }
4435
4436 private DetectedObject CreateDetObject(ScenePresence av)
4437 {
4438 DetectedObject detobj = new DetectedObject();
4439 detobj.keyUUID = av.UUID;
4440 detobj.nameStr = av.ControllingClient.Name;
4441 detobj.ownerUUID = av.UUID;
4442 detobj.posVector = av.AbsolutePosition;
4443 detobj.rotQuat = av.Rotation;
4444 detobj.velVector = av.Velocity;
4445 detobj.colliderType = 0;
4446 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4447
4448 return detobj;
4449 }
4450
4451 private DetectedObject CreateDetObjectForGround()
4452 {
4453 DetectedObject detobj = new DetectedObject();
4454 detobj.keyUUID = UUID.Zero;
4455 detobj.nameStr = "";
4456 detobj.ownerUUID = UUID.Zero;
4457 detobj.posVector = AbsolutePosition;
4458 detobj.rotQuat = Quaternion.Identity;
4459 detobj.velVector = Vector3.Zero;
4460 detobj.colliderType = 0;
4461 detobj.groupUUID = UUID.Zero;
4462
4463 return detobj;
4464 }
4465
4466 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4467 {
4468 ColliderArgs colliderArgs = new ColliderArgs();
4469 List<DetectedObject> colliding = new List<DetectedObject>();
4470 foreach (uint localId in colliders)
4471 {
4472 if (localId == 0)
4473 continue;
4474
4475 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4476 if (obj != null)
4477 {
4478 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4479 colliding.Add(CreateDetObject(obj));
4480 }
4481 else
4482 {
4483 ScenePresence av = m_scene.GetScenePresence(localId);
4484 if (av != null && (!av.IsChildAgent))
4485 {
4486 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4487 colliding.Add(CreateDetObject(av));
4488 }
4489 }
4490 }
4491
4492 colliderArgs.Colliders = colliding;
4493
4494 return colliderArgs;
4495 }
4496
4497 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4498
4499 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4500 {
4501 ColliderArgs CollidingMessage;
4502
4503 if (colliders.Count > 0)
4504 {
4505 if ((dest.RootPart.ScriptEvents & ev) != 0)
4506 {
4507 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4508
4509 if (CollidingMessage.Colliders.Count > 0)
4510 notify(dest.RootPart.LocalId, CollidingMessage);
4511 }
4512 }
4513 }
4514
4515 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4516 {
4517 if ((dest.RootPart.ScriptEvents & ev) != 0)
4518 {
4519 ColliderArgs LandCollidingMessage = new ColliderArgs();
4520 List<DetectedObject> colliding = new List<DetectedObject>();
4521
4522 colliding.Add(CreateDetObjectForGround());
4523 LandCollidingMessage.Colliders = colliding;
4524
4525 notify(dest.RootPart.LocalId, LandCollidingMessage);
4526 }
4527 }
4528
4529 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
4530 {
4531 try
4532 {
4533 List<uint> thisHitColliders = new List<uint>();
4534 List<uint> endedColliders = new List<uint>();
4535 List<uint> startedColliders = new List<uint>();
4536 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
4537 CollisionForSoundInfo soundinfo;
4538 ContactPoint curcontact;
4539
4540 if (coldata.Count == 0)
4541 {
4542 if (m_lastColliders.Count == 0)
4543 return; // nothing to do
4544
4545 foreach (uint localID in m_lastColliders)
4546 {
4547 endedColliders.Add(localID);
4548 }
4549 m_lastColliders.Clear();
4550 }
4551
4552 else
4553 {
4554 foreach (uint id in coldata.Keys)
4555 {
4556 thisHitColliders.Add(id);
4557 if (!m_lastColliders.Contains(id))
4558 {
4559 startedColliders.Add(id);
4560 curcontact = coldata[id];
4561 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
4562 {
4563 soundinfo = new CollisionForSoundInfo();
4564 soundinfo.colliderID = id;
4565 soundinfo.position = curcontact.Position;
4566 soundinfo.relativeVel = curcontact.RelativeSpeed;
4567 soundinfolist.Add(soundinfo);
4568 }
4569 }
4570 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
4571 }
4572
4573 // calculate things that ended colliding
4574 foreach (uint localID in m_lastColliders)
4575 {
4576 if (!thisHitColliders.Contains(localID))
4577 {
4578 endedColliders.Add(localID);
4579 }
4580 }
4581 //add the items that started colliding this time to the last colliders list.
4582 foreach (uint localID in startedColliders)
4583 {
4584 m_lastColliders.Add(localID);
4585 }
4586 // remove things that ended colliding from the last colliders list
4587 foreach (uint localID in endedColliders)
4588 {
4589 m_lastColliders.Remove(localID);
4590 }
4591
4592 if (soundinfolist.Count > 0)
4593 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
4594 }
4595
4596 foreach (SceneObjectGroup att in GetAttachments())
4597 {
4598 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
4599 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
4600 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
4601
4602 if (startedColliders.Contains(0))
4603 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
4604 if (m_lastColliders.Contains(0))
4605 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
4606 if (endedColliders.Contains(0))
4607 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
4608 }
4609 }
4610 finally
4611 {
4612 m_collisionEventFlag = false;
4613 }
4614 }
4615
4169 private void TeleportFlagsDebug() { 4616 private void TeleportFlagsDebug() {
4170 4617
4171 // Some temporary debugging help to show all the TeleportFlags we have... 4618 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4190,6 +4637,5 @@ namespace OpenSim.Region.Framework.Scenes
4190 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4637 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4191 4638
4192 } 4639 }
4193
4194 } 4640 }
4195} 4641}