aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs1071
1 files changed, 881 insertions, 190 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index f6295b1..af6f89c 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;
@@ -253,7 +274,9 @@ namespace OpenSim.Region.Framework.Scenes
253 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 274 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
254 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 275 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
255 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 276 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
256 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 277 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
278 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
279 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
257 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 280 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
258 } 281 }
259 282
@@ -460,7 +483,8 @@ namespace OpenSim.Region.Framework.Scenes
460 get 483 get
461 { 484 {
462 PhysicsActor actor = m_physicsActor; 485 PhysicsActor actor = m_physicsActor;
463 if (actor != null) 486// if (actor != null)
487 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
464 m_pos = actor.Position; 488 m_pos = actor.Position;
465 else 489 else
466 { 490 {
@@ -482,7 +506,7 @@ namespace OpenSim.Region.Framework.Scenes
482 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 506 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
483 if (part != null) 507 if (part != null)
484 { 508 {
485 return m_parentPosition + (m_pos * part.GetWorldRotation()); 509 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
486 } 510 }
487 else 511 else
488 { 512 {
@@ -509,7 +533,8 @@ namespace OpenSim.Region.Framework.Scenes
509 } 533 }
510 } 534 }
511 535
512 m_pos = value; 536 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
537 m_pos = value;
513 m_parentPosition = Vector3.Zero; 538 m_parentPosition = Vector3.Zero;
514 } 539 }
515 } 540 }
@@ -553,10 +578,39 @@ namespace OpenSim.Region.Framework.Scenes
553 } 578 }
554 } 579 }
555 580
581 public Quaternion OffsetRotation
582 {
583 get { return m_offsetRotation; }
584 set { m_offsetRotation = value; }
585 }
586
556 public Quaternion Rotation 587 public Quaternion Rotation
557 { 588 {
558 get { return m_bodyRot; } 589 get {
559 set { m_bodyRot = value; } 590 if (m_parentID != 0)
591 {
592 if (m_offsetRotation != null)
593 {
594 return m_offsetRotation;
595 }
596 else
597 {
598 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
599 }
600
601 }
602 else
603 {
604 return m_bodyRot;
605 }
606 }
607 set {
608 m_bodyRot = value;
609 if (m_parentID != 0)
610 {
611 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
612 }
613 }
560 } 614 }
561 615
562 public Quaternion PreviousRotation 616 public Quaternion PreviousRotation
@@ -581,11 +635,21 @@ namespace OpenSim.Region.Framework.Scenes
581 635
582 private uint m_parentID; 636 private uint m_parentID;
583 637
638
639 private UUID m_linkedPrim;
640
584 public uint ParentID 641 public uint ParentID
585 { 642 {
586 get { return m_parentID; } 643 get { return m_parentID; }
587 set { m_parentID = value; } 644 set { m_parentID = value; }
588 } 645 }
646
647 public UUID LinkedPrim
648 {
649 get { return m_linkedPrim; }
650 set { m_linkedPrim = value; }
651 }
652
589 public float Health 653 public float Health
590 { 654 {
591 get { return m_health; } 655 get { return m_health; }
@@ -707,7 +771,7 @@ namespace OpenSim.Region.Framework.Scenes
707 CreateSceneViewer(); 771 CreateSceneViewer();
708 m_animator = new ScenePresenceAnimator(this); 772 m_animator = new ScenePresenceAnimator(this);
709 } 773 }
710 774
711 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 775 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
712 { 776 {
713 m_DrawDistance = world.DefaultDrawDistance; 777 m_DrawDistance = world.DefaultDrawDistance;
@@ -722,6 +786,7 @@ namespace OpenSim.Region.Framework.Scenes
722 m_localId = m_scene.AllocateLocalId(); 786 m_localId = m_scene.AllocateLocalId();
723 787
724 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 788 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
789 m_userFlags = account.UserFlags;
725 790
726 if (account != null) 791 if (account != null)
727 m_userLevel = account.UserLevel; 792 m_userLevel = account.UserLevel;
@@ -740,10 +805,7 @@ namespace OpenSim.Region.Framework.Scenes
740 m_reprioritization_timer.AutoReset = false; 805 m_reprioritization_timer.AutoReset = false;
741 806
742 AdjustKnownSeeds(); 807 AdjustKnownSeeds();
743
744 // TODO: I think, this won't send anything, as we are still a child here...
745 Animator.TrySetMovementAnimation("STAND"); 808 Animator.TrySetMovementAnimation("STAND");
746
747 // we created a new ScenePresence (a new child agent) in a fresh region. 809 // we created a new ScenePresence (a new child agent) in a fresh region.
748 // Request info about all the (root) agents in this region 810 // Request info about all the (root) agents in this region
749 // Note: This won't send data *to* other clients in that region (children don't send) 811 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -794,25 +856,47 @@ namespace OpenSim.Region.Framework.Scenes
794 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 856 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
795 Dir_Vectors[4] = Vector3.UnitZ; //UP 857 Dir_Vectors[4] = Vector3.UnitZ; //UP
796 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 858 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
797 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 859 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
798 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 860 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
799 Dir_Vectors[7] = -Vector3.UnitX; //BACK 861 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
862 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
863 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
800 } 864 }
801 865
802 private Vector3[] GetWalkDirectionVectors() 866 private Vector3[] GetWalkDirectionVectors()
803 { 867 {
804 Vector3[] vector = new Vector3[9]; 868 Vector3[] vector = new Vector3[11];
805 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 869 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
806 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 870 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
807 vector[2] = Vector3.UnitY; //LEFT 871 vector[2] = Vector3.UnitY; //LEFT
808 vector[3] = -Vector3.UnitY; //RIGHT 872 vector[3] = -Vector3.UnitY; //RIGHT
809 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 873 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
810 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 874 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
811 vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 875 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
812 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge 876 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
813 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge 877 vector[8] = Vector3.UnitY; //LEFT_NUDGE
878 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
879 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
814 return vector; 880 return vector;
815 } 881 }
882
883 private bool[] GetDirectionIsNudge()
884 {
885 bool[] isNudge = new bool[11];
886 isNudge[0] = false; //FORWARD
887 isNudge[1] = false; //BACK
888 isNudge[2] = false; //LEFT
889 isNudge[3] = false; //RIGHT
890 isNudge[4] = false; //UP
891 isNudge[5] = false; //DOWN
892 isNudge[6] = true; //FORWARD_NUDGE
893 isNudge[7] = true; //BACK_NUDGE
894 isNudge[8] = true; //LEFT_NUDGE
895 isNudge[9] = true; //RIGHT_NUDGE
896 isNudge[10] = true; //DOWN_Nudge
897 return isNudge;
898 }
899
816 900
817 #endregion 901 #endregion
818 902
@@ -877,6 +961,62 @@ namespace OpenSim.Region.Framework.Scenes
877 pos.Y = crossedBorder.BorderLine.Z - 1; 961 pos.Y = crossedBorder.BorderLine.Z - 1;
878 } 962 }
879 963
964 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
965 if (land != null)
966 {
967 // If we come in via login, landmark or map, we want to
968 // honor landing points. If we come in via Lure, we want
969 // to ignore them.
970 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
971 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
972 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
973 {
974 // Don't restrict gods, estate managers, or land owners to
975 // the TP point. This behaviour mimics agni.
976 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
977 land.LandData.UserLocation != Vector3.Zero &&
978 GodLevel < 200 &&
979 ((land.LandData.OwnerID != m_uuid &&
980 (!m_scene.Permissions.IsGod(m_uuid)) &&
981 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
982 {
983 pos = land.LandData.UserLocation;
984 }
985 }
986
987 land.SendLandUpdateToClient(ControllingClient);
988 }
989
990 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
991 {
992 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
993
994 if (pos.X < 0)
995 {
996 emergencyPos.X = (int)Constants.RegionSize + pos.X;
997 if (!(pos.Y < 0))
998 emergencyPos.Y = pos.Y;
999 if (!(pos.Z < 0))
1000 emergencyPos.Z = pos.Z;
1001 }
1002 if (pos.Y < 0)
1003 {
1004 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
1005 if (!(pos.X < 0))
1006 emergencyPos.X = pos.X;
1007 if (!(pos.Z < 0))
1008 emergencyPos.Z = pos.Z;
1009 }
1010 if (pos.Z < 0)
1011 {
1012 emergencyPos.Z = 128;
1013 if (!(pos.Y < 0))
1014 emergencyPos.Y = pos.Y;
1015 if (!(pos.X < 0))
1016 emergencyPos.X = pos.X;
1017 }
1018 }
1019
880 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1020 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
881 { 1021 {
882 m_log.WarnFormat( 1022 m_log.WarnFormat(
@@ -1022,16 +1162,21 @@ namespace OpenSim.Region.Framework.Scenes
1022 /// <summary> 1162 /// <summary>
1023 /// Removes physics plugin scene representation of this agent if it exists. 1163 /// Removes physics plugin scene representation of this agent if it exists.
1024 /// </summary> 1164 /// </summary>
1025 private void RemoveFromPhysicalScene() 1165 public void RemoveFromPhysicalScene()
1026 { 1166 {
1027 if (PhysicsActor != null) 1167 if (PhysicsActor != null)
1028 { 1168 {
1029 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1169 try
1030 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1170 {
1031 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1171 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1032 m_physicsActor.UnSubscribeEvents(); 1172 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1033 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1173 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1034 PhysicsActor = null; 1174 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1175 m_physicsActor.UnSubscribeEvents();
1176 PhysicsActor = null;
1177 }
1178 catch
1179 { }
1035 } 1180 }
1036 } 1181 }
1037 1182
@@ -1042,11 +1187,13 @@ namespace OpenSim.Region.Framework.Scenes
1042 public void Teleport(Vector3 pos) 1187 public void Teleport(Vector3 pos)
1043 { 1188 {
1044 bool isFlying = false; 1189 bool isFlying = false;
1190
1045 if (m_physicsActor != null) 1191 if (m_physicsActor != null)
1046 isFlying = m_physicsActor.Flying; 1192 isFlying = m_physicsActor.Flying;
1047 1193
1048 RemoveFromPhysicalScene(); 1194 RemoveFromPhysicalScene();
1049 Velocity = Vector3.Zero; 1195 Velocity = Vector3.Zero;
1196 CheckLandingPoint(ref pos);
1050 AbsolutePosition = pos; 1197 AbsolutePosition = pos;
1051 AddToPhysicalScene(isFlying); 1198 AddToPhysicalScene(isFlying);
1052 if (m_appearance != null) 1199 if (m_appearance != null)
@@ -1056,6 +1203,7 @@ namespace OpenSim.Region.Framework.Scenes
1056 } 1203 }
1057 1204
1058 SendTerseUpdateToAllClients(); 1205 SendTerseUpdateToAllClients();
1206
1059 } 1207 }
1060 1208
1061 public void TeleportWithMomentum(Vector3 pos) 1209 public void TeleportWithMomentum(Vector3 pos)
@@ -1065,6 +1213,7 @@ namespace OpenSim.Region.Framework.Scenes
1065 isFlying = m_physicsActor.Flying; 1213 isFlying = m_physicsActor.Flying;
1066 1214
1067 RemoveFromPhysicalScene(); 1215 RemoveFromPhysicalScene();
1216 CheckLandingPoint(ref pos);
1068 AbsolutePosition = pos; 1217 AbsolutePosition = pos;
1069 AddToPhysicalScene(isFlying); 1218 AddToPhysicalScene(isFlying);
1070 if (m_appearance != null) 1219 if (m_appearance != null)
@@ -1275,6 +1424,7 @@ namespace OpenSim.Region.Framework.Scenes
1275 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1424 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1276 1425
1277 m_pos = m_LastFinitePos; 1426 m_pos = m_LastFinitePos;
1427
1278 if (!m_pos.IsFinite()) 1428 if (!m_pos.IsFinite())
1279 { 1429 {
1280 m_pos.X = 127f; 1430 m_pos.X = 127f;
@@ -1345,7 +1495,6 @@ namespace OpenSim.Region.Framework.Scenes
1345 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1495 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1346 } 1496 }
1347 } 1497 }
1348
1349 lock (scriptedcontrols) 1498 lock (scriptedcontrols)
1350 { 1499 {
1351 if (scriptedcontrols.Count > 0) 1500 if (scriptedcontrols.Count > 0)
@@ -1360,6 +1509,9 @@ namespace OpenSim.Region.Framework.Scenes
1360 1509
1361 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1510 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1362 { 1511 {
1512 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1513 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1514
1363 // TODO: This doesn't prevent the user from walking yet. 1515 // TODO: This doesn't prevent the user from walking yet.
1364 // Setting parent ID would fix this, if we knew what value 1516 // Setting parent ID would fix this, if we knew what value
1365 // to use. Or we could add a m_isSitting variable. 1517 // to use. Or we could add a m_isSitting variable.
@@ -1408,12 +1560,20 @@ namespace OpenSim.Region.Framework.Scenes
1408 if (actor.Flying != oldflying) 1560 if (actor.Flying != oldflying)
1409 update_movementflag = true; 1561 update_movementflag = true;
1410 1562
1563 if (m_animator.m_jumping) // add for jumping
1564 update_movementflag = true;
1565
1411 if (q != m_bodyRot) 1566 if (q != m_bodyRot)
1412 { 1567 {
1413 m_bodyRot = q; 1568 m_bodyRot = q;
1414 update_rotation = true; 1569 update_rotation = true;
1415 } 1570 }
1416 1571
1572 //guilty until proven innocent..
1573 bool Nudging = true;
1574 //Basically, if there is at least one non-nudge control then we don't need
1575 //to worry about stopping the avatar
1576
1417 if (m_parentID == 0) 1577 if (m_parentID == 0)
1418 { 1578 {
1419 bool bAllowUpdateMoveToPosition = false; 1579 bool bAllowUpdateMoveToPosition = false;
@@ -1428,9 +1588,12 @@ namespace OpenSim.Region.Framework.Scenes
1428 else 1588 else
1429 dirVectors = Dir_Vectors; 1589 dirVectors = Dir_Vectors;
1430 1590
1431 // The fact that m_movementflag is a byte needs to be fixed 1591 bool[] isNudge = GetDirectionIsNudge();
1432 // it really should be a uint 1592
1433 uint nudgehack = 250; 1593
1594
1595
1596
1434 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1597 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1435 { 1598 {
1436 if (((uint)flags & (uint)DCF) != 0) 1599 if (((uint)flags & (uint)DCF) != 0)
@@ -1440,40 +1603,28 @@ namespace OpenSim.Region.Framework.Scenes
1440 try 1603 try
1441 { 1604 {
1442 agent_control_v3 += dirVectors[i]; 1605 agent_control_v3 += dirVectors[i];
1443 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1606 if (isNudge[i] == false)
1607 {
1608 Nudging = false;
1609 }
1444 } 1610 }
1445 catch (IndexOutOfRangeException) 1611 catch (IndexOutOfRangeException)
1446 { 1612 {
1447 // Why did I get this? 1613 // Why did I get this?
1448 } 1614 }
1449 1615
1450 if ((m_movementflag & (byte)(uint)DCF) == 0) 1616 if ((m_movementflag & (uint)DCF) == 0)
1451 { 1617 {
1452 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1453 {
1454 m_movementflag |= (byte)nudgehack;
1455 }
1456 m_movementflag += (byte)(uint)DCF; 1618 m_movementflag += (byte)(uint)DCF;
1457 update_movementflag = true; 1619 update_movementflag = true;
1458 } 1620 }
1459 } 1621 }
1460 else 1622 else
1461 { 1623 {
1462 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1624 if ((m_movementflag & (uint)DCF) != 0)
1463 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1464 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1465 ) // This or is for Nudge forward
1466 { 1625 {
1467 m_movementflag -= ((byte)(uint)DCF); 1626 m_movementflag -= (byte)(uint)DCF;
1468
1469 update_movementflag = true; 1627 update_movementflag = true;
1470 /*
1471 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1472 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1473 {
1474 m_log.Debug("Removed Hack flag");
1475 }
1476 */
1477 } 1628 }
1478 else 1629 else
1479 { 1630 {
@@ -1482,7 +1633,6 @@ namespace OpenSim.Region.Framework.Scenes
1482 } 1633 }
1483 i++; 1634 i++;
1484 } 1635 }
1485
1486 //Paupaw:Do Proper PID for Autopilot here 1636 //Paupaw:Do Proper PID for Autopilot here
1487 if (bResetMoveToPosition) 1637 if (bResetMoveToPosition)
1488 { 1638 {
@@ -1494,8 +1644,41 @@ namespace OpenSim.Region.Framework.Scenes
1494 1644
1495 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) 1645 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving))
1496 { 1646 {
1647/*
1648 bool twoD = false;
1649 bool there = false;
1650 if (Animator != null)
1651 {
1652 switch (Animator.CurrentMovementAnimation)
1653 {
1654 case "STAND":
1655 case "WALK":
1656 case "RUN":
1657 case "CROUCH":
1658 case "CROUCHWALK":
1659 {
1660 twoD = true;
1661 }
1662 break;
1663 }
1664 }
1665
1666 if (twoD)
1667 {
1668*/
1669 Vector3 abspos = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, 0.0f);
1670 Vector3 tgt = new Vector3(m_moveToPositionTarget.X, m_moveToPositionTarget.Y, 0.0f);
1671/* if (Util.GetDistanceTo(abspos, tgt) <= 0.5f) there = true;
1672 }
1673 else
1674 {
1675 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) there = true;
1676 }
1677*/
1497 //Check the error term of the current position in relation to the target position 1678 //Check the error term of the current position in relation to the target position
1498 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) 1679// if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f)
1680// if (there)
1681 if (Util.GetDistanceTo(abspos, tgt) <= 0.5f)
1499 { 1682 {
1500 // we are close enough to the target 1683 // we are close enough to the target
1501 m_moveToPositionTarget = Vector3.Zero; 1684 m_moveToPositionTarget = Vector3.Zero;
@@ -1512,11 +1695,15 @@ namespace OpenSim.Region.Framework.Scenes
1512 // unknown forces are acting on the avatar and we need to adaptively respond 1695 // unknown forces are acting on the avatar and we need to adaptively respond
1513 // to such forces, but the following simple approach seems to works fine. 1696 // to such forces, but the following simple approach seems to works fine.
1514 Vector3 LocalVectorToTarget3D = 1697 Vector3 LocalVectorToTarget3D =
1515 (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1698// (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1699 (tgt - abspos)
1516 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords 1700 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords
1517 // Ignore z component of vector 1701 // Ignore z component of vector
1518 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1702 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1519 LocalVectorToTarget2D.Normalize(); 1703 LocalVectorToTarget2D.Normalize();
1704
1705 //We're not nudging
1706 Nudging = false;
1520 agent_control_v3 += LocalVectorToTarget2D; 1707 agent_control_v3 += LocalVectorToTarget2D;
1521 1708
1522 // update avatar movement flags. the avatar coordinate system is as follows: 1709 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1607,13 +1794,13 @@ namespace OpenSim.Region.Framework.Scenes
1607 // m_log.DebugFormat( 1794 // m_log.DebugFormat(
1608 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1795 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1609 1796
1610 AddNewMovement(agent_control_v3, q); 1797 AddNewMovement(agent_control_v3, q, Nudging);
1611 1798
1612 1799
1613 } 1800 }
1614 } 1801 }
1615 1802
1616 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1803 if (update_movementflag && !SitGround)
1617 Animator.UpdateMovementAnimations(); 1804 Animator.UpdateMovementAnimations();
1618 1805
1619 m_scene.EventManager.TriggerOnClientMovement(this); 1806 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1628,7 +1815,6 @@ namespace OpenSim.Region.Framework.Scenes
1628 m_sitAtAutoTarget = false; 1815 m_sitAtAutoTarget = false;
1629 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1816 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1630 //proxy.PCode = (byte)PCode.ParticleSystem; 1817 //proxy.PCode = (byte)PCode.ParticleSystem;
1631
1632 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1818 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1633 proxyObjectGroup.AttachToScene(m_scene); 1819 proxyObjectGroup.AttachToScene(m_scene);
1634 1820
@@ -1647,8 +1833,15 @@ namespace OpenSim.Region.Framework.Scenes
1647// } 1833// }
1648 } 1834 }
1649 1835
1836 public void StopMoveToPosition()
1837 {
1838 m_moveToPositionTarget = Vector3.Zero;
1839 m_moveToPositionInProgress = false;
1840 }
1841
1650 public void DoMoveToPosition(Object sender, string method, List<String> args) 1842 public void DoMoveToPosition(Object sender, string method, List<String> args)
1651 { 1843 {
1844//Console.WriteLine("SP:DoMoveToPosition");
1652 try 1845 try
1653 { 1846 {
1654 float locx = 0f; 1847 float locx = 0f;
@@ -1670,7 +1863,7 @@ namespace OpenSim.Region.Framework.Scenes
1670 } 1863 }
1671 m_moveToPositionInProgress = true; 1864 m_moveToPositionInProgress = true;
1672 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1865 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1673 } 1866 }
1674 catch (Exception ex) 1867 catch (Exception ex)
1675 { 1868 {
1676 //Why did I get this error? 1869 //Why did I get this error?
@@ -1692,7 +1885,7 @@ namespace OpenSim.Region.Framework.Scenes
1692 Velocity = Vector3.Zero; 1885 Velocity = Vector3.Zero;
1693 SendAvatarDataToAllAgents(); 1886 SendAvatarDataToAllAgents();
1694 1887
1695 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1888 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1696 } 1889 }
1697 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1890 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1698 m_requestedSitTargetUUID = UUID.Zero; 1891 m_requestedSitTargetUUID = UUID.Zero;
@@ -1729,25 +1922,22 @@ namespace OpenSim.Region.Framework.Scenes
1729 1922
1730 if (m_parentID != 0) 1923 if (m_parentID != 0)
1731 { 1924 {
1732 m_log.Debug("StandupCode Executed"); 1925 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1733 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1734 if (part != null) 1926 if (part != null)
1735 { 1927 {
1928 part.TaskInventory.LockItemsForRead(true);
1736 TaskInventoryDictionary taskIDict = part.TaskInventory; 1929 TaskInventoryDictionary taskIDict = part.TaskInventory;
1737 if (taskIDict != null) 1930 if (taskIDict != null)
1738 { 1931 {
1739 lock (taskIDict) 1932 foreach (UUID taskID in taskIDict.Keys)
1740 { 1933 {
1741 foreach (UUID taskID in taskIDict.Keys) 1934 UnRegisterControlEventsToScript(LocalId, taskID);
1742 { 1935 taskIDict[taskID].PermsMask &= ~(
1743 UnRegisterControlEventsToScript(LocalId, taskID); 1936 2048 | //PERMISSION_CONTROL_CAMERA
1744 taskIDict[taskID].PermsMask &= ~( 1937 4); // PERMISSION_TAKE_CONTROLS
1745 2048 | //PERMISSION_CONTROL_CAMERA
1746 4); // PERMISSION_TAKE_CONTROLS
1747 }
1748 } 1938 }
1749
1750 } 1939 }
1940 part.TaskInventory.LockItemsForRead(false);
1751 // Reset sit target. 1941 // Reset sit target.
1752 if (part.GetAvatarOnSitTarget() == UUID) 1942 if (part.GetAvatarOnSitTarget() == UUID)
1753 part.SitTargetAvatar = UUID.Zero; 1943 part.SitTargetAvatar = UUID.Zero;
@@ -1756,16 +1946,55 @@ namespace OpenSim.Region.Framework.Scenes
1756 m_parentPosition = part.GetWorldPosition(); 1946 m_parentPosition = part.GetWorldPosition();
1757 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1947 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1758 } 1948 }
1949 // part.GetWorldRotation() is the rotation of the object being sat on
1950 // Rotation is the sittiing Av's rotation
1951
1952 Quaternion partRot;
1953// if (part.LinkNum == 1)
1954// { // Root prim of linkset
1955// partRot = part.ParentGroup.RootPart.RotationOffset;
1956// }
1957// else
1958// { // single or child prim
1959
1960// }
1961 if (part == null) //CW: Part may be gone. llDie() for example.
1962 {
1963 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1964 }
1965 else
1966 {
1967 partRot = part.GetWorldRotation();
1968 }
1759 1969
1970 Quaternion partIRot = Quaternion.Inverse(partRot);
1971
1972 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1973 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1974
1975
1760 if (m_physicsActor == null) 1976 if (m_physicsActor == null)
1761 { 1977 {
1762 AddToPhysicalScene(false); 1978 AddToPhysicalScene(false);
1763 } 1979 }
1764 1980 //CW: If the part isn't null then we can set the current position
1765 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1981 if (part != null)
1766 m_parentPosition = Vector3.Zero; 1982 {
1767 1983 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1768 m_parentID = 0; 1984 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1985 part.IsOccupied = false;
1986 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1987 }
1988 else
1989 {
1990 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1991 AbsolutePosition = m_lastWorldPosition;
1992 }
1993
1994 m_parentPosition = Vector3.Zero;
1995 m_parentID = 0;
1996 m_linkedPrim = UUID.Zero;
1997 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1769 SendAvatarDataToAllAgents(); 1998 SendAvatarDataToAllAgents();
1770 m_requestedSitTargetID = 0; 1999 m_requestedSitTargetID = 0;
1771 if (m_physicsActor != null && m_appearance != null) 2000 if (m_physicsActor != null && m_appearance != null)
@@ -1774,7 +2003,6 @@ namespace OpenSim.Region.Framework.Scenes
1774 SetHeight(m_appearance.AvatarHeight); 2003 SetHeight(m_appearance.AvatarHeight);
1775 } 2004 }
1776 } 2005 }
1777
1778 Animator.TrySetMovementAnimation("STAND"); 2006 Animator.TrySetMovementAnimation("STAND");
1779 } 2007 }
1780 2008
@@ -1805,13 +2033,9 @@ namespace OpenSim.Region.Framework.Scenes
1805 Vector3 avSitOffSet = part.SitTargetPosition; 2033 Vector3 avSitOffSet = part.SitTargetPosition;
1806 Quaternion avSitOrientation = part.SitTargetOrientation; 2034 Quaternion avSitOrientation = part.SitTargetOrientation;
1807 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2035 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1808 2036 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1809 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2037 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1810 bool SitTargetisSet = 2038 if (SitTargetisSet && !SitTargetOccupied)
1811 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1812 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1813
1814 if (SitTargetisSet && SitTargetUnOccupied)
1815 { 2039 {
1816 //switch the target to this prim 2040 //switch the target to this prim
1817 return part; 2041 return part;
@@ -1825,85 +2049,168 @@ namespace OpenSim.Region.Framework.Scenes
1825 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2049 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1826 { 2050 {
1827 bool autopilot = true; 2051 bool autopilot = true;
2052 Vector3 autopilotTarget = new Vector3();
2053 Quaternion sitOrientation = Quaternion.Identity;
1828 Vector3 pos = new Vector3(); 2054 Vector3 pos = new Vector3();
1829 Quaternion sitOrientation = pSitOrientation;
1830 Vector3 cameraEyeOffset = Vector3.Zero; 2055 Vector3 cameraEyeOffset = Vector3.Zero;
1831 Vector3 cameraAtOffset = Vector3.Zero; 2056 Vector3 cameraAtOffset = Vector3.Zero;
1832 bool forceMouselook = false; 2057 bool forceMouselook = false;
1833 2058
1834 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2059 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1835 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2060 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1836 if (part != null) 2061 if (part == null) return;
1837 { 2062
1838 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2063 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1839 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2064 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1840 2065
1841 // Is a sit target available? 2066 // part is the prim to sit on
1842 Vector3 avSitOffSet = part.SitTargetPosition; 2067 // offset is the world-ref vector distance from that prim center to the click-spot
1843 Quaternion avSitOrientation = part.SitTargetOrientation; 2068 // UUID is the UUID of the Avatar doing the clicking
1844 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 2069
1845 2070 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1846 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2071
1847 bool SitTargetisSet = 2072 // Is a sit target available?
1848 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 2073 Vector3 avSitOffSet = part.SitTargetPosition;
1849 ( 2074 Quaternion avSitOrientation = part.SitTargetOrientation;
1850 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 2075
1851 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 2076 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1852 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 2077 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1853 ) 2078 Quaternion partRot;
1854 )); 2079// if (part.LinkNum == 1)
1855 2080// { // Root prim of linkset
1856 if (SitTargetisSet && SitTargetUnOccupied) 2081// partRot = part.ParentGroup.RootPart.RotationOffset;
1857 { 2082// }
1858 part.SitTargetAvatar = UUID; 2083// else
1859 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 2084// { // single or child prim
1860 sitOrientation = avSitOrientation; 2085 partRot = part.GetWorldRotation();
1861 autopilot = false; 2086// }
1862 } 2087 Quaternion partIRot = Quaternion.Inverse(partRot);
1863 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 2088//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1864 2089 // Sit analysis rewritten by KF 091125
1865 pos = part.AbsolutePosition + offset; 2090 if (SitTargetisSet) // scipted sit
1866 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 2091 {
1867 //{ 2092 if (!part.IsOccupied)
1868 // offset = pos; 2093 {
1869 //autopilot = false; 2094//Console.WriteLine("Scripted, unoccupied");
1870 //} 2095 part.SitTargetAvatar = UUID; // set that Av will be on it
1871 if (m_physicsActor != null) 2096 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1872 { 2097
1873 // If we're not using the client autopilot, we're immediately warping the avatar to the location 2098 Quaternion nrot = avSitOrientation;
1874 // We can remove the physicsActor until they stand up. 2099 if (!part.IsRoot)
1875 m_sitAvatarHeight = m_physicsActor.Size.Z;
1876
1877 if (autopilot)
1878 { 2100 {
1879 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2101 nrot = part.RotationOffset * avSitOrientation;
1880 {
1881 autopilot = false;
1882
1883 RemoveFromPhysicalScene();
1884 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1885 }
1886 } 2102 }
1887 else 2103 sitOrientation = nrot; // Change rotatione to the scripted one
2104 OffsetRotation = nrot;
2105 autopilot = false; // Jump direct to scripted llSitPos()
2106 }
2107 else
2108 {
2109//Console.WriteLine("Scripted, occupied");
2110 return;
2111 }
2112 }
2113 else // Not Scripted
2114 {
2115 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
2116 {
2117 // large prim & offset, ignore if other Avs sitting
2118// offset.Z -= 0.05f;
2119 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2120 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2121
2122//Console.WriteLine(" offset ={0}", offset);
2123//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2124//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2125
2126 }
2127 else // small offset
2128 {
2129//Console.WriteLine("Small offset");
2130 if (!part.IsOccupied)
2131 {
2132 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2133 autopilotTarget = part.AbsolutePosition;
2134//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2135 }
2136 else return; // occupied small
2137 } // end large/small
2138 } // end Scripted/not
2139
2140 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2141
2142 cameraAtOffset = part.GetCameraAtOffset();
2143 cameraEyeOffset = part.GetCameraEyeOffset();
2144 forceMouselook = part.GetForceMouselook();
2145 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2146 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2147
2148 if (m_physicsActor != null)
2149 {
2150 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2151 // We can remove the physicsActor until they stand up.
2152 m_sitAvatarHeight = m_physicsActor.Size.Z;
2153 if (autopilot)
2154 { // its not a scripted sit
2155// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2156 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1888 { 2157 {
2158 autopilot = false; // close enough
2159 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2160 Not using the part's position because returning the AV to the last known standing
2161 position is likely to be more friendly, isn't it? */
1889 RemoveFromPhysicalScene(); 2162 RemoveFromPhysicalScene();
1890 } 2163 Velocity = Vector3.Zero;
2164 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2165 } // else the autopilot will get us close
2166 }
2167 else
2168 { // its a scripted sit
2169 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2170 I *am* using the part's position this time because we have no real idea how far away
2171 the avatar is from the sit target. */
2172 RemoveFromPhysicalScene();
2173 Velocity = Vector3.Zero;
1891 } 2174 }
1892
1893 cameraAtOffset = part.GetCameraAtOffset();
1894 cameraEyeOffset = part.GetCameraEyeOffset();
1895 forceMouselook = part.GetForceMouselook();
1896 } 2175 }
1897 2176 else return; // physactor is null!
1898 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2177
1899 m_requestedSitTargetUUID = targetID; 2178 Vector3 offsetr; // = offset * partIRot;
2179 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2180 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2181 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2182 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2183 //offsetr = offset * partIRot;
2184//
2185 // }
2186 // else
2187 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2188 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2189 // (offset * partRot);
2190 // }
2191
2192//Console.WriteLine(" ");
2193//Console.WriteLine("link number ={0}", part.LinkNum);
2194//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2195//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2196//Console.WriteLine("Click offst ={0}", offset);
2197//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2198//Console.WriteLine("offsetr ={0}", offsetr);
2199//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2200//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2201
2202 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2203 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2204
2205 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1900 // This calls HandleAgentSit twice, once from here, and the client calls 2206 // This calls HandleAgentSit twice, once from here, and the client calls
1901 // HandleAgentSit itself after it gets to the location 2207 // HandleAgentSit itself after it gets to the location
1902 // It doesn't get to the location until we've moved them there though 2208 // It doesn't get to the location until we've moved them there though
1903 // which happens in HandleAgentSit :P 2209 // which happens in HandleAgentSit :P
1904 m_autopilotMoving = autopilot; 2210 m_autopilotMoving = autopilot;
1905 m_autoPilotTarget = pos; 2211 m_autoPilotTarget = autopilotTarget;
1906 m_sitAtAutoTarget = autopilot; 2212 m_sitAtAutoTarget = autopilot;
2213 m_initialSitTarget = autopilotTarget;
1907 if (!autopilot) 2214 if (!autopilot)
1908 HandleAgentSit(remoteClient, UUID); 2215 HandleAgentSit(remoteClient, UUID);
1909 } 2216 }
@@ -2198,47 +2505,130 @@ namespace OpenSim.Region.Framework.Scenes
2198 { 2505 {
2199 if (part != null) 2506 if (part != null)
2200 { 2507 {
2508//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2201 if (part.GetAvatarOnSitTarget() == UUID) 2509 if (part.GetAvatarOnSitTarget() == UUID)
2202 { 2510 {
2511//Console.WriteLine("Scripted Sit");
2512 // Scripted sit
2203 Vector3 sitTargetPos = part.SitTargetPosition; 2513 Vector3 sitTargetPos = part.SitTargetPosition;
2204 Quaternion sitTargetOrient = part.SitTargetOrientation; 2514 Quaternion sitTargetOrient = part.SitTargetOrientation;
2205
2206 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2207 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2208
2209 //Quaternion result = (sitTargetOrient * vq) * nq;
2210
2211 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2515 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2212 m_pos += SIT_TARGET_ADJUSTMENT; 2516 m_pos += SIT_TARGET_ADJUSTMENT;
2517 if (!part.IsRoot)
2518 {
2519 m_pos *= part.RotationOffset;
2520 }
2213 m_bodyRot = sitTargetOrient; 2521 m_bodyRot = sitTargetOrient;
2214 //Rotation = sitTargetOrient;
2215 m_parentPosition = part.AbsolutePosition; 2522 m_parentPosition = part.AbsolutePosition;
2216 2523 part.IsOccupied = true;
2217 //SendTerseUpdateToAllClients(); 2524 part.ParentGroup.AddAvatar(agentID);
2218 } 2525 }
2219 else 2526 else
2220 { 2527 {
2221 m_pos -= part.AbsolutePosition; 2528 // if m_avUnscriptedSitPos is zero then Av sits above center
2529 // Else Av sits at m_avUnscriptedSitPos
2530
2531 // Non-scripted sit by Kitto Flora 21Nov09
2532 // Calculate angle of line from prim to Av
2533 Quaternion partIRot;
2534// if (part.LinkNum == 1)
2535// { // Root prim of linkset
2536// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2537// }
2538// else
2539// { // single or child prim
2540 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2541// }
2542 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2543 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2544 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2545 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2546 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2547 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2548 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2549 // Av sits at world euler <0,0, z>, translated by part rotation
2550 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2551
2222 m_parentPosition = part.AbsolutePosition; 2552 m_parentPosition = part.AbsolutePosition;
2223 } 2553 part.IsOccupied = true;
2554 part.ParentGroup.AddAvatar(agentID);
2555 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2556 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2557 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2558 m_avUnscriptedSitPos; // adds click offset, if any
2559 //Set up raytrace to find top surface of prim
2560 Vector3 size = part.Scale;
2561 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2562 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2563 Vector3 down = new Vector3(0f, 0f, -1f);
2564//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2565 m_scene.PhysicsScene.RaycastWorld(
2566 start, // Vector3 position,
2567 down, // Vector3 direction,
2568 mag, // float length,
2569 SitAltitudeCallback); // retMethod
2570 } // end scripted/not
2224 } 2571 }
2225 else 2572 else // no Av
2226 { 2573 {
2227 return; 2574 return;
2228 } 2575 }
2229 } 2576 }
2230 m_parentID = m_requestedSitTargetID;
2231 2577
2578 //We want our offsets to reference the root prim, not the child we may have sat on
2579 if (!part.IsRoot)
2580 {
2581 m_parentID = part.ParentGroup.RootPart.LocalId;
2582 m_pos += part.OffsetPosition;
2583 }
2584 else
2585 {
2586 m_parentID = m_requestedSitTargetID;
2587 }
2588
2589 m_linkedPrim = part.UUID;
2590 if (part.GetAvatarOnSitTarget() != UUID)
2591 {
2592 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2593 }
2232 Velocity = Vector3.Zero; 2594 Velocity = Vector3.Zero;
2233 RemoveFromPhysicalScene(); 2595 RemoveFromPhysicalScene();
2234
2235 Animator.TrySetMovementAnimation(sitAnimation); 2596 Animator.TrySetMovementAnimation(sitAnimation);
2236 SendAvatarDataToAllAgents(); 2597 SendAvatarDataToAllAgents();
2237 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2238 // So we're also sending a terse update (which has avatar rotation)
2239 // [Update] We do now.
2240 //SendTerseUpdateToAllClients(); 2598 //SendTerseUpdateToAllClients();
2241 } 2599 }
2600
2601 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2602 {
2603 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2604 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2605 if(hitYN)
2606 {
2607 // m_pos = Av offset from prim center to make look like on center
2608 // m_parentPosition = Actual center pos of prim
2609 // collisionPoint = spot on prim where we want to sit
2610 // collisionPoint.Z = global sit surface height
2611 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2612 Quaternion partIRot;
2613// if (part.LinkNum == 1)
2614/// { // Root prim of linkset
2615// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2616// }
2617// else
2618// { // single or child prim
2619 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2620// }
2621 if (m_initialSitTarget != null)
2622 {
2623 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2624 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2625 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2626 m_pos += offset;
2627 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2628 }
2629
2630 }
2631 } // End SitAltitudeCallback KF.
2242 2632
2243 /// <summary> 2633 /// <summary>
2244 /// Event handler for the 'Always run' setting on the client 2634 /// Event handler for the 'Always run' setting on the client
@@ -2268,12 +2658,13 @@ namespace OpenSim.Region.Framework.Scenes
2268 /// </summary> 2658 /// </summary>
2269 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2659 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2270 /// <param name="rotation">The direction in which this avatar should now face. 2660 /// <param name="rotation">The direction in which this avatar should now face.
2271 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2661 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2272 { 2662 {
2273 if (m_isChildAgent) 2663 if (m_isChildAgent)
2274 { 2664 {
2275 // WHAT??? 2665 // WHAT???
2276 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); 2666 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent");
2667
2277 return; 2668 return;
2278 } 2669 }
2279 2670
@@ -2282,15 +2673,26 @@ namespace OpenSim.Region.Framework.Scenes
2282 Rotation = rotation; 2673 Rotation = rotation;
2283 Vector3 direc = vec * rotation; 2674 Vector3 direc = vec * rotation;
2284 direc.Normalize(); 2675 direc.Normalize();
2676 PhysicsActor actor = m_physicsActor;
2677
2678 if (actor.Flying != m_flyingOld) // add for fly velocity control
2679 {
2680 m_flyingOld = actor.Flying; // add for fly velocity control
2681 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2682 }
2683
2684 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2685
2686 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2285 2687
2286 direc *= 0.03f * 128f * m_speedModifier; 2688 direc *= 0.03f * 128f * m_speedModifier;
2287 2689
2288 PhysicsActor actor = m_physicsActor;
2289 if (actor != null) 2690 if (actor != null)
2290 { 2691 {
2291 if (actor.Flying) 2692 if (actor.Flying)
2292 { 2693 {
2293 direc *= 4.0f; 2694// rm speed mod direc *= 4.0f;
2695 direc *= 5.2f; // for speed mod
2294 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2696 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2295 //bool colliding = (m_physicsActor.IsColliding==true); 2697 //bool colliding = (m_physicsActor.IsColliding==true);
2296 //if (controlland) 2698 //if (controlland)
@@ -2303,22 +2705,34 @@ namespace OpenSim.Region.Framework.Scenes
2303 // m_log.Info("[AGENT]: Stop FLying"); 2705 // m_log.Info("[AGENT]: Stop FLying");
2304 //} 2706 //}
2305 } 2707 }
2708 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2709 {
2710 direc *= 0.0f;
2711 }
2712 /* This jumping section removed to SPA
2306 else if (!actor.Flying && actor.IsColliding) 2713 else if (!actor.Flying && actor.IsColliding)
2307 { 2714 {
2308 if (direc.Z > 2.0f) 2715 if (direc.Z > 2.0f)
2309 { 2716 {
2310 direc.Z *= 3.0f; 2717 if(m_animator.m_animTickJump == -1)
2311 2718 {
2312 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2719 direc.Z *= 3.0f; // jump
2313 Animator.TrySetMovementAnimation("PREJUMP"); 2720 }
2314 Animator.TrySetMovementAnimation("JUMP"); 2721 else
2722 {
2723 direc.Z *= 0.1f; // prejump
2724 }
2725 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2726 Animator.TrySetMovementAnimation("PREJUMP");
2727 Animator.TrySetMovementAnimation("JUMP");
2728 * /
2315 } 2729 }
2316 } 2730 } */
2317 } 2731 }
2318 2732
2319 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2733 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2320 m_forceToApply = direc; 2734 m_forceToApply = direc;
2321 2735 m_isNudging = Nudging;
2322 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2736 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2323 } 2737 }
2324 2738
@@ -2367,6 +2781,9 @@ namespace OpenSim.Region.Framework.Scenes
2367 2781
2368 CheckForSignificantMovement(); // sends update to the modules. 2782 CheckForSignificantMovement(); // sends update to the modules.
2369 } 2783 }
2784
2785 //Sending prim updates AFTER the avatar terse updates are sent
2786 SendPrimUpdates();
2370 } 2787 }
2371 2788
2372 #endregion 2789 #endregion
@@ -3182,6 +3599,7 @@ namespace OpenSim.Region.Framework.Scenes
3182 m_callbackURI = cAgent.CallbackURI; 3599 m_callbackURI = cAgent.CallbackURI;
3183 3600
3184 m_pos = cAgent.Position; 3601 m_pos = cAgent.Position;
3602
3185 m_velocity = cAgent.Velocity; 3603 m_velocity = cAgent.Velocity;
3186 m_CameraCenter = cAgent.Center; 3604 m_CameraCenter = cAgent.Center;
3187 m_CameraAtAxis = cAgent.AtAxis; 3605 m_CameraAtAxis = cAgent.AtAxis;
@@ -3270,17 +3688,45 @@ namespace OpenSim.Region.Framework.Scenes
3270 /// </summary> 3688 /// </summary>
3271 public override void UpdateMovement() 3689 public override void UpdateMovement()
3272 { 3690 {
3273 if (m_forceToApply.HasValue) 3691 if (Animator!=null) // add for jumping
3274 { 3692 { // add for jumping
3275 Vector3 force = m_forceToApply.Value; 3693 // if (!m_animator.m_jumping) // add for jumping
3276 3694 // { // add for jumping
3277 m_updateflag = true;
3278 3695
3279 Velocity = force; 3696 if (m_forceToApply.HasValue) // this section realigned
3697 {
3280 3698
3281 m_forceToApply = null; 3699 Vector3 force = m_forceToApply.Value;
3282 } 3700 m_updateflag = true;
3283 } 3701if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3702 Velocity = force;
3703//Console.WriteLine("UM1 {0}", Velocity);
3704 m_forceToApply = null;
3705 }
3706 else
3707 {
3708 if (m_isNudging)
3709 {
3710 Vector3 force = Vector3.Zero;
3711
3712 m_updateflag = true;
3713if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3714 Velocity = force;
3715//Console.WriteLine("UM2 {0}", Velocity);
3716 m_isNudging = false;
3717 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3718 }
3719 else // add for jumping
3720 { // add for jumping
3721 Vector3 force = Vector3.Zero; // add for jumping
3722if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3723//Console.WriteLine("UM3 {0}", Velocity);
3724 Velocity = force; // add for jumping
3725 }
3726 }
3727 // } // end realign
3728 } // add for jumping
3729 } // add for jumping
3284 3730
3285 /// <summary> 3731 /// <summary>
3286 /// Adds a physical representation of the avatar to the Physics plugin 3732 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3294,10 +3740,8 @@ namespace OpenSim.Region.Framework.Scenes
3294 3740
3295 Vector3 pVec = AbsolutePosition; 3741 Vector3 pVec = AbsolutePosition;
3296 3742
3297 // Old bug where the height was in centimeters instead of meters
3298 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3743 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3299 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3744 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3300
3301 scene.AddPhysicsActorTaint(m_physicsActor); 3745 scene.AddPhysicsActorTaint(m_physicsActor);
3302 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3746 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3303 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3747 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3321,18 +3765,29 @@ namespace OpenSim.Region.Framework.Scenes
3321 { 3765 {
3322 if (e == null) 3766 if (e == null)
3323 return; 3767 return;
3324 3768
3325 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3769 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3326 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3327 // as of this comment the interval is set in AddToPhysicalScene 3770 // as of this comment the interval is set in AddToPhysicalScene
3328 if (Animator!=null) 3771 if (Animator!=null)
3329 Animator.UpdateMovementAnimations(); 3772 {
3773 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3774 { // else its will lock out other animation changes, like ground sit.
3775 Animator.UpdateMovementAnimations();
3776 m_updateCount--;
3777 }
3778 }
3330 3779
3331 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3780 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3332 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3781 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3333 3782
3334 CollisionPlane = Vector4.UnitW; 3783 CollisionPlane = Vector4.UnitW;
3335 3784
3785 if (m_lastColCount != coldata.Count)
3786 {
3787 m_updateCount = UPDATE_COUNT;
3788 m_lastColCount = coldata.Count;
3789 }
3790
3336 if (coldata.Count != 0 && Animator != null) 3791 if (coldata.Count != 0 && Animator != null)
3337 { 3792 {
3338 switch (Animator.CurrentMovementAnimation) 3793 switch (Animator.CurrentMovementAnimation)
@@ -3362,6 +3817,148 @@ namespace OpenSim.Region.Framework.Scenes
3362 } 3817 }
3363 } 3818 }
3364 3819
3820 List<uint> thisHitColliders = new List<uint>();
3821 List<uint> endedColliders = new List<uint>();
3822 List<uint> startedColliders = new List<uint>();
3823
3824 foreach (uint localid in coldata.Keys)
3825 {
3826 thisHitColliders.Add(localid);
3827 if (!m_lastColliders.Contains(localid))
3828 {
3829 startedColliders.Add(localid);
3830 }
3831 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3832 }
3833
3834 // calculate things that ended colliding
3835 foreach (uint localID in m_lastColliders)
3836 {
3837 if (!thisHitColliders.Contains(localID))
3838 {
3839 endedColliders.Add(localID);
3840 }
3841 }
3842 //add the items that started colliding this time to the last colliders list.
3843 foreach (uint localID in startedColliders)
3844 {
3845 m_lastColliders.Add(localID);
3846 }
3847 // remove things that ended colliding from the last colliders list
3848 foreach (uint localID in endedColliders)
3849 {
3850 m_lastColliders.Remove(localID);
3851 }
3852
3853 // do event notification
3854 if (startedColliders.Count > 0)
3855 {
3856 ColliderArgs StartCollidingMessage = new ColliderArgs();
3857 List<DetectedObject> colliding = new List<DetectedObject>();
3858 foreach (uint localId in startedColliders)
3859 {
3860 if (localId == 0)
3861 continue;
3862
3863 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3864 string data = "";
3865 if (obj != null)
3866 {
3867 DetectedObject detobj = new DetectedObject();
3868 detobj.keyUUID = obj.UUID;
3869 detobj.nameStr = obj.Name;
3870 detobj.ownerUUID = obj.OwnerID;
3871 detobj.posVector = obj.AbsolutePosition;
3872 detobj.rotQuat = obj.GetWorldRotation();
3873 detobj.velVector = obj.Velocity;
3874 detobj.colliderType = 0;
3875 detobj.groupUUID = obj.GroupID;
3876 colliding.Add(detobj);
3877 }
3878 }
3879
3880 if (colliding.Count > 0)
3881 {
3882 StartCollidingMessage.Colliders = colliding;
3883
3884 foreach (SceneObjectGroup att in Attachments)
3885 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3886 }
3887 }
3888
3889 if (endedColliders.Count > 0)
3890 {
3891 ColliderArgs EndCollidingMessage = new ColliderArgs();
3892 List<DetectedObject> colliding = new List<DetectedObject>();
3893 foreach (uint localId in endedColliders)
3894 {
3895 if (localId == 0)
3896 continue;
3897
3898 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3899 string data = "";
3900 if (obj != null)
3901 {
3902 DetectedObject detobj = new DetectedObject();
3903 detobj.keyUUID = obj.UUID;
3904 detobj.nameStr = obj.Name;
3905 detobj.ownerUUID = obj.OwnerID;
3906 detobj.posVector = obj.AbsolutePosition;
3907 detobj.rotQuat = obj.GetWorldRotation();
3908 detobj.velVector = obj.Velocity;
3909 detobj.colliderType = 0;
3910 detobj.groupUUID = obj.GroupID;
3911 colliding.Add(detobj);
3912 }
3913 }
3914
3915 if (colliding.Count > 0)
3916 {
3917 EndCollidingMessage.Colliders = colliding;
3918
3919 foreach (SceneObjectGroup att in Attachments)
3920 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3921 }
3922 }
3923
3924 if (thisHitColliders.Count > 0)
3925 {
3926 ColliderArgs CollidingMessage = new ColliderArgs();
3927 List<DetectedObject> colliding = new List<DetectedObject>();
3928 foreach (uint localId in thisHitColliders)
3929 {
3930 if (localId == 0)
3931 continue;
3932
3933 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3934 string data = "";
3935 if (obj != null)
3936 {
3937 DetectedObject detobj = new DetectedObject();
3938 detobj.keyUUID = obj.UUID;
3939 detobj.nameStr = obj.Name;
3940 detobj.ownerUUID = obj.OwnerID;
3941 detobj.posVector = obj.AbsolutePosition;
3942 detobj.rotQuat = obj.GetWorldRotation();
3943 detobj.velVector = obj.Velocity;
3944 detobj.colliderType = 0;
3945 detobj.groupUUID = obj.GroupID;
3946 colliding.Add(detobj);
3947 }
3948 }
3949
3950 if (colliding.Count > 0)
3951 {
3952 CollidingMessage.Colliders = colliding;
3953
3954 lock (m_attachments)
3955 {
3956 foreach (SceneObjectGroup att in m_attachments)
3957 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3958 }
3959 }
3960 }
3961
3365 if (m_invulnerable) 3962 if (m_invulnerable)
3366 return; 3963 return;
3367 3964
@@ -3446,6 +4043,10 @@ namespace OpenSim.Region.Framework.Scenes
3446 { 4043 {
3447 lock (m_attachments) 4044 lock (m_attachments)
3448 { 4045 {
4046 // This may be true when the attachment comes back
4047 // from serialization after login. Clear it.
4048 gobj.IsDeleted = false;
4049
3449 m_attachments.Add(gobj); 4050 m_attachments.Add(gobj);
3450 } 4051 }
3451 } 4052 }
@@ -3787,6 +4388,39 @@ namespace OpenSim.Region.Framework.Scenes
3787 return; 4388 return;
3788 } 4389 }
3789 4390
4391 XmlDocument doc = new XmlDocument();
4392 string stateData = String.Empty;
4393
4394 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4395 if (attServ != null)
4396 {
4397 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4398 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4399 if (stateData != String.Empty)
4400 {
4401 try
4402 {
4403 doc.LoadXml(stateData);
4404 }
4405 catch { }
4406 }
4407 }
4408
4409 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4410
4411 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4412 if (nodes.Count > 0)
4413 {
4414 foreach (XmlNode n in nodes)
4415 {
4416 XmlElement elem = (XmlElement)n;
4417 string itemID = elem.GetAttribute("ItemID");
4418 string xml = elem.InnerXml;
4419
4420 itemData[new UUID(itemID)] = xml;
4421 }
4422 }
4423
3790 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4424 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3791 foreach (AvatarAttachment attach in attachments) 4425 foreach (AvatarAttachment attach in attachments)
3792 { 4426 {
@@ -3807,7 +4441,30 @@ namespace OpenSim.Region.Framework.Scenes
3807 4441
3808 try 4442 try
3809 { 4443 {
3810 m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4444 string xmlData;
4445 XmlDocument d = new XmlDocument();
4446 UUID asset;
4447 if (itemData.TryGetValue(itemID, out xmlData))
4448 {
4449 d.LoadXml(xmlData);
4450 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4451
4452 // Rez from inventory
4453 asset
4454 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4455
4456 }
4457 else
4458 {
4459 // Rez from inventory (with a null doc to let
4460 // CHANGED_OWNER happen)
4461 asset
4462 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4463 }
4464
4465 m_log.InfoFormat(
4466 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4467 p, itemID, asset);
3811 } 4468 }
3812 catch (Exception e) 4469 catch (Exception e)
3813 { 4470 {
@@ -3840,6 +4497,15 @@ namespace OpenSim.Region.Framework.Scenes
3840 m_reprioritization_called = false; 4497 m_reprioritization_called = false;
3841 } 4498 }
3842 } 4499 }
4500
4501 private Vector3 Quat2Euler(Quaternion rot){
4502 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4503 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4504 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4505 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4506 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4507 return(new Vector3(x,y,z));
4508 }
3843 4509
3844 public void SaveChangedAttachments() 4510 public void SaveChangedAttachments()
3845 { 4511 {
@@ -3863,5 +4529,30 @@ namespace OpenSim.Region.Framework.Scenes
3863 } 4529 }
3864 } 4530 }
3865 } 4531 }
4532
4533 private void CheckLandingPoint(ref Vector3 pos)
4534 {
4535 // Never constrain lures
4536 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4537 return;
4538
4539 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4540 return;
4541
4542 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4543
4544 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4545 land.LandData.UserLocation != Vector3.Zero &&
4546 land.LandData.OwnerID != m_uuid &&
4547 (!m_scene.Permissions.IsGod(m_uuid)) &&
4548 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4549 {
4550 float curr = Vector3.Distance(AbsolutePosition, pos);
4551 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4552 pos = land.LandData.UserLocation;
4553 else
4554 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4555 }
4556 }
3866 } 4557 }
3867} 4558}