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.cs1101
1 files changed, 788 insertions, 313 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fcb2f6d..486a075 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,9 @@ 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 UUID COF { get; set; }
445
446// public Vector3 ParentPosition { get; set; }
433 447
434 /// <summary> 448 /// <summary>
435 /// Position of this avatar relative to the region the avatar is in 449 /// Position of this avatar relative to the region the avatar is in
@@ -490,7 +504,7 @@ namespace OpenSim.Region.Framework.Scenes
490 if (ParentID == 0) 504 if (ParentID == 0)
491 { 505 {
492 m_pos = value; 506 m_pos = value;
493 ParentPosition = Vector3.Zero; 507// ParentPosition = Vector3.Zero;
494 } 508 }
495 509
496 //m_log.DebugFormat( 510 //m_log.DebugFormat(
@@ -559,7 +573,24 @@ namespace OpenSim.Region.Framework.Scenes
559// Scene.RegionInfo.RegionName, Name, m_velocity); 573// Scene.RegionInfo.RegionName, Name, m_velocity);
560 } 574 }
561 } 575 }
576/*
577 public override Vector3 AngularVelocity
578 {
579 get
580 {
581 if (PhysicsActor != null)
582 {
583 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
562 584
585 // m_log.DebugFormat(
586 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
587 // m_velocity, Name, Scene.RegionInfo.RegionName);
588 }
589
590 return m_rotationalvelocity;
591 }
592 }
593*/
563 private Quaternion m_bodyRot = Quaternion.Identity; 594 private Quaternion m_bodyRot = Quaternion.Identity;
564 595
565 /// <summary> 596 /// <summary>
@@ -582,8 +613,16 @@ namespace OpenSim.Region.Framework.Scenes
582 m_bodyRot = value; 613 m_bodyRot = value;
583 614
584 if (PhysicsActor != null) 615 if (PhysicsActor != null)
585 PhysicsActor.Orientation = m_bodyRot; 616 {
586 617 try
618 {
619 PhysicsActor.Orientation = m_bodyRot;
620 }
621 catch (Exception e)
622 {
623 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
624 }
625 }
587// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 626// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
588 } 627 }
589 } 628 }
@@ -597,12 +636,20 @@ namespace OpenSim.Region.Framework.Scenes
597 } 636 }
598 637
599 public bool IsChildAgent { get; set; } 638 public bool IsChildAgent { get; set; }
639 public bool IsLoggingIn { get; set; }
600 640
601 /// <summary> 641 /// <summary>
602 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 642 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
603 /// </summary> 643 /// </summary>
604 public uint ParentID { get; set; } 644 public uint ParentID { get; set; }
605 645
646 public UUID ParentUUID
647 {
648 get { return m_parentUUID; }
649 set { m_parentUUID = value; }
650 }
651 private UUID m_parentUUID = UUID.Zero;
652
606 /// <summary> 653 /// <summary>
607 /// Are we sitting on an object? 654 /// Are we sitting on an object?
608 /// </summary> 655 /// </summary>
@@ -752,6 +799,7 @@ namespace OpenSim.Region.Framework.Scenes
752 AttachmentsSyncLock = new Object(); 799 AttachmentsSyncLock = new Object();
753 AllowMovement = true; 800 AllowMovement = true;
754 IsChildAgent = true; 801 IsChildAgent = true;
802 IsLoggingIn = false;
755 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 803 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
756 Animator = new ScenePresenceAnimator(this); 804 Animator = new ScenePresenceAnimator(this);
757 PresenceType = type; 805 PresenceType = type;
@@ -795,6 +843,33 @@ namespace OpenSim.Region.Framework.Scenes
795 Appearance = appearance; 843 Appearance = appearance;
796 } 844 }
797 845
846 private void RegionHeartbeatEnd(Scene scene)
847 {
848 if (IsChildAgent)
849 return;
850
851 m_movementAnimationUpdateCounter ++;
852 if (m_movementAnimationUpdateCounter >= 2)
853 {
854 m_movementAnimationUpdateCounter = 0;
855 if (Animator != null)
856 {
857 // If the parentID == 0 we are not sitting
858 // if !SitGournd then we are not sitting on the ground
859 // Fairly straightforward, now here comes the twist
860 // if ParentUUID is NOT UUID.Zero, we are looking to
861 // be sat on an object that isn't there yet. Should
862 // be treated as if sat.
863 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
864 Animator.UpdateMovementAnimations();
865 }
866 else
867 {
868 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
869 }
870 }
871 }
872
798 public void RegisterToEvents() 873 public void RegisterToEvents()
799 { 874 {
800 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 875 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -804,8 +879,10 @@ namespace OpenSim.Region.Framework.Scenes
804 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 879 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
805 ControllingClient.OnStartAnim += HandleStartAnim; 880 ControllingClient.OnStartAnim += HandleStartAnim;
806 ControllingClient.OnStopAnim += HandleStopAnim; 881 ControllingClient.OnStopAnim += HandleStopAnim;
882 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
807 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 883 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
808 ControllingClient.OnAutoPilotGo += MoveToTarget; 884 ControllingClient.OnAutoPilotGo += MoveToTarget;
885 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
809 886
810 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 887 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
811 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 888 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -864,6 +941,38 @@ namespace OpenSim.Region.Framework.Scenes
864 "[SCENE]: Upgrading child to root agent for {0} in {1}", 941 "[SCENE]: Upgrading child to root agent for {0} in {1}",
865 Name, m_scene.RegionInfo.RegionName); 942 Name, m_scene.RegionInfo.RegionName);
866 943
944 if (ParentUUID != UUID.Zero)
945 {
946 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
947 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
948 if (part == null)
949 {
950 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
951 }
952 else
953 {
954 part.ParentGroup.AddAvatar(UUID);
955 if (part.SitTargetPosition != Vector3.Zero)
956 part.SitTargetAvatar = UUID;
957// ParentPosition = part.GetWorldPosition();
958 ParentID = part.LocalId;
959 ParentPart = part;
960 m_pos = m_prevSitOffset;
961// pos = ParentPosition;
962 pos = part.GetWorldPosition();
963 }
964 ParentUUID = UUID.Zero;
965
966 IsChildAgent = false;
967
968// Animator.TrySetMovementAnimation("SIT");
969 }
970 else
971 {
972 IsChildAgent = false;
973 IsLoggingIn = false;
974 }
975
867 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 976 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
868 977
869 IsChildAgent = false; 978 IsChildAgent = false;
@@ -876,70 +985,106 @@ namespace OpenSim.Region.Framework.Scenes
876 985
877 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 986 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
878 987
879 // Moved this from SendInitialData to ensure that Appearance is initialized 988 UUID groupUUID = UUID.Zero;
880 // before the inventory is processed in MakeRootAgent. This fixes a race condition 989 string GroupName = string.Empty;
881 // related to the handling of attachments 990 ulong groupPowers = 0;
882 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
883 991
884 if (m_scene.TestBorderCross(pos, Cardinals.E)) 992 // ----------------------------------
993 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
994 try
885 { 995 {
886 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 996 if (gm != null)
887 pos.X = crossedBorder.BorderLine.Z - 1; 997 {
998 groupUUID = ControllingClient.ActiveGroupId;
999 GroupRecord record = gm.GetGroupRecord(groupUUID);
1000 if (record != null)
1001 GroupName = record.GroupName;
1002 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1003 if (groupMembershipData != null)
1004 groupPowers = groupMembershipData.GroupPowers;
1005 }
1006 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1007 Grouptitle);
888 } 1008 }
889 1009 catch (Exception e)
890 if (m_scene.TestBorderCross(pos, Cardinals.N))
891 { 1010 {
892 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1011 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
893 pos.Y = crossedBorder.BorderLine.Z - 1;
894 } 1012 }
1013 // ------------------------------------
895 1014
896 CheckAndAdjustLandingPoint(ref pos); 1015 if (ParentID == 0)
897
898 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
899 { 1016 {
900 m_log.WarnFormat( 1017 // Moved this from SendInitialData to ensure that Appearance is initialized
901 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1018 // before the inventory is processed in MakeRootAgent. This fixes a race condition
902 pos, Name, UUID); 1019 // related to the handling of attachments
1020 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1021 if (m_scene.TestBorderCross(pos, Cardinals.E))
1022 {
1023 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1024 pos.X = crossedBorder.BorderLine.Z - 1;
1025 }
903 1026
904 if (pos.X < 0f) pos.X = 0f; 1027 if (m_scene.TestBorderCross(pos, Cardinals.N))
905 if (pos.Y < 0f) pos.Y = 0f; 1028 {
906 if (pos.Z < 0f) pos.Z = 0f; 1029 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
907 } 1030 pos.Y = crossedBorder.BorderLine.Z - 1;
1031 }
908 1032
909 float localAVHeight = 1.56f; 1033 CheckAndAdjustLandingPoint(ref pos);
910 if (Appearance.AvatarHeight > 0)
911 localAVHeight = Appearance.AvatarHeight;
912 1034
913 float posZLimit = 0; 1035 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1036 {
1037 m_log.WarnFormat(
1038 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1039 pos, Name, UUID);
914 1040
915 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1041 if (pos.X < 0f) pos.X = 0f;
916 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1042 if (pos.Y < 0f) pos.Y = 0f;
917 1043 if (pos.Z < 0f) pos.Z = 0f;
918 float newPosZ = posZLimit + localAVHeight / 2; 1044 }
919 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
920 {
921 pos.Z = newPosZ;
922 }
923 AbsolutePosition = pos;
924 1045
925 AddToPhysicalScene(isFlying); 1046 float localAVHeight = 1.56f;
1047 if (Appearance.AvatarHeight > 0)
1048 localAVHeight = Appearance.AvatarHeight;
926 1049
927 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1050 float posZLimit = 0;
928 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
929 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
930 // the value to a negative position which does not trigger the border cross.
931 // This may not be the best location for this.
932 CheckForBorderCrossing();
933 1051
934 if (ForceFly) 1052 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
935 { 1053 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
936 Flying = true; 1054
937 } 1055 float newPosZ = posZLimit + localAVHeight / 2;
938 else if (FlyDisabled) 1056 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
939 { 1057 {
940 Flying = false; 1058 pos.Z = newPosZ;
941 } 1059 }
1060 AbsolutePosition = pos;
1061
1062 if (m_teleportFlags == TeleportFlags.Default)
1063 {
1064 Vector3 vel = Velocity;
1065 AddToPhysicalScene(isFlying);
1066 if (PhysicsActor != null)
1067 PhysicsActor.SetMomentum(vel);
1068 }
1069 else
1070 AddToPhysicalScene(isFlying);
942 1071
1072 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1073 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1074 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1075 // the value to a negative position which does not trigger the border cross.
1076 // This may not be the best location for this.
1077 CheckForBorderCrossing();
1078
1079 if (ForceFly)
1080 {
1081 Flying = true;
1082 }
1083 else if (FlyDisabled)
1084 {
1085 Flying = false;
1086 }
1087 }
943 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1088 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
944 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1089 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
945 // elsewhere anyway 1090 // elsewhere anyway
@@ -976,17 +1121,22 @@ namespace OpenSim.Region.Framework.Scenes
976 { 1121 {
977 m_log.DebugFormat( 1122 m_log.DebugFormat(
978 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); 1123 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
979 1124
980 // Resume scripts 1125 // Resume scripts
981 foreach (SceneObjectGroup sog in m_attachments) 1126 Util.FireAndForget(delegate(object x) {
982 { 1127 foreach (SceneObjectGroup sog in m_attachments)
983 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1128 {
984 sog.ResumeScripts(); 1129 sog.ScheduleGroupForFullUpdate();
985 } 1130 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1131 sog.ResumeScripts();
1132 }
1133 });
986 } 1134 }
987 } 1135 }
988 } 1136 }
989 1137
1138 SendAvatarDataToAllAgents();
1139
990 // send the animations of the other presences to me 1140 // send the animations of the other presences to me
991 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1141 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
992 { 1142 {
@@ -997,9 +1147,12 @@ namespace OpenSim.Region.Framework.Scenes
997 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1147 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
998 // stall on the border crossing since the existing child agent will still have the last movement 1148 // stall on the border crossing since the existing child agent will still have the last movement
999 // recorded, which stops the input from being processed. 1149 // recorded, which stops the input from being processed.
1150
1000 MovementFlag = 0; 1151 MovementFlag = 0;
1001 1152
1002 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1153 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1154
1155 m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
1003 } 1156 }
1004 1157
1005 public int GetStateSource() 1158 public int GetStateSource()
@@ -1027,12 +1180,16 @@ namespace OpenSim.Region.Framework.Scenes
1027 /// </remarks> 1180 /// </remarks>
1028 public void MakeChildAgent() 1181 public void MakeChildAgent()
1029 { 1182 {
1183 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1184
1030 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1185 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1031 1186
1032 // Reset these so that teleporting in and walking out isn't seen 1187 // Reset these so that teleporting in and walking out isn't seen
1033 // as teleporting back 1188 // as teleporting back
1034 TeleportFlags = TeleportFlags.Default; 1189 TeleportFlags = TeleportFlags.Default;
1035 1190
1191 MovementFlag = 0;
1192
1036 // It looks like Animator is set to null somewhere, and MakeChild 1193 // It looks like Animator is set to null somewhere, and MakeChild
1037 // is called after that. Probably in aborted teleports. 1194 // is called after that. Probably in aborted teleports.
1038 if (Animator == null) 1195 if (Animator == null)
@@ -1040,6 +1197,7 @@ namespace OpenSim.Region.Framework.Scenes
1040 else 1197 else
1041 Animator.ResetAnimations(); 1198 Animator.ResetAnimations();
1042 1199
1200
1043// m_log.DebugFormat( 1201// m_log.DebugFormat(
1044// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1202// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1045// Name, UUID, m_scene.RegionInfo.RegionName); 1203// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1051,6 +1209,7 @@ namespace OpenSim.Region.Framework.Scenes
1051 IsChildAgent = true; 1209 IsChildAgent = true;
1052 m_scene.SwapRootAgentCount(true); 1210 m_scene.SwapRootAgentCount(true);
1053 RemoveFromPhysicalScene(); 1211 RemoveFromPhysicalScene();
1212 ParentID = 0; // Child agents can't be sitting
1054 1213
1055 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1214 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1056 1215
@@ -1066,9 +1225,9 @@ namespace OpenSim.Region.Framework.Scenes
1066 { 1225 {
1067// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1226// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1068 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1227 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1069 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1070 PhysicsActor.UnSubscribeEvents();
1071 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1228 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1229 PhysicsActor.UnSubscribeEvents();
1230 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1072 PhysicsActor = null; 1231 PhysicsActor = null;
1073 } 1232 }
1074// else 1233// else
@@ -1085,7 +1244,7 @@ namespace OpenSim.Region.Framework.Scenes
1085 /// <param name="pos"></param> 1244 /// <param name="pos"></param>
1086 public void Teleport(Vector3 pos) 1245 public void Teleport(Vector3 pos)
1087 { 1246 {
1088 TeleportWithMomentum(pos, null); 1247 TeleportWithMomentum(pos, Vector3.Zero);
1089 } 1248 }
1090 1249
1091 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1250 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1109,6 +1268,41 @@ namespace OpenSim.Region.Framework.Scenes
1109 SendTerseUpdateToAllClients(); 1268 SendTerseUpdateToAllClients();
1110 } 1269 }
1111 1270
1271 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1272 {
1273 CheckLandingPoint(ref newpos);
1274 AbsolutePosition = newpos;
1275
1276 if (newvel.HasValue)
1277 {
1278 if ((Vector3)newvel == Vector3.Zero)
1279 {
1280 if (PhysicsActor != null)
1281 PhysicsActor.SetMomentum(Vector3.Zero);
1282 m_velocity = Vector3.Zero;
1283 }
1284 else
1285 {
1286 if (PhysicsActor != null)
1287 PhysicsActor.SetMomentum((Vector3)newvel);
1288 m_velocity = (Vector3)newvel;
1289
1290 if (rotateToVelXY)
1291 {
1292 Vector3 lookAt = (Vector3)newvel;
1293 lookAt.Z = 0;
1294 lookAt.Normalize();
1295 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1296 return;
1297 }
1298 }
1299 }
1300
1301 SendTerseUpdateToAllClients();
1302 }
1303
1304
1305
1112 public void StopFlying() 1306 public void StopFlying()
1113 { 1307 {
1114 ControllingClient.StopFlying(this); 1308 ControllingClient.StopFlying(this);
@@ -1278,6 +1472,13 @@ namespace OpenSim.Region.Framework.Scenes
1278 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1472 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1279 } 1473 }
1280 1474
1475 public void SetSize(Vector3 size, float feetoffset)
1476 {
1477 if (PhysicsActor != null && !IsChildAgent)
1478 PhysicsActor.setAvatarSize(size, feetoffset);
1479
1480 }
1481
1281 /// <summary> 1482 /// <summary>
1282 /// Complete Avatar's movement into the region. 1483 /// Complete Avatar's movement into the region.
1283 /// </summary> 1484 /// </summary>
@@ -1297,7 +1498,8 @@ namespace OpenSim.Region.Framework.Scenes
1297 1498
1298 Vector3 look = Velocity; 1499 Vector3 look = Velocity;
1299 1500
1300 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1501 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1502 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1301 { 1503 {
1302 look = new Vector3(0.99f, 0.042f, 0); 1504 look = new Vector3(0.99f, 0.042f, 0);
1303 } 1505 }
@@ -1347,13 +1549,15 @@ namespace OpenSim.Region.Framework.Scenes
1347 // Create child agents in neighbouring regions 1549 // Create child agents in neighbouring regions
1348 if (openChildAgents && !IsChildAgent) 1550 if (openChildAgents && !IsChildAgent)
1349 { 1551 {
1552
1350 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1553 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1351 if (m_agentTransfer != null) 1554 if (m_agentTransfer != null)
1352 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1555 m_agentTransfer.EnableChildAgents(this);
1353 1556
1354 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1557 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1355 if (friendsModule != null) 1558 if (friendsModule != null)
1356 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1559 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1560
1357 } 1561 }
1358 1562
1359 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1563 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1378,36 +1582,69 @@ namespace OpenSim.Region.Framework.Scenes
1378 /// <param name="collisionPoint"></param> 1582 /// <param name="collisionPoint"></param>
1379 /// <param name="localid"></param> 1583 /// <param name="localid"></param>
1380 /// <param name="distance"></param> 1584 /// <param name="distance"></param>
1585 ///
1586
1587 private void UpdateCameraCollisionPlane(Vector4 plane)
1588 {
1589 if (m_lastCameraCollisionPlane != plane)
1590 {
1591 m_lastCameraCollisionPlane = plane;
1592 ControllingClient.SendCameraConstraint(plane);
1593 }
1594 }
1595
1381 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1596 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1382 { 1597 {
1383 const float POSITION_TOLERANCE = 0.02f; 1598 const float POSITION_TOLERANCE = 0.02f;
1384 const float VELOCITY_TOLERANCE = 0.02f;
1385 const float ROTATION_TOLERANCE = 0.02f; 1599 const float ROTATION_TOLERANCE = 0.02f;
1386 1600
1387 if (m_followCamAuto) 1601 m_doingCamRayCast = false;
1602 if (hitYN && localid != LocalId)
1388 { 1603 {
1389 if (hitYN) 1604 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1605 bool IsPrim = group != null;
1606 if (IsPrim)
1390 { 1607 {
1391 CameraConstraintActive = true; 1608 SceneObjectPart part = group.GetPart(localid);
1392 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1609 if (part != null && !part.VolumeDetectActive)
1393 1610 {
1394 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1611 CameraConstraintActive = true;
1395 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1612 pNormal.X = (float) Math.Round(pNormal.X, 2);
1613 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1614 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1615 pNormal.Normalize();
1616 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1617 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1618 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1619
1620 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1621 Vector3.Dot(collisionPoint, pNormal));
1622 UpdateCameraCollisionPlane(plane);
1623 }
1396 } 1624 }
1397 else 1625 else
1398 { 1626 {
1399 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1627 CameraConstraintActive = true;
1400 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1628 pNormal.X = (float) Math.Round(pNormal.X, 2);
1401 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1629 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1402 { 1630 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1403 if (CameraConstraintActive) 1631 pNormal.Normalize();
1404 { 1632 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1405 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1633 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1406 CameraConstraintActive = false; 1634 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1407 } 1635
1408 } 1636 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1637 Vector3.Dot(collisionPoint, pNormal));
1638 UpdateCameraCollisionPlane(plane);
1409 } 1639 }
1410 } 1640 }
1641 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1642 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1643 {
1644 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1645 UpdateCameraCollisionPlane(plane);
1646 CameraConstraintActive = false;
1647 }
1411 } 1648 }
1412 1649
1413 /// <summary> 1650 /// <summary>
@@ -1481,12 +1718,6 @@ namespace OpenSim.Region.Framework.Scenes
1481 // DrawDistance = agentData.Far; 1718 // DrawDistance = agentData.Far;
1482 DrawDistance = Scene.DefaultDrawDistance; 1719 DrawDistance = Scene.DefaultDrawDistance;
1483 1720
1484 // Check if Client has camera in 'follow cam' or 'build' mode.
1485 Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
1486
1487 m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
1488 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
1489
1490 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; 1721 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
1491 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; 1722 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
1492 1723
@@ -1506,14 +1737,38 @@ namespace OpenSim.Region.Framework.Scenes
1506 StandUp(); 1737 StandUp();
1507 } 1738 }
1508 1739
1509 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
1510 // Raycast from the avatar's head to the camera to see if there's anything blocking the view 1740 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1511 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) 1741 // this exclude checks may not be complete
1742
1743 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1512 { 1744 {
1513 if (m_followCamAuto) 1745 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1514 { 1746 {
1515 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; 1747 Vector3 posAdjusted = AbsolutePosition;
1516 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback); 1748// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1749 posAdjusted.Z += 1.0f; // viewer current camera focus point
1750 Vector3 tocam = CameraPosition - posAdjusted;
1751 tocam.X = (float)Math.Round(tocam.X, 1);
1752 tocam.Y = (float)Math.Round(tocam.Y, 1);
1753 tocam.Z = (float)Math.Round(tocam.Z, 1);
1754
1755 float distTocamlen = tocam.Length();
1756 if (distTocamlen > 0.3f)
1757 {
1758 tocam *= (1.0f / distTocamlen);
1759 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1760 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1761 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1762
1763 m_doingCamRayCast = true;
1764 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1765 }
1766 }
1767 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1768 {
1769 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1770 UpdateCameraCollisionPlane(plane);
1771 CameraConstraintActive = false;
1517 } 1772 }
1518 } 1773 }
1519 1774
@@ -1978,7 +2233,8 @@ namespace OpenSim.Region.Framework.Scenes
1978// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2233// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1979 2234
1980 MovingToTarget = false; 2235 MovingToTarget = false;
1981 MoveToPositionTarget = Vector3.Zero; 2236// MoveToPositionTarget = Vector3.Zero;
2237 m_forceToApply = null; // cancel possible last action
1982 2238
1983 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2239 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
1984 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2240 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -1996,12 +2252,17 @@ namespace OpenSim.Region.Framework.Scenes
1996// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2252// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
1997 2253
1998 SitGround = false; 2254 SitGround = false;
2255
2256/* move this down so avatar gets physical in the new position and not where it is siting
1999 if (PhysicsActor == null) 2257 if (PhysicsActor == null)
2000 AddToPhysicalScene(false); 2258 AddToPhysicalScene(false);
2259 */
2001 2260
2002 if (ParentID != 0) 2261 if (ParentID != 0)
2003 { 2262 {
2004 SceneObjectPart part = ParentPart; 2263 SceneObjectPart part = ParentPart;
2264 UnRegisterSeatControls(part.ParentGroup.UUID);
2265
2005 TaskInventoryDictionary taskIDict = part.TaskInventory; 2266 TaskInventoryDictionary taskIDict = part.TaskInventory;
2006 if (taskIDict != null) 2267 if (taskIDict != null)
2007 { 2268 {
@@ -2017,14 +2278,22 @@ namespace OpenSim.Region.Framework.Scenes
2017 } 2278 }
2018 } 2279 }
2019 2280
2020 ParentPosition = part.GetWorldPosition(); 2281 part.ParentGroup.DeleteAvatar(UUID);
2282// ParentPosition = part.GetWorldPosition();
2021 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2283 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2022 2284
2023 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 2285// m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2024 ParentPosition = Vector3.Zero; 2286// ParentPosition = Vector3.Zero;
2287 m_pos = part.AbsolutePosition + (m_pos * part.GetWorldRotation()) + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2288 if (part.SitTargetAvatar == UUID)
2289 m_bodyRot = part.GetWorldRotation() * part.SitTargetOrientation;
2025 2290
2026 ParentID = 0; 2291 ParentID = 0;
2027 ParentPart = null; 2292 ParentPart = null;
2293
2294 if (PhysicsActor == null)
2295 AddToPhysicalScene(false);
2296
2028 SendAvatarDataToAllAgents(); 2297 SendAvatarDataToAllAgents();
2029 m_requestedSitTargetID = 0; 2298 m_requestedSitTargetID = 0;
2030 2299
@@ -2034,6 +2303,9 @@ namespace OpenSim.Region.Framework.Scenes
2034 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2303 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2035 } 2304 }
2036 2305
2306 else if (PhysicsActor == null)
2307 AddToPhysicalScene(false);
2308
2037 Animator.TrySetMovementAnimation("STAND"); 2309 Animator.TrySetMovementAnimation("STAND");
2038 } 2310 }
2039 2311
@@ -2081,11 +2353,8 @@ namespace OpenSim.Region.Framework.Scenes
2081 if (part == null) 2353 if (part == null)
2082 return; 2354 return;
2083 2355
2084 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2085 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2086
2087 if (PhysicsActor != null) 2356 if (PhysicsActor != null)
2088 m_sitAvatarHeight = PhysicsActor.Size.Z; 2357 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2089 2358
2090 bool canSit = false; 2359 bool canSit = false;
2091 Vector3 pos = part.AbsolutePosition + offset; 2360 Vector3 pos = part.AbsolutePosition + offset;
@@ -2102,31 +2371,31 @@ namespace OpenSim.Region.Framework.Scenes
2102 } 2371 }
2103 else 2372 else
2104 { 2373 {
2374 if (PhysicsSit(part,offset)) // physics engine
2375 return;
2376
2105 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2377 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2106 { 2378 {
2107// m_log.DebugFormat(
2108// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2109// Name, part.Name, part.LocalId);
2110 2379
2111 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2380 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2112 canSit = true; 2381 canSit = true;
2113 } 2382 }
2114// else
2115// {
2116// m_log.DebugFormat(
2117// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2118// Name, part.Name, part.LocalId);
2119// }
2120 } 2383 }
2121 2384
2122 if (canSit) 2385 if (canSit)
2123 { 2386 {
2387
2124 if (PhysicsActor != null) 2388 if (PhysicsActor != null)
2125 { 2389 {
2126 // We can remove the physicsActor until they stand up. 2390 // We can remove the physicsActor until they stand up.
2127 RemoveFromPhysicalScene(); 2391 RemoveFromPhysicalScene();
2128 } 2392 }
2129 2393
2394 if (MovingToTarget)
2395 ResetMoveToTarget();
2396
2397 Velocity = Vector3.Zero;
2398
2130 part.AddSittingAvatar(UUID); 2399 part.AddSittingAvatar(UUID);
2131 2400
2132 cameraAtOffset = part.GetCameraAtOffset(); 2401 cameraAtOffset = part.GetCameraAtOffset();
@@ -2134,7 +2403,7 @@ namespace OpenSim.Region.Framework.Scenes
2134 forceMouselook = part.GetForceMouselook(); 2403 forceMouselook = part.GetForceMouselook();
2135 2404
2136 ControllingClient.SendSitResponse( 2405 ControllingClient.SendSitResponse(
2137 targetID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 2406 part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2138 2407
2139 m_requestedSitTargetUUID = targetID; 2408 m_requestedSitTargetUUID = targetID;
2140 2409
@@ -2148,6 +2417,9 @@ namespace OpenSim.Region.Framework.Scenes
2148 2417
2149 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2418 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2150 { 2419 {
2420 if (IsChildAgent)
2421 return;
2422
2151 if (ParentID != 0) 2423 if (ParentID != 0)
2152 { 2424 {
2153 if (ParentPart.UUID == targetID) 2425 if (ParentPart.UUID == targetID)
@@ -2163,14 +2435,6 @@ namespace OpenSim.Region.Framework.Scenes
2163 m_requestedSitTargetID = part.LocalId; 2435 m_requestedSitTargetID = part.LocalId;
2164 m_requestedSitTargetUUID = targetID; 2436 m_requestedSitTargetUUID = targetID;
2165 2437
2166// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2167
2168 if (m_scene.PhysicsScene.SupportsRayCast())
2169 {
2170 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2171 //SitRayCastAvatarPosition(part);
2172 //return;
2173 }
2174 } 2438 }
2175 else 2439 else
2176 { 2440 {
@@ -2180,197 +2444,111 @@ namespace OpenSim.Region.Framework.Scenes
2180 SendSitResponse(targetID, offset, Quaternion.Identity); 2444 SendSitResponse(targetID, offset, Quaternion.Identity);
2181 } 2445 }
2182 2446
2183 /* 2447 // returns false if does not suport so older sit can be tried
2184 public void SitRayCastAvatarPosition(SceneObjectPart part) 2448 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2185 { 2449 {
2186 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2450 if (part == null || part.ParentGroup.IsAttachment)
2187 Vector3 StartRayCastPosition = AbsolutePosition;
2188 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2189 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2190 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2191 }
2192
2193 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2194 {
2195 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2196 if (part != null)
2197 {
2198 if (hitYN)
2199 {
2200 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2201 {
2202 SitRaycastFindEdge(collisionPoint, normal);
2203 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2204 }
2205 else
2206 {
2207 SitRayCastAvatarPositionCameraZ(part);
2208 }
2209 }
2210 else
2211 {
2212 SitRayCastAvatarPositionCameraZ(part);
2213 }
2214 }
2215 else
2216 { 2451 {
2217 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2452 return true;
2218 m_requestedSitTargetUUID = UUID.Zero;
2219 m_requestedSitTargetID = 0;
2220 m_requestedSitOffset = Vector3.Zero;
2221 } 2453 }
2222 2454
2223 } 2455 if ( m_scene.PhysicsScene == null)
2456 return false;
2224 2457
2225 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part) 2458 if (part.PhysActor == null)
2226 {
2227 // Next, try to raycast from the camera Z position
2228 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2229 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2230 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2231 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2232 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2233 }
2234
2235 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2236 {
2237 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2238 if (part != null)
2239 { 2459 {
2240 if (hitYN) 2460 // none physcis shape
2241 { 2461 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2242 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2462 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2243 {
2244 SitRaycastFindEdge(collisionPoint, normal);
2245 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2246 }
2247 else
2248 {
2249 SitRayCastCameraPosition(part);
2250 }
2251 }
2252 else 2463 else
2253 { 2464 { // non physical phantom TODO
2254 SitRayCastCameraPosition(part); 2465 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2466 return false;
2255 } 2467 }
2256 } 2468 return true;
2257 else
2258 {
2259 ControllingClient.SendAlertMessage("Sit position no longer exists");
2260 m_requestedSitTargetUUID = UUID.Zero;
2261 m_requestedSitTargetID = 0;
2262 m_requestedSitOffset = Vector3.Zero;
2263 } 2469 }
2264 2470
2265 }
2266 2471
2267 public void SitRayCastCameraPosition(SceneObjectPart part) 2472 // not doing autopilot
2268 { 2473 m_requestedSitTargetID = 0;
2269 // Next, try to raycast from the camera position
2270 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2271 Vector3 StartRayCastPosition = CameraPosition;
2272 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2273 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2274 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2275 }
2276 2474
2277 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2475 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2278 { 2476 return true;
2279 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2280 if (part != null)
2281 {
2282 if (hitYN)
2283 {
2284 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2285 {
2286 SitRaycastFindEdge(collisionPoint, normal);
2287 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2288 }
2289 else
2290 {
2291 SitRayHorizontal(part);
2292 }
2293 }
2294 else
2295 {
2296 SitRayHorizontal(part);
2297 }
2298 }
2299 else
2300 {
2301 ControllingClient.SendAlertMessage("Sit position no longer exists");
2302 m_requestedSitTargetUUID = UUID.Zero;
2303 m_requestedSitTargetID = 0;
2304 m_requestedSitOffset = Vector3.Zero;
2305 }
2306 2477
2478 return false;
2307 } 2479 }
2308 2480
2309 public void SitRayHorizontal(SceneObjectPart part) 2481
2482 private bool CanEnterLandPosition(Vector3 testPos)
2310 { 2483 {
2311 // Next, try to raycast from the avatar position to fwd 2484 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2312 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2485
2313 Vector3 StartRayCastPosition = CameraPosition; 2486 if (land == null || land.LandData.Name == "NO_LAND")
2314 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2487 return true;
2315 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2488
2316 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2489 return land.CanBeOnThisLand(UUID,testPos.Z);
2317 } 2490 }
2318 2491
2319 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2492 // status
2493 // < 0 ignore
2494 // 0 bad sit spot
2495 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2320 { 2496 {
2321 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2497 if (status < 0)
2322 if (part != null) 2498 return;
2499
2500 if (status == 0)
2323 { 2501 {
2324 if (hitYN) 2502 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2325 { 2503 return;
2326 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2327 {
2328 SitRaycastFindEdge(collisionPoint, normal);
2329 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2330 // Next, try to raycast from the camera position
2331 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2332 Vector3 StartRayCastPosition = CameraPosition;
2333 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2334 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2335 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2336 }
2337 else
2338 {
2339 ControllingClient.SendAlertMessage("Sit position not accessable.");
2340 m_requestedSitTargetUUID = UUID.Zero;
2341 m_requestedSitTargetID = 0;
2342 m_requestedSitOffset = Vector3.Zero;
2343 }
2344 }
2345 else
2346 {
2347 ControllingClient.SendAlertMessage("Sit position not accessable.");
2348 m_requestedSitTargetUUID = UUID.Zero;
2349 m_requestedSitTargetID = 0;
2350 m_requestedSitOffset = Vector3.Zero;
2351 }
2352 } 2504 }
2353 else 2505
2506 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2507 if (part == null)
2508 return;
2509
2510 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2511 if(!CanEnterLandPosition(targetPos))
2354 { 2512 {
2355 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2513 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2356 m_requestedSitTargetUUID = UUID.Zero; 2514 return;
2357 m_requestedSitTargetID = 0;
2358 m_requestedSitOffset = Vector3.Zero;
2359 } 2515 }
2360 2516
2361 } 2517 RemoveFromPhysicalScene();
2362 2518
2363 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2519 if (MovingToTarget)
2364 { 2520 ResetMoveToTarget();
2365 int i = 0; 2521
2366 //throw new NotImplementedException(); 2522 Velocity = Vector3.Zero;
2367 //m_requestedSitTargetUUID = UUID.Zero; 2523
2368 //m_requestedSitTargetID = 0; 2524 part.AddSittingAvatar(UUID);
2369 //m_requestedSitOffset = Vector3.Zero;
2370 2525
2371 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2526 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2527 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2528 bool forceMouselook = part.GetForceMouselook();
2529
2530 ControllingClient.SendSitResponse(
2531 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2532
2533 // not using autopilot
2534
2535 Rotation = Orientation;
2536 m_pos = offset;
2537
2538 m_requestedSitTargetID = 0;
2539 part.ParentGroup.AddAvatar(UUID);
2540
2541 ParentPart = part;
2542 ParentID = part.LocalId;
2543 if(status == 3)
2544 Animator.TrySetMovementAnimation("SIT_GROUND");
2545 else
2546 Animator.TrySetMovementAnimation("SIT");
2547 SendAvatarDataToAllAgents();
2548
2549 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2372 } 2550 }
2373 */ 2551
2374 2552
2375 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2553 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2376 { 2554 {
@@ -2387,6 +2565,7 @@ namespace OpenSim.Region.Framework.Scenes
2387 return; 2565 return;
2388 } 2566 }
2389 2567
2568
2390 if (part.SitTargetAvatar == UUID) 2569 if (part.SitTargetAvatar == UUID)
2391 { 2570 {
2392 Vector3 sitTargetPos = part.SitTargetPosition; 2571 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2401,14 +2580,39 @@ namespace OpenSim.Region.Framework.Scenes
2401 2580
2402 //Quaternion result = (sitTargetOrient * vq) * nq; 2581 //Quaternion result = (sitTargetOrient * vq) * nq;
2403 2582
2404 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2583 double x, y, z, m;
2584
2585 Quaternion r = sitTargetOrient;
2586 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2587
2588 if (Math.Abs(1.0 - m) > 0.000001)
2589 {
2590 m = 1.0 / Math.Sqrt(m);
2591 r.X *= (float)m;
2592 r.Y *= (float)m;
2593 r.Z *= (float)m;
2594 r.W *= (float)m;
2595 }
2596
2597 x = 2 * (r.X * r.Z + r.Y * r.W);
2598 y = 2 * (-r.X * r.W + r.Y * r.Z);
2599 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2600
2601 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2602 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2603
2604 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2605
2606// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2405 Rotation = sitTargetOrient; 2607 Rotation = sitTargetOrient;
2406 ParentPosition = part.AbsolutePosition; 2608// ParentPosition = part.AbsolutePosition;
2609 part.ParentGroup.AddAvatar(UUID);
2407 } 2610 }
2408 else 2611 else
2409 { 2612 {
2410 m_pos -= part.AbsolutePosition; 2613 m_pos -= part.AbsolutePosition;
2411 ParentPosition = part.AbsolutePosition; 2614// ParentPosition = part.AbsolutePosition;
2615 part.ParentGroup.AddAvatar(UUID);
2412 2616
2413// m_log.DebugFormat( 2617// m_log.DebugFormat(
2414// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2618// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2459,6 +2663,13 @@ namespace OpenSim.Region.Framework.Scenes
2459 Animator.RemoveAnimation(animID, false); 2663 Animator.RemoveAnimation(animID, false);
2460 } 2664 }
2461 2665
2666 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
2667 {
2668 Animator.avnChangeAnim(animID, addRemove, sendPack);
2669 }
2670
2671
2672
2462 /// <summary> 2673 /// <summary>
2463 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2674 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2464 /// </summary> 2675 /// </summary>
@@ -2515,8 +2726,8 @@ namespace OpenSim.Region.Framework.Scenes
2515 direc.Z *= 2.6f; 2726 direc.Z *= 2.6f;
2516 2727
2517 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2728 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2518 Animator.TrySetMovementAnimation("PREJUMP"); 2729// Animator.TrySetMovementAnimation("PREJUMP");
2519 Animator.TrySetMovementAnimation("JUMP"); 2730// Animator.TrySetMovementAnimation("JUMP");
2520 } 2731 }
2521 } 2732 }
2522 } 2733 }
@@ -2525,6 +2736,7 @@ namespace OpenSim.Region.Framework.Scenes
2525 2736
2526 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2737 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2527 m_forceToApply = direc; 2738 m_forceToApply = direc;
2739 Animator.UpdateMovementAnimations();
2528 } 2740 }
2529 2741
2530 #endregion 2742 #endregion
@@ -2542,16 +2754,12 @@ namespace OpenSim.Region.Framework.Scenes
2542 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 2754 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2543 // grab the latest PhysicsActor velocity, whereas m_velocity is often 2755 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2544 // storing a requested force instead of an actual traveling velocity 2756 // storing a requested force instead of an actual traveling velocity
2757 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
2758 SendAvatarDataToAllAgents();
2545 2759
2546 // Throw away duplicate or insignificant updates 2760 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2547 if ( 2761 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2548 // If the velocity has become zero, send it no matter what. 2762 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2549 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2550 // otherwise, if things have changed reasonably, send the update
2551 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2552 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2553 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2554
2555 { 2763 {
2556 SendTerseUpdateToAllClients(); 2764 SendTerseUpdateToAllClients();
2557 2765
@@ -2740,6 +2948,8 @@ namespace OpenSim.Region.Framework.Scenes
2740 return; 2948 return;
2741 } 2949 }
2742 2950
2951 m_lastSize = Appearance.AvatarSize;
2952
2743 int count = 0; 2953 int count = 0;
2744 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2954 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2745 { 2955 {
@@ -2847,6 +3057,8 @@ namespace OpenSim.Region.Framework.Scenes
2847 3057
2848 avatar.ControllingClient.SendAppearance( 3058 avatar.ControllingClient.SendAppearance(
2849 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3059 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3060
3061
2850 } 3062 }
2851 3063
2852 #endregion 3064 #endregion
@@ -2921,8 +3133,9 @@ namespace OpenSim.Region.Framework.Scenes
2921 3133
2922 // If we don't have a PhysActor, we can't cross anyway 3134 // If we don't have a PhysActor, we can't cross anyway
2923 // Also don't do this while sat, sitting avatars cross with the 3135 // Also don't do this while sat, sitting avatars cross with the
2924 // object they sit on. 3136 // object they sit on. ParentUUID denoted a pending sit, don't
2925 if (ParentID != 0 || PhysicsActor == null) 3137 // interfere with it.
3138 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
2926 return; 3139 return;
2927 3140
2928 if (!IsInTransit) 3141 if (!IsInTransit)
@@ -3187,6 +3400,10 @@ namespace OpenSim.Region.Framework.Scenes
3187 } 3400 }
3188 3401
3189 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3402 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3403 private void RaiseUpdateThrottles()
3404 {
3405 m_scene.EventManager.TriggerThrottleUpdate(this);
3406 }
3190 /// <summary> 3407 /// <summary>
3191 /// This updates important decision making data about a child agent 3408 /// This updates important decision making data about a child agent
3192 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3409 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3267,6 +3484,9 @@ namespace OpenSim.Region.Framework.Scenes
3267 cAgent.AlwaysRun = SetAlwaysRun; 3484 cAgent.AlwaysRun = SetAlwaysRun;
3268 3485
3269 cAgent.Appearance = new AvatarAppearance(Appearance); 3486 cAgent.Appearance = new AvatarAppearance(Appearance);
3487
3488 cAgent.ParentPart = ParentUUID;
3489 cAgent.SitOffset = m_pos;
3270 3490
3271 lock (scriptedcontrols) 3491 lock (scriptedcontrols)
3272 { 3492 {
@@ -3275,7 +3495,7 @@ namespace OpenSim.Region.Framework.Scenes
3275 3495
3276 foreach (ScriptControllers c in scriptedcontrols.Values) 3496 foreach (ScriptControllers c in scriptedcontrols.Values)
3277 { 3497 {
3278 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3498 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3279 } 3499 }
3280 cAgent.Controllers = controls; 3500 cAgent.Controllers = controls;
3281 } 3501 }
@@ -3308,6 +3528,8 @@ namespace OpenSim.Region.Framework.Scenes
3308 CameraAtAxis = cAgent.AtAxis; 3528 CameraAtAxis = cAgent.AtAxis;
3309 CameraLeftAxis = cAgent.LeftAxis; 3529 CameraLeftAxis = cAgent.LeftAxis;
3310 CameraUpAxis = cAgent.UpAxis; 3530 CameraUpAxis = cAgent.UpAxis;
3531 ParentUUID = cAgent.ParentPart;
3532 m_prevSitOffset = cAgent.SitOffset;
3311 3533
3312 // When we get to the point of re-computing neighbors everytime this 3534 // When we get to the point of re-computing neighbors everytime this
3313 // changes, then start using the agent's drawdistance rather than the 3535 // changes, then start using the agent's drawdistance rather than the
@@ -3345,6 +3567,7 @@ namespace OpenSim.Region.Framework.Scenes
3345 foreach (ControllerData c in cAgent.Controllers) 3567 foreach (ControllerData c in cAgent.Controllers)
3346 { 3568 {
3347 ScriptControllers sc = new ScriptControllers(); 3569 ScriptControllers sc = new ScriptControllers();
3570 sc.objectID = c.ObjectID;
3348 sc.itemID = c.ItemID; 3571 sc.itemID = c.ItemID;
3349 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3572 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3350 sc.eventControls = (ScriptControlled)c.EventControls; 3573 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3412,20 +3635,27 @@ namespace OpenSim.Region.Framework.Scenes
3412 } 3635 }
3413 3636
3414 if (Appearance.AvatarHeight == 0) 3637 if (Appearance.AvatarHeight == 0)
3415 Appearance.SetHeight(); 3638// Appearance.SetHeight();
3639 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3416 3640
3417 PhysicsScene scene = m_scene.PhysicsScene; 3641 PhysicsScene scene = m_scene.PhysicsScene;
3418 3642
3419 Vector3 pVec = AbsolutePosition; 3643 Vector3 pVec = AbsolutePosition;
3420 3644
3645/*
3421 PhysicsActor = scene.AddAvatar( 3646 PhysicsActor = scene.AddAvatar(
3422 LocalId, Firstname + "." + Lastname, pVec, 3647 LocalId, Firstname + "." + Lastname, pVec,
3423 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3648 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3649*/
3650
3651 PhysicsActor = scene.AddAvatar(
3652 LocalId, Firstname + "." + Lastname, pVec,
3653 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
3424 3654
3425 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3655 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3426 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3656 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3427 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3657 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3428 PhysicsActor.SubscribeEvents(500); 3658 PhysicsActor.SubscribeEvents(100);
3429 PhysicsActor.LocalID = LocalId; 3659 PhysicsActor.LocalID = LocalId;
3430 } 3660 }
3431 3661
@@ -3439,6 +3669,7 @@ namespace OpenSim.Region.Framework.Scenes
3439 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3669 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3440 } 3670 }
3441 3671
3672
3442 /// <summary> 3673 /// <summary>
3443 /// Event called by the physics plugin to tell the avatar about a collision. 3674 /// Event called by the physics plugin to tell the avatar about a collision.
3444 /// </summary> 3675 /// </summary>
@@ -3452,7 +3683,7 @@ namespace OpenSim.Region.Framework.Scenes
3452 /// <param name="e"></param> 3683 /// <param name="e"></param>
3453 public void PhysicsCollisionUpdate(EventArgs e) 3684 public void PhysicsCollisionUpdate(EventArgs e)
3454 { 3685 {
3455 if (IsChildAgent) 3686 if (IsChildAgent || Animator == null)
3456 return; 3687 return;
3457 3688
3458 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3689 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3468,7 +3699,6 @@ namespace OpenSim.Region.Framework.Scenes
3468 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3699 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3469 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3700 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3470 3701
3471 CollisionPlane = Vector4.UnitW;
3472 3702
3473// // No collisions at all means we may be flying. Update always 3703// // No collisions at all means we may be flying. Update always
3474// // to make falling work 3704// // to make falling work
@@ -3480,6 +3710,7 @@ namespace OpenSim.Region.Framework.Scenes
3480 3710
3481 if (coldata.Count != 0) 3711 if (coldata.Count != 0)
3482 { 3712 {
3713/*
3483 switch (Animator.CurrentMovementAnimation) 3714 switch (Animator.CurrentMovementAnimation)
3484 { 3715 {
3485 case "STAND": 3716 case "STAND":
@@ -3488,24 +3719,38 @@ namespace OpenSim.Region.Framework.Scenes
3488 case "CROUCH": 3719 case "CROUCH":
3489 case "CROUCHWALK": 3720 case "CROUCHWALK":
3490 { 3721 {
3722 */
3491 ContactPoint lowest; 3723 ContactPoint lowest;
3492 lowest.SurfaceNormal = Vector3.Zero; 3724 lowest.SurfaceNormal = Vector3.Zero;
3493 lowest.Position = Vector3.Zero; 3725 lowest.Position = Vector3.Zero;
3494 lowest.Position.Z = Single.NaN; 3726 lowest.Position.Z = float.MaxValue;
3495 3727
3496 foreach (ContactPoint contact in coldata.Values) 3728 foreach (ContactPoint contact in coldata.Values)
3497 { 3729 {
3498 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 3730
3731 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3499 { 3732 {
3500 lowest = contact; 3733 lowest = contact;
3501 } 3734 }
3502 } 3735 }
3503 3736
3504 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 3737 if (lowest.Position.Z != float.MaxValue)
3738 {
3739 lowest.SurfaceNormal = -lowest.SurfaceNormal;
3740 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3741 }
3742 else
3743 CollisionPlane = Vector4.UnitW;
3744/*
3505 } 3745 }
3506 break; 3746 break;
3507 } 3747 }
3748*/
3508 } 3749 }
3750 else
3751 CollisionPlane = Vector4.UnitW;
3752
3753 RaiseCollisionScriptEvents(coldata);
3509 3754
3510 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3755 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3511 if (Invulnerable || GodLevel > 0) 3756 if (Invulnerable || GodLevel > 0)
@@ -3604,6 +3849,13 @@ namespace OpenSim.Region.Framework.Scenes
3604 // m_reprioritizationTimer.Dispose(); 3849 // m_reprioritizationTimer.Dispose();
3605 3850
3606 RemoveFromPhysicalScene(); 3851 RemoveFromPhysicalScene();
3852
3853 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
3854
3855// if (Animator != null)
3856// Animator.Close();
3857 Animator = null;
3858
3607 } 3859 }
3608 3860
3609 public void AddAttachment(SceneObjectGroup gobj) 3861 public void AddAttachment(SceneObjectGroup gobj)
@@ -3837,10 +4089,18 @@ namespace OpenSim.Region.Framework.Scenes
3837 4089
3838 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4090 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
3839 { 4091 {
4092 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4093 if (p == null)
4094 return;
4095
4096 ControllingClient.SendTakeControls(controls, false, false);
4097 ControllingClient.SendTakeControls(controls, true, false);
4098
3840 ScriptControllers obj = new ScriptControllers(); 4099 ScriptControllers obj = new ScriptControllers();
3841 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4100 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
3842 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4101 obj.eventControls = ScriptControlled.CONTROL_ZERO;
3843 4102
4103 obj.objectID = p.ParentGroup.UUID;
3844 obj.itemID = Script_item_UUID; 4104 obj.itemID = Script_item_UUID;
3845 if (pass_on == 0 && accept == 0) 4105 if (pass_on == 0 && accept == 0)
3846 { 4106 {
@@ -3889,6 +4149,21 @@ namespace OpenSim.Region.Framework.Scenes
3889 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4149 ControllingClient.SendTakeControls(int.MaxValue, false, false);
3890 } 4150 }
3891 4151
4152 private void UnRegisterSeatControls(UUID obj)
4153 {
4154 List<UUID> takers = new List<UUID>();
4155
4156 foreach (ScriptControllers c in scriptedcontrols.Values)
4157 {
4158 if (c.objectID == obj)
4159 takers.Add(c.itemID);
4160 }
4161 foreach (UUID t in takers)
4162 {
4163 UnRegisterControlEventsToScript(0, t);
4164 }
4165 }
4166
3892 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4167 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
3893 { 4168 {
3894 ScriptControllers takecontrols; 4169 ScriptControllers takecontrols;
@@ -4218,6 +4493,12 @@ namespace OpenSim.Region.Framework.Scenes
4218 4493
4219 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4494 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4220 { 4495 {
4496 string reason;
4497
4498 // Honor bans
4499 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4500 return;
4501
4221 SceneObjectGroup telehub = null; 4502 SceneObjectGroup telehub = null;
4222 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4503 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4223 { 4504 {
@@ -4257,11 +4538,206 @@ namespace OpenSim.Region.Framework.Scenes
4257 pos = land.LandData.UserLocation; 4538 pos = land.LandData.UserLocation;
4258 } 4539 }
4259 } 4540 }
4260 4541
4261 land.SendLandUpdateToClient(ControllingClient); 4542 land.SendLandUpdateToClient(ControllingClient);
4262 } 4543 }
4263 } 4544 }
4264 4545
4546 private DetectedObject CreateDetObject(SceneObjectPart obj)
4547 {
4548 DetectedObject detobj = new DetectedObject();
4549 detobj.keyUUID = obj.UUID;
4550 detobj.nameStr = obj.Name;
4551 detobj.ownerUUID = obj.OwnerID;
4552 detobj.posVector = obj.AbsolutePosition;
4553 detobj.rotQuat = obj.GetWorldRotation();
4554 detobj.velVector = obj.Velocity;
4555 detobj.colliderType = 0;
4556 detobj.groupUUID = obj.GroupID;
4557
4558 return detobj;
4559 }
4560
4561 private DetectedObject CreateDetObject(ScenePresence av)
4562 {
4563 DetectedObject detobj = new DetectedObject();
4564 detobj.keyUUID = av.UUID;
4565 detobj.nameStr = av.ControllingClient.Name;
4566 detobj.ownerUUID = av.UUID;
4567 detobj.posVector = av.AbsolutePosition;
4568 detobj.rotQuat = av.Rotation;
4569 detobj.velVector = av.Velocity;
4570 detobj.colliderType = 0;
4571 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4572
4573 return detobj;
4574 }
4575
4576 private DetectedObject CreateDetObjectForGround()
4577 {
4578 DetectedObject detobj = new DetectedObject();
4579 detobj.keyUUID = UUID.Zero;
4580 detobj.nameStr = "";
4581 detobj.ownerUUID = UUID.Zero;
4582 detobj.posVector = AbsolutePosition;
4583 detobj.rotQuat = Quaternion.Identity;
4584 detobj.velVector = Vector3.Zero;
4585 detobj.colliderType = 0;
4586 detobj.groupUUID = UUID.Zero;
4587
4588 return detobj;
4589 }
4590
4591 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4592 {
4593 ColliderArgs colliderArgs = new ColliderArgs();
4594 List<DetectedObject> colliding = new List<DetectedObject>();
4595 foreach (uint localId in colliders)
4596 {
4597 if (localId == 0)
4598 continue;
4599
4600 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4601 if (obj != null)
4602 {
4603 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4604 colliding.Add(CreateDetObject(obj));
4605 }
4606 else
4607 {
4608 ScenePresence av = m_scene.GetScenePresence(localId);
4609 if (av != null && (!av.IsChildAgent))
4610 {
4611 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4612 colliding.Add(CreateDetObject(av));
4613 }
4614 }
4615 }
4616
4617 colliderArgs.Colliders = colliding;
4618
4619 return colliderArgs;
4620 }
4621
4622 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4623
4624 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4625 {
4626 ColliderArgs CollidingMessage;
4627
4628 if (colliders.Count > 0)
4629 {
4630 if ((dest.RootPart.ScriptEvents & ev) != 0)
4631 {
4632 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4633
4634 if (CollidingMessage.Colliders.Count > 0)
4635 notify(dest.RootPart.LocalId, CollidingMessage);
4636 }
4637 }
4638 }
4639
4640 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4641 {
4642 if ((dest.RootPart.ScriptEvents & ev) != 0)
4643 {
4644 ColliderArgs LandCollidingMessage = new ColliderArgs();
4645 List<DetectedObject> colliding = new List<DetectedObject>();
4646
4647 colliding.Add(CreateDetObjectForGround());
4648 LandCollidingMessage.Colliders = colliding;
4649
4650 notify(dest.RootPart.LocalId, LandCollidingMessage);
4651 }
4652 }
4653
4654 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
4655 {
4656 try
4657 {
4658 List<uint> thisHitColliders = new List<uint>();
4659 List<uint> endedColliders = new List<uint>();
4660 List<uint> startedColliders = new List<uint>();
4661 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
4662 CollisionForSoundInfo soundinfo;
4663 ContactPoint curcontact;
4664
4665 if (coldata.Count == 0)
4666 {
4667 if (m_lastColliders.Count == 0)
4668 return; // nothing to do
4669
4670 foreach (uint localID in m_lastColliders)
4671 {
4672 endedColliders.Add(localID);
4673 }
4674 m_lastColliders.Clear();
4675 }
4676
4677 else
4678 {
4679 foreach (uint id in coldata.Keys)
4680 {
4681 thisHitColliders.Add(id);
4682 if (!m_lastColliders.Contains(id))
4683 {
4684 startedColliders.Add(id);
4685 curcontact = coldata[id];
4686 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
4687 {
4688 soundinfo = new CollisionForSoundInfo();
4689 soundinfo.colliderID = id;
4690 soundinfo.position = curcontact.Position;
4691 soundinfo.relativeVel = curcontact.RelativeSpeed;
4692 soundinfolist.Add(soundinfo);
4693 }
4694 }
4695 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
4696 }
4697
4698 // calculate things that ended colliding
4699 foreach (uint localID in m_lastColliders)
4700 {
4701 if (!thisHitColliders.Contains(localID))
4702 {
4703 endedColliders.Add(localID);
4704 }
4705 }
4706 //add the items that started colliding this time to the last colliders list.
4707 foreach (uint localID in startedColliders)
4708 {
4709 m_lastColliders.Add(localID);
4710 }
4711 // remove things that ended colliding from the last colliders list
4712 foreach (uint localID in endedColliders)
4713 {
4714 m_lastColliders.Remove(localID);
4715 }
4716
4717 if (soundinfolist.Count > 0)
4718 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
4719 }
4720
4721 foreach (SceneObjectGroup att in GetAttachments())
4722 {
4723 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
4724 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
4725 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
4726
4727 if (startedColliders.Contains(0))
4728 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
4729 if (m_lastColliders.Contains(0))
4730 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
4731 if (endedColliders.Contains(0))
4732 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
4733 }
4734 }
4735 finally
4736 {
4737 m_collisionEventFlag = false;
4738 }
4739 }
4740
4265 private void TeleportFlagsDebug() { 4741 private void TeleportFlagsDebug() {
4266 4742
4267 // Some temporary debugging help to show all the TeleportFlags we have... 4743 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4286,6 +4762,5 @@ namespace OpenSim.Region.Framework.Scenes
4286 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4762 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4287 4763
4288 } 4764 }
4289
4290 } 4765 }
4291} 4766}