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.cs1150
1 files changed, 717 insertions, 433 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 3290da1..715a9b6 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;
@@ -75,6 +76,7 @@ namespace OpenSim.Region.Framework.Scenes
75 public class ScenePresence : EntityBase, IScenePresence 76 public class ScenePresence : EntityBase, IScenePresence
76 { 77 {
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 78 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
79 private static readonly String LogHeader = "[SCENE PRESENCE]";
78 80
79// ~ScenePresence() 81// ~ScenePresence()
80// { 82// {
@@ -130,7 +132,7 @@ namespace OpenSim.Region.Framework.Scenes
130 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 132 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
131 /// issue #1716 133 /// issue #1716
132 /// </summary> 134 /// </summary>
133 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 135 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
134 136
135 /// <summary> 137 /// <summary>
136 /// Movement updates for agents in neighboring regions are sent directly to clients. 138 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -152,8 +154,6 @@ namespace OpenSim.Region.Framework.Scenes
152 /// <remarks> 154 /// <remarks>
153 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 155 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
154 /// necessary. 156 /// necessary.
155 /// NOTE: To avoid deadlocks, do not lock m_attachments and then perform other tasks under that lock. Take a copy
156 /// of the list and act on that instead.
157 /// </remarks> 157 /// </remarks>
158 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 158 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
159 159
@@ -172,6 +172,10 @@ namespace OpenSim.Region.Framework.Scenes
172 private Vector3 m_lastPosition; 172 private Vector3 m_lastPosition;
173 private Quaternion m_lastRotation; 173 private Quaternion m_lastRotation;
174 private Vector3 m_lastVelocity; 174 private Vector3 m_lastVelocity;
175 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
176
177 private bool m_followCamAuto = false;
178
175 179
176 private Vector3? m_forceToApply; 180 private Vector3? m_forceToApply;
177 private int m_userFlags; 181 private int m_userFlags;
@@ -204,6 +208,7 @@ namespace OpenSim.Region.Framework.Scenes
204// private int m_lastColCount = -1; //KF: Look for Collision chnages 208// private int m_lastColCount = -1; //KF: Look for Collision chnages
205// private int m_updateCount = 0; //KF: Update Anims for a while 209// private int m_updateCount = 0; //KF: Update Anims for a while
206// private static readonly int UPDATE_COUNT = 10; // how many frames to update for 210// private static readonly int UPDATE_COUNT = 10; // how many frames to update for
211 private List<uint> m_lastColliders = new List<uint>();
207 212
208 private TeleportFlags m_teleportFlags; 213 private TeleportFlags m_teleportFlags;
209 public TeleportFlags TeleportFlags 214 public TeleportFlags TeleportFlags
@@ -259,8 +264,6 @@ namespace OpenSim.Region.Framework.Scenes
259 /// </summary> 264 /// </summary>
260 public bool LandAtTarget { get; private set; } 265 public bool LandAtTarget { get; private set; }
261 266
262 private bool m_followCamAuto;
263
264 private int m_movementUpdateCount; 267 private int m_movementUpdateCount;
265 private const int NumMovementsBetweenRayCast = 5; 268 private const int NumMovementsBetweenRayCast = 5;
266 269
@@ -268,6 +271,13 @@ namespace OpenSim.Region.Framework.Scenes
268 //private int m_moveToPositionStateStatus; 271 //private int m_moveToPositionStateStatus;
269 //***************************************************** 272 //*****************************************************
270 273
274 private bool m_collisionEventFlag = false;
275 private object m_collisionEventLock = new Object();
276
277 private int m_movementAnimationUpdateCounter = 0;
278
279 public Vector3 PrevSitOffset { get; set; }
280
271 protected AvatarAppearance m_appearance; 281 protected AvatarAppearance m_appearance;
272 282
273 public AvatarAppearance Appearance 283 public AvatarAppearance Appearance
@@ -407,6 +417,9 @@ namespace OpenSim.Region.Framework.Scenes
407 /// </summary> 417 /// </summary>
408 protected Vector3 m_lastCameraPosition; 418 protected Vector3 m_lastCameraPosition;
409 419
420 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
421 private bool m_doingCamRayCast = false;
422
410 public Vector3 CameraPosition { get; set; } 423 public Vector3 CameraPosition { get; set; }
411 424
412 public Quaternion CameraRotation 425 public Quaternion CameraRotation
@@ -487,6 +500,10 @@ namespace OpenSim.Region.Framework.Scenes
487 get { return (IClientCore)ControllingClient; } 500 get { return (IClientCore)ControllingClient; }
488 } 501 }
489 502
503 public UUID COF { get; set; }
504
505// public Vector3 ParentPosition { get; set; }
506
490 /// <summary> 507 /// <summary>
491 /// Position of this avatar relative to the region the avatar is in 508 /// Position of this avatar relative to the region the avatar is in
492 /// </summary> 509 /// </summary>
@@ -613,7 +630,24 @@ namespace OpenSim.Region.Framework.Scenes
613// Scene.RegionInfo.RegionName, Name, m_velocity); 630// Scene.RegionInfo.RegionName, Name, m_velocity);
614 } 631 }
615 } 632 }
633/*
634 public override Vector3 AngularVelocity
635 {
636 get
637 {
638 if (PhysicsActor != null)
639 {
640 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
641
642 // m_log.DebugFormat(
643 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
644 // m_velocity, Name, Scene.RegionInfo.RegionName);
645 }
616 646
647 return m_rotationalvelocity;
648 }
649 }
650*/
617 private Quaternion m_bodyRot = Quaternion.Identity; 651 private Quaternion m_bodyRot = Quaternion.Identity;
618 652
619 /// <summary> 653 /// <summary>
@@ -636,8 +670,16 @@ namespace OpenSim.Region.Framework.Scenes
636 m_bodyRot = value; 670 m_bodyRot = value;
637 671
638 if (PhysicsActor != null) 672 if (PhysicsActor != null)
639 PhysicsActor.Orientation = m_bodyRot; 673 {
640 674 try
675 {
676 PhysicsActor.Orientation = m_bodyRot;
677 }
678 catch (Exception e)
679 {
680 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
681 }
682 }
641// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 683// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
642 } 684 }
643 } 685 }
@@ -651,12 +693,20 @@ namespace OpenSim.Region.Framework.Scenes
651 } 693 }
652 694
653 public bool IsChildAgent { get; set; } 695 public bool IsChildAgent { get; set; }
696 public bool IsLoggingIn { get; set; }
654 697
655 /// <summary> 698 /// <summary>
656 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 699 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
657 /// </summary> 700 /// </summary>
658 public uint ParentID { get; set; } 701 public uint ParentID { get; set; }
659 702
703 public UUID ParentUUID
704 {
705 get { return m_parentUUID; }
706 set { m_parentUUID = value; }
707 }
708 private UUID m_parentUUID = UUID.Zero;
709
660 /// <summary> 710 /// <summary>
661 /// Are we sitting on an object? 711 /// Are we sitting on an object?
662 /// </summary> 712 /// </summary>
@@ -710,9 +760,8 @@ namespace OpenSim.Region.Framework.Scenes
710 foreach (ulong handle in seeds.Keys) 760 foreach (ulong handle in seeds.Keys)
711 { 761 {
712 uint x, y; 762 uint x, y;
713 Utils.LongToUInts(handle, out x, out y); 763 Util.RegionHandleToRegionLoc(handle, out x, out y);
714 x = x / Constants.RegionSize; 764
715 y = y / Constants.RegionSize;
716 if (Util.IsOutsideView(DrawDistance, x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) 765 if (Util.IsOutsideView(DrawDistance, x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY))
717 { 766 {
718 old.Add(handle); 767 old.Add(handle);
@@ -734,9 +783,7 @@ namespace OpenSim.Region.Framework.Scenes
734 foreach (KeyValuePair<ulong, string> kvp in KnownRegions) 783 foreach (KeyValuePair<ulong, string> kvp in KnownRegions)
735 { 784 {
736 uint x, y; 785 uint x, y;
737 Utils.LongToUInts(kvp.Key, out x, out y); 786 Util.RegionHandleToRegionLoc(kvp.Key, out x, out y);
738 x = x / Constants.RegionSize;
739 y = y / Constants.RegionSize;
740 m_log.Info(" >> "+x+", "+y+": "+kvp.Value); 787 m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
741 } 788 }
742 } 789 }
@@ -814,6 +861,7 @@ namespace OpenSim.Region.Framework.Scenes
814 AttachmentsSyncLock = new Object(); 861 AttachmentsSyncLock = new Object();
815 AllowMovement = true; 862 AllowMovement = true;
816 IsChildAgent = true; 863 IsChildAgent = true;
864 IsLoggingIn = false;
817 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 865 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
818 Animator = new ScenePresenceAnimator(this); 866 Animator = new ScenePresenceAnimator(this);
819 PresenceType = type; 867 PresenceType = type;
@@ -859,6 +907,33 @@ namespace OpenSim.Region.Framework.Scenes
859 m_stateMachine = new ScenePresenceStateMachine(this); 907 m_stateMachine = new ScenePresenceStateMachine(this);
860 } 908 }
861 909
910 private void RegionHeartbeatEnd(Scene scene)
911 {
912 if (IsChildAgent)
913 return;
914
915 m_movementAnimationUpdateCounter ++;
916 if (m_movementAnimationUpdateCounter >= 2)
917 {
918 m_movementAnimationUpdateCounter = 0;
919 if (Animator != null)
920 {
921 // If the parentID == 0 we are not sitting
922 // if !SitGournd then we are not sitting on the ground
923 // Fairly straightforward, now here comes the twist
924 // if ParentUUID is NOT UUID.Zero, we are looking to
925 // be sat on an object that isn't there yet. Should
926 // be treated as if sat.
927 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
928 Animator.UpdateMovementAnimations();
929 }
930 else
931 {
932 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
933 }
934 }
935 }
936
862 public void RegisterToEvents() 937 public void RegisterToEvents()
863 { 938 {
864 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 939 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -926,17 +1001,46 @@ namespace OpenSim.Region.Framework.Scenes
926 /// </remarks> 1001 /// </remarks>
927 private bool MakeRootAgent(Vector3 pos, bool isFlying) 1002 private bool MakeRootAgent(Vector3 pos, bool isFlying)
928 { 1003 {
929// m_log.InfoFormat(
930// "[SCENE]: Upgrading child to root agent for {0} in {1}",
931// Name, m_scene.RegionInfo.RegionName);
932
933 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
934
935 lock (m_completeMovementLock) 1004 lock (m_completeMovementLock)
936 { 1005 {
937 if (!IsChildAgent) 1006 if (!IsChildAgent)
938 return false; 1007 return false;
939 1008
1009 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
1010
1011 // m_log.InfoFormat(
1012 // "[SCENE]: Upgrading child to root agent for {0} in {1}",
1013 // Name, m_scene.RegionInfo.RegionName);
1014
1015 if (ParentUUID != UUID.Zero)
1016 {
1017 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1018 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1019 if (part == null)
1020 {
1021 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1022 }
1023 else
1024 {
1025 part.ParentGroup.AddAvatar(UUID);
1026 if (part.SitTargetPosition != Vector3.Zero)
1027 part.SitTargetAvatar = UUID;
1028 // ParentPosition = part.GetWorldPosition();
1029 ParentID = part.LocalId;
1030 ParentPart = part;
1031 m_pos = PrevSitOffset;
1032 // pos = ParentPosition;
1033 pos = part.GetWorldPosition();
1034 }
1035 ParentUUID = UUID.Zero;
1036
1037 // Animator.TrySetMovementAnimation("SIT");
1038 }
1039 else
1040 {
1041 IsLoggingIn = false;
1042 }
1043
940 IsChildAgent = false; 1044 IsChildAgent = false;
941 } 1045 }
942 1046
@@ -953,70 +1057,111 @@ namespace OpenSim.Region.Framework.Scenes
953 1057
954 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1058 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
955 1059
956 // Moved this from SendInitialData to ensure that Appearance is initialized 1060 UUID groupUUID = UUID.Zero;
957 // before the inventory is processed in MakeRootAgent. This fixes a race condition 1061 string GroupName = string.Empty;
958 // related to the handling of attachments 1062 ulong groupPowers = 0;
959 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
960 1063
961 if (m_scene.TestBorderCross(pos, Cardinals.E)) 1064 // ----------------------------------
1065 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1066 try
962 { 1067 {
963 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 1068 if (gm != null)
964 pos.X = crossedBorder.BorderLine.Z - 1; 1069 {
1070 groupUUID = ControllingClient.ActiveGroupId;
1071 GroupRecord record = gm.GetGroupRecord(groupUUID);
1072 if (record != null)
1073 GroupName = record.GroupName;
1074 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1075 if (groupMembershipData != null)
1076 groupPowers = groupMembershipData.GroupPowers;
1077 }
1078 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1079 Grouptitle);
965 } 1080 }
966 1081 catch (Exception e)
967 if (m_scene.TestBorderCross(pos, Cardinals.N))
968 { 1082 {
969 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1083 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
970 pos.Y = crossedBorder.BorderLine.Z - 1;
971 } 1084 }
1085 // ------------------------------------
972 1086
973 CheckAndAdjustLandingPoint(ref pos); 1087 if (ParentID == 0)
974
975 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
976 { 1088 {
977 m_log.WarnFormat( 1089 // Moved this from SendInitialData to ensure that Appearance is initialized
978 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1090 // before the inventory is processed in MakeRootAgent. This fixes a race condition
979 pos, Name, UUID); 1091 // related to the handling of attachments
1092 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
980 1093
981 if (pos.X < 0f) pos.X = 0f; 1094 /* RA 20140111: Commented out these TestBorderCross's.
982 if (pos.Y < 0f) pos.Y = 0f; 1095 * Not sure why this code is here. It is not checking all the borders
983 if (pos.Z < 0f) pos.Z = 0f; 1096 * and 'in region' sanity checking is done in CheckAndAdjustLandingPoint and below.
984 } 1097 if (m_scene.TestBorderCross(pos, Cardinals.E))
1098 {
1099 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1100 pos.X = crossedBorder.BorderLine.Z - 1;
1101 }
985 1102
986 float localAVHeight = 1.56f; 1103 if (m_scene.TestBorderCross(pos, Cardinals.N))
987 if (Appearance.AvatarHeight > 0) 1104 {
988 localAVHeight = Appearance.AvatarHeight; 1105 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
1106 pos.Y = crossedBorder.BorderLine.Z - 1;
1107 }
1108 */
989 1109
990 float posZLimit = 0; 1110 CheckAndAdjustLandingPoint(ref pos);
991 1111
992 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1112 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
993 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1113 {
994 1114 m_log.WarnFormat(
995 float newPosZ = posZLimit + localAVHeight / 2; 1115 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
996 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 1116 pos, Name, UUID);
997 {
998 pos.Z = newPosZ;
999 }
1000 AbsolutePosition = pos;
1001 1117
1002 AddToPhysicalScene(isFlying); 1118 if (pos.X < 0f) pos.X = 0f;
1119 if (pos.Y < 0f) pos.Y = 0f;
1120 if (pos.Z < 0f) pos.Z = 0f;
1121 }
1003 1122
1004 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1123 float localAVHeight = 1.56f;
1005 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it 1124 if (Appearance.AvatarHeight > 0)
1006 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset 1125 localAVHeight = Appearance.AvatarHeight;
1007 // the value to a negative position which does not trigger the border cross.
1008 // This may not be the best location for this.
1009 CheckForBorderCrossing();
1010 1126
1011 if (ForceFly) 1127 float posZLimit = 0;
1012 { 1128
1013 Flying = true; 1129 if (pos.X < m_scene.RegionInfo.RegionSizeX && pos.Y < m_scene.RegionInfo.RegionSizeY)
1014 } 1130 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
1015 else if (FlyDisabled) 1131
1016 { 1132 float newPosZ = posZLimit + localAVHeight / 2;
1017 Flying = false; 1133 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
1018 } 1134 {
1135 pos.Z = newPosZ;
1136 }
1137 AbsolutePosition = pos;
1138
1139 if (m_teleportFlags == TeleportFlags.Default)
1140 {
1141 Vector3 vel = Velocity;
1142 AddToPhysicalScene(isFlying);
1143 if (PhysicsActor != null)
1144 PhysicsActor.SetMomentum(vel);
1145 }
1146 else
1147 AddToPhysicalScene(isFlying);
1148
1149 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1150 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1151 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1152 // the value to a negative position which does not trigger the border cross.
1153 // This may not be the best location for this.
1154 CheckForBorderCrossing();
1019 1155
1156 if (ForceFly)
1157 {
1158 Flying = true;
1159 }
1160 else if (FlyDisabled)
1161 {
1162 Flying = false;
1163 }
1164 }
1020 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1165 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
1021 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1166 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1022 // elsewhere anyway 1167 // elsewhere anyway
@@ -1049,6 +1194,11 @@ namespace OpenSim.Region.Framework.Scenes
1049 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1194 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1050 // not transporting the required data. 1195 // not transporting the required data.
1051 // 1196 //
1197 // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
1198 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1199 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1200 // not transporting the required data.
1201 //
1052 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of 1202 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1053 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here 1203 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1054 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. 1204 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
@@ -1057,6 +1207,9 @@ namespace OpenSim.Region.Framework.Scenes
1057 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing 1207 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1058 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the 1208 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1059 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. 1209 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1210 //
1211 // One cannot simply iterate over attachments in a fire and forget thread because this would no longer
1212 // be locked, allowing race conditions if other code changes the attachments list.
1060 List<SceneObjectGroup> attachments = GetAttachments(); 1213 List<SceneObjectGroup> attachments = GetAttachments();
1061 1214
1062 if (attachments.Count > 0) 1215 if (attachments.Count > 0)
@@ -1067,12 +1220,15 @@ namespace OpenSim.Region.Framework.Scenes
1067 // Resume scripts 1220 // Resume scripts
1068 foreach (SceneObjectGroup sog in attachments) 1221 foreach (SceneObjectGroup sog in attachments)
1069 { 1222 {
1223 sog.ScheduleGroupForFullUpdate();
1070 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1224 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1071 sog.ResumeScripts(); 1225 sog.ResumeScripts();
1072 } 1226 }
1073 } 1227 }
1074 } 1228 }
1075 1229
1230 SendAvatarDataToAllAgents();
1231
1076 // send the animations of the other presences to me 1232 // send the animations of the other presences to me
1077 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1233 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1078 { 1234 {
@@ -1083,6 +1239,7 @@ namespace OpenSim.Region.Framework.Scenes
1083 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1239 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1084 // stall on the border crossing since the existing child agent will still have the last movement 1240 // stall on the border crossing since the existing child agent will still have the last movement
1085 // recorded, which stops the input from being processed. 1241 // recorded, which stops the input from being processed.
1242
1086 MovementFlag = 0; 1243 MovementFlag = 0;
1087 1244
1088 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1245 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -1115,12 +1272,16 @@ namespace OpenSim.Region.Framework.Scenes
1115 /// </remarks> 1272 /// </remarks>
1116 public void MakeChildAgent() 1273 public void MakeChildAgent()
1117 { 1274 {
1275 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1276
1118 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1277 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1119 1278
1120 // Reset these so that teleporting in and walking out isn't seen 1279 // Reset these so that teleporting in and walking out isn't seen
1121 // as teleporting back 1280 // as teleporting back
1122 TeleportFlags = TeleportFlags.Default; 1281 TeleportFlags = TeleportFlags.Default;
1123 1282
1283 MovementFlag = 0;
1284
1124 // It looks like Animator is set to null somewhere, and MakeChild 1285 // It looks like Animator is set to null somewhere, and MakeChild
1125 // is called after that. Probably in aborted teleports. 1286 // is called after that. Probably in aborted teleports.
1126 if (Animator == null) 1287 if (Animator == null)
@@ -1128,6 +1289,7 @@ namespace OpenSim.Region.Framework.Scenes
1128 else 1289 else
1129 Animator.ResetAnimations(); 1290 Animator.ResetAnimations();
1130 1291
1292
1131// m_log.DebugFormat( 1293// m_log.DebugFormat(
1132// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1294// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1133// Name, UUID, m_scene.RegionInfo.RegionName); 1295// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1139,6 +1301,7 @@ namespace OpenSim.Region.Framework.Scenes
1139 IsChildAgent = true; 1301 IsChildAgent = true;
1140 m_scene.SwapRootAgentCount(true); 1302 m_scene.SwapRootAgentCount(true);
1141 RemoveFromPhysicalScene(); 1303 RemoveFromPhysicalScene();
1304 ParentID = 0; // Child agents can't be sitting
1142 1305
1143 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1306 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1144 1307
@@ -1154,9 +1317,9 @@ namespace OpenSim.Region.Framework.Scenes
1154 { 1317 {
1155// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1318// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1156 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1319 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1157 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1158 PhysicsActor.UnSubscribeEvents();
1159 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1320 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1321 PhysicsActor.UnSubscribeEvents();
1322 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1160 PhysicsActor = null; 1323 PhysicsActor = null;
1161 } 1324 }
1162// else 1325// else
@@ -1173,7 +1336,7 @@ namespace OpenSim.Region.Framework.Scenes
1173 /// <param name="pos"></param> 1336 /// <param name="pos"></param>
1174 public void Teleport(Vector3 pos) 1337 public void Teleport(Vector3 pos)
1175 { 1338 {
1176 TeleportWithMomentum(pos, null); 1339 TeleportWithMomentum(pos, Vector3.Zero);
1177 } 1340 }
1178 1341
1179 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1342 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1197,6 +1360,41 @@ namespace OpenSim.Region.Framework.Scenes
1197 SendTerseUpdateToAllClients(); 1360 SendTerseUpdateToAllClients();
1198 } 1361 }
1199 1362
1363 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1364 {
1365 CheckLandingPoint(ref newpos);
1366 AbsolutePosition = newpos;
1367
1368 if (newvel.HasValue)
1369 {
1370 if ((Vector3)newvel == Vector3.Zero)
1371 {
1372 if (PhysicsActor != null)
1373 PhysicsActor.SetMomentum(Vector3.Zero);
1374 m_velocity = Vector3.Zero;
1375 }
1376 else
1377 {
1378 if (PhysicsActor != null)
1379 PhysicsActor.SetMomentum((Vector3)newvel);
1380 m_velocity = (Vector3)newvel;
1381
1382 if (rotateToVelXY)
1383 {
1384 Vector3 lookAt = (Vector3)newvel;
1385 lookAt.Z = 0;
1386 lookAt.Normalize();
1387 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1388 return;
1389 }
1390 }
1391 }
1392
1393 SendTerseUpdateToAllClients();
1394 }
1395
1396
1397
1200 public void StopFlying() 1398 public void StopFlying()
1201 { 1399 {
1202 Vector3 pos = AbsolutePosition; 1400 Vector3 pos = AbsolutePosition;
@@ -1385,6 +1583,14 @@ namespace OpenSim.Region.Framework.Scenes
1385 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1583 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1386 } 1584 }
1387 1585
1586 public void SetSize(Vector3 size, float feetoffset)
1587 {
1588// TODO: Merge the physics bits
1589// if (PhysicsActor != null && !IsChildAgent)
1590// PhysicsActor.setAvatarSize(size, feetoffset);
1591
1592 }
1593
1388 private bool WaitForUpdateAgent(IClientAPI client) 1594 private bool WaitForUpdateAgent(IClientAPI client)
1389 { 1595 {
1390 // Before the source region executes UpdateAgent 1596 // Before the source region executes UpdateAgent
@@ -1444,7 +1650,8 @@ namespace OpenSim.Region.Framework.Scenes
1444 1650
1445 Vector3 look = Velocity; 1651 Vector3 look = Velocity;
1446 1652
1447 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1653 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1654 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1448 { 1655 {
1449 look = new Vector3(0.99f, 0.042f, 0); 1656 look = new Vector3(0.99f, 0.042f, 0);
1450 } 1657 }
@@ -1514,11 +1721,12 @@ namespace OpenSim.Region.Framework.Scenes
1514 { 1721 {
1515 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1722 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1516 if (m_agentTransfer != null) 1723 if (m_agentTransfer != null)
1517 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1724 m_agentTransfer.EnableChildAgents(this);
1518 1725
1519 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1726 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1520 if (friendsModule != null) 1727 if (friendsModule != null)
1521 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1728 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1729
1522 } 1730 }
1523 1731
1524 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1732 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1544,36 +1752,69 @@ namespace OpenSim.Region.Framework.Scenes
1544 /// <param name="collisionPoint"></param> 1752 /// <param name="collisionPoint"></param>
1545 /// <param name="localid"></param> 1753 /// <param name="localid"></param>
1546 /// <param name="distance"></param> 1754 /// <param name="distance"></param>
1755 ///
1756
1757 private void UpdateCameraCollisionPlane(Vector4 plane)
1758 {
1759 if (m_lastCameraCollisionPlane != plane)
1760 {
1761 m_lastCameraCollisionPlane = plane;
1762 ControllingClient.SendCameraConstraint(plane);
1763 }
1764 }
1765
1547 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1766 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1548 { 1767 {
1549 const float POSITION_TOLERANCE = 0.02f; 1768 const float POSITION_TOLERANCE = 0.02f;
1550 const float VELOCITY_TOLERANCE = 0.02f;
1551 const float ROTATION_TOLERANCE = 0.02f; 1769 const float ROTATION_TOLERANCE = 0.02f;
1552 1770
1553 if (m_followCamAuto) 1771 m_doingCamRayCast = false;
1772 if (hitYN && localid != LocalId)
1554 { 1773 {
1555 if (hitYN) 1774 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1775 bool IsPrim = group != null;
1776 if (IsPrim)
1556 { 1777 {
1557 CameraConstraintActive = true; 1778 SceneObjectPart part = group.GetPart(localid);
1558 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1779 if (part != null && !part.VolumeDetectActive)
1559 1780 {
1560 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1781 CameraConstraintActive = true;
1561 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1782 pNormal.X = (float) Math.Round(pNormal.X, 2);
1783 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1784 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1785 pNormal.Normalize();
1786 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1787 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1788 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1789
1790 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1791 Vector3.Dot(collisionPoint, pNormal));
1792 UpdateCameraCollisionPlane(plane);
1793 }
1562 } 1794 }
1563 else 1795 else
1564 { 1796 {
1565 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1797 CameraConstraintActive = true;
1566 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1798 pNormal.X = (float) Math.Round(pNormal.X, 2);
1567 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1799 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1568 { 1800 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1569 if (CameraConstraintActive) 1801 pNormal.Normalize();
1570 { 1802 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1571 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1803 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1572 CameraConstraintActive = false; 1804 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1573 } 1805
1574 } 1806 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1807 Vector3.Dot(collisionPoint, pNormal));
1808 UpdateCameraCollisionPlane(plane);
1575 } 1809 }
1576 } 1810 }
1811 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1812 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1813 {
1814 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1815 UpdateCameraCollisionPlane(plane);
1816 CameraConstraintActive = false;
1817 }
1577 } 1818 }
1578 1819
1579 /// <summary> 1820 /// <summary>
@@ -1647,6 +1888,41 @@ namespace OpenSim.Region.Framework.Scenes
1647 StandUp(); 1888 StandUp();
1648 } 1889 }
1649 1890
1891 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1892 // this exclude checks may not be complete
1893
1894 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1895 {
1896 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1897 {
1898 Vector3 posAdjusted = AbsolutePosition;
1899// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1900 posAdjusted.Z += 1.0f; // viewer current camera focus point
1901 Vector3 tocam = CameraPosition - posAdjusted;
1902 tocam.X = (float)Math.Round(tocam.X, 1);
1903 tocam.Y = (float)Math.Round(tocam.Y, 1);
1904 tocam.Z = (float)Math.Round(tocam.Z, 1);
1905
1906 float distTocamlen = tocam.Length();
1907 if (distTocamlen > 0.3f)
1908 {
1909 tocam *= (1.0f / distTocamlen);
1910 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1911 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1912 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1913
1914 m_doingCamRayCast = true;
1915 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1916 }
1917 }
1918 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1919 {
1920 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1921 UpdateCameraCollisionPlane(plane);
1922 CameraConstraintActive = false;
1923 }
1924 }
1925
1650 uint flagsForScripts = (uint)flags; 1926 uint flagsForScripts = (uint)flags;
1651 flags = RemoveIgnoredControls(flags, IgnoredControls); 1927 flags = RemoveIgnoredControls(flags, IgnoredControls);
1652 1928
@@ -2127,7 +2403,7 @@ namespace OpenSim.Region.Framework.Scenes
2127 if (regionCombinerModule != null) 2403 if (regionCombinerModule != null)
2128 regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); 2404 regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
2129 else 2405 else
2130 regionSize = new Vector2(Constants.RegionSize); 2406 regionSize = new Vector2(m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY);
2131 2407
2132 if (pos.X < 0 || pos.X >= regionSize.X 2408 if (pos.X < 0 || pos.X >= regionSize.X
2133 || pos.Y < 0 || pos.Y >= regionSize.Y 2409 || pos.Y < 0 || pos.Y >= regionSize.Y
@@ -2145,8 +2421,8 @@ namespace OpenSim.Region.Framework.Scenes
2145// } 2421// }
2146 2422
2147 // Get terrain height for sub-region in a megaregion if necessary 2423 // Get terrain height for sub-region in a megaregion if necessary
2148 int X = (int)((m_scene.RegionInfo.RegionLocX * Constants.RegionSize) + pos.X); 2424 int X = (int)((m_scene.RegionInfo.WorldLocX) + pos.X);
2149 int Y = (int)((m_scene.RegionInfo.RegionLocY * Constants.RegionSize) + pos.Y); 2425 int Y = (int)((m_scene.RegionInfo.WorldLocY) + pos.Y);
2150 GridRegion target_region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y); 2426 GridRegion target_region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y);
2151 // If X and Y is NaN, target_region will be null 2427 // If X and Y is NaN, target_region will be null
2152 if (target_region == null) 2428 if (target_region == null)
@@ -2157,7 +2433,7 @@ namespace OpenSim.Region.Framework.Scenes
2157 if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene)) 2433 if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene))
2158 targetScene = m_scene; 2434 targetScene = m_scene;
2159 2435
2160 float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % Constants.RegionSize), (int)(pos.Y % Constants.RegionSize)]; 2436 float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % regionSize.X), (int)(pos.Y % regionSize.Y)];
2161 pos.Z = Math.Max(terrainHeight, pos.Z); 2437 pos.Z = Math.Max(terrainHeight, pos.Z);
2162 2438
2163 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is 2439 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is
@@ -2207,7 +2483,8 @@ namespace OpenSim.Region.Framework.Scenes
2207// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2483// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2208 2484
2209 MovingToTarget = false; 2485 MovingToTarget = false;
2210 MoveToPositionTarget = Vector3.Zero; 2486// MoveToPositionTarget = Vector3.Zero;
2487 m_forceToApply = null; // cancel possible last action
2211 2488
2212 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2489 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
2213 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2490 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2230,6 +2507,9 @@ namespace OpenSim.Region.Framework.Scenes
2230 2507
2231 if (satOnObject) 2508 if (satOnObject)
2232 { 2509 {
2510 PrevSitOffset = m_pos; // Save sit offset
2511 UnRegisterSeatControls(part.ParentGroup.UUID);
2512
2233 TaskInventoryDictionary taskIDict = part.TaskInventory; 2513 TaskInventoryDictionary taskIDict = part.TaskInventory;
2234 if (taskIDict != null) 2514 if (taskIDict != null)
2235 { 2515 {
@@ -2245,6 +2525,7 @@ namespace OpenSim.Region.Framework.Scenes
2245 } 2525 }
2246 } 2526 }
2247 2527
2528 part.ParentGroup.DeleteAvatar(UUID);
2248 Vector3 sitPartWorldPosition = part.GetWorldPosition(); 2529 Vector3 sitPartWorldPosition = part.GetWorldPosition();
2249 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2530 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2250 2531
@@ -2305,6 +2586,9 @@ namespace OpenSim.Region.Framework.Scenes
2305 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2586 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2306 } 2587 }
2307 2588
2589 else if (PhysicsActor == null)
2590 AddToPhysicalScene(false);
2591
2308 Animator.TrySetMovementAnimation("STAND"); 2592 Animator.TrySetMovementAnimation("STAND");
2309 TriggerScenePresenceUpdated(); 2593 TriggerScenePresenceUpdated();
2310 } 2594 }
@@ -2353,11 +2637,8 @@ namespace OpenSim.Region.Framework.Scenes
2353 if (part == null) 2637 if (part == null)
2354 return; 2638 return;
2355 2639
2356 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2357 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2358
2359 if (PhysicsActor != null) 2640 if (PhysicsActor != null)
2360 m_sitAvatarHeight = PhysicsActor.Size.Z; 2641 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2361 2642
2362 bool canSit = false; 2643 bool canSit = false;
2363 2644
@@ -2384,33 +2665,32 @@ namespace OpenSim.Region.Framework.Scenes
2384 } 2665 }
2385 else 2666 else
2386 { 2667 {
2668 if (PhysicsSit(part,offset)) // physics engine
2669 return;
2670
2387 Vector3 pos = part.AbsolutePosition + offset; 2671 Vector3 pos = part.AbsolutePosition + offset;
2388 2672
2389 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2673 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2390 { 2674 {
2391// m_log.DebugFormat(
2392// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2393// Name, part.Name, part.LocalId);
2394
2395 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2675 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2396 canSit = true; 2676 canSit = true;
2397 } 2677 }
2398// else
2399// {
2400// m_log.DebugFormat(
2401// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2402// Name, part.Name, part.LocalId);
2403// }
2404 } 2678 }
2405 2679
2406 if (canSit) 2680 if (canSit)
2407 { 2681 {
2682
2408 if (PhysicsActor != null) 2683 if (PhysicsActor != null)
2409 { 2684 {
2410 // We can remove the physicsActor until they stand up. 2685 // We can remove the physicsActor until they stand up.
2411 RemoveFromPhysicalScene(); 2686 RemoveFromPhysicalScene();
2412 } 2687 }
2413 2688
2689 if (MovingToTarget)
2690 ResetMoveToTarget();
2691
2692 Velocity = Vector3.Zero;
2693
2414 part.AddSittingAvatar(UUID); 2694 part.AddSittingAvatar(UUID);
2415 2695
2416 cameraAtOffset = part.GetCameraAtOffset(); 2696 cameraAtOffset = part.GetCameraAtOffset();
@@ -2454,14 +2734,6 @@ namespace OpenSim.Region.Framework.Scenes
2454 m_requestedSitTargetID = part.LocalId; 2734 m_requestedSitTargetID = part.LocalId;
2455 m_requestedSitTargetUUID = part.UUID; 2735 m_requestedSitTargetUUID = part.UUID;
2456 2736
2457// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2458
2459 if (m_scene.PhysicsScene.SupportsRayCast())
2460 {
2461 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2462 //SitRayCastAvatarPosition(part);
2463 //return;
2464 }
2465 } 2737 }
2466 else 2738 else
2467 { 2739 {
@@ -2471,197 +2743,115 @@ namespace OpenSim.Region.Framework.Scenes
2471 SendSitResponse(targetID, offset, Quaternion.Identity); 2743 SendSitResponse(targetID, offset, Quaternion.Identity);
2472 } 2744 }
2473 2745
2474 /* 2746 // returns false if does not suport so older sit can be tried
2475 public void SitRayCastAvatarPosition(SceneObjectPart part) 2747 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2476 {
2477 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2478 Vector3 StartRayCastPosition = AbsolutePosition;
2479 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2480 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2481 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2482 }
2483
2484 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2485 { 2748 {
2486 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2749// TODO: Pull in these bits
2487 if (part != null) 2750 return false;
2488 { 2751/*
2489 if (hitYN) 2752 if (part == null || part.ParentGroup.IsAttachment)
2490 {
2491 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2492 {
2493 SitRaycastFindEdge(collisionPoint, normal);
2494 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2495 }
2496 else
2497 {
2498 SitRayCastAvatarPositionCameraZ(part);
2499 }
2500 }
2501 else
2502 {
2503 SitRayCastAvatarPositionCameraZ(part);
2504 }
2505 }
2506 else
2507 { 2753 {
2508 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2754 return true;
2509 m_requestedSitTargetUUID = UUID.Zero;
2510 m_requestedSitTargetID = 0;
2511 m_requestedSitOffset = Vector3.Zero;
2512 } 2755 }
2513 2756
2514 } 2757 if ( m_scene.PhysicsScene == null)
2515 2758 return false;
2516 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2517 {
2518 // Next, try to raycast from the camera Z position
2519 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2520 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2521 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2522 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2523 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2524 }
2525 2759
2526 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2760 if (part.PhysActor == null)
2527 {
2528 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2529 if (part != null)
2530 { 2761 {
2531 if (hitYN) 2762 // none physcis shape
2532 { 2763 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2533 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2764 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2534 {
2535 SitRaycastFindEdge(collisionPoint, normal);
2536 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2537 }
2538 else
2539 {
2540 SitRayCastCameraPosition(part);
2541 }
2542 }
2543 else 2765 else
2544 { 2766 { // non physical phantom TODO
2545 SitRayCastCameraPosition(part); 2767 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2768 return false;
2546 } 2769 }
2547 } 2770 return true;
2548 else
2549 {
2550 ControllingClient.SendAlertMessage("Sit position no longer exists");
2551 m_requestedSitTargetUUID = UUID.Zero;
2552 m_requestedSitTargetID = 0;
2553 m_requestedSitOffset = Vector3.Zero;
2554 } 2771 }
2555 2772
2556 }
2557 2773
2558 public void SitRayCastCameraPosition(SceneObjectPart part) 2774 // not doing autopilot
2559 { 2775 m_requestedSitTargetID = 0;
2560 // Next, try to raycast from the camera position
2561 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2562 Vector3 StartRayCastPosition = CameraPosition;
2563 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2564 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2565 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2566 }
2567 2776
2568 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2777 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2569 { 2778 return true;
2570 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2571 if (part != null)
2572 {
2573 if (hitYN)
2574 {
2575 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2576 {
2577 SitRaycastFindEdge(collisionPoint, normal);
2578 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2579 }
2580 else
2581 {
2582 SitRayHorizontal(part);
2583 }
2584 }
2585 else
2586 {
2587 SitRayHorizontal(part);
2588 }
2589 }
2590 else
2591 {
2592 ControllingClient.SendAlertMessage("Sit position no longer exists");
2593 m_requestedSitTargetUUID = UUID.Zero;
2594 m_requestedSitTargetID = 0;
2595 m_requestedSitOffset = Vector3.Zero;
2596 }
2597 2779
2780 return false;
2781*/
2598 } 2782 }
2599 2783
2600 public void SitRayHorizontal(SceneObjectPart part) 2784
2785 private bool CanEnterLandPosition(Vector3 testPos)
2601 { 2786 {
2602 // Next, try to raycast from the avatar position to fwd 2787 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2603 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2788
2604 Vector3 StartRayCastPosition = CameraPosition; 2789 if (land == null || land.LandData.Name == "NO_LAND")
2605 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2790 return true;
2606 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2791
2607 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2792 return land.CanBeOnThisLand(UUID,testPos.Z);
2608 } 2793 }
2609 2794
2610 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2795 // status
2796 // < 0 ignore
2797 // 0 bad sit spot
2798 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2611 { 2799 {
2612 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2800 if (status < 0)
2613 if (part != null) 2801 return;
2802
2803 if (status == 0)
2614 { 2804 {
2615 if (hitYN) 2805 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2616 { 2806 return;
2617 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2618 {
2619 SitRaycastFindEdge(collisionPoint, normal);
2620 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2621 // Next, try to raycast from the camera position
2622 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2623 Vector3 StartRayCastPosition = CameraPosition;
2624 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2625 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2626 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2627 }
2628 else
2629 {
2630 ControllingClient.SendAlertMessage("Sit position not accessable.");
2631 m_requestedSitTargetUUID = UUID.Zero;
2632 m_requestedSitTargetID = 0;
2633 m_requestedSitOffset = Vector3.Zero;
2634 }
2635 }
2636 else
2637 {
2638 ControllingClient.SendAlertMessage("Sit position not accessable.");
2639 m_requestedSitTargetUUID = UUID.Zero;
2640 m_requestedSitTargetID = 0;
2641 m_requestedSitOffset = Vector3.Zero;
2642 }
2643 } 2807 }
2644 else 2808
2809 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2810 if (part == null)
2811 return;
2812
2813 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2814 if(!CanEnterLandPosition(targetPos))
2645 { 2815 {
2646 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2816 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2647 m_requestedSitTargetUUID = UUID.Zero; 2817 return;
2648 m_requestedSitTargetID = 0;
2649 m_requestedSitOffset = Vector3.Zero;
2650 } 2818 }
2651 2819
2652 } 2820 RemoveFromPhysicalScene();
2653 2821
2654 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2822 if (MovingToTarget)
2655 { 2823 ResetMoveToTarget();
2656 int i = 0; 2824
2657 //throw new NotImplementedException(); 2825 Velocity = Vector3.Zero;
2658 //m_requestedSitTargetUUID = UUID.Zero; 2826
2659 //m_requestedSitTargetID = 0; 2827 part.AddSittingAvatar(UUID);
2660 //m_requestedSitOffset = Vector3.Zero;
2661 2828
2662 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2829 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2830 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2831 bool forceMouselook = part.GetForceMouselook();
2832
2833 ControllingClient.SendSitResponse(
2834 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2835
2836 // not using autopilot
2837
2838 Rotation = Orientation;
2839 m_pos = offset;
2840
2841 m_requestedSitTargetID = 0;
2842 part.ParentGroup.AddAvatar(UUID);
2843
2844 ParentPart = part;
2845 ParentID = part.LocalId;
2846 if(status == 3)
2847 Animator.TrySetMovementAnimation("SIT_GROUND");
2848 else
2849 Animator.TrySetMovementAnimation("SIT");
2850 SendAvatarDataToAllAgents();
2851
2852 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2663 } 2853 }
2664 */ 2854
2665 2855
2666 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2856 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2667 { 2857 {
@@ -2681,6 +2871,7 @@ namespace OpenSim.Region.Framework.Scenes
2681 return; 2871 return;
2682 } 2872 }
2683 2873
2874
2684 if (part.SitTargetAvatar == UUID) 2875 if (part.SitTargetAvatar == UUID)
2685 { 2876 {
2686 Vector3 sitTargetPos = part.SitTargetPosition; 2877 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2695,7 +2886,28 @@ namespace OpenSim.Region.Framework.Scenes
2695 2886
2696 //Quaternion result = (sitTargetOrient * vq) * nq; 2887 //Quaternion result = (sitTargetOrient * vq) * nq;
2697 2888
2698 Vector3 newPos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2889 double x, y, z, m;
2890
2891 Quaternion r = sitTargetOrient;
2892 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2893
2894 if (Math.Abs(1.0 - m) > 0.000001)
2895 {
2896 m = 1.0 / Math.Sqrt(m);
2897 r.X *= (float)m;
2898 r.Y *= (float)m;
2899 r.Z *= (float)m;
2900 r.W *= (float)m;
2901 }
2902
2903 x = 2 * (r.X * r.Z + r.Y * r.W);
2904 y = 2 * (-r.X * r.W + r.Y * r.Z);
2905 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2906
2907 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2908 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2909
2910 Vector3 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2699 Quaternion newRot; 2911 Quaternion newRot;
2700 2912
2701 if (part.IsRoot) 2913 if (part.IsRoot)
@@ -2712,6 +2924,8 @@ namespace OpenSim.Region.Framework.Scenes
2712 2924
2713 m_pos = newPos; 2925 m_pos = newPos;
2714 Rotation = newRot; 2926 Rotation = newRot;
2927
2928// ParentPosition = part.AbsolutePosition;
2715 } 2929 }
2716 else 2930 else
2717 { 2931 {
@@ -2719,11 +2933,14 @@ namespace OpenSim.Region.Framework.Scenes
2719 // being sat upon. 2933 // being sat upon.
2720 m_pos -= part.GroupPosition; 2934 m_pos -= part.GroupPosition;
2721 2935
2936// ParentPosition = part.AbsolutePosition;
2937
2722// m_log.DebugFormat( 2938// m_log.DebugFormat(
2723// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2939// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
2724// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); 2940// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
2725 } 2941 }
2726 2942
2943 part.ParentGroup.AddAvatar(UUID);
2727 ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID); 2944 ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
2728 ParentID = m_requestedSitTargetID; 2945 ParentID = m_requestedSitTargetID;
2729 m_AngularVelocity = Vector3.Zero; 2946 m_AngularVelocity = Vector3.Zero;
@@ -2834,8 +3051,8 @@ namespace OpenSim.Region.Framework.Scenes
2834 direc.Z *= 2.6f; 3051 direc.Z *= 2.6f;
2835 3052
2836 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 3053 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2837 Animator.TrySetMovementAnimation("PREJUMP"); 3054// Animator.TrySetMovementAnimation("PREJUMP");
2838 Animator.TrySetMovementAnimation("JUMP"); 3055// Animator.TrySetMovementAnimation("JUMP");
2839 } 3056 }
2840 } 3057 }
2841 } 3058 }
@@ -2844,6 +3061,7 @@ namespace OpenSim.Region.Framework.Scenes
2844 3061
2845 // TODO: Add the force instead of only setting it to support multiple forces per frame? 3062 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2846 m_forceToApply = direc; 3063 m_forceToApply = direc;
3064 Animator.UpdateMovementAnimations();
2847 } 3065 }
2848 3066
2849 #endregion 3067 #endregion
@@ -2861,16 +3079,12 @@ namespace OpenSim.Region.Framework.Scenes
2861 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 3079 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2862 // grab the latest PhysicsActor velocity, whereas m_velocity is often 3080 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2863 // storing a requested force instead of an actual traveling velocity 3081 // storing a requested force instead of an actual traveling velocity
3082 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
3083 SendAvatarDataToAllAgents();
2864 3084
2865 // Throw away duplicate or insignificant updates 3085 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2866 if ( 3086 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2867 // If the velocity has become zero, send it no matter what. 3087 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2868 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2869 // otherwise, if things have changed reasonably, send the update
2870 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2871 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2872 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2873
2874 { 3088 {
2875 SendTerseUpdateToAllClients(); 3089 SendTerseUpdateToAllClients();
2876 3090
@@ -3031,8 +3245,8 @@ namespace OpenSim.Region.Framework.Scenes
3031 // appearance goes into the avatar update packet 3245 // appearance goes into the avatar update packet
3032 SendAvatarDataToAllAgents(); 3246 SendAvatarDataToAllAgents();
3033 3247
3034 // This invocation always shows up in the viewer logs as an error. 3248 // This invocation always shows up in the viewer logs as an error. Is it needed?
3035 // SendAppearanceToAgent(this); 3249 SendAppearanceToAgent(this);
3036 3250
3037 // If we are using the the cached appearance then send it out to everyone 3251 // If we are using the the cached appearance then send it out to everyone
3038 if (cachedappearance) 3252 if (cachedappearance)
@@ -3063,6 +3277,8 @@ namespace OpenSim.Region.Framework.Scenes
3063 return; 3277 return;
3064 } 3278 }
3065 3279
3280 m_lastSize = Appearance.AvatarSize;
3281
3066 int count = 0; 3282 int count = 0;
3067 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 3283 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3068 { 3284 {
@@ -3170,6 +3386,8 @@ namespace OpenSim.Region.Framework.Scenes
3170 3386
3171 avatar.ControllingClient.SendAppearance( 3387 avatar.ControllingClient.SendAppearance(
3172 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3388 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3389
3390
3173 } 3391 }
3174 3392
3175 #endregion 3393 #endregion
@@ -3243,17 +3461,22 @@ namespace OpenSim.Region.Framework.Scenes
3243 3461
3244 // If we don't have a PhysActor, we can't cross anyway 3462 // If we don't have a PhysActor, we can't cross anyway
3245 // Also don't do this while sat, sitting avatars cross with the 3463 // Also don't do this while sat, sitting avatars cross with the
3246 // object they sit on. 3464 // object they sit on. ParentUUID denoted a pending sit, don't
3247 if (ParentID != 0 || PhysicsActor == null) 3465 // interfere with it.
3466 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3248 return; 3467 return;
3249 3468
3250 if (!IsInTransit) 3469 if (!IsInTransit)
3251 { 3470 {
3252 Vector3 pos2 = AbsolutePosition; 3471 Vector3 pos2 = AbsolutePosition;
3472 Vector3 origPosition = pos2;
3253 Vector3 vel = Velocity; 3473 Vector3 vel = Velocity;
3254 int neighbor = 0; 3474 int neighbor = 0;
3255 int[] fix = new int[2]; 3475 int[] fix = new int[2];
3256 3476
3477 // Compute the avatar position in the next physics tick.
3478 // If the avatar will be crossing, we force the crossing to happen now
3479 // in the hope that this will make the avatar movement smoother when crossing.
3257 float timeStep = 0.1f; 3480 float timeStep = 0.1f;
3258 pos2.X = pos2.X + (vel.X * timeStep); 3481 pos2.X = pos2.X + (vel.X * timeStep);
3259 pos2.Y = pos2.Y + (vel.Y * timeStep); 3482 pos2.Y = pos2.Y + (vel.Y * timeStep);
@@ -3261,111 +3484,44 @@ namespace OpenSim.Region.Framework.Scenes
3261 3484
3262 if (!IsInTransit) 3485 if (!IsInTransit)
3263 { 3486 {
3264// m_log.DebugFormat( 3487 if (!m_scene.PositionIsInCurrentRegion(pos2))
3265// "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}",
3266// pos2, Name, Scene.Name);
3267
3268 // Checks if where it's headed exists a region
3269 bool needsTransit = false;
3270 if (m_scene.TestBorderCross(pos2, Cardinals.W))
3271 { 3488 {
3272 if (m_scene.TestBorderCross(pos2, Cardinals.S)) 3489 m_log.DebugFormat("{0} CheckForBorderCrossing: position outside region. {1} in {2} at pos {3}",
3490 LogHeader, Name, Scene.Name, pos2);
3491
3492 // Disconnect from the current region
3493 bool isFlying = Flying;
3494 RemoveFromPhysicalScene();
3495 // pos2 is the forcasted position so make that the 'current' position so the crossing
3496 // code will move us into the newly addressed region.
3497 m_pos = pos2;
3498 if (CrossToNewRegion())
3273 { 3499 {
3274 needsTransit = true; 3500 AddToPhysicalScene(isFlying);
3275 neighbor = m_scene.HaveNeighbor(Cardinals.SW, ref fix);
3276 }
3277 else if (m_scene.TestBorderCross(pos2, Cardinals.N))
3278 {
3279 needsTransit = true;
3280 neighbor = m_scene.HaveNeighbor(Cardinals.NW, ref fix);
3281 } 3501 }
3282 else 3502 else
3283 { 3503 {
3284 needsTransit = true; 3504 // Tried to make crossing happen but it failed.
3285 neighbor = m_scene.HaveNeighbor(Cardinals.W, ref fix);
3286 }
3287 }
3288 else if (m_scene.TestBorderCross(pos2, Cardinals.E))
3289 {
3290 if (m_scene.TestBorderCross(pos2, Cardinals.S))
3291 {
3292 needsTransit = true;
3293 neighbor = m_scene.HaveNeighbor(Cardinals.SE, ref fix);
3294 }
3295 else if (m_scene.TestBorderCross(pos2, Cardinals.N))
3296 {
3297 needsTransit = true;
3298 neighbor = m_scene.HaveNeighbor(Cardinals.NE, ref fix);
3299 }
3300 else
3301 {
3302 needsTransit = true;
3303 neighbor = m_scene.HaveNeighbor(Cardinals.E, ref fix);
3304 }
3305 }
3306 else if (m_scene.TestBorderCross(pos2, Cardinals.S))
3307 {
3308 needsTransit = true;
3309 neighbor = m_scene.HaveNeighbor(Cardinals.S, ref fix);
3310 }
3311 else if (m_scene.TestBorderCross(pos2, Cardinals.N))
3312 {
3313 needsTransit = true;
3314 neighbor = m_scene.HaveNeighbor(Cardinals.N, ref fix);
3315 }
3316
3317 // Makes sure avatar does not end up outside region
3318 if (neighbor <= 0)
3319 {
3320 if (needsTransit)
3321 {
3322 if (m_requestedSitTargetUUID == UUID.Zero) 3505 if (m_requestedSitTargetUUID == UUID.Zero)
3323 { 3506 {
3324 bool isFlying = Flying; 3507 m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader);
3325 RemoveFromPhysicalScene(); 3508 const float borderFudge = 0.1f;
3326 3509
3327 Vector3 pos = AbsolutePosition; 3510 if (origPosition.X < 0)
3328 if (AbsolutePosition.X < 0) 3511 origPosition.X = borderFudge;
3329 pos.X += Velocity.X * 2; 3512 else if (origPosition.X > (float)m_scene.RegionInfo.RegionSizeX)
3330 else if (AbsolutePosition.X > Constants.RegionSize) 3513 origPosition.X = (float)m_scene.RegionInfo.RegionSizeX - borderFudge;
3331 pos.X -= Velocity.X * 2; 3514 if (origPosition.Y < 0)
3332 if (AbsolutePosition.Y < 0) 3515 origPosition.Y = borderFudge;
3333 pos.Y += Velocity.Y * 2; 3516 else if (origPosition.Y > (float)m_scene.RegionInfo.RegionSizeY)
3334 else if (AbsolutePosition.Y > Constants.RegionSize) 3517 origPosition.Y = (float)m_scene.RegionInfo.RegionSizeY - borderFudge;
3335 pos.Y -= Velocity.Y * 2;
3336 Velocity = Vector3.Zero; 3518 Velocity = Vector3.Zero;
3337 AbsolutePosition = pos; 3519 AbsolutePosition = origPosition;
3338
3339// m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition);
3340
3341 AddToPhysicalScene(isFlying);
3342 }
3343 }
3344 }
3345 else if (neighbor > 0)
3346 {
3347 if (!CrossToNewRegion())
3348 {
3349 if (m_requestedSitTargetUUID == UUID.Zero)
3350 {
3351 bool isFlying = Flying;
3352 RemoveFromPhysicalScene();
3353
3354 Vector3 pos = AbsolutePosition;
3355 if (AbsolutePosition.X < 0)
3356 pos.X += Velocity.X * 2;
3357 else if (AbsolutePosition.X > Constants.RegionSize)
3358 pos.X -= Velocity.X * 2;
3359 if (AbsolutePosition.Y < 0)
3360 pos.Y += Velocity.Y * 2;
3361 else if (AbsolutePosition.Y > Constants.RegionSize)
3362 pos.Y -= Velocity.Y * 2;
3363 Velocity = Vector3.Zero;
3364 AbsolutePosition = pos;
3365 3520
3366 AddToPhysicalScene(isFlying); 3521 AddToPhysicalScene(isFlying);
3367 } 3522 }
3368 } 3523 }
3524
3369 } 3525 }
3370 } 3526 }
3371 else 3527 else
@@ -3407,7 +3563,7 @@ namespace OpenSim.Region.Framework.Scenes
3407 3563
3408 // Put the child agent back at the center 3564 // Put the child agent back at the center
3409 AbsolutePosition 3565 AbsolutePosition
3410 = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); 3566 = new Vector3(((float)m_scene.RegionInfo.RegionSizeX * 0.5f), ((float)m_scene.RegionInfo.RegionSizeY * 0.5f), 70);
3411 3567
3412 Animator.ResetAnimations(); 3568 Animator.ResetAnimations();
3413 } 3569 }
@@ -3434,9 +3590,7 @@ namespace OpenSim.Region.Framework.Scenes
3434 if (handle != Scene.RegionInfo.RegionHandle) 3590 if (handle != Scene.RegionInfo.RegionHandle)
3435 { 3591 {
3436 uint x, y; 3592 uint x, y;
3437 Utils.LongToUInts(handle, out x, out y); 3593 Util.RegionHandleToRegionLoc(handle, out x, out y);
3438 x = x / Constants.RegionSize;
3439 y = y / Constants.RegionSize;
3440 3594
3441// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); 3595// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
3442// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); 3596// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
@@ -3517,8 +3671,9 @@ namespace OpenSim.Region.Framework.Scenes
3517 return; 3671 return;
3518 3672
3519 //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); 3673 //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY);
3520 int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; 3674 // Find the distance (in meters) between the two regions
3521 int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; 3675 uint shiftx = Util.RegionToWorldLoc(rRegionX - tRegionX);
3676 uint shifty = Util.RegionToWorldLoc(rRegionY - tRegionY);
3522 3677
3523 Vector3 offset = new Vector3(shiftx, shifty, 0f); 3678 Vector3 offset = new Vector3(shiftx, shifty, 0f);
3524 3679
@@ -3588,6 +3743,9 @@ namespace OpenSim.Region.Framework.Scenes
3588 cAgent.AlwaysRun = SetAlwaysRun; 3743 cAgent.AlwaysRun = SetAlwaysRun;
3589 3744
3590 cAgent.Appearance = new AvatarAppearance(Appearance); 3745 cAgent.Appearance = new AvatarAppearance(Appearance);
3746
3747 cAgent.ParentPart = ParentUUID;
3748 cAgent.SitOffset = PrevSitOffset;
3591 3749
3592 lock (scriptedcontrols) 3750 lock (scriptedcontrols)
3593 { 3751 {
@@ -3596,7 +3754,7 @@ namespace OpenSim.Region.Framework.Scenes
3596 3754
3597 foreach (ScriptControllers c in scriptedcontrols.Values) 3755 foreach (ScriptControllers c in scriptedcontrols.Values)
3598 { 3756 {
3599 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3757 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3600 } 3758 }
3601 cAgent.Controllers = controls; 3759 cAgent.Controllers = controls;
3602 } 3760 }
@@ -3630,6 +3788,8 @@ namespace OpenSim.Region.Framework.Scenes
3630 CameraAtAxis = cAgent.AtAxis; 3788 CameraAtAxis = cAgent.AtAxis;
3631 CameraLeftAxis = cAgent.LeftAxis; 3789 CameraLeftAxis = cAgent.LeftAxis;
3632 CameraUpAxis = cAgent.UpAxis; 3790 CameraUpAxis = cAgent.UpAxis;
3791 ParentUUID = cAgent.ParentPart;
3792 PrevSitOffset = cAgent.SitOffset;
3633 3793
3634 // When we get to the point of re-computing neighbors everytime this 3794 // When we get to the point of re-computing neighbors everytime this
3635 // changes, then start using the agent's drawdistance rather than the 3795 // changes, then start using the agent's drawdistance rather than the
@@ -3667,6 +3827,7 @@ namespace OpenSim.Region.Framework.Scenes
3667 foreach (ControllerData c in cAgent.Controllers) 3827 foreach (ControllerData c in cAgent.Controllers)
3668 { 3828 {
3669 ScriptControllers sc = new ScriptControllers(); 3829 ScriptControllers sc = new ScriptControllers();
3830 sc.objectID = c.ObjectID;
3670 sc.itemID = c.ItemID; 3831 sc.itemID = c.ItemID;
3671 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3832 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3672 sc.eventControls = (ScriptControlled)c.EventControls; 3833 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3732,20 +3893,27 @@ namespace OpenSim.Region.Framework.Scenes
3732 } 3893 }
3733 3894
3734 if (Appearance.AvatarHeight == 0) 3895 if (Appearance.AvatarHeight == 0)
3735 Appearance.SetHeight(); 3896// Appearance.SetHeight();
3897 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3736 3898
3737 PhysicsScene scene = m_scene.PhysicsScene; 3899 PhysicsScene scene = m_scene.PhysicsScene;
3738 3900
3739 Vector3 pVec = AbsolutePosition; 3901 Vector3 pVec = AbsolutePosition;
3740 3902
3903/*
3741 PhysicsActor = scene.AddAvatar( 3904 PhysicsActor = scene.AddAvatar(
3742 LocalId, Firstname + "." + Lastname, pVec, 3905 LocalId, Firstname + "." + Lastname, pVec,
3743 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3906 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3907*/
3908
3909 PhysicsActor = scene.AddAvatar(
3910 LocalId, Firstname + "." + Lastname, pVec,
3911 Appearance.AvatarBoxSize, isFlying);
3744 3912
3745 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3913 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3746 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3914 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3747 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3915 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3748 PhysicsActor.SubscribeEvents(500); 3916 PhysicsActor.SubscribeEvents(100);
3749 PhysicsActor.LocalID = LocalId; 3917 PhysicsActor.LocalID = LocalId;
3750 } 3918 }
3751 3919
@@ -3759,6 +3927,7 @@ namespace OpenSim.Region.Framework.Scenes
3759 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3927 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3760 } 3928 }
3761 3929
3930
3762 /// <summary> 3931 /// <summary>
3763 /// Event called by the physics plugin to tell the avatar about a collision. 3932 /// Event called by the physics plugin to tell the avatar about a collision.
3764 /// </summary> 3933 /// </summary>
@@ -3772,7 +3941,7 @@ namespace OpenSim.Region.Framework.Scenes
3772 /// <param name="e"></param> 3941 /// <param name="e"></param>
3773 public void PhysicsCollisionUpdate(EventArgs e) 3942 public void PhysicsCollisionUpdate(EventArgs e)
3774 { 3943 {
3775 if (IsChildAgent) 3944 if (IsChildAgent || Animator == null)
3776 return; 3945 return;
3777 3946
3778 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3947 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3789,7 +3958,6 @@ namespace OpenSim.Region.Framework.Scenes
3789 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3958 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3790 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3959 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3791 3960
3792 CollisionPlane = Vector4.UnitW;
3793 3961
3794// // No collisions at all means we may be flying. Update always 3962// // No collisions at all means we may be flying. Update always
3795// // to make falling work 3963// // to make falling work
@@ -3799,34 +3967,7 @@ namespace OpenSim.Region.Framework.Scenes
3799// m_lastColCount = coldata.Count; 3967// m_lastColCount = coldata.Count;
3800// } 3968// }
3801 3969
3802 if (coldata.Count != 0) 3970 CollisionPlane = Vector4.UnitW;
3803 {
3804 switch (Animator.CurrentMovementAnimation)
3805 {
3806 case "STAND":
3807 case "WALK":
3808 case "RUN":
3809 case "CROUCH":
3810 case "CROUCHWALK":
3811 {
3812 ContactPoint lowest;
3813 lowest.SurfaceNormal = Vector3.Zero;
3814 lowest.Position = Vector3.Zero;
3815 lowest.Position.Z = Single.NaN;
3816
3817 foreach (ContactPoint contact in coldata.Values)
3818 {
3819 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z)
3820 {
3821 lowest = contact;
3822 }
3823 }
3824
3825 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3826 }
3827 break;
3828 }
3829 }
3830 3971
3831 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3972 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3832 if (Invulnerable || GodLevel > 0) 3973 if (Invulnerable || GodLevel > 0)
@@ -3925,6 +4066,12 @@ namespace OpenSim.Region.Framework.Scenes
3925 // m_reprioritizationTimer.Dispose(); 4066 // m_reprioritizationTimer.Dispose();
3926 4067
3927 RemoveFromPhysicalScene(); 4068 RemoveFromPhysicalScene();
4069
4070 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
4071
4072// if (Animator != null)
4073// Animator.Close();
4074 Animator = null;
3928 4075
3929 LifecycleState = ScenePresenceState.Removed; 4076 LifecycleState = ScenePresenceState.Removed;
3930 } 4077 }
@@ -4160,10 +4307,18 @@ namespace OpenSim.Region.Framework.Scenes
4160 4307
4161 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4308 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
4162 { 4309 {
4310 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4311 if (p == null)
4312 return;
4313
4314 ControllingClient.SendTakeControls(controls, false, false);
4315 ControllingClient.SendTakeControls(controls, true, false);
4316
4163 ScriptControllers obj = new ScriptControllers(); 4317 ScriptControllers obj = new ScriptControllers();
4164 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4318 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4165 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4319 obj.eventControls = ScriptControlled.CONTROL_ZERO;
4166 4320
4321 obj.objectID = p.ParentGroup.UUID;
4167 obj.itemID = Script_item_UUID; 4322 obj.itemID = Script_item_UUID;
4168 if (pass_on == 0 && accept == 0) 4323 if (pass_on == 0 && accept == 0)
4169 { 4324 {
@@ -4212,6 +4367,21 @@ namespace OpenSim.Region.Framework.Scenes
4212 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4367 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4213 } 4368 }
4214 4369
4370 private void UnRegisterSeatControls(UUID obj)
4371 {
4372 List<UUID> takers = new List<UUID>();
4373
4374 foreach (ScriptControllers c in scriptedcontrols.Values)
4375 {
4376 if (c.objectID == obj)
4377 takers.Add(c.itemID);
4378 }
4379 foreach (UUID t in takers)
4380 {
4381 UnRegisterControlEventsToScript(0, t);
4382 }
4383 }
4384
4215 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4385 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4216 { 4386 {
4217 ScriptControllers takecontrols; 4387 ScriptControllers takecontrols;
@@ -4539,8 +4709,15 @@ namespace OpenSim.Region.Framework.Scenes
4539 } 4709 }
4540 } 4710 }
4541 4711
4712 // Modify landing point based on possible banning, telehubs or parcel restrictions.
4542 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4713 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4543 { 4714 {
4715 string reason;
4716
4717 // Honor bans
4718 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4719 return;
4720
4544 SceneObjectGroup telehub = null; 4721 SceneObjectGroup telehub = null;
4545 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4722 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4546 { 4723 {
@@ -4580,11 +4757,119 @@ namespace OpenSim.Region.Framework.Scenes
4580 pos = land.LandData.UserLocation; 4757 pos = land.LandData.UserLocation;
4581 } 4758 }
4582 } 4759 }
4583 4760
4584 land.SendLandUpdateToClient(ControllingClient); 4761 land.SendLandUpdateToClient(ControllingClient);
4585 } 4762 }
4586 } 4763 }
4587 4764
4765 private DetectedObject CreateDetObject(SceneObjectPart obj)
4766 {
4767 DetectedObject detobj = new DetectedObject();
4768 detobj.keyUUID = obj.UUID;
4769 detobj.nameStr = obj.Name;
4770 detobj.ownerUUID = obj.OwnerID;
4771 detobj.posVector = obj.AbsolutePosition;
4772 detobj.rotQuat = obj.GetWorldRotation();
4773 detobj.velVector = obj.Velocity;
4774 detobj.colliderType = 0;
4775 detobj.groupUUID = obj.GroupID;
4776
4777 return detobj;
4778 }
4779
4780 private DetectedObject CreateDetObject(ScenePresence av)
4781 {
4782 DetectedObject detobj = new DetectedObject();
4783 detobj.keyUUID = av.UUID;
4784 detobj.nameStr = av.ControllingClient.Name;
4785 detobj.ownerUUID = av.UUID;
4786 detobj.posVector = av.AbsolutePosition;
4787 detobj.rotQuat = av.Rotation;
4788 detobj.velVector = av.Velocity;
4789 detobj.colliderType = 0;
4790 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4791
4792 return detobj;
4793 }
4794
4795 private DetectedObject CreateDetObjectForGround()
4796 {
4797 DetectedObject detobj = new DetectedObject();
4798 detobj.keyUUID = UUID.Zero;
4799 detobj.nameStr = "";
4800 detobj.ownerUUID = UUID.Zero;
4801 detobj.posVector = AbsolutePosition;
4802 detobj.rotQuat = Quaternion.Identity;
4803 detobj.velVector = Vector3.Zero;
4804 detobj.colliderType = 0;
4805 detobj.groupUUID = UUID.Zero;
4806
4807 return detobj;
4808 }
4809
4810 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4811 {
4812 ColliderArgs colliderArgs = new ColliderArgs();
4813 List<DetectedObject> colliding = new List<DetectedObject>();
4814 foreach (uint localId in colliders)
4815 {
4816 if (localId == 0)
4817 continue;
4818
4819 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4820 if (obj != null)
4821 {
4822 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4823 colliding.Add(CreateDetObject(obj));
4824 }
4825 else
4826 {
4827 ScenePresence av = m_scene.GetScenePresence(localId);
4828 if (av != null && (!av.IsChildAgent))
4829 {
4830 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4831 colliding.Add(CreateDetObject(av));
4832 }
4833 }
4834 }
4835
4836 colliderArgs.Colliders = colliding;
4837
4838 return colliderArgs;
4839 }
4840
4841 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4842
4843 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4844 {
4845 ColliderArgs CollidingMessage;
4846
4847 if (colliders.Count > 0)
4848 {
4849 if ((dest.RootPart.ScriptEvents & ev) != 0)
4850 {
4851 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4852
4853 if (CollidingMessage.Colliders.Count > 0)
4854 notify(dest.RootPart.LocalId, CollidingMessage);
4855 }
4856 }
4857 }
4858
4859 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4860 {
4861 if ((dest.RootPart.ScriptEvents & ev) != 0)
4862 {
4863 ColliderArgs LandCollidingMessage = new ColliderArgs();
4864 List<DetectedObject> colliding = new List<DetectedObject>();
4865
4866 colliding.Add(CreateDetObjectForGround());
4867 LandCollidingMessage.Colliders = colliding;
4868
4869 notify(dest.RootPart.LocalId, LandCollidingMessage);
4870 }
4871 }
4872
4588 private void TeleportFlagsDebug() { 4873 private void TeleportFlagsDebug() {
4589 4874
4590 // Some temporary debugging help to show all the TeleportFlags we have... 4875 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4609,6 +4894,5 @@ namespace OpenSim.Region.Framework.Scenes
4609 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4894 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4610 4895
4611 } 4896 }
4612
4613 } 4897 }
4614} 4898}