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.cs1117
1 files changed, 798 insertions, 319 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 17da0d9..c4876b3 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;
@@ -101,7 +102,7 @@ namespace OpenSim.Region.Framework.Scenes
101 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 102 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
102 /// issue #1716 103 /// issue #1716
103 /// </summary> 104 /// </summary>
104 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 105 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
105 106
106 /// <summary> 107 /// <summary>
107 /// Movement updates for agents in neighboring regions are sent directly to clients. 108 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -123,8 +124,6 @@ namespace OpenSim.Region.Framework.Scenes
123 /// <remarks> 124 /// <remarks>
124 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 125 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
125 /// necessary. 126 /// necessary.
126 /// NOTE: To avoid deadlocks, do not lock m_attachments and then perform other tasks under that lock. Take a copy
127 /// of the list and act on that instead.
128 /// </remarks> 127 /// </remarks>
129 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 128 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
130 129
@@ -143,6 +142,10 @@ namespace OpenSim.Region.Framework.Scenes
143 private Vector3 m_lastPosition; 142 private Vector3 m_lastPosition;
144 private Quaternion m_lastRotation; 143 private Quaternion m_lastRotation;
145 private Vector3 m_lastVelocity; 144 private Vector3 m_lastVelocity;
145 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
146
147 private bool m_followCamAuto = false;
148
146 149
147 private Vector3? m_forceToApply; 150 private Vector3? m_forceToApply;
148 private int m_userFlags; 151 private int m_userFlags;
@@ -175,6 +178,7 @@ namespace OpenSim.Region.Framework.Scenes
175// private int m_lastColCount = -1; //KF: Look for Collision chnages 178// private int m_lastColCount = -1; //KF: Look for Collision chnages
176// private int m_updateCount = 0; //KF: Update Anims for a while 179// private int m_updateCount = 0; //KF: Update Anims for a while
177// private static readonly int UPDATE_COUNT = 10; // how many frames to update for 180// private static readonly int UPDATE_COUNT = 10; // how many frames to update for
181 private List<uint> m_lastColliders = new List<uint>();
178 182
179 private TeleportFlags m_teleportFlags; 183 private TeleportFlags m_teleportFlags;
180 public TeleportFlags TeleportFlags 184 public TeleportFlags TeleportFlags
@@ -230,8 +234,6 @@ namespace OpenSim.Region.Framework.Scenes
230 /// </summary> 234 /// </summary>
231 public bool LandAtTarget { get; private set; } 235 public bool LandAtTarget { get; private set; }
232 236
233 private bool m_followCamAuto;
234
235 private int m_movementUpdateCount; 237 private int m_movementUpdateCount;
236 private const int NumMovementsBetweenRayCast = 5; 238 private const int NumMovementsBetweenRayCast = 5;
237 239
@@ -239,6 +241,13 @@ namespace OpenSim.Region.Framework.Scenes
239 //private int m_moveToPositionStateStatus; 241 //private int m_moveToPositionStateStatus;
240 //***************************************************** 242 //*****************************************************
241 243
244 private bool m_collisionEventFlag = false;
245 private object m_collisionEventLock = new Object();
246
247 private int m_movementAnimationUpdateCounter = 0;
248
249 private Vector3 m_prevSitOffset;
250
242 protected AvatarAppearance m_appearance; 251 protected AvatarAppearance m_appearance;
243 252
244 public AvatarAppearance Appearance 253 public AvatarAppearance Appearance
@@ -353,6 +362,9 @@ namespace OpenSim.Region.Framework.Scenes
353 /// </summary> 362 /// </summary>
354 protected Vector3 m_lastCameraPosition; 363 protected Vector3 m_lastCameraPosition;
355 364
365 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
366 private bool m_doingCamRayCast = false;
367
356 public Vector3 CameraPosition { get; set; } 368 public Vector3 CameraPosition { get; set; }
357 369
358 public Quaternion CameraRotation 370 public Quaternion CameraRotation
@@ -433,7 +445,9 @@ namespace OpenSim.Region.Framework.Scenes
433 get { return (IClientCore)ControllingClient; } 445 get { return (IClientCore)ControllingClient; }
434 } 446 }
435 447
436 public Vector3 ParentPosition { get; set; } 448 public UUID COF { get; set; }
449
450// public Vector3 ParentPosition { get; set; }
437 451
438 /// <summary> 452 /// <summary>
439 /// Position of this avatar relative to the region the avatar is in 453 /// Position of this avatar relative to the region the avatar is in
@@ -494,7 +508,7 @@ namespace OpenSim.Region.Framework.Scenes
494 if (ParentID == 0) 508 if (ParentID == 0)
495 { 509 {
496 m_pos = value; 510 m_pos = value;
497 ParentPosition = Vector3.Zero; 511// ParentPosition = Vector3.Zero;
498 } 512 }
499 513
500 //m_log.DebugFormat( 514 //m_log.DebugFormat(
@@ -563,7 +577,24 @@ namespace OpenSim.Region.Framework.Scenes
563// Scene.RegionInfo.RegionName, Name, m_velocity); 577// Scene.RegionInfo.RegionName, Name, m_velocity);
564 } 578 }
565 } 579 }
580/*
581 public override Vector3 AngularVelocity
582 {
583 get
584 {
585 if (PhysicsActor != null)
586 {
587 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
566 588
589 // m_log.DebugFormat(
590 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
591 // m_velocity, Name, Scene.RegionInfo.RegionName);
592 }
593
594 return m_rotationalvelocity;
595 }
596 }
597*/
567 private Quaternion m_bodyRot = Quaternion.Identity; 598 private Quaternion m_bodyRot = Quaternion.Identity;
568 599
569 /// <summary> 600 /// <summary>
@@ -586,8 +617,16 @@ namespace OpenSim.Region.Framework.Scenes
586 m_bodyRot = value; 617 m_bodyRot = value;
587 618
588 if (PhysicsActor != null) 619 if (PhysicsActor != null)
589 PhysicsActor.Orientation = m_bodyRot; 620 {
590 621 try
622 {
623 PhysicsActor.Orientation = m_bodyRot;
624 }
625 catch (Exception e)
626 {
627 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
628 }
629 }
591// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 630// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
592 } 631 }
593 } 632 }
@@ -601,12 +640,20 @@ namespace OpenSim.Region.Framework.Scenes
601 } 640 }
602 641
603 public bool IsChildAgent { get; set; } 642 public bool IsChildAgent { get; set; }
643 public bool IsLoggingIn { get; set; }
604 644
605 /// <summary> 645 /// <summary>
606 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 646 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
607 /// </summary> 647 /// </summary>
608 public uint ParentID { get; set; } 648 public uint ParentID { get; set; }
609 649
650 public UUID ParentUUID
651 {
652 get { return m_parentUUID; }
653 set { m_parentUUID = value; }
654 }
655 private UUID m_parentUUID = UUID.Zero;
656
610 /// <summary> 657 /// <summary>
611 /// Are we sitting on an object? 658 /// Are we sitting on an object?
612 /// </summary> 659 /// </summary>
@@ -763,6 +810,7 @@ namespace OpenSim.Region.Framework.Scenes
763 AttachmentsSyncLock = new Object(); 810 AttachmentsSyncLock = new Object();
764 AllowMovement = true; 811 AllowMovement = true;
765 IsChildAgent = true; 812 IsChildAgent = true;
813 IsLoggingIn = false;
766 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 814 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
767 Animator = new ScenePresenceAnimator(this); 815 Animator = new ScenePresenceAnimator(this);
768 PresenceType = type; 816 PresenceType = type;
@@ -806,6 +854,33 @@ namespace OpenSim.Region.Framework.Scenes
806 Appearance = appearance; 854 Appearance = appearance;
807 } 855 }
808 856
857 private void RegionHeartbeatEnd(Scene scene)
858 {
859 if (IsChildAgent)
860 return;
861
862 m_movementAnimationUpdateCounter ++;
863 if (m_movementAnimationUpdateCounter >= 2)
864 {
865 m_movementAnimationUpdateCounter = 0;
866 if (Animator != null)
867 {
868 // If the parentID == 0 we are not sitting
869 // if !SitGournd then we are not sitting on the ground
870 // Fairly straightforward, now here comes the twist
871 // if ParentUUID is NOT UUID.Zero, we are looking to
872 // be sat on an object that isn't there yet. Should
873 // be treated as if sat.
874 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
875 Animator.UpdateMovementAnimations();
876 }
877 else
878 {
879 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
880 }
881 }
882 }
883
809 public void RegisterToEvents() 884 public void RegisterToEvents()
810 { 885 {
811 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 886 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -816,8 +891,10 @@ namespace OpenSim.Region.Framework.Scenes
816 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 891 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
817 ControllingClient.OnStartAnim += HandleStartAnim; 892 ControllingClient.OnStartAnim += HandleStartAnim;
818 ControllingClient.OnStopAnim += HandleStopAnim; 893 ControllingClient.OnStopAnim += HandleStopAnim;
894 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
819 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 895 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
820 ControllingClient.OnAutoPilotGo += MoveToTarget; 896 ControllingClient.OnAutoPilotGo += MoveToTarget;
897 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
821 898
822 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 899 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
823 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 900 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -876,6 +953,38 @@ namespace OpenSim.Region.Framework.Scenes
876 "[SCENE]: Upgrading child to root agent for {0} in {1}", 953 "[SCENE]: Upgrading child to root agent for {0} in {1}",
877 Name, m_scene.RegionInfo.RegionName); 954 Name, m_scene.RegionInfo.RegionName);
878 955
956 if (ParentUUID != UUID.Zero)
957 {
958 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
959 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
960 if (part == null)
961 {
962 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
963 }
964 else
965 {
966 part.ParentGroup.AddAvatar(UUID);
967 if (part.SitTargetPosition != Vector3.Zero)
968 part.SitTargetAvatar = UUID;
969// ParentPosition = part.GetWorldPosition();
970 ParentID = part.LocalId;
971 ParentPart = part;
972 m_pos = m_prevSitOffset;
973// pos = ParentPosition;
974 pos = part.GetWorldPosition();
975 }
976 ParentUUID = UUID.Zero;
977
978 IsChildAgent = false;
979
980// Animator.TrySetMovementAnimation("SIT");
981 }
982 else
983 {
984 IsChildAgent = false;
985 IsLoggingIn = false;
986 }
987
879 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 988 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
880 989
881 IsChildAgent = false; 990 IsChildAgent = false;
@@ -888,70 +997,106 @@ namespace OpenSim.Region.Framework.Scenes
888 997
889 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 998 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
890 999
891 // Moved this from SendInitialData to ensure that Appearance is initialized 1000 UUID groupUUID = UUID.Zero;
892 // before the inventory is processed in MakeRootAgent. This fixes a race condition 1001 string GroupName = string.Empty;
893 // related to the handling of attachments 1002 ulong groupPowers = 0;
894 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
895 1003
896 if (m_scene.TestBorderCross(pos, Cardinals.E)) 1004 // ----------------------------------
1005 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1006 try
897 { 1007 {
898 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 1008 if (gm != null)
899 pos.X = crossedBorder.BorderLine.Z - 1; 1009 {
1010 groupUUID = ControllingClient.ActiveGroupId;
1011 GroupRecord record = gm.GetGroupRecord(groupUUID);
1012 if (record != null)
1013 GroupName = record.GroupName;
1014 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1015 if (groupMembershipData != null)
1016 groupPowers = groupMembershipData.GroupPowers;
1017 }
1018 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1019 Grouptitle);
900 } 1020 }
901 1021 catch (Exception e)
902 if (m_scene.TestBorderCross(pos, Cardinals.N))
903 { 1022 {
904 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1023 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
905 pos.Y = crossedBorder.BorderLine.Z - 1;
906 } 1024 }
1025 // ------------------------------------
907 1026
908 CheckAndAdjustLandingPoint(ref pos); 1027 if (ParentID == 0)
909
910 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
911 { 1028 {
912 m_log.WarnFormat( 1029 // Moved this from SendInitialData to ensure that Appearance is initialized
913 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1030 // before the inventory is processed in MakeRootAgent. This fixes a race condition
914 pos, Name, UUID); 1031 // related to the handling of attachments
1032 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1033 if (m_scene.TestBorderCross(pos, Cardinals.E))
1034 {
1035 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1036 pos.X = crossedBorder.BorderLine.Z - 1;
1037 }
915 1038
916 if (pos.X < 0f) pos.X = 0f; 1039 if (m_scene.TestBorderCross(pos, Cardinals.N))
917 if (pos.Y < 0f) pos.Y = 0f; 1040 {
918 if (pos.Z < 0f) pos.Z = 0f; 1041 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
919 } 1042 pos.Y = crossedBorder.BorderLine.Z - 1;
1043 }
920 1044
921 float localAVHeight = 1.56f; 1045 CheckAndAdjustLandingPoint(ref pos);
922 if (Appearance.AvatarHeight > 0)
923 localAVHeight = Appearance.AvatarHeight;
924 1046
925 float posZLimit = 0; 1047 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1048 {
1049 m_log.WarnFormat(
1050 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1051 pos, Name, UUID);
926 1052
927 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1053 if (pos.X < 0f) pos.X = 0f;
928 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1054 if (pos.Y < 0f) pos.Y = 0f;
929 1055 if (pos.Z < 0f) pos.Z = 0f;
930 float newPosZ = posZLimit + localAVHeight / 2; 1056 }
931 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
932 {
933 pos.Z = newPosZ;
934 }
935 AbsolutePosition = pos;
936 1057
937 AddToPhysicalScene(isFlying); 1058 float localAVHeight = 1.56f;
1059 if (Appearance.AvatarHeight > 0)
1060 localAVHeight = Appearance.AvatarHeight;
938 1061
939 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1062 float posZLimit = 0;
940 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
941 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
942 // the value to a negative position which does not trigger the border cross.
943 // This may not be the best location for this.
944 CheckForBorderCrossing();
945 1063
946 if (ForceFly) 1064 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
947 { 1065 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
948 Flying = true; 1066
949 } 1067 float newPosZ = posZLimit + localAVHeight / 2;
950 else if (FlyDisabled) 1068 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
951 { 1069 {
952 Flying = false; 1070 pos.Z = newPosZ;
953 } 1071 }
1072 AbsolutePosition = pos;
1073
1074 if (m_teleportFlags == TeleportFlags.Default)
1075 {
1076 Vector3 vel = Velocity;
1077 AddToPhysicalScene(isFlying);
1078 if (PhysicsActor != null)
1079 PhysicsActor.SetMomentum(vel);
1080 }
1081 else
1082 AddToPhysicalScene(isFlying);
954 1083
1084 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1085 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1086 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1087 // the value to a negative position which does not trigger the border cross.
1088 // This may not be the best location for this.
1089 CheckForBorderCrossing();
1090
1091 if (ForceFly)
1092 {
1093 Flying = true;
1094 }
1095 else if (FlyDisabled)
1096 {
1097 Flying = false;
1098 }
1099 }
955 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1100 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
956 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1101 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
957 // elsewhere anyway 1102 // elsewhere anyway
@@ -983,31 +1128,28 @@ namespace OpenSim.Region.Framework.Scenes
983 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1128 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
984 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1129 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
985 // not transporting the required data. 1130 // not transporting the required data.
986 // 1131 lock (m_attachments)
987 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
988 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
989 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
990 //
991 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
992 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
993 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
994 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
995 List<SceneObjectGroup> attachments = GetAttachments();
996
997 if (attachments.Count > 0)
998 { 1132 {
999 m_log.DebugFormat( 1133 if (HasAttachments())
1000 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1001
1002 // Resume scripts
1003 foreach (SceneObjectGroup sog in attachments)
1004 { 1134 {
1005 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1135 m_log.DebugFormat(
1006 sog.ResumeScripts(); 1136 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1137
1138 // Resume scripts
1139 Util.FireAndForget(delegate(object x) {
1140 foreach (SceneObjectGroup sog in m_attachments)
1141 {
1142 sog.ScheduleGroupForFullUpdate();
1143 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1144 sog.ResumeScripts();
1145 }
1146 });
1007 } 1147 }
1008 } 1148 }
1009 } 1149 }
1010 1150
1151 SendAvatarDataToAllAgents();
1152
1011 // send the animations of the other presences to me 1153 // send the animations of the other presences to me
1012 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1154 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1013 { 1155 {
@@ -1018,6 +1160,7 @@ namespace OpenSim.Region.Framework.Scenes
1018 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1160 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1019 // stall on the border crossing since the existing child agent will still have the last movement 1161 // stall on the border crossing since the existing child agent will still have the last movement
1020 // recorded, which stops the input from being processed. 1162 // recorded, which stops the input from being processed.
1163
1021 MovementFlag = 0; 1164 MovementFlag = 0;
1022 1165
1023 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1166 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -1049,12 +1192,16 @@ namespace OpenSim.Region.Framework.Scenes
1049 /// </remarks> 1192 /// </remarks>
1050 public void MakeChildAgent() 1193 public void MakeChildAgent()
1051 { 1194 {
1195 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1196
1052 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1197 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1053 1198
1054 // Reset these so that teleporting in and walking out isn't seen 1199 // Reset these so that teleporting in and walking out isn't seen
1055 // as teleporting back 1200 // as teleporting back
1056 TeleportFlags = TeleportFlags.Default; 1201 TeleportFlags = TeleportFlags.Default;
1057 1202
1203 MovementFlag = 0;
1204
1058 // It looks like Animator is set to null somewhere, and MakeChild 1205 // It looks like Animator is set to null somewhere, and MakeChild
1059 // is called after that. Probably in aborted teleports. 1206 // is called after that. Probably in aborted teleports.
1060 if (Animator == null) 1207 if (Animator == null)
@@ -1062,6 +1209,7 @@ namespace OpenSim.Region.Framework.Scenes
1062 else 1209 else
1063 Animator.ResetAnimations(); 1210 Animator.ResetAnimations();
1064 1211
1212
1065// m_log.DebugFormat( 1213// m_log.DebugFormat(
1066// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1214// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1067// Name, UUID, m_scene.RegionInfo.RegionName); 1215// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1073,6 +1221,7 @@ namespace OpenSim.Region.Framework.Scenes
1073 IsChildAgent = true; 1221 IsChildAgent = true;
1074 m_scene.SwapRootAgentCount(true); 1222 m_scene.SwapRootAgentCount(true);
1075 RemoveFromPhysicalScene(); 1223 RemoveFromPhysicalScene();
1224 ParentID = 0; // Child agents can't be sitting
1076 1225
1077 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1226 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1078 1227
@@ -1088,9 +1237,9 @@ namespace OpenSim.Region.Framework.Scenes
1088 { 1237 {
1089// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1238// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1090 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1239 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1091 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1092 PhysicsActor.UnSubscribeEvents();
1093 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1240 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1241 PhysicsActor.UnSubscribeEvents();
1242 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1094 PhysicsActor = null; 1243 PhysicsActor = null;
1095 } 1244 }
1096// else 1245// else
@@ -1107,7 +1256,7 @@ namespace OpenSim.Region.Framework.Scenes
1107 /// <param name="pos"></param> 1256 /// <param name="pos"></param>
1108 public void Teleport(Vector3 pos) 1257 public void Teleport(Vector3 pos)
1109 { 1258 {
1110 TeleportWithMomentum(pos, null); 1259 TeleportWithMomentum(pos, Vector3.Zero);
1111 } 1260 }
1112 1261
1113 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1262 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1131,6 +1280,41 @@ namespace OpenSim.Region.Framework.Scenes
1131 SendTerseUpdateToAllClients(); 1280 SendTerseUpdateToAllClients();
1132 } 1281 }
1133 1282
1283 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1284 {
1285 CheckLandingPoint(ref newpos);
1286 AbsolutePosition = newpos;
1287
1288 if (newvel.HasValue)
1289 {
1290 if ((Vector3)newvel == Vector3.Zero)
1291 {
1292 if (PhysicsActor != null)
1293 PhysicsActor.SetMomentum(Vector3.Zero);
1294 m_velocity = Vector3.Zero;
1295 }
1296 else
1297 {
1298 if (PhysicsActor != null)
1299 PhysicsActor.SetMomentum((Vector3)newvel);
1300 m_velocity = (Vector3)newvel;
1301
1302 if (rotateToVelXY)
1303 {
1304 Vector3 lookAt = (Vector3)newvel;
1305 lookAt.Z = 0;
1306 lookAt.Normalize();
1307 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1308 return;
1309 }
1310 }
1311 }
1312
1313 SendTerseUpdateToAllClients();
1314 }
1315
1316
1317
1134 public void StopFlying() 1318 public void StopFlying()
1135 { 1319 {
1136 Vector3 pos = AbsolutePosition; 1320 Vector3 pos = AbsolutePosition;
@@ -1319,6 +1503,13 @@ namespace OpenSim.Region.Framework.Scenes
1319 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1503 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1320 } 1504 }
1321 1505
1506 public void SetSize(Vector3 size, float feetoffset)
1507 {
1508 if (PhysicsActor != null && !IsChildAgent)
1509 PhysicsActor.setAvatarSize(size, feetoffset);
1510
1511 }
1512
1322 private bool WaitForUpdateAgent(IClientAPI client) 1513 private bool WaitForUpdateAgent(IClientAPI client)
1323 { 1514 {
1324 // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero 1515 // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero
@@ -1367,7 +1558,8 @@ namespace OpenSim.Region.Framework.Scenes
1367 1558
1368 Vector3 look = Velocity; 1559 Vector3 look = Velocity;
1369 1560
1370 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1561 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1562 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1371 { 1563 {
1372 look = new Vector3(0.99f, 0.042f, 0); 1564 look = new Vector3(0.99f, 0.042f, 0);
1373 } 1565 }
@@ -1425,11 +1617,12 @@ namespace OpenSim.Region.Framework.Scenes
1425 { 1617 {
1426 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1618 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1427 if (m_agentTransfer != null) 1619 if (m_agentTransfer != null)
1428 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1620 m_agentTransfer.EnableChildAgents(this);
1429 1621
1430 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1622 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1431 if (friendsModule != null) 1623 if (friendsModule != null)
1432 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1624 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1625
1433 } 1626 }
1434 1627
1435 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1628 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1455,36 +1648,69 @@ namespace OpenSim.Region.Framework.Scenes
1455 /// <param name="collisionPoint"></param> 1648 /// <param name="collisionPoint"></param>
1456 /// <param name="localid"></param> 1649 /// <param name="localid"></param>
1457 /// <param name="distance"></param> 1650 /// <param name="distance"></param>
1651 ///
1652
1653 private void UpdateCameraCollisionPlane(Vector4 plane)
1654 {
1655 if (m_lastCameraCollisionPlane != plane)
1656 {
1657 m_lastCameraCollisionPlane = plane;
1658 ControllingClient.SendCameraConstraint(plane);
1659 }
1660 }
1661
1458 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1662 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1459 { 1663 {
1460 const float POSITION_TOLERANCE = 0.02f; 1664 const float POSITION_TOLERANCE = 0.02f;
1461 const float VELOCITY_TOLERANCE = 0.02f;
1462 const float ROTATION_TOLERANCE = 0.02f; 1665 const float ROTATION_TOLERANCE = 0.02f;
1463 1666
1464 if (m_followCamAuto) 1667 m_doingCamRayCast = false;
1668 if (hitYN && localid != LocalId)
1465 { 1669 {
1466 if (hitYN) 1670 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1671 bool IsPrim = group != null;
1672 if (IsPrim)
1467 { 1673 {
1468 CameraConstraintActive = true; 1674 SceneObjectPart part = group.GetPart(localid);
1469 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1675 if (part != null && !part.VolumeDetectActive)
1470 1676 {
1471 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1677 CameraConstraintActive = true;
1472 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1678 pNormal.X = (float) Math.Round(pNormal.X, 2);
1679 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1680 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1681 pNormal.Normalize();
1682 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1683 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1684 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1685
1686 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1687 Vector3.Dot(collisionPoint, pNormal));
1688 UpdateCameraCollisionPlane(plane);
1689 }
1473 } 1690 }
1474 else 1691 else
1475 { 1692 {
1476 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1693 CameraConstraintActive = true;
1477 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1694 pNormal.X = (float) Math.Round(pNormal.X, 2);
1478 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1695 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1479 { 1696 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1480 if (CameraConstraintActive) 1697 pNormal.Normalize();
1481 { 1698 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1482 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1699 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1483 CameraConstraintActive = false; 1700 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1484 } 1701
1485 } 1702 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1703 Vector3.Dot(collisionPoint, pNormal));
1704 UpdateCameraCollisionPlane(plane);
1486 } 1705 }
1487 } 1706 }
1707 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1708 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1709 {
1710 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1711 UpdateCameraCollisionPlane(plane);
1712 CameraConstraintActive = false;
1713 }
1488 } 1714 }
1489 1715
1490 /// <summary> 1716 /// <summary>
@@ -1558,6 +1784,41 @@ namespace OpenSim.Region.Framework.Scenes
1558 StandUp(); 1784 StandUp();
1559 } 1785 }
1560 1786
1787 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1788 // this exclude checks may not be complete
1789
1790 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1791 {
1792 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1793 {
1794 Vector3 posAdjusted = AbsolutePosition;
1795// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1796 posAdjusted.Z += 1.0f; // viewer current camera focus point
1797 Vector3 tocam = CameraPosition - posAdjusted;
1798 tocam.X = (float)Math.Round(tocam.X, 1);
1799 tocam.Y = (float)Math.Round(tocam.Y, 1);
1800 tocam.Z = (float)Math.Round(tocam.Z, 1);
1801
1802 float distTocamlen = tocam.Length();
1803 if (distTocamlen > 0.3f)
1804 {
1805 tocam *= (1.0f / distTocamlen);
1806 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1807 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1808 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1809
1810 m_doingCamRayCast = true;
1811 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1812 }
1813 }
1814 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1815 {
1816 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1817 UpdateCameraCollisionPlane(plane);
1818 CameraConstraintActive = false;
1819 }
1820 }
1821
1561 uint flagsForScripts = (uint)flags; 1822 uint flagsForScripts = (uint)flags;
1562 flags = RemoveIgnoredControls(flags, IgnoredControls); 1823 flags = RemoveIgnoredControls(flags, IgnoredControls);
1563 1824
@@ -2088,7 +2349,8 @@ namespace OpenSim.Region.Framework.Scenes
2088// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2349// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2089 2350
2090 MovingToTarget = false; 2351 MovingToTarget = false;
2091 MoveToPositionTarget = Vector3.Zero; 2352// MoveToPositionTarget = Vector3.Zero;
2353 m_forceToApply = null; // cancel possible last action
2092 2354
2093 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2355 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
2094 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2356 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2106,12 +2368,17 @@ namespace OpenSim.Region.Framework.Scenes
2106// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2368// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
2107 2369
2108 SitGround = false; 2370 SitGround = false;
2371
2372/* move this down so avatar gets physical in the new position and not where it is siting
2109 if (PhysicsActor == null) 2373 if (PhysicsActor == null)
2110 AddToPhysicalScene(false); 2374 AddToPhysicalScene(false);
2375 */
2111 2376
2112 if (ParentID != 0) 2377 if (ParentID != 0)
2113 { 2378 {
2114 SceneObjectPart part = ParentPart; 2379 SceneObjectPart part = ParentPart;
2380 UnRegisterSeatControls(part.ParentGroup.UUID);
2381
2115 TaskInventoryDictionary taskIDict = part.TaskInventory; 2382 TaskInventoryDictionary taskIDict = part.TaskInventory;
2116 if (taskIDict != null) 2383 if (taskIDict != null)
2117 { 2384 {
@@ -2127,14 +2394,22 @@ namespace OpenSim.Region.Framework.Scenes
2127 } 2394 }
2128 } 2395 }
2129 2396
2130 ParentPosition = part.GetWorldPosition(); 2397 part.ParentGroup.DeleteAvatar(UUID);
2398// ParentPosition = part.GetWorldPosition();
2131 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2399 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2132 2400
2133 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 2401// m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2134 ParentPosition = Vector3.Zero; 2402// ParentPosition = Vector3.Zero;
2403 m_pos = part.AbsolutePosition + (m_pos * part.GetWorldRotation()) + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2404 if (part.SitTargetAvatar == UUID)
2405 m_bodyRot = part.GetWorldRotation() * part.SitTargetOrientation;
2135 2406
2136 ParentID = 0; 2407 ParentID = 0;
2137 ParentPart = null; 2408 ParentPart = null;
2409
2410 if (PhysicsActor == null)
2411 AddToPhysicalScene(false);
2412
2138 SendAvatarDataToAllAgents(); 2413 SendAvatarDataToAllAgents();
2139 m_requestedSitTargetID = 0; 2414 m_requestedSitTargetID = 0;
2140 2415
@@ -2144,6 +2419,9 @@ namespace OpenSim.Region.Framework.Scenes
2144 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2419 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2145 } 2420 }
2146 2421
2422 else if (PhysicsActor == null)
2423 AddToPhysicalScene(false);
2424
2147 Animator.TrySetMovementAnimation("STAND"); 2425 Animator.TrySetMovementAnimation("STAND");
2148 TriggerScenePresenceUpdated(); 2426 TriggerScenePresenceUpdated();
2149 } 2427 }
@@ -2192,11 +2470,8 @@ namespace OpenSim.Region.Framework.Scenes
2192 if (part == null) 2470 if (part == null)
2193 return; 2471 return;
2194 2472
2195 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2196 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2197
2198 if (PhysicsActor != null) 2473 if (PhysicsActor != null)
2199 m_sitAvatarHeight = PhysicsActor.Size.Z; 2474 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2200 2475
2201 bool canSit = false; 2476 bool canSit = false;
2202 Vector3 pos = part.AbsolutePosition + offset; 2477 Vector3 pos = part.AbsolutePosition + offset;
@@ -2213,31 +2488,31 @@ namespace OpenSim.Region.Framework.Scenes
2213 } 2488 }
2214 else 2489 else
2215 { 2490 {
2491 if (PhysicsSit(part,offset)) // physics engine
2492 return;
2493
2216 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2494 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2217 { 2495 {
2218// m_log.DebugFormat(
2219// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2220// Name, part.Name, part.LocalId);
2221 2496
2222 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2497 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2223 canSit = true; 2498 canSit = true;
2224 } 2499 }
2225// else
2226// {
2227// m_log.DebugFormat(
2228// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2229// Name, part.Name, part.LocalId);
2230// }
2231 } 2500 }
2232 2501
2233 if (canSit) 2502 if (canSit)
2234 { 2503 {
2504
2235 if (PhysicsActor != null) 2505 if (PhysicsActor != null)
2236 { 2506 {
2237 // We can remove the physicsActor until they stand up. 2507 // We can remove the physicsActor until they stand up.
2238 RemoveFromPhysicalScene(); 2508 RemoveFromPhysicalScene();
2239 } 2509 }
2240 2510
2511 if (MovingToTarget)
2512 ResetMoveToTarget();
2513
2514 Velocity = Vector3.Zero;
2515
2241 part.AddSittingAvatar(UUID); 2516 part.AddSittingAvatar(UUID);
2242 2517
2243 cameraAtOffset = part.GetCameraAtOffset(); 2518 cameraAtOffset = part.GetCameraAtOffset();
@@ -2259,6 +2534,9 @@ namespace OpenSim.Region.Framework.Scenes
2259 2534
2260 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2535 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2261 { 2536 {
2537 if (IsChildAgent)
2538 return;
2539
2262 if (ParentID != 0) 2540 if (ParentID != 0)
2263 { 2541 {
2264 if (ParentPart.UUID == targetID) 2542 if (ParentPart.UUID == targetID)
@@ -2274,14 +2552,6 @@ namespace OpenSim.Region.Framework.Scenes
2274 m_requestedSitTargetID = part.LocalId; 2552 m_requestedSitTargetID = part.LocalId;
2275 m_requestedSitTargetUUID = part.UUID; 2553 m_requestedSitTargetUUID = part.UUID;
2276 2554
2277// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2278
2279 if (m_scene.PhysicsScene.SupportsRayCast())
2280 {
2281 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2282 //SitRayCastAvatarPosition(part);
2283 //return;
2284 }
2285 } 2555 }
2286 else 2556 else
2287 { 2557 {
@@ -2291,197 +2561,111 @@ namespace OpenSim.Region.Framework.Scenes
2291 SendSitResponse(targetID, offset, Quaternion.Identity); 2561 SendSitResponse(targetID, offset, Quaternion.Identity);
2292 } 2562 }
2293 2563
2294 /* 2564 // returns false if does not suport so older sit can be tried
2295 public void SitRayCastAvatarPosition(SceneObjectPart part) 2565 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2296 { 2566 {
2297 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2567 if (part == null || part.ParentGroup.IsAttachment)
2298 Vector3 StartRayCastPosition = AbsolutePosition;
2299 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2300 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2301 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2302 }
2303
2304 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2305 {
2306 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2307 if (part != null)
2308 { 2568 {
2309 if (hitYN) 2569 return true;
2310 {
2311 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2312 {
2313 SitRaycastFindEdge(collisionPoint, normal);
2314 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2315 }
2316 else
2317 {
2318 SitRayCastAvatarPositionCameraZ(part);
2319 }
2320 }
2321 else
2322 {
2323 SitRayCastAvatarPositionCameraZ(part);
2324 }
2325 }
2326 else
2327 {
2328 ControllingClient.SendAlertMessage("Sit position no longer exists");
2329 m_requestedSitTargetUUID = UUID.Zero;
2330 m_requestedSitTargetID = 0;
2331 m_requestedSitOffset = Vector3.Zero;
2332 } 2570 }
2333 2571
2334 } 2572 if ( m_scene.PhysicsScene == null)
2335 2573 return false;
2336 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2337 {
2338 // Next, try to raycast from the camera Z position
2339 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2340 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2341 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2342 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2343 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2344 }
2345 2574
2346 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2575 if (part.PhysActor == null)
2347 {
2348 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2349 if (part != null)
2350 { 2576 {
2351 if (hitYN) 2577 // none physcis shape
2352 { 2578 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2353 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2579 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2354 {
2355 SitRaycastFindEdge(collisionPoint, normal);
2356 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2357 }
2358 else
2359 {
2360 SitRayCastCameraPosition(part);
2361 }
2362 }
2363 else 2580 else
2364 { 2581 { // non physical phantom TODO
2365 SitRayCastCameraPosition(part); 2582 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2583 return false;
2366 } 2584 }
2367 } 2585 return true;
2368 else
2369 {
2370 ControllingClient.SendAlertMessage("Sit position no longer exists");
2371 m_requestedSitTargetUUID = UUID.Zero;
2372 m_requestedSitTargetID = 0;
2373 m_requestedSitOffset = Vector3.Zero;
2374 } 2586 }
2375 2587
2376 }
2377 2588
2378 public void SitRayCastCameraPosition(SceneObjectPart part) 2589 // not doing autopilot
2379 { 2590 m_requestedSitTargetID = 0;
2380 // Next, try to raycast from the camera position
2381 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2382 Vector3 StartRayCastPosition = CameraPosition;
2383 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2384 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2385 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2386 }
2387 2591
2388 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2592 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2389 { 2593 return true;
2390 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2391 if (part != null)
2392 {
2393 if (hitYN)
2394 {
2395 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2396 {
2397 SitRaycastFindEdge(collisionPoint, normal);
2398 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2399 }
2400 else
2401 {
2402 SitRayHorizontal(part);
2403 }
2404 }
2405 else
2406 {
2407 SitRayHorizontal(part);
2408 }
2409 }
2410 else
2411 {
2412 ControllingClient.SendAlertMessage("Sit position no longer exists");
2413 m_requestedSitTargetUUID = UUID.Zero;
2414 m_requestedSitTargetID = 0;
2415 m_requestedSitOffset = Vector3.Zero;
2416 }
2417 2594
2595 return false;
2418 } 2596 }
2419 2597
2420 public void SitRayHorizontal(SceneObjectPart part) 2598
2599 private bool CanEnterLandPosition(Vector3 testPos)
2421 { 2600 {
2422 // Next, try to raycast from the avatar position to fwd 2601 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2423 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2602
2424 Vector3 StartRayCastPosition = CameraPosition; 2603 if (land == null || land.LandData.Name == "NO_LAND")
2425 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2604 return true;
2426 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2605
2427 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2606 return land.CanBeOnThisLand(UUID,testPos.Z);
2428 } 2607 }
2429 2608
2430 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2609 // status
2610 // < 0 ignore
2611 // 0 bad sit spot
2612 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2431 { 2613 {
2432 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2614 if (status < 0)
2433 if (part != null) 2615 return;
2616
2617 if (status == 0)
2434 { 2618 {
2435 if (hitYN) 2619 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2436 { 2620 return;
2437 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2438 {
2439 SitRaycastFindEdge(collisionPoint, normal);
2440 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2441 // Next, try to raycast from the camera position
2442 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2443 Vector3 StartRayCastPosition = CameraPosition;
2444 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2445 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2446 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2447 }
2448 else
2449 {
2450 ControllingClient.SendAlertMessage("Sit position not accessable.");
2451 m_requestedSitTargetUUID = UUID.Zero;
2452 m_requestedSitTargetID = 0;
2453 m_requestedSitOffset = Vector3.Zero;
2454 }
2455 }
2456 else
2457 {
2458 ControllingClient.SendAlertMessage("Sit position not accessable.");
2459 m_requestedSitTargetUUID = UUID.Zero;
2460 m_requestedSitTargetID = 0;
2461 m_requestedSitOffset = Vector3.Zero;
2462 }
2463 } 2621 }
2464 else 2622
2623 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2624 if (part == null)
2625 return;
2626
2627 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2628 if(!CanEnterLandPosition(targetPos))
2465 { 2629 {
2466 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2630 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2467 m_requestedSitTargetUUID = UUID.Zero; 2631 return;
2468 m_requestedSitTargetID = 0;
2469 m_requestedSitOffset = Vector3.Zero;
2470 } 2632 }
2471 2633
2472 } 2634 RemoveFromPhysicalScene();
2473 2635
2474 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2636 if (MovingToTarget)
2475 { 2637 ResetMoveToTarget();
2476 int i = 0;
2477 //throw new NotImplementedException();
2478 //m_requestedSitTargetUUID = UUID.Zero;
2479 //m_requestedSitTargetID = 0;
2480 //m_requestedSitOffset = Vector3.Zero;
2481 2638
2482 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2639 Velocity = Vector3.Zero;
2640
2641 part.AddSittingAvatar(UUID);
2642
2643 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2644 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2645 bool forceMouselook = part.GetForceMouselook();
2646
2647 ControllingClient.SendSitResponse(
2648 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2649
2650 // not using autopilot
2651
2652 Rotation = Orientation;
2653 m_pos = offset;
2654
2655 m_requestedSitTargetID = 0;
2656 part.ParentGroup.AddAvatar(UUID);
2657
2658 ParentPart = part;
2659 ParentID = part.LocalId;
2660 if(status == 3)
2661 Animator.TrySetMovementAnimation("SIT_GROUND");
2662 else
2663 Animator.TrySetMovementAnimation("SIT");
2664 SendAvatarDataToAllAgents();
2665
2666 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2483 } 2667 }
2484 */ 2668
2485 2669
2486 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2670 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2487 { 2671 {
@@ -2498,6 +2682,7 @@ namespace OpenSim.Region.Framework.Scenes
2498 return; 2682 return;
2499 } 2683 }
2500 2684
2685
2501 if (part.SitTargetAvatar == UUID) 2686 if (part.SitTargetAvatar == UUID)
2502 { 2687 {
2503 Vector3 sitTargetPos = part.SitTargetPosition; 2688 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2512,14 +2697,39 @@ namespace OpenSim.Region.Framework.Scenes
2512 2697
2513 //Quaternion result = (sitTargetOrient * vq) * nq; 2698 //Quaternion result = (sitTargetOrient * vq) * nq;
2514 2699
2515 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2700 double x, y, z, m;
2701
2702 Quaternion r = sitTargetOrient;
2703 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2704
2705 if (Math.Abs(1.0 - m) > 0.000001)
2706 {
2707 m = 1.0 / Math.Sqrt(m);
2708 r.X *= (float)m;
2709 r.Y *= (float)m;
2710 r.Z *= (float)m;
2711 r.W *= (float)m;
2712 }
2713
2714 x = 2 * (r.X * r.Z + r.Y * r.W);
2715 y = 2 * (-r.X * r.W + r.Y * r.Z);
2716 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2717
2718 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2719 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2720
2721 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2722
2723// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2516 Rotation = sitTargetOrient; 2724 Rotation = sitTargetOrient;
2517 ParentPosition = part.AbsolutePosition; 2725// ParentPosition = part.AbsolutePosition;
2726 part.ParentGroup.AddAvatar(UUID);
2518 } 2727 }
2519 else 2728 else
2520 { 2729 {
2521 m_pos -= part.AbsolutePosition; 2730 m_pos -= part.AbsolutePosition;
2522 ParentPosition = part.AbsolutePosition; 2731// ParentPosition = part.AbsolutePosition;
2732 part.ParentGroup.AddAvatar(UUID);
2523 2733
2524// m_log.DebugFormat( 2734// m_log.DebugFormat(
2525// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2735// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2574,6 +2784,13 @@ namespace OpenSim.Region.Framework.Scenes
2574 TriggerScenePresenceUpdated(); 2784 TriggerScenePresenceUpdated();
2575 } 2785 }
2576 2786
2787 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
2788 {
2789 Animator.avnChangeAnim(animID, addRemove, sendPack);
2790 }
2791
2792
2793
2577 /// <summary> 2794 /// <summary>
2578 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2795 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2579 /// </summary> 2796 /// </summary>
@@ -2630,8 +2847,8 @@ namespace OpenSim.Region.Framework.Scenes
2630 direc.Z *= 2.6f; 2847 direc.Z *= 2.6f;
2631 2848
2632 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2849 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2633 Animator.TrySetMovementAnimation("PREJUMP"); 2850// Animator.TrySetMovementAnimation("PREJUMP");
2634 Animator.TrySetMovementAnimation("JUMP"); 2851// Animator.TrySetMovementAnimation("JUMP");
2635 } 2852 }
2636 } 2853 }
2637 } 2854 }
@@ -2640,6 +2857,7 @@ namespace OpenSim.Region.Framework.Scenes
2640 2857
2641 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2858 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2642 m_forceToApply = direc; 2859 m_forceToApply = direc;
2860 Animator.UpdateMovementAnimations();
2643 } 2861 }
2644 2862
2645 #endregion 2863 #endregion
@@ -2657,16 +2875,12 @@ namespace OpenSim.Region.Framework.Scenes
2657 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 2875 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2658 // grab the latest PhysicsActor velocity, whereas m_velocity is often 2876 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2659 // storing a requested force instead of an actual traveling velocity 2877 // storing a requested force instead of an actual traveling velocity
2878 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
2879 SendAvatarDataToAllAgents();
2660 2880
2661 // Throw away duplicate or insignificant updates 2881 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2662 if ( 2882 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2663 // If the velocity has become zero, send it no matter what. 2883 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2664 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2665 // otherwise, if things have changed reasonably, send the update
2666 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2667 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2668 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2669
2670 { 2884 {
2671 SendTerseUpdateToAllClients(); 2885 SendTerseUpdateToAllClients();
2672 2886
@@ -2825,9 +3039,7 @@ namespace OpenSim.Region.Framework.Scenes
2825 // again here... this comes after the cached appearance check because the avatars 3039 // again here... this comes after the cached appearance check because the avatars
2826 // appearance goes into the avatar update packet 3040 // appearance goes into the avatar update packet
2827 SendAvatarDataToAllAgents(); 3041 SendAvatarDataToAllAgents();
2828 3042 SendAppearanceToAgent(this);
2829 // This invocation always shows up in the viewer logs as an error.
2830 // SendAppearanceToAgent(this);
2831 3043
2832 // If we are using the the cached appearance then send it out to everyone 3044 // If we are using the the cached appearance then send it out to everyone
2833 if (cachedappearance) 3045 if (cachedappearance)
@@ -2858,6 +3070,8 @@ namespace OpenSim.Region.Framework.Scenes
2858 return; 3070 return;
2859 } 3071 }
2860 3072
3073 m_lastSize = Appearance.AvatarSize;
3074
2861 int count = 0; 3075 int count = 0;
2862 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 3076 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2863 { 3077 {
@@ -2965,6 +3179,8 @@ namespace OpenSim.Region.Framework.Scenes
2965 3179
2966 avatar.ControllingClient.SendAppearance( 3180 avatar.ControllingClient.SendAppearance(
2967 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3181 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3182
3183
2968 } 3184 }
2969 3185
2970 #endregion 3186 #endregion
@@ -3039,8 +3255,9 @@ namespace OpenSim.Region.Framework.Scenes
3039 3255
3040 // If we don't have a PhysActor, we can't cross anyway 3256 // If we don't have a PhysActor, we can't cross anyway
3041 // Also don't do this while sat, sitting avatars cross with the 3257 // Also don't do this while sat, sitting avatars cross with the
3042 // object they sit on. 3258 // object they sit on. ParentUUID denoted a pending sit, don't
3043 if (ParentID != 0 || PhysicsActor == null) 3259 // interfere with it.
3260 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3044 return; 3261 return;
3045 3262
3046 if (!IsInTransit) 3263 if (!IsInTransit)
@@ -3307,6 +3524,10 @@ namespace OpenSim.Region.Framework.Scenes
3307 } 3524 }
3308 3525
3309 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3526 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3527 private void RaiseUpdateThrottles()
3528 {
3529 m_scene.EventManager.TriggerThrottleUpdate(this);
3530 }
3310 /// <summary> 3531 /// <summary>
3311 /// This updates important decision making data about a child agent 3532 /// This updates important decision making data about a child agent
3312 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3533 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3388,6 +3609,9 @@ namespace OpenSim.Region.Framework.Scenes
3388 cAgent.AlwaysRun = SetAlwaysRun; 3609 cAgent.AlwaysRun = SetAlwaysRun;
3389 3610
3390 cAgent.Appearance = new AvatarAppearance(Appearance); 3611 cAgent.Appearance = new AvatarAppearance(Appearance);
3612
3613 cAgent.ParentPart = ParentUUID;
3614 cAgent.SitOffset = m_pos;
3391 3615
3392 lock (scriptedcontrols) 3616 lock (scriptedcontrols)
3393 { 3617 {
@@ -3396,7 +3620,7 @@ namespace OpenSim.Region.Framework.Scenes
3396 3620
3397 foreach (ScriptControllers c in scriptedcontrols.Values) 3621 foreach (ScriptControllers c in scriptedcontrols.Values)
3398 { 3622 {
3399 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3623 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3400 } 3624 }
3401 cAgent.Controllers = controls; 3625 cAgent.Controllers = controls;
3402 } 3626 }
@@ -3429,6 +3653,8 @@ namespace OpenSim.Region.Framework.Scenes
3429 CameraAtAxis = cAgent.AtAxis; 3653 CameraAtAxis = cAgent.AtAxis;
3430 CameraLeftAxis = cAgent.LeftAxis; 3654 CameraLeftAxis = cAgent.LeftAxis;
3431 CameraUpAxis = cAgent.UpAxis; 3655 CameraUpAxis = cAgent.UpAxis;
3656 ParentUUID = cAgent.ParentPart;
3657 m_prevSitOffset = cAgent.SitOffset;
3432 3658
3433 // When we get to the point of re-computing neighbors everytime this 3659 // When we get to the point of re-computing neighbors everytime this
3434 // changes, then start using the agent's drawdistance rather than the 3660 // changes, then start using the agent's drawdistance rather than the
@@ -3466,6 +3692,7 @@ namespace OpenSim.Region.Framework.Scenes
3466 foreach (ControllerData c in cAgent.Controllers) 3692 foreach (ControllerData c in cAgent.Controllers)
3467 { 3693 {
3468 ScriptControllers sc = new ScriptControllers(); 3694 ScriptControllers sc = new ScriptControllers();
3695 sc.objectID = c.ObjectID;
3469 sc.itemID = c.ItemID; 3696 sc.itemID = c.ItemID;
3470 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3697 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3471 sc.eventControls = (ScriptControlled)c.EventControls; 3698 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3533,20 +3760,27 @@ namespace OpenSim.Region.Framework.Scenes
3533 } 3760 }
3534 3761
3535 if (Appearance.AvatarHeight == 0) 3762 if (Appearance.AvatarHeight == 0)
3536 Appearance.SetHeight(); 3763// Appearance.SetHeight();
3764 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3537 3765
3538 PhysicsScene scene = m_scene.PhysicsScene; 3766 PhysicsScene scene = m_scene.PhysicsScene;
3539 3767
3540 Vector3 pVec = AbsolutePosition; 3768 Vector3 pVec = AbsolutePosition;
3541 3769
3770/*
3542 PhysicsActor = scene.AddAvatar( 3771 PhysicsActor = scene.AddAvatar(
3543 LocalId, Firstname + "." + Lastname, pVec, 3772 LocalId, Firstname + "." + Lastname, pVec,
3544 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3773 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3774*/
3775
3776 PhysicsActor = scene.AddAvatar(
3777 LocalId, Firstname + "." + Lastname, pVec,
3778 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
3545 3779
3546 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3780 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3547 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3781 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3548 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3782 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3549 PhysicsActor.SubscribeEvents(500); 3783 PhysicsActor.SubscribeEvents(100);
3550 PhysicsActor.LocalID = LocalId; 3784 PhysicsActor.LocalID = LocalId;
3551 } 3785 }
3552 3786
@@ -3560,6 +3794,7 @@ namespace OpenSim.Region.Framework.Scenes
3560 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3794 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3561 } 3795 }
3562 3796
3797
3563 /// <summary> 3798 /// <summary>
3564 /// Event called by the physics plugin to tell the avatar about a collision. 3799 /// Event called by the physics plugin to tell the avatar about a collision.
3565 /// </summary> 3800 /// </summary>
@@ -3573,7 +3808,7 @@ namespace OpenSim.Region.Framework.Scenes
3573 /// <param name="e"></param> 3808 /// <param name="e"></param>
3574 public void PhysicsCollisionUpdate(EventArgs e) 3809 public void PhysicsCollisionUpdate(EventArgs e)
3575 { 3810 {
3576 if (IsChildAgent) 3811 if (IsChildAgent || Animator == null)
3577 return; 3812 return;
3578 3813
3579 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3814 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3590,7 +3825,6 @@ namespace OpenSim.Region.Framework.Scenes
3590 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3825 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3591 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3826 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3592 3827
3593 CollisionPlane = Vector4.UnitW;
3594 3828
3595// // No collisions at all means we may be flying. Update always 3829// // No collisions at all means we may be flying. Update always
3596// // to make falling work 3830// // to make falling work
@@ -3602,6 +3836,7 @@ namespace OpenSim.Region.Framework.Scenes
3602 3836
3603 if (coldata.Count != 0) 3837 if (coldata.Count != 0)
3604 { 3838 {
3839/*
3605 switch (Animator.CurrentMovementAnimation) 3840 switch (Animator.CurrentMovementAnimation)
3606 { 3841 {
3607 case "STAND": 3842 case "STAND":
@@ -3610,24 +3845,38 @@ namespace OpenSim.Region.Framework.Scenes
3610 case "CROUCH": 3845 case "CROUCH":
3611 case "CROUCHWALK": 3846 case "CROUCHWALK":
3612 { 3847 {
3848 */
3613 ContactPoint lowest; 3849 ContactPoint lowest;
3614 lowest.SurfaceNormal = Vector3.Zero; 3850 lowest.SurfaceNormal = Vector3.Zero;
3615 lowest.Position = Vector3.Zero; 3851 lowest.Position = Vector3.Zero;
3616 lowest.Position.Z = Single.NaN; 3852 lowest.Position.Z = float.MaxValue;
3617 3853
3618 foreach (ContactPoint contact in coldata.Values) 3854 foreach (ContactPoint contact in coldata.Values)
3619 { 3855 {
3620 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 3856
3857 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3621 { 3858 {
3622 lowest = contact; 3859 lowest = contact;
3623 } 3860 }
3624 } 3861 }
3625 3862
3626 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 3863 if (lowest.Position.Z != float.MaxValue)
3864 {
3865 lowest.SurfaceNormal = -lowest.SurfaceNormal;
3866 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3867 }
3868 else
3869 CollisionPlane = Vector4.UnitW;
3870/*
3627 } 3871 }
3628 break; 3872 break;
3629 } 3873 }
3874*/
3630 } 3875 }
3876 else
3877 CollisionPlane = Vector4.UnitW;
3878
3879 RaiseCollisionScriptEvents(coldata);
3631 3880
3632 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3881 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3633 if (Invulnerable || GodLevel > 0) 3882 if (Invulnerable || GodLevel > 0)
@@ -3726,6 +3975,13 @@ namespace OpenSim.Region.Framework.Scenes
3726 // m_reprioritizationTimer.Dispose(); 3975 // m_reprioritizationTimer.Dispose();
3727 3976
3728 RemoveFromPhysicalScene(); 3977 RemoveFromPhysicalScene();
3978
3979 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
3980
3981// if (Animator != null)
3982// Animator.Close();
3983 Animator = null;
3984
3729 } 3985 }
3730 3986
3731 public void AddAttachment(SceneObjectGroup gobj) 3987 public void AddAttachment(SceneObjectGroup gobj)
@@ -3959,10 +4215,18 @@ namespace OpenSim.Region.Framework.Scenes
3959 4215
3960 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4216 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
3961 { 4217 {
4218 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4219 if (p == null)
4220 return;
4221
4222 ControllingClient.SendTakeControls(controls, false, false);
4223 ControllingClient.SendTakeControls(controls, true, false);
4224
3962 ScriptControllers obj = new ScriptControllers(); 4225 ScriptControllers obj = new ScriptControllers();
3963 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4226 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
3964 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4227 obj.eventControls = ScriptControlled.CONTROL_ZERO;
3965 4228
4229 obj.objectID = p.ParentGroup.UUID;
3966 obj.itemID = Script_item_UUID; 4230 obj.itemID = Script_item_UUID;
3967 if (pass_on == 0 && accept == 0) 4231 if (pass_on == 0 && accept == 0)
3968 { 4232 {
@@ -4011,6 +4275,21 @@ namespace OpenSim.Region.Framework.Scenes
4011 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4275 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4012 } 4276 }
4013 4277
4278 private void UnRegisterSeatControls(UUID obj)
4279 {
4280 List<UUID> takers = new List<UUID>();
4281
4282 foreach (ScriptControllers c in scriptedcontrols.Values)
4283 {
4284 if (c.objectID == obj)
4285 takers.Add(c.itemID);
4286 }
4287 foreach (UUID t in takers)
4288 {
4289 UnRegisterControlEventsToScript(0, t);
4290 }
4291 }
4292
4014 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4293 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4015 { 4294 {
4016 ScriptControllers takecontrols; 4295 ScriptControllers takecontrols;
@@ -4340,6 +4619,12 @@ namespace OpenSim.Region.Framework.Scenes
4340 4619
4341 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4620 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4342 { 4621 {
4622 string reason;
4623
4624 // Honor bans
4625 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4626 return;
4627
4343 SceneObjectGroup telehub = null; 4628 SceneObjectGroup telehub = null;
4344 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4629 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4345 { 4630 {
@@ -4379,11 +4664,206 @@ namespace OpenSim.Region.Framework.Scenes
4379 pos = land.LandData.UserLocation; 4664 pos = land.LandData.UserLocation;
4380 } 4665 }
4381 } 4666 }
4382 4667
4383 land.SendLandUpdateToClient(ControllingClient); 4668 land.SendLandUpdateToClient(ControllingClient);
4384 } 4669 }
4385 } 4670 }
4386 4671
4672 private DetectedObject CreateDetObject(SceneObjectPart obj)
4673 {
4674 DetectedObject detobj = new DetectedObject();
4675 detobj.keyUUID = obj.UUID;
4676 detobj.nameStr = obj.Name;
4677 detobj.ownerUUID = obj.OwnerID;
4678 detobj.posVector = obj.AbsolutePosition;
4679 detobj.rotQuat = obj.GetWorldRotation();
4680 detobj.velVector = obj.Velocity;
4681 detobj.colliderType = 0;
4682 detobj.groupUUID = obj.GroupID;
4683
4684 return detobj;
4685 }
4686
4687 private DetectedObject CreateDetObject(ScenePresence av)
4688 {
4689 DetectedObject detobj = new DetectedObject();
4690 detobj.keyUUID = av.UUID;
4691 detobj.nameStr = av.ControllingClient.Name;
4692 detobj.ownerUUID = av.UUID;
4693 detobj.posVector = av.AbsolutePosition;
4694 detobj.rotQuat = av.Rotation;
4695 detobj.velVector = av.Velocity;
4696 detobj.colliderType = 0;
4697 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4698
4699 return detobj;
4700 }
4701
4702 private DetectedObject CreateDetObjectForGround()
4703 {
4704 DetectedObject detobj = new DetectedObject();
4705 detobj.keyUUID = UUID.Zero;
4706 detobj.nameStr = "";
4707 detobj.ownerUUID = UUID.Zero;
4708 detobj.posVector = AbsolutePosition;
4709 detobj.rotQuat = Quaternion.Identity;
4710 detobj.velVector = Vector3.Zero;
4711 detobj.colliderType = 0;
4712 detobj.groupUUID = UUID.Zero;
4713
4714 return detobj;
4715 }
4716
4717 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4718 {
4719 ColliderArgs colliderArgs = new ColliderArgs();
4720 List<DetectedObject> colliding = new List<DetectedObject>();
4721 foreach (uint localId in colliders)
4722 {
4723 if (localId == 0)
4724 continue;
4725
4726 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4727 if (obj != null)
4728 {
4729 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4730 colliding.Add(CreateDetObject(obj));
4731 }
4732 else
4733 {
4734 ScenePresence av = m_scene.GetScenePresence(localId);
4735 if (av != null && (!av.IsChildAgent))
4736 {
4737 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4738 colliding.Add(CreateDetObject(av));
4739 }
4740 }
4741 }
4742
4743 colliderArgs.Colliders = colliding;
4744
4745 return colliderArgs;
4746 }
4747
4748 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4749
4750 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4751 {
4752 ColliderArgs CollidingMessage;
4753
4754 if (colliders.Count > 0)
4755 {
4756 if ((dest.RootPart.ScriptEvents & ev) != 0)
4757 {
4758 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4759
4760 if (CollidingMessage.Colliders.Count > 0)
4761 notify(dest.RootPart.LocalId, CollidingMessage);
4762 }
4763 }
4764 }
4765
4766 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4767 {
4768 if ((dest.RootPart.ScriptEvents & ev) != 0)
4769 {
4770 ColliderArgs LandCollidingMessage = new ColliderArgs();
4771 List<DetectedObject> colliding = new List<DetectedObject>();
4772
4773 colliding.Add(CreateDetObjectForGround());
4774 LandCollidingMessage.Colliders = colliding;
4775
4776 notify(dest.RootPart.LocalId, LandCollidingMessage);
4777 }
4778 }
4779
4780 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
4781 {
4782 try
4783 {
4784 List<uint> thisHitColliders = new List<uint>();
4785 List<uint> endedColliders = new List<uint>();
4786 List<uint> startedColliders = new List<uint>();
4787 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
4788 CollisionForSoundInfo soundinfo;
4789 ContactPoint curcontact;
4790
4791 if (coldata.Count == 0)
4792 {
4793 if (m_lastColliders.Count == 0)
4794 return; // nothing to do
4795
4796 foreach (uint localID in m_lastColliders)
4797 {
4798 endedColliders.Add(localID);
4799 }
4800 m_lastColliders.Clear();
4801 }
4802
4803 else
4804 {
4805 foreach (uint id in coldata.Keys)
4806 {
4807 thisHitColliders.Add(id);
4808 if (!m_lastColliders.Contains(id))
4809 {
4810 startedColliders.Add(id);
4811 curcontact = coldata[id];
4812 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
4813 {
4814 soundinfo = new CollisionForSoundInfo();
4815 soundinfo.colliderID = id;
4816 soundinfo.position = curcontact.Position;
4817 soundinfo.relativeVel = curcontact.RelativeSpeed;
4818 soundinfolist.Add(soundinfo);
4819 }
4820 }
4821 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
4822 }
4823
4824 // calculate things that ended colliding
4825 foreach (uint localID in m_lastColliders)
4826 {
4827 if (!thisHitColliders.Contains(localID))
4828 {
4829 endedColliders.Add(localID);
4830 }
4831 }
4832 //add the items that started colliding this time to the last colliders list.
4833 foreach (uint localID in startedColliders)
4834 {
4835 m_lastColliders.Add(localID);
4836 }
4837 // remove things that ended colliding from the last colliders list
4838 foreach (uint localID in endedColliders)
4839 {
4840 m_lastColliders.Remove(localID);
4841 }
4842
4843 if (soundinfolist.Count > 0)
4844 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
4845 }
4846
4847 foreach (SceneObjectGroup att in GetAttachments())
4848 {
4849 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
4850 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
4851 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
4852
4853 if (startedColliders.Contains(0))
4854 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
4855 if (m_lastColliders.Contains(0))
4856 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
4857 if (endedColliders.Contains(0))
4858 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
4859 }
4860 }
4861 finally
4862 {
4863 m_collisionEventFlag = false;
4864 }
4865 }
4866
4387 private void TeleportFlagsDebug() { 4867 private void TeleportFlagsDebug() {
4388 4868
4389 // Some temporary debugging help to show all the TeleportFlags we have... 4869 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4408,6 +4888,5 @@ namespace OpenSim.Region.Framework.Scenes
4408 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4888 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4409 4889
4410 } 4890 }
4411
4412 } 4891 }
4413} 4892}