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.cs1017
1 files changed, 673 insertions, 344 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 3290da1..85a20e9 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;
@@ -130,7 +131,7 @@ namespace OpenSim.Region.Framework.Scenes
130 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 131 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
131 /// issue #1716 132 /// issue #1716
132 /// </summary> 133 /// </summary>
133 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 134 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
134 135
135 /// <summary> 136 /// <summary>
136 /// Movement updates for agents in neighboring regions are sent directly to clients. 137 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -152,8 +153,6 @@ namespace OpenSim.Region.Framework.Scenes
152 /// <remarks> 153 /// <remarks>
153 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 154 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
154 /// necessary. 155 /// 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> 156 /// </remarks>
158 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 157 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
159 158
@@ -172,6 +171,10 @@ namespace OpenSim.Region.Framework.Scenes
172 private Vector3 m_lastPosition; 171 private Vector3 m_lastPosition;
173 private Quaternion m_lastRotation; 172 private Quaternion m_lastRotation;
174 private Vector3 m_lastVelocity; 173 private Vector3 m_lastVelocity;
174 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
175
176 private bool m_followCamAuto = false;
177
175 178
176 private Vector3? m_forceToApply; 179 private Vector3? m_forceToApply;
177 private int m_userFlags; 180 private int m_userFlags;
@@ -204,6 +207,7 @@ namespace OpenSim.Region.Framework.Scenes
204// private int m_lastColCount = -1; //KF: Look for Collision chnages 207// private int m_lastColCount = -1; //KF: Look for Collision chnages
205// private int m_updateCount = 0; //KF: Update Anims for a while 208// 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 209// private static readonly int UPDATE_COUNT = 10; // how many frames to update for
210 private List<uint> m_lastColliders = new List<uint>();
207 211
208 private TeleportFlags m_teleportFlags; 212 private TeleportFlags m_teleportFlags;
209 public TeleportFlags TeleportFlags 213 public TeleportFlags TeleportFlags
@@ -259,8 +263,6 @@ namespace OpenSim.Region.Framework.Scenes
259 /// </summary> 263 /// </summary>
260 public bool LandAtTarget { get; private set; } 264 public bool LandAtTarget { get; private set; }
261 265
262 private bool m_followCamAuto;
263
264 private int m_movementUpdateCount; 266 private int m_movementUpdateCount;
265 private const int NumMovementsBetweenRayCast = 5; 267 private const int NumMovementsBetweenRayCast = 5;
266 268
@@ -268,6 +270,13 @@ namespace OpenSim.Region.Framework.Scenes
268 //private int m_moveToPositionStateStatus; 270 //private int m_moveToPositionStateStatus;
269 //***************************************************** 271 //*****************************************************
270 272
273 private bool m_collisionEventFlag = false;
274 private object m_collisionEventLock = new Object();
275
276 private int m_movementAnimationUpdateCounter = 0;
277
278 public Vector3 PrevSitOffset { get; set; }
279
271 protected AvatarAppearance m_appearance; 280 protected AvatarAppearance m_appearance;
272 281
273 public AvatarAppearance Appearance 282 public AvatarAppearance Appearance
@@ -407,6 +416,9 @@ namespace OpenSim.Region.Framework.Scenes
407 /// </summary> 416 /// </summary>
408 protected Vector3 m_lastCameraPosition; 417 protected Vector3 m_lastCameraPosition;
409 418
419 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
420 private bool m_doingCamRayCast = false;
421
410 public Vector3 CameraPosition { get; set; } 422 public Vector3 CameraPosition { get; set; }
411 423
412 public Quaternion CameraRotation 424 public Quaternion CameraRotation
@@ -487,6 +499,10 @@ namespace OpenSim.Region.Framework.Scenes
487 get { return (IClientCore)ControllingClient; } 499 get { return (IClientCore)ControllingClient; }
488 } 500 }
489 501
502 public UUID COF { get; set; }
503
504// public Vector3 ParentPosition { get; set; }
505
490 /// <summary> 506 /// <summary>
491 /// Position of this avatar relative to the region the avatar is in 507 /// Position of this avatar relative to the region the avatar is in
492 /// </summary> 508 /// </summary>
@@ -613,7 +629,24 @@ namespace OpenSim.Region.Framework.Scenes
613// Scene.RegionInfo.RegionName, Name, m_velocity); 629// Scene.RegionInfo.RegionName, Name, m_velocity);
614 } 630 }
615 } 631 }
632/*
633 public override Vector3 AngularVelocity
634 {
635 get
636 {
637 if (PhysicsActor != null)
638 {
639 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
640
641 // m_log.DebugFormat(
642 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
643 // m_velocity, Name, Scene.RegionInfo.RegionName);
644 }
616 645
646 return m_rotationalvelocity;
647 }
648 }
649*/
617 private Quaternion m_bodyRot = Quaternion.Identity; 650 private Quaternion m_bodyRot = Quaternion.Identity;
618 651
619 /// <summary> 652 /// <summary>
@@ -636,8 +669,16 @@ namespace OpenSim.Region.Framework.Scenes
636 m_bodyRot = value; 669 m_bodyRot = value;
637 670
638 if (PhysicsActor != null) 671 if (PhysicsActor != null)
639 PhysicsActor.Orientation = m_bodyRot; 672 {
640 673 try
674 {
675 PhysicsActor.Orientation = m_bodyRot;
676 }
677 catch (Exception e)
678 {
679 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
680 }
681 }
641// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 682// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
642 } 683 }
643 } 684 }
@@ -651,12 +692,20 @@ namespace OpenSim.Region.Framework.Scenes
651 } 692 }
652 693
653 public bool IsChildAgent { get; set; } 694 public bool IsChildAgent { get; set; }
695 public bool IsLoggingIn { get; set; }
654 696
655 /// <summary> 697 /// <summary>
656 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 698 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
657 /// </summary> 699 /// </summary>
658 public uint ParentID { get; set; } 700 public uint ParentID { get; set; }
659 701
702 public UUID ParentUUID
703 {
704 get { return m_parentUUID; }
705 set { m_parentUUID = value; }
706 }
707 private UUID m_parentUUID = UUID.Zero;
708
660 /// <summary> 709 /// <summary>
661 /// Are we sitting on an object? 710 /// Are we sitting on an object?
662 /// </summary> 711 /// </summary>
@@ -814,6 +863,7 @@ namespace OpenSim.Region.Framework.Scenes
814 AttachmentsSyncLock = new Object(); 863 AttachmentsSyncLock = new Object();
815 AllowMovement = true; 864 AllowMovement = true;
816 IsChildAgent = true; 865 IsChildAgent = true;
866 IsLoggingIn = false;
817 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 867 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
818 Animator = new ScenePresenceAnimator(this); 868 Animator = new ScenePresenceAnimator(this);
819 PresenceType = type; 869 PresenceType = type;
@@ -859,6 +909,33 @@ namespace OpenSim.Region.Framework.Scenes
859 m_stateMachine = new ScenePresenceStateMachine(this); 909 m_stateMachine = new ScenePresenceStateMachine(this);
860 } 910 }
861 911
912 private void RegionHeartbeatEnd(Scene scene)
913 {
914 if (IsChildAgent)
915 return;
916
917 m_movementAnimationUpdateCounter ++;
918 if (m_movementAnimationUpdateCounter >= 2)
919 {
920 m_movementAnimationUpdateCounter = 0;
921 if (Animator != null)
922 {
923 // If the parentID == 0 we are not sitting
924 // if !SitGournd then we are not sitting on the ground
925 // Fairly straightforward, now here comes the twist
926 // if ParentUUID is NOT UUID.Zero, we are looking to
927 // be sat on an object that isn't there yet. Should
928 // be treated as if sat.
929 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
930 Animator.UpdateMovementAnimations();
931 }
932 else
933 {
934 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
935 }
936 }
937 }
938
862 public void RegisterToEvents() 939 public void RegisterToEvents()
863 { 940 {
864 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 941 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -926,17 +1003,46 @@ namespace OpenSim.Region.Framework.Scenes
926 /// </remarks> 1003 /// </remarks>
927 private bool MakeRootAgent(Vector3 pos, bool isFlying) 1004 private bool MakeRootAgent(Vector3 pos, bool isFlying)
928 { 1005 {
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) 1006 lock (m_completeMovementLock)
936 { 1007 {
937 if (!IsChildAgent) 1008 if (!IsChildAgent)
938 return false; 1009 return false;
939 1010
1011 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
1012
1013 // m_log.InfoFormat(
1014 // "[SCENE]: Upgrading child to root agent for {0} in {1}",
1015 // Name, m_scene.RegionInfo.RegionName);
1016
1017 if (ParentUUID != UUID.Zero)
1018 {
1019 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1020 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1021 if (part == null)
1022 {
1023 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1024 }
1025 else
1026 {
1027 part.ParentGroup.AddAvatar(UUID);
1028 if (part.SitTargetPosition != Vector3.Zero)
1029 part.SitTargetAvatar = UUID;
1030 // ParentPosition = part.GetWorldPosition();
1031 ParentID = part.LocalId;
1032 ParentPart = part;
1033 m_pos = PrevSitOffset;
1034 // pos = ParentPosition;
1035 pos = part.GetWorldPosition();
1036 }
1037 ParentUUID = UUID.Zero;
1038
1039 // Animator.TrySetMovementAnimation("SIT");
1040 }
1041 else
1042 {
1043 IsLoggingIn = false;
1044 }
1045
940 IsChildAgent = false; 1046 IsChildAgent = false;
941 } 1047 }
942 1048
@@ -953,70 +1059,106 @@ namespace OpenSim.Region.Framework.Scenes
953 1059
954 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1060 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
955 1061
956 // Moved this from SendInitialData to ensure that Appearance is initialized 1062 UUID groupUUID = UUID.Zero;
957 // before the inventory is processed in MakeRootAgent. This fixes a race condition 1063 string GroupName = string.Empty;
958 // related to the handling of attachments 1064 ulong groupPowers = 0;
959 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
960 1065
961 if (m_scene.TestBorderCross(pos, Cardinals.E)) 1066 // ----------------------------------
1067 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1068 try
962 { 1069 {
963 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 1070 if (gm != null)
964 pos.X = crossedBorder.BorderLine.Z - 1; 1071 {
1072 groupUUID = ControllingClient.ActiveGroupId;
1073 GroupRecord record = gm.GetGroupRecord(groupUUID);
1074 if (record != null)
1075 GroupName = record.GroupName;
1076 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1077 if (groupMembershipData != null)
1078 groupPowers = groupMembershipData.GroupPowers;
1079 }
1080 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1081 Grouptitle);
965 } 1082 }
966 1083 catch (Exception e)
967 if (m_scene.TestBorderCross(pos, Cardinals.N))
968 { 1084 {
969 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1085 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
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);
1095 if (m_scene.TestBorderCross(pos, Cardinals.E))
1096 {
1097 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1098 pos.X = crossedBorder.BorderLine.Z - 1;
1099 }
980 1100
981 if (pos.X < 0f) pos.X = 0f; 1101 if (m_scene.TestBorderCross(pos, Cardinals.N))
982 if (pos.Y < 0f) pos.Y = 0f; 1102 {
983 if (pos.Z < 0f) pos.Z = 0f; 1103 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
984 } 1104 pos.Y = crossedBorder.BorderLine.Z - 1;
1105 }
985 1106
986 float localAVHeight = 1.56f; 1107 CheckAndAdjustLandingPoint(ref pos);
987 if (Appearance.AvatarHeight > 0)
988 localAVHeight = Appearance.AvatarHeight;
989 1108
990 float posZLimit = 0; 1109 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1110 {
1111 m_log.WarnFormat(
1112 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1113 pos, Name, UUID);
991 1114
992 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1115 if (pos.X < 0f) pos.X = 0f;
993 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1116 if (pos.Y < 0f) pos.Y = 0f;
994 1117 if (pos.Z < 0f) pos.Z = 0f;
995 float newPosZ = posZLimit + localAVHeight / 2; 1118 }
996 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
997 {
998 pos.Z = newPosZ;
999 }
1000 AbsolutePosition = pos;
1001 1119
1002 AddToPhysicalScene(isFlying); 1120 float localAVHeight = 1.56f;
1121 if (Appearance.AvatarHeight > 0)
1122 localAVHeight = Appearance.AvatarHeight;
1003 1123
1004 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1124 float posZLimit = 0;
1005 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1006 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
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 1125
1011 if (ForceFly) 1126 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
1012 { 1127 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
1013 Flying = true; 1128
1014 } 1129 float newPosZ = posZLimit + localAVHeight / 2;
1015 else if (FlyDisabled) 1130 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
1016 { 1131 {
1017 Flying = false; 1132 pos.Z = newPosZ;
1018 } 1133 }
1134 AbsolutePosition = pos;
1135
1136 if (m_teleportFlags == TeleportFlags.Default)
1137 {
1138 Vector3 vel = Velocity;
1139 AddToPhysicalScene(isFlying);
1140 if (PhysicsActor != null)
1141 PhysicsActor.SetMomentum(vel);
1142 }
1143 else
1144 AddToPhysicalScene(isFlying);
1145
1146 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1147 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1148 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1149 // the value to a negative position which does not trigger the border cross.
1150 // This may not be the best location for this.
1151 CheckForBorderCrossing();
1019 1152
1153 if (ForceFly)
1154 {
1155 Flying = true;
1156 }
1157 else if (FlyDisabled)
1158 {
1159 Flying = false;
1160 }
1161 }
1020 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1162 // 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 1163 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1022 // elsewhere anyway 1164 // elsewhere anyway
@@ -1048,31 +1190,28 @@ namespace OpenSim.Region.Framework.Scenes
1048 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1190 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1049 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1191 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1050 // not transporting the required data. 1192 // not transporting the required data.
1051 // 1193 lock (m_attachments)
1052 // 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
1054 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
1055 //
1056 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
1057 // 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
1059 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1060 List<SceneObjectGroup> attachments = GetAttachments();
1061
1062 if (attachments.Count > 0)
1063 { 1194 {
1064 m_log.DebugFormat( 1195 if (HasAttachments())
1065 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1066
1067 // Resume scripts
1068 foreach (SceneObjectGroup sog in attachments)
1069 { 1196 {
1070 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1197 m_log.DebugFormat(
1071 sog.ResumeScripts(); 1198 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1199
1200 // Resume scripts
1201 Util.FireAndForget(delegate(object x) {
1202 foreach (SceneObjectGroup sog in m_attachments)
1203 {
1204 sog.ScheduleGroupForFullUpdate();
1205 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1206 sog.ResumeScripts();
1207 }
1208 });
1072 } 1209 }
1073 } 1210 }
1074 } 1211 }
1075 1212
1213 SendAvatarDataToAllAgents();
1214
1076 // send the animations of the other presences to me 1215 // send the animations of the other presences to me
1077 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1216 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1078 { 1217 {
@@ -1083,6 +1222,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 1222 // 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 1223 // 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. 1224 // recorded, which stops the input from being processed.
1225
1086 MovementFlag = 0; 1226 MovementFlag = 0;
1087 1227
1088 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1228 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -1115,12 +1255,16 @@ namespace OpenSim.Region.Framework.Scenes
1115 /// </remarks> 1255 /// </remarks>
1116 public void MakeChildAgent() 1256 public void MakeChildAgent()
1117 { 1257 {
1258 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1259
1118 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1260 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1119 1261
1120 // Reset these so that teleporting in and walking out isn't seen 1262 // Reset these so that teleporting in and walking out isn't seen
1121 // as teleporting back 1263 // as teleporting back
1122 TeleportFlags = TeleportFlags.Default; 1264 TeleportFlags = TeleportFlags.Default;
1123 1265
1266 MovementFlag = 0;
1267
1124 // It looks like Animator is set to null somewhere, and MakeChild 1268 // It looks like Animator is set to null somewhere, and MakeChild
1125 // is called after that. Probably in aborted teleports. 1269 // is called after that. Probably in aborted teleports.
1126 if (Animator == null) 1270 if (Animator == null)
@@ -1128,6 +1272,7 @@ namespace OpenSim.Region.Framework.Scenes
1128 else 1272 else
1129 Animator.ResetAnimations(); 1273 Animator.ResetAnimations();
1130 1274
1275
1131// m_log.DebugFormat( 1276// m_log.DebugFormat(
1132// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1277// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1133// Name, UUID, m_scene.RegionInfo.RegionName); 1278// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1139,6 +1284,7 @@ namespace OpenSim.Region.Framework.Scenes
1139 IsChildAgent = true; 1284 IsChildAgent = true;
1140 m_scene.SwapRootAgentCount(true); 1285 m_scene.SwapRootAgentCount(true);
1141 RemoveFromPhysicalScene(); 1286 RemoveFromPhysicalScene();
1287 ParentID = 0; // Child agents can't be sitting
1142 1288
1143 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1289 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1144 1290
@@ -1154,9 +1300,9 @@ namespace OpenSim.Region.Framework.Scenes
1154 { 1300 {
1155// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1301// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1156 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1302 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1157 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1158 PhysicsActor.UnSubscribeEvents();
1159 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1303 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1304 PhysicsActor.UnSubscribeEvents();
1305 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1160 PhysicsActor = null; 1306 PhysicsActor = null;
1161 } 1307 }
1162// else 1308// else
@@ -1173,7 +1319,7 @@ namespace OpenSim.Region.Framework.Scenes
1173 /// <param name="pos"></param> 1319 /// <param name="pos"></param>
1174 public void Teleport(Vector3 pos) 1320 public void Teleport(Vector3 pos)
1175 { 1321 {
1176 TeleportWithMomentum(pos, null); 1322 TeleportWithMomentum(pos, Vector3.Zero);
1177 } 1323 }
1178 1324
1179 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1325 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1197,6 +1343,41 @@ namespace OpenSim.Region.Framework.Scenes
1197 SendTerseUpdateToAllClients(); 1343 SendTerseUpdateToAllClients();
1198 } 1344 }
1199 1345
1346 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1347 {
1348 CheckLandingPoint(ref newpos);
1349 AbsolutePosition = newpos;
1350
1351 if (newvel.HasValue)
1352 {
1353 if ((Vector3)newvel == Vector3.Zero)
1354 {
1355 if (PhysicsActor != null)
1356 PhysicsActor.SetMomentum(Vector3.Zero);
1357 m_velocity = Vector3.Zero;
1358 }
1359 else
1360 {
1361 if (PhysicsActor != null)
1362 PhysicsActor.SetMomentum((Vector3)newvel);
1363 m_velocity = (Vector3)newvel;
1364
1365 if (rotateToVelXY)
1366 {
1367 Vector3 lookAt = (Vector3)newvel;
1368 lookAt.Z = 0;
1369 lookAt.Normalize();
1370 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1371 return;
1372 }
1373 }
1374 }
1375
1376 SendTerseUpdateToAllClients();
1377 }
1378
1379
1380
1200 public void StopFlying() 1381 public void StopFlying()
1201 { 1382 {
1202 Vector3 pos = AbsolutePosition; 1383 Vector3 pos = AbsolutePosition;
@@ -1385,6 +1566,14 @@ namespace OpenSim.Region.Framework.Scenes
1385 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1566 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1386 } 1567 }
1387 1568
1569 public void SetSize(Vector3 size, float feetoffset)
1570 {
1571// TODO: Merge the physics bits
1572// if (PhysicsActor != null && !IsChildAgent)
1573// PhysicsActor.setAvatarSize(size, feetoffset);
1574
1575 }
1576
1388 private bool WaitForUpdateAgent(IClientAPI client) 1577 private bool WaitForUpdateAgent(IClientAPI client)
1389 { 1578 {
1390 // Before the source region executes UpdateAgent 1579 // Before the source region executes UpdateAgent
@@ -1444,7 +1633,8 @@ namespace OpenSim.Region.Framework.Scenes
1444 1633
1445 Vector3 look = Velocity; 1634 Vector3 look = Velocity;
1446 1635
1447 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1636 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1637 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1448 { 1638 {
1449 look = new Vector3(0.99f, 0.042f, 0); 1639 look = new Vector3(0.99f, 0.042f, 0);
1450 } 1640 }
@@ -1514,11 +1704,12 @@ namespace OpenSim.Region.Framework.Scenes
1514 { 1704 {
1515 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1705 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1516 if (m_agentTransfer != null) 1706 if (m_agentTransfer != null)
1517 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1707 m_agentTransfer.EnableChildAgents(this);
1518 1708
1519 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1709 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1520 if (friendsModule != null) 1710 if (friendsModule != null)
1521 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1711 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1712
1522 } 1713 }
1523 1714
1524 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1715 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1544,36 +1735,69 @@ namespace OpenSim.Region.Framework.Scenes
1544 /// <param name="collisionPoint"></param> 1735 /// <param name="collisionPoint"></param>
1545 /// <param name="localid"></param> 1736 /// <param name="localid"></param>
1546 /// <param name="distance"></param> 1737 /// <param name="distance"></param>
1738 ///
1739
1740 private void UpdateCameraCollisionPlane(Vector4 plane)
1741 {
1742 if (m_lastCameraCollisionPlane != plane)
1743 {
1744 m_lastCameraCollisionPlane = plane;
1745 ControllingClient.SendCameraConstraint(plane);
1746 }
1747 }
1748
1547 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1749 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1548 { 1750 {
1549 const float POSITION_TOLERANCE = 0.02f; 1751 const float POSITION_TOLERANCE = 0.02f;
1550 const float VELOCITY_TOLERANCE = 0.02f;
1551 const float ROTATION_TOLERANCE = 0.02f; 1752 const float ROTATION_TOLERANCE = 0.02f;
1552 1753
1553 if (m_followCamAuto) 1754 m_doingCamRayCast = false;
1755 if (hitYN && localid != LocalId)
1554 { 1756 {
1555 if (hitYN) 1757 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1758 bool IsPrim = group != null;
1759 if (IsPrim)
1556 { 1760 {
1557 CameraConstraintActive = true; 1761 SceneObjectPart part = group.GetPart(localid);
1558 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1762 if (part != null && !part.VolumeDetectActive)
1559 1763 {
1560 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1764 CameraConstraintActive = true;
1561 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1765 pNormal.X = (float) Math.Round(pNormal.X, 2);
1766 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1767 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1768 pNormal.Normalize();
1769 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1770 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1771 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1772
1773 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1774 Vector3.Dot(collisionPoint, pNormal));
1775 UpdateCameraCollisionPlane(plane);
1776 }
1562 } 1777 }
1563 else 1778 else
1564 { 1779 {
1565 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1780 CameraConstraintActive = true;
1566 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1781 pNormal.X = (float) Math.Round(pNormal.X, 2);
1567 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1782 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1568 { 1783 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1569 if (CameraConstraintActive) 1784 pNormal.Normalize();
1570 { 1785 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1571 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1786 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1572 CameraConstraintActive = false; 1787 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1573 } 1788
1574 } 1789 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1790 Vector3.Dot(collisionPoint, pNormal));
1791 UpdateCameraCollisionPlane(plane);
1575 } 1792 }
1576 } 1793 }
1794 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1795 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1796 {
1797 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1798 UpdateCameraCollisionPlane(plane);
1799 CameraConstraintActive = false;
1800 }
1577 } 1801 }
1578 1802
1579 /// <summary> 1803 /// <summary>
@@ -1647,6 +1871,41 @@ namespace OpenSim.Region.Framework.Scenes
1647 StandUp(); 1871 StandUp();
1648 } 1872 }
1649 1873
1874 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1875 // this exclude checks may not be complete
1876
1877 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1878 {
1879 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1880 {
1881 Vector3 posAdjusted = AbsolutePosition;
1882// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1883 posAdjusted.Z += 1.0f; // viewer current camera focus point
1884 Vector3 tocam = CameraPosition - posAdjusted;
1885 tocam.X = (float)Math.Round(tocam.X, 1);
1886 tocam.Y = (float)Math.Round(tocam.Y, 1);
1887 tocam.Z = (float)Math.Round(tocam.Z, 1);
1888
1889 float distTocamlen = tocam.Length();
1890 if (distTocamlen > 0.3f)
1891 {
1892 tocam *= (1.0f / distTocamlen);
1893 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1894 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1895 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1896
1897 m_doingCamRayCast = true;
1898 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1899 }
1900 }
1901 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1902 {
1903 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1904 UpdateCameraCollisionPlane(plane);
1905 CameraConstraintActive = false;
1906 }
1907 }
1908
1650 uint flagsForScripts = (uint)flags; 1909 uint flagsForScripts = (uint)flags;
1651 flags = RemoveIgnoredControls(flags, IgnoredControls); 1910 flags = RemoveIgnoredControls(flags, IgnoredControls);
1652 1911
@@ -2207,7 +2466,8 @@ namespace OpenSim.Region.Framework.Scenes
2207// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2466// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2208 2467
2209 MovingToTarget = false; 2468 MovingToTarget = false;
2210 MoveToPositionTarget = Vector3.Zero; 2469// MoveToPositionTarget = Vector3.Zero;
2470 m_forceToApply = null; // cancel possible last action
2211 2471
2212 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2472 // 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. 2473 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2230,6 +2490,9 @@ namespace OpenSim.Region.Framework.Scenes
2230 2490
2231 if (satOnObject) 2491 if (satOnObject)
2232 { 2492 {
2493 PrevSitOffset = m_pos; // Save sit offset
2494 UnRegisterSeatControls(part.ParentGroup.UUID);
2495
2233 TaskInventoryDictionary taskIDict = part.TaskInventory; 2496 TaskInventoryDictionary taskIDict = part.TaskInventory;
2234 if (taskIDict != null) 2497 if (taskIDict != null)
2235 { 2498 {
@@ -2245,6 +2508,7 @@ namespace OpenSim.Region.Framework.Scenes
2245 } 2508 }
2246 } 2509 }
2247 2510
2511 part.ParentGroup.DeleteAvatar(UUID);
2248 Vector3 sitPartWorldPosition = part.GetWorldPosition(); 2512 Vector3 sitPartWorldPosition = part.GetWorldPosition();
2249 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2513 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2250 2514
@@ -2305,6 +2569,9 @@ namespace OpenSim.Region.Framework.Scenes
2305 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2569 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2306 } 2570 }
2307 2571
2572 else if (PhysicsActor == null)
2573 AddToPhysicalScene(false);
2574
2308 Animator.TrySetMovementAnimation("STAND"); 2575 Animator.TrySetMovementAnimation("STAND");
2309 TriggerScenePresenceUpdated(); 2576 TriggerScenePresenceUpdated();
2310 } 2577 }
@@ -2353,11 +2620,8 @@ namespace OpenSim.Region.Framework.Scenes
2353 if (part == null) 2620 if (part == null)
2354 return; 2621 return;
2355 2622
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) 2623 if (PhysicsActor != null)
2360 m_sitAvatarHeight = PhysicsActor.Size.Z; 2624 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2361 2625
2362 bool canSit = false; 2626 bool canSit = false;
2363 2627
@@ -2384,33 +2648,32 @@ namespace OpenSim.Region.Framework.Scenes
2384 } 2648 }
2385 else 2649 else
2386 { 2650 {
2651 if (PhysicsSit(part,offset)) // physics engine
2652 return;
2653
2387 Vector3 pos = part.AbsolutePosition + offset; 2654 Vector3 pos = part.AbsolutePosition + offset;
2388 2655
2389 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2656 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2390 { 2657 {
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); 2658 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2396 canSit = true; 2659 canSit = true;
2397 } 2660 }
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 } 2661 }
2405 2662
2406 if (canSit) 2663 if (canSit)
2407 { 2664 {
2665
2408 if (PhysicsActor != null) 2666 if (PhysicsActor != null)
2409 { 2667 {
2410 // We can remove the physicsActor until they stand up. 2668 // We can remove the physicsActor until they stand up.
2411 RemoveFromPhysicalScene(); 2669 RemoveFromPhysicalScene();
2412 } 2670 }
2413 2671
2672 if (MovingToTarget)
2673 ResetMoveToTarget();
2674
2675 Velocity = Vector3.Zero;
2676
2414 part.AddSittingAvatar(UUID); 2677 part.AddSittingAvatar(UUID);
2415 2678
2416 cameraAtOffset = part.GetCameraAtOffset(); 2679 cameraAtOffset = part.GetCameraAtOffset();
@@ -2454,14 +2717,6 @@ namespace OpenSim.Region.Framework.Scenes
2454 m_requestedSitTargetID = part.LocalId; 2717 m_requestedSitTargetID = part.LocalId;
2455 m_requestedSitTargetUUID = part.UUID; 2718 m_requestedSitTargetUUID = part.UUID;
2456 2719
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 } 2720 }
2466 else 2721 else
2467 { 2722 {
@@ -2471,197 +2726,115 @@ namespace OpenSim.Region.Framework.Scenes
2471 SendSitResponse(targetID, offset, Quaternion.Identity); 2726 SendSitResponse(targetID, offset, Quaternion.Identity);
2472 } 2727 }
2473 2728
2474 /* 2729 // returns false if does not suport so older sit can be tried
2475 public void SitRayCastAvatarPosition(SceneObjectPart part) 2730 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 { 2731 {
2486 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2732// TODO: Pull in these bits
2487 if (part != null) 2733 return false;
2488 { 2734/*
2489 if (hitYN) 2735 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 { 2736 {
2508 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2737 return true;
2509 m_requestedSitTargetUUID = UUID.Zero;
2510 m_requestedSitTargetID = 0;
2511 m_requestedSitOffset = Vector3.Zero;
2512 } 2738 }
2513 2739
2514 } 2740 if ( m_scene.PhysicsScene == null)
2515 2741 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 2742
2526 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2743 if (part.PhysActor == null)
2527 {
2528 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2529 if (part != null)
2530 { 2744 {
2531 if (hitYN) 2745 // none physcis shape
2532 { 2746 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2533 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2747 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 2748 else
2544 { 2749 { // non physical phantom TODO
2545 SitRayCastCameraPosition(part); 2750 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2751 return false;
2546 } 2752 }
2547 } 2753 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 } 2754 }
2555 2755
2556 }
2557 2756
2558 public void SitRayCastCameraPosition(SceneObjectPart part) 2757 // not doing autopilot
2559 { 2758 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 2759
2568 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2760 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2569 { 2761 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 2762
2763 return false;
2764*/
2598 } 2765 }
2599 2766
2600 public void SitRayHorizontal(SceneObjectPart part) 2767
2768 private bool CanEnterLandPosition(Vector3 testPos)
2601 { 2769 {
2602 // Next, try to raycast from the avatar position to fwd 2770 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2603 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2771
2604 Vector3 StartRayCastPosition = CameraPosition; 2772 if (land == null || land.LandData.Name == "NO_LAND")
2605 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2773 return true;
2606 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2774
2607 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2775 return land.CanBeOnThisLand(UUID,testPos.Z);
2608 } 2776 }
2609 2777
2610 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2778 // status
2779 // < 0 ignore
2780 // 0 bad sit spot
2781 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2611 { 2782 {
2612 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2783 if (status < 0)
2613 if (part != null) 2784 return;
2785
2786 if (status == 0)
2614 { 2787 {
2615 if (hitYN) 2788 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2616 { 2789 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 } 2790 }
2644 else 2791
2792 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2793 if (part == null)
2794 return;
2795
2796 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2797 if(!CanEnterLandPosition(targetPos))
2645 { 2798 {
2646 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2799 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2647 m_requestedSitTargetUUID = UUID.Zero; 2800 return;
2648 m_requestedSitTargetID = 0;
2649 m_requestedSitOffset = Vector3.Zero;
2650 } 2801 }
2651 2802
2652 } 2803 RemoveFromPhysicalScene();
2653 2804
2654 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2805 if (MovingToTarget)
2655 { 2806 ResetMoveToTarget();
2656 int i = 0; 2807
2657 //throw new NotImplementedException(); 2808 Velocity = Vector3.Zero;
2658 //m_requestedSitTargetUUID = UUID.Zero; 2809
2659 //m_requestedSitTargetID = 0; 2810 part.AddSittingAvatar(UUID);
2660 //m_requestedSitOffset = Vector3.Zero; 2811
2812 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2813 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2814 bool forceMouselook = part.GetForceMouselook();
2815
2816 ControllingClient.SendSitResponse(
2817 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2818
2819 // not using autopilot
2820
2821 Rotation = Orientation;
2822 m_pos = offset;
2823
2824 m_requestedSitTargetID = 0;
2825 part.ParentGroup.AddAvatar(UUID);
2826
2827 ParentPart = part;
2828 ParentID = part.LocalId;
2829 if(status == 3)
2830 Animator.TrySetMovementAnimation("SIT_GROUND");
2831 else
2832 Animator.TrySetMovementAnimation("SIT");
2833 SendAvatarDataToAllAgents();
2661 2834
2662 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2835 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2663 } 2836 }
2664 */ 2837
2665 2838
2666 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2839 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2667 { 2840 {
@@ -2681,6 +2854,7 @@ namespace OpenSim.Region.Framework.Scenes
2681 return; 2854 return;
2682 } 2855 }
2683 2856
2857
2684 if (part.SitTargetAvatar == UUID) 2858 if (part.SitTargetAvatar == UUID)
2685 { 2859 {
2686 Vector3 sitTargetPos = part.SitTargetPosition; 2860 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2695,7 +2869,28 @@ namespace OpenSim.Region.Framework.Scenes
2695 2869
2696 //Quaternion result = (sitTargetOrient * vq) * nq; 2870 //Quaternion result = (sitTargetOrient * vq) * nq;
2697 2871
2698 Vector3 newPos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2872 double x, y, z, m;
2873
2874 Quaternion r = sitTargetOrient;
2875 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2876
2877 if (Math.Abs(1.0 - m) > 0.000001)
2878 {
2879 m = 1.0 / Math.Sqrt(m);
2880 r.X *= (float)m;
2881 r.Y *= (float)m;
2882 r.Z *= (float)m;
2883 r.W *= (float)m;
2884 }
2885
2886 x = 2 * (r.X * r.Z + r.Y * r.W);
2887 y = 2 * (-r.X * r.W + r.Y * r.Z);
2888 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2889
2890 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2891 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2892
2893 Vector3 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2699 Quaternion newRot; 2894 Quaternion newRot;
2700 2895
2701 if (part.IsRoot) 2896 if (part.IsRoot)
@@ -2712,6 +2907,9 @@ namespace OpenSim.Region.Framework.Scenes
2712 2907
2713 m_pos = newPos; 2908 m_pos = newPos;
2714 Rotation = newRot; 2909 Rotation = newRot;
2910
2911// ParentPosition = part.AbsolutePosition;
2912 part.ParentGroup.AddAvatar(UUID);
2715 } 2913 }
2716 else 2914 else
2717 { 2915 {
@@ -2719,6 +2917,9 @@ namespace OpenSim.Region.Framework.Scenes
2719 // being sat upon. 2917 // being sat upon.
2720 m_pos -= part.GroupPosition; 2918 m_pos -= part.GroupPosition;
2721 2919
2920// ParentPosition = part.AbsolutePosition;
2921 part.ParentGroup.AddAvatar(UUID);
2922
2722// m_log.DebugFormat( 2923// m_log.DebugFormat(
2723// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2924// "[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); 2925// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
@@ -2834,8 +3035,8 @@ namespace OpenSim.Region.Framework.Scenes
2834 direc.Z *= 2.6f; 3035 direc.Z *= 2.6f;
2835 3036
2836 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 3037 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2837 Animator.TrySetMovementAnimation("PREJUMP"); 3038// Animator.TrySetMovementAnimation("PREJUMP");
2838 Animator.TrySetMovementAnimation("JUMP"); 3039// Animator.TrySetMovementAnimation("JUMP");
2839 } 3040 }
2840 } 3041 }
2841 } 3042 }
@@ -2844,6 +3045,7 @@ namespace OpenSim.Region.Framework.Scenes
2844 3045
2845 // TODO: Add the force instead of only setting it to support multiple forces per frame? 3046 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2846 m_forceToApply = direc; 3047 m_forceToApply = direc;
3048 Animator.UpdateMovementAnimations();
2847 } 3049 }
2848 3050
2849 #endregion 3051 #endregion
@@ -2861,16 +3063,12 @@ namespace OpenSim.Region.Framework.Scenes
2861 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 3063 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2862 // grab the latest PhysicsActor velocity, whereas m_velocity is often 3064 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2863 // storing a requested force instead of an actual traveling velocity 3065 // storing a requested force instead of an actual traveling velocity
3066 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
3067 SendAvatarDataToAllAgents();
2864 3068
2865 // Throw away duplicate or insignificant updates 3069 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2866 if ( 3070 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2867 // If the velocity has become zero, send it no matter what. 3071 !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 { 3072 {
2875 SendTerseUpdateToAllClients(); 3073 SendTerseUpdateToAllClients();
2876 3074
@@ -3030,9 +3228,7 @@ namespace OpenSim.Region.Framework.Scenes
3030 // again here... this comes after the cached appearance check because the avatars 3228 // again here... this comes after the cached appearance check because the avatars
3031 // appearance goes into the avatar update packet 3229 // appearance goes into the avatar update packet
3032 SendAvatarDataToAllAgents(); 3230 SendAvatarDataToAllAgents();
3033 3231 SendAppearanceToAgent(this);
3034 // This invocation always shows up in the viewer logs as an error.
3035 // SendAppearanceToAgent(this);
3036 3232
3037 // If we are using the the cached appearance then send it out to everyone 3233 // If we are using the the cached appearance then send it out to everyone
3038 if (cachedappearance) 3234 if (cachedappearance)
@@ -3063,6 +3259,8 @@ namespace OpenSim.Region.Framework.Scenes
3063 return; 3259 return;
3064 } 3260 }
3065 3261
3262 m_lastSize = Appearance.AvatarSize;
3263
3066 int count = 0; 3264 int count = 0;
3067 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 3265 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3068 { 3266 {
@@ -3170,6 +3368,8 @@ namespace OpenSim.Region.Framework.Scenes
3170 3368
3171 avatar.ControllingClient.SendAppearance( 3369 avatar.ControllingClient.SendAppearance(
3172 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3370 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3371
3372
3173 } 3373 }
3174 3374
3175 #endregion 3375 #endregion
@@ -3243,8 +3443,9 @@ namespace OpenSim.Region.Framework.Scenes
3243 3443
3244 // If we don't have a PhysActor, we can't cross anyway 3444 // 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 3445 // Also don't do this while sat, sitting avatars cross with the
3246 // object they sit on. 3446 // object they sit on. ParentUUID denoted a pending sit, don't
3247 if (ParentID != 0 || PhysicsActor == null) 3447 // interfere with it.
3448 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3248 return; 3449 return;
3249 3450
3250 if (!IsInTransit) 3451 if (!IsInTransit)
@@ -3588,6 +3789,9 @@ namespace OpenSim.Region.Framework.Scenes
3588 cAgent.AlwaysRun = SetAlwaysRun; 3789 cAgent.AlwaysRun = SetAlwaysRun;
3589 3790
3590 cAgent.Appearance = new AvatarAppearance(Appearance); 3791 cAgent.Appearance = new AvatarAppearance(Appearance);
3792
3793 cAgent.ParentPart = ParentUUID;
3794 cAgent.SitOffset = PrevSitOffset;
3591 3795
3592 lock (scriptedcontrols) 3796 lock (scriptedcontrols)
3593 { 3797 {
@@ -3596,7 +3800,7 @@ namespace OpenSim.Region.Framework.Scenes
3596 3800
3597 foreach (ScriptControllers c in scriptedcontrols.Values) 3801 foreach (ScriptControllers c in scriptedcontrols.Values)
3598 { 3802 {
3599 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3803 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3600 } 3804 }
3601 cAgent.Controllers = controls; 3805 cAgent.Controllers = controls;
3602 } 3806 }
@@ -3630,6 +3834,8 @@ namespace OpenSim.Region.Framework.Scenes
3630 CameraAtAxis = cAgent.AtAxis; 3834 CameraAtAxis = cAgent.AtAxis;
3631 CameraLeftAxis = cAgent.LeftAxis; 3835 CameraLeftAxis = cAgent.LeftAxis;
3632 CameraUpAxis = cAgent.UpAxis; 3836 CameraUpAxis = cAgent.UpAxis;
3837 ParentUUID = cAgent.ParentPart;
3838 PrevSitOffset = cAgent.SitOffset;
3633 3839
3634 // When we get to the point of re-computing neighbors everytime this 3840 // When we get to the point of re-computing neighbors everytime this
3635 // changes, then start using the agent's drawdistance rather than the 3841 // changes, then start using the agent's drawdistance rather than the
@@ -3667,6 +3873,7 @@ namespace OpenSim.Region.Framework.Scenes
3667 foreach (ControllerData c in cAgent.Controllers) 3873 foreach (ControllerData c in cAgent.Controllers)
3668 { 3874 {
3669 ScriptControllers sc = new ScriptControllers(); 3875 ScriptControllers sc = new ScriptControllers();
3876 sc.objectID = c.ObjectID;
3670 sc.itemID = c.ItemID; 3877 sc.itemID = c.ItemID;
3671 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3878 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3672 sc.eventControls = (ScriptControlled)c.EventControls; 3879 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3732,20 +3939,27 @@ namespace OpenSim.Region.Framework.Scenes
3732 } 3939 }
3733 3940
3734 if (Appearance.AvatarHeight == 0) 3941 if (Appearance.AvatarHeight == 0)
3735 Appearance.SetHeight(); 3942// Appearance.SetHeight();
3943 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3736 3944
3737 PhysicsScene scene = m_scene.PhysicsScene; 3945 PhysicsScene scene = m_scene.PhysicsScene;
3738 3946
3739 Vector3 pVec = AbsolutePosition; 3947 Vector3 pVec = AbsolutePosition;
3740 3948
3949/*
3950 PhysicsActor = scene.AddAvatar(
3951 LocalId, Firstname + "." + Lastname, pVec,
3952 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3953*/
3954
3741 PhysicsActor = scene.AddAvatar( 3955 PhysicsActor = scene.AddAvatar(
3742 LocalId, Firstname + "." + Lastname, pVec, 3956 LocalId, Firstname + "." + Lastname, pVec,
3743 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3957 Appearance.AvatarBoxSize, isFlying);
3744 3958
3745 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3959 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3746 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3960 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3747 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3961 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3748 PhysicsActor.SubscribeEvents(500); 3962 PhysicsActor.SubscribeEvents(100);
3749 PhysicsActor.LocalID = LocalId; 3963 PhysicsActor.LocalID = LocalId;
3750 } 3964 }
3751 3965
@@ -3759,6 +3973,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); 3973 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3760 } 3974 }
3761 3975
3976
3762 /// <summary> 3977 /// <summary>
3763 /// Event called by the physics plugin to tell the avatar about a collision. 3978 /// Event called by the physics plugin to tell the avatar about a collision.
3764 /// </summary> 3979 /// </summary>
@@ -3772,7 +3987,7 @@ namespace OpenSim.Region.Framework.Scenes
3772 /// <param name="e"></param> 3987 /// <param name="e"></param>
3773 public void PhysicsCollisionUpdate(EventArgs e) 3988 public void PhysicsCollisionUpdate(EventArgs e)
3774 { 3989 {
3775 if (IsChildAgent) 3990 if (IsChildAgent || Animator == null)
3776 return; 3991 return;
3777 3992
3778 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3993 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3789,7 +4004,6 @@ namespace OpenSim.Region.Framework.Scenes
3789 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 4004 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3790 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 4005 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3791 4006
3792 CollisionPlane = Vector4.UnitW;
3793 4007
3794// // No collisions at all means we may be flying. Update always 4008// // No collisions at all means we may be flying. Update always
3795// // to make falling work 4009// // to make falling work
@@ -3799,34 +4013,7 @@ namespace OpenSim.Region.Framework.Scenes
3799// m_lastColCount = coldata.Count; 4013// m_lastColCount = coldata.Count;
3800// } 4014// }
3801 4015
3802 if (coldata.Count != 0) 4016 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 4017
3831 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 4018 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3832 if (Invulnerable || GodLevel > 0) 4019 if (Invulnerable || GodLevel > 0)
@@ -3925,6 +4112,12 @@ namespace OpenSim.Region.Framework.Scenes
3925 // m_reprioritizationTimer.Dispose(); 4112 // m_reprioritizationTimer.Dispose();
3926 4113
3927 RemoveFromPhysicalScene(); 4114 RemoveFromPhysicalScene();
4115
4116 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
4117
4118// if (Animator != null)
4119// Animator.Close();
4120 Animator = null;
3928 4121
3929 LifecycleState = ScenePresenceState.Removed; 4122 LifecycleState = ScenePresenceState.Removed;
3930 } 4123 }
@@ -4160,10 +4353,18 @@ namespace OpenSim.Region.Framework.Scenes
4160 4353
4161 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4354 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
4162 { 4355 {
4356 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4357 if (p == null)
4358 return;
4359
4360 ControllingClient.SendTakeControls(controls, false, false);
4361 ControllingClient.SendTakeControls(controls, true, false);
4362
4163 ScriptControllers obj = new ScriptControllers(); 4363 ScriptControllers obj = new ScriptControllers();
4164 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4364 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4165 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4365 obj.eventControls = ScriptControlled.CONTROL_ZERO;
4166 4366
4367 obj.objectID = p.ParentGroup.UUID;
4167 obj.itemID = Script_item_UUID; 4368 obj.itemID = Script_item_UUID;
4168 if (pass_on == 0 && accept == 0) 4369 if (pass_on == 0 && accept == 0)
4169 { 4370 {
@@ -4212,6 +4413,21 @@ namespace OpenSim.Region.Framework.Scenes
4212 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4413 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4213 } 4414 }
4214 4415
4416 private void UnRegisterSeatControls(UUID obj)
4417 {
4418 List<UUID> takers = new List<UUID>();
4419
4420 foreach (ScriptControllers c in scriptedcontrols.Values)
4421 {
4422 if (c.objectID == obj)
4423 takers.Add(c.itemID);
4424 }
4425 foreach (UUID t in takers)
4426 {
4427 UnRegisterControlEventsToScript(0, t);
4428 }
4429 }
4430
4215 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4431 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4216 { 4432 {
4217 ScriptControllers takecontrols; 4433 ScriptControllers takecontrols;
@@ -4541,6 +4757,12 @@ namespace OpenSim.Region.Framework.Scenes
4541 4757
4542 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4758 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4543 { 4759 {
4760 string reason;
4761
4762 // Honor bans
4763 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4764 return;
4765
4544 SceneObjectGroup telehub = null; 4766 SceneObjectGroup telehub = null;
4545 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4767 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4546 { 4768 {
@@ -4580,11 +4802,119 @@ namespace OpenSim.Region.Framework.Scenes
4580 pos = land.LandData.UserLocation; 4802 pos = land.LandData.UserLocation;
4581 } 4803 }
4582 } 4804 }
4583 4805
4584 land.SendLandUpdateToClient(ControllingClient); 4806 land.SendLandUpdateToClient(ControllingClient);
4585 } 4807 }
4586 } 4808 }
4587 4809
4810 private DetectedObject CreateDetObject(SceneObjectPart obj)
4811 {
4812 DetectedObject detobj = new DetectedObject();
4813 detobj.keyUUID = obj.UUID;
4814 detobj.nameStr = obj.Name;
4815 detobj.ownerUUID = obj.OwnerID;
4816 detobj.posVector = obj.AbsolutePosition;
4817 detobj.rotQuat = obj.GetWorldRotation();
4818 detobj.velVector = obj.Velocity;
4819 detobj.colliderType = 0;
4820 detobj.groupUUID = obj.GroupID;
4821
4822 return detobj;
4823 }
4824
4825 private DetectedObject CreateDetObject(ScenePresence av)
4826 {
4827 DetectedObject detobj = new DetectedObject();
4828 detobj.keyUUID = av.UUID;
4829 detobj.nameStr = av.ControllingClient.Name;
4830 detobj.ownerUUID = av.UUID;
4831 detobj.posVector = av.AbsolutePosition;
4832 detobj.rotQuat = av.Rotation;
4833 detobj.velVector = av.Velocity;
4834 detobj.colliderType = 0;
4835 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4836
4837 return detobj;
4838 }
4839
4840 private DetectedObject CreateDetObjectForGround()
4841 {
4842 DetectedObject detobj = new DetectedObject();
4843 detobj.keyUUID = UUID.Zero;
4844 detobj.nameStr = "";
4845 detobj.ownerUUID = UUID.Zero;
4846 detobj.posVector = AbsolutePosition;
4847 detobj.rotQuat = Quaternion.Identity;
4848 detobj.velVector = Vector3.Zero;
4849 detobj.colliderType = 0;
4850 detobj.groupUUID = UUID.Zero;
4851
4852 return detobj;
4853 }
4854
4855 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4856 {
4857 ColliderArgs colliderArgs = new ColliderArgs();
4858 List<DetectedObject> colliding = new List<DetectedObject>();
4859 foreach (uint localId in colliders)
4860 {
4861 if (localId == 0)
4862 continue;
4863
4864 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4865 if (obj != null)
4866 {
4867 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4868 colliding.Add(CreateDetObject(obj));
4869 }
4870 else
4871 {
4872 ScenePresence av = m_scene.GetScenePresence(localId);
4873 if (av != null && (!av.IsChildAgent))
4874 {
4875 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4876 colliding.Add(CreateDetObject(av));
4877 }
4878 }
4879 }
4880
4881 colliderArgs.Colliders = colliding;
4882
4883 return colliderArgs;
4884 }
4885
4886 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4887
4888 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4889 {
4890 ColliderArgs CollidingMessage;
4891
4892 if (colliders.Count > 0)
4893 {
4894 if ((dest.RootPart.ScriptEvents & ev) != 0)
4895 {
4896 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4897
4898 if (CollidingMessage.Colliders.Count > 0)
4899 notify(dest.RootPart.LocalId, CollidingMessage);
4900 }
4901 }
4902 }
4903
4904 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4905 {
4906 if ((dest.RootPart.ScriptEvents & ev) != 0)
4907 {
4908 ColliderArgs LandCollidingMessage = new ColliderArgs();
4909 List<DetectedObject> colliding = new List<DetectedObject>();
4910
4911 colliding.Add(CreateDetObjectForGround());
4912 LandCollidingMessage.Colliders = colliding;
4913
4914 notify(dest.RootPart.LocalId, LandCollidingMessage);
4915 }
4916 }
4917
4588 private void TeleportFlagsDebug() { 4918 private void TeleportFlagsDebug() {
4589 4919
4590 // Some temporary debugging help to show all the TeleportFlags we have... 4920 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4609,6 +4939,5 @@ namespace OpenSim.Region.Framework.Scenes
4609 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4939 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4610 4940
4611 } 4941 }
4612
4613 } 4942 }
4614} 4943}