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.cs1071
1 files changed, 881 insertions, 190 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 1aac09d..cdf8366 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Xml;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using System.Timers; 32using System.Timers;
@@ -72,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
72// { 73// {
73// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
74// } 75// }
75 76
76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 78
78// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 79// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
@@ -87,7 +88,9 @@ namespace OpenSim.Region.Framework.Scenes
87 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 88 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
88 /// issue #1716 89 /// issue #1716
89 /// </summary> 90 /// </summary>
90 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 91// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
92 // Value revised by KF 091121 by comparison with SL.
93 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
91 94
92 public UUID currentParcelUUID = UUID.Zero; 95 public UUID currentParcelUUID = UUID.Zero;
93 96
@@ -110,6 +113,7 @@ namespace OpenSim.Region.Framework.Scenes
110 { 113 {
111 get { return m_attachments; } 114 get { return m_attachments; }
112 } 115 }
116
113 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 117 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
114 118
115 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); 119 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
@@ -119,10 +123,12 @@ namespace OpenSim.Region.Framework.Scenes
119 private SceneObjectGroup proxyObjectGroup; 123 private SceneObjectGroup proxyObjectGroup;
120 //private SceneObjectPart proxyObjectPart = null; 124 //private SceneObjectPart proxyObjectPart = null;
121 public Vector3 lastKnownAllowedPosition; 125 public Vector3 lastKnownAllowedPosition;
122 public bool sentMessageAboutRestrictedParcelFlyingDown;
123 public Vector4 CollisionPlane = Vector4.UnitW; 126 public Vector4 CollisionPlane = Vector4.UnitW;
124 127
128 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
129 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
125 private Vector3 m_lastPosition; 130 private Vector3 m_lastPosition;
131 private Vector3 m_lastWorldPosition;
126 private Quaternion m_lastRotation; 132 private Quaternion m_lastRotation;
127 private Vector3 m_lastVelocity; 133 private Vector3 m_lastVelocity;
128 //private int m_lastTerseSent; 134 //private int m_lastTerseSent;
@@ -130,6 +136,11 @@ namespace OpenSim.Region.Framework.Scenes
130 private bool m_updateflag; 136 private bool m_updateflag;
131 private byte m_movementflag; 137 private byte m_movementflag;
132 private Vector3? m_forceToApply; 138 private Vector3? m_forceToApply;
139 private int m_userFlags;
140 public int UserFlags
141 {
142 get { return m_userFlags; }
143 }
133 private TeleportFlags m_teleportFlags; 144 private TeleportFlags m_teleportFlags;
134 public TeleportFlags TeleportFlags 145 public TeleportFlags TeleportFlags
135 { 146 {
@@ -160,9 +171,10 @@ namespace OpenSim.Region.Framework.Scenes
160 private int m_perfMonMS; 171 private int m_perfMonMS;
161 172
162 private bool m_setAlwaysRun; 173 private bool m_setAlwaysRun;
163
164 private bool m_forceFly; 174 private bool m_forceFly;
165 private bool m_flyDisabled; 175 private bool m_flyDisabled;
176 private bool m_flyingOld; // add for fly velocity control
177 public bool m_wasFlying; // add for fly velocity control
166 178
167 private float m_speedModifier = 1.0f; 179 private float m_speedModifier = 1.0f;
168 180
@@ -181,7 +193,8 @@ namespace OpenSim.Region.Framework.Scenes
181 protected RegionInfo m_regionInfo; 193 protected RegionInfo m_regionInfo;
182 protected ulong crossingFromRegion; 194 protected ulong crossingFromRegion;
183 195
184 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 196 private readonly Vector3[] Dir_Vectors = new Vector3[11];
197 private bool m_isNudging = false;
185 198
186 // Position of agent's camera in world (region cordinates) 199 // Position of agent's camera in world (region cordinates)
187 protected Vector3 m_CameraCenter; 200 protected Vector3 m_CameraCenter;
@@ -206,17 +219,25 @@ namespace OpenSim.Region.Framework.Scenes
206 private bool m_autopilotMoving; 219 private bool m_autopilotMoving;
207 private Vector3 m_autoPilotTarget; 220 private Vector3 m_autoPilotTarget;
208 private bool m_sitAtAutoTarget; 221 private bool m_sitAtAutoTarget;
222 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
209 223
210 private string m_nextSitAnimation = String.Empty; 224 private string m_nextSitAnimation = String.Empty;
211 225
212 //PauPaw:Proper PID Controler for autopilot************ 226 //PauPaw:Proper PID Controler for autopilot************
213 private bool m_moveToPositionInProgress; 227 private bool m_moveToPositionInProgress;
214 private Vector3 m_moveToPositionTarget; 228 private Vector3 m_moveToPositionTarget;
229 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
215 230
216 private bool m_followCamAuto; 231 private bool m_followCamAuto;
217 232
218 private int m_movementUpdateCount; 233 private int m_movementUpdateCount;
234 private int m_lastColCount = -1; //KF: Look for Collision chnages
235 private int m_updateCount = 0; //KF: Update Anims for a while
236 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
219 private const int NumMovementsBetweenRayCast = 5; 237 private const int NumMovementsBetweenRayCast = 5;
238 private List<uint> m_lastColliders = new List<uint>();
239
240 private object m_syncRoot = new Object();
220 241
221 private bool CameraConstraintActive; 242 private bool CameraConstraintActive;
222 //private int m_moveToPositionStateStatus; 243 //private int m_moveToPositionStateStatus;
@@ -243,7 +264,9 @@ namespace OpenSim.Region.Framework.Scenes
243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 264 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 265 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 266 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
246 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 267 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
268 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
269 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
247 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 270 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
248 } 271 }
249 272
@@ -450,7 +473,8 @@ namespace OpenSim.Region.Framework.Scenes
450 get 473 get
451 { 474 {
452 PhysicsActor actor = m_physicsActor; 475 PhysicsActor actor = m_physicsActor;
453 if (actor != null) 476// if (actor != null)
477 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
454 m_pos = actor.Position; 478 m_pos = actor.Position;
455 else 479 else
456 { 480 {
@@ -472,7 +496,7 @@ namespace OpenSim.Region.Framework.Scenes
472 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 496 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
473 if (part != null) 497 if (part != null)
474 { 498 {
475 return m_parentPosition + (m_pos * part.GetWorldRotation()); 499 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
476 } 500 }
477 else 501 else
478 { 502 {
@@ -499,7 +523,8 @@ namespace OpenSim.Region.Framework.Scenes
499 } 523 }
500 } 524 }
501 525
502 m_pos = value; 526 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
527 m_pos = value;
503 m_parentPosition = Vector3.Zero; 528 m_parentPosition = Vector3.Zero;
504 } 529 }
505 } 530 }
@@ -543,10 +568,39 @@ namespace OpenSim.Region.Framework.Scenes
543 } 568 }
544 } 569 }
545 570
571 public Quaternion OffsetRotation
572 {
573 get { return m_offsetRotation; }
574 set { m_offsetRotation = value; }
575 }
576
546 public Quaternion Rotation 577 public Quaternion Rotation
547 { 578 {
548 get { return m_bodyRot; } 579 get {
549 set { m_bodyRot = value; } 580 if (m_parentID != 0)
581 {
582 if (m_offsetRotation != null)
583 {
584 return m_offsetRotation;
585 }
586 else
587 {
588 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
589 }
590
591 }
592 else
593 {
594 return m_bodyRot;
595 }
596 }
597 set {
598 m_bodyRot = value;
599 if (m_parentID != 0)
600 {
601 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
602 }
603 }
550 } 604 }
551 605
552 public Quaternion PreviousRotation 606 public Quaternion PreviousRotation
@@ -571,11 +625,21 @@ namespace OpenSim.Region.Framework.Scenes
571 625
572 private uint m_parentID; 626 private uint m_parentID;
573 627
628
629 private UUID m_linkedPrim;
630
574 public uint ParentID 631 public uint ParentID
575 { 632 {
576 get { return m_parentID; } 633 get { return m_parentID; }
577 set { m_parentID = value; } 634 set { m_parentID = value; }
578 } 635 }
636
637 public UUID LinkedPrim
638 {
639 get { return m_linkedPrim; }
640 set { m_linkedPrim = value; }
641 }
642
579 public float Health 643 public float Health
580 { 644 {
581 get { return m_health; } 645 get { return m_health; }
@@ -697,7 +761,7 @@ namespace OpenSim.Region.Framework.Scenes
697 CreateSceneViewer(); 761 CreateSceneViewer();
698 m_animator = new ScenePresenceAnimator(this); 762 m_animator = new ScenePresenceAnimator(this);
699 } 763 }
700 764
701 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 765 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
702 { 766 {
703 m_DrawDistance = world.DefaultDrawDistance; 767 m_DrawDistance = world.DefaultDrawDistance;
@@ -712,6 +776,7 @@ namespace OpenSim.Region.Framework.Scenes
712 m_localId = m_scene.AllocateLocalId(); 776 m_localId = m_scene.AllocateLocalId();
713 777
714 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 778 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
779 m_userFlags = account.UserFlags;
715 780
716 if (account != null) 781 if (account != null)
717 m_userLevel = account.UserLevel; 782 m_userLevel = account.UserLevel;
@@ -730,10 +795,7 @@ namespace OpenSim.Region.Framework.Scenes
730 m_reprioritization_timer.AutoReset = false; 795 m_reprioritization_timer.AutoReset = false;
731 796
732 AdjustKnownSeeds(); 797 AdjustKnownSeeds();
733
734 // TODO: I think, this won't send anything, as we are still a child here...
735 Animator.TrySetMovementAnimation("STAND"); 798 Animator.TrySetMovementAnimation("STAND");
736
737 // we created a new ScenePresence (a new child agent) in a fresh region. 799 // we created a new ScenePresence (a new child agent) in a fresh region.
738 // Request info about all the (root) agents in this region 800 // Request info about all the (root) agents in this region
739 // Note: This won't send data *to* other clients in that region (children don't send) 801 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -784,25 +846,47 @@ namespace OpenSim.Region.Framework.Scenes
784 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 846 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
785 Dir_Vectors[4] = Vector3.UnitZ; //UP 847 Dir_Vectors[4] = Vector3.UnitZ; //UP
786 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 848 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
787 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 849 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
788 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 850 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
789 Dir_Vectors[7] = -Vector3.UnitX; //BACK 851 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
852 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
853 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
790 } 854 }
791 855
792 private Vector3[] GetWalkDirectionVectors() 856 private Vector3[] GetWalkDirectionVectors()
793 { 857 {
794 Vector3[] vector = new Vector3[9]; 858 Vector3[] vector = new Vector3[11];
795 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 859 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
796 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 860 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
797 vector[2] = Vector3.UnitY; //LEFT 861 vector[2] = Vector3.UnitY; //LEFT
798 vector[3] = -Vector3.UnitY; //RIGHT 862 vector[3] = -Vector3.UnitY; //RIGHT
799 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 863 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
800 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 864 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
801 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 865 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
802 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 866 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
803 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 867 vector[8] = Vector3.UnitY; //LEFT_NUDGE
868 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
869 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
804 return vector; 870 return vector;
805 } 871 }
872
873 private bool[] GetDirectionIsNudge()
874 {
875 bool[] isNudge = new bool[11];
876 isNudge[0] = false; //FORWARD
877 isNudge[1] = false; //BACK
878 isNudge[2] = false; //LEFT
879 isNudge[3] = false; //RIGHT
880 isNudge[4] = false; //UP
881 isNudge[5] = false; //DOWN
882 isNudge[6] = true; //FORWARD_NUDGE
883 isNudge[7] = true; //BACK_NUDGE
884 isNudge[8] = true; //LEFT_NUDGE
885 isNudge[9] = true; //RIGHT_NUDGE
886 isNudge[10] = true; //DOWN_Nudge
887 return isNudge;
888 }
889
806 890
807 #endregion 891 #endregion
808 892
@@ -867,6 +951,62 @@ namespace OpenSim.Region.Framework.Scenes
867 pos.Y = crossedBorder.BorderLine.Z - 1; 951 pos.Y = crossedBorder.BorderLine.Z - 1;
868 } 952 }
869 953
954 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
955 if (land != null)
956 {
957 // If we come in via login, landmark or map, we want to
958 // honor landing points. If we come in via Lure, we want
959 // to ignore them.
960 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
961 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
962 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
963 {
964 // Don't restrict gods, estate managers, or land owners to
965 // the TP point. This behaviour mimics agni.
966 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
967 land.LandData.UserLocation != Vector3.Zero &&
968 GodLevel < 200 &&
969 ((land.LandData.OwnerID != m_uuid &&
970 (!m_scene.Permissions.IsGod(m_uuid)) &&
971 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
972 {
973 pos = land.LandData.UserLocation;
974 }
975 }
976
977 land.SendLandUpdateToClient(ControllingClient);
978 }
979
980 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
981 {
982 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
983
984 if (pos.X < 0)
985 {
986 emergencyPos.X = (int)Constants.RegionSize + pos.X;
987 if (!(pos.Y < 0))
988 emergencyPos.Y = pos.Y;
989 if (!(pos.Z < 0))
990 emergencyPos.Z = pos.Z;
991 }
992 if (pos.Y < 0)
993 {
994 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
995 if (!(pos.X < 0))
996 emergencyPos.X = pos.X;
997 if (!(pos.Z < 0))
998 emergencyPos.Z = pos.Z;
999 }
1000 if (pos.Z < 0)
1001 {
1002 emergencyPos.Z = 128;
1003 if (!(pos.Y < 0))
1004 emergencyPos.Y = pos.Y;
1005 if (!(pos.X < 0))
1006 emergencyPos.X = pos.X;
1007 }
1008 }
1009
870 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1010 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
871 { 1011 {
872 m_log.WarnFormat( 1012 m_log.WarnFormat(
@@ -1012,16 +1152,21 @@ namespace OpenSim.Region.Framework.Scenes
1012 /// <summary> 1152 /// <summary>
1013 /// Removes physics plugin scene representation of this agent if it exists. 1153 /// Removes physics plugin scene representation of this agent if it exists.
1014 /// </summary> 1154 /// </summary>
1015 private void RemoveFromPhysicalScene() 1155 public void RemoveFromPhysicalScene()
1016 { 1156 {
1017 if (PhysicsActor != null) 1157 if (PhysicsActor != null)
1018 { 1158 {
1019 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1159 try
1020 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1160 {
1021 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1161 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1022 m_physicsActor.UnSubscribeEvents(); 1162 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1023 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1163 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1024 PhysicsActor = null; 1164 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1165 m_physicsActor.UnSubscribeEvents();
1166 PhysicsActor = null;
1167 }
1168 catch
1169 { }
1025 } 1170 }
1026 } 1171 }
1027 1172
@@ -1032,11 +1177,13 @@ namespace OpenSim.Region.Framework.Scenes
1032 public void Teleport(Vector3 pos) 1177 public void Teleport(Vector3 pos)
1033 { 1178 {
1034 bool isFlying = false; 1179 bool isFlying = false;
1180
1035 if (m_physicsActor != null) 1181 if (m_physicsActor != null)
1036 isFlying = m_physicsActor.Flying; 1182 isFlying = m_physicsActor.Flying;
1037 1183
1038 RemoveFromPhysicalScene(); 1184 RemoveFromPhysicalScene();
1039 Velocity = Vector3.Zero; 1185 Velocity = Vector3.Zero;
1186 CheckLandingPoint(ref pos);
1040 AbsolutePosition = pos; 1187 AbsolutePosition = pos;
1041 AddToPhysicalScene(isFlying); 1188 AddToPhysicalScene(isFlying);
1042 if (m_appearance != null) 1189 if (m_appearance != null)
@@ -1046,6 +1193,7 @@ namespace OpenSim.Region.Framework.Scenes
1046 } 1193 }
1047 1194
1048 SendTerseUpdateToAllClients(); 1195 SendTerseUpdateToAllClients();
1196
1049 } 1197 }
1050 1198
1051 public void TeleportWithMomentum(Vector3 pos) 1199 public void TeleportWithMomentum(Vector3 pos)
@@ -1055,6 +1203,7 @@ namespace OpenSim.Region.Framework.Scenes
1055 isFlying = m_physicsActor.Flying; 1203 isFlying = m_physicsActor.Flying;
1056 1204
1057 RemoveFromPhysicalScene(); 1205 RemoveFromPhysicalScene();
1206 CheckLandingPoint(ref pos);
1058 AbsolutePosition = pos; 1207 AbsolutePosition = pos;
1059 AddToPhysicalScene(isFlying); 1208 AddToPhysicalScene(isFlying);
1060 if (m_appearance != null) 1209 if (m_appearance != null)
@@ -1265,6 +1414,7 @@ namespace OpenSim.Region.Framework.Scenes
1265 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1414 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1266 1415
1267 m_pos = m_LastFinitePos; 1416 m_pos = m_LastFinitePos;
1417
1268 if (!m_pos.IsFinite()) 1418 if (!m_pos.IsFinite())
1269 { 1419 {
1270 m_pos.X = 127f; 1420 m_pos.X = 127f;
@@ -1335,7 +1485,6 @@ namespace OpenSim.Region.Framework.Scenes
1335 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1485 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1336 } 1486 }
1337 } 1487 }
1338
1339 lock (scriptedcontrols) 1488 lock (scriptedcontrols)
1340 { 1489 {
1341 if (scriptedcontrols.Count > 0) 1490 if (scriptedcontrols.Count > 0)
@@ -1350,6 +1499,9 @@ namespace OpenSim.Region.Framework.Scenes
1350 1499
1351 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1500 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1352 { 1501 {
1502 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1503 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1504
1353 // TODO: This doesn't prevent the user from walking yet. 1505 // TODO: This doesn't prevent the user from walking yet.
1354 // Setting parent ID would fix this, if we knew what value 1506 // Setting parent ID would fix this, if we knew what value
1355 // to use. Or we could add a m_isSitting variable. 1507 // to use. Or we could add a m_isSitting variable.
@@ -1398,12 +1550,20 @@ namespace OpenSim.Region.Framework.Scenes
1398 if (actor.Flying != oldflying) 1550 if (actor.Flying != oldflying)
1399 update_movementflag = true; 1551 update_movementflag = true;
1400 1552
1553 if (m_animator.m_jumping) // add for jumping
1554 update_movementflag = true;
1555
1401 if (q != m_bodyRot) 1556 if (q != m_bodyRot)
1402 { 1557 {
1403 m_bodyRot = q; 1558 m_bodyRot = q;
1404 update_rotation = true; 1559 update_rotation = true;
1405 } 1560 }
1406 1561
1562 //guilty until proven innocent..
1563 bool Nudging = true;
1564 //Basically, if there is at least one non-nudge control then we don't need
1565 //to worry about stopping the avatar
1566
1407 if (m_parentID == 0) 1567 if (m_parentID == 0)
1408 { 1568 {
1409 bool bAllowUpdateMoveToPosition = false; 1569 bool bAllowUpdateMoveToPosition = false;
@@ -1418,9 +1578,12 @@ namespace OpenSim.Region.Framework.Scenes
1418 else 1578 else
1419 dirVectors = Dir_Vectors; 1579 dirVectors = Dir_Vectors;
1420 1580
1421 // The fact that m_movementflag is a byte needs to be fixed 1581 bool[] isNudge = GetDirectionIsNudge();
1422 // it really should be a uint 1582
1423 uint nudgehack = 250; 1583
1584
1585
1586
1424 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1587 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1425 { 1588 {
1426 if (((uint)flags & (uint)DCF) != 0) 1589 if (((uint)flags & (uint)DCF) != 0)
@@ -1430,40 +1593,28 @@ namespace OpenSim.Region.Framework.Scenes
1430 try 1593 try
1431 { 1594 {
1432 agent_control_v3 += dirVectors[i]; 1595 agent_control_v3 += dirVectors[i];
1433 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1596 if (isNudge[i] == false)
1597 {
1598 Nudging = false;
1599 }
1434 } 1600 }
1435 catch (IndexOutOfRangeException) 1601 catch (IndexOutOfRangeException)
1436 { 1602 {
1437 // Why did I get this? 1603 // Why did I get this?
1438 } 1604 }
1439 1605
1440 if ((m_movementflag & (byte)(uint)DCF) == 0) 1606 if ((m_movementflag & (uint)DCF) == 0)
1441 { 1607 {
1442 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1443 {
1444 m_movementflag |= (byte)nudgehack;
1445 }
1446 m_movementflag += (byte)(uint)DCF; 1608 m_movementflag += (byte)(uint)DCF;
1447 update_movementflag = true; 1609 update_movementflag = true;
1448 } 1610 }
1449 } 1611 }
1450 else 1612 else
1451 { 1613 {
1452 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1614 if ((m_movementflag & (uint)DCF) != 0)
1453 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1454 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1455 ) // This or is for Nudge forward
1456 { 1615 {
1457 m_movementflag -= ((byte)(uint)DCF); 1616 m_movementflag -= (byte)(uint)DCF;
1458
1459 update_movementflag = true; 1617 update_movementflag = true;
1460 /*
1461 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1462 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1463 {
1464 m_log.Debug("Removed Hack flag");
1465 }
1466 */
1467 } 1618 }
1468 else 1619 else
1469 { 1620 {
@@ -1472,7 +1623,6 @@ namespace OpenSim.Region.Framework.Scenes
1472 } 1623 }
1473 i++; 1624 i++;
1474 } 1625 }
1475
1476 //Paupaw:Do Proper PID for Autopilot here 1626 //Paupaw:Do Proper PID for Autopilot here
1477 if (bResetMoveToPosition) 1627 if (bResetMoveToPosition)
1478 { 1628 {
@@ -1484,8 +1634,41 @@ namespace OpenSim.Region.Framework.Scenes
1484 1634
1485 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) 1635 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving))
1486 { 1636 {
1637/*
1638 bool twoD = false;
1639 bool there = false;
1640 if (Animator != null)
1641 {
1642 switch (Animator.CurrentMovementAnimation)
1643 {
1644 case "STAND":
1645 case "WALK":
1646 case "RUN":
1647 case "CROUCH":
1648 case "CROUCHWALK":
1649 {
1650 twoD = true;
1651 }
1652 break;
1653 }
1654 }
1655
1656 if (twoD)
1657 {
1658*/
1659 Vector3 abspos = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, 0.0f);
1660 Vector3 tgt = new Vector3(m_moveToPositionTarget.X, m_moveToPositionTarget.Y, 0.0f);
1661/* if (Util.GetDistanceTo(abspos, tgt) <= 0.5f) there = true;
1662 }
1663 else
1664 {
1665 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) there = true;
1666 }
1667*/
1487 //Check the error term of the current position in relation to the target position 1668 //Check the error term of the current position in relation to the target position
1488 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) 1669// if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f)
1670// if (there)
1671 if (Util.GetDistanceTo(abspos, tgt) <= 0.5f)
1489 { 1672 {
1490 // we are close enough to the target 1673 // we are close enough to the target
1491 m_moveToPositionTarget = Vector3.Zero; 1674 m_moveToPositionTarget = Vector3.Zero;
@@ -1502,11 +1685,15 @@ namespace OpenSim.Region.Framework.Scenes
1502 // unknown forces are acting on the avatar and we need to adaptively respond 1685 // unknown forces are acting on the avatar and we need to adaptively respond
1503 // to such forces, but the following simple approach seems to works fine. 1686 // to such forces, but the following simple approach seems to works fine.
1504 Vector3 LocalVectorToTarget3D = 1687 Vector3 LocalVectorToTarget3D =
1505 (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1688// (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1689 (tgt - abspos)
1506 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords 1690 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords
1507 // Ignore z component of vector 1691 // Ignore z component of vector
1508 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1692 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1509 LocalVectorToTarget2D.Normalize(); 1693 LocalVectorToTarget2D.Normalize();
1694
1695 //We're not nudging
1696 Nudging = false;
1510 agent_control_v3 += LocalVectorToTarget2D; 1697 agent_control_v3 += LocalVectorToTarget2D;
1511 1698
1512 // update avatar movement flags. the avatar coordinate system is as follows: 1699 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1597,13 +1784,13 @@ namespace OpenSim.Region.Framework.Scenes
1597 // m_log.DebugFormat( 1784 // m_log.DebugFormat(
1598 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1785 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1599 1786
1600 AddNewMovement(agent_control_v3, q); 1787 AddNewMovement(agent_control_v3, q, Nudging);
1601 1788
1602 1789
1603 } 1790 }
1604 } 1791 }
1605 1792
1606 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1793 if (update_movementflag && !SitGround)
1607 Animator.UpdateMovementAnimations(); 1794 Animator.UpdateMovementAnimations();
1608 1795
1609 m_scene.EventManager.TriggerOnClientMovement(this); 1796 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1618,7 +1805,6 @@ namespace OpenSim.Region.Framework.Scenes
1618 m_sitAtAutoTarget = false; 1805 m_sitAtAutoTarget = false;
1619 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1806 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1620 //proxy.PCode = (byte)PCode.ParticleSystem; 1807 //proxy.PCode = (byte)PCode.ParticleSystem;
1621
1622 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1808 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1623 proxyObjectGroup.AttachToScene(m_scene); 1809 proxyObjectGroup.AttachToScene(m_scene);
1624 1810
@@ -1637,8 +1823,15 @@ namespace OpenSim.Region.Framework.Scenes
1637// } 1823// }
1638 } 1824 }
1639 1825
1826 public void StopMoveToPosition()
1827 {
1828 m_moveToPositionTarget = Vector3.Zero;
1829 m_moveToPositionInProgress = false;
1830 }
1831
1640 public void DoMoveToPosition(Object sender, string method, List<String> args) 1832 public void DoMoveToPosition(Object sender, string method, List<String> args)
1641 { 1833 {
1834//Console.WriteLine("SP:DoMoveToPosition");
1642 try 1835 try
1643 { 1836 {
1644 float locx = 0f; 1837 float locx = 0f;
@@ -1660,7 +1853,7 @@ namespace OpenSim.Region.Framework.Scenes
1660 } 1853 }
1661 m_moveToPositionInProgress = true; 1854 m_moveToPositionInProgress = true;
1662 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1855 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1663 } 1856 }
1664 catch (Exception ex) 1857 catch (Exception ex)
1665 { 1858 {
1666 //Why did I get this error? 1859 //Why did I get this error?
@@ -1682,7 +1875,7 @@ namespace OpenSim.Region.Framework.Scenes
1682 Velocity = Vector3.Zero; 1875 Velocity = Vector3.Zero;
1683 SendAvatarDataToAllAgents(); 1876 SendAvatarDataToAllAgents();
1684 1877
1685 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1878 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1686 } 1879 }
1687 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1880 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1688 m_requestedSitTargetUUID = UUID.Zero; 1881 m_requestedSitTargetUUID = UUID.Zero;
@@ -1719,25 +1912,22 @@ namespace OpenSim.Region.Framework.Scenes
1719 1912
1720 if (m_parentID != 0) 1913 if (m_parentID != 0)
1721 { 1914 {
1722 m_log.Debug("StandupCode Executed"); 1915 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1723 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1724 if (part != null) 1916 if (part != null)
1725 { 1917 {
1918 part.TaskInventory.LockItemsForRead(true);
1726 TaskInventoryDictionary taskIDict = part.TaskInventory; 1919 TaskInventoryDictionary taskIDict = part.TaskInventory;
1727 if (taskIDict != null) 1920 if (taskIDict != null)
1728 { 1921 {
1729 lock (taskIDict) 1922 foreach (UUID taskID in taskIDict.Keys)
1730 { 1923 {
1731 foreach (UUID taskID in taskIDict.Keys) 1924 UnRegisterControlEventsToScript(LocalId, taskID);
1732 { 1925 taskIDict[taskID].PermsMask &= ~(
1733 UnRegisterControlEventsToScript(LocalId, taskID); 1926 2048 | //PERMISSION_CONTROL_CAMERA
1734 taskIDict[taskID].PermsMask &= ~( 1927 4); // PERMISSION_TAKE_CONTROLS
1735 2048 | //PERMISSION_CONTROL_CAMERA
1736 4); // PERMISSION_TAKE_CONTROLS
1737 }
1738 } 1928 }
1739
1740 } 1929 }
1930 part.TaskInventory.LockItemsForRead(false);
1741 // Reset sit target. 1931 // Reset sit target.
1742 if (part.GetAvatarOnSitTarget() == UUID) 1932 if (part.GetAvatarOnSitTarget() == UUID)
1743 part.SitTargetAvatar = UUID.Zero; 1933 part.SitTargetAvatar = UUID.Zero;
@@ -1746,16 +1936,55 @@ namespace OpenSim.Region.Framework.Scenes
1746 m_parentPosition = part.GetWorldPosition(); 1936 m_parentPosition = part.GetWorldPosition();
1747 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1937 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1748 } 1938 }
1939 // part.GetWorldRotation() is the rotation of the object being sat on
1940 // Rotation is the sittiing Av's rotation
1941
1942 Quaternion partRot;
1943// if (part.LinkNum == 1)
1944// { // Root prim of linkset
1945// partRot = part.ParentGroup.RootPart.RotationOffset;
1946// }
1947// else
1948// { // single or child prim
1949
1950// }
1951 if (part == null) //CW: Part may be gone. llDie() for example.
1952 {
1953 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1954 }
1955 else
1956 {
1957 partRot = part.GetWorldRotation();
1958 }
1749 1959
1960 Quaternion partIRot = Quaternion.Inverse(partRot);
1961
1962 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1963 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1964
1965
1750 if (m_physicsActor == null) 1966 if (m_physicsActor == null)
1751 { 1967 {
1752 AddToPhysicalScene(false); 1968 AddToPhysicalScene(false);
1753 } 1969 }
1754 1970 //CW: If the part isn't null then we can set the current position
1755 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1971 if (part != null)
1756 m_parentPosition = Vector3.Zero; 1972 {
1757 1973 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1758 m_parentID = 0; 1974 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1975 part.IsOccupied = false;
1976 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1977 }
1978 else
1979 {
1980 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1981 AbsolutePosition = m_lastWorldPosition;
1982 }
1983
1984 m_parentPosition = Vector3.Zero;
1985 m_parentID = 0;
1986 m_linkedPrim = UUID.Zero;
1987 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1759 SendAvatarDataToAllAgents(); 1988 SendAvatarDataToAllAgents();
1760 m_requestedSitTargetID = 0; 1989 m_requestedSitTargetID = 0;
1761 if (m_physicsActor != null && m_appearance != null) 1990 if (m_physicsActor != null && m_appearance != null)
@@ -1764,7 +1993,6 @@ namespace OpenSim.Region.Framework.Scenes
1764 SetHeight(m_appearance.AvatarHeight); 1993 SetHeight(m_appearance.AvatarHeight);
1765 } 1994 }
1766 } 1995 }
1767
1768 Animator.TrySetMovementAnimation("STAND"); 1996 Animator.TrySetMovementAnimation("STAND");
1769 } 1997 }
1770 1998
@@ -1795,13 +2023,9 @@ namespace OpenSim.Region.Framework.Scenes
1795 Vector3 avSitOffSet = part.SitTargetPosition; 2023 Vector3 avSitOffSet = part.SitTargetPosition;
1796 Quaternion avSitOrientation = part.SitTargetOrientation; 2024 Quaternion avSitOrientation = part.SitTargetOrientation;
1797 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2025 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1798 2026 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1799 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2027 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1800 bool SitTargetisSet = 2028 if (SitTargetisSet && !SitTargetOccupied)
1801 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1802 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1803
1804 if (SitTargetisSet && SitTargetUnOccupied)
1805 { 2029 {
1806 //switch the target to this prim 2030 //switch the target to this prim
1807 return part; 2031 return part;
@@ -1815,85 +2039,168 @@ namespace OpenSim.Region.Framework.Scenes
1815 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2039 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1816 { 2040 {
1817 bool autopilot = true; 2041 bool autopilot = true;
2042 Vector3 autopilotTarget = new Vector3();
2043 Quaternion sitOrientation = Quaternion.Identity;
1818 Vector3 pos = new Vector3(); 2044 Vector3 pos = new Vector3();
1819 Quaternion sitOrientation = pSitOrientation;
1820 Vector3 cameraEyeOffset = Vector3.Zero; 2045 Vector3 cameraEyeOffset = Vector3.Zero;
1821 Vector3 cameraAtOffset = Vector3.Zero; 2046 Vector3 cameraAtOffset = Vector3.Zero;
1822 bool forceMouselook = false; 2047 bool forceMouselook = false;
1823 2048
1824 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2049 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1825 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2050 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1826 if (part != null) 2051 if (part == null) return;
1827 { 2052
1828 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2053 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1829 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2054 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1830 2055
1831 // Is a sit target available? 2056 // part is the prim to sit on
1832 Vector3 avSitOffSet = part.SitTargetPosition; 2057 // offset is the world-ref vector distance from that prim center to the click-spot
1833 Quaternion avSitOrientation = part.SitTargetOrientation; 2058 // UUID is the UUID of the Avatar doing the clicking
1834 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2059
1835 2060 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1836 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2061
1837 bool SitTargetisSet = 2062 // Is a sit target available?
1838 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 2063 Vector3 avSitOffSet = part.SitTargetPosition;
1839 ( 2064 Quaternion avSitOrientation = part.SitTargetOrientation;
1840 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 2065
1841 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 2066 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1842 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 2067 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1843 ) 2068 Quaternion partRot;
1844 )); 2069// if (part.LinkNum == 1)
1845 2070// { // Root prim of linkset
1846 if (SitTargetisSet && SitTargetUnOccupied) 2071// partRot = part.ParentGroup.RootPart.RotationOffset;
1847 { 2072// }
1848 part.SitTargetAvatar = UUID; 2073// else
1849 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 2074// { // single or child prim
1850 sitOrientation = avSitOrientation; 2075 partRot = part.GetWorldRotation();
1851 autopilot = false; 2076// }
1852 } 2077 Quaternion partIRot = Quaternion.Inverse(partRot);
1853 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2078//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1854 2079 // Sit analysis rewritten by KF 091125
1855 pos = part.AbsolutePosition + offset; 2080 if (SitTargetisSet) // scipted sit
1856 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 2081 {
1857 //{ 2082 if (!part.IsOccupied)
1858 // offset = pos; 2083 {
1859 //autopilot = false; 2084//Console.WriteLine("Scripted, unoccupied");
1860 //} 2085 part.SitTargetAvatar = UUID; // set that Av will be on it
1861 if (m_physicsActor != null) 2086 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1862 { 2087
1863 // If we're not using the client autopilot, we're immediately warping the avatar to the location 2088 Quaternion nrot = avSitOrientation;
1864 // We can remove the physicsActor until they stand up. 2089 if (!part.IsRoot)
1865 m_sitAvatarHeight = m_physicsActor.Size.Z;
1866
1867 if (autopilot)
1868 { 2090 {
1869 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2091 nrot = part.RotationOffset * avSitOrientation;
1870 {
1871 autopilot = false;
1872
1873 RemoveFromPhysicalScene();
1874 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1875 }
1876 } 2092 }
1877 else 2093 sitOrientation = nrot; // Change rotatione to the scripted one
2094 OffsetRotation = nrot;
2095 autopilot = false; // Jump direct to scripted llSitPos()
2096 }
2097 else
2098 {
2099//Console.WriteLine("Scripted, occupied");
2100 return;
2101 }
2102 }
2103 else // Not Scripted
2104 {
2105 if ( (Math.Abs(offset.X) > 0.1f) || (Math.Abs(offset.Y) > 0.1f) ) // Changed 0.5M to 0.1M as they want to be able to sit close together
2106 {
2107 // large prim & offset, ignore if other Avs sitting
2108// offset.Z -= 0.05f;
2109 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2110 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2111
2112//Console.WriteLine(" offset ={0}", offset);
2113//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2114//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2115
2116 }
2117 else // small offset
2118 {
2119//Console.WriteLine("Small offset");
2120 if (!part.IsOccupied)
2121 {
2122 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2123 autopilotTarget = part.AbsolutePosition;
2124//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2125 }
2126 else return; // occupied small
2127 } // end large/small
2128 } // end Scripted/not
2129
2130 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2131
2132 cameraAtOffset = part.GetCameraAtOffset();
2133 cameraEyeOffset = part.GetCameraEyeOffset();
2134 forceMouselook = part.GetForceMouselook();
2135 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2136 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2137
2138 if (m_physicsActor != null)
2139 {
2140 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2141 // We can remove the physicsActor until they stand up.
2142 m_sitAvatarHeight = m_physicsActor.Size.Z;
2143 if (autopilot)
2144 { // its not a scripted sit
2145// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2146 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1878 { 2147 {
2148 autopilot = false; // close enough
2149 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2150 Not using the part's position because returning the AV to the last known standing
2151 position is likely to be more friendly, isn't it? */
1879 RemoveFromPhysicalScene(); 2152 RemoveFromPhysicalScene();
1880 } 2153 Velocity = Vector3.Zero;
2154 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2155 } // else the autopilot will get us close
2156 }
2157 else
2158 { // its a scripted sit
2159 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2160 I *am* using the part's position this time because we have no real idea how far away
2161 the avatar is from the sit target. */
2162 RemoveFromPhysicalScene();
2163 Velocity = Vector3.Zero;
1881 } 2164 }
1882
1883 cameraAtOffset = part.GetCameraAtOffset();
1884 cameraEyeOffset = part.GetCameraEyeOffset();
1885 forceMouselook = part.GetForceMouselook();
1886 } 2165 }
1887 2166 else return; // physactor is null!
1888 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2167
1889 m_requestedSitTargetUUID = targetID; 2168 Vector3 offsetr; // = offset * partIRot;
2169 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2170 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2171 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2172 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2173 //offsetr = offset * partIRot;
2174//
2175 // }
2176 // else
2177 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2178 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2179 // (offset * partRot);
2180 // }
2181
2182//Console.WriteLine(" ");
2183//Console.WriteLine("link number ={0}", part.LinkNum);
2184//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2185//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2186//Console.WriteLine("Click offst ={0}", offset);
2187//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2188//Console.WriteLine("offsetr ={0}", offsetr);
2189//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2190//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2191
2192 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2193 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2194
2195 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1890 // This calls HandleAgentSit twice, once from here, and the client calls 2196 // This calls HandleAgentSit twice, once from here, and the client calls
1891 // HandleAgentSit itself after it gets to the location 2197 // HandleAgentSit itself after it gets to the location
1892 // It doesn't get to the location until we've moved them there though 2198 // It doesn't get to the location until we've moved them there though
1893 // which happens in HandleAgentSit :P 2199 // which happens in HandleAgentSit :P
1894 m_autopilotMoving = autopilot; 2200 m_autopilotMoving = autopilot;
1895 m_autoPilotTarget = pos; 2201 m_autoPilotTarget = autopilotTarget;
1896 m_sitAtAutoTarget = autopilot; 2202 m_sitAtAutoTarget = autopilot;
2203 m_initialSitTarget = autopilotTarget;
1897 if (!autopilot) 2204 if (!autopilot)
1898 HandleAgentSit(remoteClient, UUID); 2205 HandleAgentSit(remoteClient, UUID);
1899 } 2206 }
@@ -2188,47 +2495,130 @@ namespace OpenSim.Region.Framework.Scenes
2188 { 2495 {
2189 if (part != null) 2496 if (part != null)
2190 { 2497 {
2498//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2191 if (part.GetAvatarOnSitTarget() == UUID) 2499 if (part.GetAvatarOnSitTarget() == UUID)
2192 { 2500 {
2501//Console.WriteLine("Scripted Sit");
2502 // Scripted sit
2193 Vector3 sitTargetPos = part.SitTargetPosition; 2503 Vector3 sitTargetPos = part.SitTargetPosition;
2194 Quaternion sitTargetOrient = part.SitTargetOrientation; 2504 Quaternion sitTargetOrient = part.SitTargetOrientation;
2195
2196 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2197 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2198
2199 //Quaternion result = (sitTargetOrient * vq) * nq;
2200
2201 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2505 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2202 m_pos += SIT_TARGET_ADJUSTMENT; 2506 m_pos += SIT_TARGET_ADJUSTMENT;
2507 if (!part.IsRoot)
2508 {
2509 m_pos *= part.RotationOffset;
2510 }
2203 m_bodyRot = sitTargetOrient; 2511 m_bodyRot = sitTargetOrient;
2204 //Rotation = sitTargetOrient;
2205 m_parentPosition = part.AbsolutePosition; 2512 m_parentPosition = part.AbsolutePosition;
2206 2513 part.IsOccupied = true;
2207 //SendTerseUpdateToAllClients(); 2514 part.ParentGroup.AddAvatar(agentID);
2208 } 2515 }
2209 else 2516 else
2210 { 2517 {
2211 m_pos -= part.AbsolutePosition; 2518 // if m_avUnscriptedSitPos is zero then Av sits above center
2519 // Else Av sits at m_avUnscriptedSitPos
2520
2521 // Non-scripted sit by Kitto Flora 21Nov09
2522 // Calculate angle of line from prim to Av
2523 Quaternion partIRot;
2524// if (part.LinkNum == 1)
2525// { // Root prim of linkset
2526// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2527// }
2528// else
2529// { // single or child prim
2530 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2531// }
2532 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2533 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2534 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2535 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2536 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2537 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2538 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2539 // Av sits at world euler <0,0, z>, translated by part rotation
2540 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2541
2212 m_parentPosition = part.AbsolutePosition; 2542 m_parentPosition = part.AbsolutePosition;
2213 } 2543 part.IsOccupied = true;
2544 part.ParentGroup.AddAvatar(agentID);
2545 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2546 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2547 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2548 m_avUnscriptedSitPos; // adds click offset, if any
2549 //Set up raytrace to find top surface of prim
2550 Vector3 size = part.Scale;
2551 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2552 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2553 Vector3 down = new Vector3(0f, 0f, -1f);
2554//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2555 m_scene.PhysicsScene.RaycastWorld(
2556 start, // Vector3 position,
2557 down, // Vector3 direction,
2558 mag, // float length,
2559 SitAltitudeCallback); // retMethod
2560 } // end scripted/not
2214 } 2561 }
2215 else 2562 else // no Av
2216 { 2563 {
2217 return; 2564 return;
2218 } 2565 }
2219 } 2566 }
2220 m_parentID = m_requestedSitTargetID;
2221 2567
2568 //We want our offsets to reference the root prim, not the child we may have sat on
2569 if (!part.IsRoot)
2570 {
2571 m_parentID = part.ParentGroup.RootPart.LocalId;
2572 m_pos += part.OffsetPosition;
2573 }
2574 else
2575 {
2576 m_parentID = m_requestedSitTargetID;
2577 }
2578
2579 m_linkedPrim = part.UUID;
2580 if (part.GetAvatarOnSitTarget() != UUID)
2581 {
2582 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2583 }
2222 Velocity = Vector3.Zero; 2584 Velocity = Vector3.Zero;
2223 RemoveFromPhysicalScene(); 2585 RemoveFromPhysicalScene();
2224
2225 Animator.TrySetMovementAnimation(sitAnimation); 2586 Animator.TrySetMovementAnimation(sitAnimation);
2226 SendAvatarDataToAllAgents(); 2587 SendAvatarDataToAllAgents();
2227 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2228 // So we're also sending a terse update (which has avatar rotation)
2229 // [Update] We do now.
2230 //SendTerseUpdateToAllClients(); 2588 //SendTerseUpdateToAllClients();
2231 } 2589 }
2590
2591 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2592 {
2593 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2594 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2595 if(hitYN)
2596 {
2597 // m_pos = Av offset from prim center to make look like on center
2598 // m_parentPosition = Actual center pos of prim
2599 // collisionPoint = spot on prim where we want to sit
2600 // collisionPoint.Z = global sit surface height
2601 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2602 Quaternion partIRot;
2603// if (part.LinkNum == 1)
2604/// { // Root prim of linkset
2605// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2606// }
2607// else
2608// { // single or child prim
2609 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2610// }
2611 if (m_initialSitTarget != null)
2612 {
2613 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2614 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2615 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2616 m_pos += offset;
2617 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2618 }
2619
2620 }
2621 } // End SitAltitudeCallback KF.
2232 2622
2233 /// <summary> 2623 /// <summary>
2234 /// Event handler for the 'Always run' setting on the client 2624 /// Event handler for the 'Always run' setting on the client
@@ -2258,12 +2648,13 @@ namespace OpenSim.Region.Framework.Scenes
2258 /// </summary> 2648 /// </summary>
2259 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2649 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2260 /// <param name="rotation">The direction in which this avatar should now face. 2650 /// <param name="rotation">The direction in which this avatar should now face.
2261 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2651 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2262 { 2652 {
2263 if (m_isChildAgent) 2653 if (m_isChildAgent)
2264 { 2654 {
2265 // WHAT??? 2655 // WHAT???
2266 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); 2656 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent");
2657
2267 return; 2658 return;
2268 } 2659 }
2269 2660
@@ -2272,15 +2663,26 @@ namespace OpenSim.Region.Framework.Scenes
2272 Rotation = rotation; 2663 Rotation = rotation;
2273 Vector3 direc = vec * rotation; 2664 Vector3 direc = vec * rotation;
2274 direc.Normalize(); 2665 direc.Normalize();
2666 PhysicsActor actor = m_physicsActor;
2667
2668 if (actor.Flying != m_flyingOld) // add for fly velocity control
2669 {
2670 m_flyingOld = actor.Flying; // add for fly velocity control
2671 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2672 }
2673
2674 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2675
2676 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2275 2677
2276 direc *= 0.03f * 128f * m_speedModifier; 2678 direc *= 0.03f * 128f * m_speedModifier;
2277 2679
2278 PhysicsActor actor = m_physicsActor;
2279 if (actor != null) 2680 if (actor != null)
2280 { 2681 {
2281 if (actor.Flying) 2682 if (actor.Flying)
2282 { 2683 {
2283 direc *= 4.0f; 2684// rm speed mod direc *= 4.0f;
2685 direc *= 5.2f; // for speed mod
2284 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2686 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2285 //bool colliding = (m_physicsActor.IsColliding==true); 2687 //bool colliding = (m_physicsActor.IsColliding==true);
2286 //if (controlland) 2688 //if (controlland)
@@ -2293,22 +2695,34 @@ namespace OpenSim.Region.Framework.Scenes
2293 // m_log.Info("[AGENT]: Stop FLying"); 2695 // m_log.Info("[AGENT]: Stop FLying");
2294 //} 2696 //}
2295 } 2697 }
2698 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2699 {
2700 direc *= 0.0f;
2701 }
2702 /* This jumping section removed to SPA
2296 else if (!actor.Flying && actor.IsColliding) 2703 else if (!actor.Flying && actor.IsColliding)
2297 { 2704 {
2298 if (direc.Z > 2.0f) 2705 if (direc.Z > 2.0f)
2299 { 2706 {
2300 direc.Z *= 3.0f; 2707 if(m_animator.m_animTickJump == -1)
2301 2708 {
2302 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2709 direc.Z *= 3.0f; // jump
2303 Animator.TrySetMovementAnimation("PREJUMP"); 2710 }
2304 Animator.TrySetMovementAnimation("JUMP"); 2711 else
2712 {
2713 direc.Z *= 0.1f; // prejump
2714 }
2715 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2716 Animator.TrySetMovementAnimation("PREJUMP");
2717 Animator.TrySetMovementAnimation("JUMP");
2718 * /
2305 } 2719 }
2306 } 2720 } */
2307 } 2721 }
2308 2722
2309 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2723 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2310 m_forceToApply = direc; 2724 m_forceToApply = direc;
2311 2725 m_isNudging = Nudging;
2312 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2726 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2313 } 2727 }
2314 2728
@@ -2357,6 +2771,9 @@ namespace OpenSim.Region.Framework.Scenes
2357 2771
2358 CheckForSignificantMovement(); // sends update to the modules. 2772 CheckForSignificantMovement(); // sends update to the modules.
2359 } 2773 }
2774
2775 //Sending prim updates AFTER the avatar terse updates are sent
2776 SendPrimUpdates();
2360 } 2777 }
2361 2778
2362 #endregion 2779 #endregion
@@ -3149,6 +3566,7 @@ namespace OpenSim.Region.Framework.Scenes
3149 m_callbackURI = cAgent.CallbackURI; 3566 m_callbackURI = cAgent.CallbackURI;
3150 3567
3151 m_pos = cAgent.Position; 3568 m_pos = cAgent.Position;
3569
3152 m_velocity = cAgent.Velocity; 3570 m_velocity = cAgent.Velocity;
3153 m_CameraCenter = cAgent.Center; 3571 m_CameraCenter = cAgent.Center;
3154 m_CameraAtAxis = cAgent.AtAxis; 3572 m_CameraAtAxis = cAgent.AtAxis;
@@ -3237,17 +3655,45 @@ namespace OpenSim.Region.Framework.Scenes
3237 /// </summary> 3655 /// </summary>
3238 public override void UpdateMovement() 3656 public override void UpdateMovement()
3239 { 3657 {
3240 if (m_forceToApply.HasValue) 3658 if (Animator!=null) // add for jumping
3241 { 3659 { // add for jumping
3242 Vector3 force = m_forceToApply.Value; 3660 // if (!m_animator.m_jumping) // add for jumping
3243 3661 // { // add for jumping
3244 m_updateflag = true;
3245 3662
3246 Velocity = force; 3663 if (m_forceToApply.HasValue) // this section realigned
3664 {
3247 3665
3248 m_forceToApply = null; 3666 Vector3 force = m_forceToApply.Value;
3249 } 3667 m_updateflag = true;
3250 } 3668if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3669 Velocity = force;
3670//Console.WriteLine("UM1 {0}", Velocity);
3671 m_forceToApply = null;
3672 }
3673 else
3674 {
3675 if (m_isNudging)
3676 {
3677 Vector3 force = Vector3.Zero;
3678
3679 m_updateflag = true;
3680if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3681 Velocity = force;
3682//Console.WriteLine("UM2 {0}", Velocity);
3683 m_isNudging = false;
3684 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3685 }
3686 else // add for jumping
3687 { // add for jumping
3688 Vector3 force = Vector3.Zero; // add for jumping
3689if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3690//Console.WriteLine("UM3 {0}", Velocity);
3691 Velocity = force; // add for jumping
3692 }
3693 }
3694 // } // end realign
3695 } // add for jumping
3696 } // add for jumping
3251 3697
3252 /// <summary> 3698 /// <summary>
3253 /// Adds a physical representation of the avatar to the Physics plugin 3699 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3261,10 +3707,8 @@ namespace OpenSim.Region.Framework.Scenes
3261 3707
3262 Vector3 pVec = AbsolutePosition; 3708 Vector3 pVec = AbsolutePosition;
3263 3709
3264 // Old bug where the height was in centimeters instead of meters
3265 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3710 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3266 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3711 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3267
3268 scene.AddPhysicsActorTaint(m_physicsActor); 3712 scene.AddPhysicsActorTaint(m_physicsActor);
3269 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3713 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3270 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3714 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3288,18 +3732,29 @@ namespace OpenSim.Region.Framework.Scenes
3288 { 3732 {
3289 if (e == null) 3733 if (e == null)
3290 return; 3734 return;
3291 3735
3292 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3736 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3293 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3294 // as of this comment the interval is set in AddToPhysicalScene 3737 // as of this comment the interval is set in AddToPhysicalScene
3295 if (Animator!=null) 3738 if (Animator!=null)
3296 Animator.UpdateMovementAnimations(); 3739 {
3740 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3741 { // else its will lock out other animation changes, like ground sit.
3742 Animator.UpdateMovementAnimations();
3743 m_updateCount--;
3744 }
3745 }
3297 3746
3298 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3747 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3299 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3748 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3300 3749
3301 CollisionPlane = Vector4.UnitW; 3750 CollisionPlane = Vector4.UnitW;
3302 3751
3752 if (m_lastColCount != coldata.Count)
3753 {
3754 m_updateCount = UPDATE_COUNT;
3755 m_lastColCount = coldata.Count;
3756 }
3757
3303 if (coldata.Count != 0 && Animator != null) 3758 if (coldata.Count != 0 && Animator != null)
3304 { 3759 {
3305 switch (Animator.CurrentMovementAnimation) 3760 switch (Animator.CurrentMovementAnimation)
@@ -3329,6 +3784,148 @@ namespace OpenSim.Region.Framework.Scenes
3329 } 3784 }
3330 } 3785 }
3331 3786
3787 List<uint> thisHitColliders = new List<uint>();
3788 List<uint> endedColliders = new List<uint>();
3789 List<uint> startedColliders = new List<uint>();
3790
3791 foreach (uint localid in coldata.Keys)
3792 {
3793 thisHitColliders.Add(localid);
3794 if (!m_lastColliders.Contains(localid))
3795 {
3796 startedColliders.Add(localid);
3797 }
3798 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3799 }
3800
3801 // calculate things that ended colliding
3802 foreach (uint localID in m_lastColliders)
3803 {
3804 if (!thisHitColliders.Contains(localID))
3805 {
3806 endedColliders.Add(localID);
3807 }
3808 }
3809 //add the items that started colliding this time to the last colliders list.
3810 foreach (uint localID in startedColliders)
3811 {
3812 m_lastColliders.Add(localID);
3813 }
3814 // remove things that ended colliding from the last colliders list
3815 foreach (uint localID in endedColliders)
3816 {
3817 m_lastColliders.Remove(localID);
3818 }
3819
3820 // do event notification
3821 if (startedColliders.Count > 0)
3822 {
3823 ColliderArgs StartCollidingMessage = new ColliderArgs();
3824 List<DetectedObject> colliding = new List<DetectedObject>();
3825 foreach (uint localId in startedColliders)
3826 {
3827 if (localId == 0)
3828 continue;
3829
3830 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3831 string data = "";
3832 if (obj != null)
3833 {
3834 DetectedObject detobj = new DetectedObject();
3835 detobj.keyUUID = obj.UUID;
3836 detobj.nameStr = obj.Name;
3837 detobj.ownerUUID = obj.OwnerID;
3838 detobj.posVector = obj.AbsolutePosition;
3839 detobj.rotQuat = obj.GetWorldRotation();
3840 detobj.velVector = obj.Velocity;
3841 detobj.colliderType = 0;
3842 detobj.groupUUID = obj.GroupID;
3843 colliding.Add(detobj);
3844 }
3845 }
3846
3847 if (colliding.Count > 0)
3848 {
3849 StartCollidingMessage.Colliders = colliding;
3850
3851 foreach (SceneObjectGroup att in Attachments)
3852 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3853 }
3854 }
3855
3856 if (endedColliders.Count > 0)
3857 {
3858 ColliderArgs EndCollidingMessage = new ColliderArgs();
3859 List<DetectedObject> colliding = new List<DetectedObject>();
3860 foreach (uint localId in endedColliders)
3861 {
3862 if (localId == 0)
3863 continue;
3864
3865 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3866 string data = "";
3867 if (obj != null)
3868 {
3869 DetectedObject detobj = new DetectedObject();
3870 detobj.keyUUID = obj.UUID;
3871 detobj.nameStr = obj.Name;
3872 detobj.ownerUUID = obj.OwnerID;
3873 detobj.posVector = obj.AbsolutePosition;
3874 detobj.rotQuat = obj.GetWorldRotation();
3875 detobj.velVector = obj.Velocity;
3876 detobj.colliderType = 0;
3877 detobj.groupUUID = obj.GroupID;
3878 colliding.Add(detobj);
3879 }
3880 }
3881
3882 if (colliding.Count > 0)
3883 {
3884 EndCollidingMessage.Colliders = colliding;
3885
3886 foreach (SceneObjectGroup att in Attachments)
3887 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3888 }
3889 }
3890
3891 if (thisHitColliders.Count > 0)
3892 {
3893 ColliderArgs CollidingMessage = new ColliderArgs();
3894 List<DetectedObject> colliding = new List<DetectedObject>();
3895 foreach (uint localId in thisHitColliders)
3896 {
3897 if (localId == 0)
3898 continue;
3899
3900 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3901 string data = "";
3902 if (obj != null)
3903 {
3904 DetectedObject detobj = new DetectedObject();
3905 detobj.keyUUID = obj.UUID;
3906 detobj.nameStr = obj.Name;
3907 detobj.ownerUUID = obj.OwnerID;
3908 detobj.posVector = obj.AbsolutePosition;
3909 detobj.rotQuat = obj.GetWorldRotation();
3910 detobj.velVector = obj.Velocity;
3911 detobj.colliderType = 0;
3912 detobj.groupUUID = obj.GroupID;
3913 colliding.Add(detobj);
3914 }
3915 }
3916
3917 if (colliding.Count > 0)
3918 {
3919 CollidingMessage.Colliders = colliding;
3920
3921 lock (m_attachments)
3922 {
3923 foreach (SceneObjectGroup att in m_attachments)
3924 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3925 }
3926 }
3927 }
3928
3332 if (m_invulnerable) 3929 if (m_invulnerable)
3333 return; 3930 return;
3334 3931
@@ -3413,6 +4010,10 @@ namespace OpenSim.Region.Framework.Scenes
3413 { 4010 {
3414 lock (m_attachments) 4011 lock (m_attachments)
3415 { 4012 {
4013 // This may be true when the attachment comes back
4014 // from serialization after login. Clear it.
4015 gobj.IsDeleted = false;
4016
3416 m_attachments.Add(gobj); 4017 m_attachments.Add(gobj);
3417 } 4018 }
3418 } 4019 }
@@ -3754,6 +4355,39 @@ namespace OpenSim.Region.Framework.Scenes
3754 return; 4355 return;
3755 } 4356 }
3756 4357
4358 XmlDocument doc = new XmlDocument();
4359 string stateData = String.Empty;
4360
4361 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4362 if (attServ != null)
4363 {
4364 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4365 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4366 if (stateData != String.Empty)
4367 {
4368 try
4369 {
4370 doc.LoadXml(stateData);
4371 }
4372 catch { }
4373 }
4374 }
4375
4376 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4377
4378 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4379 if (nodes.Count > 0)
4380 {
4381 foreach (XmlNode n in nodes)
4382 {
4383 XmlElement elem = (XmlElement)n;
4384 string itemID = elem.GetAttribute("ItemID");
4385 string xml = elem.InnerXml;
4386
4387 itemData[new UUID(itemID)] = xml;
4388 }
4389 }
4390
3757 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4391 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3758 foreach (AvatarAttachment attach in attachments) 4392 foreach (AvatarAttachment attach in attachments)
3759 { 4393 {
@@ -3774,7 +4408,30 @@ namespace OpenSim.Region.Framework.Scenes
3774 4408
3775 try 4409 try
3776 { 4410 {
3777 m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4411 string xmlData;
4412 XmlDocument d = new XmlDocument();
4413 UUID asset;
4414 if (itemData.TryGetValue(itemID, out xmlData))
4415 {
4416 d.LoadXml(xmlData);
4417 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4418
4419 // Rez from inventory
4420 asset
4421 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4422
4423 }
4424 else
4425 {
4426 // Rez from inventory (with a null doc to let
4427 // CHANGED_OWNER happen)
4428 asset
4429 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4430 }
4431
4432 m_log.InfoFormat(
4433 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4434 p, itemID, asset);
3778 } 4435 }
3779 catch (Exception e) 4436 catch (Exception e)
3780 { 4437 {
@@ -3807,6 +4464,15 @@ namespace OpenSim.Region.Framework.Scenes
3807 m_reprioritization_called = false; 4464 m_reprioritization_called = false;
3808 } 4465 }
3809 } 4466 }
4467
4468 private Vector3 Quat2Euler(Quaternion rot){
4469 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4470 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4471 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4472 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4473 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4474 return(new Vector3(x,y,z));
4475 }
3810 4476
3811 public void SaveChangedAttachments() 4477 public void SaveChangedAttachments()
3812 { 4478 {
@@ -3830,5 +4496,30 @@ namespace OpenSim.Region.Framework.Scenes
3830 } 4496 }
3831 } 4497 }
3832 } 4498 }
4499
4500 private void CheckLandingPoint(ref Vector3 pos)
4501 {
4502 // Never constrain lures
4503 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4504 return;
4505
4506 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4507 return;
4508
4509 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4510
4511 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4512 land.LandData.UserLocation != Vector3.Zero &&
4513 land.LandData.OwnerID != m_uuid &&
4514 (!m_scene.Permissions.IsGod(m_uuid)) &&
4515 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4516 {
4517 float curr = Vector3.Distance(AbsolutePosition, pos);
4518 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4519 pos = land.LandData.UserLocation;
4520 else
4521 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4522 }
4523 }
3833 } 4524 }
3834} 4525}