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.cs1115
1 files changed, 796 insertions, 319 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 7243db1..9f330fd 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -65,6 +65,7 @@ namespace OpenSim.Region.Framework.Scenes
65 65
66 struct ScriptControllers 66 struct ScriptControllers
67 { 67 {
68 public UUID objectID;
68 public UUID itemID; 69 public UUID itemID;
69 public ScriptControlled ignoreControls; 70 public ScriptControlled ignoreControls;
70 public ScriptControlled eventControls; 71 public ScriptControlled eventControls;
@@ -120,7 +121,7 @@ namespace OpenSim.Region.Framework.Scenes
120 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 121 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
121 /// issue #1716 122 /// issue #1716
122 /// </summary> 123 /// </summary>
123 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 124 public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
124 125
125 /// <summary> 126 /// <summary>
126 /// Movement updates for agents in neighboring regions are sent directly to clients. 127 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -142,8 +143,6 @@ namespace OpenSim.Region.Framework.Scenes
142 /// <remarks> 143 /// <remarks>
143 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 144 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
144 /// necessary. 145 /// necessary.
145 /// NOTE: To avoid deadlocks, do not lock m_attachments and then perform other tasks under that lock. Take a copy
146 /// of the list and act on that instead.
147 /// </remarks> 146 /// </remarks>
148 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 147 private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
149 148
@@ -162,6 +161,10 @@ namespace OpenSim.Region.Framework.Scenes
162 private Vector3 m_lastPosition; 161 private Vector3 m_lastPosition;
163 private Quaternion m_lastRotation; 162 private Quaternion m_lastRotation;
164 private Vector3 m_lastVelocity; 163 private Vector3 m_lastVelocity;
164 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
165
166 private bool m_followCamAuto = false;
167
165 168
166 private Vector3? m_forceToApply; 169 private Vector3? m_forceToApply;
167 private int m_userFlags; 170 private int m_userFlags;
@@ -194,6 +197,7 @@ namespace OpenSim.Region.Framework.Scenes
194// private int m_lastColCount = -1; //KF: Look for Collision chnages 197// private int m_lastColCount = -1; //KF: Look for Collision chnages
195// private int m_updateCount = 0; //KF: Update Anims for a while 198// private int m_updateCount = 0; //KF: Update Anims for a while
196// private static readonly int UPDATE_COUNT = 10; // how many frames to update for 199// private static readonly int UPDATE_COUNT = 10; // how many frames to update for
200 private List<uint> m_lastColliders = new List<uint>();
197 201
198 private TeleportFlags m_teleportFlags; 202 private TeleportFlags m_teleportFlags;
199 public TeleportFlags TeleportFlags 203 public TeleportFlags TeleportFlags
@@ -249,8 +253,6 @@ namespace OpenSim.Region.Framework.Scenes
249 /// </summary> 253 /// </summary>
250 public bool LandAtTarget { get; private set; } 254 public bool LandAtTarget { get; private set; }
251 255
252 private bool m_followCamAuto;
253
254 private int m_movementUpdateCount; 256 private int m_movementUpdateCount;
255 private const int NumMovementsBetweenRayCast = 5; 257 private const int NumMovementsBetweenRayCast = 5;
256 258
@@ -258,6 +260,13 @@ namespace OpenSim.Region.Framework.Scenes
258 //private int m_moveToPositionStateStatus; 260 //private int m_moveToPositionStateStatus;
259 //***************************************************** 261 //*****************************************************
260 262
263 private bool m_collisionEventFlag = false;
264 private object m_collisionEventLock = new Object();
265
266 private int m_movementAnimationUpdateCounter = 0;
267
268 public Vector3 PrevSitOffset { get; set; }
269
261 protected AvatarAppearance m_appearance; 270 protected AvatarAppearance m_appearance;
262 271
263 public AvatarAppearance Appearance 272 public AvatarAppearance Appearance
@@ -400,6 +409,9 @@ namespace OpenSim.Region.Framework.Scenes
400 /// </summary> 409 /// </summary>
401 protected Vector3 m_lastCameraPosition; 410 protected Vector3 m_lastCameraPosition;
402 411
412 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
413 private bool m_doingCamRayCast = false;
414
403 public Vector3 CameraPosition { get; set; } 415 public Vector3 CameraPosition { get; set; }
404 416
405 public Quaternion CameraRotation 417 public Quaternion CameraRotation
@@ -480,7 +492,9 @@ namespace OpenSim.Region.Framework.Scenes
480 get { return (IClientCore)ControllingClient; } 492 get { return (IClientCore)ControllingClient; }
481 } 493 }
482 494
483 public Vector3 ParentPosition { get; set; } 495 public UUID COF { get; set; }
496
497// public Vector3 ParentPosition { get; set; }
484 498
485 /// <summary> 499 /// <summary>
486 /// Position of this avatar relative to the region the avatar is in 500 /// Position of this avatar relative to the region the avatar is in
@@ -541,7 +555,7 @@ namespace OpenSim.Region.Framework.Scenes
541 if (ParentID == 0) 555 if (ParentID == 0)
542 { 556 {
543 m_pos = value; 557 m_pos = value;
544 ParentPosition = Vector3.Zero; 558// ParentPosition = Vector3.Zero;
545 } 559 }
546 560
547 //m_log.DebugFormat( 561 //m_log.DebugFormat(
@@ -610,7 +624,24 @@ namespace OpenSim.Region.Framework.Scenes
610// Scene.RegionInfo.RegionName, Name, m_velocity); 624// Scene.RegionInfo.RegionName, Name, m_velocity);
611 } 625 }
612 } 626 }
627/*
628 public override Vector3 AngularVelocity
629 {
630 get
631 {
632 if (PhysicsActor != null)
633 {
634 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
613 635
636 // m_log.DebugFormat(
637 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
638 // m_velocity, Name, Scene.RegionInfo.RegionName);
639 }
640
641 return m_rotationalvelocity;
642 }
643 }
644*/
614 private Quaternion m_bodyRot = Quaternion.Identity; 645 private Quaternion m_bodyRot = Quaternion.Identity;
615 646
616 /// <summary> 647 /// <summary>
@@ -633,8 +664,16 @@ namespace OpenSim.Region.Framework.Scenes
633 m_bodyRot = value; 664 m_bodyRot = value;
634 665
635 if (PhysicsActor != null) 666 if (PhysicsActor != null)
636 PhysicsActor.Orientation = m_bodyRot; 667 {
637 668 try
669 {
670 PhysicsActor.Orientation = m_bodyRot;
671 }
672 catch (Exception e)
673 {
674 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
675 }
676 }
638// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 677// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
639 } 678 }
640 } 679 }
@@ -648,12 +687,20 @@ namespace OpenSim.Region.Framework.Scenes
648 } 687 }
649 688
650 public bool IsChildAgent { get; set; } 689 public bool IsChildAgent { get; set; }
690 public bool IsLoggingIn { get; set; }
651 691
652 /// <summary> 692 /// <summary>
653 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 693 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
654 /// </summary> 694 /// </summary>
655 public uint ParentID { get; set; } 695 public uint ParentID { get; set; }
656 696
697 public UUID ParentUUID
698 {
699 get { return m_parentUUID; }
700 set { m_parentUUID = value; }
701 }
702 private UUID m_parentUUID = UUID.Zero;
703
657 /// <summary> 704 /// <summary>
658 /// Are we sitting on an object? 705 /// Are we sitting on an object?
659 /// </summary> 706 /// </summary>
@@ -803,6 +850,7 @@ namespace OpenSim.Region.Framework.Scenes
803 AttachmentsSyncLock = new Object(); 850 AttachmentsSyncLock = new Object();
804 AllowMovement = true; 851 AllowMovement = true;
805 IsChildAgent = true; 852 IsChildAgent = true;
853 IsLoggingIn = false;
806 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 854 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
807 Animator = new ScenePresenceAnimator(this); 855 Animator = new ScenePresenceAnimator(this);
808 PresenceType = type; 856 PresenceType = type;
@@ -848,6 +896,33 @@ namespace OpenSim.Region.Framework.Scenes
848 m_stateMachine = new ScenePresenceStateMachine(this); 896 m_stateMachine = new ScenePresenceStateMachine(this);
849 } 897 }
850 898
899 private void RegionHeartbeatEnd(Scene scene)
900 {
901 if (IsChildAgent)
902 return;
903
904 m_movementAnimationUpdateCounter ++;
905 if (m_movementAnimationUpdateCounter >= 2)
906 {
907 m_movementAnimationUpdateCounter = 0;
908 if (Animator != null)
909 {
910 // If the parentID == 0 we are not sitting
911 // if !SitGournd then we are not sitting on the ground
912 // Fairly straightforward, now here comes the twist
913 // if ParentUUID is NOT UUID.Zero, we are looking to
914 // be sat on an object that isn't there yet. Should
915 // be treated as if sat.
916 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
917 Animator.UpdateMovementAnimations();
918 }
919 else
920 {
921 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
922 }
923 }
924 }
925
851 public void RegisterToEvents() 926 public void RegisterToEvents()
852 { 927 {
853 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 928 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -858,8 +933,10 @@ namespace OpenSim.Region.Framework.Scenes
858 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 933 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
859 ControllingClient.OnStartAnim += HandleStartAnim; 934 ControllingClient.OnStartAnim += HandleStartAnim;
860 ControllingClient.OnStopAnim += HandleStopAnim; 935 ControllingClient.OnStopAnim += HandleStopAnim;
936 ControllingClient.OnChangeAnim += avnHandleChangeAnim;
861 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; 937 ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
862 ControllingClient.OnAutoPilotGo += MoveToTarget; 938 ControllingClient.OnAutoPilotGo += MoveToTarget;
939 ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles;
863 940
864 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 941 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
865 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 942 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -918,6 +995,38 @@ namespace OpenSim.Region.Framework.Scenes
918// "[SCENE]: Upgrading child to root agent for {0} in {1}", 995// "[SCENE]: Upgrading child to root agent for {0} in {1}",
919// Name, m_scene.RegionInfo.RegionName); 996// Name, m_scene.RegionInfo.RegionName);
920 997
998 if (ParentUUID != UUID.Zero)
999 {
1000 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1001 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1002 if (part == null)
1003 {
1004 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1005 }
1006 else
1007 {
1008 part.ParentGroup.AddAvatar(UUID);
1009 if (part.SitTargetPosition != Vector3.Zero)
1010 part.SitTargetAvatar = UUID;
1011// ParentPosition = part.GetWorldPosition();
1012 ParentID = part.LocalId;
1013 ParentPart = part;
1014 m_pos = PrevSitOffset;
1015// pos = ParentPosition;
1016 pos = part.GetWorldPosition();
1017 }
1018 ParentUUID = UUID.Zero;
1019
1020 IsChildAgent = false;
1021
1022// Animator.TrySetMovementAnimation("SIT");
1023 }
1024 else
1025 {
1026 IsChildAgent = false;
1027 IsLoggingIn = false;
1028 }
1029
921 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 1030 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
922 1031
923 IsChildAgent = false; 1032 IsChildAgent = false;
@@ -935,70 +1044,106 @@ namespace OpenSim.Region.Framework.Scenes
935 1044
936 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1045 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
937 1046
938 // Moved this from SendInitialData to ensure that Appearance is initialized 1047 UUID groupUUID = UUID.Zero;
939 // before the inventory is processed in MakeRootAgent. This fixes a race condition 1048 string GroupName = string.Empty;
940 // related to the handling of attachments 1049 ulong groupPowers = 0;
941 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
942 1050
943 if (m_scene.TestBorderCross(pos, Cardinals.E)) 1051 // ----------------------------------
1052 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1053 try
944 { 1054 {
945 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 1055 if (gm != null)
946 pos.X = crossedBorder.BorderLine.Z - 1; 1056 {
1057 groupUUID = ControllingClient.ActiveGroupId;
1058 GroupRecord record = gm.GetGroupRecord(groupUUID);
1059 if (record != null)
1060 GroupName = record.GroupName;
1061 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1062 if (groupMembershipData != null)
1063 groupPowers = groupMembershipData.GroupPowers;
1064 }
1065 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1066 Grouptitle);
947 } 1067 }
948 1068 catch (Exception e)
949 if (m_scene.TestBorderCross(pos, Cardinals.N))
950 { 1069 {
951 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1070 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
952 pos.Y = crossedBorder.BorderLine.Z - 1;
953 } 1071 }
1072 // ------------------------------------
954 1073
955 CheckAndAdjustLandingPoint(ref pos); 1074 if (ParentID == 0)
956
957 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
958 { 1075 {
959 m_log.WarnFormat( 1076 // Moved this from SendInitialData to ensure that Appearance is initialized
960 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1077 // before the inventory is processed in MakeRootAgent. This fixes a race condition
961 pos, Name, UUID); 1078 // related to the handling of attachments
1079 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1080 if (m_scene.TestBorderCross(pos, Cardinals.E))
1081 {
1082 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1083 pos.X = crossedBorder.BorderLine.Z - 1;
1084 }
962 1085
963 if (pos.X < 0f) pos.X = 0f; 1086 if (m_scene.TestBorderCross(pos, Cardinals.N))
964 if (pos.Y < 0f) pos.Y = 0f; 1087 {
965 if (pos.Z < 0f) pos.Z = 0f; 1088 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
966 } 1089 pos.Y = crossedBorder.BorderLine.Z - 1;
1090 }
967 1091
968 float localAVHeight = 1.56f; 1092 CheckAndAdjustLandingPoint(ref pos);
969 if (Appearance.AvatarHeight > 0)
970 localAVHeight = Appearance.AvatarHeight;
971 1093
972 float posZLimit = 0; 1094 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1095 {
1096 m_log.WarnFormat(
1097 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1098 pos, Name, UUID);
973 1099
974 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1100 if (pos.X < 0f) pos.X = 0f;
975 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1101 if (pos.Y < 0f) pos.Y = 0f;
976 1102 if (pos.Z < 0f) pos.Z = 0f;
977 float newPosZ = posZLimit + localAVHeight / 2; 1103 }
978 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
979 {
980 pos.Z = newPosZ;
981 }
982 AbsolutePosition = pos;
983 1104
984 AddToPhysicalScene(isFlying); 1105 float localAVHeight = 1.56f;
1106 if (Appearance.AvatarHeight > 0)
1107 localAVHeight = Appearance.AvatarHeight;
985 1108
986 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1109 float posZLimit = 0;
987 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
988 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
989 // the value to a negative position which does not trigger the border cross.
990 // This may not be the best location for this.
991 CheckForBorderCrossing();
992 1110
993 if (ForceFly) 1111 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
994 { 1112 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
995 Flying = true; 1113
996 } 1114 float newPosZ = posZLimit + localAVHeight / 2;
997 else if (FlyDisabled) 1115 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
998 { 1116 {
999 Flying = false; 1117 pos.Z = newPosZ;
1000 } 1118 }
1119 AbsolutePosition = pos;
1120
1121 if (m_teleportFlags == TeleportFlags.Default)
1122 {
1123 Vector3 vel = Velocity;
1124 AddToPhysicalScene(isFlying);
1125 if (PhysicsActor != null)
1126 PhysicsActor.SetMomentum(vel);
1127 }
1128 else
1129 AddToPhysicalScene(isFlying);
1130
1131 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1132 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1133 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1134 // the value to a negative position which does not trigger the border cross.
1135 // This may not be the best location for this.
1136 CheckForBorderCrossing();
1001 1137
1138 if (ForceFly)
1139 {
1140 Flying = true;
1141 }
1142 else if (FlyDisabled)
1143 {
1144 Flying = false;
1145 }
1146 }
1002 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1147 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
1003 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1148 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1004 // elsewhere anyway 1149 // elsewhere anyway
@@ -1030,31 +1175,28 @@ namespace OpenSim.Region.Framework.Scenes
1030 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1175 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1031 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1176 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1032 // not transporting the required data. 1177 // not transporting the required data.
1033 // 1178 lock (m_attachments)
1034 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1035 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1036 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
1037 //
1038 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
1039 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1040 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1041 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1042 List<SceneObjectGroup> attachments = GetAttachments();
1043
1044 if (attachments.Count > 0)
1045 { 1179 {
1046 m_log.DebugFormat( 1180 if (HasAttachments())
1047 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1048
1049 // Resume scripts
1050 foreach (SceneObjectGroup sog in attachments)
1051 { 1181 {
1052 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1182 m_log.DebugFormat(
1053 sog.ResumeScripts(); 1183 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1184
1185 // Resume scripts
1186 Util.FireAndForget(delegate(object x) {
1187 foreach (SceneObjectGroup sog in m_attachments)
1188 {
1189 sog.ScheduleGroupForFullUpdate();
1190 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1191 sog.ResumeScripts();
1192 }
1193 });
1054 } 1194 }
1055 } 1195 }
1056 } 1196 }
1057 1197
1198 SendAvatarDataToAllAgents();
1199
1058 // send the animations of the other presences to me 1200 // send the animations of the other presences to me
1059 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1201 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1060 { 1202 {
@@ -1065,6 +1207,7 @@ namespace OpenSim.Region.Framework.Scenes
1065 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1207 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1066 // stall on the border crossing since the existing child agent will still have the last movement 1208 // stall on the border crossing since the existing child agent will still have the last movement
1067 // recorded, which stops the input from being processed. 1209 // recorded, which stops the input from being processed.
1210
1068 MovementFlag = 0; 1211 MovementFlag = 0;
1069 1212
1070 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1213 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -1096,12 +1239,16 @@ namespace OpenSim.Region.Framework.Scenes
1096 /// </remarks> 1239 /// </remarks>
1097 public void MakeChildAgent() 1240 public void MakeChildAgent()
1098 { 1241 {
1242 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1243
1099 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1244 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1100 1245
1101 // Reset these so that teleporting in and walking out isn't seen 1246 // Reset these so that teleporting in and walking out isn't seen
1102 // as teleporting back 1247 // as teleporting back
1103 TeleportFlags = TeleportFlags.Default; 1248 TeleportFlags = TeleportFlags.Default;
1104 1249
1250 MovementFlag = 0;
1251
1105 // It looks like Animator is set to null somewhere, and MakeChild 1252 // It looks like Animator is set to null somewhere, and MakeChild
1106 // is called after that. Probably in aborted teleports. 1253 // is called after that. Probably in aborted teleports.
1107 if (Animator == null) 1254 if (Animator == null)
@@ -1109,6 +1256,7 @@ namespace OpenSim.Region.Framework.Scenes
1109 else 1256 else
1110 Animator.ResetAnimations(); 1257 Animator.ResetAnimations();
1111 1258
1259
1112// m_log.DebugFormat( 1260// m_log.DebugFormat(
1113// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1261// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1114// Name, UUID, m_scene.RegionInfo.RegionName); 1262// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1120,6 +1268,7 @@ namespace OpenSim.Region.Framework.Scenes
1120 IsChildAgent = true; 1268 IsChildAgent = true;
1121 m_scene.SwapRootAgentCount(true); 1269 m_scene.SwapRootAgentCount(true);
1122 RemoveFromPhysicalScene(); 1270 RemoveFromPhysicalScene();
1271 ParentID = 0; // Child agents can't be sitting
1123 1272
1124 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1273 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1125 1274
@@ -1135,9 +1284,9 @@ namespace OpenSim.Region.Framework.Scenes
1135 { 1284 {
1136// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1285// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1137 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1286 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1138 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1139 PhysicsActor.UnSubscribeEvents();
1140 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1287 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1288 PhysicsActor.UnSubscribeEvents();
1289 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1141 PhysicsActor = null; 1290 PhysicsActor = null;
1142 } 1291 }
1143// else 1292// else
@@ -1154,7 +1303,7 @@ namespace OpenSim.Region.Framework.Scenes
1154 /// <param name="pos"></param> 1303 /// <param name="pos"></param>
1155 public void Teleport(Vector3 pos) 1304 public void Teleport(Vector3 pos)
1156 { 1305 {
1157 TeleportWithMomentum(pos, null); 1306 TeleportWithMomentum(pos, Vector3.Zero);
1158 } 1307 }
1159 1308
1160 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1309 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1178,6 +1327,41 @@ namespace OpenSim.Region.Framework.Scenes
1178 SendTerseUpdateToAllClients(); 1327 SendTerseUpdateToAllClients();
1179 } 1328 }
1180 1329
1330 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1331 {
1332 CheckLandingPoint(ref newpos);
1333 AbsolutePosition = newpos;
1334
1335 if (newvel.HasValue)
1336 {
1337 if ((Vector3)newvel == Vector3.Zero)
1338 {
1339 if (PhysicsActor != null)
1340 PhysicsActor.SetMomentum(Vector3.Zero);
1341 m_velocity = Vector3.Zero;
1342 }
1343 else
1344 {
1345 if (PhysicsActor != null)
1346 PhysicsActor.SetMomentum((Vector3)newvel);
1347 m_velocity = (Vector3)newvel;
1348
1349 if (rotateToVelXY)
1350 {
1351 Vector3 lookAt = (Vector3)newvel;
1352 lookAt.Z = 0;
1353 lookAt.Normalize();
1354 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1355 return;
1356 }
1357 }
1358 }
1359
1360 SendTerseUpdateToAllClients();
1361 }
1362
1363
1364
1181 public void StopFlying() 1365 public void StopFlying()
1182 { 1366 {
1183 Vector3 pos = AbsolutePosition; 1367 Vector3 pos = AbsolutePosition;
@@ -1366,6 +1550,13 @@ namespace OpenSim.Region.Framework.Scenes
1366 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1550 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1367 } 1551 }
1368 1552
1553 public void SetSize(Vector3 size, float feetoffset)
1554 {
1555 if (PhysicsActor != null && !IsChildAgent)
1556 PhysicsActor.setAvatarSize(size, feetoffset);
1557
1558 }
1559
1369 private bool WaitForUpdateAgent(IClientAPI client) 1560 private bool WaitForUpdateAgent(IClientAPI client)
1370 { 1561 {
1371 // Before the source region executes UpdateAgent 1562 // Before the source region executes UpdateAgent
@@ -1425,7 +1616,8 @@ namespace OpenSim.Region.Framework.Scenes
1425 1616
1426 Vector3 look = Velocity; 1617 Vector3 look = Velocity;
1427 1618
1428 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1619 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1620 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1429 { 1621 {
1430 look = new Vector3(0.99f, 0.042f, 0); 1622 look = new Vector3(0.99f, 0.042f, 0);
1431 } 1623 }
@@ -1488,11 +1680,12 @@ namespace OpenSim.Region.Framework.Scenes
1488 { 1680 {
1489 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1681 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1490 if (m_agentTransfer != null) 1682 if (m_agentTransfer != null)
1491 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1683 m_agentTransfer.EnableChildAgents(this);
1492 1684
1493 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1685 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1494 if (friendsModule != null) 1686 if (friendsModule != null)
1495 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1687 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1688
1496 } 1689 }
1497 1690
1498 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1691 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1518,36 +1711,69 @@ namespace OpenSim.Region.Framework.Scenes
1518 /// <param name="collisionPoint"></param> 1711 /// <param name="collisionPoint"></param>
1519 /// <param name="localid"></param> 1712 /// <param name="localid"></param>
1520 /// <param name="distance"></param> 1713 /// <param name="distance"></param>
1714 ///
1715
1716 private void UpdateCameraCollisionPlane(Vector4 plane)
1717 {
1718 if (m_lastCameraCollisionPlane != plane)
1719 {
1720 m_lastCameraCollisionPlane = plane;
1721 ControllingClient.SendCameraConstraint(plane);
1722 }
1723 }
1724
1521 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1725 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1522 { 1726 {
1523 const float POSITION_TOLERANCE = 0.02f; 1727 const float POSITION_TOLERANCE = 0.02f;
1524 const float VELOCITY_TOLERANCE = 0.02f;
1525 const float ROTATION_TOLERANCE = 0.02f; 1728 const float ROTATION_TOLERANCE = 0.02f;
1526 1729
1527 if (m_followCamAuto) 1730 m_doingCamRayCast = false;
1731 if (hitYN && localid != LocalId)
1528 { 1732 {
1529 if (hitYN) 1733 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1734 bool IsPrim = group != null;
1735 if (IsPrim)
1530 { 1736 {
1531 CameraConstraintActive = true; 1737 SceneObjectPart part = group.GetPart(localid);
1532 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1738 if (part != null && !part.VolumeDetectActive)
1533 1739 {
1534 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1740 CameraConstraintActive = true;
1535 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1741 pNormal.X = (float) Math.Round(pNormal.X, 2);
1742 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1743 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1744 pNormal.Normalize();
1745 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1746 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1747 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1748
1749 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1750 Vector3.Dot(collisionPoint, pNormal));
1751 UpdateCameraCollisionPlane(plane);
1752 }
1536 } 1753 }
1537 else 1754 else
1538 { 1755 {
1539 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1756 CameraConstraintActive = true;
1540 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1757 pNormal.X = (float) Math.Round(pNormal.X, 2);
1541 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1758 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1542 { 1759 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1543 if (CameraConstraintActive) 1760 pNormal.Normalize();
1544 { 1761 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1545 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1762 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1546 CameraConstraintActive = false; 1763 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1547 } 1764
1548 } 1765 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1766 Vector3.Dot(collisionPoint, pNormal));
1767 UpdateCameraCollisionPlane(plane);
1549 } 1768 }
1550 } 1769 }
1770 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1771 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1772 {
1773 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1774 UpdateCameraCollisionPlane(plane);
1775 CameraConstraintActive = false;
1776 }
1551 } 1777 }
1552 1778
1553 /// <summary> 1779 /// <summary>
@@ -1621,6 +1847,41 @@ namespace OpenSim.Region.Framework.Scenes
1621 StandUp(); 1847 StandUp();
1622 } 1848 }
1623 1849
1850 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1851 // this exclude checks may not be complete
1852
1853 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1854 {
1855 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1856 {
1857 Vector3 posAdjusted = AbsolutePosition;
1858// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1859 posAdjusted.Z += 1.0f; // viewer current camera focus point
1860 Vector3 tocam = CameraPosition - posAdjusted;
1861 tocam.X = (float)Math.Round(tocam.X, 1);
1862 tocam.Y = (float)Math.Round(tocam.Y, 1);
1863 tocam.Z = (float)Math.Round(tocam.Z, 1);
1864
1865 float distTocamlen = tocam.Length();
1866 if (distTocamlen > 0.3f)
1867 {
1868 tocam *= (1.0f / distTocamlen);
1869 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1870 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1871 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1872
1873 m_doingCamRayCast = true;
1874 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1875 }
1876 }
1877 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1878 {
1879 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1880 UpdateCameraCollisionPlane(plane);
1881 CameraConstraintActive = false;
1882 }
1883 }
1884
1624 uint flagsForScripts = (uint)flags; 1885 uint flagsForScripts = (uint)flags;
1625 flags = RemoveIgnoredControls(flags, IgnoredControls); 1886 flags = RemoveIgnoredControls(flags, IgnoredControls);
1626 1887
@@ -2156,7 +2417,8 @@ namespace OpenSim.Region.Framework.Scenes
2156// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2417// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2157 2418
2158 MovingToTarget = false; 2419 MovingToTarget = false;
2159 MoveToPositionTarget = Vector3.Zero; 2420// MoveToPositionTarget = Vector3.Zero;
2421 m_forceToApply = null; // cancel possible last action
2160 2422
2161 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2423 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
2162 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2424 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2174,12 +2436,18 @@ namespace OpenSim.Region.Framework.Scenes
2174// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2436// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
2175 2437
2176 SitGround = false; 2438 SitGround = false;
2439
2440/* move this down so avatar gets physical in the new position and not where it is siting
2177 if (PhysicsActor == null) 2441 if (PhysicsActor == null)
2178 AddToPhysicalScene(false); 2442 AddToPhysicalScene(false);
2443 */
2179 2444
2180 if (ParentID != 0) 2445 if (ParentID != 0)
2181 { 2446 {
2447 PrevSitOffset = m_pos; // Save sit offset
2182 SceneObjectPart part = ParentPart; 2448 SceneObjectPart part = ParentPart;
2449 UnRegisterSeatControls(part.ParentGroup.UUID);
2450
2183 TaskInventoryDictionary taskIDict = part.TaskInventory; 2451 TaskInventoryDictionary taskIDict = part.TaskInventory;
2184 if (taskIDict != null) 2452 if (taskIDict != null)
2185 { 2453 {
@@ -2195,14 +2463,22 @@ namespace OpenSim.Region.Framework.Scenes
2195 } 2463 }
2196 } 2464 }
2197 2465
2198 ParentPosition = part.GetWorldPosition(); 2466 part.ParentGroup.DeleteAvatar(UUID);
2467// ParentPosition = part.GetWorldPosition();
2199 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2468 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2200 2469
2201 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 2470// m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2202 ParentPosition = Vector3.Zero; 2471// ParentPosition = Vector3.Zero;
2472 m_pos = part.AbsolutePosition + (m_pos * part.GetWorldRotation()) + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2473 if (part.SitTargetAvatar == UUID)
2474 m_bodyRot = part.GetWorldRotation() * part.SitTargetOrientation;
2203 2475
2204 ParentID = 0; 2476 ParentID = 0;
2205 ParentPart = null; 2477 ParentPart = null;
2478
2479 if (PhysicsActor == null)
2480 AddToPhysicalScene(false);
2481
2206 SendAvatarDataToAllAgents(); 2482 SendAvatarDataToAllAgents();
2207 m_requestedSitTargetID = 0; 2483 m_requestedSitTargetID = 0;
2208 2484
@@ -2212,6 +2488,9 @@ namespace OpenSim.Region.Framework.Scenes
2212 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2488 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2213 } 2489 }
2214 2490
2491 else if (PhysicsActor == null)
2492 AddToPhysicalScene(false);
2493
2215 Animator.TrySetMovementAnimation("STAND"); 2494 Animator.TrySetMovementAnimation("STAND");
2216 TriggerScenePresenceUpdated(); 2495 TriggerScenePresenceUpdated();
2217 } 2496 }
@@ -2260,11 +2539,8 @@ namespace OpenSim.Region.Framework.Scenes
2260 if (part == null) 2539 if (part == null)
2261 return; 2540 return;
2262 2541
2263 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2264 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2265
2266 if (PhysicsActor != null) 2542 if (PhysicsActor != null)
2267 m_sitAvatarHeight = PhysicsActor.Size.Z; 2543 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2268 2544
2269 bool canSit = false; 2545 bool canSit = false;
2270 Vector3 pos = part.AbsolutePosition + offset; 2546 Vector3 pos = part.AbsolutePosition + offset;
@@ -2281,31 +2557,31 @@ namespace OpenSim.Region.Framework.Scenes
2281 } 2557 }
2282 else 2558 else
2283 { 2559 {
2560 if (PhysicsSit(part,offset)) // physics engine
2561 return;
2562
2284 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2563 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2285 { 2564 {
2286// m_log.DebugFormat(
2287// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2288// Name, part.Name, part.LocalId);
2289 2565
2290 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2566 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2291 canSit = true; 2567 canSit = true;
2292 } 2568 }
2293// else
2294// {
2295// m_log.DebugFormat(
2296// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2297// Name, part.Name, part.LocalId);
2298// }
2299 } 2569 }
2300 2570
2301 if (canSit) 2571 if (canSit)
2302 { 2572 {
2573
2303 if (PhysicsActor != null) 2574 if (PhysicsActor != null)
2304 { 2575 {
2305 // We can remove the physicsActor until they stand up. 2576 // We can remove the physicsActor until they stand up.
2306 RemoveFromPhysicalScene(); 2577 RemoveFromPhysicalScene();
2307 } 2578 }
2308 2579
2580 if (MovingToTarget)
2581 ResetMoveToTarget();
2582
2583 Velocity = Vector3.Zero;
2584
2309 part.AddSittingAvatar(UUID); 2585 part.AddSittingAvatar(UUID);
2310 2586
2311 cameraAtOffset = part.GetCameraAtOffset(); 2587 cameraAtOffset = part.GetCameraAtOffset();
@@ -2345,14 +2621,6 @@ namespace OpenSim.Region.Framework.Scenes
2345 m_requestedSitTargetID = part.LocalId; 2621 m_requestedSitTargetID = part.LocalId;
2346 m_requestedSitTargetUUID = part.UUID; 2622 m_requestedSitTargetUUID = part.UUID;
2347 2623
2348// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2349
2350 if (m_scene.PhysicsScene.SupportsRayCast())
2351 {
2352 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2353 //SitRayCastAvatarPosition(part);
2354 //return;
2355 }
2356 } 2624 }
2357 else 2625 else
2358 { 2626 {
@@ -2362,197 +2630,111 @@ namespace OpenSim.Region.Framework.Scenes
2362 SendSitResponse(targetID, offset, Quaternion.Identity); 2630 SendSitResponse(targetID, offset, Quaternion.Identity);
2363 } 2631 }
2364 2632
2365 /* 2633 // returns false if does not suport so older sit can be tried
2366 public void SitRayCastAvatarPosition(SceneObjectPart part) 2634 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2367 { 2635 {
2368 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2636 if (part == null || part.ParentGroup.IsAttachment)
2369 Vector3 StartRayCastPosition = AbsolutePosition;
2370 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2371 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2372 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2373 }
2374
2375 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2376 {
2377 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2378 if (part != null)
2379 { 2637 {
2380 if (hitYN) 2638 return true;
2381 {
2382 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2383 {
2384 SitRaycastFindEdge(collisionPoint, normal);
2385 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2386 }
2387 else
2388 {
2389 SitRayCastAvatarPositionCameraZ(part);
2390 }
2391 }
2392 else
2393 {
2394 SitRayCastAvatarPositionCameraZ(part);
2395 }
2396 } 2639 }
2397 else
2398 {
2399 ControllingClient.SendAlertMessage("Sit position no longer exists");
2400 m_requestedSitTargetUUID = UUID.Zero;
2401 m_requestedSitTargetID = 0;
2402 m_requestedSitOffset = Vector3.Zero;
2403 }
2404
2405 }
2406 2640
2407 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part) 2641 if ( m_scene.PhysicsScene == null)
2408 { 2642 return false;
2409 // Next, try to raycast from the camera Z position
2410 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2411 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2412 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2413 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2414 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2415 }
2416 2643
2417 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2644 if (part.PhysActor == null)
2418 {
2419 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2420 if (part != null)
2421 { 2645 {
2422 if (hitYN) 2646 // none physcis shape
2423 { 2647 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2424 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2648 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2425 {
2426 SitRaycastFindEdge(collisionPoint, normal);
2427 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2428 }
2429 else
2430 {
2431 SitRayCastCameraPosition(part);
2432 }
2433 }
2434 else 2649 else
2435 { 2650 { // non physical phantom TODO
2436 SitRayCastCameraPosition(part); 2651 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2652 return false;
2437 } 2653 }
2438 } 2654 return true;
2439 else
2440 {
2441 ControllingClient.SendAlertMessage("Sit position no longer exists");
2442 m_requestedSitTargetUUID = UUID.Zero;
2443 m_requestedSitTargetID = 0;
2444 m_requestedSitOffset = Vector3.Zero;
2445 } 2655 }
2446 2656
2447 }
2448 2657
2449 public void SitRayCastCameraPosition(SceneObjectPart part) 2658 // not doing autopilot
2450 { 2659 m_requestedSitTargetID = 0;
2451 // Next, try to raycast from the camera position
2452 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2453 Vector3 StartRayCastPosition = CameraPosition;
2454 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2455 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2456 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2457 }
2458 2660
2459 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2661 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2460 { 2662 return true;
2461 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2462 if (part != null)
2463 {
2464 if (hitYN)
2465 {
2466 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2467 {
2468 SitRaycastFindEdge(collisionPoint, normal);
2469 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2470 }
2471 else
2472 {
2473 SitRayHorizontal(part);
2474 }
2475 }
2476 else
2477 {
2478 SitRayHorizontal(part);
2479 }
2480 }
2481 else
2482 {
2483 ControllingClient.SendAlertMessage("Sit position no longer exists");
2484 m_requestedSitTargetUUID = UUID.Zero;
2485 m_requestedSitTargetID = 0;
2486 m_requestedSitOffset = Vector3.Zero;
2487 }
2488 2663
2664 return false;
2489 } 2665 }
2490 2666
2491 public void SitRayHorizontal(SceneObjectPart part) 2667
2668 private bool CanEnterLandPosition(Vector3 testPos)
2492 { 2669 {
2493 // Next, try to raycast from the avatar position to fwd 2670 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2494 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2671
2495 Vector3 StartRayCastPosition = CameraPosition; 2672 if (land == null || land.LandData.Name == "NO_LAND")
2496 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2673 return true;
2497 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2674
2498 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2675 return land.CanBeOnThisLand(UUID,testPos.Z);
2499 } 2676 }
2500 2677
2501 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2678 // status
2679 // < 0 ignore
2680 // 0 bad sit spot
2681 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2502 { 2682 {
2503 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2683 if (status < 0)
2504 if (part != null) 2684 return;
2685
2686 if (status == 0)
2505 { 2687 {
2506 if (hitYN) 2688 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2507 { 2689 return;
2508 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2509 {
2510 SitRaycastFindEdge(collisionPoint, normal);
2511 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2512 // Next, try to raycast from the camera position
2513 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2514 Vector3 StartRayCastPosition = CameraPosition;
2515 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2516 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2517 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2518 }
2519 else
2520 {
2521 ControllingClient.SendAlertMessage("Sit position not accessable.");
2522 m_requestedSitTargetUUID = UUID.Zero;
2523 m_requestedSitTargetID = 0;
2524 m_requestedSitOffset = Vector3.Zero;
2525 }
2526 }
2527 else
2528 {
2529 ControllingClient.SendAlertMessage("Sit position not accessable.");
2530 m_requestedSitTargetUUID = UUID.Zero;
2531 m_requestedSitTargetID = 0;
2532 m_requestedSitOffset = Vector3.Zero;
2533 }
2534 } 2690 }
2535 else 2691
2692 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2693 if (part == null)
2694 return;
2695
2696 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2697 if(!CanEnterLandPosition(targetPos))
2536 { 2698 {
2537 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2699 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2538 m_requestedSitTargetUUID = UUID.Zero; 2700 return;
2539 m_requestedSitTargetID = 0;
2540 m_requestedSitOffset = Vector3.Zero;
2541 } 2701 }
2542 2702
2543 } 2703 RemoveFromPhysicalScene();
2544 2704
2545 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2705 if (MovingToTarget)
2546 { 2706 ResetMoveToTarget();
2547 int i = 0; 2707
2548 //throw new NotImplementedException(); 2708 Velocity = Vector3.Zero;
2549 //m_requestedSitTargetUUID = UUID.Zero;
2550 //m_requestedSitTargetID = 0;
2551 //m_requestedSitOffset = Vector3.Zero;
2552 2709
2553 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2710 part.AddSittingAvatar(UUID);
2711
2712 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2713 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2714 bool forceMouselook = part.GetForceMouselook();
2715
2716 ControllingClient.SendSitResponse(
2717 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2718
2719 // not using autopilot
2720
2721 Rotation = Orientation;
2722 m_pos = offset;
2723
2724 m_requestedSitTargetID = 0;
2725 part.ParentGroup.AddAvatar(UUID);
2726
2727 ParentPart = part;
2728 ParentID = part.LocalId;
2729 if(status == 3)
2730 Animator.TrySetMovementAnimation("SIT_GROUND");
2731 else
2732 Animator.TrySetMovementAnimation("SIT");
2733 SendAvatarDataToAllAgents();
2734
2735 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2554 } 2736 }
2555 */ 2737
2556 2738
2557 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2739 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2558 { 2740 {
@@ -2572,6 +2754,7 @@ namespace OpenSim.Region.Framework.Scenes
2572 return; 2754 return;
2573 } 2755 }
2574 2756
2757
2575 if (part.SitTargetAvatar == UUID) 2758 if (part.SitTargetAvatar == UUID)
2576 { 2759 {
2577 Vector3 sitTargetPos = part.SitTargetPosition; 2760 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2586,14 +2769,39 @@ namespace OpenSim.Region.Framework.Scenes
2586 2769
2587 //Quaternion result = (sitTargetOrient * vq) * nq; 2770 //Quaternion result = (sitTargetOrient * vq) * nq;
2588 2771
2589 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2772 double x, y, z, m;
2773
2774 Quaternion r = sitTargetOrient;
2775 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2776
2777 if (Math.Abs(1.0 - m) > 0.000001)
2778 {
2779 m = 1.0 / Math.Sqrt(m);
2780 r.X *= (float)m;
2781 r.Y *= (float)m;
2782 r.Z *= (float)m;
2783 r.W *= (float)m;
2784 }
2785
2786 x = 2 * (r.X * r.Z + r.Y * r.W);
2787 y = 2 * (-r.X * r.W + r.Y * r.Z);
2788 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2789
2790 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2791 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2792
2793 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2794
2795// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2590 Rotation = sitTargetOrient; 2796 Rotation = sitTargetOrient;
2591 ParentPosition = part.AbsolutePosition; 2797// ParentPosition = part.AbsolutePosition;
2798 part.ParentGroup.AddAvatar(UUID);
2592 } 2799 }
2593 else 2800 else
2594 { 2801 {
2595 m_pos -= part.AbsolutePosition; 2802 m_pos -= part.AbsolutePosition;
2596 ParentPosition = part.AbsolutePosition; 2803// ParentPosition = part.AbsolutePosition;
2804 part.ParentGroup.AddAvatar(UUID);
2597 2805
2598// m_log.DebugFormat( 2806// m_log.DebugFormat(
2599// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2807// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2651,6 +2859,13 @@ namespace OpenSim.Region.Framework.Scenes
2651 TriggerScenePresenceUpdated(); 2859 TriggerScenePresenceUpdated();
2652 } 2860 }
2653 2861
2862 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
2863 {
2864 Animator.avnChangeAnim(animID, addRemove, sendPack);
2865 }
2866
2867
2868
2654 /// <summary> 2869 /// <summary>
2655 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2870 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2656 /// </summary> 2871 /// </summary>
@@ -2707,8 +2922,8 @@ namespace OpenSim.Region.Framework.Scenes
2707 direc.Z *= 2.6f; 2922 direc.Z *= 2.6f;
2708 2923
2709 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2924 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2710 Animator.TrySetMovementAnimation("PREJUMP"); 2925// Animator.TrySetMovementAnimation("PREJUMP");
2711 Animator.TrySetMovementAnimation("JUMP"); 2926// Animator.TrySetMovementAnimation("JUMP");
2712 } 2927 }
2713 } 2928 }
2714 } 2929 }
@@ -2717,6 +2932,7 @@ namespace OpenSim.Region.Framework.Scenes
2717 2932
2718 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2933 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2719 m_forceToApply = direc; 2934 m_forceToApply = direc;
2935 Animator.UpdateMovementAnimations();
2720 } 2936 }
2721 2937
2722 #endregion 2938 #endregion
@@ -2734,16 +2950,12 @@ namespace OpenSim.Region.Framework.Scenes
2734 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 2950 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2735 // grab the latest PhysicsActor velocity, whereas m_velocity is often 2951 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2736 // storing a requested force instead of an actual traveling velocity 2952 // storing a requested force instead of an actual traveling velocity
2953 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
2954 SendAvatarDataToAllAgents();
2737 2955
2738 // Throw away duplicate or insignificant updates 2956 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2739 if ( 2957 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2740 // If the velocity has become zero, send it no matter what. 2958 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2741 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2742 // otherwise, if things have changed reasonably, send the update
2743 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2744 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2745 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2746
2747 { 2959 {
2748 SendTerseUpdateToAllClients(); 2960 SendTerseUpdateToAllClients();
2749 2961
@@ -2902,9 +3114,7 @@ namespace OpenSim.Region.Framework.Scenes
2902 // again here... this comes after the cached appearance check because the avatars 3114 // again here... this comes after the cached appearance check because the avatars
2903 // appearance goes into the avatar update packet 3115 // appearance goes into the avatar update packet
2904 SendAvatarDataToAllAgents(); 3116 SendAvatarDataToAllAgents();
2905 3117 SendAppearanceToAgent(this);
2906 // This invocation always shows up in the viewer logs as an error.
2907 // SendAppearanceToAgent(this);
2908 3118
2909 // If we are using the the cached appearance then send it out to everyone 3119 // If we are using the the cached appearance then send it out to everyone
2910 if (cachedappearance) 3120 if (cachedappearance)
@@ -2935,6 +3145,8 @@ namespace OpenSim.Region.Framework.Scenes
2935 return; 3145 return;
2936 } 3146 }
2937 3147
3148 m_lastSize = Appearance.AvatarSize;
3149
2938 int count = 0; 3150 int count = 0;
2939 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 3151 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2940 { 3152 {
@@ -3042,6 +3254,8 @@ namespace OpenSim.Region.Framework.Scenes
3042 3254
3043 avatar.ControllingClient.SendAppearance( 3255 avatar.ControllingClient.SendAppearance(
3044 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3256 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3257
3258
3045 } 3259 }
3046 3260
3047 #endregion 3261 #endregion
@@ -3115,8 +3329,9 @@ namespace OpenSim.Region.Framework.Scenes
3115 3329
3116 // If we don't have a PhysActor, we can't cross anyway 3330 // If we don't have a PhysActor, we can't cross anyway
3117 // Also don't do this while sat, sitting avatars cross with the 3331 // Also don't do this while sat, sitting avatars cross with the
3118 // object they sit on. 3332 // object they sit on. ParentUUID denoted a pending sit, don't
3119 if (ParentID != 0 || PhysicsActor == null) 3333 // interfere with it.
3334 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3120 return; 3335 return;
3121 3336
3122 if (!IsInTransit) 3337 if (!IsInTransit)
@@ -3379,6 +3594,11 @@ namespace OpenSim.Region.Framework.Scenes
3379 3594
3380 private static Vector3 marker = new Vector3(-1f, -1f, -1f); 3595 private static Vector3 marker = new Vector3(-1f, -1f, -1f);
3381 3596
3597 private void RaiseUpdateThrottles()
3598 {
3599 m_scene.EventManager.TriggerThrottleUpdate(this);
3600 }
3601
3382 /// <summary> 3602 /// <summary>
3383 /// This updates important decision making data about a child agent 3603 /// This updates important decision making data about a child agent
3384 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region 3604 /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
@@ -3460,6 +3680,9 @@ namespace OpenSim.Region.Framework.Scenes
3460 cAgent.AlwaysRun = SetAlwaysRun; 3680 cAgent.AlwaysRun = SetAlwaysRun;
3461 3681
3462 cAgent.Appearance = new AvatarAppearance(Appearance); 3682 cAgent.Appearance = new AvatarAppearance(Appearance);
3683
3684 cAgent.ParentPart = ParentUUID;
3685 cAgent.SitOffset = PrevSitOffset;
3463 3686
3464 lock (scriptedcontrols) 3687 lock (scriptedcontrols)
3465 { 3688 {
@@ -3468,7 +3691,7 @@ namespace OpenSim.Region.Framework.Scenes
3468 3691
3469 foreach (ScriptControllers c in scriptedcontrols.Values) 3692 foreach (ScriptControllers c in scriptedcontrols.Values)
3470 { 3693 {
3471 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3694 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3472 } 3695 }
3473 cAgent.Controllers = controls; 3696 cAgent.Controllers = controls;
3474 } 3697 }
@@ -3502,6 +3725,8 @@ namespace OpenSim.Region.Framework.Scenes
3502 CameraAtAxis = cAgent.AtAxis; 3725 CameraAtAxis = cAgent.AtAxis;
3503 CameraLeftAxis = cAgent.LeftAxis; 3726 CameraLeftAxis = cAgent.LeftAxis;
3504 CameraUpAxis = cAgent.UpAxis; 3727 CameraUpAxis = cAgent.UpAxis;
3728 ParentUUID = cAgent.ParentPart;
3729 PrevSitOffset = cAgent.SitOffset;
3505 3730
3506 // When we get to the point of re-computing neighbors everytime this 3731 // When we get to the point of re-computing neighbors everytime this
3507 // changes, then start using the agent's drawdistance rather than the 3732 // changes, then start using the agent's drawdistance rather than the
@@ -3539,6 +3764,7 @@ namespace OpenSim.Region.Framework.Scenes
3539 foreach (ControllerData c in cAgent.Controllers) 3764 foreach (ControllerData c in cAgent.Controllers)
3540 { 3765 {
3541 ScriptControllers sc = new ScriptControllers(); 3766 ScriptControllers sc = new ScriptControllers();
3767 sc.objectID = c.ObjectID;
3542 sc.itemID = c.ItemID; 3768 sc.itemID = c.ItemID;
3543 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3769 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3544 sc.eventControls = (ScriptControlled)c.EventControls; 3770 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3606,20 +3832,27 @@ namespace OpenSim.Region.Framework.Scenes
3606 } 3832 }
3607 3833
3608 if (Appearance.AvatarHeight == 0) 3834 if (Appearance.AvatarHeight == 0)
3609 Appearance.SetHeight(); 3835// Appearance.SetHeight();
3836 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3610 3837
3611 PhysicsScene scene = m_scene.PhysicsScene; 3838 PhysicsScene scene = m_scene.PhysicsScene;
3612 3839
3613 Vector3 pVec = AbsolutePosition; 3840 Vector3 pVec = AbsolutePosition;
3614 3841
3842/*
3615 PhysicsActor = scene.AddAvatar( 3843 PhysicsActor = scene.AddAvatar(
3616 LocalId, Firstname + "." + Lastname, pVec, 3844 LocalId, Firstname + "." + Lastname, pVec,
3617 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3845 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3846*/
3847
3848 PhysicsActor = scene.AddAvatar(
3849 LocalId, Firstname + "." + Lastname, pVec,
3850 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
3618 3851
3619 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3852 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3620 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3853 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3621 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3854 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3622 PhysicsActor.SubscribeEvents(500); 3855 PhysicsActor.SubscribeEvents(100);
3623 PhysicsActor.LocalID = LocalId; 3856 PhysicsActor.LocalID = LocalId;
3624 } 3857 }
3625 3858
@@ -3633,6 +3866,7 @@ namespace OpenSim.Region.Framework.Scenes
3633 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3866 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3634 } 3867 }
3635 3868
3869
3636 /// <summary> 3870 /// <summary>
3637 /// Event called by the physics plugin to tell the avatar about a collision. 3871 /// Event called by the physics plugin to tell the avatar about a collision.
3638 /// </summary> 3872 /// </summary>
@@ -3646,7 +3880,7 @@ namespace OpenSim.Region.Framework.Scenes
3646 /// <param name="e"></param> 3880 /// <param name="e"></param>
3647 public void PhysicsCollisionUpdate(EventArgs e) 3881 public void PhysicsCollisionUpdate(EventArgs e)
3648 { 3882 {
3649 if (IsChildAgent) 3883 if (IsChildAgent || Animator == null)
3650 return; 3884 return;
3651 3885
3652 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3886 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3663,7 +3897,6 @@ namespace OpenSim.Region.Framework.Scenes
3663 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3897 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3664 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3898 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3665 3899
3666 CollisionPlane = Vector4.UnitW;
3667 3900
3668// // No collisions at all means we may be flying. Update always 3901// // No collisions at all means we may be flying. Update always
3669// // to make falling work 3902// // to make falling work
@@ -3675,6 +3908,7 @@ namespace OpenSim.Region.Framework.Scenes
3675 3908
3676 if (coldata.Count != 0) 3909 if (coldata.Count != 0)
3677 { 3910 {
3911/*
3678 switch (Animator.CurrentMovementAnimation) 3912 switch (Animator.CurrentMovementAnimation)
3679 { 3913 {
3680 case "STAND": 3914 case "STAND":
@@ -3683,24 +3917,38 @@ namespace OpenSim.Region.Framework.Scenes
3683 case "CROUCH": 3917 case "CROUCH":
3684 case "CROUCHWALK": 3918 case "CROUCHWALK":
3685 { 3919 {
3920 */
3686 ContactPoint lowest; 3921 ContactPoint lowest;
3687 lowest.SurfaceNormal = Vector3.Zero; 3922 lowest.SurfaceNormal = Vector3.Zero;
3688 lowest.Position = Vector3.Zero; 3923 lowest.Position = Vector3.Zero;
3689 lowest.Position.Z = Single.NaN; 3924 lowest.Position.Z = float.MaxValue;
3690 3925
3691 foreach (ContactPoint contact in coldata.Values) 3926 foreach (ContactPoint contact in coldata.Values)
3692 { 3927 {
3693 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) 3928
3929 if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
3694 { 3930 {
3695 lowest = contact; 3931 lowest = contact;
3696 } 3932 }
3697 } 3933 }
3698 3934
3699 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); 3935 if (lowest.Position.Z != float.MaxValue)
3936 {
3937 lowest.SurfaceNormal = -lowest.SurfaceNormal;
3938 CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3939 }
3940 else
3941 CollisionPlane = Vector4.UnitW;
3942/*
3700 } 3943 }
3701 break; 3944 break;
3702 } 3945 }
3946*/
3703 } 3947 }
3948 else
3949 CollisionPlane = Vector4.UnitW;
3950
3951 RaiseCollisionScriptEvents(coldata);
3704 3952
3705 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3953 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3706 if (Invulnerable || GodLevel > 0) 3954 if (Invulnerable || GodLevel > 0)
@@ -3799,6 +4047,12 @@ namespace OpenSim.Region.Framework.Scenes
3799 // m_reprioritizationTimer.Dispose(); 4047 // m_reprioritizationTimer.Dispose();
3800 4048
3801 RemoveFromPhysicalScene(); 4049 RemoveFromPhysicalScene();
4050
4051 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
4052
4053// if (Animator != null)
4054// Animator.Close();
4055 Animator = null;
3802 4056
3803 LifecycleState = ScenePresenceState.Removed; 4057 LifecycleState = ScenePresenceState.Removed;
3804 } 4058 }
@@ -4034,10 +4288,18 @@ namespace OpenSim.Region.Framework.Scenes
4034 4288
4035 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4289 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
4036 { 4290 {
4291 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4292 if (p == null)
4293 return;
4294
4295 ControllingClient.SendTakeControls(controls, false, false);
4296 ControllingClient.SendTakeControls(controls, true, false);
4297
4037 ScriptControllers obj = new ScriptControllers(); 4298 ScriptControllers obj = new ScriptControllers();
4038 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4299 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4039 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4300 obj.eventControls = ScriptControlled.CONTROL_ZERO;
4040 4301
4302 obj.objectID = p.ParentGroup.UUID;
4041 obj.itemID = Script_item_UUID; 4303 obj.itemID = Script_item_UUID;
4042 if (pass_on == 0 && accept == 0) 4304 if (pass_on == 0 && accept == 0)
4043 { 4305 {
@@ -4086,6 +4348,21 @@ namespace OpenSim.Region.Framework.Scenes
4086 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4348 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4087 } 4349 }
4088 4350
4351 private void UnRegisterSeatControls(UUID obj)
4352 {
4353 List<UUID> takers = new List<UUID>();
4354
4355 foreach (ScriptControllers c in scriptedcontrols.Values)
4356 {
4357 if (c.objectID == obj)
4358 takers.Add(c.itemID);
4359 }
4360 foreach (UUID t in takers)
4361 {
4362 UnRegisterControlEventsToScript(0, t);
4363 }
4364 }
4365
4089 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4366 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4090 { 4367 {
4091 ScriptControllers takecontrols; 4368 ScriptControllers takecontrols;
@@ -4415,6 +4692,12 @@ namespace OpenSim.Region.Framework.Scenes
4415 4692
4416 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4693 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4417 { 4694 {
4695 string reason;
4696
4697 // Honor bans
4698 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4699 return;
4700
4418 SceneObjectGroup telehub = null; 4701 SceneObjectGroup telehub = null;
4419 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4702 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4420 { 4703 {
@@ -4454,11 +4737,206 @@ namespace OpenSim.Region.Framework.Scenes
4454 pos = land.LandData.UserLocation; 4737 pos = land.LandData.UserLocation;
4455 } 4738 }
4456 } 4739 }
4457 4740
4458 land.SendLandUpdateToClient(ControllingClient); 4741 land.SendLandUpdateToClient(ControllingClient);
4459 } 4742 }
4460 } 4743 }
4461 4744
4745 private DetectedObject CreateDetObject(SceneObjectPart obj)
4746 {
4747 DetectedObject detobj = new DetectedObject();
4748 detobj.keyUUID = obj.UUID;
4749 detobj.nameStr = obj.Name;
4750 detobj.ownerUUID = obj.OwnerID;
4751 detobj.posVector = obj.AbsolutePosition;
4752 detobj.rotQuat = obj.GetWorldRotation();
4753 detobj.velVector = obj.Velocity;
4754 detobj.colliderType = 0;
4755 detobj.groupUUID = obj.GroupID;
4756
4757 return detobj;
4758 }
4759
4760 private DetectedObject CreateDetObject(ScenePresence av)
4761 {
4762 DetectedObject detobj = new DetectedObject();
4763 detobj.keyUUID = av.UUID;
4764 detobj.nameStr = av.ControllingClient.Name;
4765 detobj.ownerUUID = av.UUID;
4766 detobj.posVector = av.AbsolutePosition;
4767 detobj.rotQuat = av.Rotation;
4768 detobj.velVector = av.Velocity;
4769 detobj.colliderType = 0;
4770 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4771
4772 return detobj;
4773 }
4774
4775 private DetectedObject CreateDetObjectForGround()
4776 {
4777 DetectedObject detobj = new DetectedObject();
4778 detobj.keyUUID = UUID.Zero;
4779 detobj.nameStr = "";
4780 detobj.ownerUUID = UUID.Zero;
4781 detobj.posVector = AbsolutePosition;
4782 detobj.rotQuat = Quaternion.Identity;
4783 detobj.velVector = Vector3.Zero;
4784 detobj.colliderType = 0;
4785 detobj.groupUUID = UUID.Zero;
4786
4787 return detobj;
4788 }
4789
4790 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4791 {
4792 ColliderArgs colliderArgs = new ColliderArgs();
4793 List<DetectedObject> colliding = new List<DetectedObject>();
4794 foreach (uint localId in colliders)
4795 {
4796 if (localId == 0)
4797 continue;
4798
4799 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4800 if (obj != null)
4801 {
4802 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4803 colliding.Add(CreateDetObject(obj));
4804 }
4805 else
4806 {
4807 ScenePresence av = m_scene.GetScenePresence(localId);
4808 if (av != null && (!av.IsChildAgent))
4809 {
4810 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4811 colliding.Add(CreateDetObject(av));
4812 }
4813 }
4814 }
4815
4816 colliderArgs.Colliders = colliding;
4817
4818 return colliderArgs;
4819 }
4820
4821 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4822
4823 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4824 {
4825 ColliderArgs CollidingMessage;
4826
4827 if (colliders.Count > 0)
4828 {
4829 if ((dest.RootPart.ScriptEvents & ev) != 0)
4830 {
4831 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4832
4833 if (CollidingMessage.Colliders.Count > 0)
4834 notify(dest.RootPart.LocalId, CollidingMessage);
4835 }
4836 }
4837 }
4838
4839 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4840 {
4841 if ((dest.RootPart.ScriptEvents & ev) != 0)
4842 {
4843 ColliderArgs LandCollidingMessage = new ColliderArgs();
4844 List<DetectedObject> colliding = new List<DetectedObject>();
4845
4846 colliding.Add(CreateDetObjectForGround());
4847 LandCollidingMessage.Colliders = colliding;
4848
4849 notify(dest.RootPart.LocalId, LandCollidingMessage);
4850 }
4851 }
4852
4853 private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
4854 {
4855 try
4856 {
4857 List<uint> thisHitColliders = new List<uint>();
4858 List<uint> endedColliders = new List<uint>();
4859 List<uint> startedColliders = new List<uint>();
4860 List<CollisionForSoundInfo> soundinfolist = new List<CollisionForSoundInfo>();
4861 CollisionForSoundInfo soundinfo;
4862 ContactPoint curcontact;
4863
4864 if (coldata.Count == 0)
4865 {
4866 if (m_lastColliders.Count == 0)
4867 return; // nothing to do
4868
4869 foreach (uint localID in m_lastColliders)
4870 {
4871 endedColliders.Add(localID);
4872 }
4873 m_lastColliders.Clear();
4874 }
4875
4876 else
4877 {
4878 foreach (uint id in coldata.Keys)
4879 {
4880 thisHitColliders.Add(id);
4881 if (!m_lastColliders.Contains(id))
4882 {
4883 startedColliders.Add(id);
4884 curcontact = coldata[id];
4885 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
4886 {
4887 soundinfo = new CollisionForSoundInfo();
4888 soundinfo.colliderID = id;
4889 soundinfo.position = curcontact.Position;
4890 soundinfo.relativeVel = curcontact.RelativeSpeed;
4891 soundinfolist.Add(soundinfo);
4892 }
4893 }
4894 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
4895 }
4896
4897 // calculate things that ended colliding
4898 foreach (uint localID in m_lastColliders)
4899 {
4900 if (!thisHitColliders.Contains(localID))
4901 {
4902 endedColliders.Add(localID);
4903 }
4904 }
4905 //add the items that started colliding this time to the last colliders list.
4906 foreach (uint localID in startedColliders)
4907 {
4908 m_lastColliders.Add(localID);
4909 }
4910 // remove things that ended colliding from the last colliders list
4911 foreach (uint localID in endedColliders)
4912 {
4913 m_lastColliders.Remove(localID);
4914 }
4915
4916 if (soundinfolist.Count > 0)
4917 CollisionSounds.AvatarCollisionSound(this, soundinfolist);
4918 }
4919
4920 foreach (SceneObjectGroup att in GetAttachments())
4921 {
4922 SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
4923 SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
4924 SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
4925
4926 if (startedColliders.Contains(0))
4927 SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
4928 if (m_lastColliders.Contains(0))
4929 SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
4930 if (endedColliders.Contains(0))
4931 SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
4932 }
4933 }
4934 finally
4935 {
4936 m_collisionEventFlag = false;
4937 }
4938 }
4939
4462 private void TeleportFlagsDebug() { 4940 private void TeleportFlagsDebug() {
4463 4941
4464 // Some temporary debugging help to show all the TeleportFlags we have... 4942 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4483,6 +4961,5 @@ namespace OpenSim.Region.Framework.Scenes
4483 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4961 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4484 4962
4485 } 4963 }
4486
4487 } 4964 }
4488} 4965}