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.cs1077
1 files changed, 763 insertions, 314 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 82bb759..3e3b3af 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
@@ -487,7 +501,7 @@ namespace OpenSim.Region.Framework.Scenes
487 if (ParentID == 0) 501 if (ParentID == 0)
488 { 502 {
489 m_pos = value; 503 m_pos = value;
490 ParentPosition = Vector3.Zero; 504// ParentPosition = Vector3.Zero;
491 } 505 }
492 506
493 //m_log.DebugFormat( 507 //m_log.DebugFormat(
@@ -556,7 +570,24 @@ namespace OpenSim.Region.Framework.Scenes
556// Scene.RegionInfo.RegionName, Name, m_velocity); 570// Scene.RegionInfo.RegionName, Name, m_velocity);
557 } 571 }
558 } 572 }
573/*
574 public override Vector3 AngularVelocity
575 {
576 get
577 {
578 if (PhysicsActor != null)
579 {
580 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
559 581
582 // m_log.DebugFormat(
583 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
584 // m_velocity, Name, Scene.RegionInfo.RegionName);
585 }
586
587 return m_rotationalvelocity;
588 }
589 }
590*/
560 private Quaternion m_bodyRot = Quaternion.Identity; 591 private Quaternion m_bodyRot = Quaternion.Identity;
561 592
562 /// <summary> 593 /// <summary>
@@ -579,8 +610,16 @@ namespace OpenSim.Region.Framework.Scenes
579 m_bodyRot = value; 610 m_bodyRot = value;
580 611
581 if (PhysicsActor != null) 612 if (PhysicsActor != null)
582 PhysicsActor.Orientation = m_bodyRot; 613 {
583 614 try
615 {
616 PhysicsActor.Orientation = m_bodyRot;
617 }
618 catch (Exception e)
619 {
620 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
621 }
622 }
584// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 623// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
585 } 624 }
586 } 625 }
@@ -594,12 +633,20 @@ namespace OpenSim.Region.Framework.Scenes
594 } 633 }
595 634
596 public bool IsChildAgent { get; set; } 635 public bool IsChildAgent { get; set; }
636 public bool IsLoggingIn { get; set; }
597 637
598 /// <summary> 638 /// <summary>
599 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 639 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
600 /// </summary> 640 /// </summary>
601 public uint ParentID { get; set; } 641 public uint ParentID { get; set; }
602 642
643 public UUID ParentUUID
644 {
645 get { return m_parentUUID; }
646 set { m_parentUUID = value; }
647 }
648 private UUID m_parentUUID = UUID.Zero;
649
603 /// <summary> 650 /// <summary>
604 /// Are we sitting on an object? 651 /// Are we sitting on an object?
605 /// </summary> 652 /// </summary>
@@ -749,6 +796,7 @@ namespace OpenSim.Region.Framework.Scenes
749 AttachmentsSyncLock = new Object(); 796 AttachmentsSyncLock = new Object();
750 AllowMovement = true; 797 AllowMovement = true;
751 IsChildAgent = true; 798 IsChildAgent = true;
799 IsLoggingIn = false;
752 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 800 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
753 Animator = new ScenePresenceAnimator(this); 801 Animator = new ScenePresenceAnimator(this);
754 PresenceType = type; 802 PresenceType = type;
@@ -792,6 +840,33 @@ namespace OpenSim.Region.Framework.Scenes
792 Appearance = appearance; 840 Appearance = appearance;
793 } 841 }
794 842
843 private void RegionHeartbeatEnd(Scene scene)
844 {
845 if (IsChildAgent)
846 return;
847
848 m_movementAnimationUpdateCounter ++;
849 if (m_movementAnimationUpdateCounter >= 2)
850 {
851 m_movementAnimationUpdateCounter = 0;
852 if (Animator != null)
853 {
854 // If the parentID == 0 we are not sitting
855 // if !SitGournd then we are not sitting on the ground
856 // Fairly straightforward, now here comes the twist
857 // if ParentUUID is NOT UUID.Zero, we are looking to
858 // be sat on an object that isn't there yet. Should
859 // be treated as if sat.
860 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
861 Animator.UpdateMovementAnimations();
862 }
863 else
864 {
865 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
866 }
867 }
868 }
869
795 public void RegisterToEvents() 870 public void RegisterToEvents()
796 { 871 {
797 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 872 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -801,8 +876,10 @@ namespace OpenSim.Region.Framework.Scenes
801 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 876 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
802 ControllingClient.OnStartAnim += HandleStartAnim; 877 ControllingClient.OnStartAnim += HandleStartAnim;
803 ControllingClient.OnStopAnim += HandleStopAnim; 878 ControllingClient.OnStopAnim += HandleStopAnim;
879 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
804 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 880 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
805 ControllingClient.OnAutoPilotGo += MoveToTarget; 881 ControllingClient.OnAutoPilotGo += MoveToTarget;
882 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
806 883
807 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 884 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
808 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 885 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -861,10 +938,40 @@ namespace OpenSim.Region.Framework.Scenes
861 "[SCENE]: Upgrading child to root agent for {0} in {1}", 938 "[SCENE]: Upgrading child to root agent for {0} in {1}",
862 Name, m_scene.RegionInfo.RegionName); 939 Name, m_scene.RegionInfo.RegionName);
863 940
864 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
865
866 bool wasChild = IsChildAgent; 941 bool wasChild = IsChildAgent;
867 IsChildAgent = false; 942
943 if (ParentUUID != UUID.Zero)
944 {
945 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
946 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
947 if (part == null)
948 {
949 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
950 }
951 else
952 {
953 part.ParentGroup.AddAvatar(UUID);
954 if (part.SitTargetPosition != Vector3.Zero)
955 part.SitTargetAvatar = UUID;
956// ParentPosition = part.GetWorldPosition();
957 ParentID = part.LocalId;
958 ParentPart = part;
959 m_pos = m_prevSitOffset;
960// pos = ParentPosition;
961 pos = part.GetWorldPosition();
962 }
963 ParentUUID = UUID.Zero;
964
965 IsChildAgent = false;
966
967// Animator.TrySetMovementAnimation("SIT");
968 }
969 else
970 {
971 IsChildAgent = false;
972 IsLoggingIn = false;
973 }
974
868 975
869 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); 976 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
870 if (gm != null) 977 if (gm != null)
@@ -874,62 +981,99 @@ namespace OpenSim.Region.Framework.Scenes
874 981
875 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 982 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
876 983
877 // Moved this from SendInitialData to ensure that Appearance is initialized 984 UUID groupUUID = UUID.Zero;
878 // before the inventory is processed in MakeRootAgent. This fixes a race condition 985 string GroupName = string.Empty;
879 // related to the handling of attachments 986 ulong groupPowers = 0;
880 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance); 987
881 if (m_scene.TestBorderCross(pos, Cardinals.E)) 988 // ----------------------------------
989 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
990 try
882 { 991 {
883 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 992 if (gm != null)
884 pos.X = crossedBorder.BorderLine.Z - 1; 993 {
994 groupUUID = ControllingClient.ActiveGroupId;
995 GroupRecord record = gm.GetGroupRecord(groupUUID);
996 if (record != null)
997 GroupName = record.GroupName;
998 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
999 if (groupMembershipData != null)
1000 groupPowers = groupMembershipData.GroupPowers;
1001 }
1002 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1003 Grouptitle);
885 } 1004 }
886 1005 catch (Exception e)
887 if (m_scene.TestBorderCross(pos, Cardinals.N))
888 { 1006 {
889 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1007 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
890 pos.Y = crossedBorder.BorderLine.Z - 1;
891 } 1008 }
1009 // ------------------------------------
892 1010
893 CheckAndAdjustLandingPoint(ref pos); 1011 if (ParentID == 0)
894
895 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
896 { 1012 {
897 m_log.WarnFormat( 1013 // Moved this from SendInitialData to ensure that Appearance is initialized
898 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1014 // before the inventory is processed in MakeRootAgent. This fixes a race condition
899 pos, Name, UUID); 1015 // related to the handling of attachments
1016 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1017 if (m_scene.TestBorderCross(pos, Cardinals.E))
1018 {
1019 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1020 pos.X = crossedBorder.BorderLine.Z - 1;
1021 }
900 1022
901 if (pos.X < 0f) pos.X = 0f; 1023 if (m_scene.TestBorderCross(pos, Cardinals.N))
902 if (pos.Y < 0f) pos.Y = 0f; 1024 {
903 if (pos.Z < 0f) pos.Z = 0f; 1025 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
904 } 1026 pos.Y = crossedBorder.BorderLine.Z - 1;
1027 }
905 1028
906 float localAVHeight = 1.56f; 1029 CheckAndAdjustLandingPoint(ref pos);
907 if (Appearance.AvatarHeight > 0)
908 localAVHeight = Appearance.AvatarHeight;
909 1030
910 float posZLimit = 0; 1031 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1032 {
1033 m_log.WarnFormat(
1034 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1035 pos, Name, UUID);
911 1036
912 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1037 if (pos.X < 0f) pos.X = 0f;
913 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1038 if (pos.Y < 0f) pos.Y = 0f;
914 1039 if (pos.Z < 0f) pos.Z = 0f;
915 float newPosZ = posZLimit + localAVHeight / 2; 1040 }
916 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
917 {
918 pos.Z = newPosZ;
919 }
920 AbsolutePosition = pos;
921 1041
922 AddToPhysicalScene(isFlying); 1042 float localAVHeight = 1.56f;
1043 if (Appearance.AvatarHeight > 0)
1044 localAVHeight = Appearance.AvatarHeight;
923 1045
924 if (ForceFly) 1046 float posZLimit = 0;
925 { 1047
926 Flying = true; 1048 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
927 } 1049 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
928 else if (FlyDisabled) 1050
929 { 1051 float newPosZ = posZLimit + localAVHeight / 2;
930 Flying = false; 1052 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
931 } 1053 {
1054 pos.Z = newPosZ;
1055 }
1056 AbsolutePosition = pos;
932 1057
1058 if (m_teleportFlags == TeleportFlags.Default)
1059 {
1060 Vector3 vel = Velocity;
1061 AddToPhysicalScene(isFlying);
1062 if (PhysicsActor != null)
1063 PhysicsActor.SetMomentum(vel);
1064 }
1065 else
1066 AddToPhysicalScene(isFlying);
1067
1068 if (ForceFly)
1069 {
1070 Flying = true;
1071 }
1072 else if (FlyDisabled)
1073 {
1074 Flying = false;
1075 }
1076 }
933 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1077 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
934 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1078 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
935 // elsewhere anyway 1079 // elsewhere anyway
@@ -949,14 +1093,19 @@ namespace OpenSim.Region.Framework.Scenes
949 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); 1093 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
950 1094
951 // Resume scripts 1095 // Resume scripts
952 foreach (SceneObjectGroup sog in m_attachments) 1096 Util.FireAndForget(delegate(object x) {
953 { 1097 foreach (SceneObjectGroup sog in m_attachments)
954 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1098 {
955 sog.ResumeScripts(); 1099 sog.ScheduleGroupForFullUpdate();
956 } 1100 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1101 sog.ResumeScripts();
1102 }
1103 });
957 } 1104 }
958 } 1105 }
959 1106
1107 SendAvatarDataToAllAgents();
1108
960 // send the animations of the other presences to me 1109 // send the animations of the other presences to me
961 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1110 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
962 { 1111 {
@@ -967,9 +1116,12 @@ namespace OpenSim.Region.Framework.Scenes
967 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1116 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
968 // stall on the border crossing since the existing child agent will still have the last movement 1117 // stall on the border crossing since the existing child agent will still have the last movement
969 // recorded, which stops the input from being processed. 1118 // recorded, which stops the input from being processed.
1119
970 MovementFlag = 0; 1120 MovementFlag = 0;
971 1121
972 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1122 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1123
1124 m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
973 } 1125 }
974 1126
975 public int GetStateSource() 1127 public int GetStateSource()
@@ -997,12 +1149,16 @@ namespace OpenSim.Region.Framework.Scenes
997 /// </remarks> 1149 /// </remarks>
998 public void MakeChildAgent() 1150 public void MakeChildAgent()
999 { 1151 {
1152 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1153
1000 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1154 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1001 1155
1002 // Reset these so that teleporting in and walking out isn't seen 1156 // Reset these so that teleporting in and walking out isn't seen
1003 // as teleporting back 1157 // as teleporting back
1004 TeleportFlags = TeleportFlags.Default; 1158 TeleportFlags = TeleportFlags.Default;
1005 1159
1160 MovementFlag = 0;
1161
1006 // It looks like Animator is set to null somewhere, and MakeChild 1162 // It looks like Animator is set to null somewhere, and MakeChild
1007 // is called after that. Probably in aborted teleports. 1163 // is called after that. Probably in aborted teleports.
1008 if (Animator == null) 1164 if (Animator == null)
@@ -1010,6 +1166,7 @@ namespace OpenSim.Region.Framework.Scenes
1010 else 1166 else
1011 Animator.ResetAnimations(); 1167 Animator.ResetAnimations();
1012 1168
1169
1013// m_log.DebugFormat( 1170// m_log.DebugFormat(
1014// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1171// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1015// Name, UUID, m_scene.RegionInfo.RegionName); 1172// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1021,6 +1178,7 @@ namespace OpenSim.Region.Framework.Scenes
1021 IsChildAgent = true; 1178 IsChildAgent = true;
1022 m_scene.SwapRootAgentCount(true); 1179 m_scene.SwapRootAgentCount(true);
1023 RemoveFromPhysicalScene(); 1180 RemoveFromPhysicalScene();
1181 ParentID = 0; // Child agents can't be sitting
1024 1182
1025 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1183 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1026 1184
@@ -1036,9 +1194,9 @@ namespace OpenSim.Region.Framework.Scenes
1036 { 1194 {
1037// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1195// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1038 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1196 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1039 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1040 PhysicsActor.UnSubscribeEvents();
1041 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1197 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1198 PhysicsActor.UnSubscribeEvents();
1199 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1042 PhysicsActor = null; 1200 PhysicsActor = null;
1043 } 1201 }
1044// else 1202// else
@@ -1055,7 +1213,7 @@ namespace OpenSim.Region.Framework.Scenes
1055 /// <param name="pos"></param> 1213 /// <param name="pos"></param>
1056 public void Teleport(Vector3 pos) 1214 public void Teleport(Vector3 pos)
1057 { 1215 {
1058 TeleportWithMomentum(pos, null); 1216 TeleportWithMomentum(pos, Vector3.Zero);
1059 } 1217 }
1060 1218
1061 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1219 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1079,6 +1237,41 @@ namespace OpenSim.Region.Framework.Scenes
1079 SendTerseUpdateToAllClients(); 1237 SendTerseUpdateToAllClients();
1080 } 1238 }
1081 1239
1240 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1241 {
1242 CheckLandingPoint(ref newpos);
1243 AbsolutePosition = newpos;
1244
1245 if (newvel.HasValue)
1246 {
1247 if ((Vector3)newvel == Vector3.Zero)
1248 {
1249 if (PhysicsActor != null)
1250 PhysicsActor.SetMomentum(Vector3.Zero);
1251 m_velocity = Vector3.Zero;
1252 }
1253 else
1254 {
1255 if (PhysicsActor != null)
1256 PhysicsActor.SetMomentum((Vector3)newvel);
1257 m_velocity = (Vector3)newvel;
1258
1259 if (rotateToVelXY)
1260 {
1261 Vector3 lookAt = (Vector3)newvel;
1262 lookAt.Z = 0;
1263 lookAt.Normalize();
1264 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1265 return;
1266 }
1267 }
1268 }
1269
1270 SendTerseUpdateToAllClients();
1271 }
1272
1273
1274
1082 public void StopFlying() 1275 public void StopFlying()
1083 { 1276 {
1084 ControllingClient.StopFlying(this); 1277 ControllingClient.StopFlying(this);
@@ -1248,6 +1441,13 @@ namespace OpenSim.Region.Framework.Scenes
1248 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1441 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1249 } 1442 }
1250 1443
1444 public void SetSize(Vector3 size, float feetoffset)
1445 {
1446 if (PhysicsActor != null && !IsChildAgent)
1447 PhysicsActor.setAvatarSize(size, feetoffset);
1448
1449 }
1450
1251 /// <summary> 1451 /// <summary>
1252 /// Complete Avatar's movement into the region. 1452 /// Complete Avatar's movement into the region.
1253 /// </summary> 1453 /// </summary>
@@ -1267,7 +1467,8 @@ namespace OpenSim.Region.Framework.Scenes
1267 1467
1268 Vector3 look = Velocity; 1468 Vector3 look = Velocity;
1269 1469
1270 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1470 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1471 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1271 { 1472 {
1272 look = new Vector3(0.99f, 0.042f, 0); 1473 look = new Vector3(0.99f, 0.042f, 0);
1273 } 1474 }
@@ -1317,13 +1518,15 @@ namespace OpenSim.Region.Framework.Scenes
1317 // Create child agents in neighbouring regions 1518 // Create child agents in neighbouring regions
1318 if (openChildAgents && !IsChildAgent) 1519 if (openChildAgents && !IsChildAgent)
1319 { 1520 {
1521
1320 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1522 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1321 if (m_agentTransfer != null) 1523 if (m_agentTransfer != null)
1322 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1524 m_agentTransfer.EnableChildAgents(this);
1323 1525
1324 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1526 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1325 if (friendsModule != null) 1527 if (friendsModule != null)
1326 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1528 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1529
1327 } 1530 }
1328 1531
1329// m_log.DebugFormat( 1532// m_log.DebugFormat(
@@ -1339,35 +1542,43 @@ namespace OpenSim.Region.Framework.Scenes
1339 /// <param name="collisionPoint"></param> 1542 /// <param name="collisionPoint"></param>
1340 /// <param name="localid"></param> 1543 /// <param name="localid"></param>
1341 /// <param name="distance"></param> 1544 /// <param name="distance"></param>
1545 ///
1546
1547 private void UpdateCameraCollisionPlane(Vector4 plane)
1548 {
1549 if (m_lastCameraCollisionPlane != plane)
1550 {
1551 m_lastCameraCollisionPlane = plane;
1552 ControllingClient.SendCameraConstraint(plane);
1553 }
1554 }
1555
1342 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1556 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1343 { 1557 {
1344 const float POSITION_TOLERANCE = 0.02f; 1558 const float POSITION_TOLERANCE = 0.02f;
1345 const float VELOCITY_TOLERANCE = 0.02f;
1346 const float ROTATION_TOLERANCE = 0.02f; 1559 const float ROTATION_TOLERANCE = 0.02f;
1347 1560
1348 if (m_followCamAuto) 1561 m_doingCamRayCast = false;
1562 if (hitYN && localid != LocalId)
1349 { 1563 {
1350 if (hitYN) 1564 CameraConstraintActive = true;
1351 { 1565 pNormal.X = (float)Math.Round(pNormal.X, 2);
1352 CameraConstraintActive = true; 1566 pNormal.Y = (float)Math.Round(pNormal.Y, 2);
1353 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1567 pNormal.Z = (float)Math.Round(pNormal.Z, 2);
1354 1568 pNormal.Normalize();
1355 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1569 collisionPoint.X = (float)Math.Round(collisionPoint.X, 1);
1356 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1570 collisionPoint.Y = (float)Math.Round(collisionPoint.Y, 1);
1357 } 1571 collisionPoint.Z = (float)Math.Round(collisionPoint.Z, 1);
1358 else 1572
1359 { 1573 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z, Vector3.Dot(collisionPoint, pNormal));
1360 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1574 UpdateCameraCollisionPlane(plane);
1361 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1575 }
1362 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1576 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1363 { 1577 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1364 if (CameraConstraintActive) 1578 {
1365 { 1579 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1366 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1580 UpdateCameraCollisionPlane(plane);
1367 CameraConstraintActive = false; 1581 CameraConstraintActive = false;
1368 }
1369 }
1370 }
1371 } 1582 }
1372 } 1583 }
1373 1584
@@ -1442,12 +1653,6 @@ namespace OpenSim.Region.Framework.Scenes
1442 // DrawDistance = agentData.Far; 1653 // DrawDistance = agentData.Far;
1443 DrawDistance = Scene.DefaultDrawDistance; 1654 DrawDistance = Scene.DefaultDrawDistance;
1444 1655
1445 // Check if Client has camera in 'follow cam' or 'build' mode.
1446 Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
1447
1448 m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
1449 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
1450
1451 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; 1656 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
1452 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; 1657 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
1453 1658
@@ -1467,14 +1672,38 @@ namespace OpenSim.Region.Framework.Scenes
1467 StandUp(); 1672 StandUp();
1468 } 1673 }
1469 1674
1470 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
1471 // Raycast from the avatar's head to the camera to see if there's anything blocking the view 1675 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1472 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) 1676 // this exclude checks may not be complete
1677
1678 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1473 { 1679 {
1474 if (m_followCamAuto) 1680 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1475 { 1681 {
1476 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; 1682 Vector3 posAdjusted = AbsolutePosition;
1477 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback); 1683// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1684 posAdjusted.Z += 1.0f; // viewer current camera focus point
1685 Vector3 tocam = CameraPosition - posAdjusted;
1686 tocam.X = (float)Math.Round(tocam.X, 1);
1687 tocam.Y = (float)Math.Round(tocam.Y, 1);
1688 tocam.Z = (float)Math.Round(tocam.Z, 1);
1689
1690 float distTocamlen = tocam.Length();
1691 if (distTocamlen > 0.3f)
1692 {
1693 tocam *= (1.0f / distTocamlen);
1694 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1695 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1696 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1697
1698 m_doingCamRayCast = true;
1699 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1700 }
1701 }
1702 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1703 {
1704 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1705 UpdateCameraCollisionPlane(plane);
1706 CameraConstraintActive = false;
1478 } 1707 }
1479 } 1708 }
1480 1709
@@ -1939,7 +2168,8 @@ namespace OpenSim.Region.Framework.Scenes
1939// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2168// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1940 2169
1941 MovingToTarget = false; 2170 MovingToTarget = false;
1942 MoveToPositionTarget = Vector3.Zero; 2171// MoveToPositionTarget = Vector3.Zero;
2172 m_forceToApply = null; // cancel possible last action
1943 2173
1944 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2174 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
1945 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2175 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -1957,12 +2187,17 @@ namespace OpenSim.Region.Framework.Scenes
1957// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2187// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
1958 2188
1959 SitGround = false; 2189 SitGround = false;
2190
2191/* move this down so avatar gets physical in the new position and not where it is siting
1960 if (PhysicsActor == null) 2192 if (PhysicsActor == null)
1961 AddToPhysicalScene(false); 2193 AddToPhysicalScene(false);
2194 */
1962 2195
1963 if (ParentID != 0) 2196 if (ParentID != 0)
1964 { 2197 {
1965 SceneObjectPart part = ParentPart; 2198 SceneObjectPart part = ParentPart;
2199 UnRegisterSeatControls(part.ParentGroup.UUID);
2200
1966 TaskInventoryDictionary taskIDict = part.TaskInventory; 2201 TaskInventoryDictionary taskIDict = part.TaskInventory;
1967 if (taskIDict != null) 2202 if (taskIDict != null)
1968 { 2203 {
@@ -1978,14 +2213,22 @@ namespace OpenSim.Region.Framework.Scenes
1978 } 2213 }
1979 } 2214 }
1980 2215
1981 ParentPosition = part.GetWorldPosition(); 2216 part.ParentGroup.DeleteAvatar(UUID);
2217// ParentPosition = part.GetWorldPosition();
1982 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2218 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1983 2219
1984 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 2220// m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
1985 ParentPosition = Vector3.Zero; 2221// ParentPosition = Vector3.Zero;
2222 m_pos = part.AbsolutePosition + (m_pos * part.GetWorldRotation()) + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2223 if (part.SitTargetAvatar == UUID)
2224 m_bodyRot = part.GetWorldRotation() * part.SitTargetOrientation;
1986 2225
1987 ParentID = 0; 2226 ParentID = 0;
1988 ParentPart = null; 2227 ParentPart = null;
2228
2229 if (PhysicsActor == null)
2230 AddToPhysicalScene(false);
2231
1989 SendAvatarDataToAllAgents(); 2232 SendAvatarDataToAllAgents();
1990 m_requestedSitTargetID = 0; 2233 m_requestedSitTargetID = 0;
1991 2234
@@ -1995,6 +2238,9 @@ namespace OpenSim.Region.Framework.Scenes
1995 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2238 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1996 } 2239 }
1997 2240
2241 else if (PhysicsActor == null)
2242 AddToPhysicalScene(false);
2243
1998 Animator.TrySetMovementAnimation("STAND"); 2244 Animator.TrySetMovementAnimation("STAND");
1999 } 2245 }
2000 2246
@@ -2042,11 +2288,8 @@ namespace OpenSim.Region.Framework.Scenes
2042 if (part == null) 2288 if (part == null)
2043 return; 2289 return;
2044 2290
2045 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2046 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2047
2048 if (PhysicsActor != null) 2291 if (PhysicsActor != null)
2049 m_sitAvatarHeight = PhysicsActor.Size.Z; 2292 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2050 2293
2051 bool canSit = false; 2294 bool canSit = false;
2052 Vector3 pos = part.AbsolutePosition + offset; 2295 Vector3 pos = part.AbsolutePosition + offset;
@@ -2063,31 +2306,31 @@ namespace OpenSim.Region.Framework.Scenes
2063 } 2306 }
2064 else 2307 else
2065 { 2308 {
2309 if (PhysicsSit(part,offset)) // physics engine
2310 return;
2311
2066 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2312 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2067 { 2313 {
2068// m_log.DebugFormat(
2069// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2070// Name, part.Name, part.LocalId);
2071 2314
2072 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2315 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2073 canSit = true; 2316 canSit = true;
2074 } 2317 }
2075// else
2076// {
2077// m_log.DebugFormat(
2078// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2079// Name, part.Name, part.LocalId);
2080// }
2081 } 2318 }
2082 2319
2083 if (canSit) 2320 if (canSit)
2084 { 2321 {
2322
2085 if (PhysicsActor != null) 2323 if (PhysicsActor != null)
2086 { 2324 {
2087 // We can remove the physicsActor until they stand up. 2325 // We can remove the physicsActor until they stand up.
2088 RemoveFromPhysicalScene(); 2326 RemoveFromPhysicalScene();
2089 } 2327 }
2090 2328
2329 if (MovingToTarget)
2330 ResetMoveToTarget();
2331
2332 Velocity = Vector3.Zero;
2333
2091 part.AddSittingAvatar(UUID); 2334 part.AddSittingAvatar(UUID);
2092 2335
2093 cameraAtOffset = part.GetCameraAtOffset(); 2336 cameraAtOffset = part.GetCameraAtOffset();
@@ -2095,7 +2338,7 @@ namespace OpenSim.Region.Framework.Scenes
2095 forceMouselook = part.GetForceMouselook(); 2338 forceMouselook = part.GetForceMouselook();
2096 2339
2097 ControllingClient.SendSitResponse( 2340 ControllingClient.SendSitResponse(
2098 targetID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 2341 part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2099 2342
2100 m_requestedSitTargetUUID = targetID; 2343 m_requestedSitTargetUUID = targetID;
2101 2344
@@ -2109,6 +2352,9 @@ namespace OpenSim.Region.Framework.Scenes
2109 2352
2110 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2353 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2111 { 2354 {
2355 if (IsChildAgent)
2356 return;
2357
2112 if (ParentID != 0) 2358 if (ParentID != 0)
2113 { 2359 {
2114 if (ParentPart.UUID == targetID) 2360 if (ParentPart.UUID == targetID)
@@ -2124,14 +2370,6 @@ namespace OpenSim.Region.Framework.Scenes
2124 m_requestedSitTargetID = part.LocalId; 2370 m_requestedSitTargetID = part.LocalId;
2125 m_requestedSitTargetUUID = targetID; 2371 m_requestedSitTargetUUID = targetID;
2126 2372
2127// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2128
2129 if (m_scene.PhysicsScene.SupportsRayCast())
2130 {
2131 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2132 //SitRayCastAvatarPosition(part);
2133 //return;
2134 }
2135 } 2373 }
2136 else 2374 else
2137 { 2375 {
@@ -2141,197 +2379,111 @@ namespace OpenSim.Region.Framework.Scenes
2141 SendSitResponse(targetID, offset, Quaternion.Identity); 2379 SendSitResponse(targetID, offset, Quaternion.Identity);
2142 } 2380 }
2143 2381
2144 /* 2382 // returns false if does not suport so older sit can be tried
2145 public void SitRayCastAvatarPosition(SceneObjectPart part) 2383 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2146 { 2384 {
2147 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2385 if (part == null || part.ParentGroup.IsAttachment)
2148 Vector3 StartRayCastPosition = AbsolutePosition;
2149 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2150 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2151 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2152 }
2153
2154 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2155 {
2156 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2157 if (part != null)
2158 {
2159 if (hitYN)
2160 {
2161 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2162 {
2163 SitRaycastFindEdge(collisionPoint, normal);
2164 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2165 }
2166 else
2167 {
2168 SitRayCastAvatarPositionCameraZ(part);
2169 }
2170 }
2171 else
2172 {
2173 SitRayCastAvatarPositionCameraZ(part);
2174 }
2175 }
2176 else
2177 { 2386 {
2178 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2387 return true;
2179 m_requestedSitTargetUUID = UUID.Zero;
2180 m_requestedSitTargetID = 0;
2181 m_requestedSitOffset = Vector3.Zero;
2182 } 2388 }
2183 2389
2184 } 2390 if ( m_scene.PhysicsScene == null)
2185 2391 return false;
2186 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2187 {
2188 // Next, try to raycast from the camera Z position
2189 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2190 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2191 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2192 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2193 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2194 }
2195 2392
2196 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2393 if (part.PhysActor == null)
2197 {
2198 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2199 if (part != null)
2200 { 2394 {
2201 if (hitYN) 2395 // none physcis shape
2202 { 2396 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2203 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2397 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2204 {
2205 SitRaycastFindEdge(collisionPoint, normal);
2206 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2207 }
2208 else
2209 {
2210 SitRayCastCameraPosition(part);
2211 }
2212 }
2213 else 2398 else
2214 { 2399 { // non physical phantom TODO
2215 SitRayCastCameraPosition(part); 2400 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2401 return false;
2216 } 2402 }
2217 } 2403 return true;
2218 else
2219 {
2220 ControllingClient.SendAlertMessage("Sit position no longer exists");
2221 m_requestedSitTargetUUID = UUID.Zero;
2222 m_requestedSitTargetID = 0;
2223 m_requestedSitOffset = Vector3.Zero;
2224 } 2404 }
2225 2405
2226 }
2227 2406
2228 public void SitRayCastCameraPosition(SceneObjectPart part) 2407 // not doing autopilot
2229 { 2408 m_requestedSitTargetID = 0;
2230 // Next, try to raycast from the camera position
2231 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2232 Vector3 StartRayCastPosition = CameraPosition;
2233 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2234 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2235 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2236 }
2237 2409
2238 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2410 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2239 { 2411 return true;
2240 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2241 if (part != null)
2242 {
2243 if (hitYN)
2244 {
2245 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2246 {
2247 SitRaycastFindEdge(collisionPoint, normal);
2248 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2249 }
2250 else
2251 {
2252 SitRayHorizontal(part);
2253 }
2254 }
2255 else
2256 {
2257 SitRayHorizontal(part);
2258 }
2259 }
2260 else
2261 {
2262 ControllingClient.SendAlertMessage("Sit position no longer exists");
2263 m_requestedSitTargetUUID = UUID.Zero;
2264 m_requestedSitTargetID = 0;
2265 m_requestedSitOffset = Vector3.Zero;
2266 }
2267 2412
2413 return false;
2268 } 2414 }
2269 2415
2270 public void SitRayHorizontal(SceneObjectPart part) 2416
2417 private bool CanEnterLandPosition(Vector3 testPos)
2271 { 2418 {
2272 // Next, try to raycast from the avatar position to fwd 2419 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2273 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2420
2274 Vector3 StartRayCastPosition = CameraPosition; 2421 if (land == null || land.LandData.Name == "NO_LAND")
2275 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2422 return true;
2276 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2423
2277 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2424 return land.CanBeOnThisLand(UUID,testPos.Z);
2278 } 2425 }
2279 2426
2280 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2427 // status
2428 // < 0 ignore
2429 // 0 bad sit spot
2430 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2281 { 2431 {
2282 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2432 if (status < 0)
2283 if (part != null) 2433 return;
2434
2435 if (status == 0)
2284 { 2436 {
2285 if (hitYN) 2437 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2286 { 2438 return;
2287 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2288 {
2289 SitRaycastFindEdge(collisionPoint, normal);
2290 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2291 // Next, try to raycast from the camera position
2292 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2293 Vector3 StartRayCastPosition = CameraPosition;
2294 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2295 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2296 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2297 }
2298 else
2299 {
2300 ControllingClient.SendAlertMessage("Sit position not accessable.");
2301 m_requestedSitTargetUUID = UUID.Zero;
2302 m_requestedSitTargetID = 0;
2303 m_requestedSitOffset = Vector3.Zero;
2304 }
2305 }
2306 else
2307 {
2308 ControllingClient.SendAlertMessage("Sit position not accessable.");
2309 m_requestedSitTargetUUID = UUID.Zero;
2310 m_requestedSitTargetID = 0;
2311 m_requestedSitOffset = Vector3.Zero;
2312 }
2313 } 2439 }
2314 else 2440
2441 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2442 if (part == null)
2443 return;
2444
2445 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2446 if(!CanEnterLandPosition(targetPos))
2315 { 2447 {
2316 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2448 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2317 m_requestedSitTargetUUID = UUID.Zero; 2449 return;
2318 m_requestedSitTargetID = 0;
2319 m_requestedSitOffset = Vector3.Zero;
2320 } 2450 }
2321 2451
2322 } 2452 RemoveFromPhysicalScene();
2323 2453
2324 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2454 if (MovingToTarget)
2325 { 2455 ResetMoveToTarget();
2326 int i = 0; 2456
2327 //throw new NotImplementedException(); 2457 Velocity = Vector3.Zero;
2328 //m_requestedSitTargetUUID = UUID.Zero;
2329 //m_requestedSitTargetID = 0;
2330 //m_requestedSitOffset = Vector3.Zero;
2331 2458
2332 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2459 part.AddSittingAvatar(UUID);
2460
2461 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2462 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2463 bool forceMouselook = part.GetForceMouselook();
2464
2465 ControllingClient.SendSitResponse(
2466 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2467
2468 // not using autopilot
2469
2470 Rotation = Orientation;
2471 m_pos = offset;
2472
2473 m_requestedSitTargetID = 0;
2474 part.ParentGroup.AddAvatar(UUID);
2475
2476 ParentPart = part;
2477 ParentID = part.LocalId;
2478 if(status == 3)
2479 Animator.TrySetMovementAnimation("SIT_GROUND");
2480 else
2481 Animator.TrySetMovementAnimation("SIT");
2482 SendAvatarDataToAllAgents();
2483
2484 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2333 } 2485 }
2334 */ 2486
2335 2487
2336 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2488 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2337 { 2489 {
@@ -2348,6 +2500,7 @@ namespace OpenSim.Region.Framework.Scenes
2348 return; 2500 return;
2349 } 2501 }
2350 2502
2503
2351 if (part.SitTargetAvatar == UUID) 2504 if (part.SitTargetAvatar == UUID)
2352 { 2505 {
2353 Vector3 sitTargetPos = part.SitTargetPosition; 2506 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2362,14 +2515,39 @@ namespace OpenSim.Region.Framework.Scenes
2362 2515
2363 //Quaternion result = (sitTargetOrient * vq) * nq; 2516 //Quaternion result = (sitTargetOrient * vq) * nq;
2364 2517
2365 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2518 double x, y, z, m;
2519
2520 Quaternion r = sitTargetOrient;
2521 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2522
2523 if (Math.Abs(1.0 - m) > 0.000001)
2524 {
2525 m = 1.0 / Math.Sqrt(m);
2526 r.X *= (float)m;
2527 r.Y *= (float)m;
2528 r.Z *= (float)m;
2529 r.W *= (float)m;
2530 }
2531
2532 x = 2 * (r.X * r.Z + r.Y * r.W);
2533 y = 2 * (-r.X * r.W + r.Y * r.Z);
2534 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2535
2536 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2537 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2538
2539 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2540
2541// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2366 Rotation = sitTargetOrient; 2542 Rotation = sitTargetOrient;
2367 ParentPosition = part.AbsolutePosition; 2543// ParentPosition = part.AbsolutePosition;
2544 part.ParentGroup.AddAvatar(UUID);
2368 } 2545 }
2369 else 2546 else
2370 { 2547 {
2371 m_pos -= part.AbsolutePosition; 2548 m_pos -= part.AbsolutePosition;
2372 ParentPosition = part.AbsolutePosition; 2549// ParentPosition = part.AbsolutePosition;
2550 part.ParentGroup.AddAvatar(UUID);
2373 2551
2374// m_log.DebugFormat( 2552// m_log.DebugFormat(
2375// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2553// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2420,6 +2598,13 @@ namespace OpenSim.Region.Framework.Scenes
2420 Animator.RemoveAnimation(animID, false); 2598 Animator.RemoveAnimation(animID, false);
2421 } 2599 }
2422 2600
2601 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
2602 {
2603 Animator.avnChangeAnim(animID, addRemove, sendPack);
2604 }
2605
2606
2607
2423 /// <summary> 2608 /// <summary>
2424 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2609 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2425 /// </summary> 2610 /// </summary>
@@ -2476,8 +2661,8 @@ namespace OpenSim.Region.Framework.Scenes
2476 direc.Z *= 2.6f; 2661 direc.Z *= 2.6f;
2477 2662
2478 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2663 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2479 Animator.TrySetMovementAnimation("PREJUMP"); 2664// Animator.TrySetMovementAnimation("PREJUMP");
2480 Animator.TrySetMovementAnimation("JUMP"); 2665// Animator.TrySetMovementAnimation("JUMP");
2481 } 2666 }
2482 } 2667 }
2483 } 2668 }
@@ -2486,6 +2671,7 @@ namespace OpenSim.Region.Framework.Scenes
2486 2671
2487 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2672 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2488 m_forceToApply = direc; 2673 m_forceToApply = direc;
2674 Animator.UpdateMovementAnimations();
2489 } 2675 }
2490 2676
2491 #endregion 2677 #endregion
@@ -2503,16 +2689,12 @@ namespace OpenSim.Region.Framework.Scenes
2503 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 2689 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2504 // grab the latest PhysicsActor velocity, whereas m_velocity is often 2690 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2505 // storing a requested force instead of an actual traveling velocity 2691 // storing a requested force instead of an actual traveling velocity
2692 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
2693 SendAvatarDataToAllAgents();
2506 2694
2507 // Throw away duplicate or insignificant updates 2695 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2508 if ( 2696 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2509 // If the velocity has become zero, send it no matter what. 2697 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2510 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2511 // otherwise, if things have changed reasonably, send the update
2512 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2513 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2514 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2515
2516 { 2698 {
2517 SendTerseUpdateToAllClients(); 2699 SendTerseUpdateToAllClients();
2518 2700
@@ -2701,6 +2883,8 @@ namespace OpenSim.Region.Framework.Scenes
2701 return; 2883 return;
2702 } 2884 }
2703 2885
2886 m_lastSize = Appearance.AvatarSize;
2887
2704 int count = 0; 2888 int count = 0;
2705 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2889 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2706 { 2890 {
@@ -2808,6 +2992,8 @@ namespace OpenSim.Region.Framework.Scenes
2808 2992
2809 avatar.ControllingClient.SendAppearance( 2993 avatar.ControllingClient.SendAppearance(
2810 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 2994 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
2995
2996
2811 } 2997 }
2812 2998
2813 #endregion 2999 #endregion
@@ -2882,8 +3068,9 @@ namespace OpenSim.Region.Framework.Scenes
2882 3068
2883 // If we don't have a PhysActor, we can't cross anyway 3069 // If we don't have a PhysActor, we can't cross anyway
2884 // Also don't do this while sat, sitting avatars cross with the 3070 // Also don't do this while sat, sitting avatars cross with the
2885 // object they sit on. 3071 // object they sit on. ParentUUID denoted a pending sit, don't
2886 if (ParentID != 0 || PhysicsActor == null) 3072 // interfere with it.
3073 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
2887 return; 3074 return;
2888 3075
2889 if (!IsInTransit) 3076 if (!IsInTransit)
@@ -3144,6 +3331,10 @@ namespace OpenSim.Region.Framework.Scenes
3144 } 3331 }
3145 3332
3146 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3333 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3334 private void RaiseUpdateThrottles()
3335 {
3336 m_scene.EventManager.TriggerThrottleUpdate(this);
3337 }
3147 /// <summary> 3338 /// <summary>
3148 /// This updates important decision making data about a child agent 3339 /// This updates important decision making data about a child agent
3149 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3340 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3224,6 +3415,9 @@ namespace OpenSim.Region.Framework.Scenes
3224 cAgent.AlwaysRun = SetAlwaysRun; 3415 cAgent.AlwaysRun = SetAlwaysRun;
3225 3416
3226 cAgent.Appearance = new AvatarAppearance(Appearance); 3417 cAgent.Appearance = new AvatarAppearance(Appearance);
3418
3419 cAgent.ParentPart = ParentUUID;
3420 cAgent.SitOffset = m_pos;
3227 3421
3228 lock (scriptedcontrols) 3422 lock (scriptedcontrols)
3229 { 3423 {
@@ -3232,7 +3426,7 @@ namespace OpenSim.Region.Framework.Scenes
3232 3426
3233 foreach (ScriptControllers c in scriptedcontrols.Values) 3427 foreach (ScriptControllers c in scriptedcontrols.Values)
3234 { 3428 {
3235 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3429 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3236 } 3430 }
3237 cAgent.Controllers = controls; 3431 cAgent.Controllers = controls;
3238 } 3432 }
@@ -3265,6 +3459,8 @@ namespace OpenSim.Region.Framework.Scenes
3265 CameraAtAxis = cAgent.AtAxis; 3459 CameraAtAxis = cAgent.AtAxis;
3266 CameraLeftAxis = cAgent.LeftAxis; 3460 CameraLeftAxis = cAgent.LeftAxis;
3267 CameraUpAxis = cAgent.UpAxis; 3461 CameraUpAxis = cAgent.UpAxis;
3462 ParentUUID = cAgent.ParentPart;
3463 m_prevSitOffset = cAgent.SitOffset;
3268 3464
3269 // When we get to the point of re-computing neighbors everytime this 3465 // When we get to the point of re-computing neighbors everytime this
3270 // changes, then start using the agent's drawdistance rather than the 3466 // changes, then start using the agent's drawdistance rather than the
@@ -3302,6 +3498,7 @@ namespace OpenSim.Region.Framework.Scenes
3302 foreach (ControllerData c in cAgent.Controllers) 3498 foreach (ControllerData c in cAgent.Controllers)
3303 { 3499 {
3304 ScriptControllers sc = new ScriptControllers(); 3500 ScriptControllers sc = new ScriptControllers();
3501 sc.objectID = c.ObjectID;
3305 sc.itemID = c.ItemID; 3502 sc.itemID = c.ItemID;
3306 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3503 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3307 sc.eventControls = (ScriptControlled)c.EventControls; 3504 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3369,20 +3566,27 @@ namespace OpenSim.Region.Framework.Scenes
3369 } 3566 }
3370 3567
3371 if (Appearance.AvatarHeight == 0) 3568 if (Appearance.AvatarHeight == 0)
3372 Appearance.SetHeight(); 3569// Appearance.SetHeight();
3570 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3373 3571
3374 PhysicsScene scene = m_scene.PhysicsScene; 3572 PhysicsScene scene = m_scene.PhysicsScene;
3375 3573
3376 Vector3 pVec = AbsolutePosition; 3574 Vector3 pVec = AbsolutePosition;
3377 3575
3576/*
3378 PhysicsActor = scene.AddAvatar( 3577 PhysicsActor = scene.AddAvatar(
3379 LocalId, Firstname + "." + Lastname, pVec, 3578 LocalId, Firstname + "." + Lastname, pVec,
3380 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3579 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3580*/
3581
3582 PhysicsActor = scene.AddAvatar(
3583 LocalId, Firstname + "." + Lastname, pVec,
3584 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
3381 3585
3382 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3586 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3383 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3587 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3384 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3588 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3385 PhysicsActor.SubscribeEvents(500); 3589 PhysicsActor.SubscribeEvents(100);
3386 PhysicsActor.LocalID = LocalId; 3590 PhysicsActor.LocalID = LocalId;
3387 } 3591 }
3388 3592
@@ -3396,6 +3600,7 @@ namespace OpenSim.Region.Framework.Scenes
3396 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3600 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3397 } 3601 }
3398 3602
3603
3399 /// <summary> 3604 /// <summary>
3400 /// Event called by the physics plugin to tell the avatar about a collision. 3605 /// Event called by the physics plugin to tell the avatar about a collision.
3401 /// </summary> 3606 /// </summary>
@@ -3409,7 +3614,7 @@ namespace OpenSim.Region.Framework.Scenes
3409 /// <param name="e"></param> 3614 /// <param name="e"></param>
3410 public void PhysicsCollisionUpdate(EventArgs e) 3615 public void PhysicsCollisionUpdate(EventArgs e)
3411 { 3616 {
3412 if (IsChildAgent) 3617 if (IsChildAgent || Animator == null)
3413 return; 3618 return;
3414 3619
3415 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3620 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3425,7 +3630,6 @@ namespace OpenSim.Region.Framework.Scenes
3425 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3630 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3426 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3631 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3427 3632
3428 CollisionPlane = Vector4.UnitW;
3429 3633
3430// // No collisions at all means we may be flying. Update always 3634// // No collisions at all means we may be flying. Update always
3431// // to make falling work 3635// // to make falling work
@@ -3437,6 +3641,7 @@ namespace OpenSim.Region.Framework.Scenes
3437 3641
3438 if (coldata.Count != 0) 3642 if (coldata.Count != 0)
3439 { 3643 {
3644/*
3440 switch (Animator.CurrentMovementAnimation) 3645 switch (Animator.CurrentMovementAnimation)
3441 { 3646 {
3442 case "STAND": 3647 case "STAND":
@@ -3445,24 +3650,38 @@ namespace OpenSim.Region.Framework.Scenes
3445 case "CROUCH": 3650 case "CROUCH":
3446 case "CROUCHWALK": 3651 case "CROUCHWALK":
3447 { 3652 {
3653 */
3448 ContactPoint lowest; 3654 ContactPoint lowest;
3449 lowest.SurfaceNormal = Vector3.Zero; 3655 lowest.SurfaceNormal = Vector3.Zero;
3450 lowest.Position = Vector3.Zero; 3656 lowest.Position = Vector3.Zero;
3451 lowest.Position.Z = Single.NaN; 3657 lowest.Position.Z = float.MaxValue;
3452 3658
3453 foreach (ContactPoint contact in coldata.Values) 3659 foreach (ContactPoint contact in coldata.Values)
3454 { 3660 {
3455 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 3661
3662 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3456 { 3663 {
3457 lowest = contact; 3664 lowest = contact;
3458 } 3665 }
3459 } 3666 }
3460 3667
3461 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 3668 if (lowest.Position.Z != float.MaxValue)
3669 {
3670 lowest.SurfaceNormal = -lowest.SurfaceNormal;
3671 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3672 }
3673 else
3674 CollisionPlane = Vector4.UnitW;
3675/*
3462 } 3676 }
3463 break; 3677 break;
3464 } 3678 }
3679*/
3465 } 3680 }
3681 else
3682 CollisionPlane = Vector4.UnitW;
3683
3684 RaiseCollisionScriptEvents(coldata);
3466 3685
3467 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3686 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3468 if (Invulnerable || GodLevel > 0) 3687 if (Invulnerable || GodLevel > 0)
@@ -3561,6 +3780,13 @@ namespace OpenSim.Region.Framework.Scenes
3561 // m_reprioritizationTimer.Dispose(); 3780 // m_reprioritizationTimer.Dispose();
3562 3781
3563 RemoveFromPhysicalScene(); 3782 RemoveFromPhysicalScene();
3783
3784 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
3785
3786// if (Animator != null)
3787// Animator.Close();
3788 Animator = null;
3789
3564 } 3790 }
3565 3791
3566 public void AddAttachment(SceneObjectGroup gobj) 3792 public void AddAttachment(SceneObjectGroup gobj)
@@ -3794,10 +4020,18 @@ namespace OpenSim.Region.Framework.Scenes
3794 4020
3795 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4021 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
3796 { 4022 {
4023 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4024 if (p == null)
4025 return;
4026
4027 ControllingClient.SendTakeControls(controls, false, false);
4028 ControllingClient.SendTakeControls(controls, true, false);
4029
3797 ScriptControllers obj = new ScriptControllers(); 4030 ScriptControllers obj = new ScriptControllers();
3798 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4031 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
3799 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4032 obj.eventControls = ScriptControlled.CONTROL_ZERO;
3800 4033
4034 obj.objectID = p.ParentGroup.UUID;
3801 obj.itemID = Script_item_UUID; 4035 obj.itemID = Script_item_UUID;
3802 if (pass_on == 0 && accept == 0) 4036 if (pass_on == 0 && accept == 0)
3803 { 4037 {
@@ -3846,6 +4080,21 @@ namespace OpenSim.Region.Framework.Scenes
3846 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4080 ControllingClient.SendTakeControls(int.MaxValue, false, false);
3847 } 4081 }
3848 4082
4083 private void UnRegisterSeatControls(UUID obj)
4084 {
4085 List<UUID> takers = new List<UUID>();
4086
4087 foreach (ScriptControllers c in scriptedcontrols.Values)
4088 {
4089 if (c.objectID == obj)
4090 takers.Add(c.itemID);
4091 }
4092 foreach (UUID t in takers)
4093 {
4094 UnRegisterControlEventsToScript(0, t);
4095 }
4096 }
4097
3849 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4098 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
3850 { 4099 {
3851 ScriptControllers takecontrols; 4100 ScriptControllers takecontrols;
@@ -4175,6 +4424,12 @@ namespace OpenSim.Region.Framework.Scenes
4175 4424
4176 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4425 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4177 { 4426 {
4427 string reason;
4428
4429 // Honor bans
4430 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4431 return;
4432
4178 SceneObjectGroup telehub = null; 4433 SceneObjectGroup telehub = null;
4179 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4434 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4180 { 4435 {
@@ -4214,11 +4469,206 @@ namespace OpenSim.Region.Framework.Scenes
4214 pos = land.LandData.UserLocation; 4469 pos = land.LandData.UserLocation;
4215 } 4470 }
4216 } 4471 }
4217 4472
4218 land.SendLandUpdateToClient(ControllingClient); 4473 land.SendLandUpdateToClient(ControllingClient);
4219 } 4474 }
4220 } 4475 }
4221 4476
4477 private DetectedObject CreateDetObject(SceneObjectPart obj)
4478 {
4479 DetectedObject detobj = new DetectedObject();
4480 detobj.keyUUID = obj.UUID;
4481 detobj.nameStr = obj.Name;
4482 detobj.ownerUUID = obj.OwnerID;
4483 detobj.posVector = obj.AbsolutePosition;
4484 detobj.rotQuat = obj.GetWorldRotation();
4485 detobj.velVector = obj.Velocity;
4486 detobj.colliderType = 0;
4487 detobj.groupUUID = obj.GroupID;
4488
4489 return detobj;
4490 }
4491
4492 private DetectedObject CreateDetObject(ScenePresence av)
4493 {
4494 DetectedObject detobj = new DetectedObject();
4495 detobj.keyUUID = av.UUID;
4496 detobj.nameStr = av.ControllingClient.Name;
4497 detobj.ownerUUID = av.UUID;
4498 detobj.posVector = av.AbsolutePosition;
4499 detobj.rotQuat = av.Rotation;
4500 detobj.velVector = av.Velocity;
4501 detobj.colliderType = 0;
4502 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4503
4504 return detobj;
4505 }
4506
4507 private DetectedObject CreateDetObjectForGround()
4508 {
4509 DetectedObject detobj = new DetectedObject();
4510 detobj.keyUUID = UUID.Zero;
4511 detobj.nameStr = "";
4512 detobj.ownerUUID = UUID.Zero;
4513 detobj.posVector = AbsolutePosition;
4514 detobj.rotQuat = Quaternion.Identity;
4515 detobj.velVector = Vector3.Zero;
4516 detobj.colliderType = 0;
4517 detobj.groupUUID = UUID.Zero;
4518
4519 return detobj;
4520 }
4521
4522 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4523 {
4524 ColliderArgs colliderArgs = new ColliderArgs();
4525 List<DetectedObject> colliding = new List<DetectedObject>();
4526 foreach (uint localId in colliders)
4527 {
4528 if (localId == 0)
4529 continue;
4530
4531 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4532 if (obj != null)
4533 {
4534 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4535 colliding.Add(CreateDetObject(obj));
4536 }
4537 else
4538 {
4539 ScenePresence av = m_scene.GetScenePresence(localId);
4540 if (av != null && (!av.IsChildAgent))
4541 {
4542 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4543 colliding.Add(CreateDetObject(av));
4544 }
4545 }
4546 }
4547
4548 colliderArgs.Colliders = colliding;
4549
4550 return colliderArgs;
4551 }
4552
4553 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4554
4555 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4556 {
4557 ColliderArgs CollidingMessage;
4558
4559 if (colliders.Count > 0)
4560 {
4561 if ((dest.RootPart.ScriptEvents & ev) != 0)
4562 {
4563 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4564
4565 if (CollidingMessage.Colliders.Count > 0)
4566 notify(dest.RootPart.LocalId, CollidingMessage);
4567 }
4568 }
4569 }
4570
4571 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4572 {
4573 if ((dest.RootPart.ScriptEvents & ev) != 0)
4574 {
4575 ColliderArgs LandCollidingMessage = new ColliderArgs();
4576 List<DetectedObject> colliding = new List<DetectedObject>();
4577
4578 colliding.Add(CreateDetObjectForGround());
4579 LandCollidingMessage.Colliders = colliding;
4580
4581 notify(dest.RootPart.LocalId, LandCollidingMessage);
4582 }
4583 }
4584
4585 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
4586 {
4587 try
4588 {
4589 List<uint> thisHitColliders = new List<uint>();
4590 List<uint> endedColliders = new List<uint>();
4591 List<uint> startedColliders = new List<uint>();
4592 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
4593 CollisionForSoundInfo soundinfo;
4594 ContactPoint curcontact;
4595
4596 if (coldata.Count == 0)
4597 {
4598 if (m_lastColliders.Count == 0)
4599 return; // nothing to do
4600
4601 foreach (uint localID in m_lastColliders)
4602 {
4603 endedColliders.Add(localID);
4604 }
4605 m_lastColliders.Clear();
4606 }
4607
4608 else
4609 {
4610 foreach (uint id in coldata.Keys)
4611 {
4612 thisHitColliders.Add(id);
4613 if (!m_lastColliders.Contains(id))
4614 {
4615 startedColliders.Add(id);
4616 curcontact = coldata[id];
4617 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
4618 {
4619 soundinfo = new CollisionForSoundInfo();
4620 soundinfo.colliderID = id;
4621 soundinfo.position = curcontact.Position;
4622 soundinfo.relativeVel = curcontact.RelativeSpeed;
4623 soundinfolist.Add(soundinfo);
4624 }
4625 }
4626 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
4627 }
4628
4629 // calculate things that ended colliding
4630 foreach (uint localID in m_lastColliders)
4631 {
4632 if (!thisHitColliders.Contains(localID))
4633 {
4634 endedColliders.Add(localID);
4635 }
4636 }
4637 //add the items that started colliding this time to the last colliders list.
4638 foreach (uint localID in startedColliders)
4639 {
4640 m_lastColliders.Add(localID);
4641 }
4642 // remove things that ended colliding from the last colliders list
4643 foreach (uint localID in endedColliders)
4644 {
4645 m_lastColliders.Remove(localID);
4646 }
4647
4648 if (soundinfolist.Count > 0)
4649 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
4650 }
4651
4652 foreach (SceneObjectGroup att in GetAttachments())
4653 {
4654 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
4655 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
4656 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
4657
4658 if (startedColliders.Contains(0))
4659 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
4660 if (m_lastColliders.Contains(0))
4661 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
4662 if (endedColliders.Contains(0))
4663 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
4664 }
4665 }
4666 finally
4667 {
4668 m_collisionEventFlag = false;
4669 }
4670 }
4671
4222 private void TeleportFlagsDebug() { 4672 private void TeleportFlagsDebug() {
4223 4673
4224 // Some temporary debugging help to show all the TeleportFlags we have... 4674 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4243,6 +4693,5 @@ namespace OpenSim.Region.Framework.Scenes
4243 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4693 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4244 4694
4245 } 4695 }
4246
4247 } 4696 }
4248} 4697}