Allow moving an avatar as part of a linkset using llSetLinkPrimitiveParams. This unlocks an awful lot of poseball-free content, and is a step towards resolving mantis #59.
parent
6d8da699b2
commit
49d7d8534c
|
@ -110,8 +110,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
private long m_minPersistTime = 0;
|
private long m_minPersistTime = 0;
|
||||||
private Random m_rand;
|
private Random m_rand;
|
||||||
private bool m_suspendUpdates;
|
private bool m_suspendUpdates;
|
||||||
|
private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
|
||||||
private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
|
private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>();
|
||||||
|
|
||||||
public bool areUpdatesSuspended
|
public bool areUpdatesSuspended
|
||||||
{
|
{
|
||||||
|
@ -1115,6 +1115,47 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add the avatar to this linkset (avatar is sat).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="agentID"></param>
|
||||||
|
public void AddAvatar(UUID agentID)
|
||||||
|
{
|
||||||
|
ScenePresence presence;
|
||||||
|
if (m_scene.TryGetScenePresence(agentID, out presence))
|
||||||
|
{
|
||||||
|
if (!m_linkedAvatars.Contains(presence))
|
||||||
|
{
|
||||||
|
m_linkedAvatars.Add(presence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delete the avatar from this linkset (avatar is unsat).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="agentID"></param>
|
||||||
|
public void DeleteAvatar(UUID agentID)
|
||||||
|
{
|
||||||
|
ScenePresence presence;
|
||||||
|
if (m_scene.TryGetScenePresence(agentID, out presence))
|
||||||
|
{
|
||||||
|
if (m_linkedAvatars.Contains(presence))
|
||||||
|
{
|
||||||
|
m_linkedAvatars.Remove(presence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the list of linked presences (avatars sat on this group)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="agentID"></param>
|
||||||
|
public List<ScenePresence> GetLinkedAvatars()
|
||||||
|
{
|
||||||
|
return m_linkedAvatars;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attach this scene object to the given avatar.
|
/// Attach this scene object to the given avatar.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2974,6 +3015,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of parts
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int GetPartCount()
|
||||||
|
{
|
||||||
|
return Children.Count;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the parts of this scene object
|
/// Get the parts of this scene object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -219,6 +219,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
//PauPaw:Proper PID Controler for autopilot************
|
//PauPaw:Proper PID Controler for autopilot************
|
||||||
private bool m_moveToPositionInProgress;
|
private bool m_moveToPositionInProgress;
|
||||||
private Vector3 m_moveToPositionTarget;
|
private Vector3 m_moveToPositionTarget;
|
||||||
|
private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
private bool m_followCamAuto;
|
private bool m_followCamAuto;
|
||||||
|
|
||||||
|
@ -537,10 +538,39 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Quaternion OffsetRotation
|
||||||
|
{
|
||||||
|
get { return m_offsetRotation; }
|
||||||
|
set { m_offsetRotation = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public Quaternion Rotation
|
public Quaternion Rotation
|
||||||
{
|
{
|
||||||
get { return m_bodyRot; }
|
get {
|
||||||
set { m_bodyRot = value; }
|
if (m_parentID != 0)
|
||||||
|
{
|
||||||
|
if (m_offsetRotation != null)
|
||||||
|
{
|
||||||
|
return m_offsetRotation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return m_bodyRot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
m_bodyRot = value;
|
||||||
|
if (m_parentID != 0)
|
||||||
|
{
|
||||||
|
m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Quaternion PreviousRotation
|
public Quaternion PreviousRotation
|
||||||
|
@ -1795,6 +1825,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
|
Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
|
||||||
AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
|
AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
|
||||||
part.IsOccupied = false;
|
part.IsOccupied = false;
|
||||||
|
part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1804,6 +1835,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
m_parentPosition = Vector3.Zero;
|
m_parentPosition = Vector3.Zero;
|
||||||
m_parentID = 0;
|
m_parentID = 0;
|
||||||
|
m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
SendFullUpdateToAllClients();
|
SendFullUpdateToAllClients();
|
||||||
m_requestedSitTargetID = 0;
|
m_requestedSitTargetID = 0;
|
||||||
|
|
||||||
|
@ -1904,6 +1936,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
|
part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
|
||||||
offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
|
offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
|
||||||
sitOrientation = avSitOrientation; // Change rotatione to the scripted one
|
sitOrientation = avSitOrientation; // Change rotatione to the scripted one
|
||||||
|
OffsetRotation = avSitOrientation;
|
||||||
autopilot = false; // Jump direct to scripted llSitPos()
|
autopilot = false; // Jump direct to scripted llSitPos()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2311,6 +2344,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_bodyRot = sitTargetOrient;
|
m_bodyRot = sitTargetOrient;
|
||||||
m_parentPosition = part.AbsolutePosition;
|
m_parentPosition = part.AbsolutePosition;
|
||||||
part.IsOccupied = true;
|
part.IsOccupied = true;
|
||||||
|
part.ParentGroup.AddAvatar(agentID);
|
||||||
Console.WriteLine("Scripted Sit ofset {0}", m_pos);
|
Console.WriteLine("Scripted Sit ofset {0}", m_pos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2341,6 +2375,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos);
|
||||||
|
|
||||||
m_parentPosition = part.AbsolutePosition;
|
m_parentPosition = part.AbsolutePosition;
|
||||||
part.IsOccupied = true;
|
part.IsOccupied = true;
|
||||||
|
part.ParentGroup.AddAvatar(agentID);
|
||||||
m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
|
m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
|
||||||
(new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
|
(new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
|
||||||
(new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
|
(new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
|
||||||
|
|
|
@ -219,6 +219,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ScenePresence> GetLinkAvatars(int linkType)
|
||||||
|
{
|
||||||
|
List<ScenePresence> ret = new List<ScenePresence>();
|
||||||
|
if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
|
||||||
|
|
||||||
|
switch (linkType)
|
||||||
|
{
|
||||||
|
case ScriptBaseClass.LINK_SET:
|
||||||
|
return avs;
|
||||||
|
|
||||||
|
case ScriptBaseClass.LINK_ROOT:
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
case ScriptBaseClass.LINK_ALL_OTHERS:
|
||||||
|
return avs;
|
||||||
|
|
||||||
|
case ScriptBaseClass.LINK_ALL_CHILDREN:
|
||||||
|
return avs;
|
||||||
|
|
||||||
|
case ScriptBaseClass.LINK_THIS:
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (linkType < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
int partCount = m_host.ParentGroup.GetPartCount();
|
||||||
|
|
||||||
|
if (linkType <= partCount)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
linkType = linkType - partCount;
|
||||||
|
if (linkType > avs.Count)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret.Add(avs[linkType-1]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<SceneObjectPart> GetLinkParts(int linkType)
|
public List<SceneObjectPart> GetLinkParts(int linkType)
|
||||||
{
|
{
|
||||||
List<SceneObjectPart> ret = new List<SceneObjectPart>();
|
List<SceneObjectPart> ret = new List<SceneObjectPart>();
|
||||||
|
@ -7152,6 +7203,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
List<SceneObjectPart> parts = GetLinkParts(linknumber);
|
List<SceneObjectPart> parts = GetLinkParts(linknumber);
|
||||||
|
List<ScenePresence> avatars = GetLinkAvatars(linknumber);
|
||||||
if (parts.Count>0)
|
if (parts.Count>0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -7165,6 +7217,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = false;
|
parts[0].ParentGroup.areUpdatesSuspended = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (avatars.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (ScenePresence avatar in avatars)
|
||||||
|
SetPrimParams(avatar, rules);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
|
public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
|
||||||
|
@ -7172,6 +7229,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
llSetLinkPrimitiveParams(linknumber, rules);
|
llSetLinkPrimitiveParams(linknumber, rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void SetPrimParams(ScenePresence av, LSL_List rules)
|
||||||
|
{
|
||||||
|
//This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
|
||||||
|
//We only support PRIM_POSITION and PRIM_ROTATION
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
while (idx < rules.Length)
|
||||||
|
{
|
||||||
|
int code = rules.GetLSLIntegerItem(idx++);
|
||||||
|
|
||||||
|
int remain = rules.Length - idx;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case (int)ScriptBaseClass.PRIM_POSITION:
|
||||||
|
if (remain < 1)
|
||||||
|
return;
|
||||||
|
LSL_Vector v;
|
||||||
|
v = rules.GetVector3Item(idx++);
|
||||||
|
av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
|
||||||
|
av.SendFullUpdateToAllClients();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (int)ScriptBaseClass.PRIM_ROTATION:
|
||||||
|
if (remain < 1)
|
||||||
|
return;
|
||||||
|
LSL_Rotation r;
|
||||||
|
r = rules.GetQuaternionItem(idx++);
|
||||||
|
av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
|
||||||
|
av.SendFullUpdateToAllClients();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
|
protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
|
||||||
{
|
{
|
||||||
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
|
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
|
||||||
|
|
Loading…
Reference in New Issue