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.cs514
1 files changed, 379 insertions, 135 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 289ba47..a3ad7ca 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,8 +115,11 @@ 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
117 private Vector3 m_lastPosition; 119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
121 private Vector3 m_lastPosition;
122 private Vector3 m_lastWorldPosition;
118 private Quaternion m_lastRotation; 123 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 124 private Vector3 m_lastVelocity;
120 //private int m_lastTerseSent; 125 //private int m_lastTerseSent;
@@ -145,7 +150,6 @@ namespace OpenSim.Region.Framework.Scenes
145 private int m_perfMonMS; 150 private int m_perfMonMS;
146 151
147 private bool m_setAlwaysRun; 152 private bool m_setAlwaysRun;
148
149 private bool m_forceFly; 153 private bool m_forceFly;
150 private bool m_flyDisabled; 154 private bool m_flyDisabled;
151 155
@@ -169,7 +173,8 @@ namespace OpenSim.Region.Framework.Scenes
169 protected RegionInfo m_regionInfo; 173 protected RegionInfo m_regionInfo;
170 protected ulong crossingFromRegion; 174 protected ulong crossingFromRegion;
171 175
172 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 176 private readonly Vector3[] Dir_Vectors = new Vector3[11];
177 private bool m_isNudging = false;
173 178
174 // Position of agent's camera in world (region cordinates) 179 // Position of agent's camera in world (region cordinates)
175 protected Vector3 m_CameraCenter; 180 protected Vector3 m_CameraCenter;
@@ -194,6 +199,7 @@ namespace OpenSim.Region.Framework.Scenes
194 private bool m_autopilotMoving; 199 private bool m_autopilotMoving;
195 private Vector3 m_autoPilotTarget; 200 private Vector3 m_autoPilotTarget;
196 private bool m_sitAtAutoTarget; 201 private bool m_sitAtAutoTarget;
202 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
197 203
198 private string m_nextSitAnimation = String.Empty; 204 private string m_nextSitAnimation = String.Empty;
199 205
@@ -204,6 +210,9 @@ namespace OpenSim.Region.Framework.Scenes
204 private bool m_followCamAuto; 210 private bool m_followCamAuto;
205 211
206 private int m_movementUpdateCount; 212 private int m_movementUpdateCount;
213 private int m_lastColCount = -1; //KF: Look for Collision chnages
214 private int m_updateCount = 0; //KF: Update Anims for a while
215 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
207 216
208 private const int NumMovementsBetweenRayCast = 5; 217 private const int NumMovementsBetweenRayCast = 5;
209 218
@@ -233,6 +242,10 @@ namespace OpenSim.Region.Framework.Scenes
233 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 242 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
234 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
235 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
246 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
247 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
248 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
236 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
237 } 250 }
238 251
@@ -658,10 +671,7 @@ namespace OpenSim.Region.Framework.Scenes
658 671
659 672
660 AdjustKnownSeeds(); 673 AdjustKnownSeeds();
661
662 // TODO: I think, this won't send anything, as we are still a child here...
663 Animator.TrySetMovementAnimation("STAND"); 674 Animator.TrySetMovementAnimation("STAND");
664
665 // we created a new ScenePresence (a new child agent) in a fresh region. 675 // we created a new ScenePresence (a new child agent) in a fresh region.
666 // Request info about all the (root) agents in this region 676 // Request info about all the (root) agents in this region
667 // Note: This won't send data *to* other clients in that region (children don't send) 677 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -717,21 +727,47 @@ namespace OpenSim.Region.Framework.Scenes
717 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 727 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
718 Dir_Vectors[4] = Vector3.UnitZ; //UP 728 Dir_Vectors[4] = Vector3.UnitZ; //UP
719 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 729 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
720 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 730 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
731 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
732 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
733 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
734 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
721 } 735 }
722 736
723 private Vector3[] GetWalkDirectionVectors() 737 private Vector3[] GetWalkDirectionVectors()
724 { 738 {
725 Vector3[] vector = new Vector3[6]; 739 Vector3[] vector = new Vector3[11];
726 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 740 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
727 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 741 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
728 vector[2] = Vector3.UnitY; //LEFT 742 vector[2] = Vector3.UnitY; //LEFT
729 vector[3] = -Vector3.UnitY; //RIGHT 743 vector[3] = -Vector3.UnitY; //RIGHT
730 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 744 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
731 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 745 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
732 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 746 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
747 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
748 vector[8] = Vector3.UnitY; //LEFT_NUDGE
749 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
750 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
733 return vector; 751 return vector;
734 } 752 }
753
754 private bool[] GetDirectionIsNudge()
755 {
756 bool[] isNudge = new bool[11];
757 isNudge[0] = false; //FORWARD
758 isNudge[1] = false; //BACK
759 isNudge[2] = false; //LEFT
760 isNudge[3] = false; //RIGHT
761 isNudge[4] = false; //UP
762 isNudge[5] = false; //DOWN
763 isNudge[6] = true; //FORWARD_NUDGE
764 isNudge[7] = true; //BACK_NUDGE
765 isNudge[8] = true; //LEFT_NUDGE
766 isNudge[9] = true; //RIGHT_NUDGE
767 isNudge[10] = true; //DOWN_Nudge
768 return isNudge;
769 }
770
735 771
736 #endregion 772 #endregion
737 773
@@ -995,7 +1031,9 @@ namespace OpenSim.Region.Framework.Scenes
995 { 1031 {
996 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1032 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
997 } 1033 }
998 1034
1035 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1036
999 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1037 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1000 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1038 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1001 } 1039 }
@@ -1230,7 +1268,6 @@ namespace OpenSim.Region.Framework.Scenes
1230 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1268 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1231 } 1269 }
1232 } 1270 }
1233
1234 lock (scriptedcontrols) 1271 lock (scriptedcontrols)
1235 { 1272 {
1236 if (scriptedcontrols.Count > 0) 1273 if (scriptedcontrols.Count > 0)
@@ -1245,9 +1282,7 @@ namespace OpenSim.Region.Framework.Scenes
1245 1282
1246 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1283 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1247 { 1284 {
1248 // TODO: This doesn't prevent the user from walking yet. 1285 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1249 // Setting parent ID would fix this, if we knew what value
1250 // to use. Or we could add a m_isSitting variable.
1251 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 1286 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1252 } 1287 }
1253 1288
@@ -1292,6 +1327,11 @@ namespace OpenSim.Region.Framework.Scenes
1292 update_rotation = true; 1327 update_rotation = true;
1293 } 1328 }
1294 1329
1330 //guilty until proven innocent..
1331 bool Nudging = true;
1332 //Basically, if there is at least one non-nudge control then we don't need
1333 //to worry about stopping the avatar
1334
1295 if (m_parentID == 0) 1335 if (m_parentID == 0)
1296 { 1336 {
1297 bool bAllowUpdateMoveToPosition = false; 1337 bool bAllowUpdateMoveToPosition = false;
@@ -1306,6 +1346,12 @@ namespace OpenSim.Region.Framework.Scenes
1306 else 1346 else
1307 dirVectors = Dir_Vectors; 1347 dirVectors = Dir_Vectors;
1308 1348
1349 bool[] isNudge = GetDirectionIsNudge();
1350
1351
1352
1353
1354
1309 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1355 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1310 { 1356 {
1311 if (((uint)flags & (uint)DCF) != 0) 1357 if (((uint)flags & (uint)DCF) != 0)
@@ -1315,6 +1361,10 @@ namespace OpenSim.Region.Framework.Scenes
1315 try 1361 try
1316 { 1362 {
1317 agent_control_v3 += dirVectors[i]; 1363 agent_control_v3 += dirVectors[i];
1364 if (isNudge[i] == false)
1365 {
1366 Nudging = false;
1367 }
1318 } 1368 }
1319 catch (IndexOutOfRangeException) 1369 catch (IndexOutOfRangeException)
1320 { 1370 {
@@ -1376,6 +1426,9 @@ namespace OpenSim.Region.Framework.Scenes
1376 // Ignore z component of vector 1426 // Ignore z component of vector
1377 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1427 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1378 LocalVectorToTarget2D.Normalize(); 1428 LocalVectorToTarget2D.Normalize();
1429
1430 //We're not nudging
1431 Nudging = false;
1379 agent_control_v3 += LocalVectorToTarget2D; 1432 agent_control_v3 += LocalVectorToTarget2D;
1380 1433
1381 // update avatar movement flags. the avatar coordinate system is as follows: 1434 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1464,7 +1517,7 @@ namespace OpenSim.Region.Framework.Scenes
1464 // m_log.DebugFormat( 1517 // m_log.DebugFormat(
1465 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1518 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1466 1519
1467 AddNewMovement(agent_control_v3, q); 1520 AddNewMovement(agent_control_v3, q, Nudging);
1468 1521
1469 1522
1470 } 1523 }
@@ -1485,7 +1538,6 @@ namespace OpenSim.Region.Framework.Scenes
1485 m_sitAtAutoTarget = false; 1538 m_sitAtAutoTarget = false;
1486 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1539 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1487 //proxy.PCode = (byte)PCode.ParticleSystem; 1540 //proxy.PCode = (byte)PCode.ParticleSystem;
1488
1489 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1541 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1490 proxyObjectGroup.AttachToScene(m_scene); 1542 proxyObjectGroup.AttachToScene(m_scene);
1491 1543
@@ -1527,7 +1579,7 @@ namespace OpenSim.Region.Framework.Scenes
1527 } 1579 }
1528 m_moveToPositionInProgress = true; 1580 m_moveToPositionInProgress = true;
1529 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1581 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1530 } 1582 }
1531 catch (Exception ex) 1583 catch (Exception ex)
1532 { 1584 {
1533 //Why did I get this error? 1585 //Why did I get this error?
@@ -1549,7 +1601,7 @@ namespace OpenSim.Region.Framework.Scenes
1549 Velocity = Vector3.Zero; 1601 Velocity = Vector3.Zero;
1550 SendFullUpdateToAllClients(); 1602 SendFullUpdateToAllClients();
1551 1603
1552 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1604 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1553 } 1605 }
1554 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1606 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1555 m_requestedSitTargetUUID = UUID.Zero; 1607 m_requestedSitTargetUUID = UUID.Zero;
@@ -1587,46 +1639,79 @@ namespace OpenSim.Region.Framework.Scenes
1587 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1639 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1588 if (part != null) 1640 if (part != null)
1589 { 1641 {
1642 part.TaskInventory.LockItemsForRead(true);
1590 TaskInventoryDictionary taskIDict = part.TaskInventory; 1643 TaskInventoryDictionary taskIDict = part.TaskInventory;
1591 if (taskIDict != null) 1644 if (taskIDict != null)
1592 { 1645 {
1593 lock (taskIDict) 1646 foreach (UUID taskID in taskIDict.Keys)
1594 { 1647 {
1595 foreach (UUID taskID in taskIDict.Keys) 1648 UnRegisterControlEventsToScript(LocalId, taskID);
1596 { 1649 taskIDict[taskID].PermsMask &= ~(
1597 UnRegisterControlEventsToScript(LocalId, taskID); 1650 2048 | //PERMISSION_CONTROL_CAMERA
1598 taskIDict[taskID].PermsMask &= ~( 1651 4); // PERMISSION_TAKE_CONTROLS
1599 2048 | //PERMISSION_CONTROL_CAMERA
1600 4); // PERMISSION_TAKE_CONTROLS
1601 }
1602 } 1652 }
1603
1604 } 1653 }
1654 part.TaskInventory.LockItemsForRead(false);
1605 // Reset sit target. 1655 // Reset sit target.
1606 if (part.GetAvatarOnSitTarget() == UUID) 1656 if (part.GetAvatarOnSitTarget() == UUID)
1607 part.SetAvatarOnSitTarget(UUID.Zero); 1657 part.SetAvatarOnSitTarget(UUID.Zero);
1608
1609 m_parentPosition = part.GetWorldPosition(); 1658 m_parentPosition = part.GetWorldPosition();
1610 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1659 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1611 } 1660 }
1612 1661 // part.GetWorldRotation() is the rotation of the object being sat on
1613 if (m_physicsActor == null) 1662 // Rotation is the sittiing Av's rotation
1614 { 1663
1615 AddToPhysicalScene(false); 1664 Quaternion partRot;
1665// if (part.LinkNum == 1)
1666// { // Root prim of linkset
1667// partRot = part.ParentGroup.RootPart.RotationOffset;
1668// }
1669// else
1670// { // single or child prim
1671
1672// }
1673 if (part == null) //CW: Part may be gone. llDie() for example.
1674 {
1675 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1676 }
1677 else
1678 {
1679 partRot = part.GetWorldRotation();
1680 }
1681
1682 Quaternion partIRot = Quaternion.Inverse(partRot);
1683
1684 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1685 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1686
1687
1688 if (m_physicsActor == null)
1689 {
1690 AddToPhysicalScene(false);
1691 }
1692 //CW: If the part isn't null then we can set the current position
1693 if (part != null)
1694 {
1695 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1696 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1697 part.IsOccupied = false;
1698 }
1699 else
1700 {
1701 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1702 AbsolutePosition = m_lastWorldPosition;
1616 } 1703 }
1617 1704
1618 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1705 m_parentPosition = Vector3.Zero;
1619 m_parentPosition = Vector3.Zero; 1706 m_parentID = 0;
1620
1621 m_parentID = 0;
1622 SendFullUpdateToAllClients(); 1707 SendFullUpdateToAllClients();
1623 m_requestedSitTargetID = 0; 1708 m_requestedSitTargetID = 0;
1709
1624 if ((m_physicsActor != null) && (m_avHeight > 0)) 1710 if ((m_physicsActor != null) && (m_avHeight > 0))
1625 { 1711 {
1626 SetHeight(m_avHeight); 1712 SetHeight(m_avHeight);
1627 } 1713 }
1628 } 1714 }
1629
1630 Animator.TrySetMovementAnimation("STAND"); 1715 Animator.TrySetMovementAnimation("STAND");
1631 } 1716 }
1632 1717
@@ -1657,13 +1742,9 @@ namespace OpenSim.Region.Framework.Scenes
1657 Vector3 avSitOffSet = part.SitTargetPosition; 1742 Vector3 avSitOffSet = part.SitTargetPosition;
1658 Quaternion avSitOrientation = part.SitTargetOrientation; 1743 Quaternion avSitOrientation = part.SitTargetOrientation;
1659 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1744 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1660 1745 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1661 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1746 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1662 bool SitTargetisSet = 1747 if (SitTargetisSet && !SitTargetOccupied)
1663 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1664 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1665
1666 if (SitTargetisSet && SitTargetUnOccupied)
1667 { 1748 {
1668 //switch the target to this prim 1749 //switch the target to this prim
1669 return part; 1750 return part;
@@ -1677,84 +1758,152 @@ namespace OpenSim.Region.Framework.Scenes
1677 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1758 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1678 { 1759 {
1679 bool autopilot = true; 1760 bool autopilot = true;
1761 Vector3 autopilotTarget = new Vector3();
1762 Quaternion sitOrientation = Quaternion.Identity;
1680 Vector3 pos = new Vector3(); 1763 Vector3 pos = new Vector3();
1681 Quaternion sitOrientation = pSitOrientation;
1682 Vector3 cameraEyeOffset = Vector3.Zero; 1764 Vector3 cameraEyeOffset = Vector3.Zero;
1683 Vector3 cameraAtOffset = Vector3.Zero; 1765 Vector3 cameraAtOffset = Vector3.Zero;
1684 bool forceMouselook = false; 1766 bool forceMouselook = false;
1685 1767
1686 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1768 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1687 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1769 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1688 if (part != null) 1770 if (part == null) return;
1689 { 1771
1690 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1772 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1691 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1773 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1692 1774
1693 // Is a sit target available? 1775 // part is the prim to sit on
1694 Vector3 avSitOffSet = part.SitTargetPosition; 1776 // offset is the world-ref vector distance from that prim center to the click-spot
1695 Quaternion avSitOrientation = part.SitTargetOrientation; 1777 // UUID is the UUID of the Avatar doing the clicking
1696 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1778
1697 1779 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1698 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1780
1699 bool SitTargetisSet = 1781 // Is a sit target available?
1700 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1782 Vector3 avSitOffSet = part.SitTargetPosition;
1701 ( 1783 Quaternion avSitOrientation = part.SitTargetOrientation;
1702 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1784
1703 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1785 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1704 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1786 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1705 ) 1787 Quaternion partRot;
1706 )); 1788// if (part.LinkNum == 1)
1707 1789// { // Root prim of linkset
1708 if (SitTargetisSet && SitTargetUnOccupied) 1790// partRot = part.ParentGroup.RootPart.RotationOffset;
1709 { 1791// }
1710 part.SetAvatarOnSitTarget(UUID); 1792// else
1711 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1793// { // single or child prim
1712 sitOrientation = avSitOrientation; 1794 partRot = part.GetWorldRotation();
1713 autopilot = false; 1795// }
1714 } 1796 Quaternion partIRot = Quaternion.Inverse(partRot);
1715 1797//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1716 pos = part.AbsolutePosition + offset; 1798 // Sit analysis rewritten by KF 091125
1717 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1799 if (SitTargetisSet) // scipted sit
1718 //{ 1800 {
1719 // offset = pos; 1801 if (!part.IsOccupied)
1720 //autopilot = false; 1802 {
1721 //} 1803//Console.WriteLine("Scripted, unoccupied");
1722 if (m_physicsActor != null) 1804 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1723 { 1805 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1724 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1806 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1725 // We can remove the physicsActor until they stand up. 1807 autopilot = false; // Jump direct to scripted llSitPos()
1726 m_sitAvatarHeight = m_physicsActor.Size.Z; 1808 }
1727 1809 else
1728 if (autopilot) 1810 {
1729 { 1811//Console.WriteLine("Scripted, occupied");
1730 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1812 return;
1731 { 1813 }
1732 autopilot = false; 1814 }
1815 else // Not Scripted
1816 {
1817 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1818 {
1819 // large prim & offset, ignore if other Avs sitting
1820// offset.Z -= 0.05f;
1821 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1822 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1823
1824//Console.WriteLine(" offset ={0}", offset);
1825//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1826//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1827
1828 }
1829 else // small offset
1830 {
1831//Console.WriteLine("Small offset");
1832 if (!part.IsOccupied)
1833 {
1834 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1835 autopilotTarget = part.AbsolutePosition;
1836 }
1837 else return; // occupied small
1838 } // end large/small
1839 } // end Scripted/not
1840 cameraAtOffset = part.GetCameraAtOffset();
1841 cameraEyeOffset = part.GetCameraEyeOffset();
1842 forceMouselook = part.GetForceMouselook();
1843 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1844 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1733 1845
1734 RemoveFromPhysicalScene(); 1846 if (m_physicsActor != null)
1735 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1847 {
1736 } 1848 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1737 } 1849 // We can remove the physicsActor until they stand up.
1738 else 1850 m_sitAvatarHeight = m_physicsActor.Size.Z;
1851 if (autopilot)
1852 { // its not a scripted sit
1853// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1854 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1739 { 1855 {
1856 autopilot = false; // close enough
1857 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1858 Not using the part's position because returning the AV to the last known standing
1859 position is likely to be more friendly, isn't it? */
1740 RemoveFromPhysicalScene(); 1860 RemoveFromPhysicalScene();
1741 } 1861 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1862 } // else the autopilot will get us close
1863 }
1864 else
1865 { // its a scripted sit
1866 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1867 I *am* using the part's position this time because we have no real idea how far away
1868 the avatar is from the sit target. */
1869 RemoveFromPhysicalScene();
1742 } 1870 }
1743
1744 cameraAtOffset = part.GetCameraAtOffset();
1745 cameraEyeOffset = part.GetCameraEyeOffset();
1746 forceMouselook = part.GetForceMouselook();
1747 } 1871 }
1748 1872 else return; // physactor is null!
1749 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1873
1750 m_requestedSitTargetUUID = targetID; 1874 Vector3 offsetr; // = offset * partIRot;
1875 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1876 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1877 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1878 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1879 offsetr = offset * partIRot;
1880//
1881 // else
1882 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1883 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1884 // (offset * partRot);
1885 // }
1886
1887//Console.WriteLine(" ");
1888//Console.WriteLine("link number ={0}", part.LinkNum);
1889//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1890//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1891//Console.WriteLine("Click offst ={0}", offset);
1892//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1893//Console.WriteLine("offsetr ={0}", offsetr);
1894//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1895//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1896
1897 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1898 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1751 // This calls HandleAgentSit twice, once from here, and the client calls 1899 // This calls HandleAgentSit twice, once from here, and the client calls
1752 // HandleAgentSit itself after it gets to the location 1900 // HandleAgentSit itself after it gets to the location
1753 // It doesn't get to the location until we've moved them there though 1901 // It doesn't get to the location until we've moved them there though
1754 // which happens in HandleAgentSit :P 1902 // which happens in HandleAgentSit :P
1755 m_autopilotMoving = autopilot; 1903 m_autopilotMoving = autopilot;
1756 m_autoPilotTarget = pos; 1904 m_autoPilotTarget = autopilotTarget;
1757 m_sitAtAutoTarget = autopilot; 1905 m_sitAtAutoTarget = autopilot;
1906 m_initialSitTarget = autopilotTarget;
1758 if (!autopilot) 1907 if (!autopilot)
1759 HandleAgentSit(remoteClient, UUID); 1908 HandleAgentSit(remoteClient, UUID);
1760 } 1909 }
@@ -2049,31 +2198,65 @@ namespace OpenSim.Region.Framework.Scenes
2049 { 2198 {
2050 if (part != null) 2199 if (part != null)
2051 { 2200 {
2201//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2052 if (part.GetAvatarOnSitTarget() == UUID) 2202 if (part.GetAvatarOnSitTarget() == UUID)
2053 { 2203 {
2204//Console.WriteLine("Scripted Sit");
2205 // Scripted sit
2054 Vector3 sitTargetPos = part.SitTargetPosition; 2206 Vector3 sitTargetPos = part.SitTargetPosition;
2055 Quaternion sitTargetOrient = part.SitTargetOrientation; 2207 Quaternion sitTargetOrient = part.SitTargetOrientation;
2056
2057 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2058 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2059
2060 //Quaternion result = (sitTargetOrient * vq) * nq;
2061
2062 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2208 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2063 m_pos += SIT_TARGET_ADJUSTMENT; 2209 m_pos += SIT_TARGET_ADJUSTMENT;
2064 m_bodyRot = sitTargetOrient; 2210 m_bodyRot = sitTargetOrient;
2065 //Rotation = sitTargetOrient;
2066 m_parentPosition = part.AbsolutePosition; 2211 m_parentPosition = part.AbsolutePosition;
2067 2212 part.IsOccupied = true;
2068 //SendTerseUpdateToAllClients();
2069 } 2213 }
2070 else 2214 else
2071 { 2215 {
2072 m_pos -= part.AbsolutePosition; 2216 // if m_avUnscriptedSitPos is zero then Av sits above center
2217 // Else Av sits at m_avUnscriptedSitPos
2218
2219 // Non-scripted sit by Kitto Flora 21Nov09
2220 // Calculate angle of line from prim to Av
2221 Quaternion partIRot;
2222// if (part.LinkNum == 1)
2223// { // Root prim of linkset
2224// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2225// }
2226// else
2227// { // single or child prim
2228 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2229// }
2230 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2231 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2232 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2233 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2234 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2235 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2236 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2237 // Av sits at world euler <0,0, z>, translated by part rotation
2238 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2239
2073 m_parentPosition = part.AbsolutePosition; 2240 m_parentPosition = part.AbsolutePosition;
2074 } 2241 part.IsOccupied = true;
2075 } 2242 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2076 else 2243 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2244 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2245 m_avUnscriptedSitPos; // adds click offset, if any
2246 //Set up raytrace to find top surface of prim
2247 Vector3 size = part.Scale;
2248 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2249 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2250 Vector3 down = new Vector3(0f, 0f, -1f);
2251//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2252 m_scene.PhysicsScene.RaycastWorld(
2253 start, // Vector3 position,
2254 down, // Vector3 direction,
2255 mag, // float length,
2256 SitAltitudeCallback); // retMethod
2257 } // end scripted/not
2258 }
2259 else // no Av
2077 { 2260 {
2078 return; 2261 return;
2079 } 2262 }
@@ -2085,11 +2268,36 @@ namespace OpenSim.Region.Framework.Scenes
2085 2268
2086 Animator.TrySetMovementAnimation(sitAnimation); 2269 Animator.TrySetMovementAnimation(sitAnimation);
2087 SendFullUpdateToAllClients(); 2270 SendFullUpdateToAllClients();
2088 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2089 // So we're also sending a terse update (which has avatar rotation)
2090 // [Update] We do now.
2091 //SendTerseUpdateToAllClients();
2092 } 2271 }
2272
2273 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2274 {
2275 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2276 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2277 if(hitYN)
2278 {
2279 // m_pos = Av offset from prim center to make look like on center
2280 // m_parentPosition = Actual center pos of prim
2281 // collisionPoint = spot on prim where we want to sit
2282 // collisionPoint.Z = global sit surface height
2283 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2284 Quaternion partIRot;
2285// if (part.LinkNum == 1)
2286/// { // Root prim of linkset
2287// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2288// }
2289// else
2290// { // single or child prim
2291 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2292// }
2293 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2294 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2295//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2296 m_pos += offset;
2297// ControllingClient.SendClearFollowCamProperties(part.UUID);
2298
2299 }
2300 } // End SitAltitudeCallback KF.
2093 2301
2094 /// <summary> 2302 /// <summary>
2095 /// Event handler for the 'Always run' setting on the client 2303 /// Event handler for the 'Always run' setting on the client
@@ -2119,7 +2327,7 @@ namespace OpenSim.Region.Framework.Scenes
2119 /// </summary> 2327 /// </summary>
2120 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2328 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2121 /// <param name="rotation">The direction in which this avatar should now face. 2329 /// <param name="rotation">The direction in which this avatar should now face.
2122 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2330 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2123 { 2331 {
2124 if (m_isChildAgent) 2332 if (m_isChildAgent)
2125 { 2333 {
@@ -2193,7 +2401,7 @@ namespace OpenSim.Region.Framework.Scenes
2193 2401
2194 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2402 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2195 m_forceToApply = direc; 2403 m_forceToApply = direc;
2196 2404 m_isNudging = Nudging;
2197 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2405 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2198 } 2406 }
2199 2407
@@ -2208,7 +2416,7 @@ namespace OpenSim.Region.Framework.Scenes
2208 const float POSITION_TOLERANCE = 0.05f; 2416 const float POSITION_TOLERANCE = 0.05f;
2209 //const int TIME_MS_TOLERANCE = 3000; 2417 //const int TIME_MS_TOLERANCE = 3000;
2210 2418
2211 SendPrimUpdates(); 2419
2212 2420
2213 if (m_newCoarseLocations) 2421 if (m_newCoarseLocations)
2214 { 2422 {
@@ -2244,6 +2452,9 @@ namespace OpenSim.Region.Framework.Scenes
2244 CheckForBorderCrossing(); 2452 CheckForBorderCrossing();
2245 CheckForSignificantMovement(); // sends update to the modules. 2453 CheckForSignificantMovement(); // sends update to the modules.
2246 } 2454 }
2455
2456 //Sending prim updates AFTER the avatar terse updates are sent
2457 SendPrimUpdates();
2247 } 2458 }
2248 2459
2249 #endregion 2460 #endregion
@@ -3097,14 +3308,25 @@ namespace OpenSim.Region.Framework.Scenes
3097 { 3308 {
3098 if (m_forceToApply.HasValue) 3309 if (m_forceToApply.HasValue)
3099 { 3310 {
3100 Vector3 force = m_forceToApply.Value;
3101 3311
3312 Vector3 force = m_forceToApply.Value;
3102 m_updateflag = true; 3313 m_updateflag = true;
3103// movementvector = force;
3104 Velocity = force; 3314 Velocity = force;
3105 3315
3106 m_forceToApply = null; 3316 m_forceToApply = null;
3107 } 3317 }
3318 else
3319 {
3320 if (m_isNudging)
3321 {
3322 Vector3 force = Vector3.Zero;
3323
3324 m_updateflag = true;
3325 Velocity = force;
3326 m_isNudging = false;
3327 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3328 }
3329 }
3108 } 3330 }
3109 3331
3110 public override void SetText(string text, Vector3 color, double alpha) 3332 public override void SetText(string text, Vector3 color, double alpha)
@@ -3156,18 +3378,29 @@ namespace OpenSim.Region.Framework.Scenes
3156 { 3378 {
3157 if (e == null) 3379 if (e == null)
3158 return; 3380 return;
3159 3381
3160 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3382 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3161 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3162 // as of this comment the interval is set in AddToPhysicalScene 3383 // as of this comment the interval is set in AddToPhysicalScene
3163 if (Animator!=null) 3384 if (Animator!=null)
3164 Animator.UpdateMovementAnimations(); 3385 {
3386 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3387 { // else its will lock out other animation changes, like ground sit.
3388 Animator.UpdateMovementAnimations();
3389 m_updateCount--;
3390 }
3391 }
3165 3392
3166 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3393 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3167 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3394 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3168 3395
3169 CollisionPlane = Vector4.UnitW; 3396 CollisionPlane = Vector4.UnitW;
3170 3397
3398 if (m_lastColCount != coldata.Count)
3399 {
3400 m_updateCount = UPDATE_COUNT;
3401 m_lastColCount = coldata.Count;
3402 }
3403
3171 if (coldata.Count != 0 && Animator != null) 3404 if (coldata.Count != 0 && Animator != null)
3172 { 3405 {
3173 switch (Animator.CurrentMovementAnimation) 3406 switch (Animator.CurrentMovementAnimation)
@@ -3815,5 +4048,16 @@ namespace OpenSim.Region.Framework.Scenes
3815 m_reprioritization_called = false; 4048 m_reprioritization_called = false;
3816 } 4049 }
3817 } 4050 }
4051
4052 private Vector3 Quat2Euler(Quaternion rot){
4053 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4054 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4055 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4056 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4057 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4058 return(new Vector3(x,y,z));
4059 }
4060
4061
3818 } 4062 }
3819} \ No newline at end of file 4063}