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.cs997
1 files changed, 808 insertions, 189 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fa2c7b5..c108129 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,18 @@ 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 }
145 private TeleportFlags m_teleportFlags;
146 public TeleportFlags TeleportFlags
147 {
148 get { return m_teleportFlags; }
149 set { m_teleportFlags = value; }
150 }
151
133 private uint m_requestedSitTargetID; 152 private uint m_requestedSitTargetID;
134 private UUID m_requestedSitTargetUUID; 153 private UUID m_requestedSitTargetUUID;
135 public bool SitGround = false; 154 public bool SitGround = false;
@@ -153,9 +172,10 @@ namespace OpenSim.Region.Framework.Scenes
153 private int m_perfMonMS; 172 private int m_perfMonMS;
154 173
155 private bool m_setAlwaysRun; 174 private bool m_setAlwaysRun;
156
157 private bool m_forceFly; 175 private bool m_forceFly;
158 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
159 179
160 private float m_speedModifier = 1.0f; 180 private float m_speedModifier = 1.0f;
161 181
@@ -174,7 +194,8 @@ namespace OpenSim.Region.Framework.Scenes
174 protected RegionInfo m_regionInfo; 194 protected RegionInfo m_regionInfo;
175 protected ulong crossingFromRegion; 195 protected ulong crossingFromRegion;
176 196
177 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 197 private readonly Vector3[] Dir_Vectors = new Vector3[11];
198 private bool m_isNudging = false;
178 199
179 // Position of agent's camera in world (region cordinates) 200 // Position of agent's camera in world (region cordinates)
180 protected Vector3 m_CameraCenter; 201 protected Vector3 m_CameraCenter;
@@ -199,17 +220,25 @@ namespace OpenSim.Region.Framework.Scenes
199 private bool m_autopilotMoving; 220 private bool m_autopilotMoving;
200 private Vector3 m_autoPilotTarget; 221 private Vector3 m_autoPilotTarget;
201 private bool m_sitAtAutoTarget; 222 private bool m_sitAtAutoTarget;
223 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
202 224
203 private string m_nextSitAnimation = String.Empty; 225 private string m_nextSitAnimation = String.Empty;
204 226
205 //PauPaw:Proper PID Controler for autopilot************ 227 //PauPaw:Proper PID Controler for autopilot************
206 private bool m_moveToPositionInProgress; 228 private bool m_moveToPositionInProgress;
207 private Vector3 m_moveToPositionTarget; 229 private Vector3 m_moveToPositionTarget;
230 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
208 231
209 private bool m_followCamAuto; 232 private bool m_followCamAuto;
210 233
211 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
212 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();
213 242
214 private bool CameraConstraintActive; 243 private bool CameraConstraintActive;
215 //private int m_moveToPositionStateStatus; 244 //private int m_moveToPositionStateStatus;
@@ -236,7 +265,9 @@ namespace OpenSim.Region.Framework.Scenes
236 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 265 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
237 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 266 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
238 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,
239 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,
240 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
241 } 272 }
242 273
@@ -443,7 +474,8 @@ namespace OpenSim.Region.Framework.Scenes
443 get 474 get
444 { 475 {
445 PhysicsActor actor = m_physicsActor; 476 PhysicsActor actor = m_physicsActor;
446 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!
447 m_pos = actor.Position; 479 m_pos = actor.Position;
448 else 480 else
449 { 481 {
@@ -492,7 +524,8 @@ namespace OpenSim.Region.Framework.Scenes
492 } 524 }
493 } 525 }
494 526
495 m_pos = value; 527 if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
528 m_pos = value;
496 m_parentPosition = Vector3.Zero; 529 m_parentPosition = Vector3.Zero;
497 } 530 }
498 } 531 }
@@ -536,10 +569,39 @@ namespace OpenSim.Region.Framework.Scenes
536 } 569 }
537 } 570 }
538 571
572 public Quaternion OffsetRotation
573 {
574 get { return m_offsetRotation; }
575 set { m_offsetRotation = value; }
576 }
577
539 public Quaternion Rotation 578 public Quaternion Rotation
540 { 579 {
541 get { return m_bodyRot; } 580 get {
542 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 }
543 } 605 }
544 606
545 public Quaternion PreviousRotation 607 public Quaternion PreviousRotation
@@ -564,11 +626,21 @@ namespace OpenSim.Region.Framework.Scenes
564 626
565 private uint m_parentID; 627 private uint m_parentID;
566 628
629
630 private UUID m_linkedPrim;
631
567 public uint ParentID 632 public uint ParentID
568 { 633 {
569 get { return m_parentID; } 634 get { return m_parentID; }
570 set { m_parentID = value; } 635 set { m_parentID = value; }
571 } 636 }
637
638 public UUID LinkedPrim
639 {
640 get { return m_linkedPrim; }
641 set { m_linkedPrim = value; }
642 }
643
572 public float Health 644 public float Health
573 { 645 {
574 get { return m_health; } 646 get { return m_health; }
@@ -690,7 +762,7 @@ namespace OpenSim.Region.Framework.Scenes
690 CreateSceneViewer(); 762 CreateSceneViewer();
691 m_animator = new ScenePresenceAnimator(this); 763 m_animator = new ScenePresenceAnimator(this);
692 } 764 }
693 765
694 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() 766 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
695 { 767 {
696 m_rootRegionHandle = reginfo.RegionHandle; 768 m_rootRegionHandle = reginfo.RegionHandle;
@@ -704,6 +776,7 @@ namespace OpenSim.Region.Framework.Scenes
704 m_localId = m_scene.AllocateLocalId(); 776 m_localId = m_scene.AllocateLocalId();
705 777
706 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;
707 780
708 if (account != null) 781 if (account != null)
709 m_userLevel = account.UserLevel; 782 m_userLevel = account.UserLevel;
@@ -722,10 +795,7 @@ namespace OpenSim.Region.Framework.Scenes
722 m_reprioritization_timer.AutoReset = false; 795 m_reprioritization_timer.AutoReset = false;
723 796
724 AdjustKnownSeeds(); 797 AdjustKnownSeeds();
725
726 // TODO: I think, this won't send anything, as we are still a child here...
727 Animator.TrySetMovementAnimation("STAND"); 798 Animator.TrySetMovementAnimation("STAND");
728
729 // 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.
730 // Request info about all the (root) agents in this region 800 // Request info about all the (root) agents in this region
731 // 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)
@@ -776,25 +846,47 @@ namespace OpenSim.Region.Framework.Scenes
776 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 846 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
777 Dir_Vectors[4] = Vector3.UnitZ; //UP 847 Dir_Vectors[4] = Vector3.UnitZ; //UP
778 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 848 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
779 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 849 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
780 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 850 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
781 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
782 } 854 }
783 855
784 private Vector3[] GetWalkDirectionVectors() 856 private Vector3[] GetWalkDirectionVectors()
785 { 857 {
786 Vector3[] vector = new Vector3[9]; 858 Vector3[] vector = new Vector3[11];
787 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
788 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
789 vector[2] = Vector3.UnitY; //LEFT 861 vector[2] = Vector3.UnitY; //LEFT
790 vector[3] = -Vector3.UnitY; //RIGHT 862 vector[3] = -Vector3.UnitY; //RIGHT
791 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
792 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
793 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
794 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
795 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
796 return vector; 870 return vector;
797 } 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
798 890
799 #endregion 891 #endregion
800 892
@@ -856,6 +948,54 @@ namespace OpenSim.Region.Framework.Scenes
856 pos.Y = crossedBorder.BorderLine.Z - 1; 948 pos.Y = crossedBorder.BorderLine.Z - 1;
857 } 949 }
858 950
951 //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet.
952 //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent,
953 //they'll bypass the landing point. But I can't think of any decent way of fixing this.
954 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
955 if (land != null)
956 {
957 if (KnownChildRegionHandles.Count == 0)
958 {
959 //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni.
960 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && UserLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid)
961 {
962 pos = land.LandData.UserLocation;
963 }
964 }
965
966 land.SendLandUpdateToClient(ControllingClient);
967 }
968
969 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
970 {
971 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
972
973 if (pos.X < 0)
974 {
975 emergencyPos.X = (int)Constants.RegionSize + pos.X;
976 if (!(pos.Y < 0))
977 emergencyPos.Y = pos.Y;
978 if (!(pos.Z < 0))
979 emergencyPos.Z = pos.Z;
980 }
981 if (pos.Y < 0)
982 {
983 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
984 if (!(pos.X < 0))
985 emergencyPos.X = pos.X;
986 if (!(pos.Z < 0))
987 emergencyPos.Z = pos.Z;
988 }
989 if (pos.Z < 0)
990 {
991 emergencyPos.Z = 128;
992 if (!(pos.Y < 0))
993 emergencyPos.Y = pos.Y;
994 if (!(pos.X < 0))
995 emergencyPos.X = pos.X;
996 }
997 }
998
859 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 999 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
860 { 1000 {
861 m_log.WarnFormat( 1001 m_log.WarnFormat(
@@ -949,6 +1089,10 @@ namespace OpenSim.Region.Framework.Scenes
949 /// </summary> 1089 /// </summary>
950 public void MakeChildAgent() 1090 public void MakeChildAgent()
951 { 1091 {
1092 // Reset these so that teleporting in and walking out isn't seen
1093 // as teleporting back
1094 m_teleportFlags = TeleportFlags.Default;
1095
952 // It looks like m_animator is set to null somewhere, and MakeChild 1096 // It looks like m_animator is set to null somewhere, and MakeChild
953 // is called after that. Probably in aborted teleports. 1097 // is called after that. Probably in aborted teleports.
954 if (m_animator == null) 1098 if (m_animator == null)
@@ -980,12 +1124,17 @@ namespace OpenSim.Region.Framework.Scenes
980 { 1124 {
981 if (PhysicsActor != null) 1125 if (PhysicsActor != null)
982 { 1126 {
983 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1127 try
984 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; 1128 {
985 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1129 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
986 m_physicsActor.UnSubscribeEvents(); 1130 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
987 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1131 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
988 PhysicsActor = null; 1132 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1133 m_physicsActor.UnSubscribeEvents();
1134 PhysicsActor = null;
1135 }
1136 catch
1137 { }
989 } 1138 }
990 } 1139 }
991 1140
@@ -996,9 +1145,10 @@ namespace OpenSim.Region.Framework.Scenes
996 public void Teleport(Vector3 pos) 1145 public void Teleport(Vector3 pos)
997 { 1146 {
998 bool isFlying = false; 1147 bool isFlying = false;
1148
999 if (m_physicsActor != null) 1149 if (m_physicsActor != null)
1000 isFlying = m_physicsActor.Flying; 1150 isFlying = m_physicsActor.Flying;
1001 1151
1002 RemoveFromPhysicalScene(); 1152 RemoveFromPhysicalScene();
1003 Velocity = Vector3.Zero; 1153 Velocity = Vector3.Zero;
1004 AbsolutePosition = pos; 1154 AbsolutePosition = pos;
@@ -1010,6 +1160,7 @@ namespace OpenSim.Region.Framework.Scenes
1010 } 1160 }
1011 1161
1012 SendTerseUpdateToAllClients(); 1162 SendTerseUpdateToAllClients();
1163
1013 } 1164 }
1014 1165
1015 public void TeleportWithMomentum(Vector3 pos) 1166 public void TeleportWithMomentum(Vector3 pos)
@@ -1228,6 +1379,7 @@ namespace OpenSim.Region.Framework.Scenes
1228 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1379 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1229 1380
1230 m_pos = m_LastFinitePos; 1381 m_pos = m_LastFinitePos;
1382
1231 if (!m_pos.IsFinite()) 1383 if (!m_pos.IsFinite())
1232 { 1384 {
1233 m_pos.X = 127f; 1385 m_pos.X = 127f;
@@ -1294,7 +1446,6 @@ namespace OpenSim.Region.Framework.Scenes
1294 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1446 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1295 } 1447 }
1296 } 1448 }
1297
1298 lock (scriptedcontrols) 1449 lock (scriptedcontrols)
1299 { 1450 {
1300 if (scriptedcontrols.Count > 0) 1451 if (scriptedcontrols.Count > 0)
@@ -1309,6 +1460,9 @@ namespace OpenSim.Region.Framework.Scenes
1309 1460
1310 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1461 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1311 { 1462 {
1463 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1464 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1465
1312 // TODO: This doesn't prevent the user from walking yet. 1466 // TODO: This doesn't prevent the user from walking yet.
1313 // Setting parent ID would fix this, if we knew what value 1467 // Setting parent ID would fix this, if we knew what value
1314 // to use. Or we could add a m_isSitting variable. 1468 // to use. Or we could add a m_isSitting variable.
@@ -1357,12 +1511,20 @@ namespace OpenSim.Region.Framework.Scenes
1357 if (actor.Flying != oldflying) 1511 if (actor.Flying != oldflying)
1358 update_movementflag = true; 1512 update_movementflag = true;
1359 1513
1514 if (m_animator.m_jumping) // add for jumping
1515 update_movementflag = true;
1516
1360 if (q != m_bodyRot) 1517 if (q != m_bodyRot)
1361 { 1518 {
1362 m_bodyRot = q; 1519 m_bodyRot = q;
1363 update_rotation = true; 1520 update_rotation = true;
1364 } 1521 }
1365 1522
1523 //guilty until proven innocent..
1524 bool Nudging = true;
1525 //Basically, if there is at least one non-nudge control then we don't need
1526 //to worry about stopping the avatar
1527
1366 if (m_parentID == 0) 1528 if (m_parentID == 0)
1367 { 1529 {
1368 bool bAllowUpdateMoveToPosition = false; 1530 bool bAllowUpdateMoveToPosition = false;
@@ -1377,9 +1539,12 @@ namespace OpenSim.Region.Framework.Scenes
1377 else 1539 else
1378 dirVectors = Dir_Vectors; 1540 dirVectors = Dir_Vectors;
1379 1541
1380 // The fact that m_movementflag is a byte needs to be fixed 1542 bool[] isNudge = GetDirectionIsNudge();
1381 // it really should be a uint 1543
1382 uint nudgehack = 250; 1544
1545
1546
1547
1383 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1548 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1384 { 1549 {
1385 if (((uint)flags & (uint)DCF) != 0) 1550 if (((uint)flags & (uint)DCF) != 0)
@@ -1389,40 +1554,28 @@ namespace OpenSim.Region.Framework.Scenes
1389 try 1554 try
1390 { 1555 {
1391 agent_control_v3 += dirVectors[i]; 1556 agent_control_v3 += dirVectors[i];
1392 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); 1557 if (isNudge[i] == false)
1558 {
1559 Nudging = false;
1560 }
1393 } 1561 }
1394 catch (IndexOutOfRangeException) 1562 catch (IndexOutOfRangeException)
1395 { 1563 {
1396 // Why did I get this? 1564 // Why did I get this?
1397 } 1565 }
1398 1566
1399 if ((m_movementflag & (byte)(uint)DCF) == 0) 1567 if ((m_movementflag & (uint)DCF) == 0)
1400 { 1568 {
1401 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1402 {
1403 m_movementflag |= (byte)nudgehack;
1404 }
1405 m_movementflag += (byte)(uint)DCF; 1569 m_movementflag += (byte)(uint)DCF;
1406 update_movementflag = true; 1570 update_movementflag = true;
1407 } 1571 }
1408 } 1572 }
1409 else 1573 else
1410 { 1574 {
1411 if ((m_movementflag & (byte)(uint)DCF) != 0 || 1575 if ((m_movementflag & (uint)DCF) != 0)
1412 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1413 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1414 ) // This or is for Nudge forward
1415 { 1576 {
1416 m_movementflag -= ((byte)(uint)DCF); 1577 m_movementflag -= (byte)(uint)DCF;
1417
1418 update_movementflag = true; 1578 update_movementflag = true;
1419 /*
1420 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1421 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1422 {
1423 m_log.Debug("Removed Hack flag");
1424 }
1425 */
1426 } 1579 }
1427 else 1580 else
1428 { 1581 {
@@ -1431,7 +1584,6 @@ namespace OpenSim.Region.Framework.Scenes
1431 } 1584 }
1432 i++; 1585 i++;
1433 } 1586 }
1434
1435 //Paupaw:Do Proper PID for Autopilot here 1587 //Paupaw:Do Proper PID for Autopilot here
1436 if (bResetMoveToPosition) 1588 if (bResetMoveToPosition)
1437 { 1589 {
@@ -1466,6 +1618,9 @@ namespace OpenSim.Region.Framework.Scenes
1466 // Ignore z component of vector 1618 // Ignore z component of vector
1467 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1619 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1468 LocalVectorToTarget2D.Normalize(); 1620 LocalVectorToTarget2D.Normalize();
1621
1622 //We're not nudging
1623 Nudging = false;
1469 agent_control_v3 += LocalVectorToTarget2D; 1624 agent_control_v3 += LocalVectorToTarget2D;
1470 1625
1471 // update avatar movement flags. the avatar coordinate system is as follows: 1626 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1556,13 +1711,13 @@ namespace OpenSim.Region.Framework.Scenes
1556 // m_log.DebugFormat( 1711 // m_log.DebugFormat(
1557 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1712 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1558 1713
1559 AddNewMovement(agent_control_v3, q); 1714 AddNewMovement(agent_control_v3, q, Nudging);
1560 1715
1561 1716
1562 } 1717 }
1563 } 1718 }
1564 1719
1565 if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) 1720 if (update_movementflag && !SitGround)
1566 Animator.UpdateMovementAnimations(); 1721 Animator.UpdateMovementAnimations();
1567 1722
1568 m_scene.EventManager.TriggerOnClientMovement(this); 1723 m_scene.EventManager.TriggerOnClientMovement(this);
@@ -1577,7 +1732,6 @@ namespace OpenSim.Region.Framework.Scenes
1577 m_sitAtAutoTarget = false; 1732 m_sitAtAutoTarget = false;
1578 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1733 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1579 //proxy.PCode = (byte)PCode.ParticleSystem; 1734 //proxy.PCode = (byte)PCode.ParticleSystem;
1580
1581 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1735 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1582 proxyObjectGroup.AttachToScene(m_scene); 1736 proxyObjectGroup.AttachToScene(m_scene);
1583 1737
@@ -1618,8 +1772,8 @@ namespace OpenSim.Region.Framework.Scenes
1618 return; 1772 return;
1619 } 1773 }
1620 m_moveToPositionInProgress = true; 1774 m_moveToPositionInProgress = true;
1621 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1775 m_moveToPositionTarget = new Vector3(locx, locy, locz + (m_appearance.AvatarHeight / 2.0f));
1622 } 1776 }
1623 catch (Exception ex) 1777 catch (Exception ex)
1624 { 1778 {
1625 //Why did I get this error? 1779 //Why did I get this error?
@@ -1641,7 +1795,7 @@ namespace OpenSim.Region.Framework.Scenes
1641 Velocity = Vector3.Zero; 1795 Velocity = Vector3.Zero;
1642 SendAvatarDataToAllAgents(); 1796 SendAvatarDataToAllAgents();
1643 1797
1644 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1798 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1645 } 1799 }
1646 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1800 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1647 m_requestedSitTargetUUID = UUID.Zero; 1801 m_requestedSitTargetUUID = UUID.Zero;
@@ -1678,25 +1832,22 @@ namespace OpenSim.Region.Framework.Scenes
1678 1832
1679 if (m_parentID != 0) 1833 if (m_parentID != 0)
1680 { 1834 {
1681 m_log.Debug("StandupCode Executed"); 1835 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1682 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1683 if (part != null) 1836 if (part != null)
1684 { 1837 {
1838 part.TaskInventory.LockItemsForRead(true);
1685 TaskInventoryDictionary taskIDict = part.TaskInventory; 1839 TaskInventoryDictionary taskIDict = part.TaskInventory;
1686 if (taskIDict != null) 1840 if (taskIDict != null)
1687 { 1841 {
1688 lock (taskIDict) 1842 foreach (UUID taskID in taskIDict.Keys)
1689 { 1843 {
1690 foreach (UUID taskID in taskIDict.Keys) 1844 UnRegisterControlEventsToScript(LocalId, taskID);
1691 { 1845 taskIDict[taskID].PermsMask &= ~(
1692 UnRegisterControlEventsToScript(LocalId, taskID); 1846 2048 | //PERMISSION_CONTROL_CAMERA
1693 taskIDict[taskID].PermsMask &= ~( 1847 4); // PERMISSION_TAKE_CONTROLS
1694 2048 | //PERMISSION_CONTROL_CAMERA
1695 4); // PERMISSION_TAKE_CONTROLS
1696 }
1697 } 1848 }
1698
1699 } 1849 }
1850 part.TaskInventory.LockItemsForRead(false);
1700 // Reset sit target. 1851 // Reset sit target.
1701 if (part.GetAvatarOnSitTarget() == UUID) 1852 if (part.GetAvatarOnSitTarget() == UUID)
1702 part.SitTargetAvatar = UUID.Zero; 1853 part.SitTargetAvatar = UUID.Zero;
@@ -1705,16 +1856,55 @@ namespace OpenSim.Region.Framework.Scenes
1705 m_parentPosition = part.GetWorldPosition(); 1856 m_parentPosition = part.GetWorldPosition();
1706 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1857 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1707 } 1858 }
1859 // part.GetWorldRotation() is the rotation of the object being sat on
1860 // Rotation is the sittiing Av's rotation
1861
1862 Quaternion partRot;
1863// if (part.LinkNum == 1)
1864// { // Root prim of linkset
1865// partRot = part.ParentGroup.RootPart.RotationOffset;
1866// }
1867// else
1868// { // single or child prim
1869
1870// }
1871 if (part == null) //CW: Part may be gone. llDie() for example.
1872 {
1873 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1874 }
1875 else
1876 {
1877 partRot = part.GetWorldRotation();
1878 }
1879
1880 Quaternion partIRot = Quaternion.Inverse(partRot);
1708 1881
1882 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1883 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
1884
1885
1709 if (m_physicsActor == null) 1886 if (m_physicsActor == null)
1710 { 1887 {
1711 AddToPhysicalScene(false); 1888 AddToPhysicalScene(false);
1712 } 1889 }
1713 1890 //CW: If the part isn't null then we can set the current position
1714 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1891 if (part != null)
1715 m_parentPosition = Vector3.Zero; 1892 {
1716 1893 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
1717 m_parentID = 0; 1894 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1895 part.IsOccupied = false;
1896 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
1897 }
1898 else
1899 {
1900 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1901 AbsolutePosition = m_lastWorldPosition;
1902 }
1903
1904 m_parentPosition = Vector3.Zero;
1905 m_parentID = 0;
1906 m_linkedPrim = UUID.Zero;
1907 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1718 SendAvatarDataToAllAgents(); 1908 SendAvatarDataToAllAgents();
1719 m_requestedSitTargetID = 0; 1909 m_requestedSitTargetID = 0;
1720 if (m_physicsActor != null && m_appearance != null) 1910 if (m_physicsActor != null && m_appearance != null)
@@ -1723,7 +1913,6 @@ namespace OpenSim.Region.Framework.Scenes
1723 SetHeight(m_appearance.AvatarHeight); 1913 SetHeight(m_appearance.AvatarHeight);
1724 } 1914 }
1725 } 1915 }
1726
1727 Animator.TrySetMovementAnimation("STAND"); 1916 Animator.TrySetMovementAnimation("STAND");
1728 } 1917 }
1729 1918
@@ -1754,13 +1943,9 @@ namespace OpenSim.Region.Framework.Scenes
1754 Vector3 avSitOffSet = part.SitTargetPosition; 1943 Vector3 avSitOffSet = part.SitTargetPosition;
1755 Quaternion avSitOrientation = part.SitTargetOrientation; 1944 Quaternion avSitOrientation = part.SitTargetOrientation;
1756 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1945 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1757 1946 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1758 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1947 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1759 bool SitTargetisSet = 1948 if (SitTargetisSet && !SitTargetOccupied)
1760 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1761 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1762
1763 if (SitTargetisSet && SitTargetUnOccupied)
1764 { 1949 {
1765 //switch the target to this prim 1950 //switch the target to this prim
1766 return part; 1951 return part;
@@ -1774,85 +1959,167 @@ namespace OpenSim.Region.Framework.Scenes
1774 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1959 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1775 { 1960 {
1776 bool autopilot = true; 1961 bool autopilot = true;
1962 Vector3 autopilotTarget = new Vector3();
1963 Quaternion sitOrientation = Quaternion.Identity;
1777 Vector3 pos = new Vector3(); 1964 Vector3 pos = new Vector3();
1778 Quaternion sitOrientation = pSitOrientation;
1779 Vector3 cameraEyeOffset = Vector3.Zero; 1965 Vector3 cameraEyeOffset = Vector3.Zero;
1780 Vector3 cameraAtOffset = Vector3.Zero; 1966 Vector3 cameraAtOffset = Vector3.Zero;
1781 bool forceMouselook = false; 1967 bool forceMouselook = false;
1782 1968
1783 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1969 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1784 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1970 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1785 if (part != null) 1971 if (part == null) return;
1786 { 1972
1787 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1973 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1788 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1974 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1789 1975
1790 // Is a sit target available? 1976 // part is the prim to sit on
1791 Vector3 avSitOffSet = part.SitTargetPosition; 1977 // offset is the world-ref vector distance from that prim center to the click-spot
1792 Quaternion avSitOrientation = part.SitTargetOrientation; 1978 // UUID is the UUID of the Avatar doing the clicking
1793 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1979
1794 1980 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1795 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1981
1796 bool SitTargetisSet = 1982 // Is a sit target available?
1797 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1983 Vector3 avSitOffSet = part.SitTargetPosition;
1798 ( 1984 Quaternion avSitOrientation = part.SitTargetOrientation;
1799 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1985
1800 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1986 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1801 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1987 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1802 ) 1988 Quaternion partRot;
1803 )); 1989// if (part.LinkNum == 1)
1804 1990// { // Root prim of linkset
1805 if (SitTargetisSet && SitTargetUnOccupied) 1991// partRot = part.ParentGroup.RootPart.RotationOffset;
1806 { 1992// }
1807 part.SitTargetAvatar = UUID; 1993// else
1808 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1994// { // single or child prim
1809 sitOrientation = avSitOrientation; 1995 partRot = part.GetWorldRotation();
1810 autopilot = false; 1996// }
1811 } 1997 Quaternion partIRot = Quaternion.Inverse(partRot);
1812 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 1998//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1813 1999 // Sit analysis rewritten by KF 091125
1814 pos = part.AbsolutePosition + offset; 2000 if (SitTargetisSet) // scipted sit
1815 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 2001 {
1816 //{ 2002 if (!part.IsOccupied)
1817 // offset = pos; 2003 {
1818 //autopilot = false; 2004//Console.WriteLine("Scripted, unoccupied");
1819 //} 2005 part.SitTargetAvatar = UUID; // set that Av will be on it
1820 if (m_physicsActor != null) 2006 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1821 { 2007
1822 // If we're not using the client autopilot, we're immediately warping the avatar to the location 2008 Quaternion nrot = avSitOrientation;
1823 // We can remove the physicsActor until they stand up. 2009 if (!part.IsRoot)
1824 m_sitAvatarHeight = m_physicsActor.Size.Z;
1825
1826 if (autopilot)
1827 { 2010 {
1828 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2011 nrot = part.RotationOffset * avSitOrientation;
1829 {
1830 autopilot = false;
1831
1832 RemoveFromPhysicalScene();
1833 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1834 }
1835 } 2012 }
1836 else 2013 sitOrientation = nrot; // Change rotatione to the scripted one
2014 OffsetRotation = nrot;
2015 autopilot = false; // Jump direct to scripted llSitPos()
2016 }
2017 else
2018 {
2019//Console.WriteLine("Scripted, occupied");
2020 return;
2021 }
2022 }
2023 else // Not Scripted
2024 {
2025 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
2026 {
2027 // large prim & offset, ignore if other Avs sitting
2028// offset.Z -= 0.05f;
2029 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2030 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2031
2032//Console.WriteLine(" offset ={0}", offset);
2033//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2034//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2035
2036 }
2037 else // small offset
2038 {
2039//Console.WriteLine("Small offset");
2040 if (!part.IsOccupied)
2041 {
2042 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2043 autopilotTarget = part.AbsolutePosition;
2044//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2045 }
2046 else return; // occupied small
2047 } // end large/small
2048 } // end Scripted/not
2049
2050 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2051
2052 cameraAtOffset = part.GetCameraAtOffset();
2053 cameraEyeOffset = part.GetCameraEyeOffset();
2054 forceMouselook = part.GetForceMouselook();
2055 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2056 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2057
2058 if (m_physicsActor != null)
2059 {
2060 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2061 // We can remove the physicsActor until they stand up.
2062 m_sitAvatarHeight = m_physicsActor.Size.Z;
2063 if (autopilot)
2064 { // its not a scripted sit
2065// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2066 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1837 { 2067 {
2068 autopilot = false; // close enough
2069 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2070 Not using the part's position because returning the AV to the last known standing
2071 position is likely to be more friendly, isn't it? */
1838 RemoveFromPhysicalScene(); 2072 RemoveFromPhysicalScene();
1839 } 2073 Velocity = Vector3.Zero;
2074 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2075 } // else the autopilot will get us close
2076 }
2077 else
2078 { // its a scripted sit
2079 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2080 I *am* using the part's position this time because we have no real idea how far away
2081 the avatar is from the sit target. */
2082 RemoveFromPhysicalScene();
2083 Velocity = Vector3.Zero;
1840 } 2084 }
1841
1842 cameraAtOffset = part.GetCameraAtOffset();
1843 cameraEyeOffset = part.GetCameraEyeOffset();
1844 forceMouselook = part.GetForceMouselook();
1845 } 2085 }
1846 2086 else return; // physactor is null!
1847 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2087
1848 m_requestedSitTargetUUID = targetID; 2088 Vector3 offsetr; // = offset * partIRot;
2089 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2090 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2091 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2092 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2093 //offsetr = offset * partIRot;
2094//
2095 // else
2096 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2097 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2098 // (offset * partRot);
2099 // }
2100
2101//Console.WriteLine(" ");
2102//Console.WriteLine("link number ={0}", part.LinkNum);
2103//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2104//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2105//Console.WriteLine("Click offst ={0}", offset);
2106//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2107//Console.WriteLine("offsetr ={0}", offsetr);
2108//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2109//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2110
2111 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2112 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2113
2114 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1849 // This calls HandleAgentSit twice, once from here, and the client calls 2115 // This calls HandleAgentSit twice, once from here, and the client calls
1850 // HandleAgentSit itself after it gets to the location 2116 // HandleAgentSit itself after it gets to the location
1851 // It doesn't get to the location until we've moved them there though 2117 // It doesn't get to the location until we've moved them there though
1852 // which happens in HandleAgentSit :P 2118 // which happens in HandleAgentSit :P
1853 m_autopilotMoving = autopilot; 2119 m_autopilotMoving = autopilot;
1854 m_autoPilotTarget = pos; 2120 m_autoPilotTarget = autopilotTarget;
1855 m_sitAtAutoTarget = autopilot; 2121 m_sitAtAutoTarget = autopilot;
2122 m_initialSitTarget = autopilotTarget;
1856 if (!autopilot) 2123 if (!autopilot)
1857 HandleAgentSit(remoteClient, UUID); 2124 HandleAgentSit(remoteClient, UUID);
1858 } 2125 }
@@ -2147,47 +2414,130 @@ namespace OpenSim.Region.Framework.Scenes
2147 { 2414 {
2148 if (part != null) 2415 if (part != null)
2149 { 2416 {
2417//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2150 if (part.GetAvatarOnSitTarget() == UUID) 2418 if (part.GetAvatarOnSitTarget() == UUID)
2151 { 2419 {
2420//Console.WriteLine("Scripted Sit");
2421 // Scripted sit
2152 Vector3 sitTargetPos = part.SitTargetPosition; 2422 Vector3 sitTargetPos = part.SitTargetPosition;
2153 Quaternion sitTargetOrient = part.SitTargetOrientation; 2423 Quaternion sitTargetOrient = part.SitTargetOrientation;
2154
2155 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2156 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2157
2158 //Quaternion result = (sitTargetOrient * vq) * nq;
2159
2160 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2424 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2161 m_pos += SIT_TARGET_ADJUSTMENT; 2425 m_pos += SIT_TARGET_ADJUSTMENT;
2426 if (!part.IsRoot)
2427 {
2428 m_pos *= part.RotationOffset;
2429 }
2162 m_bodyRot = sitTargetOrient; 2430 m_bodyRot = sitTargetOrient;
2163 //Rotation = sitTargetOrient;
2164 m_parentPosition = part.AbsolutePosition; 2431 m_parentPosition = part.AbsolutePosition;
2165 2432 part.IsOccupied = true;
2166 //SendTerseUpdateToAllClients(); 2433 part.ParentGroup.AddAvatar(agentID);
2167 } 2434 }
2168 else 2435 else
2169 { 2436 {
2170 m_pos -= part.AbsolutePosition; 2437 // if m_avUnscriptedSitPos is zero then Av sits above center
2438 // Else Av sits at m_avUnscriptedSitPos
2439
2440 // Non-scripted sit by Kitto Flora 21Nov09
2441 // Calculate angle of line from prim to Av
2442 Quaternion partIRot;
2443// if (part.LinkNum == 1)
2444// { // Root prim of linkset
2445// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2446// }
2447// else
2448// { // single or child prim
2449 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2450// }
2451 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2452 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2453 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2454 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2455 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2456 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2457 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2458 // Av sits at world euler <0,0, z>, translated by part rotation
2459 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2460
2171 m_parentPosition = part.AbsolutePosition; 2461 m_parentPosition = part.AbsolutePosition;
2172 } 2462 part.IsOccupied = true;
2463 part.ParentGroup.AddAvatar(agentID);
2464 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2465 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2466 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2467 m_avUnscriptedSitPos; // adds click offset, if any
2468 //Set up raytrace to find top surface of prim
2469 Vector3 size = part.Scale;
2470 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2471 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2472 Vector3 down = new Vector3(0f, 0f, -1f);
2473//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2474 m_scene.PhysicsScene.RaycastWorld(
2475 start, // Vector3 position,
2476 down, // Vector3 direction,
2477 mag, // float length,
2478 SitAltitudeCallback); // retMethod
2479 } // end scripted/not
2173 } 2480 }
2174 else 2481 else // no Av
2175 { 2482 {
2176 return; 2483 return;
2177 } 2484 }
2178 } 2485 }
2179 m_parentID = m_requestedSitTargetID;
2180 2486
2487 //We want our offsets to reference the root prim, not the child we may have sat on
2488 if (!part.IsRoot)
2489 {
2490 m_parentID = part.ParentGroup.RootPart.LocalId;
2491 m_pos += part.OffsetPosition;
2492 }
2493 else
2494 {
2495 m_parentID = m_requestedSitTargetID;
2496 }
2497
2498 m_linkedPrim = part.UUID;
2499 if (part.GetAvatarOnSitTarget() != UUID)
2500 {
2501 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2502 }
2181 Velocity = Vector3.Zero; 2503 Velocity = Vector3.Zero;
2182 RemoveFromPhysicalScene(); 2504 RemoveFromPhysicalScene();
2183
2184 Animator.TrySetMovementAnimation(sitAnimation); 2505 Animator.TrySetMovementAnimation(sitAnimation);
2185 SendAvatarDataToAllAgents(); 2506 SendAvatarDataToAllAgents();
2186 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2187 // So we're also sending a terse update (which has avatar rotation)
2188 // [Update] We do now.
2189 //SendTerseUpdateToAllClients(); 2507 //SendTerseUpdateToAllClients();
2190 } 2508 }
2509
2510 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2511 {
2512 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2513 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2514 if(hitYN)
2515 {
2516 // m_pos = Av offset from prim center to make look like on center
2517 // m_parentPosition = Actual center pos of prim
2518 // collisionPoint = spot on prim where we want to sit
2519 // collisionPoint.Z = global sit surface height
2520 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2521 Quaternion partIRot;
2522// if (part.LinkNum == 1)
2523/// { // Root prim of linkset
2524// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2525// }
2526// else
2527// { // single or child prim
2528 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2529// }
2530 if (m_initialSitTarget != null)
2531 {
2532 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2533 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2534 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2535 m_pos += offset;
2536 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2537 }
2538
2539 }
2540 } // End SitAltitudeCallback KF.
2191 2541
2192 /// <summary> 2542 /// <summary>
2193 /// Event handler for the 'Always run' setting on the client 2543 /// Event handler for the 'Always run' setting on the client
@@ -2217,12 +2567,13 @@ namespace OpenSim.Region.Framework.Scenes
2217 /// </summary> 2567 /// </summary>
2218 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2568 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2219 /// <param name="rotation">The direction in which this avatar should now face. 2569 /// <param name="rotation">The direction in which this avatar should now face.
2220 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2570 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2221 { 2571 {
2222 if (m_isChildAgent) 2572 if (m_isChildAgent)
2223 { 2573 {
2224 // WHAT??? 2574 // WHAT???
2225 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); 2575 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent");
2576
2226 return; 2577 return;
2227 } 2578 }
2228 2579
@@ -2231,15 +2582,26 @@ namespace OpenSim.Region.Framework.Scenes
2231 Rotation = rotation; 2582 Rotation = rotation;
2232 Vector3 direc = vec * rotation; 2583 Vector3 direc = vec * rotation;
2233 direc.Normalize(); 2584 direc.Normalize();
2585 PhysicsActor actor = m_physicsActor;
2586
2587 if (actor.Flying != m_flyingOld) // add for fly velocity control
2588 {
2589 m_flyingOld = actor.Flying; // add for fly velocity control
2590 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2591 }
2592
2593 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2594
2595 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2234 2596
2235 direc *= 0.03f * 128f * m_speedModifier; 2597 direc *= 0.03f * 128f * m_speedModifier;
2236 2598
2237 PhysicsActor actor = m_physicsActor;
2238 if (actor != null) 2599 if (actor != null)
2239 { 2600 {
2240 if (actor.Flying) 2601 if (actor.Flying)
2241 { 2602 {
2242 direc *= 4.0f; 2603// rm speed mod direc *= 4.0f;
2604 direc *= 5.2f; // for speed mod
2243 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2605 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2244 //bool colliding = (m_physicsActor.IsColliding==true); 2606 //bool colliding = (m_physicsActor.IsColliding==true);
2245 //if (controlland) 2607 //if (controlland)
@@ -2252,22 +2614,34 @@ namespace OpenSim.Region.Framework.Scenes
2252 // m_log.Info("[AGENT]: Stop FLying"); 2614 // m_log.Info("[AGENT]: Stop FLying");
2253 //} 2615 //}
2254 } 2616 }
2617 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2618 {
2619 direc *= 0.0f;
2620 }
2621 /* This jumping section removed to SPA
2255 else if (!actor.Flying && actor.IsColliding) 2622 else if (!actor.Flying && actor.IsColliding)
2256 { 2623 {
2257 if (direc.Z > 2.0f) 2624 if (direc.Z > 2.0f)
2258 { 2625 {
2259 direc.Z *= 3.0f; 2626 if(m_animator.m_animTickJump == -1)
2260 2627 {
2261 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2628 direc.Z *= 3.0f; // jump
2262 Animator.TrySetMovementAnimation("PREJUMP"); 2629 }
2263 Animator.TrySetMovementAnimation("JUMP"); 2630 else
2631 {
2632 direc.Z *= 0.1f; // prejump
2633 }
2634 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2635 Animator.TrySetMovementAnimation("PREJUMP");
2636 Animator.TrySetMovementAnimation("JUMP");
2637 * /
2264 } 2638 }
2265 } 2639 } */
2266 } 2640 }
2267 2641
2268 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2642 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2269 m_forceToApply = direc; 2643 m_forceToApply = direc;
2270 2644 m_isNudging = Nudging;
2271 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2645 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2272 } 2646 }
2273 2647
@@ -2316,6 +2690,9 @@ namespace OpenSim.Region.Framework.Scenes
2316 2690
2317 CheckForSignificantMovement(); // sends update to the modules. 2691 CheckForSignificantMovement(); // sends update to the modules.
2318 } 2692 }
2693
2694 //Sending prim updates AFTER the avatar terse updates are sent
2695 SendPrimUpdates();
2319 } 2696 }
2320 2697
2321 #endregion 2698 #endregion
@@ -3075,6 +3452,7 @@ namespace OpenSim.Region.Framework.Scenes
3075 m_callbackURI = cAgent.CallbackURI; 3452 m_callbackURI = cAgent.CallbackURI;
3076 3453
3077 m_pos = cAgent.Position; 3454 m_pos = cAgent.Position;
3455
3078 m_velocity = cAgent.Velocity; 3456 m_velocity = cAgent.Velocity;
3079 m_CameraCenter = cAgent.Center; 3457 m_CameraCenter = cAgent.Center;
3080 m_CameraAtAxis = cAgent.AtAxis; 3458 m_CameraAtAxis = cAgent.AtAxis;
@@ -3193,20 +3571,45 @@ namespace OpenSim.Region.Framework.Scenes
3193 /// </summary> 3571 /// </summary>
3194 public override void UpdateMovement() 3572 public override void UpdateMovement()
3195 { 3573 {
3196 if (m_forceToApply.HasValue) 3574 if (Animator!=null) // add for jumping
3197 { 3575 { // add for jumping
3198 Vector3 force = m_forceToApply.Value; 3576 // if (!m_animator.m_jumping) // add for jumping
3577 // { // add for jumping
3199 3578
3200 m_updateflag = true; 3579 if (m_forceToApply.HasValue) // this section realigned
3201 3580 {
3202 // The magic constant 0.95f seems to make walking feel less jerky,
3203 // probably because it hackishly accounts for the overall latency of
3204 // these Velocity updates -- Diva
3205 Velocity = force * .95F;
3206 3581
3207 m_forceToApply = null; 3582 Vector3 force = m_forceToApply.Value;
3208 } 3583 m_updateflag = true;
3209 } 3584if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3585 Velocity = force;
3586//Console.WriteLine("UM1 {0}", Velocity);
3587 m_forceToApply = null;
3588 }
3589 else
3590 {
3591 if (m_isNudging)
3592 {
3593 Vector3 force = Vector3.Zero;
3594
3595 m_updateflag = true;
3596if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3597 Velocity = force;
3598//Console.WriteLine("UM2 {0}", Velocity);
3599 m_isNudging = false;
3600 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3601 }
3602 else // add for jumping
3603 { // add for jumping
3604 Vector3 force = Vector3.Zero; // add for jumping
3605if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3606//Console.WriteLine("UM3 {0}", Velocity);
3607 Velocity = force; // add for jumping
3608 }
3609 }
3610 // } // end realign
3611 } // add for jumping
3612 } // add for jumping
3210 3613
3211 /// <summary> 3614 /// <summary>
3212 /// Adds a physical representation of the avatar to the Physics plugin 3615 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3220,10 +3623,8 @@ namespace OpenSim.Region.Framework.Scenes
3220 3623
3221 Vector3 pVec = AbsolutePosition; 3624 Vector3 pVec = AbsolutePosition;
3222 3625
3223 // Old bug where the height was in centimeters instead of meters
3224 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, 3626 m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,
3225 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying); 3627 new Vector3(0f, 0f, m_appearance.AvatarHeight), isFlying);
3226
3227 scene.AddPhysicsActorTaint(m_physicsActor); 3628 scene.AddPhysicsActorTaint(m_physicsActor);
3228 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; 3629 //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
3229 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; 3630 m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@@ -3247,18 +3648,29 @@ namespace OpenSim.Region.Framework.Scenes
3247 { 3648 {
3248 if (e == null) 3649 if (e == null)
3249 return; 3650 return;
3250 3651
3251 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3652 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3252 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3253 // as of this comment the interval is set in AddToPhysicalScene 3653 // as of this comment the interval is set in AddToPhysicalScene
3254 if (Animator!=null) 3654 if (Animator!=null)
3255 Animator.UpdateMovementAnimations(); 3655 {
3656 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3657 { // else its will lock out other animation changes, like ground sit.
3658 Animator.UpdateMovementAnimations();
3659 m_updateCount--;
3660 }
3661 }
3256 3662
3257 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3663 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3258 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3664 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3259 3665
3260 CollisionPlane = Vector4.UnitW; 3666 CollisionPlane = Vector4.UnitW;
3261 3667
3668 if (m_lastColCount != coldata.Count)
3669 {
3670 m_updateCount = UPDATE_COUNT;
3671 m_lastColCount = coldata.Count;
3672 }
3673
3262 if (coldata.Count != 0 && Animator != null) 3674 if (coldata.Count != 0 && Animator != null)
3263 { 3675 {
3264 switch (Animator.CurrentMovementAnimation) 3676 switch (Animator.CurrentMovementAnimation)
@@ -3288,6 +3700,148 @@ namespace OpenSim.Region.Framework.Scenes
3288 } 3700 }
3289 } 3701 }
3290 3702
3703 List<uint> thisHitColliders = new List<uint>();
3704 List<uint> endedColliders = new List<uint>();
3705 List<uint> startedColliders = new List<uint>();
3706
3707 foreach (uint localid in coldata.Keys)
3708 {
3709 thisHitColliders.Add(localid);
3710 if (!m_lastColliders.Contains(localid))
3711 {
3712 startedColliders.Add(localid);
3713 }
3714 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3715 }
3716
3717 // calculate things that ended colliding
3718 foreach (uint localID in m_lastColliders)
3719 {
3720 if (!thisHitColliders.Contains(localID))
3721 {
3722 endedColliders.Add(localID);
3723 }
3724 }
3725 //add the items that started colliding this time to the last colliders list.
3726 foreach (uint localID in startedColliders)
3727 {
3728 m_lastColliders.Add(localID);
3729 }
3730 // remove things that ended colliding from the last colliders list
3731 foreach (uint localID in endedColliders)
3732 {
3733 m_lastColliders.Remove(localID);
3734 }
3735
3736 // do event notification
3737 if (startedColliders.Count > 0)
3738 {
3739 ColliderArgs StartCollidingMessage = new ColliderArgs();
3740 List<DetectedObject> colliding = new List<DetectedObject>();
3741 foreach (uint localId in startedColliders)
3742 {
3743 if (localId == 0)
3744 continue;
3745
3746 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3747 string data = "";
3748 if (obj != null)
3749 {
3750 DetectedObject detobj = new DetectedObject();
3751 detobj.keyUUID = obj.UUID;
3752 detobj.nameStr = obj.Name;
3753 detobj.ownerUUID = obj.OwnerID;
3754 detobj.posVector = obj.AbsolutePosition;
3755 detobj.rotQuat = obj.GetWorldRotation();
3756 detobj.velVector = obj.Velocity;
3757 detobj.colliderType = 0;
3758 detobj.groupUUID = obj.GroupID;
3759 colliding.Add(detobj);
3760 }
3761 }
3762
3763 if (colliding.Count > 0)
3764 {
3765 StartCollidingMessage.Colliders = colliding;
3766
3767 foreach (SceneObjectGroup att in Attachments)
3768 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3769 }
3770 }
3771
3772 if (endedColliders.Count > 0)
3773 {
3774 ColliderArgs EndCollidingMessage = new ColliderArgs();
3775 List<DetectedObject> colliding = new List<DetectedObject>();
3776 foreach (uint localId in endedColliders)
3777 {
3778 if (localId == 0)
3779 continue;
3780
3781 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3782 string data = "";
3783 if (obj != null)
3784 {
3785 DetectedObject detobj = new DetectedObject();
3786 detobj.keyUUID = obj.UUID;
3787 detobj.nameStr = obj.Name;
3788 detobj.ownerUUID = obj.OwnerID;
3789 detobj.posVector = obj.AbsolutePosition;
3790 detobj.rotQuat = obj.GetWorldRotation();
3791 detobj.velVector = obj.Velocity;
3792 detobj.colliderType = 0;
3793 detobj.groupUUID = obj.GroupID;
3794 colliding.Add(detobj);
3795 }
3796 }
3797
3798 if (colliding.Count > 0)
3799 {
3800 EndCollidingMessage.Colliders = colliding;
3801
3802 foreach (SceneObjectGroup att in Attachments)
3803 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3804 }
3805 }
3806
3807 if (thisHitColliders.Count > 0)
3808 {
3809 ColliderArgs CollidingMessage = new ColliderArgs();
3810 List<DetectedObject> colliding = new List<DetectedObject>();
3811 foreach (uint localId in thisHitColliders)
3812 {
3813 if (localId == 0)
3814 continue;
3815
3816 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3817 string data = "";
3818 if (obj != null)
3819 {
3820 DetectedObject detobj = new DetectedObject();
3821 detobj.keyUUID = obj.UUID;
3822 detobj.nameStr = obj.Name;
3823 detobj.ownerUUID = obj.OwnerID;
3824 detobj.posVector = obj.AbsolutePosition;
3825 detobj.rotQuat = obj.GetWorldRotation();
3826 detobj.velVector = obj.Velocity;
3827 detobj.colliderType = 0;
3828 detobj.groupUUID = obj.GroupID;
3829 colliding.Add(detobj);
3830 }
3831 }
3832
3833 if (colliding.Count > 0)
3834 {
3835 CollidingMessage.Colliders = colliding;
3836
3837 lock (m_attachments)
3838 {
3839 foreach (SceneObjectGroup att in m_attachments)
3840 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3841 }
3842 }
3843 }
3844
3291 if (m_invulnerable) 3845 if (m_invulnerable)
3292 return; 3846 return;
3293 3847
@@ -3713,6 +4267,39 @@ namespace OpenSim.Region.Framework.Scenes
3713 return; 4267 return;
3714 } 4268 }
3715 4269
4270 XmlDocument doc = new XmlDocument();
4271 string stateData = String.Empty;
4272
4273 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4274 if (attServ != null)
4275 {
4276 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4277 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4278 if (stateData != String.Empty)
4279 {
4280 try
4281 {
4282 doc.LoadXml(stateData);
4283 }
4284 catch { }
4285 }
4286 }
4287
4288 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4289
4290 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4291 if (nodes.Count > 0)
4292 {
4293 foreach (XmlNode n in nodes)
4294 {
4295 XmlElement elem = (XmlElement)n;
4296 string itemID = elem.GetAttribute("ItemID");
4297 string xml = elem.InnerXml;
4298
4299 itemData[new UUID(itemID)] = xml;
4300 }
4301 }
4302
3716 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4303 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3717 foreach (AvatarAttachment attach in attachments) 4304 foreach (AvatarAttachment attach in attachments)
3718 { 4305 {
@@ -3733,7 +4320,30 @@ namespace OpenSim.Region.Framework.Scenes
3733 4320
3734 try 4321 try
3735 { 4322 {
3736 m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); 4323 string xmlData;
4324 XmlDocument d = new XmlDocument();
4325 UUID asset;
4326 if (itemData.TryGetValue(itemID, out xmlData))
4327 {
4328 d.LoadXml(xmlData);
4329 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4330
4331 // Rez from inventory
4332 asset
4333 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4334
4335 }
4336 else
4337 {
4338 // Rez from inventory (with a null doc to let
4339 // CHANGED_OWNER happen)
4340 asset
4341 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4342 }
4343
4344 m_log.InfoFormat(
4345 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4346 p, itemID, asset);
3737 } 4347 }
3738 catch (Exception e) 4348 catch (Exception e)
3739 { 4349 {
@@ -3766,6 +4376,15 @@ namespace OpenSim.Region.Framework.Scenes
3766 m_reprioritization_called = false; 4376 m_reprioritization_called = false;
3767 } 4377 }
3768 } 4378 }
4379
4380 private Vector3 Quat2Euler(Quaternion rot){
4381 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4382 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4383 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4384 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4385 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4386 return(new Vector3(x,y,z));
4387 }
3769 4388
3770 public void SaveChangedAttachments() 4389 public void SaveChangedAttachments()
3771 { 4390 {