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.

avinationmerge
Tom Grimshaw 2010-06-19 10:06:09 -07:00
parent 6d8da699b2
commit 49d7d8534c
3 changed files with 188 additions and 4 deletions

View File

@ -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>

View File

@ -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) +

View File

@ -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)