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.cs1070
1 files changed, 877 insertions, 193 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 00a1487..3a5b05d 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
@@ -864,6 +948,62 @@ namespace OpenSim.Region.Framework.Scenes
864 pos.Y = crossedBorder.BorderLine.Z - 1; 948 pos.Y = crossedBorder.BorderLine.Z - 1;
865 } 949 }
866 950
951 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
952 if (land != null)
953 {
954 // If we come in via login, landmark or map, we want to
955 // honor landing points. If we come in via Lure, we want
956 // to ignore them.
957 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
958 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
959 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
960 {
961 // Don't restrict gods, estate managers, or land owners to
962 // the TP point. This behaviour mimics agni.
963 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
964 land.LandData.UserLocation != Vector3.Zero &&
965 GodLevel < 200 &&
966 ((land.LandData.OwnerID != m_uuid &&
967 (!m_scene.Permissions.IsGod(m_uuid)) &&
968 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
969 {
970 pos = land.LandData.UserLocation;
971 }
972 }
973
974 land.SendLandUpdateToClient(ControllingClient);
975 }
976
977 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
978 {
979 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
980
981 if (pos.X < 0)
982 {
983 emergencyPos.X = (int)Constants.RegionSize + pos.X;
984 if (!(pos.Y < 0))
985 emergencyPos.Y = pos.Y;
986 if (!(pos.Z < 0))
987 emergencyPos.Z = pos.Z;
988 }
989 if (pos.Y < 0)
990 {
991 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
992 if (!(pos.X < 0))
993 emergencyPos.X = pos.X;
994 if (!(pos.Z < 0))
995 emergencyPos.Z = pos.Z;
996 }
997 if (pos.Z < 0)
998 {
999 emergencyPos.Z = 128;
1000 if (!(pos.Y < 0))
1001 emergencyPos.Y = pos.Y;
1002 if (!(pos.X < 0))
1003 emergencyPos.X = pos.X;
1004 }
1005 }
1006
867 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1007 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
868 { 1008 {
869 m_log.WarnFormat( 1009 m_log.WarnFormat(
@@ -988,16 +1128,21 @@ namespace OpenSim.Region.Framework.Scenes
988 /// <summary> 1128 /// <summary>
989 /// Removes physics plugin scene representation of this agent if it exists. 1129 /// Removes physics plugin scene representation of this agent if it exists.
990 /// </summary> 1130 /// </summary>
991 private void RemoveFromPhysicalScene() 1131 public void RemoveFromPhysicalScene()
992 { 1132 {
993 if (PhysicsActor != null) 1133 if (PhysicsActor != null)
994 { 1134 {
995 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1135 try
996 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1136 {
997 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1137 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
998 m_physicsActor.UnSubscribeEvents(); 1138 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
999 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1139 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1000 PhysicsActor = null; 1140 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1141 m_physicsActor.UnSubscribeEvents();
1142 PhysicsActor = null;
1143 }
1144 catch
1145 { }
1001 } 1146 }
1002 } 1147 }
1003 1148
@@ -1008,11 +1153,13 @@ namespace OpenSim.Region.Framework.Scenes
1008 public void Teleport(Vector3 pos) 1153 public void Teleport(Vector3 pos)
1009 { 1154 {
1010 bool isFlying = false; 1155 bool isFlying = false;
1156
1011 if (m_physicsActor != null) 1157 if (m_physicsActor != null)
1012 isFlying = m_physicsActor.Flying; 1158 isFlying = m_physicsActor.Flying;
1013 1159
1014 RemoveFromPhysicalScene(); 1160 RemoveFromPhysicalScene();
1015 Velocity = Vector3.Zero; 1161 Velocity = Vector3.Zero;
1162 CheckLandingPoint(ref pos);
1016 AbsolutePosition = pos; 1163 AbsolutePosition = pos;
1017 AddToPhysicalScene(isFlying); 1164 AddToPhysicalScene(isFlying);
1018 if (m_appearance != null) 1165 if (m_appearance != null)
@@ -1022,6 +1169,7 @@ namespace OpenSim.Region.Framework.Scenes
1022 } 1169 }
1023 1170
1024 SendTerseUpdateToAllClients(); 1171 SendTerseUpdateToAllClients();
1172
1025 } 1173 }
1026 1174
1027 public void TeleportWithMomentum(Vector3 pos) 1175 public void TeleportWithMomentum(Vector3 pos)
@@ -1031,6 +1179,7 @@ namespace OpenSim.Region.Framework.Scenes
1031 isFlying = m_physicsActor.Flying; 1179 isFlying = m_physicsActor.Flying;
1032 1180
1033 RemoveFromPhysicalScene(); 1181 RemoveFromPhysicalScene();
1182 CheckLandingPoint(ref pos);
1034 AbsolutePosition = pos; 1183 AbsolutePosition = pos;
1035 AddToPhysicalScene(isFlying); 1184 AddToPhysicalScene(isFlying);
1036 if (m_appearance != null) 1185 if (m_appearance != null)
@@ -1242,6 +1391,7 @@ namespace OpenSim.Region.Framework.Scenes
1242 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1391 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1243 1392
1244 m_pos = m_LastFinitePos; 1393 m_pos = m_LastFinitePos;
1394
1245 if (!m_pos.IsFinite()) 1395 if (!m_pos.IsFinite())
1246 { 1396 {
1247 m_pos.X = 127f; 1397 m_pos.X = 127f;
@@ -1312,7 +1462,6 @@ namespace OpenSim.Region.Framework.Scenes
1312 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1462 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1313 } 1463 }
1314 } 1464 }
1315
1316 lock (scriptedcontrols) 1465 lock (scriptedcontrols)
1317 { 1466 {
1318 if (scriptedcontrols.Count > 0) 1467 if (scriptedcontrols.Count > 0)
@@ -1327,6 +1476,9 @@ namespace OpenSim.Region.Framework.Scenes
1327 1476
1328 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1477 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1329 { 1478 {
1479 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1480 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1481
1330 // TODO: This doesn't prevent the user from walking yet. 1482 // TODO: This doesn't prevent the user from walking yet.
1331 // Setting parent ID would fix this, if we knew what value 1483 // Setting parent ID would fix this, if we knew what value
1332 // to use. Or we could add a m_isSitting variable. 1484 // to use. Or we could add a m_isSitting variable.
@@ -1375,12 +1527,20 @@ namespace OpenSim.Region.Framework.Scenes
1375 if (actor.Flying != oldflying) 1527 if (actor.Flying != oldflying)
1376 update_movementflag = true; 1528 update_movementflag = true;
1377 1529
1530 if (m_animator.m_jumping) // add for jumping
1531 update_movementflag = true;
1532
1378 if (q != m_bodyRot) 1533 if (q != m_bodyRot)
1379 { 1534 {
1380 m_bodyRot = q; 1535 m_bodyRot = q;
1381 update_rotation = true; 1536 update_rotation = true;
1382 } 1537 }
1383 1538
1539 //guilty until proven innocent..
1540 bool Nudging = true;
1541 //Basically, if there is at least one non-nudge control then we don't need
1542 //to worry about stopping the avatar
1543
1384 if (m_parentID == 0) 1544 if (m_parentID == 0)
1385 { 1545 {
1386 bool bAllowUpdateMoveToPosition = false; 1546 bool bAllowUpdateMoveToPosition = false;
@@ -1395,9 +1555,12 @@ namespace OpenSim.Region.Framework.Scenes
1395 else 1555 else
1396 dirVectors = Dir_Vectors; 1556 dirVectors = Dir_Vectors;
1397 1557
1398 // The fact that m_movementflag is a byte needs to be fixed 1558 bool[] isNudge = GetDirectionIsNudge();
1399 // it really should be a uint 1559
1400 uint nudgehack = 250; 1560
1561
1562
1563
1401 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1564 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1402 { 1565 {
1403 if (((uint)flags & (uint)DCF) != 0) 1566 if (((uint)flags & (uint)DCF) != 0)
@@ -1407,40 +1570,28 @@ namespace OpenSim.Region.Framework.Scenes
1407 try 1570 try
1408 { 1571 {
1409 agent_control_v3 += dirVectors[i]; 1572 agent_control_v3 += dirVectors[i];
1410 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1573 if (isNudge[i] == false)
1574 {
1575 Nudging = false;
1576 }
1411 } 1577 }
1412 catch (IndexOutOfRangeException) 1578 catch (IndexOutOfRangeException)
1413 { 1579 {
1414 // Why did I get this? 1580 // Why did I get this?
1415 } 1581 }
1416 1582
1417 if ((m_movementflag & (byte)(uint)DCF) == 0) 1583 if ((m_movementflag & (uint)DCF) == 0)
1418 { 1584 {
1419 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1420 {
1421 m_movementflag |= (byte)nudgehack;
1422 }
1423 m_movementflag += (byte)(uint)DCF; 1585 m_movementflag += (byte)(uint)DCF;
1424 update_movementflag = true; 1586 update_movementflag = true;
1425 } 1587 }
1426 } 1588 }
1427 else 1589 else
1428 { 1590 {
1429 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1591 if ((m_movementflag & (uint)DCF) != 0)
1430 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1431 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1432 ) // This or is for Nudge forward
1433 { 1592 {
1434 m_movementflag -= ((byte)(uint)DCF); 1593 m_movementflag -= (byte)(uint)DCF;
1435
1436 update_movementflag = true; 1594 update_movementflag = true;
1437 /*
1438 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1439 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1440 {
1441 m_log.Debug("Removed Hack flag");
1442 }
1443 */
1444 } 1595 }
1445 else 1596 else
1446 { 1597 {
@@ -1449,7 +1600,6 @@ namespace OpenSim.Region.Framework.Scenes
1449 } 1600 }
1450 i++; 1601 i++;
1451 } 1602 }
1452
1453 //Paupaw:Do Proper PID for Autopilot here 1603 //Paupaw:Do Proper PID for Autopilot here
1454 if (bResetMoveToPosition) 1604 if (bResetMoveToPosition)
1455 { 1605 {
@@ -1461,8 +1611,41 @@ namespace OpenSim.Region.Framework.Scenes
1461 1611
1462 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) 1612 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving))
1463 { 1613 {
1614/*
1615 bool twoD = false;
1616 bool there = false;
1617 if (Animator != null)
1618 {
1619 switch (Animator.CurrentMovementAnimation)
1620 {
1621 case "STAND":
1622 case "WALK":
1623 case "RUN":
1624 case "CROUCH":
1625 case "CROUCHWALK":
1626 {
1627 twoD = true;
1628 }
1629 break;
1630 }
1631 }
1632
1633 if (twoD)
1634 {
1635*/
1636 Vector3 abspos = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, 0.0f);
1637 Vector3 tgt = new Vector3(m_moveToPositionTarget.X, m_moveToPositionTarget.Y, 0.0f);
1638/* if (Util.GetDistanceTo(abspos, tgt) <= 0.5f) there = true;
1639 }
1640 else
1641 {
1642 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) there = true;
1643 }
1644*/
1464 //Check the error term of the current position in relation to the target position 1645 //Check the error term of the current position in relation to the target position
1465 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) 1646// if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f)
1647// if (there)
1648 if (Util.GetDistanceTo(abspos, tgt) <= 0.5f)
1466 { 1649 {
1467 // we are close enough to the target 1650 // we are close enough to the target
1468 m_moveToPositionTarget = Vector3.Zero; 1651 m_moveToPositionTarget = Vector3.Zero;
@@ -1479,11 +1662,15 @@ namespace OpenSim.Region.Framework.Scenes
1479 // unknown forces are acting on the avatar and we need to adaptively respond 1662 // unknown forces are acting on the avatar and we need to adaptively respond
1480 // to such forces, but the following simple approach seems to works fine. 1663 // to such forces, but the following simple approach seems to works fine.
1481 Vector3 LocalVectorToTarget3D = 1664 Vector3 LocalVectorToTarget3D =
1482 (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1665// (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1666 (tgt - abspos)
1483 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords 1667 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords
1484 // Ignore z component of vector 1668 // Ignore z component of vector
1485 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1669 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1486 LocalVectorToTarget2D.Normalize(); 1670 LocalVectorToTarget2D.Normalize();
1671
1672 //We're not nudging
1673 Nudging = false;
1487 agent_control_v3 += LocalVectorToTarget2D; 1674 agent_control_v3 += LocalVectorToTarget2D;
1488 1675
1489 // update avatar movement flags. the avatar coordinate system is as follows: 1676 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1574,13 +1761,13 @@ namespace OpenSim.Region.Framework.Scenes
1574 // m_log.DebugFormat( 1761 // m_log.DebugFormat(
1575 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1762 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1576 1763
1577 AddNewMovement(agent_control_v3, q); 1764 AddNewMovement(agent_control_v3, q, Nudging);
1578 1765
1579 1766
1580 } 1767 }
1581 } 1768 }
1582 1769
1583 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1770 if (update_movementflag && !SitGround)
1584 Animator.UpdateMovementAnimations(); 1771 Animator.UpdateMovementAnimations();
1585 1772
1586 m_scene.EventManager.TriggerOnClientMovement(this); 1773 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1595,7 +1782,6 @@ namespace OpenSim.Region.Framework.Scenes
1595 m_sitAtAutoTarget = false; 1782 m_sitAtAutoTarget = false;
1596 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1783 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1597 //proxy.PCode = (byte)PCode.ParticleSystem; 1784 //proxy.PCode = (byte)PCode.ParticleSystem;
1598
1599 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1785 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1600 proxyObjectGroup.AttachToScene(m_scene); 1786 proxyObjectGroup.AttachToScene(m_scene);
1601 1787
@@ -1614,8 +1800,15 @@ namespace OpenSim.Region.Framework.Scenes
1614// } 1800// }
1615 } 1801 }
1616 1802
1803 public void StopMoveToPosition()
1804 {
1805 m_moveToPositionTarget = Vector3.Zero;
1806 m_moveToPositionInProgress = false;
1807 }
1808
1617 public void DoMoveToPosition(Object sender, string method, List<String> args) 1809 public void DoMoveToPosition(Object sender, string method, List<String> args)
1618 { 1810 {
1811//Console.WriteLine("SP:DoMoveToPosition");
1619 try 1812 try
1620 { 1813 {
1621 float locx = 0f; 1814 float locx = 0f;
@@ -1637,7 +1830,7 @@ namespace OpenSim.Region.Framework.Scenes
1637 } 1830 }
1638 m_moveToPositionInProgress = true; 1831 m_moveToPositionInProgress = true;
1639 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1832 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1640 } 1833 }
1641 catch (Exception ex) 1834 catch (Exception ex)
1642 { 1835 {
1643 //Why did I get this error? 1836 //Why did I get this error?
@@ -1659,7 +1852,7 @@ namespace OpenSim.Region.Framework.Scenes
1659 Velocity = Vector3.Zero; 1852 Velocity = Vector3.Zero;
1660 SendAvatarDataToAllAgents(); 1853 SendAvatarDataToAllAgents();
1661 1854
1662 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1855 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1663 } 1856 }
1664 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1857 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1665 m_requestedSitTargetUUID = UUID.Zero; 1858 m_requestedSitTargetUUID = UUID.Zero;
@@ -1696,25 +1889,22 @@ namespace OpenSim.Region.Framework.Scenes
1696 1889
1697 if (m_parentID != 0) 1890 if (m_parentID != 0)
1698 { 1891 {
1699 m_log.Debug("StandupCode Executed"); 1892 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1700 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1701 if (part != null) 1893 if (part != null)
1702 { 1894 {
1895 part.TaskInventory.LockItemsForRead(true);
1703 TaskInventoryDictionary taskIDict = part.TaskInventory; 1896 TaskInventoryDictionary taskIDict = part.TaskInventory;
1704 if (taskIDict != null) 1897 if (taskIDict != null)
1705 { 1898 {
1706 lock (taskIDict) 1899 foreach (UUID taskID in taskIDict.Keys)
1707 { 1900 {
1708 foreach (UUID taskID in taskIDict.Keys) 1901 UnRegisterControlEventsToScript(LocalId, taskID);
1709 { 1902 taskIDict[taskID].PermsMask &= ~(
1710 UnRegisterControlEventsToScript(LocalId, taskID); 1903 2048 | //PERMISSION_CONTROL_CAMERA
1711 taskIDict[taskID].PermsMask &= ~( 1904 4); // PERMISSION_TAKE_CONTROLS
1712 2048 | //PERMISSION_CONTROL_CAMERA
1713 4); // PERMISSION_TAKE_CONTROLS
1714 }
1715 } 1905 }
1716
1717 } 1906 }
1907 part.TaskInventory.LockItemsForRead(false);
1718 // Reset sit target. 1908 // Reset sit target.
1719 if (part.GetAvatarOnSitTarget() == UUID) 1909 if (part.GetAvatarOnSitTarget() == UUID)
1720 part.SitTargetAvatar = UUID.Zero; 1910 part.SitTargetAvatar = UUID.Zero;
@@ -1723,16 +1913,55 @@ namespace OpenSim.Region.Framework.Scenes
1723 m_parentPosition = part.GetWorldPosition(); 1913 m_parentPosition = part.GetWorldPosition();
1724 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1914 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1725 } 1915 }
1916 // part.GetWorldRotation() is the rotation of the object being sat on
1917 // Rotation is the sittiing Av's rotation
1918
1919 Quaternion partRot;
1920// if (part.LinkNum == 1)
1921// { // Root prim of linkset
1922// partRot = part.ParentGroup.RootPart.RotationOffset;
1923// }
1924// else
1925// { // single or child prim
1926
1927// }
1928 if (part == null) //CW: Part may be gone. llDie() for example.
1929 {
1930 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1931 }
1932 else
1933 {
1934 partRot = part.GetWorldRotation();
1935 }
1936
1937 Quaternion partIRot = Quaternion.Inverse(partRot);
1726 1938
1939 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1940 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1941
1942
1727 if (m_physicsActor == null) 1943 if (m_physicsActor == null)
1728 { 1944 {
1729 AddToPhysicalScene(false); 1945 AddToPhysicalScene(false);
1730 } 1946 }
1731 1947 //CW: If the part isn't null then we can set the current position
1732 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1948 if (part != null)
1733 m_parentPosition = Vector3.Zero; 1949 {
1734 1950 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1735 m_parentID = 0; 1951 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1952 part.IsOccupied = false;
1953 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1954 }
1955 else
1956 {
1957 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1958 AbsolutePosition = m_lastWorldPosition;
1959 }
1960
1961 m_parentPosition = Vector3.Zero;
1962 m_parentID = 0;
1963 m_linkedPrim = UUID.Zero;
1964 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1736 SendAvatarDataToAllAgents(); 1965 SendAvatarDataToAllAgents();
1737 m_requestedSitTargetID = 0; 1966 m_requestedSitTargetID = 0;
1738 if (m_physicsActor != null && m_appearance != null) 1967 if (m_physicsActor != null && m_appearance != null)
@@ -1741,7 +1970,6 @@ namespace OpenSim.Region.Framework.Scenes
1741 SetHeight(m_appearance.AvatarHeight); 1970 SetHeight(m_appearance.AvatarHeight);
1742 } 1971 }
1743 } 1972 }
1744
1745 Animator.TrySetMovementAnimation("STAND"); 1973 Animator.TrySetMovementAnimation("STAND");
1746 } 1974 }
1747 1975
@@ -1772,13 +2000,9 @@ namespace OpenSim.Region.Framework.Scenes
1772 Vector3 avSitOffSet = part.SitTargetPosition; 2000 Vector3 avSitOffSet = part.SitTargetPosition;
1773 Quaternion avSitOrientation = part.SitTargetOrientation; 2001 Quaternion avSitOrientation = part.SitTargetOrientation;
1774 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2002 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1775 2003 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1776 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2004 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1777 bool SitTargetisSet = 2005 if (SitTargetisSet && !SitTargetOccupied)
1778 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1779 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1780
1781 if (SitTargetisSet && SitTargetUnOccupied)
1782 { 2006 {
1783 //switch the target to this prim 2007 //switch the target to this prim
1784 return part; 2008 return part;
@@ -1792,85 +2016,168 @@ namespace OpenSim.Region.Framework.Scenes
1792 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2016 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1793 { 2017 {
1794 bool autopilot = true; 2018 bool autopilot = true;
2019 Vector3 autopilotTarget = new Vector3();
2020 Quaternion sitOrientation = Quaternion.Identity;
1795 Vector3 pos = new Vector3(); 2021 Vector3 pos = new Vector3();
1796 Quaternion sitOrientation = pSitOrientation;
1797 Vector3 cameraEyeOffset = Vector3.Zero; 2022 Vector3 cameraEyeOffset = Vector3.Zero;
1798 Vector3 cameraAtOffset = Vector3.Zero; 2023 Vector3 cameraAtOffset = Vector3.Zero;
1799 bool forceMouselook = false; 2024 bool forceMouselook = false;
1800 2025
1801 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2026 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1802 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2027 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1803 if (part != null) 2028 if (part == null) return;
1804 { 2029
1805 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2030 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1806 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2031 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1807 2032
1808 // Is a sit target available? 2033 // part is the prim to sit on
1809 Vector3 avSitOffSet = part.SitTargetPosition; 2034 // offset is the world-ref vector distance from that prim center to the click-spot
1810 Quaternion avSitOrientation = part.SitTargetOrientation; 2035 // UUID is the UUID of the Avatar doing the clicking
1811 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2036
1812 2037 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1813 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2038
1814 bool SitTargetisSet = 2039 // Is a sit target available?
1815 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 2040 Vector3 avSitOffSet = part.SitTargetPosition;
1816 ( 2041 Quaternion avSitOrientation = part.SitTargetOrientation;
1817 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 2042
1818 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 2043 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1819 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 2044 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1820 ) 2045 Quaternion partRot;
1821 )); 2046// if (part.LinkNum == 1)
1822 2047// { // Root prim of linkset
1823 if (SitTargetisSet && SitTargetUnOccupied) 2048// partRot = part.ParentGroup.RootPart.RotationOffset;
1824 { 2049// }
1825 part.SitTargetAvatar = UUID; 2050// else
1826 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 2051// { // single or child prim
1827 sitOrientation = avSitOrientation; 2052 partRot = part.GetWorldRotation();
1828 autopilot = false; 2053// }
1829 } 2054 Quaternion partIRot = Quaternion.Inverse(partRot);
1830 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2055//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1831 2056 // Sit analysis rewritten by KF 091125
1832 pos = part.AbsolutePosition + offset; 2057 if (SitTargetisSet) // scipted sit
1833 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 2058 {
1834 //{ 2059 if (!part.IsOccupied)
1835 // offset = pos; 2060 {
1836 //autopilot = false; 2061//Console.WriteLine("Scripted, unoccupied");
1837 //} 2062 part.SitTargetAvatar = UUID; // set that Av will be on it
1838 if (m_physicsActor != null) 2063 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1839 { 2064
1840 // If we're not using the client autopilot, we're immediately warping the avatar to the location 2065 Quaternion nrot = avSitOrientation;
1841 // We can remove the physicsActor until they stand up. 2066 if (!part.IsRoot)
1842 m_sitAvatarHeight = m_physicsActor.Size.Z;
1843
1844 if (autopilot)
1845 { 2067 {
1846 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2068 nrot = part.RotationOffset * avSitOrientation;
1847 {
1848 autopilot = false;
1849
1850 RemoveFromPhysicalScene();
1851 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1852 }
1853 } 2069 }
1854 else 2070 sitOrientation = nrot; // Change rotatione to the scripted one
2071 OffsetRotation = nrot;
2072 autopilot = false; // Jump direct to scripted llSitPos()
2073 }
2074 else
2075 {
2076//Console.WriteLine("Scripted, occupied");
2077 return;
2078 }
2079 }
2080 else // Not Scripted
2081 {
2082 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
2083 {
2084 // large prim & offset, ignore if other Avs sitting
2085// offset.Z -= 0.05f;
2086 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2087 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2088
2089//Console.WriteLine(" offset ={0}", offset);
2090//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2091//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2092
2093 }
2094 else // small offset
2095 {
2096//Console.WriteLine("Small offset");
2097 if (!part.IsOccupied)
2098 {
2099 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2100 autopilotTarget = part.AbsolutePosition;
2101//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2102 }
2103 else return; // occupied small
2104 } // end large/small
2105 } // end Scripted/not
2106
2107 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2108
2109 cameraAtOffset = part.GetCameraAtOffset();
2110 cameraEyeOffset = part.GetCameraEyeOffset();
2111 forceMouselook = part.GetForceMouselook();
2112 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2113 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2114
2115 if (m_physicsActor != null)
2116 {
2117 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2118 // We can remove the physicsActor until they stand up.
2119 m_sitAvatarHeight = m_physicsActor.Size.Z;
2120 if (autopilot)
2121 { // its not a scripted sit
2122// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2123 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1855 { 2124 {
2125 autopilot = false; // close enough
2126 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2127 Not using the part's position because returning the AV to the last known standing
2128 position is likely to be more friendly, isn't it? */
1856 RemoveFromPhysicalScene(); 2129 RemoveFromPhysicalScene();
1857 } 2130 Velocity = Vector3.Zero;
2131 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2132 } // else the autopilot will get us close
2133 }
2134 else
2135 { // its a scripted sit
2136 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2137 I *am* using the part's position this time because we have no real idea how far away
2138 the avatar is from the sit target. */
2139 RemoveFromPhysicalScene();
2140 Velocity = Vector3.Zero;
1858 } 2141 }
1859
1860 cameraAtOffset = part.GetCameraAtOffset();
1861 cameraEyeOffset = part.GetCameraEyeOffset();
1862 forceMouselook = part.GetForceMouselook();
1863 } 2142 }
1864 2143 else return; // physactor is null!
1865 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2144
1866 m_requestedSitTargetUUID = targetID; 2145 Vector3 offsetr; // = offset * partIRot;
2146 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2147 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2148 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2149 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2150 //offsetr = offset * partIRot;
2151//
2152 // }
2153 // else
2154 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2155 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2156 // (offset * partRot);
2157 // }
2158
2159//Console.WriteLine(" ");
2160//Console.WriteLine("link number ={0}", part.LinkNum);
2161//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2162//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2163//Console.WriteLine("Click offst ={0}", offset);
2164//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2165//Console.WriteLine("offsetr ={0}", offsetr);
2166//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2167//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2168
2169 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2170 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2171
2172 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1867 // This calls HandleAgentSit twice, once from here, and the client calls 2173 // This calls HandleAgentSit twice, once from here, and the client calls
1868 // HandleAgentSit itself after it gets to the location 2174 // HandleAgentSit itself after it gets to the location
1869 // It doesn't get to the location until we've moved them there though 2175 // It doesn't get to the location until we've moved them there though
1870 // which happens in HandleAgentSit :P 2176 // which happens in HandleAgentSit :P
1871 m_autopilotMoving = autopilot; 2177 m_autopilotMoving = autopilot;
1872 m_autoPilotTarget = pos; 2178 m_autoPilotTarget = autopilotTarget;
1873 m_sitAtAutoTarget = autopilot; 2179 m_sitAtAutoTarget = autopilot;
2180 m_initialSitTarget = autopilotTarget;
1874 if (!autopilot) 2181 if (!autopilot)
1875 HandleAgentSit(remoteClient, UUID); 2182 HandleAgentSit(remoteClient, UUID);
1876 } 2183 }
@@ -2165,47 +2472,130 @@ namespace OpenSim.Region.Framework.Scenes
2165 { 2472 {
2166 if (part != null) 2473 if (part != null)
2167 { 2474 {
2475//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2168 if (part.GetAvatarOnSitTarget() == UUID) 2476 if (part.GetAvatarOnSitTarget() == UUID)
2169 { 2477 {
2478//Console.WriteLine("Scripted Sit");
2479 // Scripted sit
2170 Vector3 sitTargetPos = part.SitTargetPosition; 2480 Vector3 sitTargetPos = part.SitTargetPosition;
2171 Quaternion sitTargetOrient = part.SitTargetOrientation; 2481 Quaternion sitTargetOrient = part.SitTargetOrientation;
2172
2173 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2174 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2175
2176 //Quaternion result = (sitTargetOrient * vq) * nq;
2177
2178 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2482 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2179 m_pos += SIT_TARGET_ADJUSTMENT; 2483 m_pos += SIT_TARGET_ADJUSTMENT;
2484 if (!part.IsRoot)
2485 {
2486 m_pos *= part.RotationOffset;
2487 }
2180 m_bodyRot = sitTargetOrient; 2488 m_bodyRot = sitTargetOrient;
2181 //Rotation = sitTargetOrient;
2182 m_parentPosition = part.AbsolutePosition; 2489 m_parentPosition = part.AbsolutePosition;
2183 2490 part.IsOccupied = true;
2184 //SendTerseUpdateToAllClients(); 2491 part.ParentGroup.AddAvatar(agentID);
2185 } 2492 }
2186 else 2493 else
2187 { 2494 {
2188 m_pos -= part.AbsolutePosition; 2495 // if m_avUnscriptedSitPos is zero then Av sits above center
2496 // Else Av sits at m_avUnscriptedSitPos
2497
2498 // Non-scripted sit by Kitto Flora 21Nov09
2499 // Calculate angle of line from prim to Av
2500 Quaternion partIRot;
2501// if (part.LinkNum == 1)
2502// { // Root prim of linkset
2503// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2504// }
2505// else
2506// { // single or child prim
2507 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2508// }
2509 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2510 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2511 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2512 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2513 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2514 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2515 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2516 // Av sits at world euler <0,0, z>, translated by part rotation
2517 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2518
2189 m_parentPosition = part.AbsolutePosition; 2519 m_parentPosition = part.AbsolutePosition;
2190 } 2520 part.IsOccupied = true;
2521 part.ParentGroup.AddAvatar(agentID);
2522 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2523 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2524 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2525 m_avUnscriptedSitPos; // adds click offset, if any
2526 //Set up raytrace to find top surface of prim
2527 Vector3 size = part.Scale;
2528 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2529 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2530 Vector3 down = new Vector3(0f, 0f, -1f);
2531//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2532 m_scene.PhysicsScene.RaycastWorld(
2533 start, // Vector3 position,
2534 down, // Vector3 direction,
2535 mag, // float length,
2536 SitAltitudeCallback); // retMethod
2537 } // end scripted/not
2191 } 2538 }
2192 else 2539 else // no Av
2193 { 2540 {
2194 return; 2541 return;
2195 } 2542 }
2196 } 2543 }
2197 m_parentID = m_requestedSitTargetID;
2198 2544
2545 //We want our offsets to reference the root prim, not the child we may have sat on
2546 if (!part.IsRoot)
2547 {
2548 m_parentID = part.ParentGroup.RootPart.LocalId;
2549 m_pos += part.OffsetPosition;
2550 }
2551 else
2552 {
2553 m_parentID = m_requestedSitTargetID;
2554 }
2555
2556 m_linkedPrim = part.UUID;
2557 if (part.GetAvatarOnSitTarget() != UUID)
2558 {
2559 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2560 }
2199 Velocity = Vector3.Zero; 2561 Velocity = Vector3.Zero;
2200 RemoveFromPhysicalScene(); 2562 RemoveFromPhysicalScene();
2201
2202 Animator.TrySetMovementAnimation(sitAnimation); 2563 Animator.TrySetMovementAnimation(sitAnimation);
2203 SendAvatarDataToAllAgents(); 2564 SendAvatarDataToAllAgents();
2204 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2205 // So we're also sending a terse update (which has avatar rotation)
2206 // [Update] We do now.
2207 //SendTerseUpdateToAllClients(); 2565 //SendTerseUpdateToAllClients();
2208 } 2566 }
2567
2568 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2569 {
2570 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2571 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2572 if(hitYN)
2573 {
2574 // m_pos = Av offset from prim center to make look like on center
2575 // m_parentPosition = Actual center pos of prim
2576 // collisionPoint = spot on prim where we want to sit
2577 // collisionPoint.Z = global sit surface height
2578 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2579 Quaternion partIRot;
2580// if (part.LinkNum == 1)
2581/// { // Root prim of linkset
2582// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2583// }
2584// else
2585// { // single or child prim
2586 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2587// }
2588 if (m_initialSitTarget != null)
2589 {
2590 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2591 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2592 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2593 m_pos += offset;
2594 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2595 }
2596
2597 }
2598 } // End SitAltitudeCallback KF.
2209 2599
2210 /// <summary> 2600 /// <summary>
2211 /// Event handler for the 'Always run' setting on the client 2601 /// Event handler for the 'Always run' setting on the client
@@ -2235,12 +2625,13 @@ namespace OpenSim.Region.Framework.Scenes
2235 /// </summary> 2625 /// </summary>
2236 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2626 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2237 /// <param name="rotation">The direction in which this avatar should now face. 2627 /// <param name="rotation">The direction in which this avatar should now face.
2238 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2628 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2239 { 2629 {
2240 if (m_isChildAgent) 2630 if (m_isChildAgent)
2241 { 2631 {
2242 // WHAT??? 2632 // WHAT???
2243 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); 2633 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent");
2634
2244 return; 2635 return;
2245 } 2636 }
2246 2637
@@ -2249,15 +2640,26 @@ namespace OpenSim.Region.Framework.Scenes
2249 Rotation = rotation; 2640 Rotation = rotation;
2250 Vector3 direc = vec * rotation; 2641 Vector3 direc = vec * rotation;
2251 direc.Normalize(); 2642 direc.Normalize();
2643 PhysicsActor actor = m_physicsActor;
2644
2645 if (actor.Flying != m_flyingOld) // add for fly velocity control
2646 {
2647 m_flyingOld = actor.Flying; // add for fly velocity control
2648 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2649 }
2650
2651 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2652
2653 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2252 2654
2253 direc *= 0.03f * 128f * m_speedModifier; 2655 direc *= 0.03f * 128f * m_speedModifier;
2254 2656
2255 PhysicsActor actor = m_physicsActor;
2256 if (actor != null) 2657 if (actor != null)
2257 { 2658 {
2258 if (actor.Flying) 2659 if (actor.Flying)
2259 { 2660 {
2260 direc *= 4.0f; 2661// rm speed mod direc *= 4.0f;
2662 direc *= 5.2f; // for speed mod
2261 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2663 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2262 //bool colliding = (m_physicsActor.IsColliding==true); 2664 //bool colliding = (m_physicsActor.IsColliding==true);
2263 //if (controlland) 2665 //if (controlland)
@@ -2270,22 +2672,34 @@ namespace OpenSim.Region.Framework.Scenes
2270 // m_log.Info("[AGENT]: Stop FLying"); 2672 // m_log.Info("[AGENT]: Stop FLying");
2271 //} 2673 //}
2272 } 2674 }
2675 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2676 {
2677 direc *= 0.0f;
2678 }
2679 /* This jumping section removed to SPA
2273 else if (!actor.Flying && actor.IsColliding) 2680 else if (!actor.Flying && actor.IsColliding)
2274 { 2681 {
2275 if (direc.Z > 2.0f) 2682 if (direc.Z > 2.0f)
2276 { 2683 {
2277 direc.Z *= 3.0f; 2684 if(m_animator.m_animTickJump == -1)
2278 2685 {
2279 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2686 direc.Z *= 3.0f; // jump
2280 Animator.TrySetMovementAnimation("PREJUMP"); 2687 }
2281 Animator.TrySetMovementAnimation("JUMP"); 2688 else
2689 {
2690 direc.Z *= 0.1f; // prejump
2691 }
2692 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2693 Animator.TrySetMovementAnimation("PREJUMP");
2694 Animator.TrySetMovementAnimation("JUMP");
2695 * /
2282 } 2696 }
2283 } 2697 } */
2284 } 2698 }
2285 2699
2286 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2700 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2287 m_forceToApply = direc; 2701 m_forceToApply = direc;
2288 2702 m_isNudging = Nudging;
2289 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2703 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2290 } 2704 }
2291 2705
@@ -2334,6 +2748,9 @@ namespace OpenSim.Region.Framework.Scenes
2334 2748
2335 CheckForSignificantMovement(); // sends update to the modules. 2749 CheckForSignificantMovement(); // sends update to the modules.
2336 } 2750 }
2751
2752 //Sending prim updates AFTER the avatar terse updates are sent
2753 SendPrimUpdates();
2337 } 2754 }
2338 2755
2339 #endregion 2756 #endregion
@@ -3143,6 +3560,7 @@ namespace OpenSim.Region.Framework.Scenes
3143 m_callbackURI = cAgent.CallbackURI; 3560 m_callbackURI = cAgent.CallbackURI;
3144 3561
3145 m_pos = cAgent.Position; 3562 m_pos = cAgent.Position;
3563
3146 m_velocity = cAgent.Velocity; 3564 m_velocity = cAgent.Velocity;
3147 m_CameraCenter = cAgent.Center; 3565 m_CameraCenter = cAgent.Center;
3148 m_CameraAtAxis = cAgent.AtAxis; 3566 m_CameraAtAxis = cAgent.AtAxis;
@@ -3265,20 +3683,45 @@ namespace OpenSim.Region.Framework.Scenes
3265 /// </summary> 3683 /// </summary>
3266 public override void UpdateMovement() 3684 public override void UpdateMovement()
3267 { 3685 {
3268 if (m_forceToApply.HasValue) 3686 if (Animator!=null) // add for jumping
3269 { 3687 { // add for jumping
3270 Vector3 force = m_forceToApply.Value; 3688 // if (!m_animator.m_jumping) // add for jumping
3689 // { // add for jumping
3271 3690
3272 m_updateflag = true; 3691 if (m_forceToApply.HasValue) // this section realigned
3273 3692 {
3274 // The magic constant 0.95f seems to make walking feel less jerky,
3275 // probably because it hackishly accounts for the overall latency of
3276 // these Velocity updates -- Diva
3277 Velocity = force * .95F;
3278 3693
3279 m_forceToApply = null; 3694 Vector3 force = m_forceToApply.Value;
3280 } 3695 m_updateflag = true;
3281 } 3696if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3697 Velocity = force;
3698//Console.WriteLine("UM1 {0}", Velocity);
3699 m_forceToApply = null;
3700 }
3701 else
3702 {
3703 if (m_isNudging)
3704 {
3705 Vector3 force = Vector3.Zero;
3706
3707 m_updateflag = true;
3708if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3709 Velocity = force;
3710//Console.WriteLine("UM2 {0}", Velocity);
3711 m_isNudging = false;
3712 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3713 }
3714 else // add for jumping
3715 { // add for jumping
3716 Vector3 force = Vector3.Zero; // add for jumping
3717if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3718//Console.WriteLine("UM3 {0}", Velocity);
3719 Velocity = force; // add for jumping
3720 }
3721 }
3722 // } // end realign
3723 } // add for jumping
3724 } // add for jumping
3282 3725
3283 /// <summary> 3726 /// <summary>
3284 /// Adds a physical representation of the avatar to the Physics plugin 3727 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3292,10 +3735,8 @@ namespace OpenSim.Region.Framework.Scenes
3292 3735
3293 Vector3 pVec = AbsolutePosition; 3736 Vector3 pVec = AbsolutePosition;
3294 3737
3295 // Old bug where the height was in centimeters instead of meters
3296 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3738 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3297 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3739 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3298
3299 scene.AddPhysicsActorTaint(m_physicsActor); 3740 scene.AddPhysicsActorTaint(m_physicsActor);
3300 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3741 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3301 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3742 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3319,18 +3760,29 @@ namespace OpenSim.Region.Framework.Scenes
3319 { 3760 {
3320 if (e == null) 3761 if (e == null)
3321 return; 3762 return;
3322 3763
3323 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3764 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3324 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3325 // as of this comment the interval is set in AddToPhysicalScene 3765 // as of this comment the interval is set in AddToPhysicalScene
3326 if (Animator!=null) 3766 if (Animator!=null)
3327 Animator.UpdateMovementAnimations(); 3767 {
3768 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3769 { // else its will lock out other animation changes, like ground sit.
3770 Animator.UpdateMovementAnimations();
3771 m_updateCount--;
3772 }
3773 }
3328 3774
3329 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3775 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3330 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3776 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3331 3777
3332 CollisionPlane = Vector4.UnitW; 3778 CollisionPlane = Vector4.UnitW;
3333 3779
3780 if (m_lastColCount != coldata.Count)
3781 {
3782 m_updateCount = UPDATE_COUNT;
3783 m_lastColCount = coldata.Count;
3784 }
3785
3334 if (coldata.Count != 0 && Animator != null) 3786 if (coldata.Count != 0 && Animator != null)
3335 { 3787 {
3336 switch (Animator.CurrentMovementAnimation) 3788 switch (Animator.CurrentMovementAnimation)
@@ -3360,6 +3812,148 @@ namespace OpenSim.Region.Framework.Scenes
3360 } 3812 }
3361 } 3813 }
3362 3814
3815 List<uint> thisHitColliders = new List<uint>();
3816 List<uint> endedColliders = new List<uint>();
3817 List<uint> startedColliders = new List<uint>();
3818
3819 foreach (uint localid in coldata.Keys)
3820 {
3821 thisHitColliders.Add(localid);
3822 if (!m_lastColliders.Contains(localid))
3823 {
3824 startedColliders.Add(localid);
3825 }
3826 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3827 }
3828
3829 // calculate things that ended colliding
3830 foreach (uint localID in m_lastColliders)
3831 {
3832 if (!thisHitColliders.Contains(localID))
3833 {
3834 endedColliders.Add(localID);
3835 }
3836 }
3837 //add the items that started colliding this time to the last colliders list.
3838 foreach (uint localID in startedColliders)
3839 {
3840 m_lastColliders.Add(localID);
3841 }
3842 // remove things that ended colliding from the last colliders list
3843 foreach (uint localID in endedColliders)
3844 {
3845 m_lastColliders.Remove(localID);
3846 }
3847
3848 // do event notification
3849 if (startedColliders.Count > 0)
3850 {
3851 ColliderArgs StartCollidingMessage = new ColliderArgs();
3852 List<DetectedObject> colliding = new List<DetectedObject>();
3853 foreach (uint localId in startedColliders)
3854 {
3855 if (localId == 0)
3856 continue;
3857
3858 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3859 string data = "";
3860 if (obj != null)
3861 {
3862 DetectedObject detobj = new DetectedObject();
3863 detobj.keyUUID = obj.UUID;
3864 detobj.nameStr = obj.Name;
3865 detobj.ownerUUID = obj.OwnerID;
3866 detobj.posVector = obj.AbsolutePosition;
3867 detobj.rotQuat = obj.GetWorldRotation();
3868 detobj.velVector = obj.Velocity;
3869 detobj.colliderType = 0;
3870 detobj.groupUUID = obj.GroupID;
3871 colliding.Add(detobj);
3872 }
3873 }
3874
3875 if (colliding.Count > 0)
3876 {
3877 StartCollidingMessage.Colliders = colliding;
3878
3879 foreach (SceneObjectGroup att in Attachments)
3880 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3881 }
3882 }
3883
3884 if (endedColliders.Count > 0)
3885 {
3886 ColliderArgs EndCollidingMessage = new ColliderArgs();
3887 List<DetectedObject> colliding = new List<DetectedObject>();
3888 foreach (uint localId in endedColliders)
3889 {
3890 if (localId == 0)
3891 continue;
3892
3893 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3894 string data = "";
3895 if (obj != null)
3896 {
3897 DetectedObject detobj = new DetectedObject();
3898 detobj.keyUUID = obj.UUID;
3899 detobj.nameStr = obj.Name;
3900 detobj.ownerUUID = obj.OwnerID;
3901 detobj.posVector = obj.AbsolutePosition;
3902 detobj.rotQuat = obj.GetWorldRotation();
3903 detobj.velVector = obj.Velocity;
3904 detobj.colliderType = 0;
3905 detobj.groupUUID = obj.GroupID;
3906 colliding.Add(detobj);
3907 }
3908 }
3909
3910 if (colliding.Count > 0)
3911 {
3912 EndCollidingMessage.Colliders = colliding;
3913
3914 foreach (SceneObjectGroup att in Attachments)
3915 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3916 }
3917 }
3918
3919 if (thisHitColliders.Count > 0)
3920 {
3921 ColliderArgs CollidingMessage = new ColliderArgs();
3922 List<DetectedObject> colliding = new List<DetectedObject>();
3923 foreach (uint localId in thisHitColliders)
3924 {
3925 if (localId == 0)
3926 continue;
3927
3928 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3929 string data = "";
3930 if (obj != null)
3931 {
3932 DetectedObject detobj = new DetectedObject();
3933 detobj.keyUUID = obj.UUID;
3934 detobj.nameStr = obj.Name;
3935 detobj.ownerUUID = obj.OwnerID;
3936 detobj.posVector = obj.AbsolutePosition;
3937 detobj.rotQuat = obj.GetWorldRotation();
3938 detobj.velVector = obj.Velocity;
3939 detobj.colliderType = 0;
3940 detobj.groupUUID = obj.GroupID;
3941 colliding.Add(detobj);
3942 }
3943 }
3944
3945 if (colliding.Count > 0)
3946 {
3947 CollidingMessage.Colliders = colliding;
3948
3949 lock (m_attachments)
3950 {
3951 foreach (SceneObjectGroup att in m_attachments)
3952 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3953 }
3954 }
3955 }
3956
3363 if (m_invulnerable) 3957 if (m_invulnerable)
3364 return; 3958 return;
3365 3959
@@ -3785,6 +4379,39 @@ namespace OpenSim.Region.Framework.Scenes
3785 return; 4379 return;
3786 } 4380 }
3787 4381
4382 XmlDocument doc = new XmlDocument();
4383 string stateData = String.Empty;
4384
4385 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4386 if (attServ != null)
4387 {
4388 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4389 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4390 if (stateData != String.Empty)
4391 {
4392 try
4393 {
4394 doc.LoadXml(stateData);
4395 }
4396 catch { }
4397 }
4398 }
4399
4400 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4401
4402 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4403 if (nodes.Count > 0)
4404 {
4405 foreach (XmlNode n in nodes)
4406 {
4407 XmlElement elem = (XmlElement)n;
4408 string itemID = elem.GetAttribute("ItemID");
4409 string xml = elem.InnerXml;
4410
4411 itemData[new UUID(itemID)] = xml;
4412 }
4413 }
4414
3788 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4415 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3789 foreach (AvatarAttachment attach in attachments) 4416 foreach (AvatarAttachment attach in attachments)
3790 { 4417 {
@@ -3805,7 +4432,30 @@ namespace OpenSim.Region.Framework.Scenes
3805 4432
3806 try 4433 try
3807 { 4434 {
3808 m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4435 string xmlData;
4436 XmlDocument d = new XmlDocument();
4437 UUID asset;
4438 if (itemData.TryGetValue(itemID, out xmlData))
4439 {
4440 d.LoadXml(xmlData);
4441 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4442
4443 // Rez from inventory
4444 asset
4445 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4446
4447 }
4448 else
4449 {
4450 // Rez from inventory (with a null doc to let
4451 // CHANGED_OWNER happen)
4452 asset
4453 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4454 }
4455
4456 m_log.InfoFormat(
4457 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4458 p, itemID, asset);
3809 } 4459 }
3810 catch (Exception e) 4460 catch (Exception e)
3811 { 4461 {
@@ -3838,6 +4488,15 @@ namespace OpenSim.Region.Framework.Scenes
3838 m_reprioritization_called = false; 4488 m_reprioritization_called = false;
3839 } 4489 }
3840 } 4490 }
4491
4492 private Vector3 Quat2Euler(Quaternion rot){
4493 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4494 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4495 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4496 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4497 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4498 return(new Vector3(x,y,z));
4499 }
3841 4500
3842 public void SaveChangedAttachments() 4501 public void SaveChangedAttachments()
3843 { 4502 {
@@ -3861,5 +4520,30 @@ namespace OpenSim.Region.Framework.Scenes
3861 } 4520 }
3862 } 4521 }
3863 } 4522 }
4523
4524 private void CheckLandingPoint(ref Vector3 pos)
4525 {
4526 // Never constrain lures
4527 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4528 return;
4529
4530 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4531 return;
4532
4533 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4534
4535 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4536 land.LandData.UserLocation != Vector3.Zero &&
4537 land.LandData.OwnerID != m_uuid &&
4538 (!m_scene.Permissions.IsGod(m_uuid)) &&
4539 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4540 {
4541 float curr = Vector3.Distance(AbsolutePosition, pos);
4542 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4543 pos = land.LandData.UserLocation;
4544 else
4545 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4546 }
4547 }
3864 } 4548 }
3865} 4549}