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.cs278
1 files changed, 188 insertions, 90 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index e827229..7ae9be5 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -351,15 +351,12 @@ namespace OpenSim.Region.Framework.Scenes
351 /// <summary> 351 /// <summary>
352 /// Record user movement inputs. 352 /// Record user movement inputs.
353 /// </summary> 353 /// </summary>
354 public byte MovementFlag { get; private set; } 354 public uint MovementFlag { get; private set; }
355 355
356 private bool m_updateflag; 356 /// <summary>
357 357 /// Is the agent stop control flag currently active?
358 public bool Updated 358 /// </summary>
359 { 359 public bool AgentControlStopActive { get; private set; }
360 set { m_updateflag = value; }
361 get { return m_updateflag; }
362 }
363 360
364 private bool m_invulnerable = true; 361 private bool m_invulnerable = true;
365 362
@@ -480,8 +477,6 @@ namespace OpenSim.Region.Framework.Scenes
480 get { return (IClientCore)ControllingClient; } 477 get { return (IClientCore)ControllingClient; }
481 } 478 }
482 479
483 public Vector3 ParentPosition { get; set; }
484
485 /// <summary> 480 /// <summary>
486 /// Position of this avatar relative to the region the avatar is in 481 /// Position of this avatar relative to the region the avatar is in
487 /// </summary> 482 /// </summary>
@@ -499,6 +494,7 @@ namespace OpenSim.Region.Framework.Scenes
499 } 494 }
500 else 495 else
501 { 496 {
497// m_log.DebugFormat("[SCENE PRESENCE]: Fetching abs pos where PhysicsActor == null and parent part {0} for {1}", Name, Scene.Name);
502 // Obtain the correct position of a seated avatar. 498 // Obtain the correct position of a seated avatar.
503 // In addition to providing the correct position while 499 // In addition to providing the correct position while
504 // the avatar is seated, this value will also 500 // the avatar is seated, this value will also
@@ -522,7 +518,7 @@ namespace OpenSim.Region.Framework.Scenes
522 } 518 }
523 set 519 set
524 { 520 {
525// m_log.DebugFormat("[SCENE PRESENCE]: Setting position of {0} in {1} to {2}", Name, Scene.Name, value); 521// m_log.DebugFormat("[SCENE PRESENCE]: Setting position of {0} to {1} in {2}", Name, value, Scene.Name);
526// Util.PrintCallStack(); 522// Util.PrintCallStack();
527 523
528 if (PhysicsActor != null) 524 if (PhysicsActor != null)
@@ -539,10 +535,7 @@ namespace OpenSim.Region.Framework.Scenes
539 535
540 // Don't update while sitting. The PhysicsActor above is null whilst sitting. 536 // Don't update while sitting. The PhysicsActor above is null whilst sitting.
541 if (ParentID == 0) 537 if (ParentID == 0)
542 {
543 m_pos = value; 538 m_pos = value;
544 ParentPosition = Vector3.Zero;
545 }
546 539
547 //m_log.DebugFormat( 540 //m_log.DebugFormat(
548 // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 541 // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
@@ -769,6 +762,14 @@ namespace OpenSim.Region.Framework.Scenes
769 set { m_speedModifier = value; } 762 set { m_speedModifier = value; }
770 } 763 }
771 764
765 /// <summary>
766 /// Modifier for agent movement if we get an AGENT_CONTROL_STOP whilst walking or running
767 /// </summary>
768 /// <remarks>
769 /// AGENT_CONTRL_STOP comes about if user holds down space key on viewers.
770 /// </remarks>
771 private float AgentControlStopSlowWhilstMoving = 0.5f;
772
772 private bool m_forceFly; 773 private bool m_forceFly;
773 774
774 public bool ForceFly 775 public bool ForceFly
@@ -1635,7 +1636,6 @@ namespace OpenSim.Region.Framework.Scenes
1635 if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None) 1636 if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None)
1636 ControllingClient.SendAgentTerseUpdate(this); 1637 ControllingClient.SendAgentTerseUpdate(this);
1637 1638
1638
1639 PhysicsActor actor = PhysicsActor; 1639 PhysicsActor actor = PhysicsActor;
1640 if (actor == null) 1640 if (actor == null)
1641 { 1641 {
@@ -1696,10 +1696,7 @@ namespace OpenSim.Region.Framework.Scenes
1696 else 1696 else
1697 dirVectors = Dir_Vectors; 1697 dirVectors = Dir_Vectors;
1698 1698
1699 // The fact that MovementFlag is a byte needs to be fixed
1700 // it really should be a uint
1701 // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction. 1699 // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
1702 uint nudgehack = 250;
1703 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1700 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1704 { 1701 {
1705 if (((uint)flags & (uint)DCF) != 0) 1702 if (((uint)flags & (uint)DCF) != 0)
@@ -1716,29 +1713,19 @@ namespace OpenSim.Region.Framework.Scenes
1716 // Why did I get this? 1713 // Why did I get this?
1717 } 1714 }
1718 1715
1719 if ((MovementFlag & (byte)(uint)DCF) == 0) 1716 if (((MovementFlag & (uint)DCF) == 0) & !AgentControlStopActive)
1720 { 1717 {
1721 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE ||
1722 DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT_NUDGE)
1723 {
1724 MovementFlag |= (byte)nudgehack;
1725 }
1726
1727 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); 1718 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
1728 MovementFlag += (byte)(uint)DCF; 1719 MovementFlag += (uint)DCF;
1729 update_movementflag = true; 1720 update_movementflag = true;
1730 } 1721 }
1731 } 1722 }
1732 else 1723 else
1733 { 1724 {
1734 if ((MovementFlag & (byte)(uint)DCF) != 0 || 1725 if ((MovementFlag & (uint)DCF) != 0)
1735 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE ||
1736 DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT_NUDGE)
1737 && ((MovementFlag & (byte)nudgehack) == nudgehack))
1738 ) // This or is for Nudge forward
1739 { 1726 {
1740 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1727 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
1741 MovementFlag -= ((byte)(uint)DCF); 1728 MovementFlag -= (uint)DCF;
1742 update_movementflag = true; 1729 update_movementflag = true;
1743 1730
1744 /* 1731 /*
@@ -1758,6 +1745,13 @@ namespace OpenSim.Region.Framework.Scenes
1758 i++; 1745 i++;
1759 } 1746 }
1760 1747
1748 // Detect AGENT_CONTROL_STOP state changes
1749 if (AgentControlStopActive != ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STOP) != 0))
1750 {
1751 AgentControlStopActive = !AgentControlStopActive;
1752 update_movementflag = true;
1753 }
1754
1761 if (MovingToTarget) 1755 if (MovingToTarget)
1762 { 1756 {
1763 // If the user has pressed a key then we want to cancel any move to target. 1757 // If the user has pressed a key then we want to cancel any move to target.
@@ -1783,53 +1777,79 @@ namespace OpenSim.Region.Framework.Scenes
1783 // Only do this if we're flying 1777 // Only do this if we're flying
1784 if (Flying && !ForceFly) 1778 if (Flying && !ForceFly)
1785 { 1779 {
1786 // Landing detection code 1780 // Need to stop in mid air if user holds down AGENT_CONTROL_STOP
1787 1781 if (AgentControlStopActive)
1788 // Are the landing controls requirements filled?
1789 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
1790 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
1791
1792 //m_log.Debug("[CONTROL]: " +flags);
1793 // Applies a satisfying roll effect to the avatar when flying.
1794 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
1795 {
1796 ApplyFlyingRoll(
1797 FLY_ROLL_RADIANS_PER_UPDATE,
1798 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
1799 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
1800 }
1801 else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 &&
1802 (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
1803 { 1782 {
1804 ApplyFlyingRoll( 1783 agent_control_v3 = Vector3.Zero;
1805 -FLY_ROLL_RADIANS_PER_UPDATE,
1806 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
1807 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
1808 } 1784 }
1809 else 1785 else
1810 { 1786 {
1811 if (m_AngularVelocity.Z != 0) 1787 // Landing detection code
1812 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
1813 }
1814 1788
1815 if (Flying && IsColliding && controlland) 1789 // Are the landing controls requirements filled?
1816 { 1790 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
1817 // nesting this check because LengthSquared() is expensive and we don't 1791 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
1818 // want to do it every step when flying. 1792
1819 if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) 1793 //m_log.Debug("[CONTROL]: " +flags);
1820 StopFlying(); 1794 // Applies a satisfying roll effect to the avatar when flying.
1795 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
1796 {
1797 ApplyFlyingRoll(
1798 FLY_ROLL_RADIANS_PER_UPDATE,
1799 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
1800 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
1801 }
1802 else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 &&
1803 (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
1804 {
1805 ApplyFlyingRoll(
1806 -FLY_ROLL_RADIANS_PER_UPDATE,
1807 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
1808 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
1809 }
1810 else
1811 {
1812 if (m_AngularVelocity.Z != 0)
1813 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
1814 }
1815
1816 if (Flying && IsColliding && controlland)
1817 {
1818 // nesting this check because LengthSquared() is expensive and we don't
1819 // want to do it every step when flying.
1820 if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX))
1821 StopFlying();
1822 }
1821 } 1823 }
1822 } 1824 }
1823 1825
1826// m_log.DebugFormat("[SCENE PRESENCE]: MovementFlag {0} for {1}", MovementFlag, Name);
1827
1824 // If the agent update does move the avatar, then calculate the force ready for the velocity update, 1828 // If the agent update does move the avatar, then calculate the force ready for the velocity update,
1825 // which occurs later in the main scene loop 1829 // which occurs later in the main scene loop
1826 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1830 // We also need to update if the user rotates their avatar whilst it is slow walking/running (if they
1831 // held down AGENT_CONTROL_STOP whilst normal walking/running). However, we do not want to update
1832 // if the user rotated whilst holding down AGENT_CONTROL_STOP when already still (which locks the
1833 // avatar location in place).
1834 if (update_movementflag
1835 || (update_rotation && DCFlagKeyPressed && (!AgentControlStopActive || MovementFlag != 0)))
1827 { 1836 {
1828// m_log.DebugFormat( 1837// if (update_movementflag || !AgentControlStopActive || MovementFlag != 0)
1829// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1838// {
1830// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1839// m_log.DebugFormat(
1840// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, mf = {4}, ur = {5}",
1841// m_scene.RegionInfo.RegionName, agent_control_v3, Name,
1842// update_movementflag, MovementFlag, update_rotation);
1843
1844 float speedModifier;
1831 1845
1832 AddNewMovement(agent_control_v3); 1846 if (AgentControlStopActive)
1847 speedModifier = AgentControlStopSlowWhilstMoving;
1848 else
1849 speedModifier = 1;
1850
1851 AddNewMovement(agent_control_v3, speedModifier);
1852// }
1833 } 1853 }
1834// else 1854// else
1835// { 1855// {
@@ -1842,7 +1862,10 @@ namespace OpenSim.Region.Framework.Scenes
1842// } 1862// }
1843 1863
1844 if (update_movementflag && ParentID == 0) 1864 if (update_movementflag && ParentID == 0)
1865 {
1866// m_log.DebugFormat("[SCENE PRESENCE]: Updating movement animations for {0}", Name);
1845 Animator.UpdateMovementAnimations(); 1867 Animator.UpdateMovementAnimations();
1868 }
1846 1869
1847 SendControlsToScripts(flagsForScripts); 1870 SendControlsToScripts(flagsForScripts);
1848 } 1871 }
@@ -2170,13 +2193,12 @@ namespace OpenSim.Region.Framework.Scenes
2170 { 2193 {
2171// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); 2194// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
2172 2195
2196 bool satOnObject = IsSatOnObject;
2197 SceneObjectPart part = ParentPart;
2173 SitGround = false; 2198 SitGround = false;
2174 if (PhysicsActor == null)
2175 AddToPhysicalScene(false);
2176 2199
2177 if (ParentID != 0) 2200 if (satOnObject)
2178 { 2201 {
2179 SceneObjectPart part = ParentPart;
2180 TaskInventoryDictionary taskIDict = part.TaskInventory; 2202 TaskInventoryDictionary taskIDict = part.TaskInventory;
2181 if (taskIDict != null) 2203 if (taskIDict != null)
2182 { 2204 {
@@ -2192,21 +2214,64 @@ namespace OpenSim.Region.Framework.Scenes
2192 } 2214 }
2193 } 2215 }
2194 2216
2195 ParentPosition = part.GetWorldPosition(); 2217 Vector3 sitPartWorldPosition = part.GetWorldPosition();
2196 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2218 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
2197 2219
2198 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2199 ParentPosition = Vector3.Zero;
2200
2201 ParentID = 0; 2220 ParentID = 0;
2202 ParentPart = null; 2221 ParentPart = null;
2222
2223 Quaternion standRotation;
2224
2225 if (part.SitTargetAvatar == UUID)
2226 {
2227 standRotation = part.GetWorldRotation();
2228
2229 if (!part.IsRoot)
2230 standRotation = standRotation * part.SitTargetOrientation;
2231// standRotation = part.RotationOffset * part.SitTargetOrientation;
2232// else
2233// standRotation = part.SitTargetOrientation;
2234
2235 }
2236 else
2237 {
2238 standRotation = Rotation;
2239 }
2240
2241 //Vector3 standPos = ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
2242 //Vector3 standPos = ParentPosition;
2243
2244// Vector3 standPositionAdjustment
2245// = part.SitTargetPosition + new Vector3(0.5f, 0f, m_sitAvatarHeight / 2f);
2246 Vector3 adjustmentForSitPosition = part.SitTargetPosition * part.GetWorldRotation();
2247
2248 // XXX: This is based on the physics capsule sizes. Need to find a better way to read this rather than
2249 // hardcoding here.
2250 Vector3 adjustmentForSitPose = new Vector3(0.74f, 0f, 0f) * standRotation;
2251
2252 Vector3 standPos = sitPartWorldPosition + adjustmentForSitPosition + adjustmentForSitPose;
2253
2254// m_log.DebugFormat(
2255// "[SCENE PRESENCE]: Setting stand to pos {0}, (adjustmentForSitPosition {1}, adjustmentForSitPose {2}) rotation {3} for {4} in {5}",
2256// standPos, adjustmentForSitPosition, adjustmentForSitPose, standRotation, Name, Scene.Name);
2257
2258 Rotation = standRotation;
2259 AbsolutePosition = standPos;
2260 }
2261
2262 // We need to wait until we have calculated proper stand positions before sitting up the physical
2263 // avatar to avoid race conditions.
2264 if (PhysicsActor == null)
2265 AddToPhysicalScene(false);
2266
2267 if (satOnObject)
2268 {
2203 SendAvatarDataToAllAgents(); 2269 SendAvatarDataToAllAgents();
2204 m_requestedSitTargetID = 0; 2270 m_requestedSitTargetID = 0;
2205 2271
2206 part.RemoveSittingAvatar(UUID); 2272 part.RemoveSittingAvatar(UUID);
2207 2273
2208 if (part != null) 2274 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2209 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2210 } 2275 }
2211 2276
2212 Animator.TrySetMovementAnimation("STAND"); 2277 Animator.TrySetMovementAnimation("STAND");
@@ -2264,7 +2329,6 @@ namespace OpenSim.Region.Framework.Scenes
2264 m_sitAvatarHeight = PhysicsActor.Size.Z; 2329 m_sitAvatarHeight = PhysicsActor.Size.Z;
2265 2330
2266 bool canSit = false; 2331 bool canSit = false;
2267 Vector3 pos = part.AbsolutePosition + offset;
2268 2332
2269 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) 2333 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
2270 { 2334 {
@@ -2274,10 +2338,23 @@ namespace OpenSim.Region.Framework.Scenes
2274 2338
2275 offset = part.SitTargetPosition; 2339 offset = part.SitTargetPosition;
2276 sitOrientation = part.SitTargetOrientation; 2340 sitOrientation = part.SitTargetOrientation;
2341
2342 if (!part.IsRoot)
2343 {
2344 // m_log.DebugFormat("Old sit orient {0}", sitOrientation);
2345 sitOrientation = part.RotationOffset * sitOrientation;
2346 // m_log.DebugFormat("New sit orient {0}", sitOrientation);
2347// m_log.DebugFormat("Old sit offset {0}", offset);
2348 offset = offset * part.RotationOffset;
2349// m_log.DebugFormat("New sit offset {0}", offset);
2350 }
2351
2277 canSit = true; 2352 canSit = true;
2278 } 2353 }
2279 else 2354 else
2280 { 2355 {
2356 Vector3 pos = part.AbsolutePosition + offset;
2357
2281 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2358 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2282 { 2359 {
2283// m_log.DebugFormat( 2360// m_log.DebugFormat(
@@ -2309,8 +2386,12 @@ namespace OpenSim.Region.Framework.Scenes
2309 cameraEyeOffset = part.GetCameraEyeOffset(); 2386 cameraEyeOffset = part.GetCameraEyeOffset();
2310 forceMouselook = part.GetForceMouselook(); 2387 forceMouselook = part.GetForceMouselook();
2311 2388
2389 // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is
2390 // being sat upon.
2391 offset += part.OffsetPosition;
2392
2312 ControllingClient.SendSitResponse( 2393 ControllingClient.SendSitResponse(
2313 part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 2394 part.ParentGroup.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2314 2395
2315 m_requestedSitTargetUUID = part.UUID; 2396 m_requestedSitTargetUUID = part.UUID;
2316 2397
@@ -2583,14 +2664,29 @@ namespace OpenSim.Region.Framework.Scenes
2583 2664
2584 //Quaternion result = (sitTargetOrient * vq) * nq; 2665 //Quaternion result = (sitTargetOrient * vq) * nq;
2585 2666
2586 m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; 2667 Vector3 newPos = sitTargetPos + SIT_TARGET_ADJUSTMENT;
2587 Rotation = sitTargetOrient; 2668 Quaternion newRot;
2588 ParentPosition = part.AbsolutePosition; 2669
2670 if (part.IsRoot)
2671 {
2672 newRot = sitTargetOrient;
2673 }
2674 else
2675 {
2676 newPos = newPos * part.RotationOffset;
2677 newRot = part.RotationOffset * sitTargetOrient;
2678 }
2679
2680 newPos += part.OffsetPosition;
2681
2682 m_pos = newPos;
2683 Rotation = newRot;
2589 } 2684 }
2590 else 2685 else
2591 { 2686 {
2592 m_pos -= part.AbsolutePosition; 2687 // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is
2593 ParentPosition = part.AbsolutePosition; 2688 // being sat upon.
2689 m_pos -= part.GroupPosition;
2594 2690
2595// m_log.DebugFormat( 2691// m_log.DebugFormat(
2596// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2692// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
@@ -2652,10 +2748,13 @@ namespace OpenSim.Region.Framework.Scenes
2652 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2748 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2653 /// </summary> 2749 /// </summary>
2654 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2750 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2655 public void AddNewMovement(Vector3 vec) 2751 /// <param name="thisAddSpeedModifier">
2752 /// Optional additional speed modifier for this particular add. Default is 1</param>
2753 public void AddNewMovement(Vector3 vec, float thisAddSpeedModifier = 1)
2656 { 2754 {
2657// m_log.DebugFormat( 2755// m_log.DebugFormat(
2658// "[SCENE PRESENCE]: Adding new movement {0} with rotation {1} for {2}", vec, Rotation, Name); 2756// "[SCENE PRESENCE]: Adding new movement {0} with rotation {1}, thisAddSpeedModifier {2} for {3}",
2757// vec, Rotation, thisAddSpeedModifier, Name);
2659 2758
2660 Vector3 direc = vec * Rotation; 2759 Vector3 direc = vec * Rotation;
2661 direc.Normalize(); 2760 direc.Normalize();
@@ -2673,7 +2772,7 @@ namespace OpenSim.Region.Framework.Scenes
2673 if ((vec.Z == 0f) && !Flying) 2772 if ((vec.Z == 0f) && !Flying)
2674 direc.Z = 0f; // Prevent camera WASD up. 2773 direc.Z = 0f; // Prevent camera WASD up.
2675 2774
2676 direc *= 0.03f * 128f * SpeedModifier; 2775 direc *= 0.03f * 128f * SpeedModifier * thisAddSpeedModifier;
2677 2776
2678// m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name); 2777// m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name);
2679 2778
@@ -2822,6 +2921,7 @@ namespace OpenSim.Region.Framework.Scenes
2822 lastTerseUpdateToAllClientsTick = currentTick; 2921 lastTerseUpdateToAllClientsTick = currentTick;
2823 lastPositionSentToAllClients = OffsetPosition; 2922 lastPositionSentToAllClients = OffsetPosition;
2824 2923
2924// Console.WriteLine("Scheduled update for {0} in {1}", Name, Scene.Name);
2825 m_scene.ForEachClient(SendTerseUpdateToClient); 2925 m_scene.ForEachClient(SendTerseUpdateToClient);
2826 } 2926 }
2827 TriggerScenePresenceUpdated(); 2927 TriggerScenePresenceUpdated();
@@ -3616,8 +3716,6 @@ namespace OpenSim.Region.Framework.Scenes
3616 { 3716 {
3617 Vector3 force = m_forceToApply.Value; 3717 Vector3 force = m_forceToApply.Value;
3618 3718
3619 Updated = true;
3620
3621 Velocity = force; 3719 Velocity = force;
3622 3720
3623 m_forceToApply = null; 3721 m_forceToApply = null;