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.cs1152
1 files changed, 719 insertions, 433 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 3290da1..576b8c2 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,113 @@ 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 = ControllingClient.ActiveGroupId;
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 (groupUUID != UUID.Zero && gm != null)
964 pos.X = crossedBorder.BorderLine.Z - 1; 1069 {
965 } 1070 GroupRecord record = gm.GetGroupRecord(groupUUID);
1071 if (record != null)
1072 groupName = record.GroupName;
1073
1074 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
966 1075
967 if (m_scene.TestBorderCross(pos, Cardinals.N)) 1076 if (groupMembershipData != null)
1077 groupPowers = groupMembershipData.GroupPowers;
1078 }
1079
1080 ControllingClient.SendAgentDataUpdate(
1081 m_uuid, groupUUID, Firstname, Lastname, groupPowers, groupName, Grouptitle);
1082 }
1083 catch (Exception e)
968 { 1084 {
969 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1085 m_log.Error("[AGENTUPDATE]: Error ", e);
970 pos.Y = crossedBorder.BorderLine.Z - 1;
971 } 1086 }
1087 // ------------------------------------
972 1088
973 CheckAndAdjustLandingPoint(ref pos); 1089 if (ParentID == 0)
974
975 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
976 { 1090 {
977 m_log.WarnFormat( 1091 // 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", 1092 // before the inventory is processed in MakeRootAgent. This fixes a race condition
979 pos, Name, UUID); 1093 // related to the handling of attachments
1094 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
980 1095
981 if (pos.X < 0f) pos.X = 0f; 1096 /* RA 20140111: Commented out these TestBorderCross's.
982 if (pos.Y < 0f) pos.Y = 0f; 1097 * Not sure why this code is here. It is not checking all the borders
983 if (pos.Z < 0f) pos.Z = 0f; 1098 * and 'in region' sanity checking is done in CheckAndAdjustLandingPoint and below.
984 } 1099 if (m_scene.TestBorderCross(pos, Cardinals.E))
1100 {
1101 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1102 pos.X = crossedBorder.BorderLine.Z - 1;
1103 }
985 1104
986 float localAVHeight = 1.56f; 1105 if (m_scene.TestBorderCross(pos, Cardinals.N))
987 if (Appearance.AvatarHeight > 0) 1106 {
988 localAVHeight = Appearance.AvatarHeight; 1107 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
1108 pos.Y = crossedBorder.BorderLine.Z - 1;
1109 }
1110 */
989 1111
990 float posZLimit = 0; 1112 CheckAndAdjustLandingPoint(ref pos);
991 1113
992 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1114 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
993 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1115 {
994 1116 m_log.WarnFormat(
995 float newPosZ = posZLimit + localAVHeight / 2; 1117 "[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))) 1118 pos, Name, UUID);
997 {
998 pos.Z = newPosZ;
999 }
1000 AbsolutePosition = pos;
1001 1119
1002 AddToPhysicalScene(isFlying); 1120 if (pos.X < 0f) pos.X = 0f;
1121 if (pos.Y < 0f) pos.Y = 0f;
1122 if (pos.Z < 0f) pos.Z = 0f;
1123 }
1003 1124
1004 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1125 float localAVHeight = 1.56f;
1005 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it 1126 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 1127 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 1128
1011 if (ForceFly) 1129 float posZLimit = 0;
1012 { 1130
1013 Flying = true; 1131 if (pos.X < m_scene.RegionInfo.RegionSizeX && pos.Y < m_scene.RegionInfo.RegionSizeY)
1014 } 1132 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
1015 else if (FlyDisabled) 1133
1016 { 1134 float newPosZ = posZLimit + localAVHeight / 2;
1017 Flying = false; 1135 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
1018 } 1136 {
1137 pos.Z = newPosZ;
1138 }
1139 AbsolutePosition = pos;
1019 1140
1141 if (m_teleportFlags == TeleportFlags.Default)
1142 {
1143 Vector3 vel = Velocity;
1144 AddToPhysicalScene(isFlying);
1145 if (PhysicsActor != null)
1146 PhysicsActor.SetMomentum(vel);
1147 }
1148 else
1149 AddToPhysicalScene(isFlying);
1150
1151 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1152 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1153 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1154 // the value to a negative position which does not trigger the border cross.
1155 // This may not be the best location for this.
1156 CheckForBorderCrossing();
1157
1158 if (ForceFly)
1159 {
1160 Flying = true;
1161 }
1162 else if (FlyDisabled)
1163 {
1164 Flying = false;
1165 }
1166 }
1020 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1167 // 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 1168 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1022 // elsewhere anyway 1169 // elsewhere anyway
@@ -1049,6 +1196,11 @@ namespace OpenSim.Region.Framework.Scenes
1049 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1196 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1050 // not transporting the required data. 1197 // not transporting the required data.
1051 // 1198 //
1199 // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
1200 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1201 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1202 // not transporting the required data.
1203 //
1052 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of 1204 // 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 1205 // 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. 1206 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
@@ -1057,6 +1209,9 @@ namespace OpenSim.Region.Framework.Scenes
1057 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing 1209 // 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 1210 // 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. 1211 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1212 //
1213 // One cannot simply iterate over attachments in a fire and forget thread because this would no longer
1214 // be locked, allowing race conditions if other code changes the attachments list.
1060 List<SceneObjectGroup> attachments = GetAttachments(); 1215 List<SceneObjectGroup> attachments = GetAttachments();
1061 1216
1062 if (attachments.Count > 0) 1217 if (attachments.Count > 0)
@@ -1067,12 +1222,15 @@ namespace OpenSim.Region.Framework.Scenes
1067 // Resume scripts 1222 // Resume scripts
1068 foreach (SceneObjectGroup sog in attachments) 1223 foreach (SceneObjectGroup sog in attachments)
1069 { 1224 {
1225 sog.ScheduleGroupForFullUpdate();
1070 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1226 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1071 sog.ResumeScripts(); 1227 sog.ResumeScripts();
1072 } 1228 }
1073 } 1229 }
1074 } 1230 }
1075 1231
1232 SendAvatarDataToAllAgents();
1233
1076 // send the animations of the other presences to me 1234 // send the animations of the other presences to me
1077 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1235 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1078 { 1236 {
@@ -1083,6 +1241,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 1241 // 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 1242 // 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. 1243 // recorded, which stops the input from being processed.
1244
1086 MovementFlag = 0; 1245 MovementFlag = 0;
1087 1246
1088 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1247 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -1115,12 +1274,16 @@ namespace OpenSim.Region.Framework.Scenes
1115 /// </remarks> 1274 /// </remarks>
1116 public void MakeChildAgent() 1275 public void MakeChildAgent()
1117 { 1276 {
1277 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1278
1118 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1279 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1119 1280
1120 // Reset these so that teleporting in and walking out isn't seen 1281 // Reset these so that teleporting in and walking out isn't seen
1121 // as teleporting back 1282 // as teleporting back
1122 TeleportFlags = TeleportFlags.Default; 1283 TeleportFlags = TeleportFlags.Default;
1123 1284
1285 MovementFlag = 0;
1286
1124 // It looks like Animator is set to null somewhere, and MakeChild 1287 // It looks like Animator is set to null somewhere, and MakeChild
1125 // is called after that. Probably in aborted teleports. 1288 // is called after that. Probably in aborted teleports.
1126 if (Animator == null) 1289 if (Animator == null)
@@ -1128,6 +1291,7 @@ namespace OpenSim.Region.Framework.Scenes
1128 else 1291 else
1129 Animator.ResetAnimations(); 1292 Animator.ResetAnimations();
1130 1293
1294
1131// m_log.DebugFormat( 1295// m_log.DebugFormat(
1132// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1296// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1133// Name, UUID, m_scene.RegionInfo.RegionName); 1297// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1139,6 +1303,7 @@ namespace OpenSim.Region.Framework.Scenes
1139 IsChildAgent = true; 1303 IsChildAgent = true;
1140 m_scene.SwapRootAgentCount(true); 1304 m_scene.SwapRootAgentCount(true);
1141 RemoveFromPhysicalScene(); 1305 RemoveFromPhysicalScene();
1306 ParentID = 0; // Child agents can't be sitting
1142 1307
1143 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1308 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1144 1309
@@ -1154,9 +1319,9 @@ namespace OpenSim.Region.Framework.Scenes
1154 { 1319 {
1155// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1320// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1156 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1321 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1157 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1158 PhysicsActor.UnSubscribeEvents();
1159 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1322 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1323 PhysicsActor.UnSubscribeEvents();
1324 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1160 PhysicsActor = null; 1325 PhysicsActor = null;
1161 } 1326 }
1162// else 1327// else
@@ -1173,7 +1338,7 @@ namespace OpenSim.Region.Framework.Scenes
1173 /// <param name="pos"></param> 1338 /// <param name="pos"></param>
1174 public void Teleport(Vector3 pos) 1339 public void Teleport(Vector3 pos)
1175 { 1340 {
1176 TeleportWithMomentum(pos, null); 1341 TeleportWithMomentum(pos, Vector3.Zero);
1177 } 1342 }
1178 1343
1179 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1344 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1197,6 +1362,41 @@ namespace OpenSim.Region.Framework.Scenes
1197 SendTerseUpdateToAllClients(); 1362 SendTerseUpdateToAllClients();
1198 } 1363 }
1199 1364
1365 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1366 {
1367 CheckLandingPoint(ref newpos);
1368 AbsolutePosition = newpos;
1369
1370 if (newvel.HasValue)
1371 {
1372 if ((Vector3)newvel == Vector3.Zero)
1373 {
1374 if (PhysicsActor != null)
1375 PhysicsActor.SetMomentum(Vector3.Zero);
1376 m_velocity = Vector3.Zero;
1377 }
1378 else
1379 {
1380 if (PhysicsActor != null)
1381 PhysicsActor.SetMomentum((Vector3)newvel);
1382 m_velocity = (Vector3)newvel;
1383
1384 if (rotateToVelXY)
1385 {
1386 Vector3 lookAt = (Vector3)newvel;
1387 lookAt.Z = 0;
1388 lookAt.Normalize();
1389 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1390 return;
1391 }
1392 }
1393 }
1394
1395 SendTerseUpdateToAllClients();
1396 }
1397
1398
1399
1200 public void StopFlying() 1400 public void StopFlying()
1201 { 1401 {
1202 Vector3 pos = AbsolutePosition; 1402 Vector3 pos = AbsolutePosition;
@@ -1385,6 +1585,14 @@ namespace OpenSim.Region.Framework.Scenes
1385 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1585 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1386 } 1586 }
1387 1587
1588 public void SetSize(Vector3 size, float feetoffset)
1589 {
1590// TODO: Merge the physics bits
1591// if (PhysicsActor != null && !IsChildAgent)
1592// PhysicsActor.setAvatarSize(size, feetoffset);
1593
1594 }
1595
1388 private bool WaitForUpdateAgent(IClientAPI client) 1596 private bool WaitForUpdateAgent(IClientAPI client)
1389 { 1597 {
1390 // Before the source region executes UpdateAgent 1598 // Before the source region executes UpdateAgent
@@ -1444,7 +1652,8 @@ namespace OpenSim.Region.Framework.Scenes
1444 1652
1445 Vector3 look = Velocity; 1653 Vector3 look = Velocity;
1446 1654
1447 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1655 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1656 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1448 { 1657 {
1449 look = new Vector3(0.99f, 0.042f, 0); 1658 look = new Vector3(0.99f, 0.042f, 0);
1450 } 1659 }
@@ -1514,11 +1723,12 @@ namespace OpenSim.Region.Framework.Scenes
1514 { 1723 {
1515 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1724 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1516 if (m_agentTransfer != null) 1725 if (m_agentTransfer != null)
1517 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1726 m_agentTransfer.EnableChildAgents(this);
1518 1727
1519 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1728 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1520 if (friendsModule != null) 1729 if (friendsModule != null)
1521 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1730 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1731
1522 } 1732 }
1523 1733
1524 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1734 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1544,36 +1754,69 @@ namespace OpenSim.Region.Framework.Scenes
1544 /// <param name="collisionPoint"></param> 1754 /// <param name="collisionPoint"></param>
1545 /// <param name="localid"></param> 1755 /// <param name="localid"></param>
1546 /// <param name="distance"></param> 1756 /// <param name="distance"></param>
1757 ///
1758
1759 private void UpdateCameraCollisionPlane(Vector4 plane)
1760 {
1761 if (m_lastCameraCollisionPlane != plane)
1762 {
1763 m_lastCameraCollisionPlane = plane;
1764 ControllingClient.SendCameraConstraint(plane);
1765 }
1766 }
1767
1547 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1768 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1548 { 1769 {
1549 const float POSITION_TOLERANCE = 0.02f; 1770 const float POSITION_TOLERANCE = 0.02f;
1550 const float VELOCITY_TOLERANCE = 0.02f;
1551 const float ROTATION_TOLERANCE = 0.02f; 1771 const float ROTATION_TOLERANCE = 0.02f;
1552 1772
1553 if (m_followCamAuto) 1773 m_doingCamRayCast = false;
1774 if (hitYN && localid != LocalId)
1554 { 1775 {
1555 if (hitYN) 1776 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1777 bool IsPrim = group != null;
1778 if (IsPrim)
1556 { 1779 {
1557 CameraConstraintActive = true; 1780 SceneObjectPart part = group.GetPart(localid);
1558 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1781 if (part != null && !part.VolumeDetectActive)
1559 1782 {
1560 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1783 CameraConstraintActive = true;
1561 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1784 pNormal.X = (float) Math.Round(pNormal.X, 2);
1785 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1786 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1787 pNormal.Normalize();
1788 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1789 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1790 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1791
1792 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1793 Vector3.Dot(collisionPoint, pNormal));
1794 UpdateCameraCollisionPlane(plane);
1795 }
1562 } 1796 }
1563 else 1797 else
1564 { 1798 {
1565 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1799 CameraConstraintActive = true;
1566 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1800 pNormal.X = (float) Math.Round(pNormal.X, 2);
1567 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1801 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1568 { 1802 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1569 if (CameraConstraintActive) 1803 pNormal.Normalize();
1570 { 1804 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1571 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1805 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1572 CameraConstraintActive = false; 1806 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1573 } 1807
1574 } 1808 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1809 Vector3.Dot(collisionPoint, pNormal));
1810 UpdateCameraCollisionPlane(plane);
1575 } 1811 }
1576 } 1812 }
1813 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1814 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1815 {
1816 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1817 UpdateCameraCollisionPlane(plane);
1818 CameraConstraintActive = false;
1819 }
1577 } 1820 }
1578 1821
1579 /// <summary> 1822 /// <summary>
@@ -1647,6 +1890,41 @@ namespace OpenSim.Region.Framework.Scenes
1647 StandUp(); 1890 StandUp();
1648 } 1891 }
1649 1892
1893 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1894 // this exclude checks may not be complete
1895
1896 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1897 {
1898 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1899 {
1900 Vector3 posAdjusted = AbsolutePosition;
1901// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1902 posAdjusted.Z += 1.0f; // viewer current camera focus point
1903 Vector3 tocam = CameraPosition - posAdjusted;
1904 tocam.X = (float)Math.Round(tocam.X, 1);
1905 tocam.Y = (float)Math.Round(tocam.Y, 1);
1906 tocam.Z = (float)Math.Round(tocam.Z, 1);
1907
1908 float distTocamlen = tocam.Length();
1909 if (distTocamlen > 0.3f)
1910 {
1911 tocam *= (1.0f / distTocamlen);
1912 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1913 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1914 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1915
1916 m_doingCamRayCast = true;
1917 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1918 }
1919 }
1920 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1921 {
1922 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1923 UpdateCameraCollisionPlane(plane);
1924 CameraConstraintActive = false;
1925 }
1926 }
1927
1650 uint flagsForScripts = (uint)flags; 1928 uint flagsForScripts = (uint)flags;
1651 flags = RemoveIgnoredControls(flags, IgnoredControls); 1929 flags = RemoveIgnoredControls(flags, IgnoredControls);
1652 1930
@@ -2127,7 +2405,7 @@ namespace OpenSim.Region.Framework.Scenes
2127 if (regionCombinerModule != null) 2405 if (regionCombinerModule != null)
2128 regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); 2406 regionSize = regionCombinerModule.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
2129 else 2407 else
2130 regionSize = new Vector2(Constants.RegionSize); 2408 regionSize = new Vector2(m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY);
2131 2409
2132 if (pos.X < 0 || pos.X >= regionSize.X 2410 if (pos.X < 0 || pos.X >= regionSize.X
2133 || pos.Y < 0 || pos.Y >= regionSize.Y 2411 || pos.Y < 0 || pos.Y >= regionSize.Y
@@ -2145,8 +2423,8 @@ namespace OpenSim.Region.Framework.Scenes
2145// } 2423// }
2146 2424
2147 // Get terrain height for sub-region in a megaregion if necessary 2425 // Get terrain height for sub-region in a megaregion if necessary
2148 int X = (int)((m_scene.RegionInfo.RegionLocX * Constants.RegionSize) + pos.X); 2426 int X = (int)((m_scene.RegionInfo.WorldLocX) + pos.X);
2149 int Y = (int)((m_scene.RegionInfo.RegionLocY * Constants.RegionSize) + pos.Y); 2427 int Y = (int)((m_scene.RegionInfo.WorldLocY) + pos.Y);
2150 GridRegion target_region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, X, Y); 2428 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 2429 // If X and Y is NaN, target_region will be null
2152 if (target_region == null) 2430 if (target_region == null)
@@ -2157,7 +2435,7 @@ namespace OpenSim.Region.Framework.Scenes
2157 if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene)) 2435 if (!SceneManager.Instance.TryGetScene(target_regionID, out targetScene))
2158 targetScene = m_scene; 2436 targetScene = m_scene;
2159 2437
2160 float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % Constants.RegionSize), (int)(pos.Y % Constants.RegionSize)]; 2438 float terrainHeight = (float)targetScene.Heightmap[(int)(pos.X % regionSize.X), (int)(pos.Y % regionSize.Y)];
2161 pos.Z = Math.Max(terrainHeight, pos.Z); 2439 pos.Z = Math.Max(terrainHeight, pos.Z);
2162 2440
2163 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is 2441 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is
@@ -2207,7 +2485,8 @@ namespace OpenSim.Region.Framework.Scenes
2207// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2485// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2208 2486
2209 MovingToTarget = false; 2487 MovingToTarget = false;
2210 MoveToPositionTarget = Vector3.Zero; 2488// MoveToPositionTarget = Vector3.Zero;
2489 m_forceToApply = null; // cancel possible last action
2211 2490
2212 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2491 // 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. 2492 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2230,6 +2509,9 @@ namespace OpenSim.Region.Framework.Scenes
2230 2509
2231 if (satOnObject) 2510 if (satOnObject)
2232 { 2511 {
2512 PrevSitOffset = m_pos; // Save sit offset
2513 UnRegisterSeatControls(part.ParentGroup.UUID);
2514
2233 TaskInventoryDictionary taskIDict = part.TaskInventory; 2515 TaskInventoryDictionary taskIDict = part.TaskInventory;
2234 if (taskIDict != null) 2516 if (taskIDict != null)
2235 { 2517 {
@@ -2245,6 +2527,7 @@ namespace OpenSim.Region.Framework.Scenes
2245 } 2527 }
2246 } 2528 }
2247 2529
2530 part.ParentGroup.DeleteAvatar(UUID);
2248 Vector3 sitPartWorldPosition = part.GetWorldPosition(); 2531 Vector3 sitPartWorldPosition = part.GetWorldPosition();
2249 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2532 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2250 2533
@@ -2305,6 +2588,9 @@ namespace OpenSim.Region.Framework.Scenes
2305 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2588 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2306 } 2589 }
2307 2590
2591 else if (PhysicsActor == null)
2592 AddToPhysicalScene(false);
2593
2308 Animator.TrySetMovementAnimation("STAND"); 2594 Animator.TrySetMovementAnimation("STAND");
2309 TriggerScenePresenceUpdated(); 2595 TriggerScenePresenceUpdated();
2310 } 2596 }
@@ -2353,11 +2639,8 @@ namespace OpenSim.Region.Framework.Scenes
2353 if (part == null) 2639 if (part == null)
2354 return; 2640 return;
2355 2641
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) 2642 if (PhysicsActor != null)
2360 m_sitAvatarHeight = PhysicsActor.Size.Z; 2643 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2361 2644
2362 bool canSit = false; 2645 bool canSit = false;
2363 2646
@@ -2384,33 +2667,32 @@ namespace OpenSim.Region.Framework.Scenes
2384 } 2667 }
2385 else 2668 else
2386 { 2669 {
2670 if (PhysicsSit(part,offset)) // physics engine
2671 return;
2672
2387 Vector3 pos = part.AbsolutePosition + offset; 2673 Vector3 pos = part.AbsolutePosition + offset;
2388 2674
2389 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2675 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2390 { 2676 {
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); 2677 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2396 canSit = true; 2678 canSit = true;
2397 } 2679 }
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 } 2680 }
2405 2681
2406 if (canSit) 2682 if (canSit)
2407 { 2683 {
2684
2408 if (PhysicsActor != null) 2685 if (PhysicsActor != null)
2409 { 2686 {
2410 // We can remove the physicsActor until they stand up. 2687 // We can remove the physicsActor until they stand up.
2411 RemoveFromPhysicalScene(); 2688 RemoveFromPhysicalScene();
2412 } 2689 }
2413 2690
2691 if (MovingToTarget)
2692 ResetMoveToTarget();
2693
2694 Velocity = Vector3.Zero;
2695
2414 part.AddSittingAvatar(UUID); 2696 part.AddSittingAvatar(UUID);
2415 2697
2416 cameraAtOffset = part.GetCameraAtOffset(); 2698 cameraAtOffset = part.GetCameraAtOffset();
@@ -2454,14 +2736,6 @@ namespace OpenSim.Region.Framework.Scenes
2454 m_requestedSitTargetID = part.LocalId; 2736 m_requestedSitTargetID = part.LocalId;
2455 m_requestedSitTargetUUID = part.UUID; 2737 m_requestedSitTargetUUID = part.UUID;
2456 2738
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 } 2739 }
2466 else 2740 else
2467 { 2741 {
@@ -2471,197 +2745,115 @@ namespace OpenSim.Region.Framework.Scenes
2471 SendSitResponse(targetID, offset, Quaternion.Identity); 2745 SendSitResponse(targetID, offset, Quaternion.Identity);
2472 } 2746 }
2473 2747
2474 /* 2748 // returns false if does not suport so older sit can be tried
2475 public void SitRayCastAvatarPosition(SceneObjectPart part) 2749 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 { 2750 {
2486 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2751// TODO: Pull in these bits
2487 if (part != null) 2752 return false;
2488 { 2753/*
2489 if (hitYN) 2754 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 { 2755 {
2508 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2756 return true;
2509 m_requestedSitTargetUUID = UUID.Zero;
2510 m_requestedSitTargetID = 0;
2511 m_requestedSitOffset = Vector3.Zero;
2512 } 2757 }
2513 2758
2514 } 2759 if ( m_scene.PhysicsScene == null)
2515 2760 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 2761
2526 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2762 if (part.PhysActor == null)
2527 {
2528 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2529 if (part != null)
2530 { 2763 {
2531 if (hitYN) 2764 // none physcis shape
2532 { 2765 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2533 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2766 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 2767 else
2544 { 2768 { // non physical phantom TODO
2545 SitRayCastCameraPosition(part); 2769 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2770 return false;
2546 } 2771 }
2547 } 2772 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 } 2773 }
2555 2774
2556 }
2557 2775
2558 public void SitRayCastCameraPosition(SceneObjectPart part) 2776 // not doing autopilot
2559 { 2777 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 2778
2568 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2779 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2569 { 2780 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 2781
2782 return false;
2783*/
2598 } 2784 }
2599 2785
2600 public void SitRayHorizontal(SceneObjectPart part) 2786
2787 private bool CanEnterLandPosition(Vector3 testPos)
2601 { 2788 {
2602 // Next, try to raycast from the avatar position to fwd 2789 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2603 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2790
2604 Vector3 StartRayCastPosition = CameraPosition; 2791 if (land == null || land.LandData.Name == "NO_LAND")
2605 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2792 return true;
2606 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2793
2607 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2794 return land.CanBeOnThisLand(UUID,testPos.Z);
2608 } 2795 }
2609 2796
2610 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2797 // status
2798 // < 0 ignore
2799 // 0 bad sit spot
2800 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2611 { 2801 {
2612 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2802 if (status < 0)
2613 if (part != null) 2803 return;
2804
2805 if (status == 0)
2614 { 2806 {
2615 if (hitYN) 2807 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2616 { 2808 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 } 2809 }
2644 else 2810
2811 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2812 if (part == null)
2813 return;
2814
2815 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2816 if(!CanEnterLandPosition(targetPos))
2645 { 2817 {
2646 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2818 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2647 m_requestedSitTargetUUID = UUID.Zero; 2819 return;
2648 m_requestedSitTargetID = 0;
2649 m_requestedSitOffset = Vector3.Zero;
2650 } 2820 }
2651 2821
2652 } 2822 RemoveFromPhysicalScene();
2653 2823
2654 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2824 if (MovingToTarget)
2655 { 2825 ResetMoveToTarget();
2656 int i = 0; 2826
2657 //throw new NotImplementedException(); 2827 Velocity = Vector3.Zero;
2658 //m_requestedSitTargetUUID = UUID.Zero; 2828
2659 //m_requestedSitTargetID = 0; 2829 part.AddSittingAvatar(UUID);
2660 //m_requestedSitOffset = Vector3.Zero; 2830
2831 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2832 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2833 bool forceMouselook = part.GetForceMouselook();
2834
2835 ControllingClient.SendSitResponse(
2836 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2837
2838 // not using autopilot
2839
2840 Rotation = Orientation;
2841 m_pos = offset;
2842
2843 m_requestedSitTargetID = 0;
2844 part.ParentGroup.AddAvatar(UUID);
2661 2845
2662 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2846 ParentPart = part;
2847 ParentID = part.LocalId;
2848 if(status == 3)
2849 Animator.TrySetMovementAnimation("SIT_GROUND");
2850 else
2851 Animator.TrySetMovementAnimation("SIT");
2852 SendAvatarDataToAllAgents();
2853
2854 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2663 } 2855 }
2664 */ 2856
2665 2857
2666 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2858 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2667 { 2859 {
@@ -2681,6 +2873,7 @@ namespace OpenSim.Region.Framework.Scenes
2681 return; 2873 return;
2682 } 2874 }
2683 2875
2876
2684 if (part.SitTargetAvatar == UUID) 2877 if (part.SitTargetAvatar == UUID)
2685 { 2878 {
2686 Vector3 sitTargetPos = part.SitTargetPosition; 2879 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2695,7 +2888,28 @@ namespace OpenSim.Region.Framework.Scenes
2695 2888
2696 //Quaternion result = (sitTargetOrient * vq) * nq; 2889 //Quaternion result = (sitTargetOrient * vq) * nq;
2697 2890
2698 Vector3 newPos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2891 double x, y, z, m;
2892
2893 Quaternion r = sitTargetOrient;
2894 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2895
2896 if (Math.Abs(1.0 - m) > 0.000001)
2897 {
2898 m = 1.0 / Math.Sqrt(m);
2899 r.X *= (float)m;
2900 r.Y *= (float)m;
2901 r.Z *= (float)m;
2902 r.W *= (float)m;
2903 }
2904
2905 x = 2 * (r.X * r.Z + r.Y * r.W);
2906 y = 2 * (-r.X * r.W + r.Y * r.Z);
2907 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2908
2909 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2910 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2911
2912 Vector3 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2699 Quaternion newRot; 2913 Quaternion newRot;
2700 2914
2701 if (part.IsRoot) 2915 if (part.IsRoot)
@@ -2712,6 +2926,8 @@ namespace OpenSim.Region.Framework.Scenes
2712 2926
2713 m_pos = newPos; 2927 m_pos = newPos;
2714 Rotation = newRot; 2928 Rotation = newRot;
2929
2930// ParentPosition = part.AbsolutePosition;
2715 } 2931 }
2716 else 2932 else
2717 { 2933 {
@@ -2719,11 +2935,14 @@ namespace OpenSim.Region.Framework.Scenes
2719 // being sat upon. 2935 // being sat upon.
2720 m_pos -= part.GroupPosition; 2936 m_pos -= part.GroupPosition;
2721 2937
2938// ParentPosition = part.AbsolutePosition;
2939
2722// m_log.DebugFormat( 2940// m_log.DebugFormat(
2723// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2941// "[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); 2942// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
2725 } 2943 }
2726 2944
2945 part.ParentGroup.AddAvatar(UUID);
2727 ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID); 2946 ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
2728 ParentID = m_requestedSitTargetID; 2947 ParentID = m_requestedSitTargetID;
2729 m_AngularVelocity = Vector3.Zero; 2948 m_AngularVelocity = Vector3.Zero;
@@ -2834,8 +3053,8 @@ namespace OpenSim.Region.Framework.Scenes
2834 direc.Z *= 2.6f; 3053 direc.Z *= 2.6f;
2835 3054
2836 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 3055 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2837 Animator.TrySetMovementAnimation("PREJUMP"); 3056// Animator.TrySetMovementAnimation("PREJUMP");
2838 Animator.TrySetMovementAnimation("JUMP"); 3057// Animator.TrySetMovementAnimation("JUMP");
2839 } 3058 }
2840 } 3059 }
2841 } 3060 }
@@ -2844,6 +3063,7 @@ namespace OpenSim.Region.Framework.Scenes
2844 3063
2845 // TODO: Add the force instead of only setting it to support multiple forces per frame? 3064 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2846 m_forceToApply = direc; 3065 m_forceToApply = direc;
3066 Animator.UpdateMovementAnimations();
2847 } 3067 }
2848 3068
2849 #endregion 3069 #endregion
@@ -2861,16 +3081,12 @@ namespace OpenSim.Region.Framework.Scenes
2861 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 3081 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2862 // grab the latest PhysicsActor velocity, whereas m_velocity is often 3082 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2863 // storing a requested force instead of an actual traveling velocity 3083 // storing a requested force instead of an actual traveling velocity
3084 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
3085 SendAvatarDataToAllAgents();
2864 3086
2865 // Throw away duplicate or insignificant updates 3087 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2866 if ( 3088 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2867 // If the velocity has become zero, send it no matter what. 3089 !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 { 3090 {
2875 SendTerseUpdateToAllClients(); 3091 SendTerseUpdateToAllClients();
2876 3092
@@ -3031,8 +3247,8 @@ namespace OpenSim.Region.Framework.Scenes
3031 // appearance goes into the avatar update packet 3247 // appearance goes into the avatar update packet
3032 SendAvatarDataToAllAgents(); 3248 SendAvatarDataToAllAgents();
3033 3249
3034 // This invocation always shows up in the viewer logs as an error. 3250 // This invocation always shows up in the viewer logs as an error. Is it needed?
3035 // SendAppearanceToAgent(this); 3251 SendAppearanceToAgent(this);
3036 3252
3037 // If we are using the the cached appearance then send it out to everyone 3253 // If we are using the the cached appearance then send it out to everyone
3038 if (cachedappearance) 3254 if (cachedappearance)
@@ -3063,6 +3279,8 @@ namespace OpenSim.Region.Framework.Scenes
3063 return; 3279 return;
3064 } 3280 }
3065 3281
3282 m_lastSize = Appearance.AvatarSize;
3283
3066 int count = 0; 3284 int count = 0;
3067 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 3285 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3068 { 3286 {
@@ -3170,6 +3388,8 @@ namespace OpenSim.Region.Framework.Scenes
3170 3388
3171 avatar.ControllingClient.SendAppearance( 3389 avatar.ControllingClient.SendAppearance(
3172 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3390 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3391
3392
3173 } 3393 }
3174 3394
3175 #endregion 3395 #endregion
@@ -3243,17 +3463,22 @@ namespace OpenSim.Region.Framework.Scenes
3243 3463
3244 // If we don't have a PhysActor, we can't cross anyway 3464 // 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 3465 // Also don't do this while sat, sitting avatars cross with the
3246 // object they sit on. 3466 // object they sit on. ParentUUID denoted a pending sit, don't
3247 if (ParentID != 0 || PhysicsActor == null) 3467 // interfere with it.
3468 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3248 return; 3469 return;
3249 3470
3250 if (!IsInTransit) 3471 if (!IsInTransit)
3251 { 3472 {
3252 Vector3 pos2 = AbsolutePosition; 3473 Vector3 pos2 = AbsolutePosition;
3474 Vector3 origPosition = pos2;
3253 Vector3 vel = Velocity; 3475 Vector3 vel = Velocity;
3254 int neighbor = 0; 3476 int neighbor = 0;
3255 int[] fix = new int[2]; 3477 int[] fix = new int[2];
3256 3478
3479 // Compute the avatar position in the next physics tick.
3480 // If the avatar will be crossing, we force the crossing to happen now
3481 // in the hope that this will make the avatar movement smoother when crossing.
3257 float timeStep = 0.1f; 3482 float timeStep = 0.1f;
3258 pos2.X = pos2.X + (vel.X * timeStep); 3483 pos2.X = pos2.X + (vel.X * timeStep);
3259 pos2.Y = pos2.Y + (vel.Y * timeStep); 3484 pos2.Y = pos2.Y + (vel.Y * timeStep);
@@ -3261,111 +3486,44 @@ namespace OpenSim.Region.Framework.Scenes
3261 3486
3262 if (!IsInTransit) 3487 if (!IsInTransit)
3263 { 3488 {
3264// m_log.DebugFormat( 3489 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 { 3490 {
3272 if (m_scene.TestBorderCross(pos2, Cardinals.S)) 3491 m_log.DebugFormat("{0} CheckForBorderCrossing: position outside region. {1} in {2} at pos {3}",
3492 LogHeader, Name, Scene.Name, pos2);
3493
3494 // Disconnect from the current region
3495 bool isFlying = Flying;
3496 RemoveFromPhysicalScene();
3497 // pos2 is the forcasted position so make that the 'current' position so the crossing
3498 // code will move us into the newly addressed region.
3499 m_pos = pos2;
3500 if (CrossToNewRegion())
3273 { 3501 {
3274 needsTransit = true; 3502 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 } 3503 }
3282 else 3504 else
3283 { 3505 {
3284 needsTransit = true; 3506 // 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) 3507 if (m_requestedSitTargetUUID == UUID.Zero)
3323 { 3508 {
3324 bool isFlying = Flying; 3509 m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader);
3325 RemoveFromPhysicalScene(); 3510 const float borderFudge = 0.1f;
3326 3511
3327 Vector3 pos = AbsolutePosition; 3512 if (origPosition.X < 0)
3328 if (AbsolutePosition.X < 0) 3513 origPosition.X = borderFudge;
3329 pos.X += Velocity.X * 2; 3514 else if (origPosition.X > (float)m_scene.RegionInfo.RegionSizeX)
3330 else if (AbsolutePosition.X > Constants.RegionSize) 3515 origPosition.X = (float)m_scene.RegionInfo.RegionSizeX - borderFudge;
3331 pos.X -= Velocity.X * 2; 3516 if (origPosition.Y < 0)
3332 if (AbsolutePosition.Y < 0) 3517 origPosition.Y = borderFudge;
3333 pos.Y += Velocity.Y * 2; 3518 else if (origPosition.Y > (float)m_scene.RegionInfo.RegionSizeY)
3334 else if (AbsolutePosition.Y > Constants.RegionSize) 3519 origPosition.Y = (float)m_scene.RegionInfo.RegionSizeY - borderFudge;
3335 pos.Y -= Velocity.Y * 2;
3336 Velocity = Vector3.Zero; 3520 Velocity = Vector3.Zero;
3337 AbsolutePosition = pos; 3521 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 3522
3366 AddToPhysicalScene(isFlying); 3523 AddToPhysicalScene(isFlying);
3367 } 3524 }
3368 } 3525 }
3526
3369 } 3527 }
3370 } 3528 }
3371 else 3529 else
@@ -3407,7 +3565,7 @@ namespace OpenSim.Region.Framework.Scenes
3407 3565
3408 // Put the child agent back at the center 3566 // Put the child agent back at the center
3409 AbsolutePosition 3567 AbsolutePosition
3410 = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); 3568 = new Vector3(((float)m_scene.RegionInfo.RegionSizeX * 0.5f), ((float)m_scene.RegionInfo.RegionSizeY * 0.5f), 70);
3411 3569
3412 Animator.ResetAnimations(); 3570 Animator.ResetAnimations();
3413 } 3571 }
@@ -3434,9 +3592,7 @@ namespace OpenSim.Region.Framework.Scenes
3434 if (handle != Scene.RegionInfo.RegionHandle) 3592 if (handle != Scene.RegionInfo.RegionHandle)
3435 { 3593 {
3436 uint x, y; 3594 uint x, y;
3437 Utils.LongToUInts(handle, out x, out y); 3595 Util.RegionHandleToRegionLoc(handle, out x, out y);
3438 x = x / Constants.RegionSize;
3439 y = y / Constants.RegionSize;
3440 3596
3441// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); 3597// 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))); 3598// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
@@ -3517,8 +3673,9 @@ namespace OpenSim.Region.Framework.Scenes
3517 return; 3673 return;
3518 3674
3519 //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); 3675 //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY);
3520 int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; 3676 // Find the distance (in meters) between the two regions
3521 int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; 3677 uint shiftx = Util.RegionToWorldLoc(rRegionX - tRegionX);
3678 uint shifty = Util.RegionToWorldLoc(rRegionY - tRegionY);
3522 3679
3523 Vector3 offset = new Vector3(shiftx, shifty, 0f); 3680 Vector3 offset = new Vector3(shiftx, shifty, 0f);
3524 3681
@@ -3588,6 +3745,9 @@ namespace OpenSim.Region.Framework.Scenes
3588 cAgent.AlwaysRun = SetAlwaysRun; 3745 cAgent.AlwaysRun = SetAlwaysRun;
3589 3746
3590 cAgent.Appearance = new AvatarAppearance(Appearance); 3747 cAgent.Appearance = new AvatarAppearance(Appearance);
3748
3749 cAgent.ParentPart = ParentUUID;
3750 cAgent.SitOffset = PrevSitOffset;
3591 3751
3592 lock (scriptedcontrols) 3752 lock (scriptedcontrols)
3593 { 3753 {
@@ -3596,7 +3756,7 @@ namespace OpenSim.Region.Framework.Scenes
3596 3756
3597 foreach (ScriptControllers c in scriptedcontrols.Values) 3757 foreach (ScriptControllers c in scriptedcontrols.Values)
3598 { 3758 {
3599 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3759 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3600 } 3760 }
3601 cAgent.Controllers = controls; 3761 cAgent.Controllers = controls;
3602 } 3762 }
@@ -3630,6 +3790,8 @@ namespace OpenSim.Region.Framework.Scenes
3630 CameraAtAxis = cAgent.AtAxis; 3790 CameraAtAxis = cAgent.AtAxis;
3631 CameraLeftAxis = cAgent.LeftAxis; 3791 CameraLeftAxis = cAgent.LeftAxis;
3632 CameraUpAxis = cAgent.UpAxis; 3792 CameraUpAxis = cAgent.UpAxis;
3793 ParentUUID = cAgent.ParentPart;
3794 PrevSitOffset = cAgent.SitOffset;
3633 3795
3634 // When we get to the point of re-computing neighbors everytime this 3796 // When we get to the point of re-computing neighbors everytime this
3635 // changes, then start using the agent's drawdistance rather than the 3797 // changes, then start using the agent's drawdistance rather than the
@@ -3667,6 +3829,7 @@ namespace OpenSim.Region.Framework.Scenes
3667 foreach (ControllerData c in cAgent.Controllers) 3829 foreach (ControllerData c in cAgent.Controllers)
3668 { 3830 {
3669 ScriptControllers sc = new ScriptControllers(); 3831 ScriptControllers sc = new ScriptControllers();
3832 sc.objectID = c.ObjectID;
3670 sc.itemID = c.ItemID; 3833 sc.itemID = c.ItemID;
3671 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3834 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3672 sc.eventControls = (ScriptControlled)c.EventControls; 3835 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3732,20 +3895,27 @@ namespace OpenSim.Region.Framework.Scenes
3732 } 3895 }
3733 3896
3734 if (Appearance.AvatarHeight == 0) 3897 if (Appearance.AvatarHeight == 0)
3735 Appearance.SetHeight(); 3898// Appearance.SetHeight();
3899 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3736 3900
3737 PhysicsScene scene = m_scene.PhysicsScene; 3901 PhysicsScene scene = m_scene.PhysicsScene;
3738 3902
3739 Vector3 pVec = AbsolutePosition; 3903 Vector3 pVec = AbsolutePosition;
3740 3904
3905/*
3741 PhysicsActor = scene.AddAvatar( 3906 PhysicsActor = scene.AddAvatar(
3742 LocalId, Firstname + "." + Lastname, pVec, 3907 LocalId, Firstname + "." + Lastname, pVec,
3743 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3908 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3909*/
3910
3911 PhysicsActor = scene.AddAvatar(
3912 LocalId, Firstname + "." + Lastname, pVec,
3913 Appearance.AvatarBoxSize, isFlying);
3744 3914
3745 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3915 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3746 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3916 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3747 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3917 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3748 PhysicsActor.SubscribeEvents(500); 3918 PhysicsActor.SubscribeEvents(100);
3749 PhysicsActor.LocalID = LocalId; 3919 PhysicsActor.LocalID = LocalId;
3750 } 3920 }
3751 3921
@@ -3759,6 +3929,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); 3929 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3760 } 3930 }
3761 3931
3932
3762 /// <summary> 3933 /// <summary>
3763 /// Event called by the physics plugin to tell the avatar about a collision. 3934 /// Event called by the physics plugin to tell the avatar about a collision.
3764 /// </summary> 3935 /// </summary>
@@ -3772,7 +3943,7 @@ namespace OpenSim.Region.Framework.Scenes
3772 /// <param name="e"></param> 3943 /// <param name="e"></param>
3773 public void PhysicsCollisionUpdate(EventArgs e) 3944 public void PhysicsCollisionUpdate(EventArgs e)
3774 { 3945 {
3775 if (IsChildAgent) 3946 if (IsChildAgent || Animator == null)
3776 return; 3947 return;
3777 3948
3778 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3949 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3789,7 +3960,6 @@ namespace OpenSim.Region.Framework.Scenes
3789 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3960 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3790 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3961 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3791 3962
3792 CollisionPlane = Vector4.UnitW;
3793 3963
3794// // No collisions at all means we may be flying. Update always 3964// // No collisions at all means we may be flying. Update always
3795// // to make falling work 3965// // to make falling work
@@ -3799,34 +3969,7 @@ namespace OpenSim.Region.Framework.Scenes
3799// m_lastColCount = coldata.Count; 3969// m_lastColCount = coldata.Count;
3800// } 3970// }
3801 3971
3802 if (coldata.Count != 0) 3972 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 3973
3831 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3974 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3832 if (Invulnerable || GodLevel > 0) 3975 if (Invulnerable || GodLevel > 0)
@@ -3925,6 +4068,12 @@ namespace OpenSim.Region.Framework.Scenes
3925 // m_reprioritizationTimer.Dispose(); 4068 // m_reprioritizationTimer.Dispose();
3926 4069
3927 RemoveFromPhysicalScene(); 4070 RemoveFromPhysicalScene();
4071
4072 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
4073
4074// if (Animator != null)
4075// Animator.Close();
4076 Animator = null;
3928 4077
3929 LifecycleState = ScenePresenceState.Removed; 4078 LifecycleState = ScenePresenceState.Removed;
3930 } 4079 }
@@ -4160,10 +4309,18 @@ namespace OpenSim.Region.Framework.Scenes
4160 4309
4161 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4310 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
4162 { 4311 {
4312 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4313 if (p == null)
4314 return;
4315
4316 ControllingClient.SendTakeControls(controls, false, false);
4317 ControllingClient.SendTakeControls(controls, true, false);
4318
4163 ScriptControllers obj = new ScriptControllers(); 4319 ScriptControllers obj = new ScriptControllers();
4164 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4320 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4165 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4321 obj.eventControls = ScriptControlled.CONTROL_ZERO;
4166 4322
4323 obj.objectID = p.ParentGroup.UUID;
4167 obj.itemID = Script_item_UUID; 4324 obj.itemID = Script_item_UUID;
4168 if (pass_on == 0 && accept == 0) 4325 if (pass_on == 0 && accept == 0)
4169 { 4326 {
@@ -4212,6 +4369,21 @@ namespace OpenSim.Region.Framework.Scenes
4212 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4369 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4213 } 4370 }
4214 4371
4372 private void UnRegisterSeatControls(UUID obj)
4373 {
4374 List<UUID> takers = new List<UUID>();
4375
4376 foreach (ScriptControllers c in scriptedcontrols.Values)
4377 {
4378 if (c.objectID == obj)
4379 takers.Add(c.itemID);
4380 }
4381 foreach (UUID t in takers)
4382 {
4383 UnRegisterControlEventsToScript(0, t);
4384 }
4385 }
4386
4215 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4387 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4216 { 4388 {
4217 ScriptControllers takecontrols; 4389 ScriptControllers takecontrols;
@@ -4539,8 +4711,15 @@ namespace OpenSim.Region.Framework.Scenes
4539 } 4711 }
4540 } 4712 }
4541 4713
4714 // Modify landing point based on possible banning, telehubs or parcel restrictions.
4542 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4715 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4543 { 4716 {
4717 string reason;
4718
4719 // Honor bans
4720 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4721 return;
4722
4544 SceneObjectGroup telehub = null; 4723 SceneObjectGroup telehub = null;
4545 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4724 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4546 { 4725 {
@@ -4580,11 +4759,119 @@ namespace OpenSim.Region.Framework.Scenes
4580 pos = land.LandData.UserLocation; 4759 pos = land.LandData.UserLocation;
4581 } 4760 }
4582 } 4761 }
4583 4762
4584 land.SendLandUpdateToClient(ControllingClient); 4763 land.SendLandUpdateToClient(ControllingClient);
4585 } 4764 }
4586 } 4765 }
4587 4766
4767 private DetectedObject CreateDetObject(SceneObjectPart obj)
4768 {
4769 DetectedObject detobj = new DetectedObject();
4770 detobj.keyUUID = obj.UUID;
4771 detobj.nameStr = obj.Name;
4772 detobj.ownerUUID = obj.OwnerID;
4773 detobj.posVector = obj.AbsolutePosition;
4774 detobj.rotQuat = obj.GetWorldRotation();
4775 detobj.velVector = obj.Velocity;
4776 detobj.colliderType = 0;
4777 detobj.groupUUID = obj.GroupID;
4778
4779 return detobj;
4780 }
4781
4782 private DetectedObject CreateDetObject(ScenePresence av)
4783 {
4784 DetectedObject detobj = new DetectedObject();
4785 detobj.keyUUID = av.UUID;
4786 detobj.nameStr = av.ControllingClient.Name;
4787 detobj.ownerUUID = av.UUID;
4788 detobj.posVector = av.AbsolutePosition;
4789 detobj.rotQuat = av.Rotation;
4790 detobj.velVector = av.Velocity;
4791 detobj.colliderType = 0;
4792 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4793
4794 return detobj;
4795 }
4796
4797 private DetectedObject CreateDetObjectForGround()
4798 {
4799 DetectedObject detobj = new DetectedObject();
4800 detobj.keyUUID = UUID.Zero;
4801 detobj.nameStr = "";
4802 detobj.ownerUUID = UUID.Zero;
4803 detobj.posVector = AbsolutePosition;
4804 detobj.rotQuat = Quaternion.Identity;
4805 detobj.velVector = Vector3.Zero;
4806 detobj.colliderType = 0;
4807 detobj.groupUUID = UUID.Zero;
4808
4809 return detobj;
4810 }
4811
4812 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4813 {
4814 ColliderArgs colliderArgs = new ColliderArgs();
4815 List<DetectedObject> colliding = new List<DetectedObject>();
4816 foreach (uint localId in colliders)
4817 {
4818 if (localId == 0)
4819 continue;
4820
4821 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4822 if (obj != null)
4823 {
4824 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4825 colliding.Add(CreateDetObject(obj));
4826 }
4827 else
4828 {
4829 ScenePresence av = m_scene.GetScenePresence(localId);
4830 if (av != null && (!av.IsChildAgent))
4831 {
4832 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4833 colliding.Add(CreateDetObject(av));
4834 }
4835 }
4836 }
4837
4838 colliderArgs.Colliders = colliding;
4839
4840 return colliderArgs;
4841 }
4842
4843 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4844
4845 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4846 {
4847 ColliderArgs CollidingMessage;
4848
4849 if (colliders.Count > 0)
4850 {
4851 if ((dest.RootPart.ScriptEvents & ev) != 0)
4852 {
4853 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4854
4855 if (CollidingMessage.Colliders.Count > 0)
4856 notify(dest.RootPart.LocalId, CollidingMessage);
4857 }
4858 }
4859 }
4860
4861 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4862 {
4863 if ((dest.RootPart.ScriptEvents & ev) != 0)
4864 {
4865 ColliderArgs LandCollidingMessage = new ColliderArgs();
4866 List<DetectedObject> colliding = new List<DetectedObject>();
4867
4868 colliding.Add(CreateDetObjectForGround());
4869 LandCollidingMessage.Colliders = colliding;
4870
4871 notify(dest.RootPart.LocalId, LandCollidingMessage);
4872 }
4873 }
4874
4588 private void TeleportFlagsDebug() { 4875 private void TeleportFlagsDebug() {
4589 4876
4590 // Some temporary debugging help to show all the TeleportFlags we have... 4877 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4609,6 +4896,5 @@ namespace OpenSim.Region.Framework.Scenes
4609 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4896 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4610 4897
4611 } 4898 }
4612
4613 } 4899 }
4614} 4900}