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.cs1102
1 files changed, 787 insertions, 315 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index ab7fd5b..83bd3fb 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.
@@ -139,6 +140,8 @@ namespace OpenSim.Region.Framework.Scenes
139 private Vector3 m_lastPosition; 140 private Vector3 m_lastPosition;
140 private Quaternion m_lastRotation; 141 private Quaternion m_lastRotation;
141 private Vector3 m_lastVelocity; 142 private Vector3 m_lastVelocity;
143 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
144
142 145
143 private Vector3? m_forceToApply; 146 private Vector3? m_forceToApply;
144 private int m_userFlags; 147 private int m_userFlags;
@@ -171,6 +174,7 @@ namespace OpenSim.Region.Framework.Scenes
171// private int m_lastColCount = -1; //KF: Look for Collision chnages 174// private int m_lastColCount = -1; //KF: Look for Collision chnages
172// private int m_updateCount = 0; //KF: Update Anims for a while 175// private int m_updateCount = 0; //KF: Update Anims for a while
173// 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>();
174 178
175 private TeleportFlags m_teleportFlags; 179 private TeleportFlags m_teleportFlags;
176 public TeleportFlags TeleportFlags 180 public TeleportFlags TeleportFlags
@@ -226,8 +230,6 @@ namespace OpenSim.Region.Framework.Scenes
226 /// </summary> 230 /// </summary>
227 public bool LandAtTarget { get; private set; } 231 public bool LandAtTarget { get; private set; }
228 232
229 private bool m_followCamAuto;
230
231 private int m_movementUpdateCount; 233 private int m_movementUpdateCount;
232 private const int NumMovementsBetweenRayCast = 5; 234 private const int NumMovementsBetweenRayCast = 5;
233 235
@@ -235,6 +237,13 @@ namespace OpenSim.Region.Framework.Scenes
235 //private int m_moveToPositionStateStatus; 237 //private int m_moveToPositionStateStatus;
236 //***************************************************** 238 //*****************************************************
237 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
238 protected AvatarAppearance m_appearance; 247 protected AvatarAppearance m_appearance;
239 248
240 public AvatarAppearance Appearance 249 public AvatarAppearance Appearance
@@ -349,6 +358,9 @@ namespace OpenSim.Region.Framework.Scenes
349 /// </summary> 358 /// </summary>
350 protected Vector3 m_lastCameraPosition; 359 protected Vector3 m_lastCameraPosition;
351 360
361 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
362 private bool m_doingCamRayCast = false;
363
352 public Vector3 CameraPosition { get; set; } 364 public Vector3 CameraPosition { get; set; }
353 365
354 public Quaternion CameraRotation 366 public Quaternion CameraRotation
@@ -429,7 +441,9 @@ namespace OpenSim.Region.Framework.Scenes
429 get { return (IClientCore)ControllingClient; } 441 get { return (IClientCore)ControllingClient; }
430 } 442 }
431 443
432 public Vector3 ParentPosition { get; set; } 444 public UUID COF { get; set; }
445
446// public Vector3 ParentPosition { get; set; }
433 447
434 /// <summary> 448 /// <summary>
435 /// 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
@@ -490,7 +504,7 @@ namespace OpenSim.Region.Framework.Scenes
490 if (ParentID == 0) 504 if (ParentID == 0)
491 { 505 {
492 m_pos = value; 506 m_pos = value;
493 ParentPosition = Vector3.Zero; 507// ParentPosition = Vector3.Zero;
494 } 508 }
495 509
496 //m_log.DebugFormat( 510 //m_log.DebugFormat(
@@ -559,7 +573,24 @@ namespace OpenSim.Region.Framework.Scenes
559// Scene.RegionInfo.RegionName, Name, m_velocity); 573// Scene.RegionInfo.RegionName, Name, m_velocity);
560 } 574 }
561 } 575 }
576/*
577 public override Vector3 AngularVelocity
578 {
579 get
580 {
581 if (PhysicsActor != null)
582 {
583 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
562 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*/
563 private Quaternion m_bodyRot = Quaternion.Identity; 594 private Quaternion m_bodyRot = Quaternion.Identity;
564 595
565 /// <summary> 596 /// <summary>
@@ -582,8 +613,16 @@ namespace OpenSim.Region.Framework.Scenes
582 m_bodyRot = value; 613 m_bodyRot = value;
583 614
584 if (PhysicsActor != null) 615 if (PhysicsActor != null)
585 PhysicsActor.Orientation = m_bodyRot; 616 {
586 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 }
587// 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);
588 } 627 }
589 } 628 }
@@ -597,12 +636,20 @@ namespace OpenSim.Region.Framework.Scenes
597 } 636 }
598 637
599 public bool IsChildAgent { get; set; } 638 public bool IsChildAgent { get; set; }
639 public bool IsLoggingIn { get; set; }
600 640
601 /// <summary> 641 /// <summary>
602 /// 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.
603 /// </summary> 643 /// </summary>
604 public uint ParentID { get; set; } 644 public uint ParentID { get; set; }
605 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
606 /// <summary> 653 /// <summary>
607 /// Are we sitting on an object? 654 /// Are we sitting on an object?
608 /// </summary> 655 /// </summary>
@@ -752,6 +799,7 @@ namespace OpenSim.Region.Framework.Scenes
752 AttachmentsSyncLock = new Object(); 799 AttachmentsSyncLock = new Object();
753 AllowMovement = true; 800 AllowMovement = true;
754 IsChildAgent = true; 801 IsChildAgent = true;
802 IsLoggingIn = false;
755 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 803 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
756 Animator = new ScenePresenceAnimator(this); 804 Animator = new ScenePresenceAnimator(this);
757 PresenceType = type; 805 PresenceType = type;
@@ -795,6 +843,33 @@ namespace OpenSim.Region.Framework.Scenes
795 Appearance = appearance; 843 Appearance = appearance;
796 } 844 }
797 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
798 public void RegisterToEvents() 873 public void RegisterToEvents()
799 { 874 {
800 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 875 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -804,8 +879,10 @@ namespace OpenSim.Region.Framework.Scenes
804 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 879 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
805 ControllingClient.OnStartAnim += HandleStartAnim; 880 ControllingClient.OnStartAnim += HandleStartAnim;
806 ControllingClient.OnStopAnim += HandleStopAnim; 881 ControllingClient.OnStopAnim += HandleStopAnim;
882 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
807 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 883 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
808 ControllingClient.OnAutoPilotGo += MoveToTarget; 884 ControllingClient.OnAutoPilotGo += MoveToTarget;
885 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
809 886
810 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 887 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
811 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 888 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -864,6 +941,38 @@ namespace OpenSim.Region.Framework.Scenes
864 "[SCENE]: Upgrading child to root agent for {0} in {1}", 941 "[SCENE]: Upgrading child to root agent for {0} in {1}",
865 Name, m_scene.RegionInfo.RegionName); 942 Name, m_scene.RegionInfo.RegionName);
866 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
867 //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);
868 977
869 IsChildAgent = false; 978 IsChildAgent = false;
@@ -876,70 +985,106 @@ namespace OpenSim.Region.Framework.Scenes
876 985
877 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 986 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
878 987
879 // Moved this from SendInitialData to ensure that Appearance is initialized 988 UUID groupUUID = UUID.Zero;
880 // before the inventory is processed in MakeRootAgent. This fixes a race condition 989 string GroupName = string.Empty;
881 // related to the handling of attachments 990 ulong groupPowers = 0;
882 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
883 991
884 if (m_scene.TestBorderCross(pos, Cardinals.E)) 992 // ----------------------------------
993 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
994 try
885 { 995 {
886 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 996 if (gm != null)
887 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);
888 } 1008 }
889 1009 catch (Exception e)
890 if (m_scene.TestBorderCross(pos, Cardinals.N))
891 { 1010 {
892 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1011 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
893 pos.Y = crossedBorder.BorderLine.Z - 1;
894 } 1012 }
1013 // ------------------------------------
895 1014
896 CheckAndAdjustLandingPoint(ref pos); 1015 if (ParentID == 0)
897
898 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
899 { 1016 {
900 m_log.WarnFormat( 1017 // Moved this from SendInitialData to ensure that Appearance is initialized
901 "[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
902 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 }
903 1026
904 if (pos.X < 0f) pos.X = 0f; 1027 if (m_scene.TestBorderCross(pos, Cardinals.N))
905 if (pos.Y < 0f) pos.Y = 0f; 1028 {
906 if (pos.Z < 0f) pos.Z = 0f; 1029 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
907 } 1030 pos.Y = crossedBorder.BorderLine.Z - 1;
1031 }
908 1032
909 float localAVHeight = 1.56f; 1033 CheckAndAdjustLandingPoint(ref pos);
910 if (Appearance.AvatarHeight > 0)
911 localAVHeight = Appearance.AvatarHeight;
912 1034
913 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);
914 1040
915 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1041 if (pos.X < 0f) pos.X = 0f;
916 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1042 if (pos.Y < 0f) pos.Y = 0f;
917 1043 if (pos.Z < 0f) pos.Z = 0f;
918 float newPosZ = posZLimit + localAVHeight / 2; 1044 }
919 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
920 {
921 pos.Z = newPosZ;
922 }
923 AbsolutePosition = pos;
924 1045
925 AddToPhysicalScene(isFlying); 1046 float localAVHeight = 1.56f;
1047 if (Appearance.AvatarHeight > 0)
1048 localAVHeight = Appearance.AvatarHeight;
926 1049
927 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1050 float posZLimit = 0;
928 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
929 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
930 // the value to a negative position which does not trigger the border cross.
931 // This may not be the best location for this.
932 CheckForBorderCrossing();
933 1051
934 if (ForceFly) 1052 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
935 { 1053 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
936 Flying = true; 1054
937 } 1055 float newPosZ = posZLimit + localAVHeight / 2;
938 else if (FlyDisabled) 1056 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
939 { 1057 {
940 Flying = false; 1058 pos.Z = newPosZ;
941 } 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);
942 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 }
943 // 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
944 // 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
945 // elsewhere anyway 1090 // elsewhere anyway
@@ -979,15 +1124,20 @@ namespace OpenSim.Region.Framework.Scenes
979 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); 1124 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
980 1125
981 // Resume scripts 1126 // Resume scripts
982 foreach (SceneObjectGroup sog in m_attachments) 1127 Util.FireAndForget(delegate(object x) {
983 { 1128 foreach (SceneObjectGroup sog in m_attachments)
984 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1129 {
985 sog.ResumeScripts(); 1130 sog.ScheduleGroupForFullUpdate();
986 } 1131 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1132 sog.ResumeScripts();
1133 }
1134 });
987 } 1135 }
988 } 1136 }
989 } 1137 }
990 1138
1139 SendAvatarDataToAllAgents();
1140
991 // send the animations of the other presences to me 1141 // send the animations of the other presences to me
992 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1142 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
993 { 1143 {
@@ -998,9 +1148,12 @@ namespace OpenSim.Region.Framework.Scenes
998 // 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
999 // 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
1000 // recorded, which stops the input from being processed. 1150 // recorded, which stops the input from being processed.
1151
1001 MovementFlag = 0; 1152 MovementFlag = 0;
1002 1153
1003 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1154 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1155
1156 m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
1004 } 1157 }
1005 1158
1006 public int GetStateSource() 1159 public int GetStateSource()
@@ -1028,12 +1181,16 @@ namespace OpenSim.Region.Framework.Scenes
1028 /// </remarks> 1181 /// </remarks>
1029 public void MakeChildAgent() 1182 public void MakeChildAgent()
1030 { 1183 {
1184 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1185
1031 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);
1032 1187
1033 // 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
1034 // as teleporting back 1189 // as teleporting back
1035 TeleportFlags = TeleportFlags.Default; 1190 TeleportFlags = TeleportFlags.Default;
1036 1191
1192 MovementFlag = 0;
1193
1037 // It looks like Animator is set to null somewhere, and MakeChild 1194 // It looks like Animator is set to null somewhere, and MakeChild
1038 // is called after that. Probably in aborted teleports. 1195 // is called after that. Probably in aborted teleports.
1039 if (Animator == null) 1196 if (Animator == null)
@@ -1041,6 +1198,7 @@ namespace OpenSim.Region.Framework.Scenes
1041 else 1198 else
1042 Animator.ResetAnimations(); 1199 Animator.ResetAnimations();
1043 1200
1201
1044// m_log.DebugFormat( 1202// m_log.DebugFormat(
1045// "[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}",
1046// Name, UUID, m_scene.RegionInfo.RegionName); 1204// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1052,6 +1210,7 @@ namespace OpenSim.Region.Framework.Scenes
1052 IsChildAgent = true; 1210 IsChildAgent = true;
1053 m_scene.SwapRootAgentCount(true); 1211 m_scene.SwapRootAgentCount(true);
1054 RemoveFromPhysicalScene(); 1212 RemoveFromPhysicalScene();
1213 ParentID = 0; // Child agents can't be sitting
1055 1214
1056 // 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
1057 1216
@@ -1067,9 +1226,9 @@ namespace OpenSim.Region.Framework.Scenes
1067 { 1226 {
1068// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1227// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1069 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1228 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1070 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1071 PhysicsActor.UnSubscribeEvents();
1072 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1229 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1230 PhysicsActor.UnSubscribeEvents();
1231 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1073 PhysicsActor = null; 1232 PhysicsActor = null;
1074 } 1233 }
1075// else 1234// else
@@ -1086,7 +1245,7 @@ namespace OpenSim.Region.Framework.Scenes
1086 /// <param name="pos"></param> 1245 /// <param name="pos"></param>
1087 public void Teleport(Vector3 pos) 1246 public void Teleport(Vector3 pos)
1088 { 1247 {
1089 TeleportWithMomentum(pos, null); 1248 TeleportWithMomentum(pos, Vector3.Zero);
1090 } 1249 }
1091 1250
1092 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1251 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1110,6 +1269,41 @@ namespace OpenSim.Region.Framework.Scenes
1110 SendTerseUpdateToAllClients(); 1269 SendTerseUpdateToAllClients();
1111 } 1270 }
1112 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
1113 public void StopFlying() 1307 public void StopFlying()
1114 { 1308 {
1115 ControllingClient.StopFlying(this); 1309 ControllingClient.StopFlying(this);
@@ -1279,6 +1473,13 @@ namespace OpenSim.Region.Framework.Scenes
1279 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1473 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1280 } 1474 }
1281 1475
1476 public void SetSize(Vector3 size, float feetoffset)
1477 {
1478 if (PhysicsActor != null && !IsChildAgent)
1479 PhysicsActor.setAvatarSize(size, feetoffset);
1480
1481 }
1482
1282 /// <summary> 1483 /// <summary>
1283 /// Complete Avatar's movement into the region. 1484 /// Complete Avatar's movement into the region.
1284 /// </summary> 1485 /// </summary>
@@ -1298,7 +1499,8 @@ namespace OpenSim.Region.Framework.Scenes
1298 1499
1299 Vector3 look = Velocity; 1500 Vector3 look = Velocity;
1300 1501
1301 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))
1302 { 1504 {
1303 look = new Vector3(0.99f, 0.042f, 0); 1505 look = new Vector3(0.99f, 0.042f, 0);
1304 } 1506 }
@@ -1353,11 +1555,12 @@ namespace OpenSim.Region.Framework.Scenes
1353 1555
1354 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1556 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1355 if (m_agentTransfer != null) 1557 if (m_agentTransfer != null)
1356 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1558 m_agentTransfer.EnableChildAgents(this);
1357 1559
1358 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1560 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1359 if (friendsModule != null) 1561 if (friendsModule != null)
1360 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1562 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1563
1361 } 1564 }
1362 1565
1363 // 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
@@ -1382,36 +1585,69 @@ namespace OpenSim.Region.Framework.Scenes
1382 /// <param name="collisionPoint"></param> 1585 /// <param name="collisionPoint"></param>
1383 /// <param name="localid"></param> 1586 /// <param name="localid"></param>
1384 /// <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
1385 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)
1386 { 1600 {
1387 const float POSITION_TOLERANCE = 0.02f; 1601 const float POSITION_TOLERANCE = 0.02f;
1388 const float VELOCITY_TOLERANCE = 0.02f;
1389 const float ROTATION_TOLERANCE = 0.02f; 1602 const float ROTATION_TOLERANCE = 0.02f;
1390 1603
1391 if (m_followCamAuto) 1604 m_doingCamRayCast = false;
1605 if (hitYN && localid != LocalId)
1392 { 1606 {
1393 if (hitYN) 1607 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1608 bool IsPrim = group != null;
1609 if (IsPrim)
1394 { 1610 {
1395 CameraConstraintActive = true; 1611 SceneObjectPart part = group.GetPart(localid);
1396 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1612 if (part != null && !part.VolumeDetectActive)
1397 1613 {
1398 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1614 CameraConstraintActive = true;
1399 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 }
1400 } 1627 }
1401 else 1628 else
1402 { 1629 {
1403 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1630 CameraConstraintActive = true;
1404 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1631 pNormal.X = (float) Math.Round(pNormal.X, 2);
1405 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1632 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1406 { 1633 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1407 if (CameraConstraintActive) 1634 pNormal.Normalize();
1408 { 1635 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1409 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1636 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1410 CameraConstraintActive = false; 1637 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1411 } 1638
1412 } 1639 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1640 Vector3.Dot(collisionPoint, pNormal));
1641 UpdateCameraCollisionPlane(plane);
1413 } 1642 }
1414 } 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 }
1415 } 1651 }
1416 1652
1417 /// <summary> 1653 /// <summary>
@@ -1485,12 +1721,6 @@ namespace OpenSim.Region.Framework.Scenes
1485 // DrawDistance = agentData.Far; 1721 // DrawDistance = agentData.Far;
1486 DrawDistance = Scene.DefaultDrawDistance; 1722 DrawDistance = Scene.DefaultDrawDistance;
1487 1723
1488 // Check if Client has camera in 'follow cam' or 'build' mode.
1489 Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
1490
1491 m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
1492 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
1493
1494 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; 1724 m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
1495 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; 1725 m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
1496 1726
@@ -1510,14 +1740,38 @@ namespace OpenSim.Region.Framework.Scenes
1510 StandUp(); 1740 StandUp();
1511 } 1741 }
1512 1742
1513 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
1514 // 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
1515 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())
1516 { 1747 {
1517 if (m_followCamAuto) 1748 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1749 {
1750 Vector3 posAdjusted = AbsolutePosition;
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))
1518 { 1771 {
1519 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; 1772 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1520 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback); 1773 UpdateCameraCollisionPlane(plane);
1774 CameraConstraintActive = false;
1521 } 1775 }
1522 } 1776 }
1523 1777
@@ -1982,7 +2236,8 @@ namespace OpenSim.Region.Framework.Scenes
1982// 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);
1983 2237
1984 MovingToTarget = false; 2238 MovingToTarget = false;
1985 MoveToPositionTarget = Vector3.Zero; 2239// MoveToPositionTarget = Vector3.Zero;
2240 m_forceToApply = null; // cancel possible last action
1986 2241
1987 // 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
1988 // 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.
@@ -2000,12 +2255,17 @@ namespace OpenSim.Region.Framework.Scenes
2000// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2255// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
2001 2256
2002 SitGround = false; 2257 SitGround = false;
2258
2259/* move this down so avatar gets physical in the new position and not where it is siting
2003 if (PhysicsActor == null) 2260 if (PhysicsActor == null)
2004 AddToPhysicalScene(false); 2261 AddToPhysicalScene(false);
2262 */
2005 2263
2006 if (ParentID != 0) 2264 if (ParentID != 0)
2007 { 2265 {
2008 SceneObjectPart part = ParentPart; 2266 SceneObjectPart part = ParentPart;
2267 UnRegisterSeatControls(part.ParentGroup.UUID);
2268
2009 TaskInventoryDictionary taskIDict = part.TaskInventory; 2269 TaskInventoryDictionary taskIDict = part.TaskInventory;
2010 if (taskIDict != null) 2270 if (taskIDict != null)
2011 { 2271 {
@@ -2021,14 +2281,22 @@ namespace OpenSim.Region.Framework.Scenes
2021 } 2281 }
2022 } 2282 }
2023 2283
2024 ParentPosition = part.GetWorldPosition(); 2284 part.ParentGroup.DeleteAvatar(UUID);
2285// ParentPosition = part.GetWorldPosition();
2025 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2286 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2026 2287
2027 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);
2028 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;
2029 2293
2030 ParentID = 0; 2294 ParentID = 0;
2031 ParentPart = null; 2295 ParentPart = null;
2296
2297 if (PhysicsActor == null)
2298 AddToPhysicalScene(false);
2299
2032 SendAvatarDataToAllAgents(); 2300 SendAvatarDataToAllAgents();
2033 m_requestedSitTargetID = 0; 2301 m_requestedSitTargetID = 0;
2034 2302
@@ -2038,6 +2306,9 @@ namespace OpenSim.Region.Framework.Scenes
2038 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2306 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2039 } 2307 }
2040 2308
2309 else if (PhysicsActor == null)
2310 AddToPhysicalScene(false);
2311
2041 Animator.TrySetMovementAnimation("STAND"); 2312 Animator.TrySetMovementAnimation("STAND");
2042 } 2313 }
2043 2314
@@ -2085,11 +2356,8 @@ namespace OpenSim.Region.Framework.Scenes
2085 if (part == null) 2356 if (part == null)
2086 return; 2357 return;
2087 2358
2088 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2089 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2090
2091 if (PhysicsActor != null) 2359 if (PhysicsActor != null)
2092 m_sitAvatarHeight = PhysicsActor.Size.Z; 2360 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2093 2361
2094 bool canSit = false; 2362 bool canSit = false;
2095 Vector3 pos = part.AbsolutePosition + offset; 2363 Vector3 pos = part.AbsolutePosition + offset;
@@ -2106,31 +2374,31 @@ namespace OpenSim.Region.Framework.Scenes
2106 } 2374 }
2107 else 2375 else
2108 { 2376 {
2377 if (PhysicsSit(part,offset)) // physics engine
2378 return;
2379
2109 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2380 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2110 { 2381 {
2111// m_log.DebugFormat(
2112// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2113// Name, part.Name, part.LocalId);
2114 2382
2115 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2383 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2116 canSit = true; 2384 canSit = true;
2117 } 2385 }
2118// else
2119// {
2120// m_log.DebugFormat(
2121// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2122// Name, part.Name, part.LocalId);
2123// }
2124 } 2386 }
2125 2387
2126 if (canSit) 2388 if (canSit)
2127 { 2389 {
2390
2128 if (PhysicsActor != null) 2391 if (PhysicsActor != null)
2129 { 2392 {
2130 // We can remove the physicsActor until they stand up. 2393 // We can remove the physicsActor until they stand up.
2131 RemoveFromPhysicalScene(); 2394 RemoveFromPhysicalScene();
2132 } 2395 }
2133 2396
2397 if (MovingToTarget)
2398 ResetMoveToTarget();
2399
2400 Velocity = Vector3.Zero;
2401
2134 part.AddSittingAvatar(UUID); 2402 part.AddSittingAvatar(UUID);
2135 2403
2136 cameraAtOffset = part.GetCameraAtOffset(); 2404 cameraAtOffset = part.GetCameraAtOffset();
@@ -2138,7 +2406,7 @@ namespace OpenSim.Region.Framework.Scenes
2138 forceMouselook = part.GetForceMouselook(); 2406 forceMouselook = part.GetForceMouselook();
2139 2407
2140 ControllingClient.SendSitResponse( 2408 ControllingClient.SendSitResponse(
2141 targetID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 2409 part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2142 2410
2143 m_requestedSitTargetUUID = targetID; 2411 m_requestedSitTargetUUID = targetID;
2144 2412
@@ -2152,6 +2420,9 @@ namespace OpenSim.Region.Framework.Scenes
2152 2420
2153 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2421 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2154 { 2422 {
2423 if (IsChildAgent)
2424 return;
2425
2155 if (ParentID != 0) 2426 if (ParentID != 0)
2156 { 2427 {
2157 if (ParentPart.UUID == targetID) 2428 if (ParentPart.UUID == targetID)
@@ -2167,14 +2438,6 @@ namespace OpenSim.Region.Framework.Scenes
2167 m_requestedSitTargetID = part.LocalId; 2438 m_requestedSitTargetID = part.LocalId;
2168 m_requestedSitTargetUUID = targetID; 2439 m_requestedSitTargetUUID = targetID;
2169 2440
2170// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2171
2172 if (m_scene.PhysicsScene.SupportsRayCast())
2173 {
2174 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2175 //SitRayCastAvatarPosition(part);
2176 //return;
2177 }
2178 } 2441 }
2179 else 2442 else
2180 { 2443 {
@@ -2184,197 +2447,111 @@ namespace OpenSim.Region.Framework.Scenes
2184 SendSitResponse(targetID, offset, Quaternion.Identity); 2447 SendSitResponse(targetID, offset, Quaternion.Identity);
2185 } 2448 }
2186 2449
2187 /* 2450 // returns false if does not suport so older sit can be tried
2188 public void SitRayCastAvatarPosition(SceneObjectPart part) 2451 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2189 {
2190 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2191 Vector3 StartRayCastPosition = AbsolutePosition;
2192 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2193 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2194 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2195 }
2196
2197 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2198 { 2452 {
2199 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2453 if (part == null || part.ParentGroup.IsAttachment)
2200 if (part != null)
2201 {
2202 if (hitYN)
2203 {
2204 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2205 {
2206 SitRaycastFindEdge(collisionPoint, normal);
2207 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2208 }
2209 else
2210 {
2211 SitRayCastAvatarPositionCameraZ(part);
2212 }
2213 }
2214 else
2215 {
2216 SitRayCastAvatarPositionCameraZ(part);
2217 }
2218 }
2219 else
2220 { 2454 {
2221 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2455 return true;
2222 m_requestedSitTargetUUID = UUID.Zero;
2223 m_requestedSitTargetID = 0;
2224 m_requestedSitOffset = Vector3.Zero;
2225 } 2456 }
2226 2457
2227 } 2458 if ( m_scene.PhysicsScene == null)
2228 2459 return false;
2229 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2230 {
2231 // Next, try to raycast from the camera Z position
2232 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2233 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2234 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2235 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2236 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2237 }
2238 2460
2239 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2461 if (part.PhysActor == null)
2240 {
2241 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2242 if (part != null)
2243 { 2462 {
2244 if (hitYN) 2463 // none physcis shape
2245 { 2464 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2246 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2465 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2247 {
2248 SitRaycastFindEdge(collisionPoint, normal);
2249 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2250 }
2251 else
2252 {
2253 SitRayCastCameraPosition(part);
2254 }
2255 }
2256 else 2466 else
2257 { 2467 { // non physical phantom TODO
2258 SitRayCastCameraPosition(part); 2468 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2469 return false;
2259 } 2470 }
2260 } 2471 return true;
2261 else
2262 {
2263 ControllingClient.SendAlertMessage("Sit position no longer exists");
2264 m_requestedSitTargetUUID = UUID.Zero;
2265 m_requestedSitTargetID = 0;
2266 m_requestedSitOffset = Vector3.Zero;
2267 } 2472 }
2268 2473
2269 }
2270 2474
2271 public void SitRayCastCameraPosition(SceneObjectPart part) 2475 // not doing autopilot
2272 { 2476 m_requestedSitTargetID = 0;
2273 // Next, try to raycast from the camera position
2274 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2275 Vector3 StartRayCastPosition = CameraPosition;
2276 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2277 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2278 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2279 }
2280 2477
2281 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2478 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2282 { 2479 return true;
2283 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2284 if (part != null)
2285 {
2286 if (hitYN)
2287 {
2288 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2289 {
2290 SitRaycastFindEdge(collisionPoint, normal);
2291 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2292 }
2293 else
2294 {
2295 SitRayHorizontal(part);
2296 }
2297 }
2298 else
2299 {
2300 SitRayHorizontal(part);
2301 }
2302 }
2303 else
2304 {
2305 ControllingClient.SendAlertMessage("Sit position no longer exists");
2306 m_requestedSitTargetUUID = UUID.Zero;
2307 m_requestedSitTargetID = 0;
2308 m_requestedSitOffset = Vector3.Zero;
2309 }
2310 2480
2481 return false;
2311 } 2482 }
2312 2483
2313 public void SitRayHorizontal(SceneObjectPart part) 2484
2485 private bool CanEnterLandPosition(Vector3 testPos)
2314 { 2486 {
2315 // Next, try to raycast from the avatar position to fwd 2487 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2316 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2488
2317 Vector3 StartRayCastPosition = CameraPosition; 2489 if (land == null || land.LandData.Name == "NO_LAND")
2318 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2490 return true;
2319 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2491
2320 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2492 return land.CanBeOnThisLand(UUID,testPos.Z);
2321 } 2493 }
2322 2494
2323 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2495 // status
2496 // < 0 ignore
2497 // 0 bad sit spot
2498 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2324 { 2499 {
2325 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2500 if (status < 0)
2326 if (part != null) 2501 return;
2502
2503 if (status == 0)
2327 { 2504 {
2328 if (hitYN) 2505 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2329 { 2506 return;
2330 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2331 {
2332 SitRaycastFindEdge(collisionPoint, normal);
2333 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2334 // Next, try to raycast from the camera position
2335 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2336 Vector3 StartRayCastPosition = CameraPosition;
2337 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2338 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2339 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2340 }
2341 else
2342 {
2343 ControllingClient.SendAlertMessage("Sit position not accessable.");
2344 m_requestedSitTargetUUID = UUID.Zero;
2345 m_requestedSitTargetID = 0;
2346 m_requestedSitOffset = Vector3.Zero;
2347 }
2348 }
2349 else
2350 {
2351 ControllingClient.SendAlertMessage("Sit position not accessable.");
2352 m_requestedSitTargetUUID = UUID.Zero;
2353 m_requestedSitTargetID = 0;
2354 m_requestedSitOffset = Vector3.Zero;
2355 }
2356 } 2507 }
2357 else 2508
2509 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2510 if (part == null)
2511 return;
2512
2513 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2514 if(!CanEnterLandPosition(targetPos))
2358 { 2515 {
2359 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2516 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2360 m_requestedSitTargetUUID = UUID.Zero; 2517 return;
2361 m_requestedSitTargetID = 0;
2362 m_requestedSitOffset = Vector3.Zero;
2363 } 2518 }
2364 2519
2365 } 2520 RemoveFromPhysicalScene();
2366 2521
2367 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2522 if (MovingToTarget)
2368 { 2523 ResetMoveToTarget();
2369 int i = 0; 2524
2370 //throw new NotImplementedException(); 2525 Velocity = Vector3.Zero;
2371 //m_requestedSitTargetUUID = UUID.Zero; 2526
2372 //m_requestedSitTargetID = 0; 2527 part.AddSittingAvatar(UUID);
2373 //m_requestedSitOffset = Vector3.Zero; 2528
2529 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2530 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2531 bool forceMouselook = part.GetForceMouselook();
2374 2532
2375 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2533 ControllingClient.SendSitResponse(
2534 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2535
2536 // not using autopilot
2537
2538 Rotation = Orientation;
2539 m_pos = offset;
2540
2541 m_requestedSitTargetID = 0;
2542 part.ParentGroup.AddAvatar(UUID);
2543
2544 ParentPart = part;
2545 ParentID = part.LocalId;
2546 if(status == 3)
2547 Animator.TrySetMovementAnimation("SIT_GROUND");
2548 else
2549 Animator.TrySetMovementAnimation("SIT");
2550 SendAvatarDataToAllAgents();
2551
2552 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2376 } 2553 }
2377 */ 2554
2378 2555
2379 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2556 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2380 { 2557 {
@@ -2391,6 +2568,7 @@ namespace OpenSim.Region.Framework.Scenes
2391 return; 2568 return;
2392 } 2569 }
2393 2570
2571
2394 if (part.SitTargetAvatar == UUID) 2572 if (part.SitTargetAvatar == UUID)
2395 { 2573 {
2396 Vector3 sitTargetPos = part.SitTargetPosition; 2574 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2405,14 +2583,39 @@ namespace OpenSim.Region.Framework.Scenes
2405 2583
2406 //Quaternion result = (sitTargetOrient * vq) * nq; 2584 //Quaternion result = (sitTargetOrient * vq) * nq;
2407 2585
2408 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2586 double x, y, z, m;
2587
2588 Quaternion r = sitTargetOrient;
2589 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2590
2591 if (Math.Abs(1.0 - m) > 0.000001)
2592 {
2593 m = 1.0 / Math.Sqrt(m);
2594 r.X *= (float)m;
2595 r.Y *= (float)m;
2596 r.Z *= (float)m;
2597 r.W *= (float)m;
2598 }
2599
2600 x = 2 * (r.X * r.Z + r.Y * r.W);
2601 y = 2 * (-r.X * r.W + r.Y * r.Z);
2602 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2603
2604 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2605 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2606
2607 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2608
2609// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2409 Rotation = sitTargetOrient; 2610 Rotation = sitTargetOrient;
2410 ParentPosition = part.AbsolutePosition; 2611// ParentPosition = part.AbsolutePosition;
2612 part.ParentGroup.AddAvatar(UUID);
2411 } 2613 }
2412 else 2614 else
2413 { 2615 {
2414 m_pos -= part.AbsolutePosition; 2616 m_pos -= part.AbsolutePosition;
2415 ParentPosition = part.AbsolutePosition; 2617// ParentPosition = part.AbsolutePosition;
2618 part.ParentGroup.AddAvatar(UUID);
2416 2619
2417// m_log.DebugFormat( 2620// m_log.DebugFormat(
2418// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2621// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2463,6 +2666,13 @@ namespace OpenSim.Region.Framework.Scenes
2463 Animator.RemoveAnimation(animID, false); 2666 Animator.RemoveAnimation(animID, false);
2464 } 2667 }
2465 2668
2669 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
2670 {
2671 Animator.avnChangeAnim(animID, addRemove, sendPack);
2672 }
2673
2674
2675
2466 /// <summary> 2676 /// <summary>
2467 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2677 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2468 /// </summary> 2678 /// </summary>
@@ -2519,8 +2729,8 @@ namespace OpenSim.Region.Framework.Scenes
2519 direc.Z *= 2.6f; 2729 direc.Z *= 2.6f;
2520 2730
2521 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2731 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2522 Animator.TrySetMovementAnimation("PREJUMP"); 2732// Animator.TrySetMovementAnimation("PREJUMP");
2523 Animator.TrySetMovementAnimation("JUMP"); 2733// Animator.TrySetMovementAnimation("JUMP");
2524 } 2734 }
2525 } 2735 }
2526 } 2736 }
@@ -2529,6 +2739,7 @@ namespace OpenSim.Region.Framework.Scenes
2529 2739
2530 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2740 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2531 m_forceToApply = direc; 2741 m_forceToApply = direc;
2742 Animator.UpdateMovementAnimations();
2532 } 2743 }
2533 2744
2534 #endregion 2745 #endregion
@@ -2546,16 +2757,12 @@ namespace OpenSim.Region.Framework.Scenes
2546 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 2757 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2547 // grab the latest PhysicsActor velocity, whereas m_velocity is often 2758 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2548 // storing a requested force instead of an actual traveling velocity 2759 // storing a requested force instead of an actual traveling velocity
2760 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
2761 SendAvatarDataToAllAgents();
2549 2762
2550 // Throw away duplicate or insignificant updates 2763 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2551 if ( 2764 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2552 // If the velocity has become zero, send it no matter what. 2765 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2553 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2554 // otherwise, if things have changed reasonably, send the update
2555 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2556 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2557 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2558
2559 { 2766 {
2560 SendTerseUpdateToAllClients(); 2767 SendTerseUpdateToAllClients();
2561 2768
@@ -2713,9 +2920,7 @@ namespace OpenSim.Region.Framework.Scenes
2713 // again here... this comes after the cached appearance check because the avatars 2920 // again here... this comes after the cached appearance check because the avatars
2714 // appearance goes into the avatar update packet 2921 // appearance goes into the avatar update packet
2715 SendAvatarDataToAllAgents(); 2922 SendAvatarDataToAllAgents();
2716 2923 SendAppearanceToAgent(this);
2717 // This invocation always shows up in the viewer logs as an error.
2718 // SendAppearanceToAgent(this);
2719 2924
2720 // If we are using the the cached appearance then send it out to everyone 2925 // If we are using the the cached appearance then send it out to everyone
2721 if (cachedappearance) 2926 if (cachedappearance)
@@ -2746,6 +2951,8 @@ namespace OpenSim.Region.Framework.Scenes
2746 return; 2951 return;
2747 } 2952 }
2748 2953
2954 m_lastSize = Appearance.AvatarSize;
2955
2749 int count = 0; 2956 int count = 0;
2750 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2957 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2751 { 2958 {
@@ -2853,6 +3060,8 @@ namespace OpenSim.Region.Framework.Scenes
2853 3060
2854 avatar.ControllingClient.SendAppearance( 3061 avatar.ControllingClient.SendAppearance(
2855 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3062 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3063
3064
2856 } 3065 }
2857 3066
2858 #endregion 3067 #endregion
@@ -2927,8 +3136,9 @@ namespace OpenSim.Region.Framework.Scenes
2927 3136
2928 // If we don't have a PhysActor, we can't cross anyway 3137 // If we don't have a PhysActor, we can't cross anyway
2929 // Also don't do this while sat, sitting avatars cross with the 3138 // Also don't do this while sat, sitting avatars cross with the
2930 // object they sit on. 3139 // object they sit on. ParentUUID denoted a pending sit, don't
2931 if (ParentID != 0 || PhysicsActor == null) 3140 // interfere with it.
3141 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
2932 return; 3142 return;
2933 3143
2934 if (!IsInTransit) 3144 if (!IsInTransit)
@@ -3191,6 +3401,10 @@ namespace OpenSim.Region.Framework.Scenes
3191 } 3401 }
3192 3402
3193 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3403 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3404 private void RaiseUpdateThrottles()
3405 {
3406 m_scene.EventManager.TriggerThrottleUpdate(this);
3407 }
3194 /// <summary> 3408 /// <summary>
3195 /// This updates important decision making data about a child agent 3409 /// This updates important decision making data about a child agent
3196 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3410 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3271,6 +3485,9 @@ namespace OpenSim.Region.Framework.Scenes
3271 cAgent.AlwaysRun = SetAlwaysRun; 3485 cAgent.AlwaysRun = SetAlwaysRun;
3272 3486
3273 cAgent.Appearance = new AvatarAppearance(Appearance); 3487 cAgent.Appearance = new AvatarAppearance(Appearance);
3488
3489 cAgent.ParentPart = ParentUUID;
3490 cAgent.SitOffset = m_pos;
3274 3491
3275 lock (scriptedcontrols) 3492 lock (scriptedcontrols)
3276 { 3493 {
@@ -3279,7 +3496,7 @@ namespace OpenSim.Region.Framework.Scenes
3279 3496
3280 foreach (ScriptControllers c in scriptedcontrols.Values) 3497 foreach (ScriptControllers c in scriptedcontrols.Values)
3281 { 3498 {
3282 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3499 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3283 } 3500 }
3284 cAgent.Controllers = controls; 3501 cAgent.Controllers = controls;
3285 } 3502 }
@@ -3312,6 +3529,8 @@ namespace OpenSim.Region.Framework.Scenes
3312 CameraAtAxis = cAgent.AtAxis; 3529 CameraAtAxis = cAgent.AtAxis;
3313 CameraLeftAxis = cAgent.LeftAxis; 3530 CameraLeftAxis = cAgent.LeftAxis;
3314 CameraUpAxis = cAgent.UpAxis; 3531 CameraUpAxis = cAgent.UpAxis;
3532 ParentUUID = cAgent.ParentPart;
3533 m_prevSitOffset = cAgent.SitOffset;
3315 3534
3316 // When we get to the point of re-computing neighbors everytime this 3535 // When we get to the point of re-computing neighbors everytime this
3317 // changes, then start using the agent's drawdistance rather than the 3536 // changes, then start using the agent's drawdistance rather than the
@@ -3349,6 +3568,7 @@ namespace OpenSim.Region.Framework.Scenes
3349 foreach (ControllerData c in cAgent.Controllers) 3568 foreach (ControllerData c in cAgent.Controllers)
3350 { 3569 {
3351 ScriptControllers sc = new ScriptControllers(); 3570 ScriptControllers sc = new ScriptControllers();
3571 sc.objectID = c.ObjectID;
3352 sc.itemID = c.ItemID; 3572 sc.itemID = c.ItemID;
3353 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3573 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3354 sc.eventControls = (ScriptControlled)c.EventControls; 3574 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3416,20 +3636,27 @@ namespace OpenSim.Region.Framework.Scenes
3416 } 3636 }
3417 3637
3418 if (Appearance.AvatarHeight == 0) 3638 if (Appearance.AvatarHeight == 0)
3419 Appearance.SetHeight(); 3639// Appearance.SetHeight();
3640 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3420 3641
3421 PhysicsScene scene = m_scene.PhysicsScene; 3642 PhysicsScene scene = m_scene.PhysicsScene;
3422 3643
3423 Vector3 pVec = AbsolutePosition; 3644 Vector3 pVec = AbsolutePosition;
3424 3645
3646/*
3425 PhysicsActor = scene.AddAvatar( 3647 PhysicsActor = scene.AddAvatar(
3426 LocalId, Firstname + "." + Lastname, pVec, 3648 LocalId, Firstname + "." + Lastname, pVec,
3427 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3649 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3650*/
3651
3652 PhysicsActor = scene.AddAvatar(
3653 LocalId, Firstname + "." + Lastname, pVec,
3654 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
3428 3655
3429 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3656 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3430 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3657 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3431 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3658 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3432 PhysicsActor.SubscribeEvents(500); 3659 PhysicsActor.SubscribeEvents(100);
3433 PhysicsActor.LocalID = LocalId; 3660 PhysicsActor.LocalID = LocalId;
3434 } 3661 }
3435 3662
@@ -3443,6 +3670,7 @@ namespace OpenSim.Region.Framework.Scenes
3443 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3670 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3444 } 3671 }
3445 3672
3673
3446 /// <summary> 3674 /// <summary>
3447 /// Event called by the physics plugin to tell the avatar about a collision. 3675 /// Event called by the physics plugin to tell the avatar about a collision.
3448 /// </summary> 3676 /// </summary>
@@ -3456,7 +3684,7 @@ namespace OpenSim.Region.Framework.Scenes
3456 /// <param name="e"></param> 3684 /// <param name="e"></param>
3457 public void PhysicsCollisionUpdate(EventArgs e) 3685 public void PhysicsCollisionUpdate(EventArgs e)
3458 { 3686 {
3459 if (IsChildAgent) 3687 if (IsChildAgent || Animator == null)
3460 return; 3688 return;
3461 3689
3462 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3690 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3472,7 +3700,6 @@ namespace OpenSim.Region.Framework.Scenes
3472 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3700 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3473 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3701 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3474 3702
3475 CollisionPlane = Vector4.UnitW;
3476 3703
3477// // No collisions at all means we may be flying. Update always 3704// // No collisions at all means we may be flying. Update always
3478// // to make falling work 3705// // to make falling work
@@ -3484,6 +3711,7 @@ namespace OpenSim.Region.Framework.Scenes
3484 3711
3485 if (coldata.Count != 0) 3712 if (coldata.Count != 0)
3486 { 3713 {
3714/*
3487 switch (Animator.CurrentMovementAnimation) 3715 switch (Animator.CurrentMovementAnimation)
3488 { 3716 {
3489 case "STAND": 3717 case "STAND":
@@ -3492,24 +3720,38 @@ namespace OpenSim.Region.Framework.Scenes
3492 case "CROUCH": 3720 case "CROUCH":
3493 case "CROUCHWALK": 3721 case "CROUCHWALK":
3494 { 3722 {
3723 */
3495 ContactPoint lowest; 3724 ContactPoint lowest;
3496 lowest.SurfaceNormal = Vector3.Zero; 3725 lowest.SurfaceNormal = Vector3.Zero;
3497 lowest.Position = Vector3.Zero; 3726 lowest.Position = Vector3.Zero;
3498 lowest.Position.Z = Single.NaN; 3727 lowest.Position.Z = float.MaxValue;
3499 3728
3500 foreach (ContactPoint contact in coldata.Values) 3729 foreach (ContactPoint contact in coldata.Values)
3501 { 3730 {
3502 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 3731
3732 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3503 { 3733 {
3504 lowest = contact; 3734 lowest = contact;
3505 } 3735 }
3506 } 3736 }
3507 3737
3508 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 3738 if (lowest.Position.Z != float.MaxValue)
3739 {
3740 lowest.SurfaceNormal = -lowest.SurfaceNormal;
3741 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3742 }
3743 else
3744 CollisionPlane = Vector4.UnitW;
3745/*
3509 } 3746 }
3510 break; 3747 break;
3511 } 3748 }
3749*/
3512 } 3750 }
3751 else
3752 CollisionPlane = Vector4.UnitW;
3753
3754 RaiseCollisionScriptEvents(coldata);
3513 3755
3514 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3756 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3515 if (Invulnerable || GodLevel > 0) 3757 if (Invulnerable || GodLevel > 0)
@@ -3608,6 +3850,13 @@ namespace OpenSim.Region.Framework.Scenes
3608 // m_reprioritizationTimer.Dispose(); 3850 // m_reprioritizationTimer.Dispose();
3609 3851
3610 RemoveFromPhysicalScene(); 3852 RemoveFromPhysicalScene();
3853
3854 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
3855
3856// if (Animator != null)
3857// Animator.Close();
3858 Animator = null;
3859
3611 } 3860 }
3612 3861
3613 public void AddAttachment(SceneObjectGroup gobj) 3862 public void AddAttachment(SceneObjectGroup gobj)
@@ -3841,10 +4090,18 @@ namespace OpenSim.Region.Framework.Scenes
3841 4090
3842 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4091 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
3843 { 4092 {
4093 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4094 if (p == null)
4095 return;
4096
4097 ControllingClient.SendTakeControls(controls, false, false);
4098 ControllingClient.SendTakeControls(controls, true, false);
4099
3844 ScriptControllers obj = new ScriptControllers(); 4100 ScriptControllers obj = new ScriptControllers();
3845 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4101 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
3846 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4102 obj.eventControls = ScriptControlled.CONTROL_ZERO;
3847 4103
4104 obj.objectID = p.ParentGroup.UUID;
3848 obj.itemID = Script_item_UUID; 4105 obj.itemID = Script_item_UUID;
3849 if (pass_on == 0 && accept == 0) 4106 if (pass_on == 0 && accept == 0)
3850 { 4107 {
@@ -3893,6 +4150,21 @@ namespace OpenSim.Region.Framework.Scenes
3893 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4150 ControllingClient.SendTakeControls(int.MaxValue, false, false);
3894 } 4151 }
3895 4152
4153 private void UnRegisterSeatControls(UUID obj)
4154 {
4155 List<UUID> takers = new List<UUID>();
4156
4157 foreach (ScriptControllers c in scriptedcontrols.Values)
4158 {
4159 if (c.objectID == obj)
4160 takers.Add(c.itemID);
4161 }
4162 foreach (UUID t in takers)
4163 {
4164 UnRegisterControlEventsToScript(0, t);
4165 }
4166 }
4167
3896 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4168 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
3897 { 4169 {
3898 ScriptControllers takecontrols; 4170 ScriptControllers takecontrols;
@@ -4222,6 +4494,12 @@ namespace OpenSim.Region.Framework.Scenes
4222 4494
4223 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4495 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4224 { 4496 {
4497 string reason;
4498
4499 // Honor bans
4500 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4501 return;
4502
4225 SceneObjectGroup telehub = null; 4503 SceneObjectGroup telehub = null;
4226 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4504 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4227 { 4505 {
@@ -4261,11 +4539,206 @@ namespace OpenSim.Region.Framework.Scenes
4261 pos = land.LandData.UserLocation; 4539 pos = land.LandData.UserLocation;
4262 } 4540 }
4263 } 4541 }
4264 4542
4265 land.SendLandUpdateToClient(ControllingClient); 4543 land.SendLandUpdateToClient(ControllingClient);
4266 } 4544 }
4267 } 4545 }
4268 4546
4547 private DetectedObject CreateDetObject(SceneObjectPart obj)
4548 {
4549 DetectedObject detobj = new DetectedObject();
4550 detobj.keyUUID = obj.UUID;
4551 detobj.nameStr = obj.Name;
4552 detobj.ownerUUID = obj.OwnerID;
4553 detobj.posVector = obj.AbsolutePosition;
4554 detobj.rotQuat = obj.GetWorldRotation();
4555 detobj.velVector = obj.Velocity;
4556 detobj.colliderType = 0;
4557 detobj.groupUUID = obj.GroupID;
4558
4559 return detobj;
4560 }
4561
4562 private DetectedObject CreateDetObject(ScenePresence av)
4563 {
4564 DetectedObject detobj = new DetectedObject();
4565 detobj.keyUUID = av.UUID;
4566 detobj.nameStr = av.ControllingClient.Name;
4567 detobj.ownerUUID = av.UUID;
4568 detobj.posVector = av.AbsolutePosition;
4569 detobj.rotQuat = av.Rotation;
4570 detobj.velVector = av.Velocity;
4571 detobj.colliderType = 0;
4572 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4573
4574 return detobj;
4575 }
4576
4577 private DetectedObject CreateDetObjectForGround()
4578 {
4579 DetectedObject detobj = new DetectedObject();
4580 detobj.keyUUID = UUID.Zero;
4581 detobj.nameStr = "";
4582 detobj.ownerUUID = UUID.Zero;
4583 detobj.posVector = AbsolutePosition;
4584 detobj.rotQuat = Quaternion.Identity;
4585 detobj.velVector = Vector3.Zero;
4586 detobj.colliderType = 0;
4587 detobj.groupUUID = UUID.Zero;
4588
4589 return detobj;
4590 }
4591
4592 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4593 {
4594 ColliderArgs colliderArgs = new ColliderArgs();
4595 List<DetectedObject> colliding = new List<DetectedObject>();
4596 foreach (uint localId in colliders)
4597 {
4598 if (localId == 0)
4599 continue;
4600
4601 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4602 if (obj != null)
4603 {
4604 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4605 colliding.Add(CreateDetObject(obj));
4606 }
4607 else
4608 {
4609 ScenePresence av = m_scene.GetScenePresence(localId);
4610 if (av != null && (!av.IsChildAgent))
4611 {
4612 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4613 colliding.Add(CreateDetObject(av));
4614 }
4615 }
4616 }
4617
4618 colliderArgs.Colliders = colliding;
4619
4620 return colliderArgs;
4621 }
4622
4623 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4624
4625 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4626 {
4627 ColliderArgs CollidingMessage;
4628
4629 if (colliders.Count > 0)
4630 {
4631 if ((dest.RootPart.ScriptEvents & ev) != 0)
4632 {
4633 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4634
4635 if (CollidingMessage.Colliders.Count > 0)
4636 notify(dest.RootPart.LocalId, CollidingMessage);
4637 }
4638 }
4639 }
4640
4641 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4642 {
4643 if ((dest.RootPart.ScriptEvents & ev) != 0)
4644 {
4645 ColliderArgs LandCollidingMessage = new ColliderArgs();
4646 List<DetectedObject> colliding = new List<DetectedObject>();
4647
4648 colliding.Add(CreateDetObjectForGround());
4649 LandCollidingMessage.Colliders = colliding;
4650
4651 notify(dest.RootPart.LocalId, LandCollidingMessage);
4652 }
4653 }
4654
4655 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
4656 {
4657 try
4658 {
4659 List<uint> thisHitColliders = new List<uint>();
4660 List<uint> endedColliders = new List<uint>();
4661 List<uint> startedColliders = new List<uint>();
4662 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
4663 CollisionForSoundInfo soundinfo;
4664 ContactPoint curcontact;
4665
4666 if (coldata.Count == 0)
4667 {
4668 if (m_lastColliders.Count == 0)
4669 return; // nothing to do
4670
4671 foreach (uint localID in m_lastColliders)
4672 {
4673 endedColliders.Add(localID);
4674 }
4675 m_lastColliders.Clear();
4676 }
4677
4678 else
4679 {
4680 foreach (uint id in coldata.Keys)
4681 {
4682 thisHitColliders.Add(id);
4683 if (!m_lastColliders.Contains(id))
4684 {
4685 startedColliders.Add(id);
4686 curcontact = coldata[id];
4687 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
4688 {
4689 soundinfo = new CollisionForSoundInfo();
4690 soundinfo.colliderID = id;
4691 soundinfo.position = curcontact.Position;
4692 soundinfo.relativeVel = curcontact.RelativeSpeed;
4693 soundinfolist.Add(soundinfo);
4694 }
4695 }
4696 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
4697 }
4698
4699 // calculate things that ended colliding
4700 foreach (uint localID in m_lastColliders)
4701 {
4702 if (!thisHitColliders.Contains(localID))
4703 {
4704 endedColliders.Add(localID);
4705 }
4706 }
4707 //add the items that started colliding this time to the last colliders list.
4708 foreach (uint localID in startedColliders)
4709 {
4710 m_lastColliders.Add(localID);
4711 }
4712 // remove things that ended colliding from the last colliders list
4713 foreach (uint localID in endedColliders)
4714 {
4715 m_lastColliders.Remove(localID);
4716 }
4717
4718 if (soundinfolist.Count > 0)
4719 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
4720 }
4721
4722 foreach (SceneObjectGroup att in GetAttachments())
4723 {
4724 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
4725 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
4726 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
4727
4728 if (startedColliders.Contains(0))
4729 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
4730 if (m_lastColliders.Contains(0))
4731 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
4732 if (endedColliders.Contains(0))
4733 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
4734 }
4735 }
4736 finally
4737 {
4738 m_collisionEventFlag = false;
4739 }
4740 }
4741
4269 private void TeleportFlagsDebug() { 4742 private void TeleportFlagsDebug() {
4270 4743
4271 // Some temporary debugging help to show all the TeleportFlags we have... 4744 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4290,6 +4763,5 @@ namespace OpenSim.Region.Framework.Scenes
4290 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4763 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4291 4764
4292 } 4765 }
4293
4294 } 4766 }
4295} 4767}