aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs42
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs1019
3 files changed, 713 insertions, 354 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
index 34aca33..d25c930 100644
--- a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
@@ -35,8 +35,8 @@ namespace OpenSim.Region.Framework.Interfaces
35 35
36 public interface IAvatarFactoryModule 36 public interface IAvatarFactoryModule
37 { 37 {
38 void SetAppearance(IScenePresence sp, AvatarAppearance appearance); 38 void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems);
39 void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams); 39 void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems);
40 40
41 /// <summary> 41 /// <summary>
42 /// Send the appearance of an avatar to others in the scene. 42 /// Send the appearance of an avatar to others in the scene.
@@ -52,6 +52,8 @@ namespace OpenSim.Region.Framework.Interfaces
52 /// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns> 52 /// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns>
53 Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId); 53 Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId);
54 54
55
56 WearableCacheItem[] GetCachedItems(UUID agentId);
55 /// <summary> 57 /// <summary>
56 /// Save the baked textures for the given agent permanently in the asset database. 58 /// Save the baked textures for the given agent permanently in the asset database.
57 /// </summary> 59 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4b4e4ba..f16a8e6 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -118,6 +118,7 @@ namespace OpenSim.Region.Framework.Scenes
118 private bool m_hasGroupChanged = false; 118 private bool m_hasGroupChanged = false;
119 private long timeFirstChanged; 119 private long timeFirstChanged;
120 private long timeLastChanged; 120 private long timeLastChanged;
121 private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>();
121 122
122 /// <summary> 123 /// <summary>
123 /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage 124 /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
@@ -1096,6 +1097,7 @@ namespace OpenSim.Region.Framework.Scenes
1096 } 1097 }
1097 } 1098 }
1098 1099
1100
1099 /// <summary> 1101 /// <summary>
1100 /// 1102 ///
1101 /// </summary> 1103 /// </summary>
@@ -1105,6 +1107,46 @@ namespace OpenSim.Region.Framework.Scenes
1105 part.ParentID = m_rootPart.LocalId; 1107 part.ParentID = m_rootPart.LocalId;
1106 part.ClearUndoState(); 1108 part.ClearUndoState();
1107 } 1109 }
1110 /// <summary>
1111 /// Add the avatar to this linkset (avatar is sat).
1112 /// </summary>
1113 /// <param name="agentID"></param>
1114 public void AddAvatar(UUID agentID)
1115 {
1116 ScenePresence presence;
1117 if (m_scene.TryGetScenePresence(agentID, out presence))
1118 {
1119 if (!m_linkedAvatars.Contains(presence))
1120 {
1121 m_linkedAvatars.Add(presence);
1122 }
1123 }
1124 }
1125
1126 /// <summary>
1127 /// Delete the avatar from this linkset (avatar is unsat).
1128 /// </summary>
1129 /// <param name="agentID"></param>
1130 public void DeleteAvatar(UUID agentID)
1131 {
1132 ScenePresence presence;
1133 if (m_scene.TryGetScenePresence(agentID, out presence))
1134 {
1135 if (m_linkedAvatars.Contains(presence))
1136 {
1137 m_linkedAvatars.Remove(presence);
1138 }
1139 }
1140 }
1141
1142 /// <summary>
1143 /// Returns the list of linked presences (avatars sat on this group)
1144 /// </summary>
1145 /// <param name="agentID"></param>
1146 public List<ScenePresence> GetLinkedAvatars()
1147 {
1148 return m_linkedAvatars;
1149 }
1108 1150
1109 public ushort GetTimeDilation() 1151 public ushort GetTimeDilation()
1110 { 1152 {
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 7ed3a4b..edb8ca8 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
@@ -397,6 +406,9 @@ namespace OpenSim.Region.Framework.Scenes
397 /// </summary> 406 /// </summary>
398 protected Vector3 m_lastCameraPosition; 407 protected Vector3 m_lastCameraPosition;
399 408
409 private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
410 private bool m_doingCamRayCast = false;
411
400 public Vector3 CameraPosition { get; set; } 412 public Vector3 CameraPosition { get; set; }
401 413
402 public Quaternion CameraRotation 414 public Quaternion CameraRotation
@@ -477,6 +489,10 @@ namespace OpenSim.Region.Framework.Scenes
477 get { return (IClientCore)ControllingClient; } 489 get { return (IClientCore)ControllingClient; }
478 } 490 }
479 491
492 public UUID COF { get; set; }
493
494// public Vector3 ParentPosition { get; set; }
495
480 /// <summary> 496 /// <summary>
481 /// Position of this avatar relative to the region the avatar is in 497 /// Position of this avatar relative to the region the avatar is in
482 /// </summary> 498 /// </summary>
@@ -603,7 +619,24 @@ namespace OpenSim.Region.Framework.Scenes
603// Scene.RegionInfo.RegionName, Name, m_velocity); 619// Scene.RegionInfo.RegionName, Name, m_velocity);
604 } 620 }
605 } 621 }
622/*
623 public override Vector3 AngularVelocity
624 {
625 get
626 {
627 if (PhysicsActor != null)
628 {
629 m_rotationalvelocity = PhysicsActor.RotationalVelocity;
630
631 // m_log.DebugFormat(
632 // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
633 // m_velocity, Name, Scene.RegionInfo.RegionName);
634 }
606 635
636 return m_rotationalvelocity;
637 }
638 }
639*/
607 private Quaternion m_bodyRot = Quaternion.Identity; 640 private Quaternion m_bodyRot = Quaternion.Identity;
608 641
609 /// <summary> 642 /// <summary>
@@ -626,8 +659,16 @@ namespace OpenSim.Region.Framework.Scenes
626 m_bodyRot = value; 659 m_bodyRot = value;
627 660
628 if (PhysicsActor != null) 661 if (PhysicsActor != null)
629 PhysicsActor.Orientation = m_bodyRot; 662 {
630 663 try
664 {
665 PhysicsActor.Orientation = m_bodyRot;
666 }
667 catch (Exception e)
668 {
669 m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
670 }
671 }
631// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 672// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
632 } 673 }
633 } 674 }
@@ -641,12 +682,20 @@ namespace OpenSim.Region.Framework.Scenes
641 } 682 }
642 683
643 public bool IsChildAgent { get; set; } 684 public bool IsChildAgent { get; set; }
685 public bool IsLoggingIn { get; set; }
644 686
645 /// <summary> 687 /// <summary>
646 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero. 688 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
647 /// </summary> 689 /// </summary>
648 public uint ParentID { get; set; } 690 public uint ParentID { get; set; }
649 691
692 public UUID ParentUUID
693 {
694 get { return m_parentUUID; }
695 set { m_parentUUID = value; }
696 }
697 private UUID m_parentUUID = UUID.Zero;
698
650 /// <summary> 699 /// <summary>
651 /// Are we sitting on an object? 700 /// Are we sitting on an object?
652 /// </summary> 701 /// </summary>
@@ -804,6 +853,7 @@ namespace OpenSim.Region.Framework.Scenes
804 AttachmentsSyncLock = new Object(); 853 AttachmentsSyncLock = new Object();
805 AllowMovement = true; 854 AllowMovement = true;
806 IsChildAgent = true; 855 IsChildAgent = true;
856 IsLoggingIn = false;
807 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; 857 m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
808 Animator = new ScenePresenceAnimator(this); 858 Animator = new ScenePresenceAnimator(this);
809 PresenceType = type; 859 PresenceType = type;
@@ -849,6 +899,33 @@ namespace OpenSim.Region.Framework.Scenes
849 m_stateMachine = new ScenePresenceStateMachine(this); 899 m_stateMachine = new ScenePresenceStateMachine(this);
850 } 900 }
851 901
902 private void RegionHeartbeatEnd(Scene scene)
903 {
904 if (IsChildAgent)
905 return;
906
907 m_movementAnimationUpdateCounter ++;
908 if (m_movementAnimationUpdateCounter >= 2)
909 {
910 m_movementAnimationUpdateCounter = 0;
911 if (Animator != null)
912 {
913 // If the parentID == 0 we are not sitting
914 // if !SitGournd then we are not sitting on the ground
915 // Fairly straightforward, now here comes the twist
916 // if ParentUUID is NOT UUID.Zero, we are looking to
917 // be sat on an object that isn't there yet. Should
918 // be treated as if sat.
919 if(ParentID == 0 && !SitGround && ParentUUID == UUID.Zero) // skip it if sitting
920 Animator.UpdateMovementAnimations();
921 }
922 else
923 {
924 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
925 }
926 }
927 }
928
852 public void RegisterToEvents() 929 public void RegisterToEvents()
853 { 930 {
854 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 931 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -919,6 +996,38 @@ namespace OpenSim.Region.Framework.Scenes
919// "[SCENE]: Upgrading child to root agent for {0} in {1}", 996// "[SCENE]: Upgrading child to root agent for {0} in {1}",
920// Name, m_scene.RegionInfo.RegionName); 997// Name, m_scene.RegionInfo.RegionName);
921 998
999 if (ParentUUID != UUID.Zero)
1000 {
1001 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1002 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1003 if (part == null)
1004 {
1005 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1006 }
1007 else
1008 {
1009 part.ParentGroup.AddAvatar(UUID);
1010 if (part.SitTargetPosition != Vector3.Zero)
1011 part.SitTargetAvatar = UUID;
1012// ParentPosition = part.GetWorldPosition();
1013 ParentID = part.LocalId;
1014 ParentPart = part;
1015 m_pos = PrevSitOffset;
1016// pos = ParentPosition;
1017 pos = part.GetWorldPosition();
1018 }
1019 ParentUUID = UUID.Zero;
1020
1021 IsChildAgent = false;
1022
1023// Animator.TrySetMovementAnimation("SIT");
1024 }
1025 else
1026 {
1027 IsChildAgent = false;
1028 IsLoggingIn = false;
1029 }
1030
922 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 1031 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
923 1032
924 IsChildAgent = false; 1033 IsChildAgent = false;
@@ -936,70 +1045,106 @@ namespace OpenSim.Region.Framework.Scenes
936 1045
937 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1046 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
938 1047
939 // Moved this from SendInitialData to ensure that Appearance is initialized 1048 UUID groupUUID = UUID.Zero;
940 // before the inventory is processed in MakeRootAgent. This fixes a race condition 1049 string GroupName = string.Empty;
941 // related to the handling of attachments 1050 ulong groupPowers = 0;
942 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
943 1051
944 if (m_scene.TestBorderCross(pos, Cardinals.E)) 1052 // ----------------------------------
1053 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1054 try
945 { 1055 {
946 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 1056 if (gm != null)
947 pos.X = crossedBorder.BorderLine.Z - 1; 1057 {
1058 groupUUID = ControllingClient.ActiveGroupId;
1059 GroupRecord record = gm.GetGroupRecord(groupUUID);
1060 if (record != null)
1061 GroupName = record.GroupName;
1062 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1063 if (groupMembershipData != null)
1064 groupPowers = groupMembershipData.GroupPowers;
1065 }
1066 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1067 Grouptitle);
948 } 1068 }
949 1069 catch (Exception e)
950 if (m_scene.TestBorderCross(pos, Cardinals.N))
951 { 1070 {
952 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 1071 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
953 pos.Y = crossedBorder.BorderLine.Z - 1;
954 } 1072 }
1073 // ------------------------------------
955 1074
956 CheckAndAdjustLandingPoint(ref pos); 1075 if (ParentID == 0)
957
958 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
959 { 1076 {
960 m_log.WarnFormat( 1077 // Moved this from SendInitialData to ensure that Appearance is initialized
961 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1078 // before the inventory is processed in MakeRootAgent. This fixes a race condition
962 pos, Name, UUID); 1079 // related to the handling of attachments
1080 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
1081 if (m_scene.TestBorderCross(pos, Cardinals.E))
1082 {
1083 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1084 pos.X = crossedBorder.BorderLine.Z - 1;
1085 }
963 1086
964 if (pos.X < 0f) pos.X = 0f; 1087 if (m_scene.TestBorderCross(pos, Cardinals.N))
965 if (pos.Y < 0f) pos.Y = 0f; 1088 {
966 if (pos.Z < 0f) pos.Z = 0f; 1089 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
967 } 1090 pos.Y = crossedBorder.BorderLine.Z - 1;
1091 }
968 1092
969 float localAVHeight = 1.56f; 1093 CheckAndAdjustLandingPoint(ref pos);
970 if (Appearance.AvatarHeight > 0)
971 localAVHeight = Appearance.AvatarHeight;
972 1094
973 float posZLimit = 0; 1095 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1096 {
1097 m_log.WarnFormat(
1098 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1099 pos, Name, UUID);
974 1100
975 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1101 if (pos.X < 0f) pos.X = 0f;
976 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1102 if (pos.Y < 0f) pos.Y = 0f;
977 1103 if (pos.Z < 0f) pos.Z = 0f;
978 float newPosZ = posZLimit + localAVHeight / 2; 1104 }
979 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
980 {
981 pos.Z = newPosZ;
982 }
983 AbsolutePosition = pos;
984 1105
985 AddToPhysicalScene(isFlying); 1106 float localAVHeight = 1.56f;
1107 if (Appearance.AvatarHeight > 0)
1108 localAVHeight = Appearance.AvatarHeight;
986 1109
987 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1110 float posZLimit = 0;
988 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
989 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
990 // the value to a negative position which does not trigger the border cross.
991 // This may not be the best location for this.
992 CheckForBorderCrossing();
993 1111
994 if (ForceFly) 1112 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
995 { 1113 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
996 Flying = true; 1114
997 } 1115 float newPosZ = posZLimit + localAVHeight / 2;
998 else if (FlyDisabled) 1116 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
999 { 1117 {
1000 Flying = false; 1118 pos.Z = newPosZ;
1001 } 1119 }
1120 AbsolutePosition = pos;
1121
1122 if (m_teleportFlags == TeleportFlags.Default)
1123 {
1124 Vector3 vel = Velocity;
1125 AddToPhysicalScene(isFlying);
1126 if (PhysicsActor != null)
1127 PhysicsActor.SetMomentum(vel);
1128 }
1129 else
1130 AddToPhysicalScene(isFlying);
1131
1132 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1133 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1134 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1135 // the value to a negative position which does not trigger the border cross.
1136 // This may not be the best location for this.
1137 CheckForBorderCrossing();
1002 1138
1139 if (ForceFly)
1140 {
1141 Flying = true;
1142 }
1143 else if (FlyDisabled)
1144 {
1145 Flying = false;
1146 }
1147 }
1003 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 1148 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
1004 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 1149 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1005 // elsewhere anyway 1150 // elsewhere anyway
@@ -1031,31 +1176,28 @@ namespace OpenSim.Region.Framework.Scenes
1031 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1176 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1032 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1177 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1033 // not transporting the required data. 1178 // not transporting the required data.
1034 // 1179 lock (m_attachments)
1035 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1036 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1037 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
1038 //
1039 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
1040 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1041 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1042 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1043 List<SceneObjectGroup> attachments = GetAttachments();
1044
1045 if (attachments.Count > 0)
1046 { 1180 {
1047 m_log.DebugFormat( 1181 if (HasAttachments())
1048 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1049
1050 // Resume scripts
1051 foreach (SceneObjectGroup sog in attachments)
1052 { 1182 {
1053 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1183 m_log.DebugFormat(
1054 sog.ResumeScripts(); 1184 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1185
1186 // Resume scripts
1187 Util.FireAndForget(delegate(object x) {
1188 foreach (SceneObjectGroup sog in m_attachments)
1189 {
1190 sog.ScheduleGroupForFullUpdate();
1191 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1192 sog.ResumeScripts();
1193 }
1194 });
1055 } 1195 }
1056 } 1196 }
1057 } 1197 }
1058 1198
1199 SendAvatarDataToAllAgents();
1200
1059 // send the animations of the other presences to me 1201 // send the animations of the other presences to me
1060 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence) 1202 m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
1061 { 1203 {
@@ -1066,6 +1208,7 @@ namespace OpenSim.Region.Framework.Scenes
1066 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will 1208 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1067 // stall on the border crossing since the existing child agent will still have the last movement 1209 // stall on the border crossing since the existing child agent will still have the last movement
1068 // recorded, which stops the input from being processed. 1210 // recorded, which stops the input from being processed.
1211
1069 MovementFlag = 0; 1212 MovementFlag = 0;
1070 1213
1071 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1214 m_scene.EventManager.TriggerOnMakeRootAgent(this);
@@ -1097,12 +1240,16 @@ namespace OpenSim.Region.Framework.Scenes
1097 /// </remarks> 1240 /// </remarks>
1098 public void MakeChildAgent() 1241 public void MakeChildAgent()
1099 { 1242 {
1243 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
1244
1100 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); 1245 m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
1101 1246
1102 // Reset these so that teleporting in and walking out isn't seen 1247 // Reset these so that teleporting in and walking out isn't seen
1103 // as teleporting back 1248 // as teleporting back
1104 TeleportFlags = TeleportFlags.Default; 1249 TeleportFlags = TeleportFlags.Default;
1105 1250
1251 MovementFlag = 0;
1252
1106 // It looks like Animator is set to null somewhere, and MakeChild 1253 // It looks like Animator is set to null somewhere, and MakeChild
1107 // is called after that. Probably in aborted teleports. 1254 // is called after that. Probably in aborted teleports.
1108 if (Animator == null) 1255 if (Animator == null)
@@ -1110,6 +1257,7 @@ namespace OpenSim.Region.Framework.Scenes
1110 else 1257 else
1111 Animator.ResetAnimations(); 1258 Animator.ResetAnimations();
1112 1259
1260
1113// m_log.DebugFormat( 1261// m_log.DebugFormat(
1114// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", 1262// "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
1115// Name, UUID, m_scene.RegionInfo.RegionName); 1263// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1121,6 +1269,7 @@ namespace OpenSim.Region.Framework.Scenes
1121 IsChildAgent = true; 1269 IsChildAgent = true;
1122 m_scene.SwapRootAgentCount(true); 1270 m_scene.SwapRootAgentCount(true);
1123 RemoveFromPhysicalScene(); 1271 RemoveFromPhysicalScene();
1272 ParentID = 0; // Child agents can't be sitting
1124 1273
1125 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into 1274 // FIXME: Set RegionHandle to the region handle of the scene this agent is moving into
1126 1275
@@ -1136,9 +1285,9 @@ namespace OpenSim.Region.Framework.Scenes
1136 { 1285 {
1137// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1286// PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1138 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1287 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
1139 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1140 PhysicsActor.UnSubscribeEvents();
1141 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1288 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1289 PhysicsActor.UnSubscribeEvents();
1290 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1142 PhysicsActor = null; 1291 PhysicsActor = null;
1143 } 1292 }
1144// else 1293// else
@@ -1155,7 +1304,7 @@ namespace OpenSim.Region.Framework.Scenes
1155 /// <param name="pos"></param> 1304 /// <param name="pos"></param>
1156 public void Teleport(Vector3 pos) 1305 public void Teleport(Vector3 pos)
1157 { 1306 {
1158 TeleportWithMomentum(pos, null); 1307 TeleportWithMomentum(pos, Vector3.Zero);
1159 } 1308 }
1160 1309
1161 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1310 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
@@ -1179,6 +1328,41 @@ namespace OpenSim.Region.Framework.Scenes
1179 SendTerseUpdateToAllClients(); 1328 SendTerseUpdateToAllClients();
1180 } 1329 }
1181 1330
1331 public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY)
1332 {
1333 CheckLandingPoint(ref newpos);
1334 AbsolutePosition = newpos;
1335
1336 if (newvel.HasValue)
1337 {
1338 if ((Vector3)newvel == Vector3.Zero)
1339 {
1340 if (PhysicsActor != null)
1341 PhysicsActor.SetMomentum(Vector3.Zero);
1342 m_velocity = Vector3.Zero;
1343 }
1344 else
1345 {
1346 if (PhysicsActor != null)
1347 PhysicsActor.SetMomentum((Vector3)newvel);
1348 m_velocity = (Vector3)newvel;
1349
1350 if (rotateToVelXY)
1351 {
1352 Vector3 lookAt = (Vector3)newvel;
1353 lookAt.Z = 0;
1354 lookAt.Normalize();
1355 ControllingClient.SendLocalTeleport(newpos, lookAt, (uint)TeleportFlags.ViaLocation);
1356 return;
1357 }
1358 }
1359 }
1360
1361 SendTerseUpdateToAllClients();
1362 }
1363
1364
1365
1182 public void StopFlying() 1366 public void StopFlying()
1183 { 1367 {
1184 Vector3 pos = AbsolutePosition; 1368 Vector3 pos = AbsolutePosition;
@@ -1367,6 +1551,14 @@ namespace OpenSim.Region.Framework.Scenes
1367 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); 1551 PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
1368 } 1552 }
1369 1553
1554 public void SetSize(Vector3 size, float feetoffset)
1555 {
1556// TODO: Merge the physics bits
1557// if (PhysicsActor != null && !IsChildAgent)
1558// PhysicsActor.setAvatarSize(size, feetoffset);
1559
1560 }
1561
1370 private bool WaitForUpdateAgent(IClientAPI client) 1562 private bool WaitForUpdateAgent(IClientAPI client)
1371 { 1563 {
1372 // Before the source region executes UpdateAgent 1564 // Before the source region executes UpdateAgent
@@ -1426,7 +1618,8 @@ namespace OpenSim.Region.Framework.Scenes
1426 1618
1427 Vector3 look = Velocity; 1619 Vector3 look = Velocity;
1428 1620
1429 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1621 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1622 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1430 { 1623 {
1431 look = new Vector3(0.99f, 0.042f, 0); 1624 look = new Vector3(0.99f, 0.042f, 0);
1432 } 1625 }
@@ -1489,11 +1682,12 @@ namespace OpenSim.Region.Framework.Scenes
1489 { 1682 {
1490 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1683 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1491 if (m_agentTransfer != null) 1684 if (m_agentTransfer != null)
1492 Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); 1685 m_agentTransfer.EnableChildAgents(this);
1493 1686
1494 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1687 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1495 if (friendsModule != null) 1688 if (friendsModule != null)
1496 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1689 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1690
1497 } 1691 }
1498 1692
1499 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1693 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
@@ -1519,36 +1713,69 @@ namespace OpenSim.Region.Framework.Scenes
1519 /// <param name="collisionPoint"></param> 1713 /// <param name="collisionPoint"></param>
1520 /// <param name="localid"></param> 1714 /// <param name="localid"></param>
1521 /// <param name="distance"></param> 1715 /// <param name="distance"></param>
1716 ///
1717
1718 private void UpdateCameraCollisionPlane(Vector4 plane)
1719 {
1720 if (m_lastCameraCollisionPlane != plane)
1721 {
1722 m_lastCameraCollisionPlane = plane;
1723 ControllingClient.SendCameraConstraint(plane);
1724 }
1725 }
1726
1522 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) 1727 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1523 { 1728 {
1524 const float POSITION_TOLERANCE = 0.02f; 1729 const float POSITION_TOLERANCE = 0.02f;
1525 const float VELOCITY_TOLERANCE = 0.02f;
1526 const float ROTATION_TOLERANCE = 0.02f; 1730 const float ROTATION_TOLERANCE = 0.02f;
1527 1731
1528 if (m_followCamAuto) 1732 m_doingCamRayCast = false;
1733 if (hitYN && localid != LocalId)
1529 { 1734 {
1530 if (hitYN) 1735 SceneObjectGroup group = m_scene.GetGroupByPrim(localid);
1736 bool IsPrim = group != null;
1737 if (IsPrim)
1531 { 1738 {
1532 CameraConstraintActive = true; 1739 SceneObjectPart part = group.GetPart(localid);
1533 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); 1740 if (part != null && !part.VolumeDetectActive)
1534 1741 {
1535 Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); 1742 CameraConstraintActive = true;
1536 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); 1743 pNormal.X = (float) Math.Round(pNormal.X, 2);
1744 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1745 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1746 pNormal.Normalize();
1747 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1748 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1749 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1750
1751 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1752 Vector3.Dot(collisionPoint, pNormal));
1753 UpdateCameraCollisionPlane(plane);
1754 }
1537 } 1755 }
1538 else 1756 else
1539 { 1757 {
1540 if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 1758 CameraConstraintActive = true;
1541 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 1759 pNormal.X = (float) Math.Round(pNormal.X, 2);
1542 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) 1760 pNormal.Y = (float) Math.Round(pNormal.Y, 2);
1543 { 1761 pNormal.Z = (float) Math.Round(pNormal.Z, 2);
1544 if (CameraConstraintActive) 1762 pNormal.Normalize();
1545 { 1763 collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
1546 ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); 1764 collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
1547 CameraConstraintActive = false; 1765 collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
1548 } 1766
1549 } 1767 Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z,
1768 Vector3.Dot(collisionPoint, pNormal));
1769 UpdateCameraCollisionPlane(plane);
1550 } 1770 }
1551 } 1771 }
1772 else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
1773 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
1774 {
1775 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
1776 UpdateCameraCollisionPlane(plane);
1777 CameraConstraintActive = false;
1778 }
1552 } 1779 }
1553 1780
1554 /// <summary> 1781 /// <summary>
@@ -1622,6 +1849,41 @@ namespace OpenSim.Region.Framework.Scenes
1622 StandUp(); 1849 StandUp();
1623 } 1850 }
1624 1851
1852 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1853 // this exclude checks may not be complete
1854
1855 if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
1856 {
1857 if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
1858 {
1859 Vector3 posAdjusted = AbsolutePosition;
1860// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
1861 posAdjusted.Z += 1.0f; // viewer current camera focus point
1862 Vector3 tocam = CameraPosition - posAdjusted;
1863 tocam.X = (float)Math.Round(tocam.X, 1);
1864 tocam.Y = (float)Math.Round(tocam.Y, 1);
1865 tocam.Z = (float)Math.Round(tocam.Z, 1);
1866
1867 float distTocamlen = tocam.Length();
1868 if (distTocamlen > 0.3f)
1869 {
1870 tocam *= (1.0f / distTocamlen);
1871 posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
1872 posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
1873 posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
1874
1875 m_doingCamRayCast = true;
1876 m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
1877 }
1878 }
1879 else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
1880 {
1881 Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
1882 UpdateCameraCollisionPlane(plane);
1883 CameraConstraintActive = false;
1884 }
1885 }
1886
1625 uint flagsForScripts = (uint)flags; 1887 uint flagsForScripts = (uint)flags;
1626 flags = RemoveIgnoredControls(flags, IgnoredControls); 1888 flags = RemoveIgnoredControls(flags, IgnoredControls);
1627 1889
@@ -2180,7 +2442,8 @@ namespace OpenSim.Region.Framework.Scenes
2180// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 2442// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
2181 2443
2182 MovingToTarget = false; 2444 MovingToTarget = false;
2183 MoveToPositionTarget = Vector3.Zero; 2445// MoveToPositionTarget = Vector3.Zero;
2446 m_forceToApply = null; // cancel possible last action
2184 2447
2185 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct 2448 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
2186 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. 2449 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@@ -2203,6 +2466,9 @@ namespace OpenSim.Region.Framework.Scenes
2203 2466
2204 if (satOnObject) 2467 if (satOnObject)
2205 { 2468 {
2469 PrevSitOffset = m_pos; // Save sit offset
2470 UnRegisterSeatControls(part.ParentGroup.UUID);
2471
2206 TaskInventoryDictionary taskIDict = part.TaskInventory; 2472 TaskInventoryDictionary taskIDict = part.TaskInventory;
2207 if (taskIDict != null) 2473 if (taskIDict != null)
2208 { 2474 {
@@ -2218,6 +2484,7 @@ namespace OpenSim.Region.Framework.Scenes
2218 } 2484 }
2219 } 2485 }
2220 2486
2487 part.ParentGroup.DeleteAvatar(UUID);
2221 Vector3 sitPartWorldPosition = part.GetWorldPosition(); 2488 Vector3 sitPartWorldPosition = part.GetWorldPosition();
2222 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2489 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2223 2490
@@ -2278,6 +2545,9 @@ namespace OpenSim.Region.Framework.Scenes
2278 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2545 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2279 } 2546 }
2280 2547
2548 else if (PhysicsActor == null)
2549 AddToPhysicalScene(false);
2550
2281 Animator.TrySetMovementAnimation("STAND"); 2551 Animator.TrySetMovementAnimation("STAND");
2282 TriggerScenePresenceUpdated(); 2552 TriggerScenePresenceUpdated();
2283 } 2553 }
@@ -2326,11 +2596,8 @@ namespace OpenSim.Region.Framework.Scenes
2326 if (part == null) 2596 if (part == null)
2327 return; 2597 return;
2328 2598
2329 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2330 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2331
2332 if (PhysicsActor != null) 2599 if (PhysicsActor != null)
2333 m_sitAvatarHeight = PhysicsActor.Size.Z; 2600 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2334 2601
2335 bool canSit = false; 2602 bool canSit = false;
2336 2603
@@ -2357,33 +2624,32 @@ namespace OpenSim.Region.Framework.Scenes
2357 } 2624 }
2358 else 2625 else
2359 { 2626 {
2627 if (PhysicsSit(part,offset)) // physics engine
2628 return;
2629
2360 Vector3 pos = part.AbsolutePosition + offset; 2630 Vector3 pos = part.AbsolutePosition + offset;
2361 2631
2362 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2632 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2363 { 2633 {
2364// m_log.DebugFormat(
2365// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2366// Name, part.Name, part.LocalId);
2367
2368 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2634 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2369 canSit = true; 2635 canSit = true;
2370 } 2636 }
2371// else
2372// {
2373// m_log.DebugFormat(
2374// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2375// Name, part.Name, part.LocalId);
2376// }
2377 } 2637 }
2378 2638
2379 if (canSit) 2639 if (canSit)
2380 { 2640 {
2641
2381 if (PhysicsActor != null) 2642 if (PhysicsActor != null)
2382 { 2643 {
2383 // We can remove the physicsActor until they stand up. 2644 // We can remove the physicsActor until they stand up.
2384 RemoveFromPhysicalScene(); 2645 RemoveFromPhysicalScene();
2385 } 2646 }
2386 2647
2648 if (MovingToTarget)
2649 ResetMoveToTarget();
2650
2651 Velocity = Vector3.Zero;
2652
2387 part.AddSittingAvatar(UUID); 2653 part.AddSittingAvatar(UUID);
2388 2654
2389 cameraAtOffset = part.GetCameraAtOffset(); 2655 cameraAtOffset = part.GetCameraAtOffset();
@@ -2427,14 +2693,6 @@ namespace OpenSim.Region.Framework.Scenes
2427 m_requestedSitTargetID = part.LocalId; 2693 m_requestedSitTargetID = part.LocalId;
2428 m_requestedSitTargetUUID = part.UUID; 2694 m_requestedSitTargetUUID = part.UUID;
2429 2695
2430// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2431
2432 if (m_scene.PhysicsScene.SupportsRayCast())
2433 {
2434 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
2435 //SitRayCastAvatarPosition(part);
2436 //return;
2437 }
2438 } 2696 }
2439 else 2697 else
2440 { 2698 {
@@ -2444,197 +2702,115 @@ namespace OpenSim.Region.Framework.Scenes
2444 SendSitResponse(targetID, offset, Quaternion.Identity); 2702 SendSitResponse(targetID, offset, Quaternion.Identity);
2445 } 2703 }
2446 2704
2447 /* 2705 // returns false if does not suport so older sit can be tried
2448 public void SitRayCastAvatarPosition(SceneObjectPart part) 2706 public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
2449 { 2707 {
2450 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2708// TODO: Pull in these bits
2451 Vector3 StartRayCastPosition = AbsolutePosition; 2709 return false;
2452 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2710/*
2453 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2711 if (part == null || part.ParentGroup.IsAttachment)
2454 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2455 }
2456
2457 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
2458 {
2459 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2460 if (part != null)
2461 {
2462 if (hitYN)
2463 {
2464 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2465 {
2466 SitRaycastFindEdge(collisionPoint, normal);
2467 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2468 }
2469 else
2470 {
2471 SitRayCastAvatarPositionCameraZ(part);
2472 }
2473 }
2474 else
2475 {
2476 SitRayCastAvatarPositionCameraZ(part);
2477 }
2478 }
2479 else
2480 { 2712 {
2481 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2713 return true;
2482 m_requestedSitTargetUUID = UUID.Zero;
2483 m_requestedSitTargetID = 0;
2484 m_requestedSitOffset = Vector3.Zero;
2485 } 2714 }
2486 2715
2487 } 2716 if ( m_scene.PhysicsScene == null)
2488 2717 return false;
2489 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2490 {
2491 // Next, try to raycast from the camera Z position
2492 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2493 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2494 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2495 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2496 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2497 }
2498 2718
2499 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2719 if (part.PhysActor == null)
2500 {
2501 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2502 if (part != null)
2503 { 2720 {
2504 if (hitYN) 2721 // none physcis shape
2505 { 2722 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
2506 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) 2723 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2507 {
2508 SitRaycastFindEdge(collisionPoint, normal);
2509 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2510 }
2511 else
2512 {
2513 SitRayCastCameraPosition(part);
2514 }
2515 }
2516 else 2724 else
2517 { 2725 { // non physical phantom TODO
2518 SitRayCastCameraPosition(part); 2726 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2727 return false;
2519 } 2728 }
2520 } 2729 return true;
2521 else
2522 {
2523 ControllingClient.SendAlertMessage("Sit position no longer exists");
2524 m_requestedSitTargetUUID = UUID.Zero;
2525 m_requestedSitTargetID = 0;
2526 m_requestedSitOffset = Vector3.Zero;
2527 } 2730 }
2528 2731
2529 }
2530 2732
2531 public void SitRayCastCameraPosition(SceneObjectPart part) 2733 // not doing autopilot
2532 { 2734 m_requestedSitTargetID = 0;
2533 // Next, try to raycast from the camera position
2534 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2535 Vector3 StartRayCastPosition = CameraPosition;
2536 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2537 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2538 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2539 }
2540 2735
2541 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2736 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2542 { 2737 return true;
2543 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2544 if (part != null)
2545 {
2546 if (hitYN)
2547 {
2548 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2549 {
2550 SitRaycastFindEdge(collisionPoint, normal);
2551 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2552 }
2553 else
2554 {
2555 SitRayHorizontal(part);
2556 }
2557 }
2558 else
2559 {
2560 SitRayHorizontal(part);
2561 }
2562 }
2563 else
2564 {
2565 ControllingClient.SendAlertMessage("Sit position no longer exists");
2566 m_requestedSitTargetUUID = UUID.Zero;
2567 m_requestedSitTargetID = 0;
2568 m_requestedSitOffset = Vector3.Zero;
2569 }
2570 2738
2739 return false;
2740*/
2571 } 2741 }
2572 2742
2573 public void SitRayHorizontal(SceneObjectPart part) 2743
2744 private bool CanEnterLandPosition(Vector3 testPos)
2574 { 2745 {
2575 // Next, try to raycast from the avatar position to fwd 2746 ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
2576 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; 2747
2577 Vector3 StartRayCastPosition = CameraPosition; 2748 if (land == null || land.LandData.Name == "NO_LAND")
2578 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); 2749 return true;
2579 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); 2750
2580 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); 2751 return land.CanBeOnThisLand(UUID,testPos.Z);
2581 } 2752 }
2582 2753
2583 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2754 // status
2755 // < 0 ignore
2756 // 0 bad sit spot
2757 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2584 { 2758 {
2585 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2759 if (status < 0)
2586 if (part != null) 2760 return;
2761
2762 if (status == 0)
2587 { 2763 {
2588 if (hitYN) 2764 ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
2589 { 2765 return;
2590 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2591 {
2592 SitRaycastFindEdge(collisionPoint, normal);
2593 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2594 // Next, try to raycast from the camera position
2595 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2596 Vector3 StartRayCastPosition = CameraPosition;
2597 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2598 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2599 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2600 }
2601 else
2602 {
2603 ControllingClient.SendAlertMessage("Sit position not accessable.");
2604 m_requestedSitTargetUUID = UUID.Zero;
2605 m_requestedSitTargetID = 0;
2606 m_requestedSitOffset = Vector3.Zero;
2607 }
2608 }
2609 else
2610 {
2611 ControllingClient.SendAlertMessage("Sit position not accessable.");
2612 m_requestedSitTargetUUID = UUID.Zero;
2613 m_requestedSitTargetID = 0;
2614 m_requestedSitOffset = Vector3.Zero;
2615 }
2616 } 2766 }
2617 else 2767
2768 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2769 if (part == null)
2770 return;
2771
2772 Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
2773 if(!CanEnterLandPosition(targetPos))
2618 { 2774 {
2619 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2775 ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
2620 m_requestedSitTargetUUID = UUID.Zero; 2776 return;
2621 m_requestedSitTargetID = 0;
2622 m_requestedSitOffset = Vector3.Zero;
2623 } 2777 }
2624 2778
2625 } 2779 RemoveFromPhysicalScene();
2626 2780
2627 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2781 if (MovingToTarget)
2628 { 2782 ResetMoveToTarget();
2629 int i = 0; 2783
2630 //throw new NotImplementedException(); 2784 Velocity = Vector3.Zero;
2631 //m_requestedSitTargetUUID = UUID.Zero; 2785
2632 //m_requestedSitTargetID = 0; 2786 part.AddSittingAvatar(UUID);
2633 //m_requestedSitOffset = Vector3.Zero; 2787
2788 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2789 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2790 bool forceMouselook = part.GetForceMouselook();
2791
2792 ControllingClient.SendSitResponse(
2793 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2794
2795 // not using autopilot
2796
2797 Rotation = Orientation;
2798 m_pos = offset;
2799
2800 m_requestedSitTargetID = 0;
2801 part.ParentGroup.AddAvatar(UUID);
2802
2803 ParentPart = part;
2804 ParentID = part.LocalId;
2805 if(status == 3)
2806 Animator.TrySetMovementAnimation("SIT_GROUND");
2807 else
2808 Animator.TrySetMovementAnimation("SIT");
2809 SendAvatarDataToAllAgents();
2634 2810
2635 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2811 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2636 } 2812 }
2637 */ 2813
2638 2814
2639 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2815 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2640 { 2816 {
@@ -2654,6 +2830,7 @@ namespace OpenSim.Region.Framework.Scenes
2654 return; 2830 return;
2655 } 2831 }
2656 2832
2833
2657 if (part.SitTargetAvatar == UUID) 2834 if (part.SitTargetAvatar == UUID)
2658 { 2835 {
2659 Vector3 sitTargetPos = part.SitTargetPosition; 2836 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2668,29 +2845,39 @@ namespace OpenSim.Region.Framework.Scenes
2668 2845
2669 //Quaternion result = (sitTargetOrient * vq) * nq; 2846 //Quaternion result = (sitTargetOrient * vq) * nq;
2670 2847
2671 Vector3 newPos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2848 double x, y, z, m;
2672 Quaternion newRot;
2673 2849
2674 if (part.IsRoot) 2850 Quaternion r = sitTargetOrient;
2675 { 2851 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2676 newRot = sitTargetOrient; 2852
2677 } 2853 if (Math.Abs(1.0 - m) > 0.000001)
2678 else
2679 { 2854 {
2680 newPos = newPos * part.RotationOffset; 2855 m = 1.0 / Math.Sqrt(m);
2681 newRot = part.RotationOffset * sitTargetOrient; 2856 r.X *= (float)m;
2857 r.Y *= (float)m;
2858 r.Z *= (float)m;
2859 r.W *= (float)m;
2682 } 2860 }
2683 2861
2684 newPos += part.OffsetPosition; 2862 x = 2 * (r.X * r.Z + r.Y * r.W);
2863 y = 2 * (-r.X * r.W + r.Y * r.Z);
2864 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
2865
2866 Vector3 up = new Vector3((float)x, (float)y, (float)z);
2867 Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
2685 2868
2686 m_pos = newPos; 2869 m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
2687 Rotation = newRot; 2870
2871// m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset;
2872 Rotation = sitTargetOrient;
2873// ParentPosition = part.AbsolutePosition;
2874 part.ParentGroup.AddAvatar(UUID);
2688 } 2875 }
2689 else 2876 else
2690 { 2877 {
2691 // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is 2878 m_pos -= part.AbsolutePosition;
2692 // being sat upon. 2879// ParentPosition = part.AbsolutePosition;
2693 m_pos -= part.GroupPosition; 2880 part.ParentGroup.AddAvatar(UUID);
2694 2881
2695// m_log.DebugFormat( 2882// m_log.DebugFormat(
2696// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2883// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2807,8 +2994,8 @@ namespace OpenSim.Region.Framework.Scenes
2807 direc.Z *= 2.6f; 2994 direc.Z *= 2.6f;
2808 2995
2809 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2996 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2810 Animator.TrySetMovementAnimation("PREJUMP"); 2997// Animator.TrySetMovementAnimation("PREJUMP");
2811 Animator.TrySetMovementAnimation("JUMP"); 2998// Animator.TrySetMovementAnimation("JUMP");
2812 } 2999 }
2813 } 3000 }
2814 } 3001 }
@@ -2817,6 +3004,7 @@ namespace OpenSim.Region.Framework.Scenes
2817 3004
2818 // TODO: Add the force instead of only setting it to support multiple forces per frame? 3005 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2819 m_forceToApply = direc; 3006 m_forceToApply = direc;
3007 Animator.UpdateMovementAnimations();
2820 } 3008 }
2821 3009
2822 #endregion 3010 #endregion
@@ -2834,16 +3022,12 @@ namespace OpenSim.Region.Framework.Scenes
2834 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 3022 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2835 // grab the latest PhysicsActor velocity, whereas m_velocity is often 3023 // grab the latest PhysicsActor velocity, whereas m_velocity is often
2836 // storing a requested force instead of an actual traveling velocity 3024 // storing a requested force instead of an actual traveling velocity
3025 if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
3026 SendAvatarDataToAllAgents();
2837 3027
2838 // Throw away duplicate or insignificant updates 3028 if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
2839 if ( 3029 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
2840 // If the velocity has become zero, send it no matter what. 3030 !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
2841 (Velocity != m_lastVelocity && Velocity == Vector3.Zero)
2842 // otherwise, if things have changed reasonably, send the update
2843 || (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
2844 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
2845 || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
2846
2847 { 3031 {
2848 SendTerseUpdateToAllClients(); 3032 SendTerseUpdateToAllClients();
2849 3033
@@ -3003,9 +3187,7 @@ namespace OpenSim.Region.Framework.Scenes
3003 // again here... this comes after the cached appearance check because the avatars 3187 // again here... this comes after the cached appearance check because the avatars
3004 // appearance goes into the avatar update packet 3188 // appearance goes into the avatar update packet
3005 SendAvatarDataToAllAgents(); 3189 SendAvatarDataToAllAgents();
3006 3190 SendAppearanceToAgent(this);
3007 // This invocation always shows up in the viewer logs as an error.
3008 // SendAppearanceToAgent(this);
3009 3191
3010 // If we are using the the cached appearance then send it out to everyone 3192 // If we are using the the cached appearance then send it out to everyone
3011 if (cachedappearance) 3193 if (cachedappearance)
@@ -3036,6 +3218,8 @@ namespace OpenSim.Region.Framework.Scenes
3036 return; 3218 return;
3037 } 3219 }
3038 3220
3221 m_lastSize = Appearance.AvatarSize;
3222
3039 int count = 0; 3223 int count = 0;
3040 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 3224 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
3041 { 3225 {
@@ -3143,6 +3327,8 @@ namespace OpenSim.Region.Framework.Scenes
3143 3327
3144 avatar.ControllingClient.SendAppearance( 3328 avatar.ControllingClient.SendAppearance(
3145 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); 3329 UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
3330
3331
3146 } 3332 }
3147 3333
3148 #endregion 3334 #endregion
@@ -3216,8 +3402,9 @@ namespace OpenSim.Region.Framework.Scenes
3216 3402
3217 // If we don't have a PhysActor, we can't cross anyway 3403 // If we don't have a PhysActor, we can't cross anyway
3218 // Also don't do this while sat, sitting avatars cross with the 3404 // Also don't do this while sat, sitting avatars cross with the
3219 // object they sit on. 3405 // object they sit on. ParentUUID denoted a pending sit, don't
3220 if (ParentID != 0 || PhysicsActor == null) 3406 // interfere with it.
3407 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3221 return; 3408 return;
3222 3409
3223 if (!IsInTransit) 3410 if (!IsInTransit)
@@ -3561,6 +3748,9 @@ namespace OpenSim.Region.Framework.Scenes
3561 cAgent.AlwaysRun = SetAlwaysRun; 3748 cAgent.AlwaysRun = SetAlwaysRun;
3562 3749
3563 cAgent.Appearance = new AvatarAppearance(Appearance); 3750 cAgent.Appearance = new AvatarAppearance(Appearance);
3751
3752 cAgent.ParentPart = ParentUUID;
3753 cAgent.SitOffset = PrevSitOffset;
3564 3754
3565 lock (scriptedcontrols) 3755 lock (scriptedcontrols)
3566 { 3756 {
@@ -3569,7 +3759,7 @@ namespace OpenSim.Region.Framework.Scenes
3569 3759
3570 foreach (ScriptControllers c in scriptedcontrols.Values) 3760 foreach (ScriptControllers c in scriptedcontrols.Values)
3571 { 3761 {
3572 controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); 3762 controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
3573 } 3763 }
3574 cAgent.Controllers = controls; 3764 cAgent.Controllers = controls;
3575 } 3765 }
@@ -3603,6 +3793,8 @@ namespace OpenSim.Region.Framework.Scenes
3603 CameraAtAxis = cAgent.AtAxis; 3793 CameraAtAxis = cAgent.AtAxis;
3604 CameraLeftAxis = cAgent.LeftAxis; 3794 CameraLeftAxis = cAgent.LeftAxis;
3605 CameraUpAxis = cAgent.UpAxis; 3795 CameraUpAxis = cAgent.UpAxis;
3796 ParentUUID = cAgent.ParentPart;
3797 PrevSitOffset = cAgent.SitOffset;
3606 3798
3607 // When we get to the point of re-computing neighbors everytime this 3799 // When we get to the point of re-computing neighbors everytime this
3608 // changes, then start using the agent's drawdistance rather than the 3800 // changes, then start using the agent's drawdistance rather than the
@@ -3640,6 +3832,7 @@ namespace OpenSim.Region.Framework.Scenes
3640 foreach (ControllerData c in cAgent.Controllers) 3832 foreach (ControllerData c in cAgent.Controllers)
3641 { 3833 {
3642 ScriptControllers sc = new ScriptControllers(); 3834 ScriptControllers sc = new ScriptControllers();
3835 sc.objectID = c.ObjectID;
3643 sc.itemID = c.ItemID; 3836 sc.itemID = c.ItemID;
3644 sc.ignoreControls = (ScriptControlled)c.IgnoreControls; 3837 sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
3645 sc.eventControls = (ScriptControlled)c.EventControls; 3838 sc.eventControls = (ScriptControlled)c.EventControls;
@@ -3705,20 +3898,27 @@ namespace OpenSim.Region.Framework.Scenes
3705 } 3898 }
3706 3899
3707 if (Appearance.AvatarHeight == 0) 3900 if (Appearance.AvatarHeight == 0)
3708 Appearance.SetHeight(); 3901// Appearance.SetHeight();
3902 Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
3709 3903
3710 PhysicsScene scene = m_scene.PhysicsScene; 3904 PhysicsScene scene = m_scene.PhysicsScene;
3711 3905
3712 Vector3 pVec = AbsolutePosition; 3906 Vector3 pVec = AbsolutePosition;
3713 3907
3908/*
3909 PhysicsActor = scene.AddAvatar(
3910 LocalId, Firstname + "." + Lastname, pVec,
3911 new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
3912*/
3913
3714 PhysicsActor = scene.AddAvatar( 3914 PhysicsActor = scene.AddAvatar(
3715 LocalId, Firstname + "." + Lastname, pVec, 3915 LocalId, Firstname + "." + Lastname, pVec,
3716 new Vector3(0f, 0f, Appearance.AvatarHeight), isFlying); 3916 Appearance.AvatarBoxSize, isFlying);
3717 3917
3718 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3918 //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3719 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3919 PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
3720 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3920 PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3721 PhysicsActor.SubscribeEvents(500); 3921 PhysicsActor.SubscribeEvents(100);
3722 PhysicsActor.LocalID = LocalId; 3922 PhysicsActor.LocalID = LocalId;
3723 } 3923 }
3724 3924
@@ -3732,6 +3932,7 @@ namespace OpenSim.Region.Framework.Scenes
3732 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); 3932 ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
3733 } 3933 }
3734 3934
3935
3735 /// <summary> 3936 /// <summary>
3736 /// Event called by the physics plugin to tell the avatar about a collision. 3937 /// Event called by the physics plugin to tell the avatar about a collision.
3737 /// </summary> 3938 /// </summary>
@@ -3745,7 +3946,7 @@ namespace OpenSim.Region.Framework.Scenes
3745 /// <param name="e"></param> 3946 /// <param name="e"></param>
3746 public void PhysicsCollisionUpdate(EventArgs e) 3947 public void PhysicsCollisionUpdate(EventArgs e)
3747 { 3948 {
3748 if (IsChildAgent) 3949 if (IsChildAgent || Animator == null)
3749 return; 3950 return;
3750 3951
3751 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3952 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
@@ -3762,7 +3963,6 @@ namespace OpenSim.Region.Framework.Scenes
3762 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3963 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3763 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3964 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3764 3965
3765 CollisionPlane = Vector4.UnitW;
3766 3966
3767// // No collisions at all means we may be flying. Update always 3967// // No collisions at all means we may be flying. Update always
3768// // to make falling work 3968// // to make falling work
@@ -3772,34 +3972,7 @@ namespace OpenSim.Region.Framework.Scenes
3772// m_lastColCount = coldata.Count; 3972// m_lastColCount = coldata.Count;
3773// } 3973// }
3774 3974
3775 if (coldata.Count != 0) 3975 CollisionPlane = Vector4.UnitW;
3776 {
3777 switch (Animator.CurrentMovementAnimation)
3778 {
3779 case "STAND":
3780 case "WALK":
3781 case "RUN":
3782 case "CROUCH":
3783 case "CROUCHWALK":
3784 {
3785 ContactPoint lowest;
3786 lowest.SurfaceNormal = Vector3.Zero;
3787 lowest.Position = Vector3.Zero;
3788 lowest.Position.Z = Single.NaN;
3789
3790 foreach (ContactPoint contact in coldata.Values)
3791 {
3792 if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z)
3793 {
3794 lowest = contact;
3795 }
3796 }
3797
3798 CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
3799 }
3800 break;
3801 }
3802 }
3803 3976
3804 // Gods do not take damage and Invulnerable is set depending on parcel/region flags 3977 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3805 if (Invulnerable || GodLevel > 0) 3978 if (Invulnerable || GodLevel > 0)
@@ -3898,6 +4071,12 @@ namespace OpenSim.Region.Framework.Scenes
3898 // m_reprioritizationTimer.Dispose(); 4071 // m_reprioritizationTimer.Dispose();
3899 4072
3900 RemoveFromPhysicalScene(); 4073 RemoveFromPhysicalScene();
4074
4075 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
4076
4077// if (Animator != null)
4078// Animator.Close();
4079 Animator = null;
3901 4080
3902 LifecycleState = ScenePresenceState.Removed; 4081 LifecycleState = ScenePresenceState.Removed;
3903 } 4082 }
@@ -4133,10 +4312,18 @@ namespace OpenSim.Region.Framework.Scenes
4133 4312
4134 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) 4313 public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
4135 { 4314 {
4315 SceneObjectPart p = m_scene.GetSceneObjectPart(Obj_localID);
4316 if (p == null)
4317 return;
4318
4319 ControllingClient.SendTakeControls(controls, false, false);
4320 ControllingClient.SendTakeControls(controls, true, false);
4321
4136 ScriptControllers obj = new ScriptControllers(); 4322 ScriptControllers obj = new ScriptControllers();
4137 obj.ignoreControls = ScriptControlled.CONTROL_ZERO; 4323 obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
4138 obj.eventControls = ScriptControlled.CONTROL_ZERO; 4324 obj.eventControls = ScriptControlled.CONTROL_ZERO;
4139 4325
4326 obj.objectID = p.ParentGroup.UUID;
4140 obj.itemID = Script_item_UUID; 4327 obj.itemID = Script_item_UUID;
4141 if (pass_on == 0 && accept == 0) 4328 if (pass_on == 0 && accept == 0)
4142 { 4329 {
@@ -4185,6 +4372,21 @@ namespace OpenSim.Region.Framework.Scenes
4185 ControllingClient.SendTakeControls(int.MaxValue, false, false); 4372 ControllingClient.SendTakeControls(int.MaxValue, false, false);
4186 } 4373 }
4187 4374
4375 private void UnRegisterSeatControls(UUID obj)
4376 {
4377 List<UUID> takers = new List<UUID>();
4378
4379 foreach (ScriptControllers c in scriptedcontrols.Values)
4380 {
4381 if (c.objectID == obj)
4382 takers.Add(c.itemID);
4383 }
4384 foreach (UUID t in takers)
4385 {
4386 UnRegisterControlEventsToScript(0, t);
4387 }
4388 }
4389
4188 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) 4390 public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
4189 { 4391 {
4190 ScriptControllers takecontrols; 4392 ScriptControllers takecontrols;
@@ -4514,6 +4716,12 @@ namespace OpenSim.Region.Framework.Scenes
4514 4716
4515 private void CheckAndAdjustLandingPoint(ref Vector3 pos) 4717 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
4516 { 4718 {
4719 string reason;
4720
4721 // Honor bans
4722 if (!m_scene.TestLandRestrictions(UUID, out reason, ref pos.X, ref pos.Y))
4723 return;
4724
4517 SceneObjectGroup telehub = null; 4725 SceneObjectGroup telehub = null;
4518 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null) 4726 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
4519 { 4727 {
@@ -4553,11 +4761,119 @@ namespace OpenSim.Region.Framework.Scenes
4553 pos = land.LandData.UserLocation; 4761 pos = land.LandData.UserLocation;
4554 } 4762 }
4555 } 4763 }
4556 4764
4557 land.SendLandUpdateToClient(ControllingClient); 4765 land.SendLandUpdateToClient(ControllingClient);
4558 } 4766 }
4559 } 4767 }
4560 4768
4769 private DetectedObject CreateDetObject(SceneObjectPart obj)
4770 {
4771 DetectedObject detobj = new DetectedObject();
4772 detobj.keyUUID = obj.UUID;
4773 detobj.nameStr = obj.Name;
4774 detobj.ownerUUID = obj.OwnerID;
4775 detobj.posVector = obj.AbsolutePosition;
4776 detobj.rotQuat = obj.GetWorldRotation();
4777 detobj.velVector = obj.Velocity;
4778 detobj.colliderType = 0;
4779 detobj.groupUUID = obj.GroupID;
4780
4781 return detobj;
4782 }
4783
4784 private DetectedObject CreateDetObject(ScenePresence av)
4785 {
4786 DetectedObject detobj = new DetectedObject();
4787 detobj.keyUUID = av.UUID;
4788 detobj.nameStr = av.ControllingClient.Name;
4789 detobj.ownerUUID = av.UUID;
4790 detobj.posVector = av.AbsolutePosition;
4791 detobj.rotQuat = av.Rotation;
4792 detobj.velVector = av.Velocity;
4793 detobj.colliderType = 0;
4794 detobj.groupUUID = av.ControllingClient.ActiveGroupId;
4795
4796 return detobj;
4797 }
4798
4799 private DetectedObject CreateDetObjectForGround()
4800 {
4801 DetectedObject detobj = new DetectedObject();
4802 detobj.keyUUID = UUID.Zero;
4803 detobj.nameStr = "";
4804 detobj.ownerUUID = UUID.Zero;
4805 detobj.posVector = AbsolutePosition;
4806 detobj.rotQuat = Quaternion.Identity;
4807 detobj.velVector = Vector3.Zero;
4808 detobj.colliderType = 0;
4809 detobj.groupUUID = UUID.Zero;
4810
4811 return detobj;
4812 }
4813
4814 private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
4815 {
4816 ColliderArgs colliderArgs = new ColliderArgs();
4817 List<DetectedObject> colliding = new List<DetectedObject>();
4818 foreach (uint localId in colliders)
4819 {
4820 if (localId == 0)
4821 continue;
4822
4823 SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
4824 if (obj != null)
4825 {
4826 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
4827 colliding.Add(CreateDetObject(obj));
4828 }
4829 else
4830 {
4831 ScenePresence av = m_scene.GetScenePresence(localId);
4832 if (av != null && (!av.IsChildAgent))
4833 {
4834 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
4835 colliding.Add(CreateDetObject(av));
4836 }
4837 }
4838 }
4839
4840 colliderArgs.Colliders = colliding;
4841
4842 return colliderArgs;
4843 }
4844
4845 private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
4846
4847 private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
4848 {
4849 ColliderArgs CollidingMessage;
4850
4851 if (colliders.Count > 0)
4852 {
4853 if ((dest.RootPart.ScriptEvents & ev) != 0)
4854 {
4855 CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
4856
4857 if (CollidingMessage.Colliders.Count > 0)
4858 notify(dest.RootPart.LocalId, CollidingMessage);
4859 }
4860 }
4861 }
4862
4863 private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
4864 {
4865 if ((dest.RootPart.ScriptEvents & ev) != 0)
4866 {
4867 ColliderArgs LandCollidingMessage = new ColliderArgs();
4868 List<DetectedObject> colliding = new List<DetectedObject>();
4869
4870 colliding.Add(CreateDetObjectForGround());
4871 LandCollidingMessage.Colliders = colliding;
4872
4873 notify(dest.RootPart.LocalId, LandCollidingMessage);
4874 }
4875 }
4876
4561 private void TeleportFlagsDebug() { 4877 private void TeleportFlagsDebug() {
4562 4878
4563 // Some temporary debugging help to show all the TeleportFlags we have... 4879 // Some temporary debugging help to show all the TeleportFlags we have...
@@ -4582,6 +4898,5 @@ namespace OpenSim.Region.Framework.Scenes
4582 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************"); 4898 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
4583 4899
4584 } 4900 }
4585
4586 } 4901 }
4587} 4902}