As per mailing list last week, remove facility that would automatically move the avatar if prim with no sit target was out of sitting range.

Now, no movement occurs.
Note that you can still sit on a prim with an explicit sit target from any distance, as was the case before.
remove-scene-viewer
Justin Clark-Casey (justincc) 2011-11-11 21:42:58 +00:00
parent a658bddbcd
commit b1cb4f5b04
2 changed files with 197 additions and 227 deletions

View File

@ -188,20 +188,12 @@ namespace OpenSim.Region.Framework.Scenes
private readonly Vector3[] Dir_Vectors = new Vector3[11];
protected Timer m_reprioritization_timer;
protected bool m_reprioritizing;
protected bool m_reprioritization_called;
private Quaternion m_headrotation = Quaternion.Identity;
//Reuse the Vector3 instead of creating a new one on the UpdateMovement method
// private Vector3 movementvector;
private bool m_autopilotMoving;
private Vector3 m_autoPilotTarget;
private bool m_sitAtAutoTarget;
private string m_nextSitAnimation = String.Empty;
//PauPaw:Proper PID Controler for autopilot************
@ -1417,9 +1409,6 @@ namespace OpenSim.Region.Framework.Scenes
}
}
if (m_autopilotMoving)
CheckAtSitTarget();
if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
{
m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
@ -1636,111 +1625,109 @@ namespace OpenSim.Region.Framework.Scenes
// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
if (!m_autopilotMoving)
{
double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
// Check the error term of the current position in relation to the target position
if (distanceToTarget <= 1)
// Check the error term of the current position in relation to the target position
if (distanceToTarget <= 1)
{
// We are close enough to the target
AbsolutePosition = MoveToPositionTarget;
ResetMoveToTarget();
updated = true;
}
else
{
try
{
// We are close enough to the target
AbsolutePosition = MoveToPositionTarget;
ResetMoveToTarget();
updated = true;
}
else
{
try
{
// move avatar in 3D at one meter/second towards target, in avatar coordinate frame.
// This movement vector gets added to the velocity through AddNewMovement().
// Theoretically we might need a more complex PID approach here if other
// unknown forces are acting on the avatar and we need to adaptively respond
// to such forces, but the following simple approach seems to works fine.
Vector3 LocalVectorToTarget3D =
(MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
* Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
// Ignore z component of vector
// move avatar in 3D at one meter/second towards target, in avatar coordinate frame.
// This movement vector gets added to the velocity through AddNewMovement().
// Theoretically we might need a more complex PID approach here if other
// unknown forces are acting on the avatar and we need to adaptively respond
// to such forces, but the following simple approach seems to works fine.
Vector3 LocalVectorToTarget3D =
(MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
* Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
// Ignore z component of vector
// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
LocalVectorToTarget3D.Normalize();
LocalVectorToTarget3D.Normalize();
// update avatar movement flags. the avatar coordinate system is as follows:
//
// +X (forward)
//
// ^
// |
// |
// |
// |
// (left) +Y <--------o--------> -Y
// avatar
// |
// |
// |
// |
// v
// -X
//
// update avatar movement flags. the avatar coordinate system is as follows:
//
// +X (forward)
//
// ^
// |
// |
// |
// |
// (left) +Y <--------o--------> -Y
// avatar
// |
// |
// |
// |
// v
// -X
//
// based on the above avatar coordinate system, classify the movement into
// one of left/right/back/forward.
if (LocalVectorToTarget3D.X < 0) //MoveBack
{
MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
updated = true;
}
else if (LocalVectorToTarget3D.X > 0) //Move Forward
{
MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
updated = true;
}
// based on the above avatar coordinate system, classify the movement into
// one of left/right/back/forward.
if (LocalVectorToTarget3D.X < 0) //MoveBack
{
MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
updated = true;
}
else if (LocalVectorToTarget3D.X > 0) //Move Forward
{
MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
updated = true;
}
if (LocalVectorToTarget3D.Y > 0) //MoveLeft
{
MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
updated = true;
}
else if (LocalVectorToTarget3D.Y < 0) //MoveRight
{
MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
updated = true;
}
if (LocalVectorToTarget3D.Y > 0) //MoveLeft
{
MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
updated = true;
}
else if (LocalVectorToTarget3D.Y < 0) //MoveRight
{
MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
updated = true;
}
if (LocalVectorToTarget3D.Z > 0) //Up
{
// Don't set these flags for up or down - doing so will make the avatar crouch or
// keep trying to jump even if walking along level ground
//MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
//AgentControlFlags
//AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
updated = true;
}
else if (LocalVectorToTarget3D.Z < 0) //Down
{
//MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
//AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
updated = true;
}
if (LocalVectorToTarget3D.Z > 0) //Up
{
// Don't set these flags for up or down - doing so will make the avatar crouch or
// keep trying to jump even if walking along level ground
//MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
//AgentControlFlags
//AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
updated = true;
}
else if (LocalVectorToTarget3D.Z < 0) //Down
{
//MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
//AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
updated = true;
}
// m_log.DebugFormat(
// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
// LocalVectorToTarget3D, agent_control_v3, Name);
agent_control_v3 += LocalVectorToTarget3D;
}
catch (Exception e)
{
//Avoid system crash, can be slower but...
m_log.DebugFormat("Crash! {0}", e.ToString());
}
agent_control_v3 += LocalVectorToTarget3D;
}
catch (Exception e)
{
//Avoid system crash, can be slower but...
m_log.DebugFormat("Crash! {0}", e.ToString());
}
}
@ -1842,47 +1829,6 @@ namespace OpenSim.Region.Framework.Scenes
AgentControlFlags = (uint)AgentManager.ControlFlags.NONE;
}
private void CheckAtSitTarget()
{
//m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString());
if (Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget) <= 1.5)
{
if (m_sitAtAutoTarget)
{
SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetUUID);
if (part != null)
{
AbsolutePosition = part.AbsolutePosition;
Velocity = Vector3.Zero;
SendAvatarDataToAllAgents();
//HandleAgentSit(ControllingClient, m_requestedSitTargetUUID);
}
//ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
m_requestedSitTargetUUID = UUID.Zero;
}
/*
else
{
//ControllingClient.SendAlertMessage("Autopilot cancelled");
//SendTerseUpdateToAllClients();
//PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
//proxy.PCode = (byte)PCode.ParticleSystem;
////uint nextUUID = m_scene.NextLocalId;
//proxyObjectGroup = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, UUID, nextUUID, m_autoPilotTarget, Quaternion.Identity, proxy);
//if (proxyObjectGroup != null)
//{
//proxyObjectGroup.SendGroupFullUpdate();
//ControllingClient.SendSitResponse(UUID.Zero, m_autoPilotTarget, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false);
//m_scene.DeleteSceneObject(proxyObjectGroup);
//}
}
*/
m_autoPilotTarget = Vector3.Zero;
m_autopilotMoving = false;
}
}
/// <summary>
/// Perform the logic necessary to stand the avatar up. This method also executes
/// the stand animation.
@ -1893,7 +1839,7 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentID != 0)
{
m_log.Debug("StandupCode Executed");
// m_log.Debug("StandupCode Executed");
SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
if (part != null)
{
@ -1983,7 +1929,6 @@ namespace OpenSim.Region.Framework.Scenes
private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
{
bool autopilot = true;
Vector3 pos = new Vector3();
Quaternion sitOrientation = pSitOrientation;
Vector3 cameraEyeOffset = Vector3.Zero;
@ -1991,86 +1936,85 @@ namespace OpenSim.Region.Framework.Scenes
bool forceMouselook = false;
SceneObjectPart part = FindNextAvailableSitTarget(targetID);
if (part != null)
{
// TODO: determine position to sit at based on scene geometry; don't trust offset from client
// see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
if (part == null)
return;
// Is a sit target available?
Vector3 avSitOffSet = part.SitTargetPosition;
Quaternion avSitOrientation = part.SitTargetOrientation;
UUID avOnTargetAlready = part.SitTargetAvatar;
// TODO: determine position to sit at based on scene geometry; don't trust offset from client
// see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
bool SitTargetisSet =
(!(avSitOffSet == Vector3.Zero &&
(
avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
|| avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
|| avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
)
));
// Is a sit target available?
Vector3 avSitOffSet = part.SitTargetPosition;
Quaternion avSitOrientation = part.SitTargetOrientation;
UUID avOnTargetAlready = part.SitTargetAvatar;
bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
bool SitTargetisSet =
(!(avSitOffSet == Vector3.Zero &&
(
avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
|| avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
|| avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
)
));
// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
if (SitTargetisSet && SitTargetUnOccupied)
if (PhysicsActor != null)
m_sitAvatarHeight = m_physicsActor.Size.Z;
bool canSit = false;
pos = part.AbsolutePosition + offset;
if (SitTargetisSet)
{
if (SitTargetUnOccupied)
{
m_log.DebugFormat(
"[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
Name, part.Name, part.LocalId);
part.SitTargetAvatar = UUID;
offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
sitOrientation = avSitOrientation;
autopilot = false;
canSit = true;
}
pos = part.AbsolutePosition + offset;
//if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
//{
// offset = pos;
//autopilot = false;
//}
}
else
{
if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
{
m_log.DebugFormat(
"[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
Name, part.Name, part.LocalId);
AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
canSit = true;
}
}
if (canSit)
{
if (PhysicsActor != null)
{
// If we're not using the client autopilot, we're immediately warping the avatar to the location
// We can remove the physicsActor until they stand up.
m_sitAvatarHeight = PhysicsActor.Size.Z;
if (autopilot)
{
if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
{
autopilot = false;
RemoveFromPhysicalScene();
AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
}
}
else
{
RemoveFromPhysicalScene();
}
RemoveFromPhysicalScene();
}
cameraAtOffset = part.GetCameraAtOffset();
cameraEyeOffset = part.GetCameraEyeOffset();
forceMouselook = part.GetForceMouselook();
}
ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
m_requestedSitTargetUUID = targetID;
ControllingClient.SendSitResponse(
targetID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
m_requestedSitTargetUUID = targetID;
// This calls HandleAgentSit twice, once from here, and the client calls
// HandleAgentSit itself after it gets to the location
// It doesn't get to the location until we've moved them there though
// which happens in HandleAgentSit :P
m_autopilotMoving = autopilot;
m_autoPilotTarget = pos;
m_sitAtAutoTarget = autopilot;
if (!autopilot)
HandleAgentSit(remoteClient, UUID);
// Moved here to avoid a race with default sit anim
// The script event needs to be raised after the default sit anim is set.
if (part != null)
// Moved here to avoid a race with default sit anim
// The script event needs to be raised after the default sit anim is set.
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
}
}
// public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
@ -2099,11 +2043,11 @@ namespace OpenSim.Region.Framework.Scenes
{
m_nextSitAnimation = part.SitAnimation;
}
m_requestedSitTargetID = part.LocalId;
//m_requestedSitOffset = offset;
m_requestedSitTargetUUID = targetID;
m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
if (m_scene.PhysicsScene.SupportsRayCast())
{
@ -2328,43 +2272,40 @@ namespace OpenSim.Region.Framework.Scenes
{
SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
if (m_sitAtAutoTarget || !m_autopilotMoving)
if (part != null)
{
if (part != null)
if (part.SitTargetAvatar == UUID)
{
if (part.SitTargetAvatar == UUID)
{
Vector3 sitTargetPos = part.SitTargetPosition;
Quaternion sitTargetOrient = part.SitTargetOrientation;
Vector3 sitTargetPos = part.SitTargetPosition;
Quaternion sitTargetOrient = part.SitTargetOrientation;
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}",
// Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId);
//Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
//Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
//Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
//Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
//Quaternion result = (sitTargetOrient * vq) * nq;
//Quaternion result = (sitTargetOrient * vq) * nq;
m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT;
Rotation = sitTargetOrient;
ParentPosition = part.AbsolutePosition;
}
else
{
m_pos -= part.AbsolutePosition;
ParentPosition = part.AbsolutePosition;
m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT;
Rotation = sitTargetOrient;
ParentPosition = part.AbsolutePosition;
}
else
{
m_pos -= part.AbsolutePosition;
ParentPosition = part.AbsolutePosition;
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
}
}
else
{
return;
}
}
else
{
return;
}
ParentID = m_requestedSitTargetID;

View File

@ -53,7 +53,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
}
[Test]
public void TestSitOutsideRange()
public void TestSitOutsideRangeNoTarget()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
}
[Test]
public void TestSitWithinRange()
public void TestSitWithinRangeNoTarget()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
@ -124,5 +124,34 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
Assert.That(sp.ParentID, Is.EqualTo(0));
}
[Test]
public void TestSitAndStandWithSitTarget()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
// If a prim has a sit target then we can sit from any distance away
Vector3 startPos = new Vector3(128, 128, 30);
sp.AbsolutePosition = startPos;
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
part.SitTargetPosition = new Vector3(0, 0, 1);
sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, part.UUID, Vector3.Zero);
Assert.That(part.SitTargetAvatar, Is.EqualTo(sp.UUID));
Assert.That(sp.ParentID, Is.EqualTo(part.LocalId));
Assert.That(
sp.AbsolutePosition,
Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT));
sp.StandUp();
Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
Assert.That(sp.ParentID, Is.EqualTo(0));
}
}
}