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.cs1022
1 files changed, 833 insertions, 189 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index cd70de8..a1ca9c5 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>();
@@ -121,8 +125,11 @@ namespace OpenSim.Region.Framework.Scenes
121 public Vector3 lastKnownAllowedPosition; 125 public Vector3 lastKnownAllowedPosition;
122 public bool sentMessageAboutRestrictedParcelFlyingDown; 126 public bool sentMessageAboutRestrictedParcelFlyingDown;
123 public Vector4 CollisionPlane = Vector4.UnitW; 127 public Vector4 CollisionPlane = Vector4.UnitW;
124 128
129 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
130 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
125 private Vector3 m_lastPosition; 131 private Vector3 m_lastPosition;
132 private Vector3 m_lastWorldPosition;
126 private Quaternion m_lastRotation; 133 private Quaternion m_lastRotation;
127 private Vector3 m_lastVelocity; 134 private Vector3 m_lastVelocity;
128 //private int m_lastTerseSent; 135 //private int m_lastTerseSent;
@@ -130,6 +137,11 @@ namespace OpenSim.Region.Framework.Scenes
130 private bool m_updateflag; 137 private bool m_updateflag;
131 private byte m_movementflag; 138 private byte m_movementflag;
132 private Vector3? m_forceToApply; 139 private Vector3? m_forceToApply;
140 private int m_userFlags;
141 public int UserFlags
142 {
143 get { return m_userFlags; }
144 }
133 private TeleportFlags m_teleportFlags; 145 private TeleportFlags m_teleportFlags;
134 public TeleportFlags TeleportFlags 146 public TeleportFlags TeleportFlags
135 { 147 {
@@ -160,9 +172,10 @@ namespace OpenSim.Region.Framework.Scenes
160 private int m_perfMonMS; 172 private int m_perfMonMS;
161 173
162 private bool m_setAlwaysRun; 174 private bool m_setAlwaysRun;
163
164 private bool m_forceFly; 175 private bool m_forceFly;
165 private bool m_flyDisabled; 176 private bool m_flyDisabled;
177 private bool m_flyingOld; // add for fly velocity control
178 public bool m_wasFlying; // add for fly velocity control
166 179
167 private float m_speedModifier = 1.0f; 180 private float m_speedModifier = 1.0f;
168 181
@@ -181,7 +194,8 @@ namespace OpenSim.Region.Framework.Scenes
181 protected RegionInfo m_regionInfo; 194 protected RegionInfo m_regionInfo;
182 protected ulong crossingFromRegion; 195 protected ulong crossingFromRegion;
183 196
184 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 197 private readonly Vector3[] Dir_Vectors = new Vector3[11];
198 private bool m_isNudging = false;
185 199
186 // Position of agent's camera in world (region cordinates) 200 // Position of agent's camera in world (region cordinates)
187 protected Vector3 m_CameraCenter; 201 protected Vector3 m_CameraCenter;
@@ -206,17 +220,25 @@ namespace OpenSim.Region.Framework.Scenes
206 private bool m_autopilotMoving; 220 private bool m_autopilotMoving;
207 private Vector3 m_autoPilotTarget; 221 private Vector3 m_autoPilotTarget;
208 private bool m_sitAtAutoTarget; 222 private bool m_sitAtAutoTarget;
223 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
209 224
210 private string m_nextSitAnimation = String.Empty; 225 private string m_nextSitAnimation = String.Empty;
211 226
212 //PauPaw:Proper PID Controler for autopilot************ 227 //PauPaw:Proper PID Controler for autopilot************
213 private bool m_moveToPositionInProgress; 228 private bool m_moveToPositionInProgress;
214 private Vector3 m_moveToPositionTarget; 229 private Vector3 m_moveToPositionTarget;
230 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
215 231
216 private bool m_followCamAuto; 232 private bool m_followCamAuto;
217 233
218 private int m_movementUpdateCount; 234 private int m_movementUpdateCount;
235 private int m_lastColCount = -1; //KF: Look for Collision chnages
236 private int m_updateCount = 0; //KF: Update Anims for a while
237 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
219 private const int NumMovementsBetweenRayCast = 5; 238 private const int NumMovementsBetweenRayCast = 5;
239 private List<uint> m_lastColliders = new List<uint>();
240
241 private object m_syncRoot = new Object();
220 242
221 private bool CameraConstraintActive; 243 private bool CameraConstraintActive;
222 //private int m_moveToPositionStateStatus; 244 //private int m_moveToPositionStateStatus;
@@ -243,7 +265,9 @@ namespace OpenSim.Region.Framework.Scenes
243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 265 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 266 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 267 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, 268 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
269 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
270 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 271 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
248 } 272 }
249 273
@@ -450,7 +474,8 @@ namespace OpenSim.Region.Framework.Scenes
450 get 474 get
451 { 475 {
452 PhysicsActor actor = m_physicsActor; 476 PhysicsActor actor = m_physicsActor;
453 if (actor != null) 477// if (actor != null)
478 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
454 m_pos = actor.Position; 479 m_pos = actor.Position;
455 else 480 else
456 { 481 {
@@ -499,7 +524,8 @@ namespace OpenSim.Region.Framework.Scenes
499 } 524 }
500 } 525 }
501 526
502 m_pos = value; 527 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
528 m_pos = value;
503 m_parentPosition = Vector3.Zero; 529 m_parentPosition = Vector3.Zero;
504 } 530 }
505 } 531 }
@@ -543,10 +569,39 @@ namespace OpenSim.Region.Framework.Scenes
543 } 569 }
544 } 570 }
545 571
572 public Quaternion OffsetRotation
573 {
574 get { return m_offsetRotation; }
575 set { m_offsetRotation = value; }
576 }
577
546 public Quaternion Rotation 578 public Quaternion Rotation
547 { 579 {
548 get { return m_bodyRot; } 580 get {
549 set { m_bodyRot = value; } 581 if (m_parentID != 0)
582 {
583 if (m_offsetRotation != null)
584 {
585 return m_offsetRotation;
586 }
587 else
588 {
589 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
590 }
591
592 }
593 else
594 {
595 return m_bodyRot;
596 }
597 }
598 set {
599 m_bodyRot = value;
600 if (m_parentID != 0)
601 {
602 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
603 }
604 }
550 } 605 }
551 606
552 public Quaternion PreviousRotation 607 public Quaternion PreviousRotation
@@ -571,11 +626,21 @@ namespace OpenSim.Region.Framework.Scenes
571 626
572 private uint m_parentID; 627 private uint m_parentID;
573 628
629
630 private UUID m_linkedPrim;
631
574 public uint ParentID 632 public uint ParentID
575 { 633 {
576 get { return m_parentID; } 634 get { return m_parentID; }
577 set { m_parentID = value; } 635 set { m_parentID = value; }
578 } 636 }
637
638 public UUID LinkedPrim
639 {
640 get { return m_linkedPrim; }
641 set { m_linkedPrim = value; }
642 }
643
579 public float Health 644 public float Health
580 { 645 {
581 get { return m_health; } 646 get { return m_health; }
@@ -697,7 +762,7 @@ namespace OpenSim.Region.Framework.Scenes
697 CreateSceneViewer(); 762 CreateSceneViewer();
698 m_animator = new ScenePresenceAnimator(this); 763 m_animator = new ScenePresenceAnimator(this);
699 } 764 }
700 765
701 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 766 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
702 { 767 {
703 m_rootRegionHandle = reginfo.RegionHandle; 768 m_rootRegionHandle = reginfo.RegionHandle;
@@ -711,6 +776,7 @@ namespace OpenSim.Region.Framework.Scenes
711 m_localId = m_scene.AllocateLocalId(); 776 m_localId = m_scene.AllocateLocalId();
712 777
713 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;
714 780
715 if (account != null) 781 if (account != null)
716 m_userLevel = account.UserLevel; 782 m_userLevel = account.UserLevel;
@@ -729,10 +795,7 @@ namespace OpenSim.Region.Framework.Scenes
729 m_reprioritization_timer.AutoReset = false; 795 m_reprioritization_timer.AutoReset = false;
730 796
731 AdjustKnownSeeds(); 797 AdjustKnownSeeds();
732
733 // TODO: I think, this won't send anything, as we are still a child here...
734 Animator.TrySetMovementAnimation("STAND"); 798 Animator.TrySetMovementAnimation("STAND");
735
736 // 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.
737 // Request info about all the (root) agents in this region 800 // Request info about all the (root) agents in this region
738 // 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)
@@ -783,25 +846,47 @@ namespace OpenSim.Region.Framework.Scenes
783 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 846 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
784 Dir_Vectors[4] = Vector3.UnitZ; //UP 847 Dir_Vectors[4] = Vector3.UnitZ; //UP
785 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 848 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
786 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 849 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
787 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 850 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
788 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
789 } 854 }
790 855
791 private Vector3[] GetWalkDirectionVectors() 856 private Vector3[] GetWalkDirectionVectors()
792 { 857 {
793 Vector3[] vector = new Vector3[9]; 858 Vector3[] vector = new Vector3[11];
794 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
795 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
796 vector[2] = Vector3.UnitY; //LEFT 861 vector[2] = Vector3.UnitY; //LEFT
797 vector[3] = -Vector3.UnitY; //RIGHT 862 vector[3] = -Vector3.UnitY; //RIGHT
798 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
799 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
800 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
801 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
802 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
803 return vector; 870 return vector;
804 } 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
805 890
806 #endregion 891 #endregion
807 892
@@ -863,6 +948,62 @@ namespace OpenSim.Region.Framework.Scenes
863 pos.Y = crossedBorder.BorderLine.Z - 1; 948 pos.Y = crossedBorder.BorderLine.Z - 1;
864 } 949 }
865 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
866 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1007 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
867 { 1008 {
868 m_log.WarnFormat( 1009 m_log.WarnFormat(
@@ -991,12 +1132,17 @@ namespace OpenSim.Region.Framework.Scenes
991 { 1132 {
992 if (PhysicsActor != null) 1133 if (PhysicsActor != null)
993 { 1134 {
994 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1135 try
995 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1136 {
996 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1137 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
997 m_physicsActor.UnSubscribeEvents(); 1138 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
998 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1139 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
999 PhysicsActor = null; 1140 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1141 m_physicsActor.UnSubscribeEvents();
1142 PhysicsActor = null;
1143 }
1144 catch
1145 { }
1000 } 1146 }
1001 } 1147 }
1002 1148
@@ -1007,11 +1153,13 @@ namespace OpenSim.Region.Framework.Scenes
1007 public void Teleport(Vector3 pos) 1153 public void Teleport(Vector3 pos)
1008 { 1154 {
1009 bool isFlying = false; 1155 bool isFlying = false;
1156
1010 if (m_physicsActor != null) 1157 if (m_physicsActor != null)
1011 isFlying = m_physicsActor.Flying; 1158 isFlying = m_physicsActor.Flying;
1012 1159
1013 RemoveFromPhysicalScene(); 1160 RemoveFromPhysicalScene();
1014 Velocity = Vector3.Zero; 1161 Velocity = Vector3.Zero;
1162 CheckLandingPoint(ref pos);
1015 AbsolutePosition = pos; 1163 AbsolutePosition = pos;
1016 AddToPhysicalScene(isFlying); 1164 AddToPhysicalScene(isFlying);
1017 if (m_appearance != null) 1165 if (m_appearance != null)
@@ -1021,6 +1169,7 @@ namespace OpenSim.Region.Framework.Scenes
1021 } 1169 }
1022 1170
1023 SendTerseUpdateToAllClients(); 1171 SendTerseUpdateToAllClients();
1172
1024 } 1173 }
1025 1174
1026 public void TeleportWithMomentum(Vector3 pos) 1175 public void TeleportWithMomentum(Vector3 pos)
@@ -1030,6 +1179,7 @@ namespace OpenSim.Region.Framework.Scenes
1030 isFlying = m_physicsActor.Flying; 1179 isFlying = m_physicsActor.Flying;
1031 1180
1032 RemoveFromPhysicalScene(); 1181 RemoveFromPhysicalScene();
1182 CheckLandingPoint(ref pos);
1033 AbsolutePosition = pos; 1183 AbsolutePosition = pos;
1034 AddToPhysicalScene(isFlying); 1184 AddToPhysicalScene(isFlying);
1035 if (m_appearance != null) 1185 if (m_appearance != null)
@@ -1239,6 +1389,7 @@ namespace OpenSim.Region.Framework.Scenes
1239 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1389 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1240 1390
1241 m_pos = m_LastFinitePos; 1391 m_pos = m_LastFinitePos;
1392
1242 if (!m_pos.IsFinite()) 1393 if (!m_pos.IsFinite())
1243 { 1394 {
1244 m_pos.X = 127f; 1395 m_pos.X = 127f;
@@ -1305,7 +1456,6 @@ namespace OpenSim.Region.Framework.Scenes
1305 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1456 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1306 } 1457 }
1307 } 1458 }
1308
1309 lock (scriptedcontrols) 1459 lock (scriptedcontrols)
1310 { 1460 {
1311 if (scriptedcontrols.Count > 0) 1461 if (scriptedcontrols.Count > 0)
@@ -1320,6 +1470,9 @@ namespace OpenSim.Region.Framework.Scenes
1320 1470
1321 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1471 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1322 { 1472 {
1473 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1474 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1475
1323 // TODO: This doesn't prevent the user from walking yet. 1476 // TODO: This doesn't prevent the user from walking yet.
1324 // Setting parent ID would fix this, if we knew what value 1477 // Setting parent ID would fix this, if we knew what value
1325 // to use. Or we could add a m_isSitting variable. 1478 // to use. Or we could add a m_isSitting variable.
@@ -1368,12 +1521,20 @@ namespace OpenSim.Region.Framework.Scenes
1368 if (actor.Flying != oldflying) 1521 if (actor.Flying != oldflying)
1369 update_movementflag = true; 1522 update_movementflag = true;
1370 1523
1524 if (m_animator.m_jumping) // add for jumping
1525 update_movementflag = true;
1526
1371 if (q != m_bodyRot) 1527 if (q != m_bodyRot)
1372 { 1528 {
1373 m_bodyRot = q; 1529 m_bodyRot = q;
1374 update_rotation = true; 1530 update_rotation = true;
1375 } 1531 }
1376 1532
1533 //guilty until proven innocent..
1534 bool Nudging = true;
1535 //Basically, if there is at least one non-nudge control then we don't need
1536 //to worry about stopping the avatar
1537
1377 if (m_parentID == 0) 1538 if (m_parentID == 0)
1378 { 1539 {
1379 bool bAllowUpdateMoveToPosition = false; 1540 bool bAllowUpdateMoveToPosition = false;
@@ -1388,9 +1549,12 @@ namespace OpenSim.Region.Framework.Scenes
1388 else 1549 else
1389 dirVectors = Dir_Vectors; 1550 dirVectors = Dir_Vectors;
1390 1551
1391 // The fact that m_movementflag is a byte needs to be fixed 1552 bool[] isNudge = GetDirectionIsNudge();
1392 // it really should be a uint 1553
1393 uint nudgehack = 250; 1554
1555
1556
1557
1394 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1558 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1395 { 1559 {
1396 if (((uint)flags & (uint)DCF) != 0) 1560 if (((uint)flags & (uint)DCF) != 0)
@@ -1400,40 +1564,28 @@ namespace OpenSim.Region.Framework.Scenes
1400 try 1564 try
1401 { 1565 {
1402 agent_control_v3 += dirVectors[i]; 1566 agent_control_v3 += dirVectors[i];
1403 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1567 if (isNudge[i] == false)
1568 {
1569 Nudging = false;
1570 }
1404 } 1571 }
1405 catch (IndexOutOfRangeException) 1572 catch (IndexOutOfRangeException)
1406 { 1573 {
1407 // Why did I get this? 1574 // Why did I get this?
1408 } 1575 }
1409 1576
1410 if ((m_movementflag & (byte)(uint)DCF) == 0) 1577 if ((m_movementflag & (uint)DCF) == 0)
1411 { 1578 {
1412 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1413 {
1414 m_movementflag |= (byte)nudgehack;
1415 }
1416 m_movementflag += (byte)(uint)DCF; 1579 m_movementflag += (byte)(uint)DCF;
1417 update_movementflag = true; 1580 update_movementflag = true;
1418 } 1581 }
1419 } 1582 }
1420 else 1583 else
1421 { 1584 {
1422 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1585 if ((m_movementflag & (uint)DCF) != 0)
1423 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1424 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1425 ) // This or is for Nudge forward
1426 { 1586 {
1427 m_movementflag -= ((byte)(uint)DCF); 1587 m_movementflag -= (byte)(uint)DCF;
1428
1429 update_movementflag = true; 1588 update_movementflag = true;
1430 /*
1431 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1432 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1433 {
1434 m_log.Debug("Removed Hack flag");
1435 }
1436 */
1437 } 1589 }
1438 else 1590 else
1439 { 1591 {
@@ -1442,7 +1594,6 @@ namespace OpenSim.Region.Framework.Scenes
1442 } 1594 }
1443 i++; 1595 i++;
1444 } 1596 }
1445
1446 //Paupaw:Do Proper PID for Autopilot here 1597 //Paupaw:Do Proper PID for Autopilot here
1447 if (bResetMoveToPosition) 1598 if (bResetMoveToPosition)
1448 { 1599 {
@@ -1477,6 +1628,9 @@ namespace OpenSim.Region.Framework.Scenes
1477 // Ignore z component of vector 1628 // Ignore z component of vector
1478 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1629 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1479 LocalVectorToTarget2D.Normalize(); 1630 LocalVectorToTarget2D.Normalize();
1631
1632 //We're not nudging
1633 Nudging = false;
1480 agent_control_v3 += LocalVectorToTarget2D; 1634 agent_control_v3 += LocalVectorToTarget2D;
1481 1635
1482 // update avatar movement flags. the avatar coordinate system is as follows: 1636 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1567,13 +1721,13 @@ namespace OpenSim.Region.Framework.Scenes
1567 // m_log.DebugFormat( 1721 // m_log.DebugFormat(
1568 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1722 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1569 1723
1570 AddNewMovement(agent_control_v3, q); 1724 AddNewMovement(agent_control_v3, q, Nudging);
1571 1725
1572 1726
1573 } 1727 }
1574 } 1728 }
1575 1729
1576 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1730 if (update_movementflag && !SitGround)
1577 Animator.UpdateMovementAnimations(); 1731 Animator.UpdateMovementAnimations();
1578 1732
1579 m_scene.EventManager.TriggerOnClientMovement(this); 1733 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1588,7 +1742,6 @@ namespace OpenSim.Region.Framework.Scenes
1588 m_sitAtAutoTarget = false; 1742 m_sitAtAutoTarget = false;
1589 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1743 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1590 //proxy.PCode = (byte)PCode.ParticleSystem; 1744 //proxy.PCode = (byte)PCode.ParticleSystem;
1591
1592 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1745 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1593 proxyObjectGroup.AttachToScene(m_scene); 1746 proxyObjectGroup.AttachToScene(m_scene);
1594 1747
@@ -1629,8 +1782,8 @@ namespace OpenSim.Region.Framework.Scenes
1629 return; 1782 return;
1630 } 1783 }
1631 m_moveToPositionInProgress = true; 1784 m_moveToPositionInProgress = true;
1632 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1785 m_moveToPositionTarget = new Vector3(locx, locy, locz + (m_appearance.AvatarHeight / 2.0f));
1633 } 1786 }
1634 catch (Exception ex) 1787 catch (Exception ex)
1635 { 1788 {
1636 //Why did I get this error? 1789 //Why did I get this error?
@@ -1652,7 +1805,7 @@ namespace OpenSim.Region.Framework.Scenes
1652 Velocity = Vector3.Zero; 1805 Velocity = Vector3.Zero;
1653 SendAvatarDataToAllAgents(); 1806 SendAvatarDataToAllAgents();
1654 1807
1655 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1808 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1656 } 1809 }
1657 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1810 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1658 m_requestedSitTargetUUID = UUID.Zero; 1811 m_requestedSitTargetUUID = UUID.Zero;
@@ -1689,25 +1842,22 @@ namespace OpenSim.Region.Framework.Scenes
1689 1842
1690 if (m_parentID != 0) 1843 if (m_parentID != 0)
1691 { 1844 {
1692 m_log.Debug("StandupCode Executed"); 1845 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1693 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1694 if (part != null) 1846 if (part != null)
1695 { 1847 {
1848 part.TaskInventory.LockItemsForRead(true);
1696 TaskInventoryDictionary taskIDict = part.TaskInventory; 1849 TaskInventoryDictionary taskIDict = part.TaskInventory;
1697 if (taskIDict != null) 1850 if (taskIDict != null)
1698 { 1851 {
1699 lock (taskIDict) 1852 foreach (UUID taskID in taskIDict.Keys)
1700 { 1853 {
1701 foreach (UUID taskID in taskIDict.Keys) 1854 UnRegisterControlEventsToScript(LocalId, taskID);
1702 { 1855 taskIDict[taskID].PermsMask &= ~(
1703 UnRegisterControlEventsToScript(LocalId, taskID); 1856 2048 | //PERMISSION_CONTROL_CAMERA
1704 taskIDict[taskID].PermsMask &= ~( 1857 4); // PERMISSION_TAKE_CONTROLS
1705 2048 | //PERMISSION_CONTROL_CAMERA
1706 4); // PERMISSION_TAKE_CONTROLS
1707 }
1708 } 1858 }
1709
1710 } 1859 }
1860 part.TaskInventory.LockItemsForRead(false);
1711 // Reset sit target. 1861 // Reset sit target.
1712 if (part.GetAvatarOnSitTarget() == UUID) 1862 if (part.GetAvatarOnSitTarget() == UUID)
1713 part.SitTargetAvatar = UUID.Zero; 1863 part.SitTargetAvatar = UUID.Zero;
@@ -1716,16 +1866,55 @@ namespace OpenSim.Region.Framework.Scenes
1716 m_parentPosition = part.GetWorldPosition(); 1866 m_parentPosition = part.GetWorldPosition();
1717 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1867 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1718 } 1868 }
1869 // part.GetWorldRotation() is the rotation of the object being sat on
1870 // Rotation is the sittiing Av's rotation
1871
1872 Quaternion partRot;
1873// if (part.LinkNum == 1)
1874// { // Root prim of linkset
1875// partRot = part.ParentGroup.RootPart.RotationOffset;
1876// }
1877// else
1878// { // single or child prim
1879
1880// }
1881 if (part == null) //CW: Part may be gone. llDie() for example.
1882 {
1883 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1884 }
1885 else
1886 {
1887 partRot = part.GetWorldRotation();
1888 }
1889
1890 Quaternion partIRot = Quaternion.Inverse(partRot);
1719 1891
1892 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1893 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1894
1895
1720 if (m_physicsActor == null) 1896 if (m_physicsActor == null)
1721 { 1897 {
1722 AddToPhysicalScene(false); 1898 AddToPhysicalScene(false);
1723 } 1899 }
1724 1900 //CW: If the part isn't null then we can set the current position
1725 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1901 if (part != null)
1726 m_parentPosition = Vector3.Zero; 1902 {
1727 1903 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1728 m_parentID = 0; 1904 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1905 part.IsOccupied = false;
1906 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1907 }
1908 else
1909 {
1910 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1911 AbsolutePosition = m_lastWorldPosition;
1912 }
1913
1914 m_parentPosition = Vector3.Zero;
1915 m_parentID = 0;
1916 m_linkedPrim = UUID.Zero;
1917 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1729 SendAvatarDataToAllAgents(); 1918 SendAvatarDataToAllAgents();
1730 m_requestedSitTargetID = 0; 1919 m_requestedSitTargetID = 0;
1731 if (m_physicsActor != null && m_appearance != null) 1920 if (m_physicsActor != null && m_appearance != null)
@@ -1734,7 +1923,6 @@ namespace OpenSim.Region.Framework.Scenes
1734 SetHeight(m_appearance.AvatarHeight); 1923 SetHeight(m_appearance.AvatarHeight);
1735 } 1924 }
1736 } 1925 }
1737
1738 Animator.TrySetMovementAnimation("STAND"); 1926 Animator.TrySetMovementAnimation("STAND");
1739 } 1927 }
1740 1928
@@ -1765,13 +1953,9 @@ namespace OpenSim.Region.Framework.Scenes
1765 Vector3 avSitOffSet = part.SitTargetPosition; 1953 Vector3 avSitOffSet = part.SitTargetPosition;
1766 Quaternion avSitOrientation = part.SitTargetOrientation; 1954 Quaternion avSitOrientation = part.SitTargetOrientation;
1767 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1955 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1768 1956 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1769 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1957 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1770 bool SitTargetisSet = 1958 if (SitTargetisSet && !SitTargetOccupied)
1771 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1772 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1773
1774 if (SitTargetisSet && SitTargetUnOccupied)
1775 { 1959 {
1776 //switch the target to this prim 1960 //switch the target to this prim
1777 return part; 1961 return part;
@@ -1785,85 +1969,168 @@ namespace OpenSim.Region.Framework.Scenes
1785 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1969 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1786 { 1970 {
1787 bool autopilot = true; 1971 bool autopilot = true;
1972 Vector3 autopilotTarget = new Vector3();
1973 Quaternion sitOrientation = Quaternion.Identity;
1788 Vector3 pos = new Vector3(); 1974 Vector3 pos = new Vector3();
1789 Quaternion sitOrientation = pSitOrientation;
1790 Vector3 cameraEyeOffset = Vector3.Zero; 1975 Vector3 cameraEyeOffset = Vector3.Zero;
1791 Vector3 cameraAtOffset = Vector3.Zero; 1976 Vector3 cameraAtOffset = Vector3.Zero;
1792 bool forceMouselook = false; 1977 bool forceMouselook = false;
1793 1978
1794 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1979 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1795 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1980 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1796 if (part != null) 1981 if (part == null) return;
1797 { 1982
1798 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1983 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1799 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1984 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1800 1985
1801 // Is a sit target available? 1986 // part is the prim to sit on
1802 Vector3 avSitOffSet = part.SitTargetPosition; 1987 // offset is the world-ref vector distance from that prim center to the click-spot
1803 Quaternion avSitOrientation = part.SitTargetOrientation; 1988 // UUID is the UUID of the Avatar doing the clicking
1804 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1989
1805 1990 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1806 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1991
1807 bool SitTargetisSet = 1992 // Is a sit target available?
1808 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1993 Vector3 avSitOffSet = part.SitTargetPosition;
1809 ( 1994 Quaternion avSitOrientation = part.SitTargetOrientation;
1810 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1995
1811 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1996 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1812 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1997 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1813 ) 1998 Quaternion partRot;
1814 )); 1999// if (part.LinkNum == 1)
1815 2000// { // Root prim of linkset
1816 if (SitTargetisSet && SitTargetUnOccupied) 2001// partRot = part.ParentGroup.RootPart.RotationOffset;
1817 { 2002// }
1818 part.SitTargetAvatar = UUID; 2003// else
1819 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 2004// { // single or child prim
1820 sitOrientation = avSitOrientation; 2005 partRot = part.GetWorldRotation();
1821 autopilot = false; 2006// }
1822 } 2007 Quaternion partIRot = Quaternion.Inverse(partRot);
1823 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2008//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1824 2009 // Sit analysis rewritten by KF 091125
1825 pos = part.AbsolutePosition + offset; 2010 if (SitTargetisSet) // scipted sit
1826 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 2011 {
1827 //{ 2012 if (!part.IsOccupied)
1828 // offset = pos; 2013 {
1829 //autopilot = false; 2014//Console.WriteLine("Scripted, unoccupied");
1830 //} 2015 part.SitTargetAvatar = UUID; // set that Av will be on it
1831 if (m_physicsActor != null) 2016 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1832 { 2017
1833 // If we're not using the client autopilot, we're immediately warping the avatar to the location 2018 Quaternion nrot = avSitOrientation;
1834 // We can remove the physicsActor until they stand up. 2019 if (!part.IsRoot)
1835 m_sitAvatarHeight = m_physicsActor.Size.Z;
1836
1837 if (autopilot)
1838 { 2020 {
1839 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2021 nrot = part.RotationOffset * avSitOrientation;
1840 {
1841 autopilot = false;
1842
1843 RemoveFromPhysicalScene();
1844 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1845 }
1846 } 2022 }
1847 else 2023 sitOrientation = nrot; // Change rotatione to the scripted one
2024 OffsetRotation = nrot;
2025 autopilot = false; // Jump direct to scripted llSitPos()
2026 }
2027 else
2028 {
2029//Console.WriteLine("Scripted, occupied");
2030 return;
2031 }
2032 }
2033 else // Not Scripted
2034 {
2035 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
2036 {
2037 // large prim & offset, ignore if other Avs sitting
2038// offset.Z -= 0.05f;
2039 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2040 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2041
2042//Console.WriteLine(" offset ={0}", offset);
2043//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2044//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2045
2046 }
2047 else // small offset
2048 {
2049//Console.WriteLine("Small offset");
2050 if (!part.IsOccupied)
2051 {
2052 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2053 autopilotTarget = part.AbsolutePosition;
2054//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2055 }
2056 else return; // occupied small
2057 } // end large/small
2058 } // end Scripted/not
2059
2060 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2061
2062 cameraAtOffset = part.GetCameraAtOffset();
2063 cameraEyeOffset = part.GetCameraEyeOffset();
2064 forceMouselook = part.GetForceMouselook();
2065 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2066 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2067
2068 if (m_physicsActor != null)
2069 {
2070 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2071 // We can remove the physicsActor until they stand up.
2072 m_sitAvatarHeight = m_physicsActor.Size.Z;
2073 if (autopilot)
2074 { // its not a scripted sit
2075// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2076 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1848 { 2077 {
2078 autopilot = false; // close enough
2079 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2080 Not using the part's position because returning the AV to the last known standing
2081 position is likely to be more friendly, isn't it? */
1849 RemoveFromPhysicalScene(); 2082 RemoveFromPhysicalScene();
1850 } 2083 Velocity = Vector3.Zero;
2084 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2085 } // else the autopilot will get us close
2086 }
2087 else
2088 { // its a scripted sit
2089 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2090 I *am* using the part's position this time because we have no real idea how far away
2091 the avatar is from the sit target. */
2092 RemoveFromPhysicalScene();
2093 Velocity = Vector3.Zero;
1851 } 2094 }
1852
1853 cameraAtOffset = part.GetCameraAtOffset();
1854 cameraEyeOffset = part.GetCameraEyeOffset();
1855 forceMouselook = part.GetForceMouselook();
1856 } 2095 }
1857 2096 else return; // physactor is null!
1858 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2097
1859 m_requestedSitTargetUUID = targetID; 2098 Vector3 offsetr; // = offset * partIRot;
2099 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2100 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2101 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2102 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2103 //offsetr = offset * partIRot;
2104//
2105 // }
2106 // else
2107 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2108 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2109 // (offset * partRot);
2110 // }
2111
2112//Console.WriteLine(" ");
2113//Console.WriteLine("link number ={0}", part.LinkNum);
2114//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2115//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2116//Console.WriteLine("Click offst ={0}", offset);
2117//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2118//Console.WriteLine("offsetr ={0}", offsetr);
2119//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2120//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2121
2122 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2123 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2124
2125 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1860 // This calls HandleAgentSit twice, once from here, and the client calls 2126 // This calls HandleAgentSit twice, once from here, and the client calls
1861 // HandleAgentSit itself after it gets to the location 2127 // HandleAgentSit itself after it gets to the location
1862 // It doesn't get to the location until we've moved them there though 2128 // It doesn't get to the location until we've moved them there though
1863 // which happens in HandleAgentSit :P 2129 // which happens in HandleAgentSit :P
1864 m_autopilotMoving = autopilot; 2130 m_autopilotMoving = autopilot;
1865 m_autoPilotTarget = pos; 2131 m_autoPilotTarget = autopilotTarget;
1866 m_sitAtAutoTarget = autopilot; 2132 m_sitAtAutoTarget = autopilot;
2133 m_initialSitTarget = autopilotTarget;
1867 if (!autopilot) 2134 if (!autopilot)
1868 HandleAgentSit(remoteClient, UUID); 2135 HandleAgentSit(remoteClient, UUID);
1869 } 2136 }
@@ -2158,47 +2425,130 @@ namespace OpenSim.Region.Framework.Scenes
2158 { 2425 {
2159 if (part != null) 2426 if (part != null)
2160 { 2427 {
2428//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2161 if (part.GetAvatarOnSitTarget() == UUID) 2429 if (part.GetAvatarOnSitTarget() == UUID)
2162 { 2430 {
2431//Console.WriteLine("Scripted Sit");
2432 // Scripted sit
2163 Vector3 sitTargetPos = part.SitTargetPosition; 2433 Vector3 sitTargetPos = part.SitTargetPosition;
2164 Quaternion sitTargetOrient = part.SitTargetOrientation; 2434 Quaternion sitTargetOrient = part.SitTargetOrientation;
2165
2166 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2167 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2168
2169 //Quaternion result = (sitTargetOrient * vq) * nq;
2170
2171 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2435 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2172 m_pos += SIT_TARGET_ADJUSTMENT; 2436 m_pos += SIT_TARGET_ADJUSTMENT;
2437 if (!part.IsRoot)
2438 {
2439 m_pos *= part.RotationOffset;
2440 }
2173 m_bodyRot = sitTargetOrient; 2441 m_bodyRot = sitTargetOrient;
2174 //Rotation = sitTargetOrient;
2175 m_parentPosition = part.AbsolutePosition; 2442 m_parentPosition = part.AbsolutePosition;
2176 2443 part.IsOccupied = true;
2177 //SendTerseUpdateToAllClients(); 2444 part.ParentGroup.AddAvatar(agentID);
2178 } 2445 }
2179 else 2446 else
2180 { 2447 {
2181 m_pos -= part.AbsolutePosition; 2448 // if m_avUnscriptedSitPos is zero then Av sits above center
2449 // Else Av sits at m_avUnscriptedSitPos
2450
2451 // Non-scripted sit by Kitto Flora 21Nov09
2452 // Calculate angle of line from prim to Av
2453 Quaternion partIRot;
2454// if (part.LinkNum == 1)
2455// { // Root prim of linkset
2456// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2457// }
2458// else
2459// { // single or child prim
2460 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2461// }
2462 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2463 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2464 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2465 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2466 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2467 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2468 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2469 // Av sits at world euler <0,0, z>, translated by part rotation
2470 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2471
2182 m_parentPosition = part.AbsolutePosition; 2472 m_parentPosition = part.AbsolutePosition;
2183 } 2473 part.IsOccupied = true;
2474 part.ParentGroup.AddAvatar(agentID);
2475 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2476 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2477 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2478 m_avUnscriptedSitPos; // adds click offset, if any
2479 //Set up raytrace to find top surface of prim
2480 Vector3 size = part.Scale;
2481 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2482 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2483 Vector3 down = new Vector3(0f, 0f, -1f);
2484//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2485 m_scene.PhysicsScene.RaycastWorld(
2486 start, // Vector3 position,
2487 down, // Vector3 direction,
2488 mag, // float length,
2489 SitAltitudeCallback); // retMethod
2490 } // end scripted/not
2184 } 2491 }
2185 else 2492 else // no Av
2186 { 2493 {
2187 return; 2494 return;
2188 } 2495 }
2189 } 2496 }
2190 m_parentID = m_requestedSitTargetID;
2191 2497
2498 //We want our offsets to reference the root prim, not the child we may have sat on
2499 if (!part.IsRoot)
2500 {
2501 m_parentID = part.ParentGroup.RootPart.LocalId;
2502 m_pos += part.OffsetPosition;
2503 }
2504 else
2505 {
2506 m_parentID = m_requestedSitTargetID;
2507 }
2508
2509 m_linkedPrim = part.UUID;
2510 if (part.GetAvatarOnSitTarget() != UUID)
2511 {
2512 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2513 }
2192 Velocity = Vector3.Zero; 2514 Velocity = Vector3.Zero;
2193 RemoveFromPhysicalScene(); 2515 RemoveFromPhysicalScene();
2194
2195 Animator.TrySetMovementAnimation(sitAnimation); 2516 Animator.TrySetMovementAnimation(sitAnimation);
2196 SendAvatarDataToAllAgents(); 2517 SendAvatarDataToAllAgents();
2197 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2198 // So we're also sending a terse update (which has avatar rotation)
2199 // [Update] We do now.
2200 //SendTerseUpdateToAllClients(); 2518 //SendTerseUpdateToAllClients();
2201 } 2519 }
2520
2521 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2522 {
2523 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2524 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2525 if(hitYN)
2526 {
2527 // m_pos = Av offset from prim center to make look like on center
2528 // m_parentPosition = Actual center pos of prim
2529 // collisionPoint = spot on prim where we want to sit
2530 // collisionPoint.Z = global sit surface height
2531 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2532 Quaternion partIRot;
2533// if (part.LinkNum == 1)
2534/// { // Root prim of linkset
2535// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2536// }
2537// else
2538// { // single or child prim
2539 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2540// }
2541 if (m_initialSitTarget != null)
2542 {
2543 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2544 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2545 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2546 m_pos += offset;
2547 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2548 }
2549
2550 }
2551 } // End SitAltitudeCallback KF.
2202 2552
2203 /// <summary> 2553 /// <summary>
2204 /// Event handler for the 'Always run' setting on the client 2554 /// Event handler for the 'Always run' setting on the client
@@ -2228,12 +2578,13 @@ namespace OpenSim.Region.Framework.Scenes
2228 /// </summary> 2578 /// </summary>
2229 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2579 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2230 /// <param name="rotation">The direction in which this avatar should now face. 2580 /// <param name="rotation">The direction in which this avatar should now face.
2231 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2581 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2232 { 2582 {
2233 if (m_isChildAgent) 2583 if (m_isChildAgent)
2234 { 2584 {
2235 // WHAT??? 2585 // WHAT???
2236 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); 2586 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent");
2587
2237 return; 2588 return;
2238 } 2589 }
2239 2590
@@ -2242,15 +2593,26 @@ namespace OpenSim.Region.Framework.Scenes
2242 Rotation = rotation; 2593 Rotation = rotation;
2243 Vector3 direc = vec * rotation; 2594 Vector3 direc = vec * rotation;
2244 direc.Normalize(); 2595 direc.Normalize();
2596 PhysicsActor actor = m_physicsActor;
2597
2598 if (actor.Flying != m_flyingOld) // add for fly velocity control
2599 {
2600 m_flyingOld = actor.Flying; // add for fly velocity control
2601 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2602 }
2603
2604 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2605
2606 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2245 2607
2246 direc *= 0.03f * 128f * m_speedModifier; 2608 direc *= 0.03f * 128f * m_speedModifier;
2247 2609
2248 PhysicsActor actor = m_physicsActor;
2249 if (actor != null) 2610 if (actor != null)
2250 { 2611 {
2251 if (actor.Flying) 2612 if (actor.Flying)
2252 { 2613 {
2253 direc *= 4.0f; 2614// rm speed mod direc *= 4.0f;
2615 direc *= 5.2f; // for speed mod
2254 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2616 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2255 //bool colliding = (m_physicsActor.IsColliding==true); 2617 //bool colliding = (m_physicsActor.IsColliding==true);
2256 //if (controlland) 2618 //if (controlland)
@@ -2263,22 +2625,34 @@ namespace OpenSim.Region.Framework.Scenes
2263 // m_log.Info("[AGENT]: Stop FLying"); 2625 // m_log.Info("[AGENT]: Stop FLying");
2264 //} 2626 //}
2265 } 2627 }
2628 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2629 {
2630 direc *= 0.0f;
2631 }
2632 /* This jumping section removed to SPA
2266 else if (!actor.Flying && actor.IsColliding) 2633 else if (!actor.Flying && actor.IsColliding)
2267 { 2634 {
2268 if (direc.Z > 2.0f) 2635 if (direc.Z > 2.0f)
2269 { 2636 {
2270 direc.Z *= 3.0f; 2637 if(m_animator.m_animTickJump == -1)
2271 2638 {
2272 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2639 direc.Z *= 3.0f; // jump
2273 Animator.TrySetMovementAnimation("PREJUMP"); 2640 }
2274 Animator.TrySetMovementAnimation("JUMP"); 2641 else
2642 {
2643 direc.Z *= 0.1f; // prejump
2644 }
2645 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2646 Animator.TrySetMovementAnimation("PREJUMP");
2647 Animator.TrySetMovementAnimation("JUMP");
2648 * /
2275 } 2649 }
2276 } 2650 } */
2277 } 2651 }
2278 2652
2279 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2653 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2280 m_forceToApply = direc; 2654 m_forceToApply = direc;
2281 2655 m_isNudging = Nudging;
2282 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2656 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2283 } 2657 }
2284 2658
@@ -2327,6 +2701,9 @@ namespace OpenSim.Region.Framework.Scenes
2327 2701
2328 CheckForSignificantMovement(); // sends update to the modules. 2702 CheckForSignificantMovement(); // sends update to the modules.
2329 } 2703 }
2704
2705 //Sending prim updates AFTER the avatar terse updates are sent
2706 SendPrimUpdates();
2330 } 2707 }
2331 2708
2332 #endregion 2709 #endregion
@@ -3113,6 +3490,7 @@ namespace OpenSim.Region.Framework.Scenes
3113 m_callbackURI = cAgent.CallbackURI; 3490 m_callbackURI = cAgent.CallbackURI;
3114 3491
3115 m_pos = cAgent.Position; 3492 m_pos = cAgent.Position;
3493
3116 m_velocity = cAgent.Velocity; 3494 m_velocity = cAgent.Velocity;
3117 m_CameraCenter = cAgent.Center; 3495 m_CameraCenter = cAgent.Center;
3118 m_CameraAtAxis = cAgent.AtAxis; 3496 m_CameraAtAxis = cAgent.AtAxis;
@@ -3231,20 +3609,45 @@ namespace OpenSim.Region.Framework.Scenes
3231 /// </summary> 3609 /// </summary>
3232 public override void UpdateMovement() 3610 public override void UpdateMovement()
3233 { 3611 {
3234 if (m_forceToApply.HasValue) 3612 if (Animator!=null) // add for jumping
3235 { 3613 { // add for jumping
3236 Vector3 force = m_forceToApply.Value; 3614 // if (!m_animator.m_jumping) // add for jumping
3237 3615 // { // add for jumping
3238 m_updateflag = true;
3239 3616
3240 // The magic constant 0.95f seems to make walking feel less jerky, 3617 if (m_forceToApply.HasValue) // this section realigned
3241 // probably because it hackishly accounts for the overall latency of 3618 {
3242 // these Velocity updates -- Diva
3243 Velocity = force * .95F;
3244 3619
3245 m_forceToApply = null; 3620 Vector3 force = m_forceToApply.Value;
3246 } 3621 m_updateflag = true;
3247 } 3622if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3623 Velocity = force;
3624//Console.WriteLine("UM1 {0}", Velocity);
3625 m_forceToApply = null;
3626 }
3627 else
3628 {
3629 if (m_isNudging)
3630 {
3631 Vector3 force = Vector3.Zero;
3632
3633 m_updateflag = true;
3634if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3635 Velocity = force;
3636//Console.WriteLine("UM2 {0}", Velocity);
3637 m_isNudging = false;
3638 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3639 }
3640 else // add for jumping
3641 { // add for jumping
3642 Vector3 force = Vector3.Zero; // add for jumping
3643if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3644//Console.WriteLine("UM3 {0}", Velocity);
3645 Velocity = force; // add for jumping
3646 }
3647 }
3648 // } // end realign
3649 } // add for jumping
3650 } // add for jumping
3248 3651
3249 /// <summary> 3652 /// <summary>
3250 /// Adds a physical representation of the avatar to the Physics plugin 3653 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3258,10 +3661,8 @@ namespace OpenSim.Region.Framework.Scenes
3258 3661
3259 Vector3 pVec = AbsolutePosition; 3662 Vector3 pVec = AbsolutePosition;
3260 3663
3261 // Old bug where the height was in centimeters instead of meters
3262 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3664 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3263 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3665 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3264
3265 scene.AddPhysicsActorTaint(m_physicsActor); 3666 scene.AddPhysicsActorTaint(m_physicsActor);
3266 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3667 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3267 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3668 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3285,18 +3686,29 @@ namespace OpenSim.Region.Framework.Scenes
3285 { 3686 {
3286 if (e == null) 3687 if (e == null)
3287 return; 3688 return;
3288 3689
3289 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3690 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3290 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3291 // as of this comment the interval is set in AddToPhysicalScene 3691 // as of this comment the interval is set in AddToPhysicalScene
3292 if (Animator!=null) 3692 if (Animator!=null)
3293 Animator.UpdateMovementAnimations(); 3693 {
3694 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3695 { // else its will lock out other animation changes, like ground sit.
3696 Animator.UpdateMovementAnimations();
3697 m_updateCount--;
3698 }
3699 }
3294 3700
3295 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3701 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3296 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3702 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3297 3703
3298 CollisionPlane = Vector4.UnitW; 3704 CollisionPlane = Vector4.UnitW;
3299 3705
3706 if (m_lastColCount != coldata.Count)
3707 {
3708 m_updateCount = UPDATE_COUNT;
3709 m_lastColCount = coldata.Count;
3710 }
3711
3300 if (coldata.Count != 0 && Animator != null) 3712 if (coldata.Count != 0 && Animator != null)
3301 { 3713 {
3302 switch (Animator.CurrentMovementAnimation) 3714 switch (Animator.CurrentMovementAnimation)
@@ -3326,6 +3738,148 @@ namespace OpenSim.Region.Framework.Scenes
3326 } 3738 }
3327 } 3739 }
3328 3740
3741 List<uint> thisHitColliders = new List<uint>();
3742 List<uint> endedColliders = new List<uint>();
3743 List<uint> startedColliders = new List<uint>();
3744
3745 foreach (uint localid in coldata.Keys)
3746 {
3747 thisHitColliders.Add(localid);
3748 if (!m_lastColliders.Contains(localid))
3749 {
3750 startedColliders.Add(localid);
3751 }
3752 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3753 }
3754
3755 // calculate things that ended colliding
3756 foreach (uint localID in m_lastColliders)
3757 {
3758 if (!thisHitColliders.Contains(localID))
3759 {
3760 endedColliders.Add(localID);
3761 }
3762 }
3763 //add the items that started colliding this time to the last colliders list.
3764 foreach (uint localID in startedColliders)
3765 {
3766 m_lastColliders.Add(localID);
3767 }
3768 // remove things that ended colliding from the last colliders list
3769 foreach (uint localID in endedColliders)
3770 {
3771 m_lastColliders.Remove(localID);
3772 }
3773
3774 // do event notification
3775 if (startedColliders.Count > 0)
3776 {
3777 ColliderArgs StartCollidingMessage = new ColliderArgs();
3778 List<DetectedObject> colliding = new List<DetectedObject>();
3779 foreach (uint localId in startedColliders)
3780 {
3781 if (localId == 0)
3782 continue;
3783
3784 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3785 string data = "";
3786 if (obj != null)
3787 {
3788 DetectedObject detobj = new DetectedObject();
3789 detobj.keyUUID = obj.UUID;
3790 detobj.nameStr = obj.Name;
3791 detobj.ownerUUID = obj.OwnerID;
3792 detobj.posVector = obj.AbsolutePosition;
3793 detobj.rotQuat = obj.GetWorldRotation();
3794 detobj.velVector = obj.Velocity;
3795 detobj.colliderType = 0;
3796 detobj.groupUUID = obj.GroupID;
3797 colliding.Add(detobj);
3798 }
3799 }
3800
3801 if (colliding.Count > 0)
3802 {
3803 StartCollidingMessage.Colliders = colliding;
3804
3805 foreach (SceneObjectGroup att in Attachments)
3806 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3807 }
3808 }
3809
3810 if (endedColliders.Count > 0)
3811 {
3812 ColliderArgs EndCollidingMessage = new ColliderArgs();
3813 List<DetectedObject> colliding = new List<DetectedObject>();
3814 foreach (uint localId in endedColliders)
3815 {
3816 if (localId == 0)
3817 continue;
3818
3819 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3820 string data = "";
3821 if (obj != null)
3822 {
3823 DetectedObject detobj = new DetectedObject();
3824 detobj.keyUUID = obj.UUID;
3825 detobj.nameStr = obj.Name;
3826 detobj.ownerUUID = obj.OwnerID;
3827 detobj.posVector = obj.AbsolutePosition;
3828 detobj.rotQuat = obj.GetWorldRotation();
3829 detobj.velVector = obj.Velocity;
3830 detobj.colliderType = 0;
3831 detobj.groupUUID = obj.GroupID;
3832 colliding.Add(detobj);
3833 }
3834 }
3835
3836 if (colliding.Count > 0)
3837 {
3838 EndCollidingMessage.Colliders = colliding;
3839
3840 foreach (SceneObjectGroup att in Attachments)
3841 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3842 }
3843 }
3844
3845 if (thisHitColliders.Count > 0)
3846 {
3847 ColliderArgs CollidingMessage = new ColliderArgs();
3848 List<DetectedObject> colliding = new List<DetectedObject>();
3849 foreach (uint localId in thisHitColliders)
3850 {
3851 if (localId == 0)
3852 continue;
3853
3854 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3855 string data = "";
3856 if (obj != null)
3857 {
3858 DetectedObject detobj = new DetectedObject();
3859 detobj.keyUUID = obj.UUID;
3860 detobj.nameStr = obj.Name;
3861 detobj.ownerUUID = obj.OwnerID;
3862 detobj.posVector = obj.AbsolutePosition;
3863 detobj.rotQuat = obj.GetWorldRotation();
3864 detobj.velVector = obj.Velocity;
3865 detobj.colliderType = 0;
3866 detobj.groupUUID = obj.GroupID;
3867 colliding.Add(detobj);
3868 }
3869 }
3870
3871 if (colliding.Count > 0)
3872 {
3873 CollidingMessage.Colliders = colliding;
3874
3875 lock (m_attachments)
3876 {
3877 foreach (SceneObjectGroup att in m_attachments)
3878 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3879 }
3880 }
3881 }
3882
3329 if (m_invulnerable) 3883 if (m_invulnerable)
3330 return; 3884 return;
3331 3885
@@ -3751,6 +4305,39 @@ namespace OpenSim.Region.Framework.Scenes
3751 return; 4305 return;
3752 } 4306 }
3753 4307
4308 XmlDocument doc = new XmlDocument();
4309 string stateData = String.Empty;
4310
4311 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4312 if (attServ != null)
4313 {
4314 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4315 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4316 if (stateData != String.Empty)
4317 {
4318 try
4319 {
4320 doc.LoadXml(stateData);
4321 }
4322 catch { }
4323 }
4324 }
4325
4326 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4327
4328 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4329 if (nodes.Count > 0)
4330 {
4331 foreach (XmlNode n in nodes)
4332 {
4333 XmlElement elem = (XmlElement)n;
4334 string itemID = elem.GetAttribute("ItemID");
4335 string xml = elem.InnerXml;
4336
4337 itemData[new UUID(itemID)] = xml;
4338 }
4339 }
4340
3754 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4341 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3755 foreach (AvatarAttachment attach in attachments) 4342 foreach (AvatarAttachment attach in attachments)
3756 { 4343 {
@@ -3771,7 +4358,30 @@ namespace OpenSim.Region.Framework.Scenes
3771 4358
3772 try 4359 try
3773 { 4360 {
3774 m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4361 string xmlData;
4362 XmlDocument d = new XmlDocument();
4363 UUID asset;
4364 if (itemData.TryGetValue(itemID, out xmlData))
4365 {
4366 d.LoadXml(xmlData);
4367 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4368
4369 // Rez from inventory
4370 asset
4371 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4372
4373 }
4374 else
4375 {
4376 // Rez from inventory (with a null doc to let
4377 // CHANGED_OWNER happen)
4378 asset
4379 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4380 }
4381
4382 m_log.InfoFormat(
4383 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4384 p, itemID, asset);
3775 } 4385 }
3776 catch (Exception e) 4386 catch (Exception e)
3777 { 4387 {
@@ -3804,6 +4414,15 @@ namespace OpenSim.Region.Framework.Scenes
3804 m_reprioritization_called = false; 4414 m_reprioritization_called = false;
3805 } 4415 }
3806 } 4416 }
4417
4418 private Vector3 Quat2Euler(Quaternion rot){
4419 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4420 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4421 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4422 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4423 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4424 return(new Vector3(x,y,z));
4425 }
3807 4426
3808 public void SaveChangedAttachments() 4427 public void SaveChangedAttachments()
3809 { 4428 {
@@ -3827,5 +4446,30 @@ namespace OpenSim.Region.Framework.Scenes
3827 } 4446 }
3828 } 4447 }
3829 } 4448 }
4449
4450 private void CheckLandingPoint(ref Vector3 pos)
4451 {
4452 // Never constrain lures
4453 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4454 return;
4455
4456 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4457 return;
4458
4459 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4460
4461 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4462 land.LandData.UserLocation != Vector3.Zero &&
4463 land.LandData.OwnerID != m_uuid &&
4464 (!m_scene.Permissions.IsGod(m_uuid)) &&
4465 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4466 {
4467 float curr = Vector3.Distance(AbsolutePosition, pos);
4468 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4469 pos = land.LandData.UserLocation;
4470 else
4471 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4472 }
4473 }
3830 } 4474 }
3831} 4475}