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.cs471
1 files changed, 343 insertions, 128 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 2710cff..c67463a 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -113,7 +115,9 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 115 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 116 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 117 public Vector4 CollisionPlane = Vector4.UnitW;
116 118
119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
117 private Vector3 m_lastPosition; 121 private Vector3 m_lastPosition;
118 private Quaternion m_lastRotation; 122 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 123 private Vector3 m_lastVelocity;
@@ -145,7 +149,6 @@ namespace OpenSim.Region.Framework.Scenes
145 private int m_perfMonMS; 149 private int m_perfMonMS;
146 150
147 private bool m_setAlwaysRun; 151 private bool m_setAlwaysRun;
148
149 private bool m_forceFly; 152 private bool m_forceFly;
150 private bool m_flyDisabled; 153 private bool m_flyDisabled;
151 154
@@ -169,7 +172,8 @@ namespace OpenSim.Region.Framework.Scenes
169 protected RegionInfo m_regionInfo; 172 protected RegionInfo m_regionInfo;
170 protected ulong crossingFromRegion; 173 protected ulong crossingFromRegion;
171 174
172 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 175 private readonly Vector3[] Dir_Vectors = new Vector3[11];
176 private bool m_isNudging = false;
173 177
174 // Position of agent's camera in world (region cordinates) 178 // Position of agent's camera in world (region cordinates)
175 protected Vector3 m_CameraCenter; 179 protected Vector3 m_CameraCenter;
@@ -194,6 +198,7 @@ namespace OpenSim.Region.Framework.Scenes
194 private bool m_autopilotMoving; 198 private bool m_autopilotMoving;
195 private Vector3 m_autoPilotTarget; 199 private Vector3 m_autoPilotTarget;
196 private bool m_sitAtAutoTarget; 200 private bool m_sitAtAutoTarget;
201 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
197 202
198 private string m_nextSitAnimation = String.Empty; 203 private string m_nextSitAnimation = String.Empty;
199 204
@@ -204,6 +209,9 @@ namespace OpenSim.Region.Framework.Scenes
204 private bool m_followCamAuto; 209 private bool m_followCamAuto;
205 210
206 private int m_movementUpdateCount; 211 private int m_movementUpdateCount;
212 private int m_lastColCount = -1; //KF: Look for Collision chnages
213 private int m_updateCount = 0; //KF: Update Anims for a while
214 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
207 215
208 private const int NumMovementsBetweenRayCast = 5; 216 private const int NumMovementsBetweenRayCast = 5;
209 217
@@ -233,6 +241,10 @@ namespace OpenSim.Region.Framework.Scenes
233 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 241 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
234 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 242 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
235 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 243 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
244 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
245 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
246 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
247 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 248 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
237 } 249 }
238 250
@@ -658,10 +670,7 @@ namespace OpenSim.Region.Framework.Scenes
658 670
659 671
660 AdjustKnownSeeds(); 672 AdjustKnownSeeds();
661
662 // TODO: I think, this won't send anything, as we are still a child here...
663 Animator.TrySetMovementAnimation("STAND"); 673 Animator.TrySetMovementAnimation("STAND");
664
665 // we created a new ScenePresence (a new child agent) in a fresh region. 674 // we created a new ScenePresence (a new child agent) in a fresh region.
666 // Request info about all the (root) agents in this region 675 // 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) 676 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -717,21 +726,47 @@ namespace OpenSim.Region.Framework.Scenes
717 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 726 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
718 Dir_Vectors[4] = Vector3.UnitZ; //UP 727 Dir_Vectors[4] = Vector3.UnitZ; //UP
719 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 728 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
720 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 729 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
730 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
731 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
732 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
733 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
721 } 734 }
722 735
723 private Vector3[] GetWalkDirectionVectors() 736 private Vector3[] GetWalkDirectionVectors()
724 { 737 {
725 Vector3[] vector = new Vector3[6]; 738 Vector3[] vector = new Vector3[11];
726 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 739 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
727 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 740 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
728 vector[2] = Vector3.UnitY; //LEFT 741 vector[2] = Vector3.UnitY; //LEFT
729 vector[3] = -Vector3.UnitY; //RIGHT 742 vector[3] = -Vector3.UnitY; //RIGHT
730 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 743 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
731 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 744 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
732 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 745 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
746 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
747 vector[8] = Vector3.UnitY; //LEFT_NUDGE
748 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
749 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
733 return vector; 750 return vector;
734 } 751 }
752
753 private bool[] GetDirectionIsNudge()
754 {
755 bool[] isNudge = new bool[11];
756 isNudge[0] = false; //FORWARD
757 isNudge[1] = false; //BACK
758 isNudge[2] = false; //LEFT
759 isNudge[3] = false; //RIGHT
760 isNudge[4] = false; //UP
761 isNudge[5] = false; //DOWN
762 isNudge[6] = true; //FORWARD_NUDGE
763 isNudge[7] = true; //BACK_NUDGE
764 isNudge[8] = true; //LEFT_NUDGE
765 isNudge[9] = true; //RIGHT_NUDGE
766 isNudge[10] = true; //DOWN_Nudge
767 return isNudge;
768 }
769
735 770
736 #endregion 771 #endregion
737 772
@@ -995,7 +1030,9 @@ namespace OpenSim.Region.Framework.Scenes
995 { 1030 {
996 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1031 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
997 } 1032 }
998 1033
1034 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1035
999 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1036 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1000 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1037 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1001 } 1038 }
@@ -1230,7 +1267,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); 1267 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1231 } 1268 }
1232 } 1269 }
1233
1234 lock (scriptedcontrols) 1270 lock (scriptedcontrols)
1235 { 1271 {
1236 if (scriptedcontrols.Count > 0) 1272 if (scriptedcontrols.Count > 0)
@@ -1245,9 +1281,7 @@ namespace OpenSim.Region.Framework.Scenes
1245 1281
1246 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1282 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1247 { 1283 {
1248 // TODO: This doesn't prevent the user from walking yet. 1284 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
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"); 1285 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1252 } 1286 }
1253 1287
@@ -1292,6 +1326,11 @@ namespace OpenSim.Region.Framework.Scenes
1292 update_rotation = true; 1326 update_rotation = true;
1293 } 1327 }
1294 1328
1329 //guilty until proven innocent..
1330 bool Nudging = true;
1331 //Basically, if there is at least one non-nudge control then we don't need
1332 //to worry about stopping the avatar
1333
1295 if (m_parentID == 0) 1334 if (m_parentID == 0)
1296 { 1335 {
1297 bool bAllowUpdateMoveToPosition = false; 1336 bool bAllowUpdateMoveToPosition = false;
@@ -1306,6 +1345,12 @@ namespace OpenSim.Region.Framework.Scenes
1306 else 1345 else
1307 dirVectors = Dir_Vectors; 1346 dirVectors = Dir_Vectors;
1308 1347
1348 bool[] isNudge = GetDirectionIsNudge();
1349
1350
1351
1352
1353
1309 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1354 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1310 { 1355 {
1311 if (((uint)flags & (uint)DCF) != 0) 1356 if (((uint)flags & (uint)DCF) != 0)
@@ -1315,6 +1360,10 @@ namespace OpenSim.Region.Framework.Scenes
1315 try 1360 try
1316 { 1361 {
1317 agent_control_v3 += dirVectors[i]; 1362 agent_control_v3 += dirVectors[i];
1363 if (isNudge[i] == false)
1364 {
1365 Nudging = false;
1366 }
1318 } 1367 }
1319 catch (IndexOutOfRangeException) 1368 catch (IndexOutOfRangeException)
1320 { 1369 {
@@ -1376,6 +1425,9 @@ namespace OpenSim.Region.Framework.Scenes
1376 // Ignore z component of vector 1425 // Ignore z component of vector
1377 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1426 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1378 LocalVectorToTarget2D.Normalize(); 1427 LocalVectorToTarget2D.Normalize();
1428
1429 //We're not nudging
1430 Nudging = false;
1379 agent_control_v3 += LocalVectorToTarget2D; 1431 agent_control_v3 += LocalVectorToTarget2D;
1380 1432
1381 // update avatar movement flags. the avatar coordinate system is as follows: 1433 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1464,7 +1516,7 @@ namespace OpenSim.Region.Framework.Scenes
1464 // m_log.DebugFormat( 1516 // m_log.DebugFormat(
1465 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1517 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1466 1518
1467 AddNewMovement(agent_control_v3, q); 1519 AddNewMovement(agent_control_v3, q, Nudging);
1468 1520
1469 1521
1470 } 1522 }
@@ -1485,7 +1537,6 @@ namespace OpenSim.Region.Framework.Scenes
1485 m_sitAtAutoTarget = false; 1537 m_sitAtAutoTarget = false;
1486 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1538 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1487 //proxy.PCode = (byte)PCode.ParticleSystem; 1539 //proxy.PCode = (byte)PCode.ParticleSystem;
1488
1489 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1540 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1490 proxyObjectGroup.AttachToScene(m_scene); 1541 proxyObjectGroup.AttachToScene(m_scene);
1491 1542
@@ -1527,7 +1578,7 @@ namespace OpenSim.Region.Framework.Scenes
1527 } 1578 }
1528 m_moveToPositionInProgress = true; 1579 m_moveToPositionInProgress = true;
1529 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1580 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1530 } 1581 }
1531 catch (Exception ex) 1582 catch (Exception ex)
1532 { 1583 {
1533 //Why did I get this error? 1584 //Why did I get this error?
@@ -1549,7 +1600,7 @@ namespace OpenSim.Region.Framework.Scenes
1549 Velocity = Vector3.Zero; 1600 Velocity = Vector3.Zero;
1550 SendFullUpdateToAllClients(); 1601 SendFullUpdateToAllClients();
1551 1602
1552 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1603 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1553 } 1604 }
1554 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1605 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1555 m_requestedSitTargetUUID = UUID.Zero; 1606 m_requestedSitTargetUUID = UUID.Zero;
@@ -1587,38 +1638,51 @@ namespace OpenSim.Region.Framework.Scenes
1587 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1638 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1588 if (part != null) 1639 if (part != null)
1589 { 1640 {
1641 part.TaskInventory.LockItemsForRead(true);
1590 TaskInventoryDictionary taskIDict = part.TaskInventory; 1642 TaskInventoryDictionary taskIDict = part.TaskInventory;
1591 if (taskIDict != null) 1643 if (taskIDict != null)
1592 { 1644 {
1593 lock (taskIDict) 1645 foreach (UUID taskID in taskIDict.Keys)
1594 { 1646 {
1595 foreach (UUID taskID in taskIDict.Keys) 1647 UnRegisterControlEventsToScript(LocalId, taskID);
1596 { 1648 taskIDict[taskID].PermsMask &= ~(
1597 UnRegisterControlEventsToScript(LocalId, taskID); 1649 2048 | //PERMISSION_CONTROL_CAMERA
1598 taskIDict[taskID].PermsMask &= ~( 1650 4); // PERMISSION_TAKE_CONTROLS
1599 2048 | //PERMISSION_CONTROL_CAMERA
1600 4); // PERMISSION_TAKE_CONTROLS
1601 }
1602 } 1651 }
1603
1604 } 1652 }
1653 part.TaskInventory.LockItemsForRead(false);
1605 // Reset sit target. 1654 // Reset sit target.
1606 if (part.GetAvatarOnSitTarget() == UUID) 1655 if (part.GetAvatarOnSitTarget() == UUID)
1607 part.SetAvatarOnSitTarget(UUID.Zero); 1656 part.SetAvatarOnSitTarget(UUID.Zero);
1608
1609 m_parentPosition = part.GetWorldPosition(); 1657 m_parentPosition = part.GetWorldPosition();
1610 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1658 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1611 } 1659 }
1660 // part.GetWorldRotation() is the rotation of the object being sat on
1661 // Rotation is the sittiing Av's rotation
1662
1663 Quaternion partRot;
1664 if (part.LinkNum == 1)
1665 { // Root prim of linkset
1666 partRot = part.ParentGroup.RootPart.RotationOffset;
1667 }
1668 else
1669 { // single or child prim
1670 partRot = part.GetWorldRotation();
1671 }
1672 Quaternion partIRot = Quaternion.Inverse(partRot);
1673
1674 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1675 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1676 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ( m_pos * partRot); // + av sit offset!
1612 1677
1613 if (m_physicsActor == null) 1678 if (m_physicsActor == null)
1614 { 1679 {
1615 AddToPhysicalScene(false); 1680 AddToPhysicalScene(false);
1616 } 1681 }
1617 1682 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1618 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight);
1619 m_parentPosition = Vector3.Zero; 1683 m_parentPosition = Vector3.Zero;
1620 1684 m_parentID = 0;
1621 m_parentID = 0; 1685 part.IsOccupied = false;
1622 SendFullUpdateToAllClients(); 1686 SendFullUpdateToAllClients();
1623 m_requestedSitTargetID = 0; 1687 m_requestedSitTargetID = 0;
1624 if ((m_physicsActor != null) && (m_avHeight > 0)) 1688 if ((m_physicsActor != null) && (m_avHeight > 0))
@@ -1626,7 +1690,6 @@ namespace OpenSim.Region.Framework.Scenes
1626 SetHeight(m_avHeight); 1690 SetHeight(m_avHeight);
1627 } 1691 }
1628 } 1692 }
1629
1630 Animator.TrySetMovementAnimation("STAND"); 1693 Animator.TrySetMovementAnimation("STAND");
1631 } 1694 }
1632 1695
@@ -1657,13 +1720,9 @@ namespace OpenSim.Region.Framework.Scenes
1657 Vector3 avSitOffSet = part.SitTargetPosition; 1720 Vector3 avSitOffSet = part.SitTargetPosition;
1658 Quaternion avSitOrientation = part.SitTargetOrientation; 1721 Quaternion avSitOrientation = part.SitTargetOrientation;
1659 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1722 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1660 1723 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1661 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1724 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1662 bool SitTargetisSet = 1725 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 { 1726 {
1668 //switch the target to this prim 1727 //switch the target to this prim
1669 return part; 1728 return part;
@@ -1677,84 +1736,146 @@ namespace OpenSim.Region.Framework.Scenes
1677 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1736 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1678 { 1737 {
1679 bool autopilot = true; 1738 bool autopilot = true;
1739 Vector3 autopilotTarget = new Vector3();
1740 Quaternion sitOrientation = Quaternion.Identity;
1680 Vector3 pos = new Vector3(); 1741 Vector3 pos = new Vector3();
1681 Quaternion sitOrientation = pSitOrientation;
1682 Vector3 cameraEyeOffset = Vector3.Zero; 1742 Vector3 cameraEyeOffset = Vector3.Zero;
1683 Vector3 cameraAtOffset = Vector3.Zero; 1743 Vector3 cameraAtOffset = Vector3.Zero;
1684 bool forceMouselook = false; 1744 bool forceMouselook = false;
1685 1745
1686 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1746 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1687 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1747 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1688 if (part != null) 1748 if (part == null) return;
1689 { 1749
1690 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1750 // 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 1751 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1692 1752
1693 // Is a sit target available? 1753 // part is the prim to sit on
1694 Vector3 avSitOffSet = part.SitTargetPosition; 1754 // offset is the world-ref vector distance from that prim center to the click-spot
1695 Quaternion avSitOrientation = part.SitTargetOrientation; 1755 // UUID is the UUID of the Avatar doing the clicking
1696 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1756
1697 1757 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1698 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1758
1699 bool SitTargetisSet = 1759 // Is a sit target available?
1700 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1760 Vector3 avSitOffSet = part.SitTargetPosition;
1701 ( 1761 Quaternion avSitOrientation = part.SitTargetOrientation;
1702 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1762
1703 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1763 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 1764 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1705 ) 1765 Quaternion partRot;
1706 )); 1766 if (part.LinkNum == 1)
1707 1767 { // Root prim of linkset
1708 if (SitTargetisSet && SitTargetUnOccupied) 1768 partRot = part.ParentGroup.RootPart.RotationOffset;
1709 { 1769 }
1710 part.SetAvatarOnSitTarget(UUID); 1770 else
1711 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1771 { // single or child prim
1712 sitOrientation = avSitOrientation; 1772 partRot = part.GetWorldRotation();
1713 autopilot = false; 1773 }
1714 } 1774 Quaternion partIRot = Quaternion.Inverse(partRot);
1715 1775//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1716 pos = part.AbsolutePosition + offset; 1776 // Sit analysis rewritten by KF 091125
1717 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1777 if (SitTargetisSet) // scipted sit
1718 //{ 1778 {
1719 // offset = pos; 1779 if (!part.IsOccupied)
1720 //autopilot = false; 1780 {
1721 //} 1781//Console.WriteLine("Scripted, unoccupied");
1722 if (m_physicsActor != null) 1782 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1723 { 1783 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 1784 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1725 // We can remove the physicsActor until they stand up. 1785 autopilot = false; // Jump direct to scripted llSitPos()
1726 m_sitAvatarHeight = m_physicsActor.Size.Z; 1786 }
1727 1787 else
1728 if (autopilot) 1788 {
1729 { 1789//Console.WriteLine("Scripted, occupied");
1730 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1790 return;
1731 { 1791 }
1732 autopilot = false; 1792 }
1793 else // Not Scripted
1794 {
1795 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1796 {
1797 // large prim & offset, ignore if other Avs sitting
1798// offset.Z -= 0.05f;
1799 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1800 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1801
1802//Console.WriteLine(" offset ={0}", offset);
1803//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1804//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1805
1806 }
1807 else // small offset
1808 {
1809//Console.WriteLine("Small offset");
1810 if (!part.IsOccupied)
1811 {
1812 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1813 autopilotTarget = part.AbsolutePosition;
1814 }
1815 else return; // occupied small
1816 } // end large/small
1817 } // end Scripted/not
1818 cameraAtOffset = part.GetCameraAtOffset();
1819 cameraEyeOffset = part.GetCameraEyeOffset();
1820 forceMouselook = part.GetForceMouselook();
1821 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1822 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1733 1823
1734 RemoveFromPhysicalScene(); 1824 if (m_physicsActor != null)
1735 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1825 {
1736 } 1826 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1737 } 1827 // We can remove the physicsActor until they stand up.
1738 else 1828 m_sitAvatarHeight = m_physicsActor.Size.Z;
1829 if (autopilot)
1830 { // its not a scripted sit
1831// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1832 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1739 { 1833 {
1834 autopilot = false; // close enough
1740 RemoveFromPhysicalScene(); 1835 RemoveFromPhysicalScene();
1741 } 1836 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1837 } // else the autopilot will get us close
1838 }
1839 else
1840 { // its a scripted sit
1841 RemoveFromPhysicalScene();
1742 } 1842 }
1743
1744 cameraAtOffset = part.GetCameraAtOffset();
1745 cameraEyeOffset = part.GetCameraEyeOffset();
1746 forceMouselook = part.GetForceMouselook();
1747 } 1843 }
1844 else return; // physactor is null!
1748 1845
1749 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1846 Vector3 offsetr; // = offset * partIRot;
1750 m_requestedSitTargetUUID = targetID; 1847 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1848 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1849 if (part.LinkNum < 2)
1850 { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1851 offsetr = offset * partIRot;
1852 }
1853 else
1854 { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1855 offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1856 (offset * partRot);
1857 }
1858
1859//Console.WriteLine(" ");
1860//Console.WriteLine("link number ={0}", part.LinkNum);
1861//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1862//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1863//Console.WriteLine("Click offst ={0}", offset);
1864//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1865//Console.WriteLine("offsetr ={0}", offsetr);
1866//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1867//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1868
1869 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1870 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1751 // This calls HandleAgentSit twice, once from here, and the client calls 1871 // This calls HandleAgentSit twice, once from here, and the client calls
1752 // HandleAgentSit itself after it gets to the location 1872 // HandleAgentSit itself after it gets to the location
1753 // It doesn't get to the location until we've moved them there though 1873 // It doesn't get to the location until we've moved them there though
1754 // which happens in HandleAgentSit :P 1874 // which happens in HandleAgentSit :P
1755 m_autopilotMoving = autopilot; 1875 m_autopilotMoving = autopilot;
1756 m_autoPilotTarget = pos; 1876 m_autoPilotTarget = autopilotTarget;
1757 m_sitAtAutoTarget = autopilot; 1877 m_sitAtAutoTarget = autopilot;
1878 m_initialSitTarget = autopilotTarget;
1758 if (!autopilot) 1879 if (!autopilot)
1759 HandleAgentSit(remoteClient, UUID); 1880 HandleAgentSit(remoteClient, UUID);
1760 } 1881 }
@@ -2051,29 +2172,62 @@ namespace OpenSim.Region.Framework.Scenes
2051 { 2172 {
2052 if (part.GetAvatarOnSitTarget() == UUID) 2173 if (part.GetAvatarOnSitTarget() == UUID)
2053 { 2174 {
2175//Console.WriteLine("Scripted Sit");
2176 // Scripted sit
2054 Vector3 sitTargetPos = part.SitTargetPosition; 2177 Vector3 sitTargetPos = part.SitTargetPosition;
2055 Quaternion sitTargetOrient = part.SitTargetOrientation; 2178 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); 2179 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2063 m_pos += SIT_TARGET_ADJUSTMENT; 2180 m_pos += SIT_TARGET_ADJUSTMENT;
2064 m_bodyRot = sitTargetOrient; 2181 m_bodyRot = sitTargetOrient;
2065 //Rotation = sitTargetOrient;
2066 m_parentPosition = part.AbsolutePosition; 2182 m_parentPosition = part.AbsolutePosition;
2067 2183 part.IsOccupied = true;
2068 //SendTerseUpdateToAllClients();
2069 } 2184 }
2070 else 2185 else
2071 { 2186 {
2072 m_pos -= part.AbsolutePosition; 2187 // if m_avUnscriptedSitPos is zero then Av sits above center
2188 // Else Av sits at m_avUnscriptedSitPos
2189
2190 // Non-scripted sit by Kitto Flora 21Nov09
2191 // Calculate angle of line from prim to Av
2192 Quaternion partIRot;
2193 if (part.LinkNum == 1)
2194 { // Root prim of linkset
2195 partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2196 }
2197 else
2198 { // single or child prim
2199 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2200 }
2201 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2202 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2203 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2204 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2205 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2206 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2207 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2208 // Av sits at world euler <0,0, z>, translated by part rotation
2209 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2210
2073 m_parentPosition = part.AbsolutePosition; 2211 m_parentPosition = part.AbsolutePosition;
2074 } 2212 part.IsOccupied = true;
2075 } 2213 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2076 else 2214 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2215 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2216 m_avUnscriptedSitPos; // adds click offset, if any
2217 //Set up raytrace to find top surface of prim
2218 Vector3 size = part.Scale;
2219 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2220 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2221 Vector3 down = new Vector3(0f, 0f, -1f);
2222//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2223 m_scene.PhysicsScene.RaycastWorld(
2224 start, // Vector3 position,
2225 down, // Vector3 direction,
2226 mag, // float length,
2227 SitAltitudeCallback); // retMethod
2228 } // end scripted/not
2229 }
2230 else // no Av
2077 { 2231 {
2078 return; 2232 return;
2079 } 2233 }
@@ -2085,11 +2239,36 @@ namespace OpenSim.Region.Framework.Scenes
2085 2239
2086 Animator.TrySetMovementAnimation(sitAnimation); 2240 Animator.TrySetMovementAnimation(sitAnimation);
2087 SendFullUpdateToAllClients(); 2241 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 } 2242 }
2243
2244 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2245 {
2246 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2247 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2248 if(hitYN)
2249 {
2250 // m_pos = Av offset from prim center to make look like on center
2251 // m_parentPosition = Actual center pos of prim
2252 // collisionPoint = spot on prim where we want to sit
2253 // collisionPoint.Z = global sit surface height
2254 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2255 Quaternion partIRot;
2256 if (part.LinkNum == 1)
2257 { // Root prim of linkset
2258 partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2259 }
2260 else
2261 { // single or child prim
2262 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2263 }
2264 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2265 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2266//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2267 m_pos += offset;
2268// ControllingClient.SendClearFollowCamProperties(part.UUID);
2269
2270 }
2271 } // End SitAltitudeCallback KF.
2093 2272
2094 /// <summary> 2273 /// <summary>
2095 /// Event handler for the 'Always run' setting on the client 2274 /// Event handler for the 'Always run' setting on the client
@@ -2119,7 +2298,7 @@ namespace OpenSim.Region.Framework.Scenes
2119 /// </summary> 2298 /// </summary>
2120 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2299 /// <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. 2300 /// <param name="rotation">The direction in which this avatar should now face.
2122 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2301 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2123 { 2302 {
2124 if (m_isChildAgent) 2303 if (m_isChildAgent)
2125 { 2304 {
@@ -2193,7 +2372,7 @@ namespace OpenSim.Region.Framework.Scenes
2193 2372
2194 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2373 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2195 m_forceToApply = direc; 2374 m_forceToApply = direc;
2196 2375 m_isNudging = Nudging;
2197 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2376 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2198 } 2377 }
2199 2378
@@ -2208,7 +2387,7 @@ namespace OpenSim.Region.Framework.Scenes
2208 const float POSITION_TOLERANCE = 0.05f; 2387 const float POSITION_TOLERANCE = 0.05f;
2209 //const int TIME_MS_TOLERANCE = 3000; 2388 //const int TIME_MS_TOLERANCE = 3000;
2210 2389
2211 SendPrimUpdates(); 2390
2212 2391
2213 if (m_newCoarseLocations) 2392 if (m_newCoarseLocations)
2214 { 2393 {
@@ -2244,6 +2423,9 @@ namespace OpenSim.Region.Framework.Scenes
2244 CheckForBorderCrossing(); 2423 CheckForBorderCrossing();
2245 CheckForSignificantMovement(); // sends update to the modules. 2424 CheckForSignificantMovement(); // sends update to the modules.
2246 } 2425 }
2426
2427 //Sending prim updates AFTER the avatar terse updates are sent
2428 SendPrimUpdates();
2247 } 2429 }
2248 2430
2249 #endregion 2431 #endregion
@@ -3097,14 +3279,25 @@ namespace OpenSim.Region.Framework.Scenes
3097 { 3279 {
3098 if (m_forceToApply.HasValue) 3280 if (m_forceToApply.HasValue)
3099 { 3281 {
3100 Vector3 force = m_forceToApply.Value;
3101 3282
3283 Vector3 force = m_forceToApply.Value;
3102 m_updateflag = true; 3284 m_updateflag = true;
3103// movementvector = force;
3104 Velocity = force; 3285 Velocity = force;
3105 3286
3106 m_forceToApply = null; 3287 m_forceToApply = null;
3107 } 3288 }
3289 else
3290 {
3291 if (m_isNudging)
3292 {
3293 Vector3 force = Vector3.Zero;
3294
3295 m_updateflag = true;
3296 Velocity = force;
3297 m_isNudging = false;
3298 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3299 }
3300 }
3108 } 3301 }
3109 3302
3110 public override void SetText(string text, Vector3 color, double alpha) 3303 public override void SetText(string text, Vector3 color, double alpha)
@@ -3156,18 +3349,29 @@ namespace OpenSim.Region.Framework.Scenes
3156 { 3349 {
3157 if (e == null) 3350 if (e == null)
3158 return; 3351 return;
3159 3352
3160 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3353 // 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 3354 // as of this comment the interval is set in AddToPhysicalScene
3163 if (Animator!=null) 3355 if (Animator!=null)
3164 Animator.UpdateMovementAnimations(); 3356 {
3357 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3358 { // else its will lock out other animation changes, like ground sit.
3359 Animator.UpdateMovementAnimations();
3360 m_updateCount--;
3361 }
3362 }
3165 3363
3166 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3364 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3167 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3365 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3168 3366
3169 CollisionPlane = Vector4.UnitW; 3367 CollisionPlane = Vector4.UnitW;
3170 3368
3369 if (m_lastColCount != coldata.Count)
3370 {
3371 m_updateCount = UPDATE_COUNT;
3372 m_lastColCount = coldata.Count;
3373 }
3374
3171 if (coldata.Count != 0 && Animator != null) 3375 if (coldata.Count != 0 && Animator != null)
3172 { 3376 {
3173 switch (Animator.CurrentMovementAnimation) 3377 switch (Animator.CurrentMovementAnimation)
@@ -3815,5 +4019,16 @@ namespace OpenSim.Region.Framework.Scenes
3815 m_reprioritization_called = false; 4019 m_reprioritization_called = false;
3816 } 4020 }
3817 } 4021 }
4022
4023 private Vector3 Quat2Euler(Quaternion rot){
4024 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4025 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4026 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4027 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4028 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4029 return(new Vector3(x,y,z));
4030 }
4031
4032
3818 } 4033 }
3819} \ No newline at end of file 4034}