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.cs404
1 files changed, 279 insertions, 125 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 24840d4..fbc4ed5 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -113,7 +115,9 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 115 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 116 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 117 public Vector4 CollisionPlane = Vector4.UnitW;
116 118
119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
117 private Vector3 m_lastPosition; 121 private Vector3 m_lastPosition;
118 private Quaternion m_lastRotation; 122 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 123 private Vector3 m_lastVelocity;
@@ -144,7 +148,6 @@ namespace OpenSim.Region.Framework.Scenes
144 private int m_perfMonMS; 148 private int m_perfMonMS;
145 149
146 private bool m_setAlwaysRun; 150 private bool m_setAlwaysRun;
147
148 private bool m_forceFly; 151 private bool m_forceFly;
149 private bool m_flyDisabled; 152 private bool m_flyDisabled;
150 153
@@ -168,7 +171,8 @@ namespace OpenSim.Region.Framework.Scenes
168 protected RegionInfo m_regionInfo; 171 protected RegionInfo m_regionInfo;
169 protected ulong crossingFromRegion; 172 protected ulong crossingFromRegion;
170 173
171 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 174 private readonly Vector3[] Dir_Vectors = new Vector3[11];
175 private bool m_isNudging = false;
172 176
173 // Position of agent's camera in world (region cordinates) 177 // Position of agent's camera in world (region cordinates)
174 protected Vector3 m_CameraCenter; 178 protected Vector3 m_CameraCenter;
@@ -193,6 +197,7 @@ namespace OpenSim.Region.Framework.Scenes
193 private bool m_autopilotMoving; 197 private bool m_autopilotMoving;
194 private Vector3 m_autoPilotTarget; 198 private Vector3 m_autoPilotTarget;
195 private bool m_sitAtAutoTarget; 199 private bool m_sitAtAutoTarget;
200 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
196 201
197 private string m_nextSitAnimation = String.Empty; 202 private string m_nextSitAnimation = String.Empty;
198 203
@@ -203,6 +208,9 @@ namespace OpenSim.Region.Framework.Scenes
203 private bool m_followCamAuto; 208 private bool m_followCamAuto;
204 209
205 private int m_movementUpdateCount; 210 private int m_movementUpdateCount;
211 private int m_lastColCount = -1; //KF: Look for Collision chnages
212 private int m_updateCount = 0; //KF: Update Anims for a while
213 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
206 214
207 private const int NumMovementsBetweenRayCast = 5; 215 private const int NumMovementsBetweenRayCast = 5;
208 216
@@ -232,6 +240,10 @@ namespace OpenSim.Region.Framework.Scenes
232 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 240 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
233 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 241 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
234 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 242 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
243 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
244 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
245 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
246 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
235 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 247 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
236 } 248 }
237 249
@@ -658,9 +670,7 @@ namespace OpenSim.Region.Framework.Scenes
658 670
659 AdjustKnownSeeds(); 671 AdjustKnownSeeds();
660 672
661 // TODO: I think, this won't send anything, as we are still a child here... 673 Animator.TrySetMovementAnimation("STAND");
662 Animator.TrySetMovementAnimation("STAND");
663
664 // we created a new ScenePresence (a new child agent) in a fresh region. 674 // we created a new ScenePresence (a new child agent) in a fresh region.
665 // Request info about all the (root) agents in this region 675 // Request info about all the (root) agents in this region
666 // Note: This won't send data *to* other clients in that region (children don't send) 676 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -716,21 +726,47 @@ namespace OpenSim.Region.Framework.Scenes
716 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 726 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
717 Dir_Vectors[4] = Vector3.UnitZ; //UP 727 Dir_Vectors[4] = Vector3.UnitZ; //UP
718 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 728 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
719 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 729 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
730 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
731 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
732 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
733 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
720 } 734 }
721 735
722 private Vector3[] GetWalkDirectionVectors() 736 private Vector3[] GetWalkDirectionVectors()
723 { 737 {
724 Vector3[] vector = new Vector3[6]; 738 Vector3[] vector = new Vector3[11];
725 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 739 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
726 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 740 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
727 vector[2] = Vector3.UnitY; //LEFT 741 vector[2] = Vector3.UnitY; //LEFT
728 vector[3] = -Vector3.UnitY; //RIGHT 742 vector[3] = -Vector3.UnitY; //RIGHT
729 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 743 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
730 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 744 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
731 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 745 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
746 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
747 vector[8] = Vector3.UnitY; //LEFT_NUDGE
748 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
749 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
732 return vector; 750 return vector;
733 } 751 }
752
753 private bool[] GetDirectionIsNudge()
754 {
755 bool[] isNudge = new bool[11];
756 isNudge[0] = false; //FORWARD
757 isNudge[1] = false; //BACK
758 isNudge[2] = false; //LEFT
759 isNudge[3] = false; //RIGHT
760 isNudge[4] = false; //UP
761 isNudge[5] = false; //DOWN
762 isNudge[6] = true; //FORWARD_NUDGE
763 isNudge[7] = true; //BACK_NUDGE
764 isNudge[8] = true; //LEFT_NUDGE
765 isNudge[9] = true; //RIGHT_NUDGE
766 isNudge[10] = true; //DOWN_Nudge
767 return isNudge;
768 }
769
734 770
735 #endregion 771 #endregion
736 772
@@ -994,7 +1030,9 @@ namespace OpenSim.Region.Framework.Scenes
994 { 1030 {
995 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1031 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
996 } 1032 }
997 1033
1034 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1035
998 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1036 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
999 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1037 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1000 } 1038 }
@@ -1229,7 +1267,6 @@ namespace OpenSim.Region.Framework.Scenes
1229 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1267 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1230 } 1268 }
1231 } 1269 }
1232
1233 lock (scriptedcontrols) 1270 lock (scriptedcontrols)
1234 { 1271 {
1235 if (scriptedcontrols.Count > 0) 1272 if (scriptedcontrols.Count > 0)
@@ -1244,9 +1281,7 @@ namespace OpenSim.Region.Framework.Scenes
1244 1281
1245 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1282 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1246 { 1283 {
1247 // TODO: This doesn't prevent the user from walking yet. 1284 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1248 // Setting parent ID would fix this, if we knew what value
1249 // to use. Or we could add a m_isSitting variable.
1250 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 1285 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1251 } 1286 }
1252 1287
@@ -1261,7 +1296,6 @@ namespace OpenSim.Region.Framework.Scenes
1261 { 1296 {
1262 return; 1297 return;
1263 } 1298 }
1264
1265 if (m_allowMovement) 1299 if (m_allowMovement)
1266 { 1300 {
1267 int i = 0; 1301 int i = 0;
@@ -1289,6 +1323,11 @@ namespace OpenSim.Region.Framework.Scenes
1289 update_rotation = true; 1323 update_rotation = true;
1290 } 1324 }
1291 1325
1326 //guilty until proven innocent..
1327 bool Nudging = true;
1328 //Basically, if there is at least one non-nudge control then we don't need
1329 //to worry about stopping the avatar
1330
1292 if (m_parentID == 0) 1331 if (m_parentID == 0)
1293 { 1332 {
1294 bool bAllowUpdateMoveToPosition = false; 1333 bool bAllowUpdateMoveToPosition = false;
@@ -1303,6 +1342,12 @@ namespace OpenSim.Region.Framework.Scenes
1303 else 1342 else
1304 dirVectors = Dir_Vectors; 1343 dirVectors = Dir_Vectors;
1305 1344
1345 bool[] isNudge = GetDirectionIsNudge();
1346
1347
1348
1349
1350
1306 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1351 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1307 { 1352 {
1308 if (((uint)flags & (uint)DCF) != 0) 1353 if (((uint)flags & (uint)DCF) != 0)
@@ -1312,6 +1357,10 @@ namespace OpenSim.Region.Framework.Scenes
1312 try 1357 try
1313 { 1358 {
1314 agent_control_v3 += dirVectors[i]; 1359 agent_control_v3 += dirVectors[i];
1360 if (isNudge[i] == false)
1361 {
1362 Nudging = false;
1363 }
1315 } 1364 }
1316 catch (IndexOutOfRangeException) 1365 catch (IndexOutOfRangeException)
1317 { 1366 {
@@ -1373,6 +1422,9 @@ namespace OpenSim.Region.Framework.Scenes
1373 // Ignore z component of vector 1422 // Ignore z component of vector
1374 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1423 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1375 LocalVectorToTarget2D.Normalize(); 1424 LocalVectorToTarget2D.Normalize();
1425
1426 //We're not nudging
1427 Nudging = false;
1376 agent_control_v3 += LocalVectorToTarget2D; 1428 agent_control_v3 += LocalVectorToTarget2D;
1377 1429
1378 // update avatar movement flags. the avatar coordinate system is as follows: 1430 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1455,7 +1507,7 @@ namespace OpenSim.Region.Framework.Scenes
1455 // m_log.DebugFormat( 1507 // m_log.DebugFormat(
1456 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1508 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1457 1509
1458 AddNewMovement(agent_control_v3, q); 1510 AddNewMovement(agent_control_v3, q, Nudging);
1459 1511
1460 if (update_movementflag) 1512 if (update_movementflag)
1461 Animator.UpdateMovementAnimations(); 1513 Animator.UpdateMovementAnimations();
@@ -1474,7 +1526,6 @@ namespace OpenSim.Region.Framework.Scenes
1474 m_sitAtAutoTarget = false; 1526 m_sitAtAutoTarget = false;
1475 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1527 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1476 //proxy.PCode = (byte)PCode.ParticleSystem; 1528 //proxy.PCode = (byte)PCode.ParticleSystem;
1477
1478 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1529 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1479 proxyObjectGroup.AttachToScene(m_scene); 1530 proxyObjectGroup.AttachToScene(m_scene);
1480 1531
@@ -1516,7 +1567,7 @@ namespace OpenSim.Region.Framework.Scenes
1516 } 1567 }
1517 m_moveToPositionInProgress = true; 1568 m_moveToPositionInProgress = true;
1518 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1569 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1519 } 1570 }
1520 catch (Exception ex) 1571 catch (Exception ex)
1521 { 1572 {
1522 //Why did I get this error? 1573 //Why did I get this error?
@@ -1538,7 +1589,7 @@ namespace OpenSim.Region.Framework.Scenes
1538 Velocity = Vector3.Zero; 1589 Velocity = Vector3.Zero;
1539 SendFullUpdateToAllClients(); 1590 SendFullUpdateToAllClients();
1540 1591
1541 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1592 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1542 } 1593 }
1543 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1594 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1544 m_requestedSitTargetUUID = UUID.Zero; 1595 m_requestedSitTargetUUID = UUID.Zero;
@@ -1576,38 +1627,40 @@ namespace OpenSim.Region.Framework.Scenes
1576 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1627 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1577 if (part != null) 1628 if (part != null)
1578 { 1629 {
1630 part.TaskInventory.LockItemsForRead(true);
1579 TaskInventoryDictionary taskIDict = part.TaskInventory; 1631 TaskInventoryDictionary taskIDict = part.TaskInventory;
1580 if (taskIDict != null) 1632 if (taskIDict != null)
1581 { 1633 {
1582 lock (taskIDict) 1634 foreach (UUID taskID in taskIDict.Keys)
1583 { 1635 {
1584 foreach (UUID taskID in taskIDict.Keys) 1636 UnRegisterControlEventsToScript(LocalId, taskID);
1585 { 1637 taskIDict[taskID].PermsMask &= ~(
1586 UnRegisterControlEventsToScript(LocalId, taskID); 1638 2048 | //PERMISSION_CONTROL_CAMERA
1587 taskIDict[taskID].PermsMask &= ~( 1639 4); // PERMISSION_TAKE_CONTROLS
1588 2048 | //PERMISSION_CONTROL_CAMERA
1589 4); // PERMISSION_TAKE_CONTROLS
1590 }
1591 } 1640 }
1592
1593 } 1641 }
1642 part.TaskInventory.LockItemsForRead(false);
1594 // Reset sit target. 1643 // Reset sit target.
1595 if (part.GetAvatarOnSitTarget() == UUID) 1644 if (part.GetAvatarOnSitTarget() == UUID)
1596 part.SetAvatarOnSitTarget(UUID.Zero); 1645 part.SetAvatarOnSitTarget(UUID.Zero);
1597
1598 m_parentPosition = part.GetWorldPosition(); 1646 m_parentPosition = part.GetWorldPosition();
1599 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1647 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1600 } 1648 }
1649 // part.GetWorldRotation() is the rotation of the object being sat on
1650 // Rotation is the sittiing Av's rotation
1651
1652 Quaternion wr = Quaternion.Inverse(Quaternion.Inverse(Rotation) * Quaternion.Inverse(part.GetWorldRotation())); // world or. of the av
1653 Vector3 so = new Vector3(1.0f, 0f, 0f) * wr; // 1M infront of av
1654 Vector3 wso = so + part.GetWorldPosition() + ( m_pos * part.GetWorldRotation()); // + av sit offset!
1601 1655
1602 if (m_physicsActor == null) 1656 if (m_physicsActor == null)
1603 { 1657 {
1604 AddToPhysicalScene(false); 1658 AddToPhysicalScene(false);
1605 } 1659 }
1606 1660 AbsolutePosition = wso; //KF: Fix stand up.
1607 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight);
1608 m_parentPosition = Vector3.Zero; 1661 m_parentPosition = Vector3.Zero;
1609 1662 m_parentID = 0;
1610 m_parentID = 0; 1663 part.IsOccupied = false;
1611 SendFullUpdateToAllClients(); 1664 SendFullUpdateToAllClients();
1612 m_requestedSitTargetID = 0; 1665 m_requestedSitTargetID = 0;
1613 if ((m_physicsActor != null) && (m_avHeight > 0)) 1666 if ((m_physicsActor != null) && (m_avHeight > 0))
@@ -1646,13 +1699,9 @@ namespace OpenSim.Region.Framework.Scenes
1646 Vector3 avSitOffSet = part.SitTargetPosition; 1699 Vector3 avSitOffSet = part.SitTargetPosition;
1647 Quaternion avSitOrientation = part.SitTargetOrientation; 1700 Quaternion avSitOrientation = part.SitTargetOrientation;
1648 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1701 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1649 1702 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1650 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1703 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1651 bool SitTargetisSet = 1704 if (SitTargetisSet && !SitTargetOccupied)
1652 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1653 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1654
1655 if (SitTargetisSet && SitTargetUnOccupied)
1656 { 1705 {
1657 //switch the target to this prim 1706 //switch the target to this prim
1658 return part; 1707 return part;
@@ -1666,7 +1715,7 @@ namespace OpenSim.Region.Framework.Scenes
1666 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset) 1715 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset)
1667 { 1716 {
1668 bool autopilot = true; 1717 bool autopilot = true;
1669 Vector3 pos = new Vector3(); 1718 Vector3 autopilotTarget = new Vector3();
1670 Quaternion sitOrientation = Quaternion.Identity; 1719 Quaternion sitOrientation = Quaternion.Identity;
1671 Vector3 cameraEyeOffset = Vector3.Zero; 1720 Vector3 cameraEyeOffset = Vector3.Zero;
1672 Vector3 cameraAtOffset = Vector3.Zero; 1721 Vector3 cameraAtOffset = Vector3.Zero;
@@ -1674,76 +1723,104 @@ namespace OpenSim.Region.Framework.Scenes
1674 1723
1675 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1724 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1676 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1725 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1677 if (part != null) 1726 if (part == null) return;
1678 { 1727
1679 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1728 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1680 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1729 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1681 1730
1682 // Is a sit target available? 1731 // part is the prim to sit on
1683 Vector3 avSitOffSet = part.SitTargetPosition; 1732 // offset is the world-ref vector distance from that prim center to the click-spot
1684 Quaternion avSitOrientation = part.SitTargetOrientation; 1733 // UUID is the UUID of the Avatar doing the clicking
1685 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1734
1686 1735 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1687 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1736
1688 bool SitTargetisSet = 1737 // Is a sit target available?
1689 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1738 Vector3 avSitOffSet = part.SitTargetPosition;
1690 ( 1739 Quaternion avSitOrientation = part.SitTargetOrientation;
1691 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1740
1692 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1741 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1693 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1742 Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1694 ) 1743
1695 )); 1744//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1696 1745 // Sit analysis rewritten by KF 091125
1697 if (SitTargetisSet && SitTargetUnOccupied) 1746 if (SitTargetisSet) // scipted sit
1698 { 1747 {
1699 part.SetAvatarOnSitTarget(UUID); 1748 if (!part.IsOccupied)
1700 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1749 {
1701 sitOrientation = avSitOrientation; 1750//Console.WriteLine("Scripted, unoccupied");
1702 autopilot = false; 1751 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1703 } 1752 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1704 1753 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1705 pos = part.AbsolutePosition + offset; 1754 autopilot = false; // Jump direct to scripted llSitPos()
1706 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1755 }
1707 //{ 1756 else
1708 // offset = pos; 1757 {
1709 //autopilot = false; 1758//Console.WriteLine("Scripted, occupied");
1710 //} 1759 return;
1711 if (m_physicsActor != null) 1760 }
1712 { 1761 }
1713 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1762 else // Not Scripted
1714 // We can remove the physicsActor until they stand up. 1763 {
1715 m_sitAvatarHeight = m_physicsActor.Size.Z; 1764 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1716 1765 {
1717 if (autopilot) 1766 // large prim & offset, ignore if other Avs sitting
1718 { 1767// offset.Z -= 0.05f;
1719 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1768 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1720 { 1769 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1721 autopilot = false; 1770
1771//Console.WriteLine(" offset ={0}", offset);
1772//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1773//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1774
1775 }
1776 else // small offset
1777 {
1778//Console.WriteLine("Small offset");
1779 if (!part.IsOccupied)
1780 {
1781 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1782 autopilotTarget = part.AbsolutePosition;
1783 }
1784 else return; // occupied small
1785 } // end large/small
1786 } // end Scripted/not
1787 cameraAtOffset = part.GetCameraAtOffset();
1788 cameraEyeOffset = part.GetCameraEyeOffset();
1789 forceMouselook = part.GetForceMouselook();
1722 1790
1723 RemoveFromPhysicalScene(); 1791 if (m_physicsActor != null)
1724 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1792 {
1725 } 1793 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1726 } 1794 // We can remove the physicsActor until they stand up.
1727 else 1795 m_sitAvatarHeight = m_physicsActor.Size.Z;
1796 if (autopilot)
1797 { // its not a scripted sit
1798// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1799 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1728 { 1800 {
1801 autopilot = false; // close enough
1729 RemoveFromPhysicalScene(); 1802 RemoveFromPhysicalScene();
1730 } 1803 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1804 } // else the autopilot will get us close
1805 }
1806 else
1807 { // its a scripted sit
1808 RemoveFromPhysicalScene();
1731 } 1809 }
1732
1733 cameraAtOffset = part.GetCameraAtOffset();
1734 cameraEyeOffset = part.GetCameraEyeOffset();
1735 forceMouselook = part.GetForceMouselook();
1736 } 1810 }
1811 else return; // physactor is null!
1737 1812
1738 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1813 Vector3 offsetr = offset * partIRot;
1739 m_requestedSitTargetUUID = targetID; 1814 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1815 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1740 // This calls HandleAgentSit twice, once from here, and the client calls 1816 // This calls HandleAgentSit twice, once from here, and the client calls
1741 // HandleAgentSit itself after it gets to the location 1817 // HandleAgentSit itself after it gets to the location
1742 // It doesn't get to the location until we've moved them there though 1818 // It doesn't get to the location until we've moved them there though
1743 // which happens in HandleAgentSit :P 1819 // which happens in HandleAgentSit :P
1744 m_autopilotMoving = autopilot; 1820 m_autopilotMoving = autopilot;
1745 m_autoPilotTarget = pos; 1821 m_autoPilotTarget = autopilotTarget;
1746 m_sitAtAutoTarget = autopilot; 1822 m_sitAtAutoTarget = autopilot;
1823 m_initialSitTarget = autopilotTarget;
1747 if (!autopilot) 1824 if (!autopilot)
1748 HandleAgentSit(remoteClient, UUID); 1825 HandleAgentSit(remoteClient, UUID);
1749 } 1826 }
@@ -1839,29 +1916,55 @@ namespace OpenSim.Region.Framework.Scenes
1839 { 1916 {
1840 if (part.GetAvatarOnSitTarget() == UUID) 1917 if (part.GetAvatarOnSitTarget() == UUID)
1841 { 1918 {
1919//Console.WriteLine("Scripted Sit");
1920 // Scripted sit
1842 Vector3 sitTargetPos = part.SitTargetPosition; 1921 Vector3 sitTargetPos = part.SitTargetPosition;
1843 Quaternion sitTargetOrient = part.SitTargetOrientation; 1922 Quaternion sitTargetOrient = part.SitTargetOrientation;
1844
1845 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
1846 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
1847
1848 //Quaternion result = (sitTargetOrient * vq) * nq;
1849
1850 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 1923 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
1851 m_pos += SIT_TARGET_ADJUSTMENT; 1924 m_pos += SIT_TARGET_ADJUSTMENT;
1852 m_bodyRot = sitTargetOrient; 1925 m_bodyRot = sitTargetOrient;
1853 //Rotation = sitTargetOrient;
1854 m_parentPosition = part.AbsolutePosition; 1926 m_parentPosition = part.AbsolutePosition;
1855 1927 part.IsOccupied = true;
1856 //SendTerseUpdateToAllClients();
1857 } 1928 }
1858 else 1929 else
1859 { 1930 {
1860 m_pos -= part.AbsolutePosition; 1931//Console.WriteLine("NON Scripted Sit");
1932 // if m_avUnscriptedSitPos is zero then Av sits above center
1933 // Else Av sits at m_avUnscriptedSitPos
1934
1935 // Non-scripted sit by Kitto Flora 21Nov09
1936 // Calculate angle of line from prim to Av
1937 Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1938 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
1939 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
1940 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
1941 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
1942 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
1943 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
1944 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
1945 // Av sits at world euler <0,0, z>, translated by part rotation
1946 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
1947
1861 m_parentPosition = part.AbsolutePosition; 1948 m_parentPosition = part.AbsolutePosition;
1862 } 1949 part.IsOccupied = true;
1863 } 1950 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
1864 else 1951 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
1952 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
1953 m_avUnscriptedSitPos; // adds click offset, if any
1954 //Set up raytrace to find top surface of prim
1955 Vector3 size = part.Scale;
1956 float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
1957 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
1958 Vector3 down = new Vector3(0f, 0f, -1f);
1959//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
1960 m_scene.PhysicsScene.RaycastWorld(
1961 start, // Vector3 position,
1962 down, // Vector3 direction,
1963 mag, // float length,
1964 SitAltitudeCallback); // retMethod
1965 } // end scripted/not
1966 }
1967 else // no Av
1865 { 1968 {
1866 return; 1969 return;
1867 } 1970 }
@@ -1873,11 +1976,26 @@ namespace OpenSim.Region.Framework.Scenes
1873 1976
1874 Animator.TrySetMovementAnimation(sitAnimation); 1977 Animator.TrySetMovementAnimation(sitAnimation);
1875 SendFullUpdateToAllClients(); 1978 SendFullUpdateToAllClients();
1876 // This may seem stupid, but Our Full updates don't send avatar rotation :P
1877 // So we're also sending a terse update (which has avatar rotation)
1878 // [Update] We do now.
1879 //SendTerseUpdateToAllClients();
1880 } 1979 }
1980
1981 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
1982 {
1983 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
1984 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
1985 if(hitYN)
1986 {
1987 // m_pos = Av offset from prim center to make look like on center
1988 // m_parentPosition = Actual center pos of prim
1989 // collisionPoint = spot on prim where we want to sit
1990 // collisionPoint.Z = global sit surface height
1991 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
1992 Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1993 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
1994 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
1995//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
1996 m_pos += offset;
1997 }
1998 } // End SitAltitudeCallback KF.
1881 1999
1882 /// <summary> 2000 /// <summary>
1883 /// Event handler for the 'Always run' setting on the client 2001 /// Event handler for the 'Always run' setting on the client
@@ -1907,7 +2025,7 @@ namespace OpenSim.Region.Framework.Scenes
1907 /// </summary> 2025 /// </summary>
1908 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2026 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
1909 /// <param name="rotation">The direction in which this avatar should now face. 2027 /// <param name="rotation">The direction in which this avatar should now face.
1910 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2028 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
1911 { 2029 {
1912 if (m_isChildAgent) 2030 if (m_isChildAgent)
1913 { 2031 {
@@ -1981,7 +2099,7 @@ namespace OpenSim.Region.Framework.Scenes
1981 2099
1982 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2100 // TODO: Add the force instead of only setting it to support multiple forces per frame?
1983 m_forceToApply = direc; 2101 m_forceToApply = direc;
1984 2102 m_isNudging = Nudging;
1985 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2103 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
1986 } 2104 }
1987 2105
@@ -1996,7 +2114,7 @@ namespace OpenSim.Region.Framework.Scenes
1996 const float POSITION_TOLERANCE = 0.05f; 2114 const float POSITION_TOLERANCE = 0.05f;
1997 //const int TIME_MS_TOLERANCE = 3000; 2115 //const int TIME_MS_TOLERANCE = 3000;
1998 2116
1999 SendPrimUpdates(); 2117
2000 2118
2001 if (m_newCoarseLocations) 2119 if (m_newCoarseLocations)
2002 { 2120 {
@@ -2032,6 +2150,9 @@ namespace OpenSim.Region.Framework.Scenes
2032 CheckForBorderCrossing(); 2150 CheckForBorderCrossing();
2033 CheckForSignificantMovement(); // sends update to the modules. 2151 CheckForSignificantMovement(); // sends update to the modules.
2034 } 2152 }
2153
2154 //Sending prim updates AFTER the avatar terse updates are sent
2155 SendPrimUpdates();
2035 } 2156 }
2036 2157
2037 #endregion 2158 #endregion
@@ -2885,14 +3006,25 @@ namespace OpenSim.Region.Framework.Scenes
2885 { 3006 {
2886 if (m_forceToApply.HasValue) 3007 if (m_forceToApply.HasValue)
2887 { 3008 {
2888 Vector3 force = m_forceToApply.Value;
2889 3009
3010 Vector3 force = m_forceToApply.Value;
2890 m_updateflag = true; 3011 m_updateflag = true;
2891// movementvector = force;
2892 Velocity = force; 3012 Velocity = force;
2893 3013
2894 m_forceToApply = null; 3014 m_forceToApply = null;
2895 } 3015 }
3016 else
3017 {
3018 if (m_isNudging)
3019 {
3020 Vector3 force = Vector3.Zero;
3021
3022 m_updateflag = true;
3023 Velocity = force;
3024 m_isNudging = false;
3025 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3026 }
3027 }
2896 } 3028 }
2897 3029
2898 public override void SetText(string text, Vector3 color, double alpha) 3030 public override void SetText(string text, Vector3 color, double alpha)
@@ -2942,10 +3074,15 @@ namespace OpenSim.Region.Framework.Scenes
2942 // Event called by the physics plugin to tell the avatar about a collision. 3074 // Event called by the physics plugin to tell the avatar about a collision.
2943 private void PhysicsCollisionUpdate(EventArgs e) 3075 private void PhysicsCollisionUpdate(EventArgs e)
2944 { 3076 {
3077 if (m_updateCount > 0) //KF: Update Anims for a short period. Many Anim
3078 { // changes are very asynchronous.
3079 Animator.UpdateMovementAnimations();
3080 m_updateCount--;
3081 }
3082
2945 if (e == null) 3083 if (e == null)
2946 return; 3084 return;
2947 3085
2948 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
2949 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( 3086 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
2950 // as of this comment the interval is set in AddToPhysicalScene 3087 // as of this comment the interval is set in AddToPhysicalScene
2951 if (Animator!=null) 3088 if (Animator!=null)
@@ -2956,6 +3093,12 @@ namespace OpenSim.Region.Framework.Scenes
2956 3093
2957 CollisionPlane = Vector4.UnitW; 3094 CollisionPlane = Vector4.UnitW;
2958 3095
3096 if (m_lastColCount != coldata.Count)
3097 {
3098 m_updateCount = 10;
3099 m_lastColCount = coldata.Count;
3100 }
3101
2959 if (coldata.Count != 0 && Animator != null) 3102 if (coldata.Count != 0 && Animator != null)
2960 { 3103 {
2961 switch (Animator.CurrentMovementAnimation) 3104 switch (Animator.CurrentMovementAnimation)
@@ -3603,5 +3746,16 @@ namespace OpenSim.Region.Framework.Scenes
3603 m_reprioritization_called = false; 3746 m_reprioritization_called = false;
3604 } 3747 }
3605 } 3748 }
3749
3750 private Vector3 Quat2Euler(Quaternion rot){
3751 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
3752 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
3753 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
3754 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
3755 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
3756 return(new Vector3(x,y,z));
3757 }
3758
3759
3606 } 3760 }
3607} \ No newline at end of file 3761}