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.cs1008
1 files changed, 670 insertions, 338 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 49f70c4..5e80f5a 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;
@@ -919,6 +996,38 @@ namespace OpenSim.Region.Framework.Scenes
919// "[SCENE]: Upgrading child to root agent for {0} in {1}", 996// "[SCENE]: Upgrading child to root agent for {0} in {1}",
920// Name, m_scene.RegionInfo.RegionName); 997// Name, m_scene.RegionInfo.RegionName);
921 998
999 if (ParentUUID != UUID.Zero)
1000 {
1001 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1002 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1003 if (part == null)
1004 {
1005 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1006 }
1007 else
1008 {
1009 part.ParentGroup.AddAvatar(UUID);
1010 if (part.SitTargetPosition != Vector3.Zero)
1011 part.SitTargetAvatar = UUID;
1012// ParentPosition = part.GetWorldPosition();
1013 ParentID = part.LocalId;
1014 ParentPart = part;
1015 m_pos = PrevSitOffset;
1016// pos = ParentPosition;
1017 pos = part.GetWorldPosition();
1018 }
1019 ParentUUID = UUID.Zero;
1020
1021 IsChildAgent = false;
1022
1023// Animator.TrySetMovementAnimation("SIT");
1024 }
1025 else
1026 {
1027 IsChildAgent = false;
1028 IsLoggingIn = false;
1029 }
1030
922 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 1031 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
923 1032
924 IsChildAgent = false; 1033 IsChildAgent = false;
@@ -936,70 +1045,106 @@ namespace OpenSim.Region.Framework.Scenes
936 1045
937 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1046 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
938 1047
939 // Moved this from SendInitialData to ensure that Appearance is initialized 1048 UUID groupUUID = UUID.Zero;
940 // before the inventory is processed in MakeRootAgent. This fixes a race condition 1049 string GroupName = string.Empty;
941 // related to the handling of attachments 1050 ulong groupPowers = 0;
942 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
943 1051
944 if (m_scene.TestBorderCross(pos, Cardinals.E)) 1052 // ----------------------------------
1053 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1054 try
945 { 1055 {
946 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 1056 if (gm != null)
947 pos.X = crossedBorder.BorderLine.Z - 1; 1057 {
1058 groupUUID = ControllingClient.ActiveGroupId;
1059 GroupRecord record = gm.GetGroupRecord(groupUUID);
1060 if (record != null)
1061 GroupName = record.GroupName;
1062 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1063 if (groupMembershipData != null)
1064 groupPowers = groupMembershipData.GroupPowers;
1065 }
1066 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1067 Grouptitle);
948 } 1068 }
949 1069 catch (Exception e)
950 if (m_scene.TestBorderCross(pos, Cardinals.N))
951 { 1070 {
952 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1071 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
953 pos.Y = crossedBorder.BorderLine.Z - 1;
954 } 1072 }
1073 // ------------------------------------
955 1074
956 CheckAndAdjustLandingPoint(ref pos); 1075 if (ParentID == 0)
957
958 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
959 { 1076 {
960 m_log.WarnFormat( 1077 // 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", 1078 // before the inventory is processed in MakeRootAgent. This fixes a race condition
962 pos, Name, UUID); 1079 // related to the handling of attachments
1080 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1081 if (m_scene.TestBorderCross(pos, Cardinals.E))
1082 {
1083 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1084 pos.X = crossedBorder.BorderLine.Z - 1;
1085 }
963 1086
964 if (pos.X < 0f) pos.X = 0f; 1087 if (m_scene.TestBorderCross(pos, Cardinals.N))
965 if (pos.Y < 0f) pos.Y = 0f; 1088 {
966 if (pos.Z < 0f) pos.Z = 0f; 1089 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
967 } 1090 pos.Y = crossedBorder.BorderLine.Z - 1;
1091 }
968 1092
969 float localAVHeight = 1.56f; 1093 CheckAndAdjustLandingPoint(ref pos);
970 if (Appearance.AvatarHeight > 0)
971 localAVHeight = Appearance.AvatarHeight;
972 1094
973 float posZLimit = 0; 1095 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1096 {
1097 m_log.WarnFormat(
1098 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1099 pos, Name, UUID);
974 1100
975 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1101 if (pos.X < 0f) pos.X = 0f;
976 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1102 if (pos.Y < 0f) pos.Y = 0f;
977 1103 if (pos.Z < 0f) pos.Z = 0f;
978 float newPosZ = posZLimit + localAVHeight / 2; 1104 }
979 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
980 {
981 pos.Z = newPosZ;
982 }
983 AbsolutePosition = pos;
984 1105
985 AddToPhysicalScene(isFlying); 1106 float localAVHeight = 1.56f;
1107 if (Appearance.AvatarHeight > 0)
1108 localAVHeight = Appearance.AvatarHeight;
986 1109
987 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1110 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 1111
994 if (ForceFly) 1112 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
995 { 1113 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
996 Flying = true; 1114
997 } 1115 float newPosZ = posZLimit + localAVHeight / 2;
998 else if (FlyDisabled) 1116 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
999 { 1117 {
1000 Flying = false; 1118 pos.Z = newPosZ;
1001 } 1119 }
1120 AbsolutePosition = pos;
1121
1122 if (m_teleportFlags == TeleportFlags.Default)
1123 {
1124 Vector3 vel = Velocity;
1125 AddToPhysicalScene(isFlying);
1126 if (PhysicsActor != null)
1127 PhysicsActor.SetMomentum(vel);
1128 }
1129 else
1130 AddToPhysicalScene(isFlying);
1131
1132 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1133 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1134 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1135 // the value to a negative position which does not trigger the border cross.
1136 // This may not be the best location for this.
1137 CheckForBorderCrossing();
1002 1138
1139 if (ForceFly)
1140 {
1141 Flying = true;
1142 }
1143 else if (FlyDisabled)
1144 {
1145 Flying = false;
1146 }
1147 }
1003 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1148 // 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 1149 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1005 // elsewhere anyway 1150 // elsewhere anyway
@@ -1031,31 +1176,28 @@ namespace OpenSim.Region.Framework.Scenes
1031 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1176 // 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 1177 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1033 // not transporting the required data. 1178 // not transporting the required data.
1034 // 1179 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 { 1180 {
1047 m_log.DebugFormat( 1181 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 { 1182 {
1053 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1183 m_log.DebugFormat(
1054 sog.ResumeScripts(); 1184 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1185
1186 // Resume scripts
1187 Util.FireAndForget(delegate(object x) {
1188 foreach (SceneObjectGroup sog in m_attachments)
1189 {
1190 sog.ScheduleGroupForFullUpdate();
1191 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1192 sog.ResumeScripts();
1193 }
1194 });
1055 } 1195 }
1056 } 1196 }
1057 } 1197 }
1058 1198
1199 SendAvatarDataToAllAgents();
1200
1059 // send the animations of the other presences to me 1201 // send the animations of the other presences to me
1060 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1202 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1061 { 1203 {
@@ -1066,6 +1208,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 1208 // 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 1209 // 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. 1210 // recorded, which stops the input from being processed.
1211
1069 MovementFlag = 0; 1212 MovementFlag = 0;
1070 1213
1071 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1214 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -1097,12 +1240,16 @@ namespace OpenSim.Region.Framework.Scenes
1097 /// </remarks> 1240 /// </remarks>
1098 public void MakeChildAgent() 1241 public void MakeChildAgent()
1099 { 1242 {
1243 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1244
1100 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1245 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1101 1246
1102 // Reset these so that teleporting in and walking out isn't seen 1247 // Reset these so that teleporting in and walking out isn't seen
1103 // as teleporting back 1248 // as teleporting back
1104 TeleportFlags = TeleportFlags.Default; 1249 TeleportFlags = TeleportFlags.Default;
1105 1250
1251 MovementFlag = 0;
1252
1106 // It looks like Animator is set to null somewhere, and MakeChild 1253 // It looks like Animator is set to null somewhere, and MakeChild
1107 // is called after that. Probably in aborted teleports. 1254 // is called after that. Probably in aborted teleports.
1108 if (Animator == null) 1255 if (Animator == null)
@@ -1110,6 +1257,7 @@ namespace OpenSim.Region.Framework.Scenes
1110 else 1257 else
1111 Animator.ResetAnimations(); 1258 Animator.ResetAnimations();
1112 1259
1260
1113// m_log.DebugFormat( 1261// m_log.DebugFormat(
1114// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1262// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1115// Name, UUID, m_scene.RegionInfo.RegionName); 1263// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1121,6 +1269,7 @@ namespace OpenSim.Region.Framework.Scenes
1121 IsChildAgent = true; 1269 IsChildAgent = true;
1122 m_scene.SwapRootAgentCount(true); 1270 m_scene.SwapRootAgentCount(true);
1123 RemoveFromPhysicalScene(); 1271 RemoveFromPhysicalScene();
1272 ParentID = 0; // Child agents can't be sitting
1124 1273
1125 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1274 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1126 1275
@@ -1136,9 +1285,9 @@ namespace OpenSim.Region.Framework.Scenes
1136 { 1285 {
1137// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1286// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1138 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1287 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1139 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1140 PhysicsActor.UnSubscribeEvents();
1141 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1288 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1289 PhysicsActor.UnSubscribeEvents();
1290 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1142 PhysicsActor = null; 1291 PhysicsActor = null;
1143 } 1292 }
1144// else 1293// else
@@ -1155,7 +1304,7 @@ namespace OpenSim.Region.Framework.Scenes
1155 /// <param name="pos"></param> 1304 /// <param name="pos"></param>
1156 public void Teleport(Vector3 pos) 1305 public void Teleport(Vector3 pos)
1157 { 1306 {
1158 TeleportWithMomentum(pos, null); 1307 TeleportWithMomentum(pos, Vector3.Zero);
1159 } 1308 }
1160 1309
1161 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1310 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1179,6 +1328,41 @@ namespace OpenSim.Region.Framework.Scenes
1179 SendTerseUpdateToAllClients(); 1328 SendTerseUpdateToAllClients();
1180 } 1329 }
1181 1330
1331 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1332 {
1333 CheckLandingPoint(ref newpos);
1334 AbsolutePosition = newpos;
1335
1336 if (newvel.HasValue)
1337 {
1338 if ((Vector3)newvel == Vector3.Zero)
1339 {
1340 if (PhysicsActor != null)
1341 PhysicsActor.SetMomentum(Vector3.Zero);
1342 m_velocity = Vector3.Zero;
1343 }
1344 else
1345 {
1346 if (PhysicsActor != null)
1347 PhysicsActor.SetMomentum((Vector3)newvel);
1348 m_velocity = (Vector3)newvel;
1349
1350 if (rotateToVelXY)
1351 {
1352 Vector3 lookAt = (Vector3)newvel;
1353 lookAt.Z = 0;
1354 lookAt.Normalize();
1355 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1356 return;
1357 }
1358 }
1359 }
1360
1361 SendTerseUpdateToAllClients();
1362 }
1363
1364
1365
1182 public void StopFlying() 1366 public void StopFlying()
1183 { 1367 {
1184 Vector3 pos = AbsolutePosition; 1368 Vector3 pos = AbsolutePosition;
@@ -1367,6 +1551,14 @@ namespace OpenSim.Region.Framework.Scenes
1367 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1551 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1368 } 1552 }
1369 1553
1554 public void SetSize(Vector3 size, float feetoffset)
1555 {
1556// TODO: Merge the physics bits
1557// if (PhysicsActor != null && !IsChildAgent)
1558// PhysicsActor.setAvatarSize(size, feetoffset);
1559
1560 }
1561
1370 private bool WaitForUpdateAgent(IClientAPI client) 1562 private bool WaitForUpdateAgent(IClientAPI client)
1371 { 1563 {
1372 // Before the source region executes UpdateAgent 1564 // Before the source region executes UpdateAgent
@@ -1426,7 +1618,8 @@ namespace OpenSim.Region.Framework.Scenes
1426 1618
1427 Vector3 look = Velocity; 1619 Vector3 look = Velocity;
1428 1620
1429 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1621 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1622 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1430 { 1623 {
1431 look = new Vector3(0.99f, 0.042f, 0); 1624 look = new Vector3(0.99f, 0.042f, 0);
1432 } 1625 }
@@ -1489,11 +1682,12 @@ namespace OpenSim.Region.Framework.Scenes
1489 { 1682 {
1490 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1683 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1491 if (m_agentTransfer != null) 1684 if (m_agentTransfer != null)
1492 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1685 m_agentTransfer.EnableChildAgents(this);
1493 1686
1494 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1687 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1495 if (friendsModule != null) 1688 if (friendsModule != null)
1496 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1689 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1690
1497 } 1691 }
1498 1692
1499 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1693 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1519,36 +1713,69 @@ namespace OpenSim.Region.Framework.Scenes
1519 /// <param name="collisionPoint"></param> 1713 /// <param name="collisionPoint"></param>
1520 /// <param name="localid"></param> 1714 /// <param name="localid"></param>
1521 /// <param name="distance"></param> 1715 /// <param name="distance"></param>
1716 ///
1717
1718 private void UpdateCameraCollisionPlane(Vector4 plane)
1719 {
1720 if (m_lastCameraCollisionPlane != plane)
1721 {
1722 m_lastCameraCollisionPlane = plane;
1723 ControllingClient.SendCameraConstraint(plane);
1724 }
1725 }
1726
1522 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1727 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1523 { 1728 {
1524 const float POSITION_TOLERANCE = 0.02f; 1729 const float POSITION_TOLERANCE = 0.02f;
1525 const float VELOCITY_TOLERANCE = 0.02f;
1526 const float ROTATION_TOLERANCE = 0.02f; 1730 const float ROTATION_TOLERANCE = 0.02f;
1527 1731
1528 if (m_followCamAuto) 1732 m_doingCamRayCast = false;
1733 if (hitYN && localid != LocalId)
1529 { 1734 {
1530 if (hitYN) 1735 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1736 bool IsPrim = group != null;
1737 if (IsPrim)
1531 { 1738 {
1532 CameraConstraintActive = true; 1739 SceneObjectPart part = group.GetPart(localid);
1533 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1740 if (part != null && !part.VolumeDetectActive)
1534 1741 {
1535 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1742 CameraConstraintActive = true;
1536 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1743 pNormal.X = (float) Math.Round(pNormal.X, 2);
1744 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1745 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1746 pNormal.Normalize();
1747 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1748 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1749 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1750
1751 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1752 Vector3.Dot(collisionPoint, pNormal));
1753 UpdateCameraCollisionPlane(plane);
1754 }
1537 } 1755 }
1538 else 1756 else
1539 { 1757 {
1540 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1758 CameraConstraintActive = true;
1541 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1759 pNormal.X = (float) Math.Round(pNormal.X, 2);
1542 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1760 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1543 { 1761 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1544 if (CameraConstraintActive) 1762 pNormal.Normalize();
1545 { 1763 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1546 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1764 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1547 CameraConstraintActive = false; 1765 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1548 } 1766
1549 } 1767 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1768 Vector3.Dot(collisionPoint, pNormal));
1769 UpdateCameraCollisionPlane(plane);
1550 } 1770 }
1551 } 1771 }
1772 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1773 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1774 {
1775 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1776 UpdateCameraCollisionPlane(plane);
1777 CameraConstraintActive = false;
1778 }
1552 } 1779 }
1553 1780
1554 /// <summary> 1781 /// <summary>
@@ -1622,6 +1849,41 @@ namespace OpenSim.Region.Framework.Scenes
1622 StandUp(); 1849 StandUp();
1623 } 1850 }
1624 1851
1852 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1853 // this exclude checks may not be complete
1854
1855 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1856 {
1857 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1858 {
1859 Vector3 posAdjusted = AbsolutePosition;
1860// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1861 posAdjusted.Z += 1.0f; // viewer current camera focus point
1862 Vector3 tocam = CameraPosition - posAdjusted;
1863 tocam.X = (float)Math.Round(tocam.X, 1);
1864 tocam.Y = (float)Math.Round(tocam.Y, 1);
1865 tocam.Z = (float)Math.Round(tocam.Z, 1);
1866
1867 float distTocamlen = tocam.Length();
1868 if (distTocamlen > 0.3f)
1869 {
1870 tocam *= (1.0f / distTocamlen);
1871 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1872 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1873 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1874
1875 m_doingCamRayCast = true;
1876 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1877 }
1878 }
1879 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1880 {
1881 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1882 UpdateCameraCollisionPlane(plane);
1883 CameraConstraintActive = false;
1884 }
1885 }
1886
1625 uint flagsForScripts = (uint)flags; 1887 uint flagsForScripts = (uint)flags;
1626 flags = RemoveIgnoredControls(flags, IgnoredControls); 1888 flags = RemoveIgnoredControls(flags, IgnoredControls);
1627 1889
@@ -2182,7 +2444,8 @@ namespace OpenSim.Region.Framework.Scenes
2182// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2444// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2183 2445
2184 MovingToTarget = false; 2446 MovingToTarget = false;
2185 MoveToPositionTarget = Vector3.Zero; 2447// MoveToPositionTarget = Vector3.Zero;
2448 m_forceToApply = null; // cancel possible last action
2186 2449
2187 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2450 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
2188 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2451 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2205,6 +2468,9 @@ namespace OpenSim.Region.Framework.Scenes
2205 2468
2206 if (satOnObject) 2469 if (satOnObject)
2207 { 2470 {
2471 PrevSitOffset = m_pos; // Save sit offset
2472 UnRegisterSeatControls(part.ParentGroup.UUID);
2473
2208 TaskInventoryDictionary taskIDict = part.TaskInventory; 2474 TaskInventoryDictionary taskIDict = part.TaskInventory;
2209 if (taskIDict != null) 2475 if (taskIDict != null)
2210 { 2476 {
@@ -2220,6 +2486,7 @@ namespace OpenSim.Region.Framework.Scenes
2220 } 2486 }
2221 } 2487 }
2222 2488
2489 part.ParentGroup.DeleteAvatar(UUID);
2223 Vector3 sitPartWorldPosition = part.GetWorldPosition(); 2490 Vector3 sitPartWorldPosition = part.GetWorldPosition();
2224 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2491 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2225 2492
@@ -2280,6 +2547,9 @@ namespace OpenSim.Region.Framework.Scenes
2280 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2547 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2281 } 2548 }
2282 2549
2550 else if (PhysicsActor == null)
2551 AddToPhysicalScene(false);
2552
2283 Animator.TrySetMovementAnimation("STAND"); 2553 Animator.TrySetMovementAnimation("STAND");
2284 TriggerScenePresenceUpdated(); 2554 TriggerScenePresenceUpdated();
2285 } 2555 }
@@ -2328,11 +2598,8 @@ namespace OpenSim.Region.Framework.Scenes
2328 if (part == null) 2598 if (part == null)
2329 return; 2599 return;
2330 2600
2331 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2332 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2333
2334 if (PhysicsActor != null) 2601 if (PhysicsActor != null)
2335 m_sitAvatarHeight = PhysicsActor.Size.Z; 2602 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2336 2603
2337 bool canSit = false; 2604 bool canSit = false;
2338 2605
@@ -2359,33 +2626,32 @@ namespace OpenSim.Region.Framework.Scenes
2359 } 2626 }
2360 else 2627 else
2361 { 2628 {
2629 if (PhysicsSit(part,offset)) // physics engine
2630 return;
2631
2362 Vector3 pos = part.AbsolutePosition + offset; 2632 Vector3 pos = part.AbsolutePosition + offset;
2363 2633
2364 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2634 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2365 { 2635 {
2366// m_log.DebugFormat(
2367// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2368// Name, part.Name, part.LocalId);
2369
2370 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2636 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2371 canSit = true; 2637 canSit = true;
2372 } 2638 }
2373// else
2374// {
2375// m_log.DebugFormat(
2376// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2377// Name, part.Name, part.LocalId);
2378// }
2379 } 2639 }
2380 2640
2381 if (canSit) 2641 if (canSit)
2382 { 2642 {
2643
2383 if (PhysicsActor != null) 2644 if (PhysicsActor != null)
2384 { 2645 {
2385 // We can remove the physicsActor until they stand up. 2646 // We can remove the physicsActor until they stand up.
2386 RemoveFromPhysicalScene(); 2647 RemoveFromPhysicalScene();
2387 } 2648 }
2388 2649
2650 if (MovingToTarget)
2651 ResetMoveToTarget();
2652
2653 Velocity = Vector3.Zero;
2654
2389 part.AddSittingAvatar(UUID); 2655 part.AddSittingAvatar(UUID);
2390 2656
2391 cameraAtOffset = part.GetCameraAtOffset(); 2657 cameraAtOffset = part.GetCameraAtOffset();
@@ -2429,14 +2695,6 @@ namespace OpenSim.Region.Framework.Scenes
2429 m_requestedSitTargetID = part.LocalId; 2695 m_requestedSitTargetID = part.LocalId;
2430 m_requestedSitTargetUUID = part.UUID; 2696 m_requestedSitTargetUUID = part.UUID;
2431 2697
2432// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2433
2434 if (m_scene.PhysicsScene.SupportsRayCast())
2435 {
2436 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2437 //SitRayCastAvatarPosition(part);
2438 //return;
2439 }
2440 } 2698 }
2441 else 2699 else
2442 { 2700 {
@@ -2446,197 +2704,115 @@ namespace OpenSim.Region.Framework.Scenes
2446 SendSitResponse(targetID, offset, Quaternion.Identity); 2704 SendSitResponse(targetID, offset, Quaternion.Identity);
2447 } 2705 }
2448 2706
2449 /* 2707 // returns false if does not suport so older sit can be tried
2450 public void SitRayCastAvatarPosition(SceneObjectPart part) 2708 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2451 {
2452 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2453 Vector3 StartRayCastPosition = AbsolutePosition;
2454 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2455 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2456 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2457 }
2458
2459 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2460 { 2709 {
2461 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2710// TODO: Pull in these bits
2462 if (part != null) 2711 return false;
2463 { 2712/*
2464 if (hitYN) 2713 if (part == null || part.ParentGroup.IsAttachment)
2465 {
2466 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2467 {
2468 SitRaycastFindEdge(collisionPoint, normal);
2469 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2470 }
2471 else
2472 {
2473 SitRayCastAvatarPositionCameraZ(part);
2474 }
2475 }
2476 else
2477 {
2478 SitRayCastAvatarPositionCameraZ(part);
2479 }
2480 }
2481 else
2482 { 2714 {
2483 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2715 return true;
2484 m_requestedSitTargetUUID = UUID.Zero;
2485 m_requestedSitTargetID = 0;
2486 m_requestedSitOffset = Vector3.Zero;
2487 } 2716 }
2488 2717
2489 } 2718 if ( m_scene.PhysicsScene == null)
2490 2719 return false;
2491 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2492 {
2493 // Next, try to raycast from the camera Z position
2494 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2495 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2496 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2497 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2498 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2499 }
2500 2720
2501 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2721 if (part.PhysActor == null)
2502 {
2503 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2504 if (part != null)
2505 { 2722 {
2506 if (hitYN) 2723 // none physcis shape
2507 { 2724 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2508 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2725 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2509 {
2510 SitRaycastFindEdge(collisionPoint, normal);
2511 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2512 }
2513 else
2514 {
2515 SitRayCastCameraPosition(part);
2516 }
2517 }
2518 else 2726 else
2519 { 2727 { // non physical phantom TODO
2520 SitRayCastCameraPosition(part); 2728 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2729 return false;
2521 } 2730 }
2522 } 2731 return true;
2523 else
2524 {
2525 ControllingClient.SendAlertMessage("Sit position no longer exists");
2526 m_requestedSitTargetUUID = UUID.Zero;
2527 m_requestedSitTargetID = 0;
2528 m_requestedSitOffset = Vector3.Zero;
2529 } 2732 }
2530 2733
2531 }
2532 2734
2533 public void SitRayCastCameraPosition(SceneObjectPart part) 2735 // not doing autopilot
2534 { 2736 m_requestedSitTargetID = 0;
2535 // Next, try to raycast from the camera position
2536 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2537 Vector3 StartRayCastPosition = CameraPosition;
2538 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2539 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2540 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2541 }
2542 2737
2543 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2738 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2544 { 2739 return true;
2545 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2546 if (part != null)
2547 {
2548 if (hitYN)
2549 {
2550 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2551 {
2552 SitRaycastFindEdge(collisionPoint, normal);
2553 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2554 }
2555 else
2556 {
2557 SitRayHorizontal(part);
2558 }
2559 }
2560 else
2561 {
2562 SitRayHorizontal(part);
2563 }
2564 }
2565 else
2566 {
2567 ControllingClient.SendAlertMessage("Sit position no longer exists");
2568 m_requestedSitTargetUUID = UUID.Zero;
2569 m_requestedSitTargetID = 0;
2570 m_requestedSitOffset = Vector3.Zero;
2571 }
2572 2740
2741 return false;
2742*/
2573 } 2743 }
2574 2744
2575 public void SitRayHorizontal(SceneObjectPart part) 2745
2746 private bool CanEnterLandPosition(Vector3 testPos)
2576 { 2747 {
2577 // Next, try to raycast from the avatar position to fwd 2748 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2578 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2749
2579 Vector3 StartRayCastPosition = CameraPosition; 2750 if (land == null || land.LandData.Name == "NO_LAND")
2580 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2751 return true;
2581 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2752
2582 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2753 return land.CanBeOnThisLand(UUID,testPos.Z);
2583 } 2754 }
2584 2755
2585 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2756 // status
2757 // < 0 ignore
2758 // 0 bad sit spot
2759 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2586 { 2760 {
2587 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2761 if (status < 0)
2588 if (part != null) 2762 return;
2763
2764 if (status == 0)
2589 { 2765 {
2590 if (hitYN) 2766 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2591 { 2767 return;
2592 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2593 {
2594 SitRaycastFindEdge(collisionPoint, normal);
2595 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2596 // Next, try to raycast from the camera position
2597 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2598 Vector3 StartRayCastPosition = CameraPosition;
2599 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2600 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2601 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2602 }
2603 else
2604 {
2605 ControllingClient.SendAlertMessage("Sit position not accessable.");
2606 m_requestedSitTargetUUID = UUID.Zero;
2607 m_requestedSitTargetID = 0;
2608 m_requestedSitOffset = Vector3.Zero;
2609 }
2610 }
2611 else
2612 {
2613 ControllingClient.SendAlertMessage("Sit position not accessable.");
2614 m_requestedSitTargetUUID = UUID.Zero;
2615 m_requestedSitTargetID = 0;
2616 m_requestedSitOffset = Vector3.Zero;
2617 }
2618 } 2768 }
2619 else 2769
2770 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2771 if (part == null)
2772 return;
2773
2774 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2775 if(!CanEnterLandPosition(targetPos))
2620 { 2776 {
2621 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2777 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2622 m_requestedSitTargetUUID = UUID.Zero; 2778 return;
2623 m_requestedSitTargetID = 0;
2624 m_requestedSitOffset = Vector3.Zero;
2625 } 2779 }
2626 2780
2627 } 2781 RemoveFromPhysicalScene();
2628 2782
2629 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2783 if (MovingToTarget)
2630 { 2784 ResetMoveToTarget();
2631 int i = 0; 2785
2632 //throw new NotImplementedException(); 2786 Velocity = Vector3.Zero;
2633 //m_requestedSitTargetUUID = UUID.Zero; 2787
2634 //m_requestedSitTargetID = 0; 2788 part.AddSittingAvatar(UUID);
2635 //m_requestedSitOffset = Vector3.Zero; 2789
2790 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2791 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2792 bool forceMouselook = part.GetForceMouselook();
2793
2794 ControllingClient.SendSitResponse(
2795 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2796
2797 // not using autopilot
2798
2799 Rotation = Orientation;
2800 m_pos = offset;
2801
2802 m_requestedSitTargetID = 0;
2803 part.ParentGroup.AddAvatar(UUID);
2804
2805 ParentPart = part;
2806 ParentID = part.LocalId;
2807 if(status == 3)
2808 Animator.TrySetMovementAnimation("SIT_GROUND");
2809 else
2810 Animator.TrySetMovementAnimation("SIT");
2811 SendAvatarDataToAllAgents();
2636 2812
2637 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2813 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2638 } 2814 }
2639 */ 2815
2640 2816
2641 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2817 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2642 { 2818 {
@@ -2656,6 +2832,7 @@ namespace OpenSim.Region.Framework.Scenes
2656 return; 2832 return;
2657 } 2833 }
2658 2834
2835
2659 if (part.SitTargetAvatar == UUID) 2836 if (part.SitTargetAvatar == UUID)
2660 { 2837 {
2661 Vector3 sitTargetPos = part.SitTargetPosition; 2838 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2670,7 +2847,28 @@ namespace OpenSim.Region.Framework.Scenes
2670 2847
2671 //Quaternion result = (sitTargetOrient * vq) * nq; 2848 //Quaternion result = (sitTargetOrient * vq) * nq;
2672 2849
2673 Vector3 newPos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2850 double x, y, z, m;
2851
2852 Quaternion r = sitTargetOrient;
2853 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2854
2855 if (Math.Abs(1.0 - m) > 0.000001)
2856 {
2857 m = 1.0 / Math.Sqrt(m);
2858 r.X *= (float)m;
2859 r.Y *= (float)m;
2860 r.Z *= (float)m;
2861 r.W *= (float)m;
2862 }
2863
2864 x = 2 * (r.X * r.Z + r.Y * r.W);
2865 y = 2 * (-r.X * r.W + r.Y * r.Z);
2866 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2867
2868 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2869 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2870
2871 Vector3 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2674 Quaternion newRot; 2872 Quaternion newRot;
2675 2873
2676 if (part.IsRoot) 2874 if (part.IsRoot)
@@ -2687,6 +2885,9 @@ namespace OpenSim.Region.Framework.Scenes
2687 2885
2688 m_pos = newPos; 2886 m_pos = newPos;
2689 Rotation = newRot; 2887 Rotation = newRot;
2888
2889// ParentPosition = part.AbsolutePosition;
2890 part.ParentGroup.AddAvatar(UUID);
2690 } 2891 }
2691 else 2892 else
2692 { 2893 {
@@ -2694,6 +2895,9 @@ namespace OpenSim.Region.Framework.Scenes
2694 // being sat upon. 2895 // being sat upon.
2695 m_pos -= part.GroupPosition; 2896 m_pos -= part.GroupPosition;
2696 2897
2898// ParentPosition = part.AbsolutePosition;
2899 part.ParentGroup.AddAvatar(UUID);
2900
2697// m_log.DebugFormat( 2901// m_log.DebugFormat(
2698// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2902// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
2699// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); 2903// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
@@ -2809,8 +3013,8 @@ namespace OpenSim.Region.Framework.Scenes
2809 direc.Z *= 2.6f; 3013 direc.Z *= 2.6f;
2810 3014
2811 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 3015 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2812 Animator.TrySetMovementAnimation("PREJUMP"); 3016// Animator.TrySetMovementAnimation("PREJUMP");
2813 Animator.TrySetMovementAnimation("JUMP"); 3017// Animator.TrySetMovementAnimation("JUMP");
2814 } 3018 }
2815 } 3019 }
2816 } 3020 }
@@ -2819,6 +3023,7 @@ namespace OpenSim.Region.Framework.Scenes
2819 3023
2820 // TODO: Add the force instead of only setting it to support multiple forces per frame? 3024 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2821 m_forceToApply = direc; 3025 m_forceToApply = direc;
3026 Animator.UpdateMovementAnimations();
2822 } 3027 }
2823 3028
2824 #endregion 3029 #endregion
@@ -2836,16 +3041,12 @@ namespace OpenSim.Region.Framework.Scenes
2836 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 3041 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2837 // grab the latest PhysicsActor velocity, whereas m_velocity is often 3042 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2838 // storing a requested force instead of an actual traveling velocity 3043 // storing a requested force instead of an actual traveling velocity
3044 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
3045 SendAvatarDataToAllAgents();
2839 3046
2840 // Throw away duplicate or insignificant updates 3047 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2841 if ( 3048 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2842 // If the velocity has become zero, send it no matter what. 3049 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2843 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2844 // otherwise, if things have changed reasonably, send the update
2845 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2846 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2847 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2848
2849 { 3050 {
2850 SendTerseUpdateToAllClients(); 3051 SendTerseUpdateToAllClients();
2851 3052
@@ -3005,9 +3206,7 @@ namespace OpenSim.Region.Framework.Scenes
3005 // again here... this comes after the cached appearance check because the avatars 3206 // again here... this comes after the cached appearance check because the avatars
3006 // appearance goes into the avatar update packet 3207 // appearance goes into the avatar update packet
3007 SendAvatarDataToAllAgents(); 3208 SendAvatarDataToAllAgents();
3008 3209 SendAppearanceToAgent(this);
3009 // This invocation always shows up in the viewer logs as an error.
3010 // SendAppearanceToAgent(this);
3011 3210
3012 // If we are using the the cached appearance then send it out to everyone 3211 // If we are using the the cached appearance then send it out to everyone
3013 if (cachedappearance) 3212 if (cachedappearance)
@@ -3038,6 +3237,8 @@ namespace OpenSim.Region.Framework.Scenes
3038 return; 3237 return;
3039 } 3238 }
3040 3239
3240 m_lastSize = Appearance.AvatarSize;
3241
3041 int count = 0; 3242 int count = 0;
3042 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 3243 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3043 { 3244 {
@@ -3145,6 +3346,8 @@ namespace OpenSim.Region.Framework.Scenes
3145 3346
3146 avatar.ControllingClient.SendAppearance( 3347 avatar.ControllingClient.SendAppearance(
3147 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3348 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3349
3350
3148 } 3351 }
3149 3352
3150 #endregion 3353 #endregion
@@ -3218,8 +3421,9 @@ namespace OpenSim.Region.Framework.Scenes
3218 3421
3219 // If we don't have a PhysActor, we can't cross anyway 3422 // If we don't have a PhysActor, we can't cross anyway
3220 // Also don't do this while sat, sitting avatars cross with the 3423 // Also don't do this while sat, sitting avatars cross with the
3221 // object they sit on. 3424 // object they sit on. ParentUUID denoted a pending sit, don't
3222 if (ParentID != 0 || PhysicsActor == null) 3425 // interfere with it.
3426 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3223 return; 3427 return;
3224 3428
3225 if (!IsInTransit) 3429 if (!IsInTransit)
@@ -3563,6 +3767,9 @@ namespace OpenSim.Region.Framework.Scenes
3563 cAgent.AlwaysRun = SetAlwaysRun; 3767 cAgent.AlwaysRun = SetAlwaysRun;
3564 3768
3565 cAgent.Appearance = new AvatarAppearance(Appearance); 3769 cAgent.Appearance = new AvatarAppearance(Appearance);
3770
3771 cAgent.ParentPart = ParentUUID;
3772 cAgent.SitOffset = PrevSitOffset;
3566 3773
3567 lock (scriptedcontrols) 3774 lock (scriptedcontrols)
3568 { 3775 {
@@ -3571,7 +3778,7 @@ namespace OpenSim.Region.Framework.Scenes
3571 3778
3572 foreach (ScriptControllers c in scriptedcontrols.Values) 3779 foreach (ScriptControllers c in scriptedcontrols.Values)
3573 { 3780 {
3574 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3781 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3575 } 3782 }
3576 cAgent.Controllers = controls; 3783 cAgent.Controllers = controls;
3577 } 3784 }
@@ -3605,6 +3812,8 @@ namespace OpenSim.Region.Framework.Scenes
3605 CameraAtAxis = cAgent.AtAxis; 3812 CameraAtAxis = cAgent.AtAxis;
3606 CameraLeftAxis = cAgent.LeftAxis; 3813 CameraLeftAxis = cAgent.LeftAxis;
3607 CameraUpAxis = cAgent.UpAxis; 3814 CameraUpAxis = cAgent.UpAxis;
3815 ParentUUID = cAgent.ParentPart;
3816 PrevSitOffset = cAgent.SitOffset;
3608 3817
3609 // When we get to the point of re-computing neighbors everytime this 3818 // When we get to the point of re-computing neighbors everytime this
3610 // changes, then start using the agent's drawdistance rather than the 3819 // changes, then start using the agent's drawdistance rather than the
@@ -3642,6 +3851,7 @@ namespace OpenSim.Region.Framework.Scenes
3642 foreach (ControllerData c in cAgent.Controllers) 3851 foreach (ControllerData c in cAgent.Controllers)
3643 { 3852 {
3644 ScriptControllers sc = new ScriptControllers(); 3853 ScriptControllers sc = new ScriptControllers();
3854 sc.objectID = c.ObjectID;
3645 sc.itemID = c.ItemID; 3855 sc.itemID = c.ItemID;
3646 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3856 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3647 sc.eventControls = (ScriptControlled)c.EventControls; 3857 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3707,20 +3917,27 @@ namespace OpenSim.Region.Framework.Scenes
3707 } 3917 }
3708 3918
3709 if (Appearance.AvatarHeight == 0) 3919 if (Appearance.AvatarHeight == 0)
3710 Appearance.SetHeight(); 3920// Appearance.SetHeight();
3921 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3711 3922
3712 PhysicsScene scene = m_scene.PhysicsScene; 3923 PhysicsScene scene = m_scene.PhysicsScene;
3713 3924
3714 Vector3 pVec = AbsolutePosition; 3925 Vector3 pVec = AbsolutePosition;
3715 3926
3927/*
3928 PhysicsActor = scene.AddAvatar(
3929 LocalId, Firstname + "." + Lastname, pVec,
3930 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3931*/
3932
3716 PhysicsActor = scene.AddAvatar( 3933 PhysicsActor = scene.AddAvatar(
3717 LocalId, Firstname + "." + Lastname, pVec, 3934 LocalId, Firstname + "." + Lastname, pVec,
3718 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3935 Appearance.AvatarBoxSize, isFlying);
3719 3936
3720 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3937 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3721 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3938 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3722 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3939 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3723 PhysicsActor.SubscribeEvents(500); 3940 PhysicsActor.SubscribeEvents(100);
3724 PhysicsActor.LocalID = LocalId; 3941 PhysicsActor.LocalID = LocalId;
3725 } 3942 }
3726 3943
@@ -3734,6 +3951,7 @@ namespace OpenSim.Region.Framework.Scenes
3734 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3951 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3735 } 3952 }
3736 3953
3954
3737 /// <summary> 3955 /// <summary>
3738 /// Event called by the physics plugin to tell the avatar about a collision. 3956 /// Event called by the physics plugin to tell the avatar about a collision.
3739 /// </summary> 3957 /// </summary>
@@ -3747,7 +3965,7 @@ namespace OpenSim.Region.Framework.Scenes
3747 /// <param name="e"></param> 3965 /// <param name="e"></param>
3748 public void PhysicsCollisionUpdate(EventArgs e) 3966 public void PhysicsCollisionUpdate(EventArgs e)
3749 { 3967 {
3750 if (IsChildAgent) 3968 if (IsChildAgent || Animator == null)
3751 return; 3969 return;
3752 3970
3753 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3971 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3764,7 +3982,6 @@ namespace OpenSim.Region.Framework.Scenes
3764 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3982 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3765 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3983 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3766 3984
3767 CollisionPlane = Vector4.UnitW;
3768 3985
3769// // No collisions at all means we may be flying. Update always 3986// // No collisions at all means we may be flying. Update always
3770// // to make falling work 3987// // to make falling work
@@ -3774,34 +3991,7 @@ namespace OpenSim.Region.Framework.Scenes
3774// m_lastColCount = coldata.Count; 3991// m_lastColCount = coldata.Count;
3775// } 3992// }
3776 3993
3777 if (coldata.Count != 0) 3994 CollisionPlane = Vector4.UnitW;
3778 {
3779 switch (Animator.CurrentMovementAnimation)
3780 {
3781 case "STAND":
3782 case "WALK":
3783 case "RUN":
3784 case "CROUCH":
3785 case "CROUCHWALK":
3786 {
3787 ContactPoint lowest;
3788 lowest.SurfaceNormal = Vector3.Zero;
3789 lowest.Position = Vector3.Zero;
3790 lowest.Position.Z = Single.NaN;
3791
3792 foreach (ContactPoint contact in coldata.Values)
3793 {
3794 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z)
3795 {
3796 lowest = contact;
3797 }
3798 }
3799
3800 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3801 }
3802 break;
3803 }
3804 }
3805 3995
3806 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3996 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3807 if (Invulnerable || GodLevel > 0) 3997 if (Invulnerable || GodLevel > 0)
@@ -3900,6 +4090,12 @@ namespace OpenSim.Region.Framework.Scenes
3900 // m_reprioritizationTimer.Dispose(); 4090 // m_reprioritizationTimer.Dispose();
3901 4091
3902 RemoveFromPhysicalScene(); 4092 RemoveFromPhysicalScene();
4093
4094 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
4095
4096// if (Animator != null)
4097// Animator.Close();
4098 Animator = null;
3903 4099
3904 LifecycleState = ScenePresenceState.Removed; 4100 LifecycleState = ScenePresenceState.Removed;
3905 } 4101 }
@@ -4135,10 +4331,18 @@ namespace OpenSim.Region.Framework.Scenes
4135 4331
4136 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4332 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
4137 { 4333 {
4334 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4335 if (p == null)
4336 return;
4337
4338 ControllingClient.SendTakeControls(controls, false, false);
4339 ControllingClient.SendTakeControls(controls, true, false);
4340
4138 ScriptControllers obj = new ScriptControllers(); 4341 ScriptControllers obj = new ScriptControllers();
4139 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4342 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4140 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4343 obj.eventControls = ScriptControlled.CONTROL_ZERO;
4141 4344
4345 obj.objectID = p.ParentGroup.UUID;
4142 obj.itemID = Script_item_UUID; 4346 obj.itemID = Script_item_UUID;
4143 if (pass_on == 0 && accept == 0) 4347 if (pass_on == 0 && accept == 0)
4144 { 4348 {
@@ -4187,6 +4391,21 @@ namespace OpenSim.Region.Framework.Scenes
4187 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4391 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4188 } 4392 }
4189 4393
4394 private void UnRegisterSeatControls(UUID obj)
4395 {
4396 List<UUID> takers = new List<UUID>();
4397
4398 foreach (ScriptControllers c in scriptedcontrols.Values)
4399 {
4400 if (c.objectID == obj)
4401 takers.Add(c.itemID);
4402 }
4403 foreach (UUID t in takers)
4404 {
4405 UnRegisterControlEventsToScript(0, t);
4406 }
4407 }
4408
4190 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4409 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4191 { 4410 {
4192 ScriptControllers takecontrols; 4411 ScriptControllers takecontrols;
@@ -4516,6 +4735,12 @@ namespace OpenSim.Region.Framework.Scenes
4516 4735
4517 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4736 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4518 { 4737 {
4738 string reason;
4739
4740 // Honor bans
4741 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4742 return;
4743
4519 SceneObjectGroup telehub = null; 4744 SceneObjectGroup telehub = null;
4520 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4745 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4521 { 4746 {
@@ -4555,11 +4780,119 @@ namespace OpenSim.Region.Framework.Scenes
4555 pos = land.LandData.UserLocation; 4780 pos = land.LandData.UserLocation;
4556 } 4781 }
4557 } 4782 }
4558 4783
4559 land.SendLandUpdateToClient(ControllingClient); 4784 land.SendLandUpdateToClient(ControllingClient);
4560 } 4785 }
4561 } 4786 }
4562 4787
4788 private DetectedObject CreateDetObject(SceneObjectPart obj)
4789 {
4790 DetectedObject detobj = new DetectedObject();
4791 detobj.keyUUID = obj.UUID;
4792 detobj.nameStr = obj.Name;
4793 detobj.ownerUUID = obj.OwnerID;
4794 detobj.posVector = obj.AbsolutePosition;
4795 detobj.rotQuat = obj.GetWorldRotation();
4796 detobj.velVector = obj.Velocity;
4797 detobj.colliderType = 0;
4798 detobj.groupUUID = obj.GroupID;
4799
4800 return detobj;
4801 }
4802
4803 private DetectedObject CreateDetObject(ScenePresence av)
4804 {
4805 DetectedObject detobj = new DetectedObject();
4806 detobj.keyUUID = av.UUID;
4807 detobj.nameStr = av.ControllingClient.Name;
4808 detobj.ownerUUID = av.UUID;
4809 detobj.posVector = av.AbsolutePosition;
4810 detobj.rotQuat = av.Rotation;
4811 detobj.velVector = av.Velocity;
4812 detobj.colliderType = 0;
4813 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4814
4815 return detobj;
4816 }
4817
4818 private DetectedObject CreateDetObjectForGround()
4819 {
4820 DetectedObject detobj = new DetectedObject();
4821 detobj.keyUUID = UUID.Zero;
4822 detobj.nameStr = "";
4823 detobj.ownerUUID = UUID.Zero;
4824 detobj.posVector = AbsolutePosition;
4825 detobj.rotQuat = Quaternion.Identity;
4826 detobj.velVector = Vector3.Zero;
4827 detobj.colliderType = 0;
4828 detobj.groupUUID = UUID.Zero;
4829
4830 return detobj;
4831 }
4832
4833 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4834 {
4835 ColliderArgs colliderArgs = new ColliderArgs();
4836 List<DetectedObject> colliding = new List<DetectedObject>();
4837 foreach (uint localId in colliders)
4838 {
4839 if (localId == 0)
4840 continue;
4841
4842 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4843 if (obj != null)
4844 {
4845 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4846 colliding.Add(CreateDetObject(obj));
4847 }
4848 else
4849 {
4850 ScenePresence av = m_scene.GetScenePresence(localId);
4851 if (av != null && (!av.IsChildAgent))
4852 {
4853 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4854 colliding.Add(CreateDetObject(av));
4855 }
4856 }
4857 }
4858
4859 colliderArgs.Colliders = colliding;
4860
4861 return colliderArgs;
4862 }
4863
4864 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4865
4866 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4867 {
4868 ColliderArgs CollidingMessage;
4869
4870 if (colliders.Count > 0)
4871 {
4872 if ((dest.RootPart.ScriptEvents & ev) != 0)
4873 {
4874 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4875
4876 if (CollidingMessage.Colliders.Count > 0)
4877 notify(dest.RootPart.LocalId, CollidingMessage);
4878 }
4879 }
4880 }
4881
4882 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4883 {
4884 if ((dest.RootPart.ScriptEvents & ev) != 0)
4885 {
4886 ColliderArgs LandCollidingMessage = new ColliderArgs();
4887 List<DetectedObject> colliding = new List<DetectedObject>();
4888
4889 colliding.Add(CreateDetObjectForGround());
4890 LandCollidingMessage.Colliders = colliding;
4891
4892 notify(dest.RootPart.LocalId, LandCollidingMessage);
4893 }
4894 }
4895
4563 private void TeleportFlagsDebug() { 4896 private void TeleportFlagsDebug() {
4564 4897
4565 // Some temporary debugging help to show all the TeleportFlags we have... 4898 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4584,6 +4917,5 @@ namespace OpenSim.Region.Framework.Scenes
4584 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4917 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4585 4918
4586 } 4919 }
4587
4588 } 4920 }
4589} 4921}