aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs442
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs176
2 files changed, 370 insertions, 248 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fe2dfef..087697f 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -164,7 +164,11 @@ namespace OpenSim.Region.Framework.Scenes
164 164
165 private uint m_requestedSitTargetID; 165 private uint m_requestedSitTargetID;
166 private UUID m_requestedSitTargetUUID; 166 private UUID m_requestedSitTargetUUID;
167 public bool SitGround = false; 167
168 /// <summary>
169 /// Are we sitting on the ground?
170 /// </summary>
171 public bool SitGround { get; private set; }
168 172
169 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 173 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
170 174
@@ -189,20 +193,12 @@ namespace OpenSim.Region.Framework.Scenes
189 193
190 private readonly Vector3[] Dir_Vectors = new Vector3[11]; 194 private readonly Vector3[] Dir_Vectors = new Vector3[11];
191 195
192
193 protected Timer m_reprioritization_timer; 196 protected Timer m_reprioritization_timer;
194 protected bool m_reprioritizing; 197 protected bool m_reprioritizing;
195 protected bool m_reprioritization_called; 198 protected bool m_reprioritization_called;
196 199
197 private Quaternion m_headrotation = Quaternion.Identity; 200 private Quaternion m_headrotation = Quaternion.Identity;
198 201
199 //Reuse the Vector3 instead of creating a new one on the UpdateMovement method
200// private Vector3 movementvector;
201
202 private bool m_autopilotMoving;
203 private Vector3 m_autoPilotTarget;
204 private bool m_sitAtAutoTarget;
205
206 private string m_nextSitAnimation = String.Empty; 202 private string m_nextSitAnimation = String.Empty;
207 203
208 //PauPaw:Proper PID Controler for autopilot************ 204 //PauPaw:Proper PID Controler for autopilot************
@@ -1422,20 +1418,8 @@ namespace OpenSim.Region.Framework.Scenes
1422 } 1418 }
1423 } 1419 }
1424 1420
1425 if (m_autopilotMoving)
1426 CheckAtSitTarget();
1427
1428 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1421 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1429 { 1422 HandleAgentSitOnGround();
1430 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1431 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1432
1433 // TODO: This doesn't prevent the user from walking yet.
1434 // Setting parent ID would fix this, if we knew what value
1435 // to use. Or we could add a m_isSitting variable.
1436 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1437 SitGround = true;
1438 }
1439 1423
1440 // In the future, these values might need to go global. 1424 // In the future, these values might need to go global.
1441 // Here's where you get them. 1425 // Here's where you get them.
@@ -1641,111 +1625,109 @@ namespace OpenSim.Region.Framework.Scenes
1641// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1625// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1642// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1626// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1643 1627
1644 if (!m_autopilotMoving) 1628 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1645 { 1629
1646 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1647// m_log.DebugFormat( 1630// m_log.DebugFormat(
1648// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1631// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1649// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1632// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1650 1633
1651 // Check the error term of the current position in relation to the target position 1634 // Check the error term of the current position in relation to the target position
1652 if (distanceToTarget <= 1) 1635 if (distanceToTarget <= 1)
1653 { 1636 {
1654 // We are close enough to the target 1637 // We are close enough to the target
1655 AbsolutePosition = MoveToPositionTarget; 1638 AbsolutePosition = MoveToPositionTarget;
1656 ResetMoveToTarget(); 1639 ResetMoveToTarget();
1657 updated = true; 1640 updated = true;
1658 } 1641 }
1659 else 1642 else
1643 {
1644 try
1660 { 1645 {
1661 try 1646 // move avatar in 3D at one meter/second towards target, in avatar coordinate frame.
1662 { 1647 // This movement vector gets added to the velocity through AddNewMovement().
1663 // move avatar in 3D at one meter/second towards target, in avatar coordinate frame. 1648 // Theoretically we might need a more complex PID approach here if other
1664 // This movement vector gets added to the velocity through AddNewMovement(). 1649 // unknown forces are acting on the avatar and we need to adaptively respond
1665 // Theoretically we might need a more complex PID approach here if other 1650 // to such forces, but the following simple approach seems to works fine.
1666 // unknown forces are acting on the avatar and we need to adaptively respond 1651 Vector3 LocalVectorToTarget3D =
1667 // to such forces, but the following simple approach seems to works fine. 1652 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1668 Vector3 LocalVectorToTarget3D = 1653 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1669 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1654 // Ignore z component of vector
1670 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1671 // Ignore z component of vector
1672// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1655// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1673 LocalVectorToTarget3D.Normalize(); 1656 LocalVectorToTarget3D.Normalize();
1674 1657
1675 // update avatar movement flags. the avatar coordinate system is as follows: 1658 // update avatar movement flags. the avatar coordinate system is as follows:
1676 // 1659 //
1677 // +X (forward) 1660 // +X (forward)
1678 // 1661 //
1679 // ^ 1662 // ^
1680 // | 1663 // |
1681 // | 1664 // |
1682 // | 1665 // |
1683 // | 1666 // |
1684 // (left) +Y <--------o--------> -Y 1667 // (left) +Y <--------o--------> -Y
1685 // avatar 1668 // avatar
1686 // | 1669 // |
1687 // | 1670 // |
1688 // | 1671 // |
1689 // | 1672 // |
1690 // v 1673 // v
1691 // -X 1674 // -X
1692 // 1675 //
1693 1676
1694 // based on the above avatar coordinate system, classify the movement into 1677 // based on the above avatar coordinate system, classify the movement into
1695 // one of left/right/back/forward. 1678 // one of left/right/back/forward.
1696 if (LocalVectorToTarget3D.X < 0) //MoveBack 1679 if (LocalVectorToTarget3D.X < 0) //MoveBack
1697 { 1680 {
1698 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; 1681 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1699 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; 1682 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1700 updated = true; 1683 updated = true;
1701 } 1684 }
1702 else if (LocalVectorToTarget3D.X > 0) //Move Forward 1685 else if (LocalVectorToTarget3D.X > 0) //Move Forward
1703 { 1686 {
1704 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; 1687 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1705 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; 1688 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1706 updated = true; 1689 updated = true;
1707 } 1690 }
1708 1691
1709 if (LocalVectorToTarget3D.Y > 0) //MoveLeft 1692 if (LocalVectorToTarget3D.Y > 0) //MoveLeft
1710 { 1693 {
1711 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; 1694 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1712 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; 1695 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1713 updated = true; 1696 updated = true;
1714 } 1697 }
1715 else if (LocalVectorToTarget3D.Y < 0) //MoveRight 1698 else if (LocalVectorToTarget3D.Y < 0) //MoveRight
1716 { 1699 {
1717 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; 1700 MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1718 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; 1701 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1719 updated = true; 1702 updated = true;
1720 } 1703 }
1721 1704
1722 if (LocalVectorToTarget3D.Z > 0) //Up 1705 if (LocalVectorToTarget3D.Z > 0) //Up
1723 { 1706 {
1724 // Don't set these flags for up or down - doing so will make the avatar crouch or 1707 // Don't set these flags for up or down - doing so will make the avatar crouch or
1725 // keep trying to jump even if walking along level ground 1708 // keep trying to jump even if walking along level ground
1726 //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; 1709 //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
1727 //AgentControlFlags 1710 //AgentControlFlags
1728 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; 1711 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
1729 updated = true; 1712 updated = true;
1730 } 1713 }
1731 else if (LocalVectorToTarget3D.Z < 0) //Down 1714 else if (LocalVectorToTarget3D.Z < 0) //Down
1732 { 1715 {
1733 //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; 1716 //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
1734 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; 1717 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
1735 updated = true; 1718 updated = true;
1736 } 1719 }
1737 1720
1738// m_log.DebugFormat( 1721// m_log.DebugFormat(
1739// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1722// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1740// LocalVectorToTarget3D, agent_control_v3, Name); 1723// LocalVectorToTarget3D, agent_control_v3, Name);
1741 1724
1742 agent_control_v3 += LocalVectorToTarget3D; 1725 agent_control_v3 += LocalVectorToTarget3D;
1743 } 1726 }
1744 catch (Exception e) 1727 catch (Exception e)
1745 { 1728 {
1746 //Avoid system crash, can be slower but... 1729 //Avoid system crash, can be slower but...
1747 m_log.DebugFormat("Crash! {0}", e.ToString()); 1730 m_log.DebugFormat("Crash! {0}", e.ToString());
1748 }
1749 } 1731 }
1750 } 1732 }
1751 1733
@@ -1847,58 +1829,20 @@ namespace OpenSim.Region.Framework.Scenes
1847 AgentControlFlags = (uint)AgentManager.ControlFlags.NONE; 1829 AgentControlFlags = (uint)AgentManager.ControlFlags.NONE;
1848 } 1830 }
1849 1831
1850 private void CheckAtSitTarget()
1851 {
1852 //m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString());
1853 if (Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget) <= 1.5)
1854 {
1855 if (m_sitAtAutoTarget)
1856 {
1857 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetUUID);
1858 if (part != null)
1859 {
1860 AbsolutePosition = part.AbsolutePosition;
1861 Velocity = Vector3.Zero;
1862 SendAvatarDataToAllAgents();
1863
1864 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID);
1865 }
1866 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1867 m_requestedSitTargetUUID = UUID.Zero;
1868 }
1869 /*
1870 else
1871 {
1872 //ControllingClient.SendAlertMessage("Autopilot cancelled");
1873 //SendTerseUpdateToAllClients();
1874 //PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1875 //proxy.PCode = (byte)PCode.ParticleSystem;
1876 ////uint nextUUID = m_scene.NextLocalId;
1877
1878 //proxyObjectGroup = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, UUID, nextUUID, m_autoPilotTarget, Quaternion.Identity, proxy);
1879 //if (proxyObjectGroup != null)
1880 //{
1881 //proxyObjectGroup.SendGroupFullUpdate();
1882 //ControllingClient.SendSitResponse(UUID.Zero, m_autoPilotTarget, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false);
1883 //m_scene.DeleteSceneObject(proxyObjectGroup);
1884 //}
1885 }
1886 */
1887 m_autoPilotTarget = Vector3.Zero;
1888 m_autopilotMoving = false;
1889 }
1890 }
1891 /// <summary> 1832 /// <summary>
1892 /// Perform the logic necessary to stand the avatar up. This method also executes 1833 /// Perform the logic necessary to stand the avatar up. This method also executes
1893 /// the stand animation. 1834 /// the stand animation.
1894 /// </summary> 1835 /// </summary>
1895 public void StandUp() 1836 public void StandUp()
1896 { 1837 {
1838// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
1839
1897 SitGround = false; 1840 SitGround = false;
1841 if (PhysicsActor == null)
1842 AddToPhysicalScene(false);
1898 1843
1899 if (ParentID != 0) 1844 if (ParentID != 0)
1900 { 1845 {
1901 m_log.Debug("StandupCode Executed");
1902 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 1846 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
1903 if (part != null) 1847 if (part != null)
1904 { 1848 {
@@ -1926,11 +1870,6 @@ namespace OpenSim.Region.Framework.Scenes
1926 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1870 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1927 } 1871 }
1928 1872
1929 if (PhysicsActor == null)
1930 {
1931 AddToPhysicalScene(false);
1932 }
1933
1934 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 1873 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
1935 ParentPosition = Vector3.Zero; 1874 ParentPosition = Vector3.Zero;
1936 1875
@@ -1987,9 +1926,8 @@ namespace OpenSim.Region.Framework.Scenes
1987 return targetPart; 1926 return targetPart;
1988 } 1927 }
1989 1928
1990 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1929 private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1991 { 1930 {
1992 bool autopilot = true;
1993 Vector3 pos = new Vector3(); 1931 Vector3 pos = new Vector3();
1994 Quaternion sitOrientation = pSitOrientation; 1932 Quaternion sitOrientation = pSitOrientation;
1995 Vector3 cameraEyeOffset = Vector3.Zero; 1933 Vector3 cameraEyeOffset = Vector3.Zero;
@@ -1997,89 +1935,87 @@ namespace OpenSim.Region.Framework.Scenes
1997 bool forceMouselook = false; 1935 bool forceMouselook = false;
1998 1936
1999 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1937 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2000 if (part != null) 1938 if (part == null)
2001 { 1939 return;
2002 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2003 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2004 1940
2005 // Is a sit target available? 1941 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2006 Vector3 avSitOffSet = part.SitTargetPosition; 1942 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2007 Quaternion avSitOrientation = part.SitTargetOrientation;
2008 UUID avOnTargetAlready = part.SitTargetAvatar;
2009 1943
2010 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1944 // Is a sit target available?
2011 bool SitTargetisSet = 1945 Vector3 avSitOffSet = part.SitTargetPosition;
2012 (!(avSitOffSet == Vector3.Zero && 1946 Quaternion avSitOrientation = part.SitTargetOrientation;
2013 ( 1947 UUID avOnTargetAlready = part.SitTargetAvatar;
2014 avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion 1948
2015 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1949 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
2016 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1950 bool SitTargetisSet =
2017 ) 1951 (!(avSitOffSet == Vector3.Zero &&
2018 )); 1952 (
1953 avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
1954 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1955 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1956 )
1957 ));
2019 1958
2020// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied); 1959// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
2021 1960
2022 if (SitTargetisSet && SitTargetUnOccupied) 1961 if (PhysicsActor != null)
1962 m_sitAvatarHeight = m_physicsActor.Size.Z;
1963
1964 bool canSit = false;
1965 pos = part.AbsolutePosition + offset;
1966
1967 if (SitTargetisSet)
1968 {
1969 if (SitTargetUnOccupied)
2023 { 1970 {
1971 m_log.DebugFormat(
1972 "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
1973 Name, part.Name, part.LocalId);
1974
2024 part.SitTargetAvatar = UUID; 1975 part.SitTargetAvatar = UUID;
2025 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1976 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
2026 sitOrientation = avSitOrientation; 1977 sitOrientation = avSitOrientation;
2027 autopilot = false; 1978 canSit = true;
2028 } 1979 }
2029 pos = part.AbsolutePosition + offset; 1980 }
2030 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1981 else
2031 //{ 1982 {
2032 // offset = pos; 1983 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2033 //autopilot = false;
2034 //}
2035 if (PhysicsActor != null)
2036 { 1984 {
2037 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1985 m_log.DebugFormat(
2038 // We can remove the physicsActor until they stand up. 1986 "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2039 m_sitAvatarHeight = PhysicsActor.Size.Z; 1987 Name, part.Name, part.LocalId);
2040 1988
2041 if (autopilot) 1989 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2042 { 1990 canSit = true;
2043 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1991 }
2044 { 1992 }
2045 autopilot = false;
2046 1993
2047 RemoveFromPhysicalScene(); 1994 if (canSit)
2048 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1995 {
2049 } 1996 if (PhysicsActor != null)
2050 } 1997 {
2051 else 1998 // We can remove the physicsActor until they stand up.
2052 { 1999 RemoveFromPhysicalScene();
2053 RemoveFromPhysicalScene();
2054 }
2055 } 2000 }
2056 2001
2057 cameraAtOffset = part.GetCameraAtOffset(); 2002 cameraAtOffset = part.GetCameraAtOffset();
2058 cameraEyeOffset = part.GetCameraEyeOffset(); 2003 cameraEyeOffset = part.GetCameraEyeOffset();
2059 forceMouselook = part.GetForceMouselook(); 2004 forceMouselook = part.GetForceMouselook();
2060 }
2061 2005
2062 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2006 ControllingClient.SendSitResponse(
2063 m_requestedSitTargetUUID = targetID; 2007 targetID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2064 2008
2065 // This calls HandleAgentSit twice, once from here, and the client calls 2009 m_requestedSitTargetUUID = targetID;
2066 // HandleAgentSit itself after it gets to the location
2067 // It doesn't get to the location until we've moved them there though
2068 // which happens in HandleAgentSit :P
2069 m_autopilotMoving = autopilot;
2070 m_autoPilotTarget = pos;
2071 m_sitAtAutoTarget = autopilot;
2072 if (!autopilot)
2073 HandleAgentSit(remoteClient, UUID);
2074 2010
2075 // Moved here to avoid a race with default sit anim 2011 HandleAgentSit(ControllingClient, UUID);
2076 // The script event needs to be raised after the default sit anim is set.
2077 if (part != null)
2078 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2079 2012
2013 // Moved here to avoid a race with default sit anim
2014 // The script event needs to be raised after the default sit anim is set.
2015 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2016 }
2080 } 2017 }
2081 2018
2082 // public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
2083 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2019 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2084 { 2020 {
2085 if (ParentID != 0) 2021 if (ParentID != 0)
@@ -2105,11 +2041,11 @@ namespace OpenSim.Region.Framework.Scenes
2105 { 2041 {
2106 m_nextSitAnimation = part.SitAnimation; 2042 m_nextSitAnimation = part.SitAnimation;
2107 } 2043 }
2044
2108 m_requestedSitTargetID = part.LocalId; 2045 m_requestedSitTargetID = part.LocalId;
2109 //m_requestedSitOffset = offset;
2110 m_requestedSitTargetUUID = targetID; 2046 m_requestedSitTargetUUID = targetID;
2111 2047
2112 m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); 2048// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2113 2049
2114 if (m_scene.PhysicsScene.SupportsRayCast()) 2050 if (m_scene.PhysicsScene.SupportsRayCast())
2115 { 2051 {
@@ -2123,7 +2059,7 @@ namespace OpenSim.Region.Framework.Scenes
2123 m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); 2059 m_log.Warn("Sit requested on unknown object: " + targetID.ToString());
2124 } 2060 }
2125 2061
2126 SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); 2062 SendSitResponse(targetID, offset, Quaternion.Identity);
2127 } 2063 }
2128 2064
2129 /* 2065 /*
@@ -2334,45 +2270,42 @@ namespace OpenSim.Region.Framework.Scenes
2334 { 2270 {
2335 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); 2271 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
2336 2272
2337 if (m_sitAtAutoTarget || !m_autopilotMoving) 2273 if (part != null)
2338 { 2274 {
2339 if (part != null) 2275 if (part.SitTargetAvatar == UUID)
2340 { 2276 {
2341 if (part.SitTargetAvatar == UUID) 2277 Vector3 sitTargetPos = part.SitTargetPosition;
2342 { 2278 Quaternion sitTargetOrient = part.SitTargetOrientation;
2343 Vector3 sitTargetPos = part.SitTargetPosition;
2344 Quaternion sitTargetOrient = part.SitTargetOrientation;
2345 2279
2346// m_log.DebugFormat( 2280// m_log.DebugFormat(
2347// "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}", 2281// "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}",
2348// Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId); 2282// Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId);
2349 2283
2350 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0); 2284 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2351 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w); 2285 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2352 2286
2353 //Quaternion result = (sitTargetOrient * vq) * nq; 2287 //Quaternion result = (sitTargetOrient * vq) * nq;
2354 2288
2355 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2289 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT;
2356 Rotation = sitTargetOrient; 2290 Rotation = sitTargetOrient;
2357 ParentPosition = part.AbsolutePosition; 2291 ParentPosition = part.AbsolutePosition;
2358 part.ParentGroup.AddAvatar(UUID); 2292 part.ParentGroup.AddAvatar(UUID);
2359 } 2293 }
2360 else 2294 else
2361 { 2295 {
2362 m_pos -= part.AbsolutePosition; 2296 m_pos -= part.AbsolutePosition;
2363 ParentPosition = part.AbsolutePosition; 2297 ParentPosition = part.AbsolutePosition;
2364 part.ParentGroup.AddAvatar(UUID); 2298 part.ParentGroup.AddAvatar(UUID);
2365 2299
2366// m_log.DebugFormat( 2300// m_log.DebugFormat(
2367// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2301// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
2368// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); 2302// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
2369 }
2370 }
2371 else
2372 {
2373 return;
2374 } 2303 }
2375 } 2304 }
2305 else
2306 {
2307 return;
2308 }
2376 2309
2377 ParentID = m_requestedSitTargetID; 2310 ParentID = m_requestedSitTargetID;
2378 2311
@@ -2383,6 +2316,19 @@ namespace OpenSim.Region.Framework.Scenes
2383 SendAvatarDataToAllAgents(); 2316 SendAvatarDataToAllAgents();
2384 } 2317 }
2385 2318
2319 public void HandleAgentSitOnGround()
2320 {
2321 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
2322 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
2323
2324 // TODO: This doesn't prevent the user from walking yet.
2325 // Setting parent ID would fix this, if we knew what value
2326 // to use. Or we could add a m_isSitting variable.
2327 //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
2328 SitGround = true;
2329 RemoveFromPhysicalScene();
2330 }
2331
2386 /// <summary> 2332 /// <summary>
2387 /// Event handler for the 'Always run' setting on the client 2333 /// Event handler for the 'Always run' setting on the client
2388 /// Tells the physics plugin to increase speed of movement. 2334 /// Tells the physics plugin to increase speed of movement.
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
new file mode 100644
index 0000000..b7b8db4
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
@@ -0,0 +1,176 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using Nini.Config;
31using NUnit.Framework;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications;
35using OpenSim.Framework.Servers;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
38using OpenSim.Tests.Common;
39using OpenSim.Tests.Common.Mock;
40using System.Threading;
41
42namespace OpenSim.Region.Framework.Scenes.Tests
43{
44 [TestFixture]
45 public class ScenePresenceSitTests
46 {
47 private TestScene m_scene;
48 private ScenePresence m_sp;
49
50 [SetUp]
51 public void Init()
52 {
53 m_scene = SceneHelpers.SetupScene();
54 m_sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
55 }
56
57 [Test]
58 public void TestSitOutsideRangeNoTarget()
59 {
60 TestHelpers.InMethod();
61// log4net.Config.XmlConfigurator.Configure();
62
63 // More than 10 meters away from 0, 0, 0 (default part position)
64 Vector3 startPos = new Vector3(10.1f, 0, 0);
65 m_sp.AbsolutePosition = startPos;
66
67 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
68
69 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
70
71 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
72 Assert.That(m_sp.ParentID, Is.EqualTo(0));
73 }
74
75 [Test]
76 public void TestSitWithinRangeNoTarget()
77 {
78 TestHelpers.InMethod();
79// log4net.Config.XmlConfigurator.Configure();
80
81 // Less than 10 meters away from 0, 0, 0 (default part position)
82 Vector3 startPos = new Vector3(9.9f, 0, 0);
83 m_sp.AbsolutePosition = startPos;
84
85 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
86
87 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
88
89 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
90 Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
91 }
92
93 [Test]
94 public void TestSitAndStandWithNoSitTarget()
95 {
96 TestHelpers.InMethod();
97// log4net.Config.XmlConfigurator.Configure();
98
99 // Make sure we're within range to sit
100 Vector3 startPos = new Vector3(1, 1, 1);
101 m_sp.AbsolutePosition = startPos;
102
103 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
104
105 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
106
107 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
108 Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
109 Assert.That(m_sp.PhysicsActor, Is.Null);
110
111 // FIXME: This is different for live avatars - z position is adjusted. This is half the height of the
112 // default avatar.
113 // Curiously, Vector3.ToString() will not display the last two places of the float. For example,
114 // printing out npc.AbsolutePosition will give <0, 0, 0.8454993> not <0, 0, 0.845499337>
115 Assert.That(
116 m_sp.AbsolutePosition,
117 Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, 0.845499337f)));
118
119 m_sp.StandUp();
120
121 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
122 Assert.That(m_sp.ParentID, Is.EqualTo(0));
123 Assert.That(m_sp.PhysicsActor, Is.Not.Null);
124 }
125
126 [Test]
127 public void TestSitAndStandWithSitTarget()
128 {
129 TestHelpers.InMethod();
130// log4net.Config.XmlConfigurator.Configure();
131
132 // If a prim has a sit target then we can sit from any distance away
133 Vector3 startPos = new Vector3(128, 128, 30);
134 m_sp.AbsolutePosition = startPos;
135
136 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
137 part.SitTargetPosition = new Vector3(0, 0, 1);
138
139 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
140
141 Assert.That(part.SitTargetAvatar, Is.EqualTo(m_sp.UUID));
142 Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
143 Assert.That(
144 m_sp.AbsolutePosition,
145 Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT));
146 Assert.That(m_sp.PhysicsActor, Is.Null);
147
148 m_sp.StandUp();
149
150 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
151 Assert.That(m_sp.ParentID, Is.EqualTo(0));
152 Assert.That(m_sp.PhysicsActor, Is.Not.Null);
153 }
154
155 [Test]
156 public void TestSitAndStandOnGround()
157 {
158 TestHelpers.InMethod();
159// log4net.Config.XmlConfigurator.Configure();
160
161 // If a prim has a sit target then we can sit from any distance away
162// Vector3 startPos = new Vector3(128, 128, 30);
163// sp.AbsolutePosition = startPos;
164
165 m_sp.HandleAgentSitOnGround();
166
167 Assert.That(m_sp.SitGround, Is.True);
168 Assert.That(m_sp.PhysicsActor, Is.Null);
169
170 m_sp.StandUp();
171
172 Assert.That(m_sp.SitGround, Is.False);
173 Assert.That(m_sp.PhysicsActor, Is.Not.Null);
174 }
175 }
176} \ No newline at end of file