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.cs1107
1 files changed, 780 insertions, 327 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 7ed3a4b..3c749aa 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -65,6 +65,7 @@ namespace OpenSim.Region.Framework.Scenes
65 65
66 struct ScriptControllers 66 struct ScriptControllers
67 { 67 {
68 public UUID objectID;
68 public UUID itemID; 69 public UUID itemID;
69 public ScriptControlled ignoreControls; 70 public ScriptControlled ignoreControls;
70 public ScriptControlled eventControls; 71 public ScriptControlled eventControls;
@@ -120,7 +121,7 @@ namespace OpenSim.Region.Framework.Scenes
120 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 121 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
121 /// issue #1716 122 /// issue #1716
122 /// </summary> 123 /// </summary>
123 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 124 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
124 125
125 /// <summary> 126 /// <summary>
126 /// Movement updates for agents in neighboring regions are sent directly to clients. 127 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -142,8 +143,6 @@ namespace OpenSim.Region.Framework.Scenes
142 /// <remarks> 143 /// <remarks>
143 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 144 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
144 /// necessary. 145 /// necessary.
145 /// NOTE: To avoid deadlocks, do not lock m_attachments and then perform other tasks under that lock. Take a copy
146 /// of the list and act on that instead.
147 /// </remarks> 146 /// </remarks>
148 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 147 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
149 148
@@ -162,6 +161,10 @@ namespace OpenSim.Region.Framework.Scenes
162 private Vector3 m_lastPosition; 161 private Vector3 m_lastPosition;
163 private Quaternion m_lastRotation; 162 private Quaternion m_lastRotation;
164 private Vector3 m_lastVelocity; 163 private Vector3 m_lastVelocity;
164 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
165
166 private bool m_followCamAuto = false;
167
165 168
166 private Vector3? m_forceToApply; 169 private Vector3? m_forceToApply;
167 private int m_userFlags; 170 private int m_userFlags;
@@ -194,6 +197,7 @@ namespace OpenSim.Region.Framework.Scenes
194// private int m_lastColCount = -1; //KF: Look for Collision chnages 197// private int m_lastColCount = -1; //KF: Look for Collision chnages
195// private int m_updateCount = 0; //KF: Update Anims for a while 198// private int m_updateCount = 0; //KF: Update Anims for a while
196// private static readonly int UPDATE_COUNT = 10; // how many frames to update for 199// private static readonly int UPDATE_COUNT = 10; // how many frames to update for
200 private List<uint> m_lastColliders = new List<uint>();
197 201
198 private TeleportFlags m_teleportFlags; 202 private TeleportFlags m_teleportFlags;
199 public TeleportFlags TeleportFlags 203 public TeleportFlags TeleportFlags
@@ -249,8 +253,6 @@ namespace OpenSim.Region.Framework.Scenes
249 /// </summary> 253 /// </summary>
250 public bool LandAtTarget { get; private set; } 254 public bool LandAtTarget { get; private set; }
251 255
252 private bool m_followCamAuto;
253
254 private int m_movementUpdateCount; 256 private int m_movementUpdateCount;
255 private const int NumMovementsBetweenRayCast = 5; 257 private const int NumMovementsBetweenRayCast = 5;
256 258
@@ -258,6 +260,13 @@ namespace OpenSim.Region.Framework.Scenes
258 //private int m_moveToPositionStateStatus; 260 //private int m_moveToPositionStateStatus;
259 //***************************************************** 261 //*****************************************************
260 262
263 private bool m_collisionEventFlag = false;
264 private object m_collisionEventLock = new Object();
265
266 private int m_movementAnimationUpdateCounter = 0;
267
268 public Vector3 PrevSitOffset { get; set; }
269
261 protected AvatarAppearance m_appearance; 270 protected AvatarAppearance m_appearance;
262 271
263 public AvatarAppearance Appearance 272 public AvatarAppearance Appearance
@@ -397,6 +406,9 @@ namespace OpenSim.Region.Framework.Scenes
397 /// </summary> 406 /// </summary>
398 protected Vector3 m_lastCameraPosition; 407 protected Vector3 m_lastCameraPosition;
399 408
409 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
410 private bool m_doingCamRayCast = false;
411
400 public Vector3 CameraPosition { get; set; } 412 public Vector3 CameraPosition { get; set; }
401 413
402 public Quaternion CameraRotation 414 public Quaternion CameraRotation
@@ -477,6 +489,10 @@ namespace OpenSim.Region.Framework.Scenes
477 get { return (IClientCore)ControllingClient; } 489 get { return (IClientCore)ControllingClient; }
478 } 490 }
479 491
492 public UUID COF { get; set; }
493
494// public Vector3 ParentPosition { get; set; }
495
480 /// <summary> 496 /// <summary>
481 /// Position of this avatar relative to the region the avatar is in 497 /// Position of this avatar relative to the region the avatar is in
482 /// </summary> 498 /// </summary>
@@ -603,7 +619,24 @@ namespace OpenSim.Region.Framework.Scenes
603// Scene.RegionInfo.RegionName, Name, m_velocity); 619// Scene.RegionInfo.RegionName, Name, m_velocity);
604 } 620 }
605 } 621 }
622/*
623 public override Vector3 AngularVelocity
624 {
625 get
626 {
627 if (PhysicsActor != null)
628 {
629 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
630
631 // m_log.DebugFormat(
632 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
633 // m_velocity, Name, Scene.RegionInfo.RegionName);
634 }
606 635
636 return m_rotationalvelocity;
637 }
638 }
639*/
607 private Quaternion m_bodyRot = Quaternion.Identity; 640 private Quaternion m_bodyRot = Quaternion.Identity;
608 641
609 /// <summary> 642 /// <summary>
@@ -626,8 +659,16 @@ namespace OpenSim.Region.Framework.Scenes
626 m_bodyRot = value; 659 m_bodyRot = value;
627 660
628 if (PhysicsActor != null) 661 if (PhysicsActor != null)
629 PhysicsActor.Orientation = m_bodyRot; 662 {
630 663 try
664 {
665 PhysicsActor.Orientation = m_bodyRot;
666 }
667 catch (Exception e)
668 {
669 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
670 }
671 }
631// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 672// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
632 } 673 }
633 } 674 }
@@ -641,12 +682,20 @@ namespace OpenSim.Region.Framework.Scenes
641 } 682 }
642 683
643 public bool IsChildAgent { get; set; } 684 public bool IsChildAgent { get; set; }
685 public bool IsLoggingIn { get; set; }
644 686
645 /// <summary> 687 /// <summary>
646 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 688 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
647 /// </summary> 689 /// </summary>
648 public uint ParentID { get; set; } 690 public uint ParentID { get; set; }
649 691
692 public UUID ParentUUID
693 {
694 get { return m_parentUUID; }
695 set { m_parentUUID = value; }
696 }
697 private UUID m_parentUUID = UUID.Zero;
698
650 /// <summary> 699 /// <summary>
651 /// Are we sitting on an object? 700 /// Are we sitting on an object?
652 /// </summary> 701 /// </summary>
@@ -804,6 +853,7 @@ namespace OpenSim.Region.Framework.Scenes
804 AttachmentsSyncLock = new Object(); 853 AttachmentsSyncLock = new Object();
805 AllowMovement = true; 854 AllowMovement = true;
806 IsChildAgent = true; 855 IsChildAgent = true;
856 IsLoggingIn = false;
807 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 857 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
808 Animator = new ScenePresenceAnimator(this); 858 Animator = new ScenePresenceAnimator(this);
809 PresenceType = type; 859 PresenceType = type;
@@ -849,6 +899,33 @@ namespace OpenSim.Region.Framework.Scenes
849 m_stateMachine = new ScenePresenceStateMachine(this); 899 m_stateMachine = new ScenePresenceStateMachine(this);
850 } 900 }
851 901
902 private void RegionHeartbeatEnd(Scene scene)
903 {
904 if (IsChildAgent)
905 return;
906
907 m_movementAnimationUpdateCounter ++;
908 if (m_movementAnimationUpdateCounter >= 2)
909 {
910 m_movementAnimationUpdateCounter = 0;
911 if (Animator != null)
912 {
913 // If the parentID == 0 we are not sitting
914 // if !SitGournd then we are not sitting on the ground
915 // Fairly straightforward, now here comes the twist
916 // if ParentUUID is NOT UUID.Zero, we are looking to
917 // be sat on an object that isn't there yet. Should
918 // be treated as if sat.
919 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
920 Animator.UpdateMovementAnimations();
921 }
922 else
923 {
924 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
925 }
926 }
927 }
928
852 public void RegisterToEvents() 929 public void RegisterToEvents()
853 { 930 {
854 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 931 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -859,8 +936,10 @@ namespace OpenSim.Region.Framework.Scenes
859 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 936 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
860 ControllingClient.OnStartAnim += HandleStartAnim; 937 ControllingClient.OnStartAnim += HandleStartAnim;
861 ControllingClient.OnStopAnim += HandleStopAnim; 938 ControllingClient.OnStopAnim += HandleStopAnim;
939 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
862 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 940 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
863 ControllingClient.OnAutoPilotGo += MoveToTarget; 941 ControllingClient.OnAutoPilotGo += MoveToTarget;
942 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
864 943
865 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 944 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
866 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 945 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -919,6 +998,38 @@ namespace OpenSim.Region.Framework.Scenes
919// "[SCENE]: Upgrading child to root agent for {0} in {1}", 998// "[SCENE]: Upgrading child to root agent for {0} in {1}",
920// Name, m_scene.RegionInfo.RegionName); 999// Name, m_scene.RegionInfo.RegionName);
921 1000
1001 if (ParentUUID != UUID.Zero)
1002 {
1003 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1004 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1005 if (part == null)
1006 {
1007 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1008 }
1009 else
1010 {
1011 part.ParentGroup.AddAvatar(UUID);
1012 if (part.SitTargetPosition != Vector3.Zero)
1013 part.SitTargetAvatar = UUID;
1014// ParentPosition = part.GetWorldPosition();
1015 ParentID = part.LocalId;
1016 ParentPart = part;
1017 m_pos = PrevSitOffset;
1018// pos = ParentPosition;
1019 pos = part.GetWorldPosition();
1020 }
1021 ParentUUID = UUID.Zero;
1022
1023 IsChildAgent = false;
1024
1025// Animator.TrySetMovementAnimation("SIT");
1026 }
1027 else
1028 {
1029 IsChildAgent = false;
1030 IsLoggingIn = false;
1031 }
1032
922 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 1033 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
923 1034
924 IsChildAgent = false; 1035 IsChildAgent = false;
@@ -936,70 +1047,106 @@ namespace OpenSim.Region.Framework.Scenes
936 1047
937 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1048 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
938 1049
939 // Moved this from SendInitialData to ensure that Appearance is initialized 1050 UUID groupUUID = UUID.Zero;
940 // before the inventory is processed in MakeRootAgent. This fixes a race condition 1051 string GroupName = string.Empty;
941 // related to the handling of attachments 1052 ulong groupPowers = 0;
942 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
943 1053
944 if (m_scene.TestBorderCross(pos, Cardinals.E)) 1054 // ----------------------------------
1055 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1056 try
945 { 1057 {
946 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 1058 if (gm != null)
947 pos.X = crossedBorder.BorderLine.Z - 1; 1059 {
1060 groupUUID = ControllingClient.ActiveGroupId;
1061 GroupRecord record = gm.GetGroupRecord(groupUUID);
1062 if (record != null)
1063 GroupName = record.GroupName;
1064 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1065 if (groupMembershipData != null)
1066 groupPowers = groupMembershipData.GroupPowers;
1067 }
1068 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1069 Grouptitle);
948 } 1070 }
949 1071 catch (Exception e)
950 if (m_scene.TestBorderCross(pos, Cardinals.N))
951 { 1072 {
952 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1073 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
953 pos.Y = crossedBorder.BorderLine.Z - 1;
954 } 1074 }
1075 // ------------------------------------
955 1076
956 CheckAndAdjustLandingPoint(ref pos); 1077 if (ParentID == 0)
957
958 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
959 { 1078 {
960 m_log.WarnFormat( 1079 // Moved this from SendInitialData to ensure that Appearance is initialized
961 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1080 // before the inventory is processed in MakeRootAgent. This fixes a race condition
962 pos, Name, UUID); 1081 // related to the handling of attachments
1082 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1083 if (m_scene.TestBorderCross(pos, Cardinals.E))
1084 {
1085 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1086 pos.X = crossedBorder.BorderLine.Z - 1;
1087 }
963 1088
964 if (pos.X < 0f) pos.X = 0f; 1089 if (m_scene.TestBorderCross(pos, Cardinals.N))
965 if (pos.Y < 0f) pos.Y = 0f; 1090 {
966 if (pos.Z < 0f) pos.Z = 0f; 1091 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
967 } 1092 pos.Y = crossedBorder.BorderLine.Z - 1;
1093 }
968 1094
969 float localAVHeight = 1.56f; 1095 CheckAndAdjustLandingPoint(ref pos);
970 if (Appearance.AvatarHeight > 0)
971 localAVHeight = Appearance.AvatarHeight;
972 1096
973 float posZLimit = 0; 1097 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1098 {
1099 m_log.WarnFormat(
1100 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1101 pos, Name, UUID);
974 1102
975 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1103 if (pos.X < 0f) pos.X = 0f;
976 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1104 if (pos.Y < 0f) pos.Y = 0f;
977 1105 if (pos.Z < 0f) pos.Z = 0f;
978 float newPosZ = posZLimit + localAVHeight / 2; 1106 }
979 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
980 {
981 pos.Z = newPosZ;
982 }
983 AbsolutePosition = pos;
984 1107
985 AddToPhysicalScene(isFlying); 1108 float localAVHeight = 1.56f;
1109 if (Appearance.AvatarHeight > 0)
1110 localAVHeight = Appearance.AvatarHeight;
986 1111
987 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1112 float posZLimit = 0;
988 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
989 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
990 // the value to a negative position which does not trigger the border cross.
991 // This may not be the best location for this.
992 CheckForBorderCrossing();
993 1113
994 if (ForceFly) 1114 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
995 { 1115 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
996 Flying = true; 1116
997 } 1117 float newPosZ = posZLimit + localAVHeight / 2;
998 else if (FlyDisabled) 1118 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
999 { 1119 {
1000 Flying = false; 1120 pos.Z = newPosZ;
1001 } 1121 }
1122 AbsolutePosition = pos;
1002 1123
1124 if (m_teleportFlags == TeleportFlags.Default)
1125 {
1126 Vector3 vel = Velocity;
1127 AddToPhysicalScene(isFlying);
1128 if (PhysicsActor != null)
1129 PhysicsActor.SetMomentum(vel);
1130 }
1131 else
1132 AddToPhysicalScene(isFlying);
1133
1134 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1135 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1136 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1137 // the value to a negative position which does not trigger the border cross.
1138 // This may not be the best location for this.
1139 CheckForBorderCrossing();
1140
1141 if (ForceFly)
1142 {
1143 Flying = true;
1144 }
1145 else if (FlyDisabled)
1146 {
1147 Flying = false;
1148 }
1149 }
1003 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1150 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
1004 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1151 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1005 // elsewhere anyway 1152 // elsewhere anyway
@@ -1031,31 +1178,28 @@ namespace OpenSim.Region.Framework.Scenes
1031 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1178 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1032 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1179 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1033 // not transporting the required data. 1180 // not transporting the required data.
1034 // 1181 lock (m_attachments)
1035 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1036 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1037 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
1038 //
1039 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
1040 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1041 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1042 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1043 List<SceneObjectGroup> attachments = GetAttachments();
1044
1045 if (attachments.Count > 0)
1046 { 1182 {
1047 m_log.DebugFormat( 1183 if (HasAttachments())
1048 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1049
1050 // Resume scripts
1051 foreach (SceneObjectGroup sog in attachments)
1052 { 1184 {
1053 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1185 m_log.DebugFormat(
1054 sog.ResumeScripts(); 1186 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1187
1188 // Resume scripts
1189 Util.FireAndForget(delegate(object x) {
1190 foreach (SceneObjectGroup sog in m_attachments)
1191 {
1192 sog.ScheduleGroupForFullUpdate();
1193 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1194 sog.ResumeScripts();
1195 }
1196 });
1055 } 1197 }
1056 } 1198 }
1057 } 1199 }
1058 1200
1201 SendAvatarDataToAllAgents();
1202
1059 // send the animations of the other presences to me 1203 // send the animations of the other presences to me
1060 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1204 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1061 { 1205 {
@@ -1066,6 +1210,7 @@ namespace OpenSim.Region.Framework.Scenes
1066 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1210 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1067 // stall on the border crossing since the existing child agent will still have the last movement 1211 // stall on the border crossing since the existing child agent will still have the last movement
1068 // recorded, which stops the input from being processed. 1212 // recorded, which stops the input from being processed.
1213
1069 MovementFlag = 0; 1214 MovementFlag = 0;
1070 1215
1071 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1216 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -1097,12 +1242,16 @@ namespace OpenSim.Region.Framework.Scenes
1097 /// </remarks> 1242 /// </remarks>
1098 public void MakeChildAgent() 1243 public void MakeChildAgent()
1099 { 1244 {
1245 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1246
1100 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1247 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1101 1248
1102 // Reset these so that teleporting in and walking out isn't seen 1249 // Reset these so that teleporting in and walking out isn't seen
1103 // as teleporting back 1250 // as teleporting back
1104 TeleportFlags = TeleportFlags.Default; 1251 TeleportFlags = TeleportFlags.Default;
1105 1252
1253 MovementFlag = 0;
1254
1106 // It looks like Animator is set to null somewhere, and MakeChild 1255 // It looks like Animator is set to null somewhere, and MakeChild
1107 // is called after that. Probably in aborted teleports. 1256 // is called after that. Probably in aborted teleports.
1108 if (Animator == null) 1257 if (Animator == null)
@@ -1110,6 +1259,7 @@ namespace OpenSim.Region.Framework.Scenes
1110 else 1259 else
1111 Animator.ResetAnimations(); 1260 Animator.ResetAnimations();
1112 1261
1262
1113// m_log.DebugFormat( 1263// m_log.DebugFormat(
1114// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1264// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1115// Name, UUID, m_scene.RegionInfo.RegionName); 1265// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1121,6 +1271,7 @@ namespace OpenSim.Region.Framework.Scenes
1121 IsChildAgent = true; 1271 IsChildAgent = true;
1122 m_scene.SwapRootAgentCount(true); 1272 m_scene.SwapRootAgentCount(true);
1123 RemoveFromPhysicalScene(); 1273 RemoveFromPhysicalScene();
1274 ParentID = 0; // Child agents can't be sitting
1124 1275
1125 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1276 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1126 1277
@@ -1136,9 +1287,9 @@ namespace OpenSim.Region.Framework.Scenes
1136 { 1287 {
1137// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1288// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1138 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1289 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1139 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1140 PhysicsActor.UnSubscribeEvents();
1141 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1290 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1291 PhysicsActor.UnSubscribeEvents();
1292 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1142 PhysicsActor = null; 1293 PhysicsActor = null;
1143 } 1294 }
1144// else 1295// else
@@ -1155,7 +1306,7 @@ namespace OpenSim.Region.Framework.Scenes
1155 /// <param name="pos"></param> 1306 /// <param name="pos"></param>
1156 public void Teleport(Vector3 pos) 1307 public void Teleport(Vector3 pos)
1157 { 1308 {
1158 TeleportWithMomentum(pos, null); 1309 TeleportWithMomentum(pos, Vector3.Zero);
1159 } 1310 }
1160 1311
1161 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1312 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1179,6 +1330,41 @@ namespace OpenSim.Region.Framework.Scenes
1179 SendTerseUpdateToAllClients(); 1330 SendTerseUpdateToAllClients();
1180 } 1331 }
1181 1332
1333 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1334 {
1335 CheckLandingPoint(ref newpos);
1336 AbsolutePosition = newpos;
1337
1338 if (newvel.HasValue)
1339 {
1340 if ((Vector3)newvel == Vector3.Zero)
1341 {
1342 if (PhysicsActor != null)
1343 PhysicsActor.SetMomentum(Vector3.Zero);
1344 m_velocity = Vector3.Zero;
1345 }
1346 else
1347 {
1348 if (PhysicsActor != null)
1349 PhysicsActor.SetMomentum((Vector3)newvel);
1350 m_velocity = (Vector3)newvel;
1351
1352 if (rotateToVelXY)
1353 {
1354 Vector3 lookAt = (Vector3)newvel;
1355 lookAt.Z = 0;
1356 lookAt.Normalize();
1357 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1358 return;
1359 }
1360 }
1361 }
1362
1363 SendTerseUpdateToAllClients();
1364 }
1365
1366
1367
1182 public void StopFlying() 1368 public void StopFlying()
1183 { 1369 {
1184 Vector3 pos = AbsolutePosition; 1370 Vector3 pos = AbsolutePosition;
@@ -1367,6 +1553,13 @@ namespace OpenSim.Region.Framework.Scenes
1367 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1553 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1368 } 1554 }
1369 1555
1556 public void SetSize(Vector3 size, float feetoffset)
1557 {
1558 if (PhysicsActor != null && !IsChildAgent)
1559 PhysicsActor.setAvatarSize(size, feetoffset);
1560
1561 }
1562
1370 private bool WaitForUpdateAgent(IClientAPI client) 1563 private bool WaitForUpdateAgent(IClientAPI client)
1371 { 1564 {
1372 // Before the source region executes UpdateAgent 1565 // Before the source region executes UpdateAgent
@@ -1426,7 +1619,8 @@ namespace OpenSim.Region.Framework.Scenes
1426 1619
1427 Vector3 look = Velocity; 1620 Vector3 look = Velocity;
1428 1621
1429 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1622 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1623 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1430 { 1624 {
1431 look = new Vector3(0.99f, 0.042f, 0); 1625 look = new Vector3(0.99f, 0.042f, 0);
1432 } 1626 }
@@ -1489,11 +1683,12 @@ namespace OpenSim.Region.Framework.Scenes
1489 { 1683 {
1490 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1684 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1491 if (m_agentTransfer != null) 1685 if (m_agentTransfer != null)
1492 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1686 m_agentTransfer.EnableChildAgents(this);
1493 1687
1494 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1688 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1495 if (friendsModule != null) 1689 if (friendsModule != null)
1496 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1690 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1691
1497 } 1692 }
1498 1693
1499 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1694 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1519,36 +1714,69 @@ namespace OpenSim.Region.Framework.Scenes
1519 /// <param name="collisionPoint"></param> 1714 /// <param name="collisionPoint"></param>
1520 /// <param name="localid"></param> 1715 /// <param name="localid"></param>
1521 /// <param name="distance"></param> 1716 /// <param name="distance"></param>
1717 ///
1718
1719 private void UpdateCameraCollisionPlane(Vector4 plane)
1720 {
1721 if (m_lastCameraCollisionPlane != plane)
1722 {
1723 m_lastCameraCollisionPlane = plane;
1724 ControllingClient.SendCameraConstraint(plane);
1725 }
1726 }
1727
1522 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1728 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1523 { 1729 {
1524 const float POSITION_TOLERANCE = 0.02f; 1730 const float POSITION_TOLERANCE = 0.02f;
1525 const float VELOCITY_TOLERANCE = 0.02f;
1526 const float ROTATION_TOLERANCE = 0.02f; 1731 const float ROTATION_TOLERANCE = 0.02f;
1527 1732
1528 if (m_followCamAuto) 1733 m_doingCamRayCast = false;
1734 if (hitYN && localid != LocalId)
1529 { 1735 {
1530 if (hitYN) 1736 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1737 bool IsPrim = group != null;
1738 if (IsPrim)
1531 { 1739 {
1532 CameraConstraintActive = true; 1740 SceneObjectPart part = group.GetPart(localid);
1533 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1741 if (part != null && !part.VolumeDetectActive)
1534 1742 {
1535 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1743 CameraConstraintActive = true;
1536 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1744 pNormal.X = (float) Math.Round(pNormal.X, 2);
1745 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1746 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1747 pNormal.Normalize();
1748 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1749 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1750 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1751
1752 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1753 Vector3.Dot(collisionPoint, pNormal));
1754 UpdateCameraCollisionPlane(plane);
1755 }
1537 } 1756 }
1538 else 1757 else
1539 { 1758 {
1540 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1759 CameraConstraintActive = true;
1541 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1760 pNormal.X = (float) Math.Round(pNormal.X, 2);
1542 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1761 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1543 { 1762 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1544 if (CameraConstraintActive) 1763 pNormal.Normalize();
1545 { 1764 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1546 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1765 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1547 CameraConstraintActive = false; 1766 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1548 } 1767
1549 } 1768 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1769 Vector3.Dot(collisionPoint, pNormal));
1770 UpdateCameraCollisionPlane(plane);
1550 } 1771 }
1551 } 1772 }
1773 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1774 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1775 {
1776 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1777 UpdateCameraCollisionPlane(plane);
1778 CameraConstraintActive = false;
1779 }
1552 } 1780 }
1553 1781
1554 /// <summary> 1782 /// <summary>
@@ -1622,6 +1850,41 @@ namespace OpenSim.Region.Framework.Scenes
1622 StandUp(); 1850 StandUp();
1623 } 1851 }
1624 1852
1853 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1854 // this exclude checks may not be complete
1855
1856 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1857 {
1858 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1859 {
1860 Vector3 posAdjusted = AbsolutePosition;
1861// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1862 posAdjusted.Z += 1.0f; // viewer current camera focus point
1863 Vector3 tocam = CameraPosition - posAdjusted;
1864 tocam.X = (float)Math.Round(tocam.X, 1);
1865 tocam.Y = (float)Math.Round(tocam.Y, 1);
1866 tocam.Z = (float)Math.Round(tocam.Z, 1);
1867
1868 float distTocamlen = tocam.Length();
1869 if (distTocamlen > 0.3f)
1870 {
1871 tocam *= (1.0f / distTocamlen);
1872 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1873 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1874 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1875
1876 m_doingCamRayCast = true;
1877 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1878 }
1879 }
1880 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1881 {
1882 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1883 UpdateCameraCollisionPlane(plane);
1884 CameraConstraintActive = false;
1885 }
1886 }
1887
1625 uint flagsForScripts = (uint)flags; 1888 uint flagsForScripts = (uint)flags;
1626 flags = RemoveIgnoredControls(flags, IgnoredControls); 1889 flags = RemoveIgnoredControls(flags, IgnoredControls);
1627 1890
@@ -2180,7 +2443,8 @@ namespace OpenSim.Region.Framework.Scenes
2180// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2443// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2181 2444
2182 MovingToTarget = false; 2445 MovingToTarget = false;
2183 MoveToPositionTarget = Vector3.Zero; 2446// MoveToPositionTarget = Vector3.Zero;
2447 m_forceToApply = null; // cancel possible last action
2184 2448
2185 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2449 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
2186 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2450 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2203,6 +2467,9 @@ namespace OpenSim.Region.Framework.Scenes
2203 2467
2204 if (satOnObject) 2468 if (satOnObject)
2205 { 2469 {
2470 PrevSitOffset = m_pos; // Save sit offset
2471 UnRegisterSeatControls(part.ParentGroup.UUID);
2472
2206 TaskInventoryDictionary taskIDict = part.TaskInventory; 2473 TaskInventoryDictionary taskIDict = part.TaskInventory;
2207 if (taskIDict != null) 2474 if (taskIDict != null)
2208 { 2475 {
@@ -2218,6 +2485,7 @@ namespace OpenSim.Region.Framework.Scenes
2218 } 2485 }
2219 } 2486 }
2220 2487
2488 part.ParentGroup.DeleteAvatar(UUID);
2221 Vector3 sitPartWorldPosition = part.GetWorldPosition(); 2489 Vector3 sitPartWorldPosition = part.GetWorldPosition();
2222 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2490 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2223 2491
@@ -2278,6 +2546,9 @@ namespace OpenSim.Region.Framework.Scenes
2278 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2546 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2279 } 2547 }
2280 2548
2549 else if (PhysicsActor == null)
2550 AddToPhysicalScene(false);
2551
2281 Animator.TrySetMovementAnimation("STAND"); 2552 Animator.TrySetMovementAnimation("STAND");
2282 TriggerScenePresenceUpdated(); 2553 TriggerScenePresenceUpdated();
2283 } 2554 }
@@ -2326,11 +2597,8 @@ namespace OpenSim.Region.Framework.Scenes
2326 if (part == null) 2597 if (part == null)
2327 return; 2598 return;
2328 2599
2329 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2330 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2331
2332 if (PhysicsActor != null) 2600 if (PhysicsActor != null)
2333 m_sitAvatarHeight = PhysicsActor.Size.Z; 2601 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2334 2602
2335 bool canSit = false; 2603 bool canSit = false;
2336 2604
@@ -2357,33 +2625,32 @@ namespace OpenSim.Region.Framework.Scenes
2357 } 2625 }
2358 else 2626 else
2359 { 2627 {
2628 if (PhysicsSit(part,offset)) // physics engine
2629 return;
2630
2360 Vector3 pos = part.AbsolutePosition + offset; 2631 Vector3 pos = part.AbsolutePosition + offset;
2361 2632
2362 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2633 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2363 { 2634 {
2364// m_log.DebugFormat(
2365// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2366// Name, part.Name, part.LocalId);
2367
2368 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2635 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2369 canSit = true; 2636 canSit = true;
2370 } 2637 }
2371// else
2372// {
2373// m_log.DebugFormat(
2374// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2375// Name, part.Name, part.LocalId);
2376// }
2377 } 2638 }
2378 2639
2379 if (canSit) 2640 if (canSit)
2380 { 2641 {
2642
2381 if (PhysicsActor != null) 2643 if (PhysicsActor != null)
2382 { 2644 {
2383 // We can remove the physicsActor until they stand up. 2645 // We can remove the physicsActor until they stand up.
2384 RemoveFromPhysicalScene(); 2646 RemoveFromPhysicalScene();
2385 } 2647 }
2386 2648
2649 if (MovingToTarget)
2650 ResetMoveToTarget();
2651
2652 Velocity = Vector3.Zero;
2653
2387 part.AddSittingAvatar(UUID); 2654 part.AddSittingAvatar(UUID);
2388 2655
2389 cameraAtOffset = part.GetCameraAtOffset(); 2656 cameraAtOffset = part.GetCameraAtOffset();
@@ -2427,14 +2694,6 @@ namespace OpenSim.Region.Framework.Scenes
2427 m_requestedSitTargetID = part.LocalId; 2694 m_requestedSitTargetID = part.LocalId;
2428 m_requestedSitTargetUUID = part.UUID; 2695 m_requestedSitTargetUUID = part.UUID;
2429 2696
2430// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2431
2432 if (m_scene.PhysicsScene.SupportsRayCast())
2433 {
2434 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2435 //SitRayCastAvatarPosition(part);
2436 //return;
2437 }
2438 } 2697 }
2439 else 2698 else
2440 { 2699 {
@@ -2444,197 +2703,111 @@ namespace OpenSim.Region.Framework.Scenes
2444 SendSitResponse(targetID, offset, Quaternion.Identity); 2703 SendSitResponse(targetID, offset, Quaternion.Identity);
2445 } 2704 }
2446 2705
2447 /* 2706 // returns false if does not suport so older sit can be tried
2448 public void SitRayCastAvatarPosition(SceneObjectPart part) 2707 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2449 { 2708 {
2450 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2709 if (part == null || part.ParentGroup.IsAttachment)
2451 Vector3 StartRayCastPosition = AbsolutePosition;
2452 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2453 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2454 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2455 }
2456
2457 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2458 {
2459 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2460 if (part != null)
2461 {
2462 if (hitYN)
2463 {
2464 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2465 {
2466 SitRaycastFindEdge(collisionPoint, normal);
2467 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2468 }
2469 else
2470 {
2471 SitRayCastAvatarPositionCameraZ(part);
2472 }
2473 }
2474 else
2475 {
2476 SitRayCastAvatarPositionCameraZ(part);
2477 }
2478 }
2479 else
2480 { 2710 {
2481 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2711 return true;
2482 m_requestedSitTargetUUID = UUID.Zero;
2483 m_requestedSitTargetID = 0;
2484 m_requestedSitOffset = Vector3.Zero;
2485 } 2712 }
2486 2713
2487 } 2714 if ( m_scene.PhysicsScene == null)
2488 2715 return false;
2489 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2490 {
2491 // Next, try to raycast from the camera Z position
2492 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2493 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2494 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2495 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2496 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2497 }
2498 2716
2499 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2717 if (part.PhysActor == null)
2500 {
2501 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2502 if (part != null)
2503 { 2718 {
2504 if (hitYN) 2719 // none physcis shape
2505 { 2720 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2506 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2721 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2507 {
2508 SitRaycastFindEdge(collisionPoint, normal);
2509 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2510 }
2511 else
2512 {
2513 SitRayCastCameraPosition(part);
2514 }
2515 }
2516 else 2722 else
2517 { 2723 { // non physical phantom TODO
2518 SitRayCastCameraPosition(part); 2724 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2725 return false;
2519 } 2726 }
2520 } 2727 return true;
2521 else
2522 {
2523 ControllingClient.SendAlertMessage("Sit position no longer exists");
2524 m_requestedSitTargetUUID = UUID.Zero;
2525 m_requestedSitTargetID = 0;
2526 m_requestedSitOffset = Vector3.Zero;
2527 } 2728 }
2528 2729
2529 }
2530 2730
2531 public void SitRayCastCameraPosition(SceneObjectPart part) 2731 // not doing autopilot
2532 { 2732 m_requestedSitTargetID = 0;
2533 // Next, try to raycast from the camera position
2534 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2535 Vector3 StartRayCastPosition = CameraPosition;
2536 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2537 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2538 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2539 }
2540 2733
2541 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2734 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2542 { 2735 return true;
2543 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2544 if (part != null)
2545 {
2546 if (hitYN)
2547 {
2548 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2549 {
2550 SitRaycastFindEdge(collisionPoint, normal);
2551 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2552 }
2553 else
2554 {
2555 SitRayHorizontal(part);
2556 }
2557 }
2558 else
2559 {
2560 SitRayHorizontal(part);
2561 }
2562 }
2563 else
2564 {
2565 ControllingClient.SendAlertMessage("Sit position no longer exists");
2566 m_requestedSitTargetUUID = UUID.Zero;
2567 m_requestedSitTargetID = 0;
2568 m_requestedSitOffset = Vector3.Zero;
2569 }
2570 2736
2737 return false;
2571 } 2738 }
2572 2739
2573 public void SitRayHorizontal(SceneObjectPart part) 2740
2741 private bool CanEnterLandPosition(Vector3 testPos)
2574 { 2742 {
2575 // Next, try to raycast from the avatar position to fwd 2743 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2576 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2744
2577 Vector3 StartRayCastPosition = CameraPosition; 2745 if (land == null || land.LandData.Name == "NO_LAND")
2578 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2746 return true;
2579 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2747
2580 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2748 return land.CanBeOnThisLand(UUID,testPos.Z);
2581 } 2749 }
2582 2750
2583 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2751 // status
2752 // < 0 ignore
2753 // 0 bad sit spot
2754 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2584 { 2755 {
2585 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2756 if (status < 0)
2586 if (part != null) 2757 return;
2758
2759 if (status == 0)
2587 { 2760 {
2588 if (hitYN) 2761 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2589 { 2762 return;
2590 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2591 {
2592 SitRaycastFindEdge(collisionPoint, normal);
2593 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2594 // Next, try to raycast from the camera position
2595 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2596 Vector3 StartRayCastPosition = CameraPosition;
2597 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2598 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2599 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2600 }
2601 else
2602 {
2603 ControllingClient.SendAlertMessage("Sit position not accessable.");
2604 m_requestedSitTargetUUID = UUID.Zero;
2605 m_requestedSitTargetID = 0;
2606 m_requestedSitOffset = Vector3.Zero;
2607 }
2608 }
2609 else
2610 {
2611 ControllingClient.SendAlertMessage("Sit position not accessable.");
2612 m_requestedSitTargetUUID = UUID.Zero;
2613 m_requestedSitTargetID = 0;
2614 m_requestedSitOffset = Vector3.Zero;
2615 }
2616 } 2763 }
2617 else 2764
2765 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2766 if (part == null)
2767 return;
2768
2769 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2770 if(!CanEnterLandPosition(targetPos))
2618 { 2771 {
2619 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2772 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2620 m_requestedSitTargetUUID = UUID.Zero; 2773 return;
2621 m_requestedSitTargetID = 0;
2622 m_requestedSitOffset = Vector3.Zero;
2623 } 2774 }
2624 2775
2625 } 2776 RemoveFromPhysicalScene();
2626 2777
2627 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2778 if (MovingToTarget)
2628 { 2779 ResetMoveToTarget();
2629 int i = 0; 2780
2630 //throw new NotImplementedException(); 2781 Velocity = Vector3.Zero;
2631 //m_requestedSitTargetUUID = UUID.Zero;
2632 //m_requestedSitTargetID = 0;
2633 //m_requestedSitOffset = Vector3.Zero;
2634 2782
2635 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2783 part.AddSittingAvatar(UUID);
2784
2785 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2786 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2787 bool forceMouselook = part.GetForceMouselook();
2788
2789 ControllingClient.SendSitResponse(
2790 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2791
2792 // not using autopilot
2793
2794 Rotation = Orientation;
2795 m_pos = offset;
2796
2797 m_requestedSitTargetID = 0;
2798 part.ParentGroup.AddAvatar(UUID);
2799
2800 ParentPart = part;
2801 ParentID = part.LocalId;
2802 if(status == 3)
2803 Animator.TrySetMovementAnimation("SIT_GROUND");
2804 else
2805 Animator.TrySetMovementAnimation("SIT");
2806 SendAvatarDataToAllAgents();
2807
2808 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2636 } 2809 }
2637 */ 2810
2638 2811
2639 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2812 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2640 { 2813 {
@@ -2654,6 +2827,7 @@ namespace OpenSim.Region.Framework.Scenes
2654 return; 2827 return;
2655 } 2828 }
2656 2829
2830
2657 if (part.SitTargetAvatar == UUID) 2831 if (part.SitTargetAvatar == UUID)
2658 { 2832 {
2659 Vector3 sitTargetPos = part.SitTargetPosition; 2833 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2668,29 +2842,39 @@ namespace OpenSim.Region.Framework.Scenes
2668 2842
2669 //Quaternion result = (sitTargetOrient * vq) * nq; 2843 //Quaternion result = (sitTargetOrient * vq) * nq;
2670 2844
2671 Vector3 newPos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2845 double x, y, z, m;
2672 Quaternion newRot;
2673 2846
2674 if (part.IsRoot) 2847 Quaternion r = sitTargetOrient;
2675 { 2848 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2676 newRot = sitTargetOrient; 2849
2677 } 2850 if (Math.Abs(1.0 - m) > 0.000001)
2678 else
2679 { 2851 {
2680 newPos = newPos * part.RotationOffset; 2852 m = 1.0 / Math.Sqrt(m);
2681 newRot = part.RotationOffset * sitTargetOrient; 2853 r.X *= (float)m;
2854 r.Y *= (float)m;
2855 r.Z *= (float)m;
2856 r.W *= (float)m;
2682 } 2857 }
2683 2858
2684 newPos += part.OffsetPosition; 2859 x = 2 * (r.X * r.Z + r.Y * r.W);
2860 y = 2 * (-r.X * r.W + r.Y * r.Z);
2861 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2862
2863 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2864 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2865
2866 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2685 2867
2686 m_pos = newPos; 2868// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2687 Rotation = newRot; 2869 Rotation = sitTargetOrient;
2870// ParentPosition = part.AbsolutePosition;
2871 part.ParentGroup.AddAvatar(UUID);
2688 } 2872 }
2689 else 2873 else
2690 { 2874 {
2691 // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is 2875 m_pos -= part.AbsolutePosition;
2692 // being sat upon. 2876// ParentPosition = part.AbsolutePosition;
2693 m_pos -= part.GroupPosition; 2877 part.ParentGroup.AddAvatar(UUID);
2694 2878
2695// m_log.DebugFormat( 2879// m_log.DebugFormat(
2696// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2880// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2748,6 +2932,13 @@ namespace OpenSim.Region.Framework.Scenes
2748 TriggerScenePresenceUpdated(); 2932 TriggerScenePresenceUpdated();
2749 } 2933 }
2750 2934
2935 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
2936 {
2937 Animator.avnChangeAnim(animID, addRemove, sendPack);
2938 }
2939
2940
2941
2751 /// <summary> 2942 /// <summary>
2752 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2943 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2753 /// </summary> 2944 /// </summary>
@@ -2807,8 +2998,8 @@ namespace OpenSim.Region.Framework.Scenes
2807 direc.Z *= 2.6f; 2998 direc.Z *= 2.6f;
2808 2999
2809 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 3000 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2810 Animator.TrySetMovementAnimation("PREJUMP"); 3001// Animator.TrySetMovementAnimation("PREJUMP");
2811 Animator.TrySetMovementAnimation("JUMP"); 3002// Animator.TrySetMovementAnimation("JUMP");
2812 } 3003 }
2813 } 3004 }
2814 } 3005 }
@@ -2817,6 +3008,7 @@ namespace OpenSim.Region.Framework.Scenes
2817 3008
2818 // TODO: Add the force instead of only setting it to support multiple forces per frame? 3009 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2819 m_forceToApply = direc; 3010 m_forceToApply = direc;
3011 Animator.UpdateMovementAnimations();
2820 } 3012 }
2821 3013
2822 #endregion 3014 #endregion
@@ -2834,16 +3026,12 @@ namespace OpenSim.Region.Framework.Scenes
2834 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 3026 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2835 // grab the latest PhysicsActor velocity, whereas m_velocity is often 3027 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2836 // storing a requested force instead of an actual traveling velocity 3028 // storing a requested force instead of an actual traveling velocity
3029 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
3030 SendAvatarDataToAllAgents();
2837 3031
2838 // Throw away duplicate or insignificant updates 3032 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2839 if ( 3033 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2840 // If the velocity has become zero, send it no matter what. 3034 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2841 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2842 // otherwise, if things have changed reasonably, send the update
2843 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2844 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2845 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2846
2847 { 3035 {
2848 SendTerseUpdateToAllClients(); 3036 SendTerseUpdateToAllClients();
2849 3037
@@ -3003,9 +3191,7 @@ namespace OpenSim.Region.Framework.Scenes
3003 // again here... this comes after the cached appearance check because the avatars 3191 // again here... this comes after the cached appearance check because the avatars
3004 // appearance goes into the avatar update packet 3192 // appearance goes into the avatar update packet
3005 SendAvatarDataToAllAgents(); 3193 SendAvatarDataToAllAgents();
3006 3194 SendAppearanceToAgent(this);
3007 // This invocation always shows up in the viewer logs as an error.
3008 // SendAppearanceToAgent(this);
3009 3195
3010 // If we are using the the cached appearance then send it out to everyone 3196 // If we are using the the cached appearance then send it out to everyone
3011 if (cachedappearance) 3197 if (cachedappearance)
@@ -3036,6 +3222,8 @@ namespace OpenSim.Region.Framework.Scenes
3036 return; 3222 return;
3037 } 3223 }
3038 3224
3225 m_lastSize = Appearance.AvatarSize;
3226
3039 int count = 0; 3227 int count = 0;
3040 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 3228 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3041 { 3229 {
@@ -3143,6 +3331,8 @@ namespace OpenSim.Region.Framework.Scenes
3143 3331
3144 avatar.ControllingClient.SendAppearance( 3332 avatar.ControllingClient.SendAppearance(
3145 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3333 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3334
3335
3146 } 3336 }
3147 3337
3148 #endregion 3338 #endregion
@@ -3216,8 +3406,9 @@ namespace OpenSim.Region.Framework.Scenes
3216 3406
3217 // If we don't have a PhysActor, we can't cross anyway 3407 // If we don't have a PhysActor, we can't cross anyway
3218 // Also don't do this while sat, sitting avatars cross with the 3408 // Also don't do this while sat, sitting avatars cross with the
3219 // object they sit on. 3409 // object they sit on. ParentUUID denoted a pending sit, don't
3220 if (ParentID != 0 || PhysicsActor == null) 3410 // interfere with it.
3411 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3221 return; 3412 return;
3222 3413
3223 if (!IsInTransit) 3414 if (!IsInTransit)
@@ -3480,6 +3671,11 @@ namespace OpenSim.Region.Framework.Scenes
3480 3671
3481 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3672 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3482 3673
3674 private void RaiseUpdateThrottles()
3675 {
3676 m_scene.EventManager.TriggerThrottleUpdate(this);
3677 }
3678
3483 /// <summary> 3679 /// <summary>
3484 /// This updates important decision making data about a child agent 3680 /// This updates important decision making data about a child agent
3485 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3681 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3561,6 +3757,9 @@ namespace OpenSim.Region.Framework.Scenes
3561 cAgent.AlwaysRun = SetAlwaysRun; 3757 cAgent.AlwaysRun = SetAlwaysRun;
3562 3758
3563 cAgent.Appearance = new AvatarAppearance(Appearance); 3759 cAgent.Appearance = new AvatarAppearance(Appearance);
3760
3761 cAgent.ParentPart = ParentUUID;
3762 cAgent.SitOffset = PrevSitOffset;
3564 3763
3565 lock (scriptedcontrols) 3764 lock (scriptedcontrols)
3566 { 3765 {
@@ -3569,7 +3768,7 @@ namespace OpenSim.Region.Framework.Scenes
3569 3768
3570 foreach (ScriptControllers c in scriptedcontrols.Values) 3769 foreach (ScriptControllers c in scriptedcontrols.Values)
3571 { 3770 {
3572 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3771 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3573 } 3772 }
3574 cAgent.Controllers = controls; 3773 cAgent.Controllers = controls;
3575 } 3774 }
@@ -3603,6 +3802,8 @@ namespace OpenSim.Region.Framework.Scenes
3603 CameraAtAxis = cAgent.AtAxis; 3802 CameraAtAxis = cAgent.AtAxis;
3604 CameraLeftAxis = cAgent.LeftAxis; 3803 CameraLeftAxis = cAgent.LeftAxis;
3605 CameraUpAxis = cAgent.UpAxis; 3804 CameraUpAxis = cAgent.UpAxis;
3805 ParentUUID = cAgent.ParentPart;
3806 PrevSitOffset = cAgent.SitOffset;
3606 3807
3607 // When we get to the point of re-computing neighbors everytime this 3808 // When we get to the point of re-computing neighbors everytime this
3608 // changes, then start using the agent's drawdistance rather than the 3809 // changes, then start using the agent's drawdistance rather than the
@@ -3640,6 +3841,7 @@ namespace OpenSim.Region.Framework.Scenes
3640 foreach (ControllerData c in cAgent.Controllers) 3841 foreach (ControllerData c in cAgent.Controllers)
3641 { 3842 {
3642 ScriptControllers sc = new ScriptControllers(); 3843 ScriptControllers sc = new ScriptControllers();
3844 sc.objectID = c.ObjectID;
3643 sc.itemID = c.ItemID; 3845 sc.itemID = c.ItemID;
3644 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3846 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3645 sc.eventControls = (ScriptControlled)c.EventControls; 3847 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3705,20 +3907,27 @@ namespace OpenSim.Region.Framework.Scenes
3705 } 3907 }
3706 3908
3707 if (Appearance.AvatarHeight == 0) 3909 if (Appearance.AvatarHeight == 0)
3708 Appearance.SetHeight(); 3910// Appearance.SetHeight();
3911 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3709 3912
3710 PhysicsScene scene = m_scene.PhysicsScene; 3913 PhysicsScene scene = m_scene.PhysicsScene;
3711 3914
3712 Vector3 pVec = AbsolutePosition; 3915 Vector3 pVec = AbsolutePosition;
3713 3916
3917/*
3714 PhysicsActor = scene.AddAvatar( 3918 PhysicsActor = scene.AddAvatar(
3715 LocalId, Firstname + "." + Lastname, pVec, 3919 LocalId, Firstname + "." + Lastname, pVec,
3716 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3920 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3921*/
3922
3923 PhysicsActor = scene.AddAvatar(
3924 LocalId, Firstname + "." + Lastname, pVec,
3925 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
3717 3926
3718 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3927 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3719 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3928 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3720 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3929 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3721 PhysicsActor.SubscribeEvents(500); 3930 PhysicsActor.SubscribeEvents(100);
3722 PhysicsActor.LocalID = LocalId; 3931 PhysicsActor.LocalID = LocalId;
3723 } 3932 }
3724 3933
@@ -3732,6 +3941,7 @@ namespace OpenSim.Region.Framework.Scenes
3732 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3941 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3733 } 3942 }
3734 3943
3944
3735 /// <summary> 3945 /// <summary>
3736 /// Event called by the physics plugin to tell the avatar about a collision. 3946 /// Event called by the physics plugin to tell the avatar about a collision.
3737 /// </summary> 3947 /// </summary>
@@ -3745,7 +3955,7 @@ namespace OpenSim.Region.Framework.Scenes
3745 /// <param name="e"></param> 3955 /// <param name="e"></param>
3746 public void PhysicsCollisionUpdate(EventArgs e) 3956 public void PhysicsCollisionUpdate(EventArgs e)
3747 { 3957 {
3748 if (IsChildAgent) 3958 if (IsChildAgent || Animator == null)
3749 return; 3959 return;
3750 3960
3751 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3961 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3762,7 +3972,6 @@ namespace OpenSim.Region.Framework.Scenes
3762 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3972 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3763 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3973 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3764 3974
3765 CollisionPlane = Vector4.UnitW;
3766 3975
3767// // No collisions at all means we may be flying. Update always 3976// // No collisions at all means we may be flying. Update always
3768// // to make falling work 3977// // to make falling work
@@ -3774,6 +3983,7 @@ namespace OpenSim.Region.Framework.Scenes
3774 3983
3775 if (coldata.Count != 0) 3984 if (coldata.Count != 0)
3776 { 3985 {
3986/*
3777 switch (Animator.CurrentMovementAnimation) 3987 switch (Animator.CurrentMovementAnimation)
3778 { 3988 {
3779 case "STAND": 3989 case "STAND":
@@ -3782,24 +3992,38 @@ namespace OpenSim.Region.Framework.Scenes
3782 case "CROUCH": 3992 case "CROUCH":
3783 case "CROUCHWALK": 3993 case "CROUCHWALK":
3784 { 3994 {
3995 */
3785 ContactPoint lowest; 3996 ContactPoint lowest;
3786 lowest.SurfaceNormal = Vector3.Zero; 3997 lowest.SurfaceNormal = Vector3.Zero;
3787 lowest.Position = Vector3.Zero; 3998 lowest.Position = Vector3.Zero;
3788 lowest.Position.Z = Single.NaN; 3999 lowest.Position.Z = float.MaxValue;
3789 4000
3790 foreach (ContactPoint contact in coldata.Values) 4001 foreach (ContactPoint contact in coldata.Values)
3791 { 4002 {
3792 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 4003
4004 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3793 { 4005 {
3794 lowest = contact; 4006 lowest = contact;
3795 } 4007 }
3796 } 4008 }
3797 4009
3798 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 4010 if (lowest.Position.Z != float.MaxValue)
4011 {
4012 lowest.SurfaceNormal = -lowest.SurfaceNormal;
4013 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
4014 }
4015 else
4016 CollisionPlane = Vector4.UnitW;
4017/*
3799 } 4018 }
3800 break; 4019 break;
3801 } 4020 }
4021*/
3802 } 4022 }
4023 else
4024 CollisionPlane = Vector4.UnitW;
4025
4026 RaiseCollisionScriptEvents(coldata);
3803 4027
3804 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 4028 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3805 if (Invulnerable || GodLevel > 0) 4029 if (Invulnerable || GodLevel > 0)
@@ -3898,6 +4122,12 @@ namespace OpenSim.Region.Framework.Scenes
3898 // m_reprioritizationTimer.Dispose(); 4122 // m_reprioritizationTimer.Dispose();
3899 4123
3900 RemoveFromPhysicalScene(); 4124 RemoveFromPhysicalScene();
4125
4126 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
4127
4128// if (Animator != null)
4129// Animator.Close();
4130 Animator = null;
3901 4131
3902 LifecycleState = ScenePresenceState.Removed; 4132 LifecycleState = ScenePresenceState.Removed;
3903 } 4133 }
@@ -4133,10 +4363,18 @@ namespace OpenSim.Region.Framework.Scenes
4133 4363
4134 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4364 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
4135 { 4365 {
4366 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4367 if (p == null)
4368 return;
4369
4370 ControllingClient.SendTakeControls(controls, false, false);
4371 ControllingClient.SendTakeControls(controls, true, false);
4372
4136 ScriptControllers obj = new ScriptControllers(); 4373 ScriptControllers obj = new ScriptControllers();
4137 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4374 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4138 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4375 obj.eventControls = ScriptControlled.CONTROL_ZERO;
4139 4376
4377 obj.objectID = p.ParentGroup.UUID;
4140 obj.itemID = Script_item_UUID; 4378 obj.itemID = Script_item_UUID;
4141 if (pass_on == 0 && accept == 0) 4379 if (pass_on == 0 && accept == 0)
4142 { 4380 {
@@ -4185,6 +4423,21 @@ namespace OpenSim.Region.Framework.Scenes
4185 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4423 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4186 } 4424 }
4187 4425
4426 private void UnRegisterSeatControls(UUID obj)
4427 {
4428 List<UUID> takers = new List<UUID>();
4429
4430 foreach (ScriptControllers c in scriptedcontrols.Values)
4431 {
4432 if (c.objectID == obj)
4433 takers.Add(c.itemID);
4434 }
4435 foreach (UUID t in takers)
4436 {
4437 UnRegisterControlEventsToScript(0, t);
4438 }
4439 }
4440
4188 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4441 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4189 { 4442 {
4190 ScriptControllers takecontrols; 4443 ScriptControllers takecontrols;
@@ -4514,6 +4767,12 @@ namespace OpenSim.Region.Framework.Scenes
4514 4767
4515 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4768 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4516 { 4769 {
4770 string reason;
4771
4772 // Honor bans
4773 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4774 return;
4775
4517 SceneObjectGroup telehub = null; 4776 SceneObjectGroup telehub = null;
4518 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4777 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4519 { 4778 {
@@ -4553,11 +4812,206 @@ namespace OpenSim.Region.Framework.Scenes
4553 pos = land.LandData.UserLocation; 4812 pos = land.LandData.UserLocation;
4554 } 4813 }
4555 } 4814 }
4556 4815
4557 land.SendLandUpdateToClient(ControllingClient); 4816 land.SendLandUpdateToClient(ControllingClient);
4558 } 4817 }
4559 } 4818 }
4560 4819
4820 private DetectedObject CreateDetObject(SceneObjectPart obj)
4821 {
4822 DetectedObject detobj = new DetectedObject();
4823 detobj.keyUUID = obj.UUID;
4824 detobj.nameStr = obj.Name;
4825 detobj.ownerUUID = obj.OwnerID;
4826 detobj.posVector = obj.AbsolutePosition;
4827 detobj.rotQuat = obj.GetWorldRotation();
4828 detobj.velVector = obj.Velocity;
4829 detobj.colliderType = 0;
4830 detobj.groupUUID = obj.GroupID;
4831
4832 return detobj;
4833 }
4834
4835 private DetectedObject CreateDetObject(ScenePresence av)
4836 {
4837 DetectedObject detobj = new DetectedObject();
4838 detobj.keyUUID = av.UUID;
4839 detobj.nameStr = av.ControllingClient.Name;
4840 detobj.ownerUUID = av.UUID;
4841 detobj.posVector = av.AbsolutePosition;
4842 detobj.rotQuat = av.Rotation;
4843 detobj.velVector = av.Velocity;
4844 detobj.colliderType = 0;
4845 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4846
4847 return detobj;
4848 }
4849
4850 private DetectedObject CreateDetObjectForGround()
4851 {
4852 DetectedObject detobj = new DetectedObject();
4853 detobj.keyUUID = UUID.Zero;
4854 detobj.nameStr = "";
4855 detobj.ownerUUID = UUID.Zero;
4856 detobj.posVector = AbsolutePosition;
4857 detobj.rotQuat = Quaternion.Identity;
4858 detobj.velVector = Vector3.Zero;
4859 detobj.colliderType = 0;
4860 detobj.groupUUID = UUID.Zero;
4861
4862 return detobj;
4863 }
4864
4865 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4866 {
4867 ColliderArgs colliderArgs = new ColliderArgs();
4868 List<DetectedObject> colliding = new List<DetectedObject>();
4869 foreach (uint localId in colliders)
4870 {
4871 if (localId == 0)
4872 continue;
4873
4874 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4875 if (obj != null)
4876 {
4877 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4878 colliding.Add(CreateDetObject(obj));
4879 }
4880 else
4881 {
4882 ScenePresence av = m_scene.GetScenePresence(localId);
4883 if (av != null && (!av.IsChildAgent))
4884 {
4885 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4886 colliding.Add(CreateDetObject(av));
4887 }
4888 }
4889 }
4890
4891 colliderArgs.Colliders = colliding;
4892
4893 return colliderArgs;
4894 }
4895
4896 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4897
4898 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4899 {
4900 ColliderArgs CollidingMessage;
4901
4902 if (colliders.Count > 0)
4903 {
4904 if ((dest.RootPart.ScriptEvents & ev) != 0)
4905 {
4906 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4907
4908 if (CollidingMessage.Colliders.Count > 0)
4909 notify(dest.RootPart.LocalId, CollidingMessage);
4910 }
4911 }
4912 }
4913
4914 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4915 {
4916 if ((dest.RootPart.ScriptEvents & ev) != 0)
4917 {
4918 ColliderArgs LandCollidingMessage = new ColliderArgs();
4919 List<DetectedObject> colliding = new List<DetectedObject>();
4920
4921 colliding.Add(CreateDetObjectForGround());
4922 LandCollidingMessage.Colliders = colliding;
4923
4924 notify(dest.RootPart.LocalId, LandCollidingMessage);
4925 }
4926 }
4927
4928 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
4929 {
4930 try
4931 {
4932 List<uint> thisHitColliders = new List<uint>();
4933 List<uint> endedColliders = new List<uint>();
4934 List<uint> startedColliders = new List<uint>();
4935 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
4936 CollisionForSoundInfo soundinfo;
4937 ContactPoint curcontact;
4938
4939 if (coldata.Count == 0)
4940 {
4941 if (m_lastColliders.Count == 0)
4942 return; // nothing to do
4943
4944 foreach (uint localID in m_lastColliders)
4945 {
4946 endedColliders.Add(localID);
4947 }
4948 m_lastColliders.Clear();
4949 }
4950
4951 else
4952 {
4953 foreach (uint id in coldata.Keys)
4954 {
4955 thisHitColliders.Add(id);
4956 if (!m_lastColliders.Contains(id))
4957 {
4958 startedColliders.Add(id);
4959 curcontact = coldata[id];
4960 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
4961 {
4962 soundinfo = new CollisionForSoundInfo();
4963 soundinfo.colliderID = id;
4964 soundinfo.position = curcontact.Position;
4965 soundinfo.relativeVel = curcontact.RelativeSpeed;
4966 soundinfolist.Add(soundinfo);
4967 }
4968 }
4969 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
4970 }
4971
4972 // calculate things that ended colliding
4973 foreach (uint localID in m_lastColliders)
4974 {
4975 if (!thisHitColliders.Contains(localID))
4976 {
4977 endedColliders.Add(localID);
4978 }
4979 }
4980 //add the items that started colliding this time to the last colliders list.
4981 foreach (uint localID in startedColliders)
4982 {
4983 m_lastColliders.Add(localID);
4984 }
4985 // remove things that ended colliding from the last colliders list
4986 foreach (uint localID in endedColliders)
4987 {
4988 m_lastColliders.Remove(localID);
4989 }
4990
4991 if (soundinfolist.Count > 0)
4992 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
4993 }
4994
4995 foreach (SceneObjectGroup att in GetAttachments())
4996 {
4997 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
4998 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
4999 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
5000
5001 if (startedColliders.Contains(0))
5002 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
5003 if (m_lastColliders.Contains(0))
5004 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
5005 if (endedColliders.Contains(0))
5006 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
5007 }
5008 }
5009 finally
5010 {
5011 m_collisionEventFlag = false;
5012 }
5013 }
5014
4561 private void TeleportFlagsDebug() { 5015 private void TeleportFlagsDebug() {
4562 5016
4563 // Some temporary debugging help to show all the TeleportFlags we have... 5017 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4582,6 +5036,5 @@ namespace OpenSim.Region.Framework.Scenes
4582 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 5036 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4583 5037
4584 } 5038 }
4585
4586 } 5039 }
4587} 5040}