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.cs1116
1 files changed, 797 insertions, 319 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 69339b7..5301a82 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -65,6 +65,7 @@ namespace OpenSim.Region.Framework.Scenes
65 65
66 struct ScriptControllers 66 struct ScriptControllers
67 { 67 {
68 public UUID objectID;
68 public UUID itemID; 69 public UUID itemID;
69 public ScriptControlled ignoreControls; 70 public ScriptControlled ignoreControls;
70 public ScriptControlled eventControls; 71 public ScriptControlled eventControls;
@@ -120,7 +121,7 @@ namespace OpenSim.Region.Framework.Scenes
120 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 121 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
121 /// issue #1716 122 /// issue #1716
122 /// </summary> 123 /// </summary>
123 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 124 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
124 125
125 /// <summary> 126 /// <summary>
126 /// Movement updates for agents in neighboring regions are sent directly to clients. 127 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -142,8 +143,6 @@ namespace OpenSim.Region.Framework.Scenes
142 /// <remarks> 143 /// <remarks>
143 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 144 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
144 /// necessary. 145 /// necessary.
145 /// NOTE: To avoid deadlocks, do not lock m_attachments and then perform other tasks under that lock. Take a copy
146 /// of the list and act on that instead.
147 /// </remarks> 146 /// </remarks>
148 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 147 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
149 148
@@ -162,6 +161,10 @@ namespace OpenSim.Region.Framework.Scenes
162 private Vector3 m_lastPosition; 161 private Vector3 m_lastPosition;
163 private Quaternion m_lastRotation; 162 private Quaternion m_lastRotation;
164 private Vector3 m_lastVelocity; 163 private Vector3 m_lastVelocity;
164 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
165
166 private bool m_followCamAuto = false;
167
165 168
166 private Vector3? m_forceToApply; 169 private Vector3? m_forceToApply;
167 private int m_userFlags; 170 private int m_userFlags;
@@ -194,6 +197,7 @@ namespace OpenSim.Region.Framework.Scenes
194// private int m_lastColCount = -1; //KF: Look for Collision chnages 197// private int m_lastColCount = -1; //KF: Look for Collision chnages
195// private int m_updateCount = 0; //KF: Update Anims for a while 198// private int m_updateCount = 0; //KF: Update Anims for a while
196// private static readonly int UPDATE_COUNT = 10; // how many frames to update for 199// private static readonly int UPDATE_COUNT = 10; // how many frames to update for
200 private List<uint> m_lastColliders = new List<uint>();
197 201
198 private TeleportFlags m_teleportFlags; 202 private TeleportFlags m_teleportFlags;
199 public TeleportFlags TeleportFlags 203 public TeleportFlags TeleportFlags
@@ -249,8 +253,6 @@ namespace OpenSim.Region.Framework.Scenes
249 /// </summary> 253 /// </summary>
250 public bool LandAtTarget { get; private set; } 254 public bool LandAtTarget { get; private set; }
251 255
252 private bool m_followCamAuto;
253
254 private int m_movementUpdateCount; 256 private int m_movementUpdateCount;
255 private const int NumMovementsBetweenRayCast = 5; 257 private const int NumMovementsBetweenRayCast = 5;
256 258
@@ -258,6 +260,13 @@ namespace OpenSim.Region.Framework.Scenes
258 //private int m_moveToPositionStateStatus; 260 //private int m_moveToPositionStateStatus;
259 //***************************************************** 261 //*****************************************************
260 262
263 private bool m_collisionEventFlag = false;
264 private object m_collisionEventLock = new Object();
265
266 private int m_movementAnimationUpdateCounter = 0;
267
268 private Vector3 m_prevSitOffset;
269
261 protected AvatarAppearance m_appearance; 270 protected AvatarAppearance m_appearance;
262 271
263 public AvatarAppearance Appearance 272 public AvatarAppearance Appearance
@@ -386,6 +395,9 @@ namespace OpenSim.Region.Framework.Scenes
386 /// </summary> 395 /// </summary>
387 protected Vector3 m_lastCameraPosition; 396 protected Vector3 m_lastCameraPosition;
388 397
398 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
399 private bool m_doingCamRayCast = false;
400
389 public Vector3 CameraPosition { get; set; } 401 public Vector3 CameraPosition { get; set; }
390 402
391 public Quaternion CameraRotation 403 public Quaternion CameraRotation
@@ -466,7 +478,9 @@ namespace OpenSim.Region.Framework.Scenes
466 get { return (IClientCore)ControllingClient; } 478 get { return (IClientCore)ControllingClient; }
467 } 479 }
468 480
469 public Vector3 ParentPosition { get; set; } 481 public UUID COF { get; set; }
482
483// public Vector3 ParentPosition { get; set; }
470 484
471 /// <summary> 485 /// <summary>
472 /// Position of this avatar relative to the region the avatar is in 486 /// Position of this avatar relative to the region the avatar is in
@@ -527,7 +541,7 @@ namespace OpenSim.Region.Framework.Scenes
527 if (ParentID == 0) 541 if (ParentID == 0)
528 { 542 {
529 m_pos = value; 543 m_pos = value;
530 ParentPosition = Vector3.Zero; 544// ParentPosition = Vector3.Zero;
531 } 545 }
532 546
533 //m_log.DebugFormat( 547 //m_log.DebugFormat(
@@ -596,7 +610,24 @@ namespace OpenSim.Region.Framework.Scenes
596// Scene.RegionInfo.RegionName, Name, m_velocity); 610// Scene.RegionInfo.RegionName, Name, m_velocity);
597 } 611 }
598 } 612 }
613/*
614 public override Vector3 AngularVelocity
615 {
616 get
617 {
618 if (PhysicsActor != null)
619 {
620 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
599 621
622 // m_log.DebugFormat(
623 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
624 // m_velocity, Name, Scene.RegionInfo.RegionName);
625 }
626
627 return m_rotationalvelocity;
628 }
629 }
630*/
600 private Quaternion m_bodyRot = Quaternion.Identity; 631 private Quaternion m_bodyRot = Quaternion.Identity;
601 632
602 /// <summary> 633 /// <summary>
@@ -619,8 +650,16 @@ namespace OpenSim.Region.Framework.Scenes
619 m_bodyRot = value; 650 m_bodyRot = value;
620 651
621 if (PhysicsActor != null) 652 if (PhysicsActor != null)
622 PhysicsActor.Orientation = m_bodyRot; 653 {
623 654 try
655 {
656 PhysicsActor.Orientation = m_bodyRot;
657 }
658 catch (Exception e)
659 {
660 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
661 }
662 }
624// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 663// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
625 } 664 }
626 } 665 }
@@ -634,12 +673,20 @@ namespace OpenSim.Region.Framework.Scenes
634 } 673 }
635 674
636 public bool IsChildAgent { get; set; } 675 public bool IsChildAgent { get; set; }
676 public bool IsLoggingIn { get; set; }
637 677
638 /// <summary> 678 /// <summary>
639 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 679 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
640 /// </summary> 680 /// </summary>
641 public uint ParentID { get; set; } 681 public uint ParentID { get; set; }
642 682
683 public UUID ParentUUID
684 {
685 get { return m_parentUUID; }
686 set { m_parentUUID = value; }
687 }
688 private UUID m_parentUUID = UUID.Zero;
689
643 /// <summary> 690 /// <summary>
644 /// Are we sitting on an object? 691 /// Are we sitting on an object?
645 /// </summary> 692 /// </summary>
@@ -789,6 +836,7 @@ namespace OpenSim.Region.Framework.Scenes
789 AttachmentsSyncLock = new Object(); 836 AttachmentsSyncLock = new Object();
790 AllowMovement = true; 837 AllowMovement = true;
791 IsChildAgent = true; 838 IsChildAgent = true;
839 IsLoggingIn = false;
792 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 840 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
793 Animator = new ScenePresenceAnimator(this); 841 Animator = new ScenePresenceAnimator(this);
794 PresenceType = type; 842 PresenceType = type;
@@ -834,6 +882,33 @@ namespace OpenSim.Region.Framework.Scenes
834 m_stateMachine = new ScenePresenceStateMachine(this); 882 m_stateMachine = new ScenePresenceStateMachine(this);
835 } 883 }
836 884
885 private void RegionHeartbeatEnd(Scene scene)
886 {
887 if (IsChildAgent)
888 return;
889
890 m_movementAnimationUpdateCounter ++;
891 if (m_movementAnimationUpdateCounter >= 2)
892 {
893 m_movementAnimationUpdateCounter = 0;
894 if (Animator != null)
895 {
896 // If the parentID == 0 we are not sitting
897 // if !SitGournd then we are not sitting on the ground
898 // Fairly straightforward, now here comes the twist
899 // if ParentUUID is NOT UUID.Zero, we are looking to
900 // be sat on an object that isn't there yet. Should
901 // be treated as if sat.
902 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
903 Animator.UpdateMovementAnimations();
904 }
905 else
906 {
907 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
908 }
909 }
910 }
911
837 public void RegisterToEvents() 912 public void RegisterToEvents()
838 { 913 {
839 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 914 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -844,8 +919,10 @@ namespace OpenSim.Region.Framework.Scenes
844 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 919 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
845 ControllingClient.OnStartAnim += HandleStartAnim; 920 ControllingClient.OnStartAnim += HandleStartAnim;
846 ControllingClient.OnStopAnim += HandleStopAnim; 921 ControllingClient.OnStopAnim += HandleStopAnim;
922 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
847 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 923 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
848 ControllingClient.OnAutoPilotGo += MoveToTarget; 924 ControllingClient.OnAutoPilotGo += MoveToTarget;
925 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
849 926
850 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 927 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
851 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 928 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -904,6 +981,38 @@ namespace OpenSim.Region.Framework.Scenes
904 "[SCENE]: Upgrading child to root agent for {0} in {1}", 981 "[SCENE]: Upgrading child to root agent for {0} in {1}",
905 Name, m_scene.RegionInfo.RegionName); 982 Name, m_scene.RegionInfo.RegionName);
906 983
984 if (ParentUUID != UUID.Zero)
985 {
986 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
987 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
988 if (part == null)
989 {
990 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
991 }
992 else
993 {
994 part.ParentGroup.AddAvatar(UUID);
995 if (part.SitTargetPosition != Vector3.Zero)
996 part.SitTargetAvatar = UUID;
997// ParentPosition = part.GetWorldPosition();
998 ParentID = part.LocalId;
999 ParentPart = part;
1000 m_pos = m_prevSitOffset;
1001// pos = ParentPosition;
1002 pos = part.GetWorldPosition();
1003 }
1004 ParentUUID = UUID.Zero;
1005
1006 IsChildAgent = false;
1007
1008// Animator.TrySetMovementAnimation("SIT");
1009 }
1010 else
1011 {
1012 IsChildAgent = false;
1013 IsLoggingIn = false;
1014 }
1015
907 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 1016 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
908 1017
909 IsChildAgent = false; 1018 IsChildAgent = false;
@@ -921,70 +1030,106 @@ namespace OpenSim.Region.Framework.Scenes
921 1030
922 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1031 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
923 1032
924 // Moved this from SendInitialData to ensure that Appearance is initialized 1033 UUID groupUUID = UUID.Zero;
925 // before the inventory is processed in MakeRootAgent. This fixes a race condition 1034 string GroupName = string.Empty;
926 // related to the handling of attachments 1035 ulong groupPowers = 0;
927 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
928 1036
929 if (m_scene.TestBorderCross(pos, Cardinals.E)) 1037 // ----------------------------------
1038 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1039 try
930 { 1040 {
931 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 1041 if (gm != null)
932 pos.X = crossedBorder.BorderLine.Z - 1; 1042 {
1043 groupUUID = ControllingClient.ActiveGroupId;
1044 GroupRecord record = gm.GetGroupRecord(groupUUID);
1045 if (record != null)
1046 GroupName = record.GroupName;
1047 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1048 if (groupMembershipData != null)
1049 groupPowers = groupMembershipData.GroupPowers;
1050 }
1051 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1052 Grouptitle);
933 } 1053 }
934 1054 catch (Exception e)
935 if (m_scene.TestBorderCross(pos, Cardinals.N))
936 { 1055 {
937 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1056 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
938 pos.Y = crossedBorder.BorderLine.Z - 1;
939 } 1057 }
1058 // ------------------------------------
940 1059
941 CheckAndAdjustLandingPoint(ref pos); 1060 if (ParentID == 0)
942
943 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
944 { 1061 {
945 m_log.WarnFormat( 1062 // Moved this from SendInitialData to ensure that Appearance is initialized
946 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1063 // before the inventory is processed in MakeRootAgent. This fixes a race condition
947 pos, Name, UUID); 1064 // related to the handling of attachments
1065 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1066 if (m_scene.TestBorderCross(pos, Cardinals.E))
1067 {
1068 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1069 pos.X = crossedBorder.BorderLine.Z - 1;
1070 }
948 1071
949 if (pos.X < 0f) pos.X = 0f; 1072 if (m_scene.TestBorderCross(pos, Cardinals.N))
950 if (pos.Y < 0f) pos.Y = 0f; 1073 {
951 if (pos.Z < 0f) pos.Z = 0f; 1074 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
952 } 1075 pos.Y = crossedBorder.BorderLine.Z - 1;
1076 }
953 1077
954 float localAVHeight = 1.56f; 1078 CheckAndAdjustLandingPoint(ref pos);
955 if (Appearance.AvatarHeight > 0)
956 localAVHeight = Appearance.AvatarHeight;
957 1079
958 float posZLimit = 0; 1080 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1081 {
1082 m_log.WarnFormat(
1083 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1084 pos, Name, UUID);
959 1085
960 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1086 if (pos.X < 0f) pos.X = 0f;
961 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1087 if (pos.Y < 0f) pos.Y = 0f;
962 1088 if (pos.Z < 0f) pos.Z = 0f;
963 float newPosZ = posZLimit + localAVHeight / 2; 1089 }
964 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
965 {
966 pos.Z = newPosZ;
967 }
968 AbsolutePosition = pos;
969 1090
970 AddToPhysicalScene(isFlying); 1091 float localAVHeight = 1.56f;
1092 if (Appearance.AvatarHeight > 0)
1093 localAVHeight = Appearance.AvatarHeight;
971 1094
972 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1095 float posZLimit = 0;
973 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
974 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
975 // the value to a negative position which does not trigger the border cross.
976 // This may not be the best location for this.
977 CheckForBorderCrossing();
978 1096
979 if (ForceFly) 1097 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
980 { 1098 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
981 Flying = true; 1099
982 } 1100 float newPosZ = posZLimit + localAVHeight / 2;
983 else if (FlyDisabled) 1101 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
984 { 1102 {
985 Flying = false; 1103 pos.Z = newPosZ;
986 } 1104 }
1105 AbsolutePosition = pos;
1106
1107 if (m_teleportFlags == TeleportFlags.Default)
1108 {
1109 Vector3 vel = Velocity;
1110 AddToPhysicalScene(isFlying);
1111 if (PhysicsActor != null)
1112 PhysicsActor.SetMomentum(vel);
1113 }
1114 else
1115 AddToPhysicalScene(isFlying);
987 1116
1117 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1118 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1119 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1120 // the value to a negative position which does not trigger the border cross.
1121 // This may not be the best location for this.
1122 CheckForBorderCrossing();
1123
1124 if (ForceFly)
1125 {
1126 Flying = true;
1127 }
1128 else if (FlyDisabled)
1129 {
1130 Flying = false;
1131 }
1132 }
988 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1133 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
989 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1134 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
990 // elsewhere anyway 1135 // elsewhere anyway
@@ -1016,31 +1161,28 @@ namespace OpenSim.Region.Framework.Scenes
1016 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1161 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1017 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1162 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1018 // not transporting the required data. 1163 // not transporting the required data.
1019 // 1164 lock (m_attachments)
1020 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1021 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1022 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
1023 //
1024 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
1025 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1026 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1027 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1028 List<SceneObjectGroup> attachments = GetAttachments();
1029
1030 if (attachments.Count > 0)
1031 { 1165 {
1032 m_log.DebugFormat( 1166 if (HasAttachments())
1033 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1034
1035 // Resume scripts
1036 foreach (SceneObjectGroup sog in attachments)
1037 { 1167 {
1038 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1168 m_log.DebugFormat(
1039 sog.ResumeScripts(); 1169 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1170
1171 // Resume scripts
1172 Util.FireAndForget(delegate(object x) {
1173 foreach (SceneObjectGroup sog in m_attachments)
1174 {
1175 sog.ScheduleGroupForFullUpdate();
1176 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1177 sog.ResumeScripts();
1178 }
1179 });
1040 } 1180 }
1041 } 1181 }
1042 } 1182 }
1043 1183
1184 SendAvatarDataToAllAgents();
1185
1044 // send the animations of the other presences to me 1186 // send the animations of the other presences to me
1045 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1187 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1046 { 1188 {
@@ -1051,6 +1193,7 @@ namespace OpenSim.Region.Framework.Scenes
1051 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1193 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1052 // stall on the border crossing since the existing child agent will still have the last movement 1194 // stall on the border crossing since the existing child agent will still have the last movement
1053 // recorded, which stops the input from being processed. 1195 // recorded, which stops the input from being processed.
1196
1054 MovementFlag = 0; 1197 MovementFlag = 0;
1055 1198
1056 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1199 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -1082,12 +1225,16 @@ namespace OpenSim.Region.Framework.Scenes
1082 /// </remarks> 1225 /// </remarks>
1083 public void MakeChildAgent() 1226 public void MakeChildAgent()
1084 { 1227 {
1228 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1229
1085 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1230 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1086 1231
1087 // Reset these so that teleporting in and walking out isn't seen 1232 // Reset these so that teleporting in and walking out isn't seen
1088 // as teleporting back 1233 // as teleporting back
1089 TeleportFlags = TeleportFlags.Default; 1234 TeleportFlags = TeleportFlags.Default;
1090 1235
1236 MovementFlag = 0;
1237
1091 // It looks like Animator is set to null somewhere, and MakeChild 1238 // It looks like Animator is set to null somewhere, and MakeChild
1092 // is called after that. Probably in aborted teleports. 1239 // is called after that. Probably in aborted teleports.
1093 if (Animator == null) 1240 if (Animator == null)
@@ -1095,6 +1242,7 @@ namespace OpenSim.Region.Framework.Scenes
1095 else 1242 else
1096 Animator.ResetAnimations(); 1243 Animator.ResetAnimations();
1097 1244
1245
1098// m_log.DebugFormat( 1246// m_log.DebugFormat(
1099// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1247// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1100// Name, UUID, m_scene.RegionInfo.RegionName); 1248// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1106,6 +1254,7 @@ namespace OpenSim.Region.Framework.Scenes
1106 IsChildAgent = true; 1254 IsChildAgent = true;
1107 m_scene.SwapRootAgentCount(true); 1255 m_scene.SwapRootAgentCount(true);
1108 RemoveFromPhysicalScene(); 1256 RemoveFromPhysicalScene();
1257 ParentID = 0; // Child agents can't be sitting
1109 1258
1110 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1259 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1111 1260
@@ -1121,9 +1270,9 @@ namespace OpenSim.Region.Framework.Scenes
1121 { 1270 {
1122// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1271// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1123 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1272 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1124 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1125 PhysicsActor.UnSubscribeEvents();
1126 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1273 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1274 PhysicsActor.UnSubscribeEvents();
1275 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1127 PhysicsActor = null; 1276 PhysicsActor = null;
1128 } 1277 }
1129// else 1278// else
@@ -1140,7 +1289,7 @@ namespace OpenSim.Region.Framework.Scenes
1140 /// <param name="pos"></param> 1289 /// <param name="pos"></param>
1141 public void Teleport(Vector3 pos) 1290 public void Teleport(Vector3 pos)
1142 { 1291 {
1143 TeleportWithMomentum(pos, null); 1292 TeleportWithMomentum(pos, Vector3.Zero);
1144 } 1293 }
1145 1294
1146 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1295 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1164,6 +1313,41 @@ namespace OpenSim.Region.Framework.Scenes
1164 SendTerseUpdateToAllClients(); 1313 SendTerseUpdateToAllClients();
1165 } 1314 }
1166 1315
1316 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1317 {
1318 CheckLandingPoint(ref newpos);
1319 AbsolutePosition = newpos;
1320
1321 if (newvel.HasValue)
1322 {
1323 if ((Vector3)newvel == Vector3.Zero)
1324 {
1325 if (PhysicsActor != null)
1326 PhysicsActor.SetMomentum(Vector3.Zero);
1327 m_velocity = Vector3.Zero;
1328 }
1329 else
1330 {
1331 if (PhysicsActor != null)
1332 PhysicsActor.SetMomentum((Vector3)newvel);
1333 m_velocity = (Vector3)newvel;
1334
1335 if (rotateToVelXY)
1336 {
1337 Vector3 lookAt = (Vector3)newvel;
1338 lookAt.Z = 0;
1339 lookAt.Normalize();
1340 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1341 return;
1342 }
1343 }
1344 }
1345
1346 SendTerseUpdateToAllClients();
1347 }
1348
1349
1350
1167 public void StopFlying() 1351 public void StopFlying()
1168 { 1352 {
1169 Vector3 pos = AbsolutePosition; 1353 Vector3 pos = AbsolutePosition;
@@ -1352,6 +1536,13 @@ namespace OpenSim.Region.Framework.Scenes
1352 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1536 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1353 } 1537 }
1354 1538
1539 public void SetSize(Vector3 size, float feetoffset)
1540 {
1541 if (PhysicsActor != null && !IsChildAgent)
1542 PhysicsActor.setAvatarSize(size, feetoffset);
1543
1544 }
1545
1355 private bool WaitForUpdateAgent(IClientAPI client) 1546 private bool WaitForUpdateAgent(IClientAPI client)
1356 { 1547 {
1357 // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero 1548 // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero
@@ -1400,7 +1591,8 @@ namespace OpenSim.Region.Framework.Scenes
1400 1591
1401 Vector3 look = Velocity; 1592 Vector3 look = Velocity;
1402 1593
1403 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1594 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1595 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1404 { 1596 {
1405 look = new Vector3(0.99f, 0.042f, 0); 1597 look = new Vector3(0.99f, 0.042f, 0);
1406 } 1598 }
@@ -1458,11 +1650,12 @@ namespace OpenSim.Region.Framework.Scenes
1458 { 1650 {
1459 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1651 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1460 if (m_agentTransfer != null) 1652 if (m_agentTransfer != null)
1461 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1653 m_agentTransfer.EnableChildAgents(this);
1462 1654
1463 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1655 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1464 if (friendsModule != null) 1656 if (friendsModule != null)
1465 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1657 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1658
1466 } 1659 }
1467 1660
1468 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1661 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1488,36 +1681,69 @@ namespace OpenSim.Region.Framework.Scenes
1488 /// <param name="collisionPoint"></param> 1681 /// <param name="collisionPoint"></param>
1489 /// <param name="localid"></param> 1682 /// <param name="localid"></param>
1490 /// <param name="distance"></param> 1683 /// <param name="distance"></param>
1684 ///
1685
1686 private void UpdateCameraCollisionPlane(Vector4 plane)
1687 {
1688 if (m_lastCameraCollisionPlane != plane)
1689 {
1690 m_lastCameraCollisionPlane = plane;
1691 ControllingClient.SendCameraConstraint(plane);
1692 }
1693 }
1694
1491 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1695 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1492 { 1696 {
1493 const float POSITION_TOLERANCE = 0.02f; 1697 const float POSITION_TOLERANCE = 0.02f;
1494 const float VELOCITY_TOLERANCE = 0.02f;
1495 const float ROTATION_TOLERANCE = 0.02f; 1698 const float ROTATION_TOLERANCE = 0.02f;
1496 1699
1497 if (m_followCamAuto) 1700 m_doingCamRayCast = false;
1701 if (hitYN && localid != LocalId)
1498 { 1702 {
1499 if (hitYN) 1703 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1704 bool IsPrim = group != null;
1705 if (IsPrim)
1500 { 1706 {
1501 CameraConstraintActive = true; 1707 SceneObjectPart part = group.GetPart(localid);
1502 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1708 if (part != null && !part.VolumeDetectActive)
1503 1709 {
1504 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1710 CameraConstraintActive = true;
1505 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1711 pNormal.X = (float) Math.Round(pNormal.X, 2);
1712 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1713 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1714 pNormal.Normalize();
1715 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1716 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1717 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1718
1719 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1720 Vector3.Dot(collisionPoint, pNormal));
1721 UpdateCameraCollisionPlane(plane);
1722 }
1506 } 1723 }
1507 else 1724 else
1508 { 1725 {
1509 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1726 CameraConstraintActive = true;
1510 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1727 pNormal.X = (float) Math.Round(pNormal.X, 2);
1511 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1728 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1512 { 1729 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1513 if (CameraConstraintActive) 1730 pNormal.Normalize();
1514 { 1731 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1515 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1732 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1516 CameraConstraintActive = false; 1733 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1517 } 1734
1518 } 1735 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1736 Vector3.Dot(collisionPoint, pNormal));
1737 UpdateCameraCollisionPlane(plane);
1519 } 1738 }
1520 } 1739 }
1740 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1741 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1742 {
1743 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1744 UpdateCameraCollisionPlane(plane);
1745 CameraConstraintActive = false;
1746 }
1521 } 1747 }
1522 1748
1523 /// <summary> 1749 /// <summary>
@@ -1591,6 +1817,41 @@ namespace OpenSim.Region.Framework.Scenes
1591 StandUp(); 1817 StandUp();
1592 } 1818 }
1593 1819
1820 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1821 // this exclude checks may not be complete
1822
1823 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1824 {
1825 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1826 {
1827 Vector3 posAdjusted = AbsolutePosition;
1828// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1829 posAdjusted.Z += 1.0f; // viewer current camera focus point
1830 Vector3 tocam = CameraPosition - posAdjusted;
1831 tocam.X = (float)Math.Round(tocam.X, 1);
1832 tocam.Y = (float)Math.Round(tocam.Y, 1);
1833 tocam.Z = (float)Math.Round(tocam.Z, 1);
1834
1835 float distTocamlen = tocam.Length();
1836 if (distTocamlen > 0.3f)
1837 {
1838 tocam *= (1.0f / distTocamlen);
1839 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1840 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1841 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1842
1843 m_doingCamRayCast = true;
1844 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1845 }
1846 }
1847 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1848 {
1849 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1850 UpdateCameraCollisionPlane(plane);
1851 CameraConstraintActive = false;
1852 }
1853 }
1854
1594 uint flagsForScripts = (uint)flags; 1855 uint flagsForScripts = (uint)flags;
1595 flags = RemoveIgnoredControls(flags, IgnoredControls); 1856 flags = RemoveIgnoredControls(flags, IgnoredControls);
1596 1857
@@ -2127,7 +2388,8 @@ namespace OpenSim.Region.Framework.Scenes
2127// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2388// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2128 2389
2129 MovingToTarget = false; 2390 MovingToTarget = false;
2130 MoveToPositionTarget = Vector3.Zero; 2391// MoveToPositionTarget = Vector3.Zero;
2392 m_forceToApply = null; // cancel possible last action
2131 2393
2132 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2394 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
2133 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2395 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2145,12 +2407,17 @@ namespace OpenSim.Region.Framework.Scenes
2145// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2407// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
2146 2408
2147 SitGround = false; 2409 SitGround = false;
2410
2411/* move this down so avatar gets physical in the new position and not where it is siting
2148 if (PhysicsActor == null) 2412 if (PhysicsActor == null)
2149 AddToPhysicalScene(false); 2413 AddToPhysicalScene(false);
2414 */
2150 2415
2151 if (ParentID != 0) 2416 if (ParentID != 0)
2152 { 2417 {
2153 SceneObjectPart part = ParentPart; 2418 SceneObjectPart part = ParentPart;
2419 UnRegisterSeatControls(part.ParentGroup.UUID);
2420
2154 TaskInventoryDictionary taskIDict = part.TaskInventory; 2421 TaskInventoryDictionary taskIDict = part.TaskInventory;
2155 if (taskIDict != null) 2422 if (taskIDict != null)
2156 { 2423 {
@@ -2166,14 +2433,22 @@ namespace OpenSim.Region.Framework.Scenes
2166 } 2433 }
2167 } 2434 }
2168 2435
2169 ParentPosition = part.GetWorldPosition(); 2436 part.ParentGroup.DeleteAvatar(UUID);
2437// ParentPosition = part.GetWorldPosition();
2170 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2438 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2171 2439
2172 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 2440// m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2173 ParentPosition = Vector3.Zero; 2441// ParentPosition = Vector3.Zero;
2442 m_pos = part.AbsolutePosition + (m_pos * part.GetWorldRotation()) + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2443 if (part.SitTargetAvatar == UUID)
2444 m_bodyRot = part.GetWorldRotation() * part.SitTargetOrientation;
2174 2445
2175 ParentID = 0; 2446 ParentID = 0;
2176 ParentPart = null; 2447 ParentPart = null;
2448
2449 if (PhysicsActor == null)
2450 AddToPhysicalScene(false);
2451
2177 SendAvatarDataToAllAgents(); 2452 SendAvatarDataToAllAgents();
2178 m_requestedSitTargetID = 0; 2453 m_requestedSitTargetID = 0;
2179 2454
@@ -2183,6 +2458,9 @@ namespace OpenSim.Region.Framework.Scenes
2183 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2458 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2184 } 2459 }
2185 2460
2461 else if (PhysicsActor == null)
2462 AddToPhysicalScene(false);
2463
2186 Animator.TrySetMovementAnimation("STAND"); 2464 Animator.TrySetMovementAnimation("STAND");
2187 TriggerScenePresenceUpdated(); 2465 TriggerScenePresenceUpdated();
2188 } 2466 }
@@ -2231,11 +2509,8 @@ namespace OpenSim.Region.Framework.Scenes
2231 if (part == null) 2509 if (part == null)
2232 return; 2510 return;
2233 2511
2234 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2235 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2236
2237 if (PhysicsActor != null) 2512 if (PhysicsActor != null)
2238 m_sitAvatarHeight = PhysicsActor.Size.Z; 2513 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2239 2514
2240 bool canSit = false; 2515 bool canSit = false;
2241 Vector3 pos = part.AbsolutePosition + offset; 2516 Vector3 pos = part.AbsolutePosition + offset;
@@ -2252,31 +2527,31 @@ namespace OpenSim.Region.Framework.Scenes
2252 } 2527 }
2253 else 2528 else
2254 { 2529 {
2530 if (PhysicsSit(part,offset)) // physics engine
2531 return;
2532
2255 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2533 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2256 { 2534 {
2257// m_log.DebugFormat(
2258// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2259// Name, part.Name, part.LocalId);
2260 2535
2261 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2536 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2262 canSit = true; 2537 canSit = true;
2263 } 2538 }
2264// else
2265// {
2266// m_log.DebugFormat(
2267// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2268// Name, part.Name, part.LocalId);
2269// }
2270 } 2539 }
2271 2540
2272 if (canSit) 2541 if (canSit)
2273 { 2542 {
2543
2274 if (PhysicsActor != null) 2544 if (PhysicsActor != null)
2275 { 2545 {
2276 // We can remove the physicsActor until they stand up. 2546 // We can remove the physicsActor until they stand up.
2277 RemoveFromPhysicalScene(); 2547 RemoveFromPhysicalScene();
2278 } 2548 }
2279 2549
2550 if (MovingToTarget)
2551 ResetMoveToTarget();
2552
2553 Velocity = Vector3.Zero;
2554
2280 part.AddSittingAvatar(UUID); 2555 part.AddSittingAvatar(UUID);
2281 2556
2282 cameraAtOffset = part.GetCameraAtOffset(); 2557 cameraAtOffset = part.GetCameraAtOffset();
@@ -2298,6 +2573,9 @@ namespace OpenSim.Region.Framework.Scenes
2298 2573
2299 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2574 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2300 { 2575 {
2576 if (IsChildAgent)
2577 return;
2578
2301 if (ParentID != 0) 2579 if (ParentID != 0)
2302 { 2580 {
2303 if (ParentPart.UUID == targetID) 2581 if (ParentPart.UUID == targetID)
@@ -2313,14 +2591,6 @@ namespace OpenSim.Region.Framework.Scenes
2313 m_requestedSitTargetID = part.LocalId; 2591 m_requestedSitTargetID = part.LocalId;
2314 m_requestedSitTargetUUID = part.UUID; 2592 m_requestedSitTargetUUID = part.UUID;
2315 2593
2316// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2317
2318 if (m_scene.PhysicsScene.SupportsRayCast())
2319 {
2320 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2321 //SitRayCastAvatarPosition(part);
2322 //return;
2323 }
2324 } 2594 }
2325 else 2595 else
2326 { 2596 {
@@ -2330,197 +2600,111 @@ namespace OpenSim.Region.Framework.Scenes
2330 SendSitResponse(targetID, offset, Quaternion.Identity); 2600 SendSitResponse(targetID, offset, Quaternion.Identity);
2331 } 2601 }
2332 2602
2333 /* 2603 // returns false if does not suport so older sit can be tried
2334 public void SitRayCastAvatarPosition(SceneObjectPart part) 2604 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2335 { 2605 {
2336 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2606 if (part == null || part.ParentGroup.IsAttachment)
2337 Vector3 StartRayCastPosition = AbsolutePosition;
2338 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2339 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2340 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2341 }
2342
2343 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2344 {
2345 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2346 if (part != null)
2347 { 2607 {
2348 if (hitYN) 2608 return true;
2349 {
2350 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2351 {
2352 SitRaycastFindEdge(collisionPoint, normal);
2353 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2354 }
2355 else
2356 {
2357 SitRayCastAvatarPositionCameraZ(part);
2358 }
2359 }
2360 else
2361 {
2362 SitRayCastAvatarPositionCameraZ(part);
2363 }
2364 }
2365 else
2366 {
2367 ControllingClient.SendAlertMessage("Sit position no longer exists");
2368 m_requestedSitTargetUUID = UUID.Zero;
2369 m_requestedSitTargetID = 0;
2370 m_requestedSitOffset = Vector3.Zero;
2371 } 2609 }
2372 2610
2373 } 2611 if ( m_scene.PhysicsScene == null)
2374 2612 return false;
2375 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2376 {
2377 // Next, try to raycast from the camera Z position
2378 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2379 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2380 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2381 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2382 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2383 }
2384 2613
2385 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2614 if (part.PhysActor == null)
2386 {
2387 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2388 if (part != null)
2389 { 2615 {
2390 if (hitYN) 2616 // none physcis shape
2391 { 2617 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2392 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2618 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2393 {
2394 SitRaycastFindEdge(collisionPoint, normal);
2395 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2396 }
2397 else
2398 {
2399 SitRayCastCameraPosition(part);
2400 }
2401 }
2402 else 2619 else
2403 { 2620 { // non physical phantom TODO
2404 SitRayCastCameraPosition(part); 2621 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2622 return false;
2405 } 2623 }
2406 } 2624 return true;
2407 else
2408 {
2409 ControllingClient.SendAlertMessage("Sit position no longer exists");
2410 m_requestedSitTargetUUID = UUID.Zero;
2411 m_requestedSitTargetID = 0;
2412 m_requestedSitOffset = Vector3.Zero;
2413 } 2625 }
2414 2626
2415 }
2416 2627
2417 public void SitRayCastCameraPosition(SceneObjectPart part) 2628 // not doing autopilot
2418 { 2629 m_requestedSitTargetID = 0;
2419 // Next, try to raycast from the camera position
2420 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2421 Vector3 StartRayCastPosition = CameraPosition;
2422 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2423 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2424 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2425 }
2426 2630
2427 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2631 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2428 { 2632 return true;
2429 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2430 if (part != null)
2431 {
2432 if (hitYN)
2433 {
2434 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2435 {
2436 SitRaycastFindEdge(collisionPoint, normal);
2437 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2438 }
2439 else
2440 {
2441 SitRayHorizontal(part);
2442 }
2443 }
2444 else
2445 {
2446 SitRayHorizontal(part);
2447 }
2448 }
2449 else
2450 {
2451 ControllingClient.SendAlertMessage("Sit position no longer exists");
2452 m_requestedSitTargetUUID = UUID.Zero;
2453 m_requestedSitTargetID = 0;
2454 m_requestedSitOffset = Vector3.Zero;
2455 }
2456 2633
2634 return false;
2457 } 2635 }
2458 2636
2459 public void SitRayHorizontal(SceneObjectPart part) 2637
2638 private bool CanEnterLandPosition(Vector3 testPos)
2460 { 2639 {
2461 // Next, try to raycast from the avatar position to fwd 2640 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2462 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2641
2463 Vector3 StartRayCastPosition = CameraPosition; 2642 if (land == null || land.LandData.Name == "NO_LAND")
2464 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2643 return true;
2465 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2644
2466 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2645 return land.CanBeOnThisLand(UUID,testPos.Z);
2467 } 2646 }
2468 2647
2469 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2648 // status
2649 // < 0 ignore
2650 // 0 bad sit spot
2651 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2470 { 2652 {
2471 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2653 if (status < 0)
2472 if (part != null) 2654 return;
2655
2656 if (status == 0)
2473 { 2657 {
2474 if (hitYN) 2658 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2475 { 2659 return;
2476 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2477 {
2478 SitRaycastFindEdge(collisionPoint, normal);
2479 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2480 // Next, try to raycast from the camera position
2481 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2482 Vector3 StartRayCastPosition = CameraPosition;
2483 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2484 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2485 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2486 }
2487 else
2488 {
2489 ControllingClient.SendAlertMessage("Sit position not accessable.");
2490 m_requestedSitTargetUUID = UUID.Zero;
2491 m_requestedSitTargetID = 0;
2492 m_requestedSitOffset = Vector3.Zero;
2493 }
2494 }
2495 else
2496 {
2497 ControllingClient.SendAlertMessage("Sit position not accessable.");
2498 m_requestedSitTargetUUID = UUID.Zero;
2499 m_requestedSitTargetID = 0;
2500 m_requestedSitOffset = Vector3.Zero;
2501 }
2502 } 2660 }
2503 else 2661
2662 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2663 if (part == null)
2664 return;
2665
2666 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2667 if(!CanEnterLandPosition(targetPos))
2504 { 2668 {
2505 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2669 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2506 m_requestedSitTargetUUID = UUID.Zero; 2670 return;
2507 m_requestedSitTargetID = 0;
2508 m_requestedSitOffset = Vector3.Zero;
2509 } 2671 }
2510 2672
2511 } 2673 RemoveFromPhysicalScene();
2512 2674
2513 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2675 if (MovingToTarget)
2514 { 2676 ResetMoveToTarget();
2515 int i = 0; 2677
2516 //throw new NotImplementedException(); 2678 Velocity = Vector3.Zero;
2517 //m_requestedSitTargetUUID = UUID.Zero; 2679
2518 //m_requestedSitTargetID = 0; 2680 part.AddSittingAvatar(UUID);
2519 //m_requestedSitOffset = Vector3.Zero; 2681
2682 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2683 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2684 bool forceMouselook = part.GetForceMouselook();
2685
2686 ControllingClient.SendSitResponse(
2687 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2688
2689 // not using autopilot
2690
2691 Rotation = Orientation;
2692 m_pos = offset;
2520 2693
2521 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2694 m_requestedSitTargetID = 0;
2695 part.ParentGroup.AddAvatar(UUID);
2696
2697 ParentPart = part;
2698 ParentID = part.LocalId;
2699 if(status == 3)
2700 Animator.TrySetMovementAnimation("SIT_GROUND");
2701 else
2702 Animator.TrySetMovementAnimation("SIT");
2703 SendAvatarDataToAllAgents();
2704
2705 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2522 } 2706 }
2523 */ 2707
2524 2708
2525 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2709 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2526 { 2710 {
@@ -2537,6 +2721,7 @@ namespace OpenSim.Region.Framework.Scenes
2537 return; 2721 return;
2538 } 2722 }
2539 2723
2724
2540 if (part.SitTargetAvatar == UUID) 2725 if (part.SitTargetAvatar == UUID)
2541 { 2726 {
2542 Vector3 sitTargetPos = part.SitTargetPosition; 2727 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2551,14 +2736,39 @@ namespace OpenSim.Region.Framework.Scenes
2551 2736
2552 //Quaternion result = (sitTargetOrient * vq) * nq; 2737 //Quaternion result = (sitTargetOrient * vq) * nq;
2553 2738
2554 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2739 double x, y, z, m;
2740
2741 Quaternion r = sitTargetOrient;
2742 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2743
2744 if (Math.Abs(1.0 - m) > 0.000001)
2745 {
2746 m = 1.0 / Math.Sqrt(m);
2747 r.X *= (float)m;
2748 r.Y *= (float)m;
2749 r.Z *= (float)m;
2750 r.W *= (float)m;
2751 }
2752
2753 x = 2 * (r.X * r.Z + r.Y * r.W);
2754 y = 2 * (-r.X * r.W + r.Y * r.Z);
2755 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2756
2757 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2758 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2759
2760 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2761
2762// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2555 Rotation = sitTargetOrient; 2763 Rotation = sitTargetOrient;
2556 ParentPosition = part.AbsolutePosition; 2764// ParentPosition = part.AbsolutePosition;
2765 part.ParentGroup.AddAvatar(UUID);
2557 } 2766 }
2558 else 2767 else
2559 { 2768 {
2560 m_pos -= part.AbsolutePosition; 2769 m_pos -= part.AbsolutePosition;
2561 ParentPosition = part.AbsolutePosition; 2770// ParentPosition = part.AbsolutePosition;
2771 part.ParentGroup.AddAvatar(UUID);
2562 2772
2563// m_log.DebugFormat( 2773// m_log.DebugFormat(
2564// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2774// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2613,6 +2823,13 @@ namespace OpenSim.Region.Framework.Scenes
2613 TriggerScenePresenceUpdated(); 2823 TriggerScenePresenceUpdated();
2614 } 2824 }
2615 2825
2826 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
2827 {
2828 Animator.avnChangeAnim(animID, addRemove, sendPack);
2829 }
2830
2831
2832
2616 /// <summary> 2833 /// <summary>
2617 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2834 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2618 /// </summary> 2835 /// </summary>
@@ -2669,8 +2886,8 @@ namespace OpenSim.Region.Framework.Scenes
2669 direc.Z *= 2.6f; 2886 direc.Z *= 2.6f;
2670 2887
2671 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2888 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2672 Animator.TrySetMovementAnimation("PREJUMP"); 2889// Animator.TrySetMovementAnimation("PREJUMP");
2673 Animator.TrySetMovementAnimation("JUMP"); 2890// Animator.TrySetMovementAnimation("JUMP");
2674 } 2891 }
2675 } 2892 }
2676 } 2893 }
@@ -2679,6 +2896,7 @@ namespace OpenSim.Region.Framework.Scenes
2679 2896
2680 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2897 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2681 m_forceToApply = direc; 2898 m_forceToApply = direc;
2899 Animator.UpdateMovementAnimations();
2682 } 2900 }
2683 2901
2684 #endregion 2902 #endregion
@@ -2696,16 +2914,12 @@ namespace OpenSim.Region.Framework.Scenes
2696 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 2914 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2697 // grab the latest PhysicsActor velocity, whereas m_velocity is often 2915 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2698 // storing a requested force instead of an actual traveling velocity 2916 // storing a requested force instead of an actual traveling velocity
2917 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
2918 SendAvatarDataToAllAgents();
2699 2919
2700 // Throw away duplicate or insignificant updates 2920 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2701 if ( 2921 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2702 // If the velocity has become zero, send it no matter what. 2922 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2703 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2704 // otherwise, if things have changed reasonably, send the update
2705 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2706 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2707 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2708
2709 { 2923 {
2710 SendTerseUpdateToAllClients(); 2924 SendTerseUpdateToAllClients();
2711 2925
@@ -2864,9 +3078,7 @@ namespace OpenSim.Region.Framework.Scenes
2864 // again here... this comes after the cached appearance check because the avatars 3078 // again here... this comes after the cached appearance check because the avatars
2865 // appearance goes into the avatar update packet 3079 // appearance goes into the avatar update packet
2866 SendAvatarDataToAllAgents(); 3080 SendAvatarDataToAllAgents();
2867 3081 SendAppearanceToAgent(this);
2868 // This invocation always shows up in the viewer logs as an error.
2869 // SendAppearanceToAgent(this);
2870 3082
2871 // If we are using the the cached appearance then send it out to everyone 3083 // If we are using the the cached appearance then send it out to everyone
2872 if (cachedappearance) 3084 if (cachedappearance)
@@ -2897,6 +3109,8 @@ namespace OpenSim.Region.Framework.Scenes
2897 return; 3109 return;
2898 } 3110 }
2899 3111
3112 m_lastSize = Appearance.AvatarSize;
3113
2900 int count = 0; 3114 int count = 0;
2901 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 3115 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2902 { 3116 {
@@ -3004,6 +3218,8 @@ namespace OpenSim.Region.Framework.Scenes
3004 3218
3005 avatar.ControllingClient.SendAppearance( 3219 avatar.ControllingClient.SendAppearance(
3006 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3220 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3221
3222
3007 } 3223 }
3008 3224
3009 #endregion 3225 #endregion
@@ -3077,8 +3293,9 @@ namespace OpenSim.Region.Framework.Scenes
3077 3293
3078 // If we don't have a PhysActor, we can't cross anyway 3294 // If we don't have a PhysActor, we can't cross anyway
3079 // Also don't do this while sat, sitting avatars cross with the 3295 // Also don't do this while sat, sitting avatars cross with the
3080 // object they sit on. 3296 // object they sit on. ParentUUID denoted a pending sit, don't
3081 if (ParentID != 0 || PhysicsActor == null) 3297 // interfere with it.
3298 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3082 return; 3299 return;
3083 3300
3084 if (!IsInTransit) 3301 if (!IsInTransit)
@@ -3345,6 +3562,10 @@ namespace OpenSim.Region.Framework.Scenes
3345 } 3562 }
3346 3563
3347 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3564 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3565 private void RaiseUpdateThrottles()
3566 {
3567 m_scene.EventManager.TriggerThrottleUpdate(this);
3568 }
3348 /// <summary> 3569 /// <summary>
3349 /// This updates important decision making data about a child agent 3570 /// This updates important decision making data about a child agent
3350 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3571 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3426,6 +3647,9 @@ namespace OpenSim.Region.Framework.Scenes
3426 cAgent.AlwaysRun = SetAlwaysRun; 3647 cAgent.AlwaysRun = SetAlwaysRun;
3427 3648
3428 cAgent.Appearance = new AvatarAppearance(Appearance); 3649 cAgent.Appearance = new AvatarAppearance(Appearance);
3650
3651 cAgent.ParentPart = ParentUUID;
3652 cAgent.SitOffset = m_pos;
3429 3653
3430 lock (scriptedcontrols) 3654 lock (scriptedcontrols)
3431 { 3655 {
@@ -3434,7 +3658,7 @@ namespace OpenSim.Region.Framework.Scenes
3434 3658
3435 foreach (ScriptControllers c in scriptedcontrols.Values) 3659 foreach (ScriptControllers c in scriptedcontrols.Values)
3436 { 3660 {
3437 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3661 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3438 } 3662 }
3439 cAgent.Controllers = controls; 3663 cAgent.Controllers = controls;
3440 } 3664 }
@@ -3467,6 +3691,8 @@ namespace OpenSim.Region.Framework.Scenes
3467 CameraAtAxis = cAgent.AtAxis; 3691 CameraAtAxis = cAgent.AtAxis;
3468 CameraLeftAxis = cAgent.LeftAxis; 3692 CameraLeftAxis = cAgent.LeftAxis;
3469 CameraUpAxis = cAgent.UpAxis; 3693 CameraUpAxis = cAgent.UpAxis;
3694 ParentUUID = cAgent.ParentPart;
3695 m_prevSitOffset = cAgent.SitOffset;
3470 3696
3471 // When we get to the point of re-computing neighbors everytime this 3697 // When we get to the point of re-computing neighbors everytime this
3472 // changes, then start using the agent's drawdistance rather than the 3698 // changes, then start using the agent's drawdistance rather than the
@@ -3504,6 +3730,7 @@ namespace OpenSim.Region.Framework.Scenes
3504 foreach (ControllerData c in cAgent.Controllers) 3730 foreach (ControllerData c in cAgent.Controllers)
3505 { 3731 {
3506 ScriptControllers sc = new ScriptControllers(); 3732 ScriptControllers sc = new ScriptControllers();
3733 sc.objectID = c.ObjectID;
3507 sc.itemID = c.ItemID; 3734 sc.itemID = c.ItemID;
3508 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3735 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3509 sc.eventControls = (ScriptControlled)c.EventControls; 3736 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3571,20 +3798,27 @@ namespace OpenSim.Region.Framework.Scenes
3571 } 3798 }
3572 3799
3573 if (Appearance.AvatarHeight == 0) 3800 if (Appearance.AvatarHeight == 0)
3574 Appearance.SetHeight(); 3801// Appearance.SetHeight();
3802 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3575 3803
3576 PhysicsScene scene = m_scene.PhysicsScene; 3804 PhysicsScene scene = m_scene.PhysicsScene;
3577 3805
3578 Vector3 pVec = AbsolutePosition; 3806 Vector3 pVec = AbsolutePosition;
3579 3807
3808/*
3809 PhysicsActor = scene.AddAvatar(
3810 LocalId, Firstname + "." + Lastname, pVec,
3811 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3812*/
3813
3580 PhysicsActor = scene.AddAvatar( 3814 PhysicsActor = scene.AddAvatar(
3581 LocalId, Firstname + "." + Lastname, pVec, 3815 LocalId, Firstname + "." + Lastname, pVec,
3582 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3816 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
3583 3817
3584 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3818 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3585 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3819 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3586 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3820 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3587 PhysicsActor.SubscribeEvents(500); 3821 PhysicsActor.SubscribeEvents(100);
3588 PhysicsActor.LocalID = LocalId; 3822 PhysicsActor.LocalID = LocalId;
3589 } 3823 }
3590 3824
@@ -3598,6 +3832,7 @@ namespace OpenSim.Region.Framework.Scenes
3598 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3832 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3599 } 3833 }
3600 3834
3835
3601 /// <summary> 3836 /// <summary>
3602 /// Event called by the physics plugin to tell the avatar about a collision. 3837 /// Event called by the physics plugin to tell the avatar about a collision.
3603 /// </summary> 3838 /// </summary>
@@ -3611,7 +3846,7 @@ namespace OpenSim.Region.Framework.Scenes
3611 /// <param name="e"></param> 3846 /// <param name="e"></param>
3612 public void PhysicsCollisionUpdate(EventArgs e) 3847 public void PhysicsCollisionUpdate(EventArgs e)
3613 { 3848 {
3614 if (IsChildAgent) 3849 if (IsChildAgent || Animator == null)
3615 return; 3850 return;
3616 3851
3617 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3852 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3628,7 +3863,6 @@ namespace OpenSim.Region.Framework.Scenes
3628 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3863 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3629 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3864 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3630 3865
3631 CollisionPlane = Vector4.UnitW;
3632 3866
3633// // No collisions at all means we may be flying. Update always 3867// // No collisions at all means we may be flying. Update always
3634// // to make falling work 3868// // to make falling work
@@ -3640,6 +3874,7 @@ namespace OpenSim.Region.Framework.Scenes
3640 3874
3641 if (coldata.Count != 0) 3875 if (coldata.Count != 0)
3642 { 3876 {
3877/*
3643 switch (Animator.CurrentMovementAnimation) 3878 switch (Animator.CurrentMovementAnimation)
3644 { 3879 {
3645 case "STAND": 3880 case "STAND":
@@ -3648,24 +3883,38 @@ namespace OpenSim.Region.Framework.Scenes
3648 case "CROUCH": 3883 case "CROUCH":
3649 case "CROUCHWALK": 3884 case "CROUCHWALK":
3650 { 3885 {
3886 */
3651 ContactPoint lowest; 3887 ContactPoint lowest;
3652 lowest.SurfaceNormal = Vector3.Zero; 3888 lowest.SurfaceNormal = Vector3.Zero;
3653 lowest.Position = Vector3.Zero; 3889 lowest.Position = Vector3.Zero;
3654 lowest.Position.Z = Single.NaN; 3890 lowest.Position.Z = float.MaxValue;
3655 3891
3656 foreach (ContactPoint contact in coldata.Values) 3892 foreach (ContactPoint contact in coldata.Values)
3657 { 3893 {
3658 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 3894
3895 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3659 { 3896 {
3660 lowest = contact; 3897 lowest = contact;
3661 } 3898 }
3662 } 3899 }
3663 3900
3664 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 3901 if (lowest.Position.Z != float.MaxValue)
3902 {
3903 lowest.SurfaceNormal = -lowest.SurfaceNormal;
3904 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3905 }
3906 else
3907 CollisionPlane = Vector4.UnitW;
3908/*
3665 } 3909 }
3666 break; 3910 break;
3667 } 3911 }
3912*/
3668 } 3913 }
3914 else
3915 CollisionPlane = Vector4.UnitW;
3916
3917 RaiseCollisionScriptEvents(coldata);
3669 3918
3670 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3919 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3671 if (Invulnerable || GodLevel > 0) 3920 if (Invulnerable || GodLevel > 0)
@@ -3764,6 +4013,12 @@ namespace OpenSim.Region.Framework.Scenes
3764 // m_reprioritizationTimer.Dispose(); 4013 // m_reprioritizationTimer.Dispose();
3765 4014
3766 RemoveFromPhysicalScene(); 4015 RemoveFromPhysicalScene();
4016
4017 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
4018
4019// if (Animator != null)
4020// Animator.Close();
4021 Animator = null;
3767 4022
3768 LifecycleState = ScenePresenceState.Removed; 4023 LifecycleState = ScenePresenceState.Removed;
3769 } 4024 }
@@ -3999,10 +4254,18 @@ namespace OpenSim.Region.Framework.Scenes
3999 4254
4000 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4255 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
4001 { 4256 {
4257 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4258 if (p == null)
4259 return;
4260
4261 ControllingClient.SendTakeControls(controls, false, false);
4262 ControllingClient.SendTakeControls(controls, true, false);
4263
4002 ScriptControllers obj = new ScriptControllers(); 4264 ScriptControllers obj = new ScriptControllers();
4003 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4265 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4004 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4266 obj.eventControls = ScriptControlled.CONTROL_ZERO;
4005 4267
4268 obj.objectID = p.ParentGroup.UUID;
4006 obj.itemID = Script_item_UUID; 4269 obj.itemID = Script_item_UUID;
4007 if (pass_on == 0 && accept == 0) 4270 if (pass_on == 0 && accept == 0)
4008 { 4271 {
@@ -4051,6 +4314,21 @@ namespace OpenSim.Region.Framework.Scenes
4051 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4314 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4052 } 4315 }
4053 4316
4317 private void UnRegisterSeatControls(UUID obj)
4318 {
4319 List<UUID> takers = new List<UUID>();
4320
4321 foreach (ScriptControllers c in scriptedcontrols.Values)
4322 {
4323 if (c.objectID == obj)
4324 takers.Add(c.itemID);
4325 }
4326 foreach (UUID t in takers)
4327 {
4328 UnRegisterControlEventsToScript(0, t);
4329 }
4330 }
4331
4054 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4332 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4055 { 4333 {
4056 ScriptControllers takecontrols; 4334 ScriptControllers takecontrols;
@@ -4380,6 +4658,12 @@ namespace OpenSim.Region.Framework.Scenes
4380 4658
4381 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4659 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4382 { 4660 {
4661 string reason;
4662
4663 // Honor bans
4664 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4665 return;
4666
4383 SceneObjectGroup telehub = null; 4667 SceneObjectGroup telehub = null;
4384 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4668 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4385 { 4669 {
@@ -4419,11 +4703,206 @@ namespace OpenSim.Region.Framework.Scenes
4419 pos = land.LandData.UserLocation; 4703 pos = land.LandData.UserLocation;
4420 } 4704 }
4421 } 4705 }
4422 4706
4423 land.SendLandUpdateToClient(ControllingClient); 4707 land.SendLandUpdateToClient(ControllingClient);
4424 } 4708 }
4425 } 4709 }
4426 4710
4711 private DetectedObject CreateDetObject(SceneObjectPart obj)
4712 {
4713 DetectedObject detobj = new DetectedObject();
4714 detobj.keyUUID = obj.UUID;
4715 detobj.nameStr = obj.Name;
4716 detobj.ownerUUID = obj.OwnerID;
4717 detobj.posVector = obj.AbsolutePosition;
4718 detobj.rotQuat = obj.GetWorldRotation();
4719 detobj.velVector = obj.Velocity;
4720 detobj.colliderType = 0;
4721 detobj.groupUUID = obj.GroupID;
4722
4723 return detobj;
4724 }
4725
4726 private DetectedObject CreateDetObject(ScenePresence av)
4727 {
4728 DetectedObject detobj = new DetectedObject();
4729 detobj.keyUUID = av.UUID;
4730 detobj.nameStr = av.ControllingClient.Name;
4731 detobj.ownerUUID = av.UUID;
4732 detobj.posVector = av.AbsolutePosition;
4733 detobj.rotQuat = av.Rotation;
4734 detobj.velVector = av.Velocity;
4735 detobj.colliderType = 0;
4736 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4737
4738 return detobj;
4739 }
4740
4741 private DetectedObject CreateDetObjectForGround()
4742 {
4743 DetectedObject detobj = new DetectedObject();
4744 detobj.keyUUID = UUID.Zero;
4745 detobj.nameStr = "";
4746 detobj.ownerUUID = UUID.Zero;
4747 detobj.posVector = AbsolutePosition;
4748 detobj.rotQuat = Quaternion.Identity;
4749 detobj.velVector = Vector3.Zero;
4750 detobj.colliderType = 0;
4751 detobj.groupUUID = UUID.Zero;
4752
4753 return detobj;
4754 }
4755
4756 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4757 {
4758 ColliderArgs colliderArgs = new ColliderArgs();
4759 List<DetectedObject> colliding = new List<DetectedObject>();
4760 foreach (uint localId in colliders)
4761 {
4762 if (localId == 0)
4763 continue;
4764
4765 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4766 if (obj != null)
4767 {
4768 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4769 colliding.Add(CreateDetObject(obj));
4770 }
4771 else
4772 {
4773 ScenePresence av = m_scene.GetScenePresence(localId);
4774 if (av != null && (!av.IsChildAgent))
4775 {
4776 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4777 colliding.Add(CreateDetObject(av));
4778 }
4779 }
4780 }
4781
4782 colliderArgs.Colliders = colliding;
4783
4784 return colliderArgs;
4785 }
4786
4787 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4788
4789 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4790 {
4791 ColliderArgs CollidingMessage;
4792
4793 if (colliders.Count > 0)
4794 {
4795 if ((dest.RootPart.ScriptEvents & ev) != 0)
4796 {
4797 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4798
4799 if (CollidingMessage.Colliders.Count > 0)
4800 notify(dest.RootPart.LocalId, CollidingMessage);
4801 }
4802 }
4803 }
4804
4805 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4806 {
4807 if ((dest.RootPart.ScriptEvents & ev) != 0)
4808 {
4809 ColliderArgs LandCollidingMessage = new ColliderArgs();
4810 List<DetectedObject> colliding = new List<DetectedObject>();
4811
4812 colliding.Add(CreateDetObjectForGround());
4813 LandCollidingMessage.Colliders = colliding;
4814
4815 notify(dest.RootPart.LocalId, LandCollidingMessage);
4816 }
4817 }
4818
4819 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
4820 {
4821 try
4822 {
4823 List<uint> thisHitColliders = new List<uint>();
4824 List<uint> endedColliders = new List<uint>();
4825 List<uint> startedColliders = new List<uint>();
4826 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
4827 CollisionForSoundInfo soundinfo;
4828 ContactPoint curcontact;
4829
4830 if (coldata.Count == 0)
4831 {
4832 if (m_lastColliders.Count == 0)
4833 return; // nothing to do
4834
4835 foreach (uint localID in m_lastColliders)
4836 {
4837 endedColliders.Add(localID);
4838 }
4839 m_lastColliders.Clear();
4840 }
4841
4842 else
4843 {
4844 foreach (uint id in coldata.Keys)
4845 {
4846 thisHitColliders.Add(id);
4847 if (!m_lastColliders.Contains(id))
4848 {
4849 startedColliders.Add(id);
4850 curcontact = coldata[id];
4851 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
4852 {
4853 soundinfo = new CollisionForSoundInfo();
4854 soundinfo.colliderID = id;
4855 soundinfo.position = curcontact.Position;
4856 soundinfo.relativeVel = curcontact.RelativeSpeed;
4857 soundinfolist.Add(soundinfo);
4858 }
4859 }
4860 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
4861 }
4862
4863 // calculate things that ended colliding
4864 foreach (uint localID in m_lastColliders)
4865 {
4866 if (!thisHitColliders.Contains(localID))
4867 {
4868 endedColliders.Add(localID);
4869 }
4870 }
4871 //add the items that started colliding this time to the last colliders list.
4872 foreach (uint localID in startedColliders)
4873 {
4874 m_lastColliders.Add(localID);
4875 }
4876 // remove things that ended colliding from the last colliders list
4877 foreach (uint localID in endedColliders)
4878 {
4879 m_lastColliders.Remove(localID);
4880 }
4881
4882 if (soundinfolist.Count > 0)
4883 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
4884 }
4885
4886 foreach (SceneObjectGroup att in GetAttachments())
4887 {
4888 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
4889 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
4890 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
4891
4892 if (startedColliders.Contains(0))
4893 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
4894 if (m_lastColliders.Contains(0))
4895 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
4896 if (endedColliders.Contains(0))
4897 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
4898 }
4899 }
4900 finally
4901 {
4902 m_collisionEventFlag = false;
4903 }
4904 }
4905
4427 private void TeleportFlagsDebug() { 4906 private void TeleportFlagsDebug() {
4428 4907
4429 // Some temporary debugging help to show all the TeleportFlags we have... 4908 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4448,6 +4927,5 @@ namespace OpenSim.Region.Framework.Scenes
4448 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4927 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4449 4928
4450 } 4929 }
4451
4452 } 4930 }
4453} 4931}