* Adds much better support for attachments that you right click on in world.

* Your friends can see your attachments now.  People who appear in the sim after you've attached something can also see your attachments.
* You can position & rotate your attachments now.  Positions do *not* save.
* You can detach attachments now the regular way.
* Attachments do not cross into other regions with you..(this isn't too far off)
* Updated ODE to not request terse updates on child prim.
0.6.0-stable
Teravus Ovares 2008-04-24 11:32:41 +00:00
parent c49b25f19e
commit aa8aee90a3
8 changed files with 177 additions and 27 deletions

View File

@ -454,6 +454,7 @@ namespace OpenSim.Framework
event AvatarNowWearing OnAvatarNowWearing; event AvatarNowWearing OnAvatarNowWearing;
event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
event ObjectAttach OnObjectAttach; event ObjectAttach OnObjectAttach;
event ObjectDeselect OnObjectDetach;
event StartAnim OnStartAnim; event StartAnim OnStartAnim;
event StopAnim OnStopAnim; event StopAnim OnStopAnim;
event LinkObjects OnLinkObjects; event LinkObjects OnLinkObjects;
@ -638,7 +639,8 @@ namespace OpenSim.Framework
void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, byte[] color, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, byte[] color,
uint parentID, byte[] particleSystem, LLQuaternion rotation, byte clickAction, byte[] textureanimation); uint parentID, byte[] particleSystem, LLQuaternion rotation, byte clickAction, byte[] textureanimation,
bool attachment, uint AttachmentPoint);
void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, byte[] color, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, byte[] color,

View File

@ -235,6 +235,7 @@ namespace OpenSim.Region.ClientStack
private ScriptAnswer handlerScriptAnswer = null; private ScriptAnswer handlerScriptAnswer = null;
private RequestPayPrice handlerRequestPayPrice = null; private RequestPayPrice handlerRequestPayPrice = null;
private ObjectDeselect handlerObjectDetach = null;
/* Properties */ /* Properties */
@ -689,6 +690,7 @@ namespace OpenSim.Region.ClientStack
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event ObjectAttach OnObjectAttach; public event ObjectAttach OnObjectAttach;
public event ObjectDeselect OnObjectDetach;
public event GenericCall2 OnCompleteMovementToRegion; public event GenericCall2 OnCompleteMovementToRegion;
public event UpdateAgent OnAgentUpdate; public event UpdateAgent OnAgentUpdate;
public event AgentRequestSit OnAgentRequestSit; public event AgentRequestSit OnAgentRequestSit;
@ -1989,6 +1991,7 @@ namespace OpenSim.Region.ClientStack
/// <param name="attachPoint"></param> /// <param name="attachPoint"></param>
public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint) public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint)
{ {
ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach); ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach);
Console.WriteLine("Attach object!"); Console.WriteLine("Attach object!");
// TODO: don't create new blocks if recycling an old packet // TODO: don't create new blocks if recycling an old packet
@ -2013,13 +2016,13 @@ namespace OpenSim.Region.ClientStack
SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, flags, SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, flags,
objectID, ownerID, text, color, parentID, particleSystem, objectID, ownerID, text, color, parentID, particleSystem,
rotation, clickAction, textureanim); rotation, clickAction, textureanim, false,(uint)0);
} }
public void SendPrimitiveToClient( public void SendPrimitiveToClient(
ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos,
uint flags, uint flags,
LLUUID objectID, LLUUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, LLUUID objectID, LLUUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem,
LLQuaternion rotation, byte clickAction, byte[] textureanim) LLQuaternion rotation, byte clickAction, byte[] textureanim, bool attachment, uint AttachPoint)
{ {
ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
// TODO: don't create new blocks if recycling an old packet // TODO: don't create new blocks if recycling an old packet
@ -2050,6 +2053,18 @@ namespace OpenSim.Region.ClientStack
outPacket.ObjectData[0].ClickAction = clickAction; outPacket.ObjectData[0].ClickAction = clickAction;
//outPacket.ObjectData[0].Flags = 0; //outPacket.ObjectData[0].Flags = 0;
if (attachment)
{
// Necessary???
outPacket.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 2);
outPacket.ObjectData[0].JointPivot = new LLVector3(0, 0, 0);
// Item from inventory???
outPacket.ObjectData[0].NameValue =
Helpers.StringToField("AttachItemID STRING RW SV " + objectID.UUID);
outPacket.ObjectData[0].State = (byte)(((byte)AttachPoint) << 4);
}
// Sound Radius // Sound Radius
outPacket.ObjectData[0].Radius = 20; outPacket.ObjectData[0].Radius = 20;
@ -3437,6 +3452,21 @@ namespace OpenSim.Region.ClientStack
} }
} }
break;
case PacketType.ObjectDetach:
ObjectDetachPacket dett = (ObjectDetachPacket)Pack;
for (int j = 0; j < dett.ObjectData.Length; j++)
{
uint obj = dett.ObjectData[j].ObjectLocalID;
handlerObjectDetach = OnObjectDetach;
if (handlerObjectDetach != null)
{
handlerObjectDetach(obj,this);
}
}
break; break;
case PacketType.SetAlwaysRun: case PacketType.SetAlwaysRun:
SetAlwaysRunPacket run = (SetAlwaysRunPacket)Pack; SetAlwaysRunPacket run = (SetAlwaysRunPacket)Pack;

View File

@ -293,8 +293,45 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
} }
public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
{
List<EntityBase> EntityList = GetEntities();
foreach (EntityBase obj in EntityList)
{
if (obj is SceneObjectGroup)
{
if (((SceneObjectGroup)obj).LocalId == objectLocalID)
{
SceneObjectGroup group = (SceneObjectGroup)obj;
group.DetachToGround();
}
}
}
}
public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot) public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot)
{
List<EntityBase> EntityList = GetEntities();
foreach (EntityBase obj in EntityList)
{
if (obj is SceneObjectGroup)
{
if (((SceneObjectGroup)obj).LocalId == objectLocalID)
{
SceneObjectGroup group = (SceneObjectGroup)obj;
group.AttachToAgent(remoteClient.AgentId, AttachmentPt);
}
}
}
}
// Use the above method.
public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot,
bool deadMethod)
{ {
Console.WriteLine("Attaching object " + objectLocalID + " to " + AttachmentPt); Console.WriteLine("Attaching object " + objectLocalID + " to " + AttachmentPt);
SceneObjectPart p = GetSceneObjectPart(objectLocalID); SceneObjectPart p = GetSceneObjectPart(objectLocalID);
@ -1005,7 +1042,14 @@ namespace OpenSim.Region.Environment.Scenes
SceneObjectGroup group = GetGroupByPrim(localID); SceneObjectGroup group = GetGroupByPrim(localID);
if (group != null) if (group != null)
{ {
LLVector3 oldPos = group.AbsolutePosition; LLVector3 oldPos = group.AbsolutePosition;
if (group.RootPart.m_IsAttachment)
{
group.UpdateGroupPosition(pos);
}
else
{
if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos)) if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos))
{ {
group.SendGroupTerseUpdate(); group.SendGroupTerseUpdate();
@ -1017,6 +1061,7 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
} }
}
/// <summary> /// <summary>
/// ///

View File

@ -1528,6 +1528,7 @@ namespace OpenSim.Region.Environment.Scenes
client.OnRezObject += RezObject; client.OnRezObject += RezObject;
client.OnRezSingleAttachmentFromInv += RezSingleAttachment; client.OnRezSingleAttachmentFromInv += RezSingleAttachment;
client.OnObjectAttach += m_innerScene.AttachObject; client.OnObjectAttach += m_innerScene.AttachObject;
client.OnObjectDetach += m_innerScene.DetachObject;
client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest; client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest;
client.OnObjectDescription += m_innerScene.PrimDescription; client.OnObjectDescription += m_innerScene.PrimDescription;
client.OnObjectName += m_innerScene.PrimName; client.OnObjectName += m_innerScene.PrimName;

View File

@ -180,7 +180,7 @@ namespace OpenSim.Region.Environment.Scenes
set set
{ {
LLVector3 val = value; LLVector3 val = value;
if (val.X > 257f || val.X < -1f || val.Y > 257f || val.Y < -1f) if ((val.X > 257f || val.X < -1f || val.Y > 257f || val.Y < -1f) && !m_rootPart.m_IsAttachment)
{ {
m_scene.CrossPrimGroupIntoNewRegion(val, this); m_scene.CrossPrimGroupIntoNewRegion(val, this);
} }
@ -612,6 +612,42 @@ namespace OpenSim.Region.Environment.Scenes
m_rootPart = part; m_rootPart = part;
} }
public void AttachToAgent(LLUUID agentID, uint attachmentpoint)
{
ScenePresence avatar = m_scene.GetScenePresence(agentID);
if (avatar != null)
{
m_rootPart.m_attachedAvatar = agentID;
m_rootPart.SetParentLocalId(avatar.LocalId);
m_rootPart.SetAttachmentPoint(attachmentpoint);
m_rootPart.m_IsAttachment = true;
if (m_rootPart.PhysActor != null)
{
m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor);
m_rootPart.PhysActor = null;
AbsolutePosition = LLVector3.Zero;
}
m_rootPart.ScheduleFullUpdate();
}
}
public void DetachToGround()
{
ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.m_attachedAvatar);
LLVector3 detachedpos = new LLVector3(127f,127f,127f);
if (avatar != null)
{
detachedpos = avatar.AbsolutePosition;
}
AbsolutePosition = detachedpos;
m_rootPart.m_attachedAvatar = LLUUID.Zero;
m_rootPart.SetParentLocalId(0);
m_rootPart.SetAttachmentPoint((byte)0);
m_rootPart.m_IsAttachment = false;
m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_scene.m_physicalPrim);
m_rootPart.ScheduleFullUpdate();
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

View File

@ -99,6 +99,11 @@ namespace OpenSim.Region.Environment.Scenes
// TODO: This needs to be persisted in next XML version update! // TODO: This needs to be persisted in next XML version update!
[XmlIgnore] public int[] PayPrice = {0,0,0,0,0}; [XmlIgnore] public int[] PayPrice = {0,0,0,0,0};
[XmlIgnore] public bool m_IsAttachment = false;
[XmlIgnore] public uint m_attachmentPoint = (byte)0;
[XmlIgnore] public LLUUID m_attachedAvatar = LLUUID.Zero;
public Int32 CreationDate; public Int32 CreationDate;
public uint ParentID = 0; public uint ParentID = 0;
@ -1272,6 +1277,16 @@ namespace OpenSim.Region.Environment.Scenes
return returnresult; return returnresult;
} }
// Use this for attachments! LocalID should be avatar's localid
public void SetParentLocalId(uint localID)
{
ParentID = localID;
}
public void SetAttachmentPoint(uint AttachmentPoint)
{
m_attachmentPoint = AttachmentPoint;
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
@ -2212,7 +2227,7 @@ namespace OpenSim.Region.Environment.Scenes
byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A};
remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, lPos, clientFlags, m_uuid, remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, lPos, clientFlags, m_uuid,
OwnerID, OwnerID,
m_text, color, ParentID, m_particleSystem, lRot, m_clickAction, m_TextureAnimation); m_text, color, ParentID, m_particleSystem, lRot, m_clickAction, m_TextureAnimation, m_IsAttachment, m_attachmentPoint);
} }
/// Terse updates /// Terse updates
@ -2271,6 +2286,12 @@ namespace OpenSim.Region.Environment.Scenes
public void SendTerseUpdateToClient(IClientAPI remoteClient, LLVector3 lPos) public void SendTerseUpdateToClient(IClientAPI remoteClient, LLVector3 lPos)
{ {
LLQuaternion mRot = RotationOffset; LLQuaternion mRot = RotationOffset;
if (m_IsAttachment)
{
remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, (byte)(((byte)m_attachmentPoint) << 4));
}
else
{
if ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) == 0) if ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) == 0)
{ {
remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Shape.State); remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Shape.State);
@ -2282,6 +2303,7 @@ namespace OpenSim.Region.Environment.Scenes
//System.Console.WriteLine("LID: " + LocalID + "RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString()); //System.Console.WriteLine("LID: " + LocalID + "RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString());
} }
} }
}
#endregion #endregion

View File

@ -61,6 +61,7 @@ namespace OpenSim.Region.Examples.SimpleModule
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event ObjectAttach OnObjectAttach; public event ObjectAttach OnObjectAttach;
public event ObjectDeselect OnObjectDetach;
public event StartAnim OnStartAnim; public event StartAnim OnStartAnim;
public event StopAnim OnStopAnim; public event StopAnim OnStopAnim;
public event LinkObjects OnLinkObjects; public event LinkObjects OnLinkObjects;
@ -380,7 +381,8 @@ namespace OpenSim.Region.Examples.SimpleModule
PrimitiveBaseShape primShape, LLVector3 pos, uint flags, PrimitiveBaseShape primShape, LLVector3 pos, uint flags,
LLUUID objectID, LLUUID ownerID, string text, byte[] color, LLUUID objectID, LLUUID ownerID, string text, byte[] color,
uint parentID, uint parentID,
byte[] particleSystem, LLQuaternion rotation, byte clickAction, byte[] textureanimation) byte[] particleSystem, LLQuaternion rotation, byte clickAction, byte[] textureanimation,
bool attachment, uint AttachmentPoint)
{ {
} }
public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID,

View File

@ -819,7 +819,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim) if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim)
{ {
OdePrim obj = (OdePrim)m_taintparent; OdePrim obj = (OdePrim)m_taintparent;
if (obj.Body != (IntPtr)0 && Body != (IntPtr)0) if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body)
{ {
_linkJointGroup = d.JointGroupCreate(0); _linkJointGroup = d.JointGroupCreate(0);
m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup); m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup);
@ -1098,7 +1098,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (_parent != null) if (_parent != null)
{ {
OdePrim odParent = (OdePrim)_parent; OdePrim odParent = (OdePrim)_parent;
if (Body != (IntPtr)0 && odParent.Body != (IntPtr)0) if (Body != (IntPtr)0 && odParent.Body != (IntPtr)0 && Body != odParent.Body)
{ {
m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup); m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup);
d.JointAttach(m_linkJoint, Body, odParent.Body); d.JointAttach(m_linkJoint, Body, odParent.Body);
@ -1978,11 +1978,13 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
_position = l_position; _position = l_position;
//_parent_scene.remActivePrim(this); //_parent_scene.remActivePrim(this);
if (_parent == null)
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
return; return;
} }
else else
{ {
if (_parent == null)
base.RaiseOutOfBounds(l_position); base.RaiseOutOfBounds(l_position);
return; return;
} }
@ -1998,6 +2000,7 @@ namespace OpenSim.Region.Physics.OdePlugin
//IsPhysical = false; //IsPhysical = false;
if (_parent == null)
base.RaiseOutOfBounds(_position); base.RaiseOutOfBounds(_position);
_acceleration.X = 0; _acceleration.X = 0;
@ -2010,7 +2013,10 @@ namespace OpenSim.Region.Physics.OdePlugin
m_rotationalVelocity.X = 0; m_rotationalVelocity.X = 0;
m_rotationalVelocity.Y = 0; m_rotationalVelocity.Y = 0;
m_rotationalVelocity.Z = 0; m_rotationalVelocity.Z = 0;
if (_parent == null)
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
m_throttleUpdates = false; m_throttleUpdates = false;
throttleCounter = 0; throttleCounter = 0;
_zeroFlag = true; _zeroFlag = true;
@ -2054,14 +2060,20 @@ namespace OpenSim.Region.Physics.OdePlugin
m_throttleUpdates = false; m_throttleUpdates = false;
throttleCounter = 0; throttleCounter = 0;
m_rotationalVelocity = pv; m_rotationalVelocity = pv;
if (_parent == null)
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
m_lastUpdateSent = true; m_lastUpdateSent = true;
} }
} }
else else
{ {
if (lastZeroFlag != _zeroFlag) if (lastZeroFlag != _zeroFlag)
{
if (_parent == null)
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
}
m_lastVelocity = _velocity; m_lastVelocity = _velocity;
@ -2092,7 +2104,7 @@ namespace OpenSim.Region.Physics.OdePlugin
m_lastUpdateSent = false; m_lastUpdateSent = false;
if (!m_throttleUpdates || throttleCounter > 15) if (!m_throttleUpdates || throttleCounter > 15)
{ {
if (_parent == null)
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
} }
else else