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.cs1122
1 files changed, 792 insertions, 330 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index bab14dd..1859cb1 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -63,6 +63,7 @@ namespace OpenSim.Region.Framework.Scenes
63 63
64 struct ScriptControllers 64 struct ScriptControllers
65 { 65 {
66 public UUID objectID;
66 public UUID itemID; 67 public UUID itemID;
67 public ScriptControlled ignoreControls; 68 public ScriptControlled ignoreControls;
68 public ScriptControlled eventControls; 69 public ScriptControlled eventControls;
@@ -99,7 +100,7 @@ namespace OpenSim.Region.Framework.Scenes
99 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 100 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
100 /// issue #1716 101 /// issue #1716
101 /// </summary> 102 /// </summary>
102 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 103 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
103 104
104 /// <summary> 105 /// <summary>
105 /// Movement updates for agents in neighboring regions are sent directly to clients. 106 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -121,8 +122,6 @@ namespace OpenSim.Region.Framework.Scenes
121 /// <remarks> 122 /// <remarks>
122 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 123 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
123 /// necessary. 124 /// necessary.
124 /// NOTE: To avoid deadlocks, do not lock m_attachments and then perform other tasks under that lock. Take a copy
125 /// of the list and act on that instead.
126 /// </remarks> 125 /// </remarks>
127 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 126 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
128 127
@@ -141,6 +140,8 @@ namespace OpenSim.Region.Framework.Scenes
141 private Vector3 m_lastPosition; 140 private Vector3 m_lastPosition;
142 private Quaternion m_lastRotation; 141 private Quaternion m_lastRotation;
143 private Vector3 m_lastVelocity; 142 private Vector3 m_lastVelocity;
143 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
144
144 145
145 private Vector3? m_forceToApply; 146 private Vector3? m_forceToApply;
146 private int m_userFlags; 147 private int m_userFlags;
@@ -173,6 +174,7 @@ namespace OpenSim.Region.Framework.Scenes
173// private int m_lastColCount = -1; //KF: Look for Collision chnages 174// private int m_lastColCount = -1; //KF: Look for Collision chnages
174// private int m_updateCount = 0; //KF: Update Anims for a while 175// private int m_updateCount = 0; //KF: Update Anims for a while
175// private static readonly int UPDATE_COUNT = 10; // how many frames to update for 176// private static readonly int UPDATE_COUNT = 10; // how many frames to update for
177 private List<uint> m_lastColliders = new List<uint>();
176 178
177 private TeleportFlags m_teleportFlags; 179 private TeleportFlags m_teleportFlags;
178 public TeleportFlags TeleportFlags 180 public TeleportFlags TeleportFlags
@@ -228,8 +230,6 @@ namespace OpenSim.Region.Framework.Scenes
228 /// </summary> 230 /// </summary>
229 public bool LandAtTarget { get; private set; } 231 public bool LandAtTarget { get; private set; }
230 232
231 private bool m_followCamAuto;
232
233 private int m_movementUpdateCount; 233 private int m_movementUpdateCount;
234 private const int NumMovementsBetweenRayCast = 5; 234 private const int NumMovementsBetweenRayCast = 5;
235 235
@@ -237,6 +237,13 @@ namespace OpenSim.Region.Framework.Scenes
237 //private int m_moveToPositionStateStatus; 237 //private int m_moveToPositionStateStatus;
238 //***************************************************** 238 //*****************************************************
239 239
240 private bool m_collisionEventFlag = false;
241 private object m_collisionEventLock = new Object();
242
243 private int m_movementAnimationUpdateCounter = 0;
244
245 private Vector3 m_prevSitOffset;
246
240 protected AvatarAppearance m_appearance; 247 protected AvatarAppearance m_appearance;
241 248
242 public AvatarAppearance Appearance 249 public AvatarAppearance Appearance
@@ -351,6 +358,9 @@ namespace OpenSim.Region.Framework.Scenes
351 /// </summary> 358 /// </summary>
352 protected Vector3 m_lastCameraPosition; 359 protected Vector3 m_lastCameraPosition;
353 360
361 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
362 private bool m_doingCamRayCast = false;
363
354 public Vector3 CameraPosition { get; set; } 364 public Vector3 CameraPosition { get; set; }
355 365
356 public Quaternion CameraRotation 366 public Quaternion CameraRotation
@@ -431,7 +441,9 @@ namespace OpenSim.Region.Framework.Scenes
431 get { return (IClientCore)ControllingClient; } 441 get { return (IClientCore)ControllingClient; }
432 } 442 }
433 443
434 public Vector3 ParentPosition { get; set; } 444 public UUID COF { get; set; }
445
446// public Vector3 ParentPosition { get; set; }
435 447
436 /// <summary> 448 /// <summary>
437 /// Position of this avatar relative to the region the avatar is in 449 /// Position of this avatar relative to the region the avatar is in
@@ -492,7 +504,7 @@ namespace OpenSim.Region.Framework.Scenes
492 if (ParentID == 0) 504 if (ParentID == 0)
493 { 505 {
494 m_pos = value; 506 m_pos = value;
495 ParentPosition = Vector3.Zero; 507// ParentPosition = Vector3.Zero;
496 } 508 }
497 509
498 //m_log.DebugFormat( 510 //m_log.DebugFormat(
@@ -561,7 +573,24 @@ namespace OpenSim.Region.Framework.Scenes
561// Scene.RegionInfo.RegionName, Name, m_velocity); 573// Scene.RegionInfo.RegionName, Name, m_velocity);
562 } 574 }
563 } 575 }
576/*
577 public override Vector3 AngularVelocity
578 {
579 get
580 {
581 if (PhysicsActor != null)
582 {
583 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
564 584
585 // m_log.DebugFormat(
586 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
587 // m_velocity, Name, Scene.RegionInfo.RegionName);
588 }
589
590 return m_rotationalvelocity;
591 }
592 }
593*/
565 private Quaternion m_bodyRot = Quaternion.Identity; 594 private Quaternion m_bodyRot = Quaternion.Identity;
566 595
567 /// <summary> 596 /// <summary>
@@ -584,8 +613,16 @@ namespace OpenSim.Region.Framework.Scenes
584 m_bodyRot = value; 613 m_bodyRot = value;
585 614
586 if (PhysicsActor != null) 615 if (PhysicsActor != null)
587 PhysicsActor.Orientation = m_bodyRot; 616 {
588 617 try
618 {
619 PhysicsActor.Orientation = m_bodyRot;
620 }
621 catch (Exception e)
622 {
623 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
624 }
625 }
589// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 626// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
590 } 627 }
591 } 628 }
@@ -599,12 +636,20 @@ namespace OpenSim.Region.Framework.Scenes
599 } 636 }
600 637
601 public bool IsChildAgent { get; set; } 638 public bool IsChildAgent { get; set; }
639 public bool IsLoggingIn { get; set; }
602 640
603 /// <summary> 641 /// <summary>
604 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 642 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
605 /// </summary> 643 /// </summary>
606 public uint ParentID { get; set; } 644 public uint ParentID { get; set; }
607 645
646 public UUID ParentUUID
647 {
648 get { return m_parentUUID; }
649 set { m_parentUUID = value; }
650 }
651 private UUID m_parentUUID = UUID.Zero;
652
608 /// <summary> 653 /// <summary>
609 /// Are we sitting on an object? 654 /// Are we sitting on an object?
610 /// </summary> 655 /// </summary>
@@ -754,6 +799,7 @@ namespace OpenSim.Region.Framework.Scenes
754 AttachmentsSyncLock = new Object(); 799 AttachmentsSyncLock = new Object();
755 AllowMovement = true; 800 AllowMovement = true;
756 IsChildAgent = true; 801 IsChildAgent = true;
802 IsLoggingIn = false;
757 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 803 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
758 Animator = new ScenePresenceAnimator(this); 804 Animator = new ScenePresenceAnimator(this);
759 PresenceType = type; 805 PresenceType = type;
@@ -797,6 +843,33 @@ namespace OpenSim.Region.Framework.Scenes
797 Appearance = appearance; 843 Appearance = appearance;
798 } 844 }
799 845
846 private void RegionHeartbeatEnd(Scene scene)
847 {
848 if (IsChildAgent)
849 return;
850
851 m_movementAnimationUpdateCounter ++;
852 if (m_movementAnimationUpdateCounter >= 2)
853 {
854 m_movementAnimationUpdateCounter = 0;
855 if (Animator != null)
856 {
857 // If the parentID == 0 we are not sitting
858 // if !SitGournd then we are not sitting on the ground
859 // Fairly straightforward, now here comes the twist
860 // if ParentUUID is NOT UUID.Zero, we are looking to
861 // be sat on an object that isn't there yet. Should
862 // be treated as if sat.
863 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
864 Animator.UpdateMovementAnimations();
865 }
866 else
867 {
868 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
869 }
870 }
871 }
872
800 public void RegisterToEvents() 873 public void RegisterToEvents()
801 { 874 {
802 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 875 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -806,8 +879,10 @@ namespace OpenSim.Region.Framework.Scenes
806 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 879 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
807 ControllingClient.OnStartAnim += HandleStartAnim; 880 ControllingClient.OnStartAnim += HandleStartAnim;
808 ControllingClient.OnStopAnim += HandleStopAnim; 881 ControllingClient.OnStopAnim += HandleStopAnim;
882 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
809 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 883 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
810 ControllingClient.OnAutoPilotGo += MoveToTarget; 884 ControllingClient.OnAutoPilotGo += MoveToTarget;
885 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
811 886
812 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 887 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
813 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 888 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -866,6 +941,38 @@ namespace OpenSim.Region.Framework.Scenes
866 "[SCENE]: Upgrading child to root agent for {0} in {1}", 941 "[SCENE]: Upgrading child to root agent for {0} in {1}",
867 Name, m_scene.RegionInfo.RegionName); 942 Name, m_scene.RegionInfo.RegionName);
868 943
944 if (ParentUUID != UUID.Zero)
945 {
946 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
947 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
948 if (part == null)
949 {
950 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
951 }
952 else
953 {
954 part.ParentGroup.AddAvatar(UUID);
955 if (part.SitTargetPosition != Vector3.Zero)
956 part.SitTargetAvatar = UUID;
957// ParentPosition = part.GetWorldPosition();
958 ParentID = part.LocalId;
959 ParentPart = part;
960 m_pos = m_prevSitOffset;
961// pos = ParentPosition;
962 pos = part.GetWorldPosition();
963 }
964 ParentUUID = UUID.Zero;
965
966 IsChildAgent = false;
967
968// Animator.TrySetMovementAnimation("SIT");
969 }
970 else
971 {
972 IsChildAgent = false;
973 IsLoggingIn = false;
974 }
975
869 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 976 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
870 977
871 IsChildAgent = false; 978 IsChildAgent = false;
@@ -878,70 +985,106 @@ namespace OpenSim.Region.Framework.Scenes
878 985
879 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 986 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
880 987
881 // Moved this from SendInitialData to ensure that Appearance is initialized 988 UUID groupUUID = UUID.Zero;
882 // before the inventory is processed in MakeRootAgent. This fixes a race condition 989 string GroupName = string.Empty;
883 // related to the handling of attachments 990 ulong groupPowers = 0;
884 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
885 991
886 if (m_scene.TestBorderCross(pos, Cardinals.E)) 992 // ----------------------------------
993 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
994 try
887 { 995 {
888 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 996 if (gm != null)
889 pos.X = crossedBorder.BorderLine.Z - 1; 997 {
998 groupUUID = ControllingClient.ActiveGroupId;
999 GroupRecord record = gm.GetGroupRecord(groupUUID);
1000 if (record != null)
1001 GroupName = record.GroupName;
1002 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1003 if (groupMembershipData != null)
1004 groupPowers = groupMembershipData.GroupPowers;
1005 }
1006 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1007 Grouptitle);
890 } 1008 }
891 1009 catch (Exception e)
892 if (m_scene.TestBorderCross(pos, Cardinals.N))
893 { 1010 {
894 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1011 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
895 pos.Y = crossedBorder.BorderLine.Z - 1;
896 } 1012 }
1013 // ------------------------------------
897 1014
898 CheckAndAdjustLandingPoint(ref pos); 1015 if (ParentID == 0)
899
900 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
901 { 1016 {
902 m_log.WarnFormat( 1017 // Moved this from SendInitialData to ensure that Appearance is initialized
903 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1018 // before the inventory is processed in MakeRootAgent. This fixes a race condition
904 pos, Name, UUID); 1019 // related to the handling of attachments
1020 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1021 if (m_scene.TestBorderCross(pos, Cardinals.E))
1022 {
1023 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1024 pos.X = crossedBorder.BorderLine.Z - 1;
1025 }
905 1026
906 if (pos.X < 0f) pos.X = 0f; 1027 if (m_scene.TestBorderCross(pos, Cardinals.N))
907 if (pos.Y < 0f) pos.Y = 0f; 1028 {
908 if (pos.Z < 0f) pos.Z = 0f; 1029 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
909 } 1030 pos.Y = crossedBorder.BorderLine.Z - 1;
1031 }
910 1032
911 float localAVHeight = 1.56f; 1033 CheckAndAdjustLandingPoint(ref pos);
912 if (Appearance.AvatarHeight > 0)
913 localAVHeight = Appearance.AvatarHeight;
914 1034
915 float posZLimit = 0; 1035 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1036 {
1037 m_log.WarnFormat(
1038 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1039 pos, Name, UUID);
916 1040
917 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1041 if (pos.X < 0f) pos.X = 0f;
918 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1042 if (pos.Y < 0f) pos.Y = 0f;
919 1043 if (pos.Z < 0f) pos.Z = 0f;
920 float newPosZ = posZLimit + localAVHeight / 2; 1044 }
921 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
922 {
923 pos.Z = newPosZ;
924 }
925 AbsolutePosition = pos;
926 1045
927 AddToPhysicalScene(isFlying); 1046 float localAVHeight = 1.56f;
1047 if (Appearance.AvatarHeight > 0)
1048 localAVHeight = Appearance.AvatarHeight;
928 1049
929 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1050 float posZLimit = 0;
930 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
931 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
932 // the value to a negative position which does not trigger the border cross.
933 // This may not be the best location for this.
934 CheckForBorderCrossing();
935 1051
936 if (ForceFly) 1052 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
937 { 1053 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
938 Flying = true; 1054
939 } 1055 float newPosZ = posZLimit + localAVHeight / 2;
940 else if (FlyDisabled) 1056 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
941 { 1057 {
942 Flying = false; 1058 pos.Z = newPosZ;
943 } 1059 }
1060 AbsolutePosition = pos;
1061
1062 if (m_teleportFlags == TeleportFlags.Default)
1063 {
1064 Vector3 vel = Velocity;
1065 AddToPhysicalScene(isFlying);
1066 if (PhysicsActor != null)
1067 PhysicsActor.SetMomentum(vel);
1068 }
1069 else
1070 AddToPhysicalScene(isFlying);
944 1071
1072 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1073 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1074 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1075 // the value to a negative position which does not trigger the border cross.
1076 // This may not be the best location for this.
1077 CheckForBorderCrossing();
1078
1079 if (ForceFly)
1080 {
1081 Flying = true;
1082 }
1083 else if (FlyDisabled)
1084 {
1085 Flying = false;
1086 }
1087 }
945 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1088 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
946 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1089 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
947 // elsewhere anyway 1090 // elsewhere anyway
@@ -973,31 +1116,28 @@ namespace OpenSim.Region.Framework.Scenes
973 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1116 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
974 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1117 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
975 // not transporting the required data. 1118 // not transporting the required data.
976 // 1119 lock (m_attachments)
977 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
978 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
979 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
980 //
981 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
982 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
983 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
984 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
985 List<SceneObjectGroup> attachments = GetAttachments();
986
987 if (attachments.Count > 0)
988 { 1120 {
989 m_log.DebugFormat( 1121 if (HasAttachments())
990 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
991
992 // Resume scripts
993 foreach (SceneObjectGroup sog in attachments)
994 { 1122 {
995 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1123 m_log.DebugFormat(
996 sog.ResumeScripts(); 1124 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1125
1126 // Resume scripts
1127 Util.FireAndForget(delegate(object x) {
1128 foreach (SceneObjectGroup sog in m_attachments)
1129 {
1130 sog.ScheduleGroupForFullUpdate();
1131 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1132 sog.ResumeScripts();
1133 }
1134 });
997 } 1135 }
998 } 1136 }
999 } 1137 }
1000 1138
1139 SendAvatarDataToAllAgents();
1140
1001 // send the animations of the other presences to me 1141 // send the animations of the other presences to me
1002 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1142 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1003 { 1143 {
@@ -1008,9 +1148,12 @@ namespace OpenSim.Region.Framework.Scenes
1008 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1148 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1009 // stall on the border crossing since the existing child agent will still have the last movement 1149 // stall on the border crossing since the existing child agent will still have the last movement
1010 // recorded, which stops the input from being processed. 1150 // recorded, which stops the input from being processed.
1151
1011 MovementFlag = 0; 1152 MovementFlag = 0;
1012 1153
1013 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1154 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1155
1156 m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
1014 } 1157 }
1015 1158
1016 public int GetStateSource() 1159 public int GetStateSource()
@@ -1038,12 +1181,16 @@ namespace OpenSim.Region.Framework.Scenes
1038 /// </remarks> 1181 /// </remarks>
1039 public void MakeChildAgent() 1182 public void MakeChildAgent()
1040 { 1183 {
1184 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1185
1041 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1186 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1042 1187
1043 // Reset these so that teleporting in and walking out isn't seen 1188 // Reset these so that teleporting in and walking out isn't seen
1044 // as teleporting back 1189 // as teleporting back
1045 TeleportFlags = TeleportFlags.Default; 1190 TeleportFlags = TeleportFlags.Default;
1046 1191
1192 MovementFlag = 0;
1193
1047 // It looks like Animator is set to null somewhere, and MakeChild 1194 // It looks like Animator is set to null somewhere, and MakeChild
1048 // is called after that. Probably in aborted teleports. 1195 // is called after that. Probably in aborted teleports.
1049 if (Animator == null) 1196 if (Animator == null)
@@ -1051,6 +1198,7 @@ namespace OpenSim.Region.Framework.Scenes
1051 else 1198 else
1052 Animator.ResetAnimations(); 1199 Animator.ResetAnimations();
1053 1200
1201
1054// m_log.DebugFormat( 1202// m_log.DebugFormat(
1055// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1203// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1056// Name, UUID, m_scene.RegionInfo.RegionName); 1204// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1062,6 +1210,7 @@ namespace OpenSim.Region.Framework.Scenes
1062 IsChildAgent = true; 1210 IsChildAgent = true;
1063 m_scene.SwapRootAgentCount(true); 1211 m_scene.SwapRootAgentCount(true);
1064 RemoveFromPhysicalScene(); 1212 RemoveFromPhysicalScene();
1213 ParentID = 0; // Child agents can't be sitting
1065 1214
1066 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1215 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1067 1216
@@ -1077,9 +1226,9 @@ namespace OpenSim.Region.Framework.Scenes
1077 { 1226 {
1078// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1227// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1079 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1228 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1080 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1081 PhysicsActor.UnSubscribeEvents();
1082 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1229 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1230 PhysicsActor.UnSubscribeEvents();
1231 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1083 PhysicsActor = null; 1232 PhysicsActor = null;
1084 } 1233 }
1085// else 1234// else
@@ -1096,7 +1245,7 @@ namespace OpenSim.Region.Framework.Scenes
1096 /// <param name="pos"></param> 1245 /// <param name="pos"></param>
1097 public void Teleport(Vector3 pos) 1246 public void Teleport(Vector3 pos)
1098 { 1247 {
1099 TeleportWithMomentum(pos, null); 1248 TeleportWithMomentum(pos, Vector3.Zero);
1100 } 1249 }
1101 1250
1102 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1251 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1120,6 +1269,41 @@ namespace OpenSim.Region.Framework.Scenes
1120 SendTerseUpdateToAllClients(); 1269 SendTerseUpdateToAllClients();
1121 } 1270 }
1122 1271
1272 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1273 {
1274 CheckLandingPoint(ref newpos);
1275 AbsolutePosition = newpos;
1276
1277 if (newvel.HasValue)
1278 {
1279 if ((Vector3)newvel == Vector3.Zero)
1280 {
1281 if (PhysicsActor != null)
1282 PhysicsActor.SetMomentum(Vector3.Zero);
1283 m_velocity = Vector3.Zero;
1284 }
1285 else
1286 {
1287 if (PhysicsActor != null)
1288 PhysicsActor.SetMomentum((Vector3)newvel);
1289 m_velocity = (Vector3)newvel;
1290
1291 if (rotateToVelXY)
1292 {
1293 Vector3 lookAt = (Vector3)newvel;
1294 lookAt.Z = 0;
1295 lookAt.Normalize();
1296 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1297 return;
1298 }
1299 }
1300 }
1301
1302 SendTerseUpdateToAllClients();
1303 }
1304
1305
1306
1123 public void StopFlying() 1307 public void StopFlying()
1124 { 1308 {
1125 ControllingClient.StopFlying(this); 1309 ControllingClient.StopFlying(this);
@@ -1289,6 +1473,13 @@ namespace OpenSim.Region.Framework.Scenes
1289 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1473 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1290 } 1474 }
1291 1475
1476 public void SetSize(Vector3 size, float feetoffset)
1477 {
1478 if (PhysicsActor != null && !IsChildAgent)
1479 PhysicsActor.setAvatarSize(size, feetoffset);
1480
1481 }
1482
1292 /// <summary> 1483 /// <summary>
1293 /// Complete Avatar's movement into the region. 1484 /// Complete Avatar's movement into the region.
1294 /// </summary> 1485 /// </summary>
@@ -1308,7 +1499,8 @@ namespace OpenSim.Region.Framework.Scenes
1308 1499
1309 Vector3 look = Velocity; 1500 Vector3 look = Velocity;
1310 1501
1311 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1502 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1503 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1312 { 1504 {
1313 look = new Vector3(0.99f, 0.042f, 0); 1505 look = new Vector3(0.99f, 0.042f, 0);
1314 } 1506 }
@@ -1363,11 +1555,12 @@ namespace OpenSim.Region.Framework.Scenes
1363 1555
1364 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1556 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1365 if (m_agentTransfer != null) 1557 if (m_agentTransfer != null)
1366 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1558 m_agentTransfer.EnableChildAgents(this);
1367 1559
1368 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1560 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1369 if (friendsModule != null) 1561 if (friendsModule != null)
1370 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1562 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1563
1371 } 1564 }
1372 1565
1373 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1566 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1392,36 +1585,69 @@ namespace OpenSim.Region.Framework.Scenes
1392 /// <param name="collisionPoint"></param> 1585 /// <param name="collisionPoint"></param>
1393 /// <param name="localid"></param> 1586 /// <param name="localid"></param>
1394 /// <param name="distance"></param> 1587 /// <param name="distance"></param>
1588 ///
1589
1590 private void UpdateCameraCollisionPlane(Vector4 plane)
1591 {
1592 if (m_lastCameraCollisionPlane != plane)
1593 {
1594 m_lastCameraCollisionPlane = plane;
1595 ControllingClient.SendCameraConstraint(plane);
1596 }
1597 }
1598
1395 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1599 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1396 { 1600 {
1397 const float POSITION_TOLERANCE = 0.02f; 1601 const float POSITION_TOLERANCE = 0.02f;
1398 const float VELOCITY_TOLERANCE = 0.02f;
1399 const float ROTATION_TOLERANCE = 0.02f; 1602 const float ROTATION_TOLERANCE = 0.02f;
1400 1603
1401 if (m_followCamAuto) 1604 m_doingCamRayCast = false;
1605 if (hitYN && localid != LocalId)
1402 { 1606 {
1403 if (hitYN) 1607 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1608 bool IsPrim = group != null;
1609 if (IsPrim)
1404 { 1610 {
1405 CameraConstraintActive = true; 1611 SceneObjectPart part = group.GetPart(localid);
1406 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1612 if (part != null && !part.VolumeDetectActive)
1407 1613 {
1408 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1614 CameraConstraintActive = true;
1409 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1615 pNormal.X = (float) Math.Round(pNormal.X, 2);
1616 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1617 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1618 pNormal.Normalize();
1619 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1620 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1621 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1622
1623 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1624 Vector3.Dot(collisionPoint, pNormal));
1625 UpdateCameraCollisionPlane(plane);
1626 }
1410 } 1627 }
1411 else 1628 else
1412 { 1629 {
1413 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1630 CameraConstraintActive = true;
1414 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1631 pNormal.X = (float) Math.Round(pNormal.X, 2);
1415 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1632 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1416 { 1633 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1417 if (CameraConstraintActive) 1634 pNormal.Normalize();
1418 { 1635 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1419 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1636 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1420 CameraConstraintActive = false; 1637 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1421 } 1638
1422 } 1639 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1640 Vector3.Dot(collisionPoint, pNormal));
1641 UpdateCameraCollisionPlane(plane);
1423 } 1642 }
1424 } 1643 }
1644 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1645 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1646 {
1647 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1648 UpdateCameraCollisionPlane(plane);
1649 CameraConstraintActive = false;
1650 }
1425 } 1651 }
1426 1652
1427 /// <summary> 1653 /// <summary>
@@ -1495,12 +1721,6 @@ namespace OpenSim.Region.Framework.Scenes
1495 // DrawDistance = agentData.Far; 1721 // DrawDistance = agentData.Far;
1496 DrawDistance = Scene.DefaultDrawDistance; 1722 DrawDistance = Scene.DefaultDrawDistance;
1497 1723
1498 // Check if Client has camera in 'follow cam' or 'build' mode.
1499 Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
1500
1501 m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
1502 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
1503
1504 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; 1724 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
1505 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; 1725 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
1506 1726
@@ -1520,14 +1740,38 @@ namespace OpenSim.Region.Framework.Scenes
1520 StandUp(); 1740 StandUp();
1521 } 1741 }
1522 1742
1523 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
1524 // Raycast from the avatar's head to the camera to see if there's anything blocking the view 1743 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1525 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) 1744 // this exclude checks may not be complete
1745
1746 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1526 { 1747 {
1527 if (m_followCamAuto) 1748 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1528 { 1749 {
1529 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; 1750 Vector3 posAdjusted = AbsolutePosition;
1530 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback); 1751// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1752 posAdjusted.Z += 1.0f; // viewer current camera focus point
1753 Vector3 tocam = CameraPosition - posAdjusted;
1754 tocam.X = (float)Math.Round(tocam.X, 1);
1755 tocam.Y = (float)Math.Round(tocam.Y, 1);
1756 tocam.Z = (float)Math.Round(tocam.Z, 1);
1757
1758 float distTocamlen = tocam.Length();
1759 if (distTocamlen > 0.3f)
1760 {
1761 tocam *= (1.0f / distTocamlen);
1762 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1763 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1764 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1765
1766 m_doingCamRayCast = true;
1767 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1768 }
1769 }
1770 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1771 {
1772 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1773 UpdateCameraCollisionPlane(plane);
1774 CameraConstraintActive = false;
1531 } 1775 }
1532 } 1776 }
1533 1777
@@ -1992,7 +2236,8 @@ namespace OpenSim.Region.Framework.Scenes
1992// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2236// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1993 2237
1994 MovingToTarget = false; 2238 MovingToTarget = false;
1995 MoveToPositionTarget = Vector3.Zero; 2239// MoveToPositionTarget = Vector3.Zero;
2240 m_forceToApply = null; // cancel possible last action
1996 2241
1997 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2242 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
1998 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2243 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2010,12 +2255,17 @@ namespace OpenSim.Region.Framework.Scenes
2010// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2255// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
2011 2256
2012 SitGround = false; 2257 SitGround = false;
2258
2259/* move this down so avatar gets physical in the new position and not where it is siting
2013 if (PhysicsActor == null) 2260 if (PhysicsActor == null)
2014 AddToPhysicalScene(false); 2261 AddToPhysicalScene(false);
2262 */
2015 2263
2016 if (ParentID != 0) 2264 if (ParentID != 0)
2017 { 2265 {
2018 SceneObjectPart part = ParentPart; 2266 SceneObjectPart part = ParentPart;
2267 UnRegisterSeatControls(part.ParentGroup.UUID);
2268
2019 TaskInventoryDictionary taskIDict = part.TaskInventory; 2269 TaskInventoryDictionary taskIDict = part.TaskInventory;
2020 if (taskIDict != null) 2270 if (taskIDict != null)
2021 { 2271 {
@@ -2031,14 +2281,22 @@ namespace OpenSim.Region.Framework.Scenes
2031 } 2281 }
2032 } 2282 }
2033 2283
2034 ParentPosition = part.GetWorldPosition(); 2284 part.ParentGroup.DeleteAvatar(UUID);
2285// ParentPosition = part.GetWorldPosition();
2035 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2286 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2036 2287
2037 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 2288// m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2038 ParentPosition = Vector3.Zero; 2289// ParentPosition = Vector3.Zero;
2290 m_pos = part.AbsolutePosition + (m_pos * part.GetWorldRotation()) + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2291 if (part.SitTargetAvatar == UUID)
2292 m_bodyRot = part.GetWorldRotation() * part.SitTargetOrientation;
2039 2293
2040 ParentID = 0; 2294 ParentID = 0;
2041 ParentPart = null; 2295 ParentPart = null;
2296
2297 if (PhysicsActor == null)
2298 AddToPhysicalScene(false);
2299
2042 SendAvatarDataToAllAgents(); 2300 SendAvatarDataToAllAgents();
2043 m_requestedSitTargetID = 0; 2301 m_requestedSitTargetID = 0;
2044 2302
@@ -2048,6 +2306,9 @@ namespace OpenSim.Region.Framework.Scenes
2048 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2306 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2049 } 2307 }
2050 2308
2309 else if (PhysicsActor == null)
2310 AddToPhysicalScene(false);
2311
2051 Animator.TrySetMovementAnimation("STAND"); 2312 Animator.TrySetMovementAnimation("STAND");
2052 TriggerScenePresenceUpdated(); 2313 TriggerScenePresenceUpdated();
2053 } 2314 }
@@ -2096,11 +2357,8 @@ namespace OpenSim.Region.Framework.Scenes
2096 if (part == null) 2357 if (part == null)
2097 return; 2358 return;
2098 2359
2099 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2100 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2101
2102 if (PhysicsActor != null) 2360 if (PhysicsActor != null)
2103 m_sitAvatarHeight = PhysicsActor.Size.Z; 2361 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2104 2362
2105 bool canSit = false; 2363 bool canSit = false;
2106 Vector3 pos = part.AbsolutePosition + offset; 2364 Vector3 pos = part.AbsolutePosition + offset;
@@ -2117,31 +2375,31 @@ namespace OpenSim.Region.Framework.Scenes
2117 } 2375 }
2118 else 2376 else
2119 { 2377 {
2378 if (PhysicsSit(part,offset)) // physics engine
2379 return;
2380
2120 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2381 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2121 { 2382 {
2122// m_log.DebugFormat(
2123// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2124// Name, part.Name, part.LocalId);
2125 2383
2126 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2384 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2127 canSit = true; 2385 canSit = true;
2128 } 2386 }
2129// else
2130// {
2131// m_log.DebugFormat(
2132// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2133// Name, part.Name, part.LocalId);
2134// }
2135 } 2387 }
2136 2388
2137 if (canSit) 2389 if (canSit)
2138 { 2390 {
2391
2139 if (PhysicsActor != null) 2392 if (PhysicsActor != null)
2140 { 2393 {
2141 // We can remove the physicsActor until they stand up. 2394 // We can remove the physicsActor until they stand up.
2142 RemoveFromPhysicalScene(); 2395 RemoveFromPhysicalScene();
2143 } 2396 }
2144 2397
2398 if (MovingToTarget)
2399 ResetMoveToTarget();
2400
2401 Velocity = Vector3.Zero;
2402
2145 part.AddSittingAvatar(UUID); 2403 part.AddSittingAvatar(UUID);
2146 2404
2147 cameraAtOffset = part.GetCameraAtOffset(); 2405 cameraAtOffset = part.GetCameraAtOffset();
@@ -2163,6 +2421,9 @@ namespace OpenSim.Region.Framework.Scenes
2163 2421
2164 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2422 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2165 { 2423 {
2424 if (IsChildAgent)
2425 return;
2426
2166 if (ParentID != 0) 2427 if (ParentID != 0)
2167 { 2428 {
2168 if (ParentPart.UUID == targetID) 2429 if (ParentPart.UUID == targetID)
@@ -2178,14 +2439,6 @@ namespace OpenSim.Region.Framework.Scenes
2178 m_requestedSitTargetID = part.LocalId; 2439 m_requestedSitTargetID = part.LocalId;
2179 m_requestedSitTargetUUID = part.UUID; 2440 m_requestedSitTargetUUID = part.UUID;
2180 2441
2181// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2182
2183 if (m_scene.PhysicsScene.SupportsRayCast())
2184 {
2185 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2186 //SitRayCastAvatarPosition(part);
2187 //return;
2188 }
2189 } 2442 }
2190 else 2443 else
2191 { 2444 {
@@ -2195,197 +2448,111 @@ namespace OpenSim.Region.Framework.Scenes
2195 SendSitResponse(targetID, offset, Quaternion.Identity); 2448 SendSitResponse(targetID, offset, Quaternion.Identity);
2196 } 2449 }
2197 2450
2198 /* 2451 // returns false if does not suport so older sit can be tried
2199 public void SitRayCastAvatarPosition(SceneObjectPart part) 2452 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2200 { 2453 {
2201 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2454 if (part == null || part.ParentGroup.IsAttachment)
2202 Vector3 StartRayCastPosition = AbsolutePosition;
2203 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2204 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2205 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2206 }
2207
2208 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2209 {
2210 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2211 if (part != null)
2212 {
2213 if (hitYN)
2214 {
2215 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2216 {
2217 SitRaycastFindEdge(collisionPoint, normal);
2218 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2219 }
2220 else
2221 {
2222 SitRayCastAvatarPositionCameraZ(part);
2223 }
2224 }
2225 else
2226 {
2227 SitRayCastAvatarPositionCameraZ(part);
2228 }
2229 }
2230 else
2231 { 2455 {
2232 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2456 return true;
2233 m_requestedSitTargetUUID = UUID.Zero;
2234 m_requestedSitTargetID = 0;
2235 m_requestedSitOffset = Vector3.Zero;
2236 } 2457 }
2237 2458
2238 } 2459 if ( m_scene.PhysicsScene == null)
2239 2460 return false;
2240 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2241 {
2242 // Next, try to raycast from the camera Z position
2243 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2244 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2245 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2246 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2247 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2248 }
2249 2461
2250 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2462 if (part.PhysActor == null)
2251 {
2252 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2253 if (part != null)
2254 { 2463 {
2255 if (hitYN) 2464 // none physcis shape
2256 { 2465 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2257 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2466 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2258 {
2259 SitRaycastFindEdge(collisionPoint, normal);
2260 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2261 }
2262 else
2263 {
2264 SitRayCastCameraPosition(part);
2265 }
2266 }
2267 else 2467 else
2268 { 2468 { // non physical phantom TODO
2269 SitRayCastCameraPosition(part); 2469 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2470 return false;
2270 } 2471 }
2271 } 2472 return true;
2272 else
2273 {
2274 ControllingClient.SendAlertMessage("Sit position no longer exists");
2275 m_requestedSitTargetUUID = UUID.Zero;
2276 m_requestedSitTargetID = 0;
2277 m_requestedSitOffset = Vector3.Zero;
2278 } 2473 }
2279 2474
2280 }
2281 2475
2282 public void SitRayCastCameraPosition(SceneObjectPart part) 2476 // not doing autopilot
2283 { 2477 m_requestedSitTargetID = 0;
2284 // Next, try to raycast from the camera position
2285 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2286 Vector3 StartRayCastPosition = CameraPosition;
2287 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2288 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2289 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2290 }
2291 2478
2292 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2479 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2293 { 2480 return true;
2294 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2295 if (part != null)
2296 {
2297 if (hitYN)
2298 {
2299 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2300 {
2301 SitRaycastFindEdge(collisionPoint, normal);
2302 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2303 }
2304 else
2305 {
2306 SitRayHorizontal(part);
2307 }
2308 }
2309 else
2310 {
2311 SitRayHorizontal(part);
2312 }
2313 }
2314 else
2315 {
2316 ControllingClient.SendAlertMessage("Sit position no longer exists");
2317 m_requestedSitTargetUUID = UUID.Zero;
2318 m_requestedSitTargetID = 0;
2319 m_requestedSitOffset = Vector3.Zero;
2320 }
2321 2481
2482 return false;
2322 } 2483 }
2323 2484
2324 public void SitRayHorizontal(SceneObjectPart part) 2485
2486 private bool CanEnterLandPosition(Vector3 testPos)
2325 { 2487 {
2326 // Next, try to raycast from the avatar position to fwd 2488 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2327 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2489
2328 Vector3 StartRayCastPosition = CameraPosition; 2490 if (land == null || land.LandData.Name == "NO_LAND")
2329 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2491 return true;
2330 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2492
2331 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2493 return land.CanBeOnThisLand(UUID,testPos.Z);
2332 } 2494 }
2333 2495
2334 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2496 // status
2497 // < 0 ignore
2498 // 0 bad sit spot
2499 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2335 { 2500 {
2336 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2501 if (status < 0)
2337 if (part != null) 2502 return;
2503
2504 if (status == 0)
2338 { 2505 {
2339 if (hitYN) 2506 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2340 { 2507 return;
2341 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2342 {
2343 SitRaycastFindEdge(collisionPoint, normal);
2344 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2345 // Next, try to raycast from the camera position
2346 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2347 Vector3 StartRayCastPosition = CameraPosition;
2348 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2349 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2350 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2351 }
2352 else
2353 {
2354 ControllingClient.SendAlertMessage("Sit position not accessable.");
2355 m_requestedSitTargetUUID = UUID.Zero;
2356 m_requestedSitTargetID = 0;
2357 m_requestedSitOffset = Vector3.Zero;
2358 }
2359 }
2360 else
2361 {
2362 ControllingClient.SendAlertMessage("Sit position not accessable.");
2363 m_requestedSitTargetUUID = UUID.Zero;
2364 m_requestedSitTargetID = 0;
2365 m_requestedSitOffset = Vector3.Zero;
2366 }
2367 } 2508 }
2368 else 2509
2510 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2511 if (part == null)
2512 return;
2513
2514 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2515 if(!CanEnterLandPosition(targetPos))
2369 { 2516 {
2370 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2517 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2371 m_requestedSitTargetUUID = UUID.Zero; 2518 return;
2372 m_requestedSitTargetID = 0;
2373 m_requestedSitOffset = Vector3.Zero;
2374 } 2519 }
2375 2520
2376 } 2521 RemoveFromPhysicalScene();
2377 2522
2378 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2523 if (MovingToTarget)
2379 { 2524 ResetMoveToTarget();
2380 int i = 0; 2525
2381 //throw new NotImplementedException(); 2526 Velocity = Vector3.Zero;
2382 //m_requestedSitTargetUUID = UUID.Zero;
2383 //m_requestedSitTargetID = 0;
2384 //m_requestedSitOffset = Vector3.Zero;
2385 2527
2386 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2528 part.AddSittingAvatar(UUID);
2529
2530 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2531 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2532 bool forceMouselook = part.GetForceMouselook();
2533
2534 ControllingClient.SendSitResponse(
2535 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2536
2537 // not using autopilot
2538
2539 Rotation = Orientation;
2540 m_pos = offset;
2541
2542 m_requestedSitTargetID = 0;
2543 part.ParentGroup.AddAvatar(UUID);
2544
2545 ParentPart = part;
2546 ParentID = part.LocalId;
2547 if(status == 3)
2548 Animator.TrySetMovementAnimation("SIT_GROUND");
2549 else
2550 Animator.TrySetMovementAnimation("SIT");
2551 SendAvatarDataToAllAgents();
2552
2553 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2387 } 2554 }
2388 */ 2555
2389 2556
2390 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2557 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2391 { 2558 {
@@ -2402,6 +2569,7 @@ namespace OpenSim.Region.Framework.Scenes
2402 return; 2569 return;
2403 } 2570 }
2404 2571
2572
2405 if (part.SitTargetAvatar == UUID) 2573 if (part.SitTargetAvatar == UUID)
2406 { 2574 {
2407 Vector3 sitTargetPos = part.SitTargetPosition; 2575 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2416,14 +2584,39 @@ namespace OpenSim.Region.Framework.Scenes
2416 2584
2417 //Quaternion result = (sitTargetOrient * vq) * nq; 2585 //Quaternion result = (sitTargetOrient * vq) * nq;
2418 2586
2419 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2587 double x, y, z, m;
2588
2589 Quaternion r = sitTargetOrient;
2590 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2591
2592 if (Math.Abs(1.0 - m) > 0.000001)
2593 {
2594 m = 1.0 / Math.Sqrt(m);
2595 r.X *= (float)m;
2596 r.Y *= (float)m;
2597 r.Z *= (float)m;
2598 r.W *= (float)m;
2599 }
2600
2601 x = 2 * (r.X * r.Z + r.Y * r.W);
2602 y = 2 * (-r.X * r.W + r.Y * r.Z);
2603 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2604
2605 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2606 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2607
2608 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2609
2610// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2420 Rotation = sitTargetOrient; 2611 Rotation = sitTargetOrient;
2421 ParentPosition = part.AbsolutePosition; 2612// ParentPosition = part.AbsolutePosition;
2613 part.ParentGroup.AddAvatar(UUID);
2422 } 2614 }
2423 else 2615 else
2424 { 2616 {
2425 m_pos -= part.AbsolutePosition; 2617 m_pos -= part.AbsolutePosition;
2426 ParentPosition = part.AbsolutePosition; 2618// ParentPosition = part.AbsolutePosition;
2619 part.ParentGroup.AddAvatar(UUID);
2427 2620
2428// m_log.DebugFormat( 2621// m_log.DebugFormat(
2429// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2622// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2478,6 +2671,13 @@ namespace OpenSim.Region.Framework.Scenes
2478 TriggerScenePresenceUpdated(); 2671 TriggerScenePresenceUpdated();
2479 } 2672 }
2480 2673
2674 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
2675 {
2676 Animator.avnChangeAnim(animID, addRemove, sendPack);
2677 }
2678
2679
2680
2481 /// <summary> 2681 /// <summary>
2482 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2682 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2483 /// </summary> 2683 /// </summary>
@@ -2534,8 +2734,8 @@ namespace OpenSim.Region.Framework.Scenes
2534 direc.Z *= 2.6f; 2734 direc.Z *= 2.6f;
2535 2735
2536 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2736 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2537 Animator.TrySetMovementAnimation("PREJUMP"); 2737// Animator.TrySetMovementAnimation("PREJUMP");
2538 Animator.TrySetMovementAnimation("JUMP"); 2738// Animator.TrySetMovementAnimation("JUMP");
2539 } 2739 }
2540 } 2740 }
2541 } 2741 }
@@ -2544,6 +2744,7 @@ namespace OpenSim.Region.Framework.Scenes
2544 2744
2545 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2745 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2546 m_forceToApply = direc; 2746 m_forceToApply = direc;
2747 Animator.UpdateMovementAnimations();
2547 } 2748 }
2548 2749
2549 #endregion 2750 #endregion
@@ -2561,16 +2762,12 @@ namespace OpenSim.Region.Framework.Scenes
2561 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 2762 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2562 // grab the latest PhysicsActor velocity, whereas m_velocity is often 2763 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2563 // storing a requested force instead of an actual traveling velocity 2764 // storing a requested force instead of an actual traveling velocity
2765 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
2766 SendAvatarDataToAllAgents();
2564 2767
2565 // Throw away duplicate or insignificant updates 2768 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2566 if ( 2769 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2567 // If the velocity has become zero, send it no matter what. 2770 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2568 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2569 // otherwise, if things have changed reasonably, send the update
2570 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2571 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2572 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2573
2574 { 2771 {
2575 SendTerseUpdateToAllClients(); 2772 SendTerseUpdateToAllClients();
2576 2773
@@ -2728,9 +2925,7 @@ namespace OpenSim.Region.Framework.Scenes
2728 // again here... this comes after the cached appearance check because the avatars 2925 // again here... this comes after the cached appearance check because the avatars
2729 // appearance goes into the avatar update packet 2926 // appearance goes into the avatar update packet
2730 SendAvatarDataToAllAgents(); 2927 SendAvatarDataToAllAgents();
2731 2928 SendAppearanceToAgent(this);
2732 // This invocation always shows up in the viewer logs as an error.
2733 // SendAppearanceToAgent(this);
2734 2929
2735 // If we are using the the cached appearance then send it out to everyone 2930 // If we are using the the cached appearance then send it out to everyone
2736 if (cachedappearance) 2931 if (cachedappearance)
@@ -2761,6 +2956,8 @@ namespace OpenSim.Region.Framework.Scenes
2761 return; 2956 return;
2762 } 2957 }
2763 2958
2959 m_lastSize = Appearance.AvatarSize;
2960
2764 int count = 0; 2961 int count = 0;
2765 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2962 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2766 { 2963 {
@@ -2868,6 +3065,8 @@ namespace OpenSim.Region.Framework.Scenes
2868 3065
2869 avatar.ControllingClient.SendAppearance( 3066 avatar.ControllingClient.SendAppearance(
2870 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3067 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3068
3069
2871 } 3070 }
2872 3071
2873 #endregion 3072 #endregion
@@ -2942,8 +3141,9 @@ namespace OpenSim.Region.Framework.Scenes
2942 3141
2943 // If we don't have a PhysActor, we can't cross anyway 3142 // If we don't have a PhysActor, we can't cross anyway
2944 // Also don't do this while sat, sitting avatars cross with the 3143 // Also don't do this while sat, sitting avatars cross with the
2945 // object they sit on. 3144 // object they sit on. ParentUUID denoted a pending sit, don't
2946 if (ParentID != 0 || PhysicsActor == null) 3145 // interfere with it.
3146 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
2947 return; 3147 return;
2948 3148
2949 if (!IsInTransit) 3149 if (!IsInTransit)
@@ -3206,6 +3406,10 @@ namespace OpenSim.Region.Framework.Scenes
3206 } 3406 }
3207 3407
3208 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3408 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3409 private void RaiseUpdateThrottles()
3410 {
3411 m_scene.EventManager.TriggerThrottleUpdate(this);
3412 }
3209 /// <summary> 3413 /// <summary>
3210 /// This updates important decision making data about a child agent 3414 /// This updates important decision making data about a child agent
3211 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3415 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3286,6 +3490,9 @@ namespace OpenSim.Region.Framework.Scenes
3286 cAgent.AlwaysRun = SetAlwaysRun; 3490 cAgent.AlwaysRun = SetAlwaysRun;
3287 3491
3288 cAgent.Appearance = new AvatarAppearance(Appearance); 3492 cAgent.Appearance = new AvatarAppearance(Appearance);
3493
3494 cAgent.ParentPart = ParentUUID;
3495 cAgent.SitOffset = m_pos;
3289 3496
3290 lock (scriptedcontrols) 3497 lock (scriptedcontrols)
3291 { 3498 {
@@ -3294,7 +3501,7 @@ namespace OpenSim.Region.Framework.Scenes
3294 3501
3295 foreach (ScriptControllers c in scriptedcontrols.Values) 3502 foreach (ScriptControllers c in scriptedcontrols.Values)
3296 { 3503 {
3297 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3504 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3298 } 3505 }
3299 cAgent.Controllers = controls; 3506 cAgent.Controllers = controls;
3300 } 3507 }
@@ -3327,6 +3534,8 @@ namespace OpenSim.Region.Framework.Scenes
3327 CameraAtAxis = cAgent.AtAxis; 3534 CameraAtAxis = cAgent.AtAxis;
3328 CameraLeftAxis = cAgent.LeftAxis; 3535 CameraLeftAxis = cAgent.LeftAxis;
3329 CameraUpAxis = cAgent.UpAxis; 3536 CameraUpAxis = cAgent.UpAxis;
3537 ParentUUID = cAgent.ParentPart;
3538 m_prevSitOffset = cAgent.SitOffset;
3330 3539
3331 // When we get to the point of re-computing neighbors everytime this 3540 // When we get to the point of re-computing neighbors everytime this
3332 // changes, then start using the agent's drawdistance rather than the 3541 // changes, then start using the agent's drawdistance rather than the
@@ -3364,6 +3573,7 @@ namespace OpenSim.Region.Framework.Scenes
3364 foreach (ControllerData c in cAgent.Controllers) 3573 foreach (ControllerData c in cAgent.Controllers)
3365 { 3574 {
3366 ScriptControllers sc = new ScriptControllers(); 3575 ScriptControllers sc = new ScriptControllers();
3576 sc.objectID = c.ObjectID;
3367 sc.itemID = c.ItemID; 3577 sc.itemID = c.ItemID;
3368 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3578 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3369 sc.eventControls = (ScriptControlled)c.EventControls; 3579 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3431,20 +3641,27 @@ namespace OpenSim.Region.Framework.Scenes
3431 } 3641 }
3432 3642
3433 if (Appearance.AvatarHeight == 0) 3643 if (Appearance.AvatarHeight == 0)
3434 Appearance.SetHeight(); 3644// Appearance.SetHeight();
3645 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3435 3646
3436 PhysicsScene scene = m_scene.PhysicsScene; 3647 PhysicsScene scene = m_scene.PhysicsScene;
3437 3648
3438 Vector3 pVec = AbsolutePosition; 3649 Vector3 pVec = AbsolutePosition;
3439 3650
3651/*
3440 PhysicsActor = scene.AddAvatar( 3652 PhysicsActor = scene.AddAvatar(
3441 LocalId, Firstname + "." + Lastname, pVec, 3653 LocalId, Firstname + "." + Lastname, pVec,
3442 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3654 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3655*/
3656
3657 PhysicsActor = scene.AddAvatar(
3658 LocalId, Firstname + "." + Lastname, pVec,
3659 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
3443 3660
3444 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3661 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3445 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3662 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3446 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3663 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3447 PhysicsActor.SubscribeEvents(500); 3664 PhysicsActor.SubscribeEvents(100);
3448 PhysicsActor.LocalID = LocalId; 3665 PhysicsActor.LocalID = LocalId;
3449 } 3666 }
3450 3667
@@ -3458,6 +3675,7 @@ namespace OpenSim.Region.Framework.Scenes
3458 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3675 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3459 } 3676 }
3460 3677
3678
3461 /// <summary> 3679 /// <summary>
3462 /// Event called by the physics plugin to tell the avatar about a collision. 3680 /// Event called by the physics plugin to tell the avatar about a collision.
3463 /// </summary> 3681 /// </summary>
@@ -3471,7 +3689,7 @@ namespace OpenSim.Region.Framework.Scenes
3471 /// <param name="e"></param> 3689 /// <param name="e"></param>
3472 public void PhysicsCollisionUpdate(EventArgs e) 3690 public void PhysicsCollisionUpdate(EventArgs e)
3473 { 3691 {
3474 if (IsChildAgent) 3692 if (IsChildAgent || Animator == null)
3475 return; 3693 return;
3476 3694
3477 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3695 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3488,7 +3706,6 @@ namespace OpenSim.Region.Framework.Scenes
3488 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3706 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3489 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3707 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3490 3708
3491 CollisionPlane = Vector4.UnitW;
3492 3709
3493// // No collisions at all means we may be flying. Update always 3710// // No collisions at all means we may be flying. Update always
3494// // to make falling work 3711// // to make falling work
@@ -3500,6 +3717,7 @@ namespace OpenSim.Region.Framework.Scenes
3500 3717
3501 if (coldata.Count != 0) 3718 if (coldata.Count != 0)
3502 { 3719 {
3720/*
3503 switch (Animator.CurrentMovementAnimation) 3721 switch (Animator.CurrentMovementAnimation)
3504 { 3722 {
3505 case "STAND": 3723 case "STAND":
@@ -3508,24 +3726,38 @@ namespace OpenSim.Region.Framework.Scenes
3508 case "CROUCH": 3726 case "CROUCH":
3509 case "CROUCHWALK": 3727 case "CROUCHWALK":
3510 { 3728 {
3729 */
3511 ContactPoint lowest; 3730 ContactPoint lowest;
3512 lowest.SurfaceNormal = Vector3.Zero; 3731 lowest.SurfaceNormal = Vector3.Zero;
3513 lowest.Position = Vector3.Zero; 3732 lowest.Position = Vector3.Zero;
3514 lowest.Position.Z = Single.NaN; 3733 lowest.Position.Z = float.MaxValue;
3515 3734
3516 foreach (ContactPoint contact in coldata.Values) 3735 foreach (ContactPoint contact in coldata.Values)
3517 { 3736 {
3518 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 3737
3738 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3519 { 3739 {
3520 lowest = contact; 3740 lowest = contact;
3521 } 3741 }
3522 } 3742 }
3523 3743
3524 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 3744 if (lowest.Position.Z != float.MaxValue)
3745 {
3746 lowest.SurfaceNormal = -lowest.SurfaceNormal;
3747 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3748 }
3749 else
3750 CollisionPlane = Vector4.UnitW;
3751/*
3525 } 3752 }
3526 break; 3753 break;
3527 } 3754 }
3755*/
3528 } 3756 }
3757 else
3758 CollisionPlane = Vector4.UnitW;
3759
3760 RaiseCollisionScriptEvents(coldata);
3529 3761
3530 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3762 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3531 if (Invulnerable || GodLevel > 0) 3763 if (Invulnerable || GodLevel > 0)
@@ -3624,6 +3856,13 @@ namespace OpenSim.Region.Framework.Scenes
3624 // m_reprioritizationTimer.Dispose(); 3856 // m_reprioritizationTimer.Dispose();
3625 3857
3626 RemoveFromPhysicalScene(); 3858 RemoveFromPhysicalScene();
3859
3860 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
3861
3862// if (Animator != null)
3863// Animator.Close();
3864 Animator = null;
3865
3627 } 3866 }
3628 3867
3629 public void AddAttachment(SceneObjectGroup gobj) 3868 public void AddAttachment(SceneObjectGroup gobj)
@@ -3857,10 +4096,18 @@ namespace OpenSim.Region.Framework.Scenes
3857 4096
3858 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4097 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
3859 { 4098 {
4099 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4100 if (p == null)
4101 return;
4102
4103 ControllingClient.SendTakeControls(controls, false, false);
4104 ControllingClient.SendTakeControls(controls, true, false);
4105
3860 ScriptControllers obj = new ScriptControllers(); 4106 ScriptControllers obj = new ScriptControllers();
3861 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4107 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
3862 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4108 obj.eventControls = ScriptControlled.CONTROL_ZERO;
3863 4109
4110 obj.objectID = p.ParentGroup.UUID;
3864 obj.itemID = Script_item_UUID; 4111 obj.itemID = Script_item_UUID;
3865 if (pass_on == 0 && accept == 0) 4112 if (pass_on == 0 && accept == 0)
3866 { 4113 {
@@ -3909,6 +4156,21 @@ namespace OpenSim.Region.Framework.Scenes
3909 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4156 ControllingClient.SendTakeControls(int.MaxValue, false, false);
3910 } 4157 }
3911 4158
4159 private void UnRegisterSeatControls(UUID obj)
4160 {
4161 List<UUID> takers = new List<UUID>();
4162
4163 foreach (ScriptControllers c in scriptedcontrols.Values)
4164 {
4165 if (c.objectID == obj)
4166 takers.Add(c.itemID);
4167 }
4168 foreach (UUID t in takers)
4169 {
4170 UnRegisterControlEventsToScript(0, t);
4171 }
4172 }
4173
3912 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4174 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
3913 { 4175 {
3914 ScriptControllers takecontrols; 4176 ScriptControllers takecontrols;
@@ -4238,6 +4500,12 @@ namespace OpenSim.Region.Framework.Scenes
4238 4500
4239 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4501 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4240 { 4502 {
4503 string reason;
4504
4505 // Honor bans
4506 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4507 return;
4508
4241 SceneObjectGroup telehub = null; 4509 SceneObjectGroup telehub = null;
4242 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4510 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4243 { 4511 {
@@ -4277,11 +4545,206 @@ namespace OpenSim.Region.Framework.Scenes
4277 pos = land.LandData.UserLocation; 4545 pos = land.LandData.UserLocation;
4278 } 4546 }
4279 } 4547 }
4280 4548
4281 land.SendLandUpdateToClient(ControllingClient); 4549 land.SendLandUpdateToClient(ControllingClient);
4282 } 4550 }
4283 } 4551 }
4284 4552
4553 private DetectedObject CreateDetObject(SceneObjectPart obj)
4554 {
4555 DetectedObject detobj = new DetectedObject();
4556 detobj.keyUUID = obj.UUID;
4557 detobj.nameStr = obj.Name;
4558 detobj.ownerUUID = obj.OwnerID;
4559 detobj.posVector = obj.AbsolutePosition;
4560 detobj.rotQuat = obj.GetWorldRotation();
4561 detobj.velVector = obj.Velocity;
4562 detobj.colliderType = 0;
4563 detobj.groupUUID = obj.GroupID;
4564
4565 return detobj;
4566 }
4567
4568 private DetectedObject CreateDetObject(ScenePresence av)
4569 {
4570 DetectedObject detobj = new DetectedObject();
4571 detobj.keyUUID = av.UUID;
4572 detobj.nameStr = av.ControllingClient.Name;
4573 detobj.ownerUUID = av.UUID;
4574 detobj.posVector = av.AbsolutePosition;
4575 detobj.rotQuat = av.Rotation;
4576 detobj.velVector = av.Velocity;
4577 detobj.colliderType = 0;
4578 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4579
4580 return detobj;
4581 }
4582
4583 private DetectedObject CreateDetObjectForGround()
4584 {
4585 DetectedObject detobj = new DetectedObject();
4586 detobj.keyUUID = UUID.Zero;
4587 detobj.nameStr = "";
4588 detobj.ownerUUID = UUID.Zero;
4589 detobj.posVector = AbsolutePosition;
4590 detobj.rotQuat = Quaternion.Identity;
4591 detobj.velVector = Vector3.Zero;
4592 detobj.colliderType = 0;
4593 detobj.groupUUID = UUID.Zero;
4594
4595 return detobj;
4596 }
4597
4598 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4599 {
4600 ColliderArgs colliderArgs = new ColliderArgs();
4601 List<DetectedObject> colliding = new List<DetectedObject>();
4602 foreach (uint localId in colliders)
4603 {
4604 if (localId == 0)
4605 continue;
4606
4607 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4608 if (obj != null)
4609 {
4610 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4611 colliding.Add(CreateDetObject(obj));
4612 }
4613 else
4614 {
4615 ScenePresence av = m_scene.GetScenePresence(localId);
4616 if (av != null && (!av.IsChildAgent))
4617 {
4618 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4619 colliding.Add(CreateDetObject(av));
4620 }
4621 }
4622 }
4623
4624 colliderArgs.Colliders = colliding;
4625
4626 return colliderArgs;
4627 }
4628
4629 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4630
4631 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4632 {
4633 ColliderArgs CollidingMessage;
4634
4635 if (colliders.Count > 0)
4636 {
4637 if ((dest.RootPart.ScriptEvents & ev) != 0)
4638 {
4639 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4640
4641 if (CollidingMessage.Colliders.Count > 0)
4642 notify(dest.RootPart.LocalId, CollidingMessage);
4643 }
4644 }
4645 }
4646
4647 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4648 {
4649 if ((dest.RootPart.ScriptEvents & ev) != 0)
4650 {
4651 ColliderArgs LandCollidingMessage = new ColliderArgs();
4652 List<DetectedObject> colliding = new List<DetectedObject>();
4653
4654 colliding.Add(CreateDetObjectForGround());
4655 LandCollidingMessage.Colliders = colliding;
4656
4657 notify(dest.RootPart.LocalId, LandCollidingMessage);
4658 }
4659 }
4660
4661 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
4662 {
4663 try
4664 {
4665 List<uint> thisHitColliders = new List<uint>();
4666 List<uint> endedColliders = new List<uint>();
4667 List<uint> startedColliders = new List<uint>();
4668 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
4669 CollisionForSoundInfo soundinfo;
4670 ContactPoint curcontact;
4671
4672 if (coldata.Count == 0)
4673 {
4674 if (m_lastColliders.Count == 0)
4675 return; // nothing to do
4676
4677 foreach (uint localID in m_lastColliders)
4678 {
4679 endedColliders.Add(localID);
4680 }
4681 m_lastColliders.Clear();
4682 }
4683
4684 else
4685 {
4686 foreach (uint id in coldata.Keys)
4687 {
4688 thisHitColliders.Add(id);
4689 if (!m_lastColliders.Contains(id))
4690 {
4691 startedColliders.Add(id);
4692 curcontact = coldata[id];
4693 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
4694 {
4695 soundinfo = new CollisionForSoundInfo();
4696 soundinfo.colliderID = id;
4697 soundinfo.position = curcontact.Position;
4698 soundinfo.relativeVel = curcontact.RelativeSpeed;
4699 soundinfolist.Add(soundinfo);
4700 }
4701 }
4702 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
4703 }
4704
4705 // calculate things that ended colliding
4706 foreach (uint localID in m_lastColliders)
4707 {
4708 if (!thisHitColliders.Contains(localID))
4709 {
4710 endedColliders.Add(localID);
4711 }
4712 }
4713 //add the items that started colliding this time to the last colliders list.
4714 foreach (uint localID in startedColliders)
4715 {
4716 m_lastColliders.Add(localID);
4717 }
4718 // remove things that ended colliding from the last colliders list
4719 foreach (uint localID in endedColliders)
4720 {
4721 m_lastColliders.Remove(localID);
4722 }
4723
4724 if (soundinfolist.Count > 0)
4725 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
4726 }
4727
4728 foreach (SceneObjectGroup att in GetAttachments())
4729 {
4730 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
4731 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
4732 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
4733
4734 if (startedColliders.Contains(0))
4735 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
4736 if (m_lastColliders.Contains(0))
4737 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
4738 if (endedColliders.Contains(0))
4739 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
4740 }
4741 }
4742 finally
4743 {
4744 m_collisionEventFlag = false;
4745 }
4746 }
4747
4285 private void TeleportFlagsDebug() { 4748 private void TeleportFlagsDebug() {
4286 4749
4287 // Some temporary debugging help to show all the TeleportFlags we have... 4750 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4306,6 +4769,5 @@ namespace OpenSim.Region.Framework.Scenes
4306 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4769 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4307 4770
4308 } 4771 }
4309
4310 } 4772 }
4311} 4773}