From aa8aee90a35458f1f601ca23e2298b212782d0a3 Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Thu, 24 Apr 2008 11:32:41 +0000
Subject: * 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.
---
OpenSim/Framework/IClientAPI.cs | 4 +-
OpenSim/Region/ClientStack/ClientView.cs | 34 ++++++++++++-
OpenSim/Region/Environment/Scenes/InnerScene.cs | 55 ++++++++++++++++++++--
OpenSim/Region/Environment/Scenes/Scene.cs | 1 +
.../Region/Environment/Scenes/SceneObjectGroup.cs | 38 ++++++++++++++-
.../Region/Environment/Scenes/SceneObjectPart.cs | 34 ++++++++++---
.../Region/Examples/SimpleModule/MyNpcCharacter.cs | 4 +-
OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 32 +++++++++----
8 files changed, 176 insertions(+), 26 deletions(-)
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 4faaad6..28047e7 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -454,6 +454,7 @@ namespace OpenSim.Framework
event AvatarNowWearing OnAvatarNowWearing;
event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
event ObjectAttach OnObjectAttach;
+ event ObjectDeselect OnObjectDetach;
event StartAnim OnStartAnim;
event StopAnim OnStopAnim;
event LinkObjects OnLinkObjects;
@@ -638,7 +639,8 @@ namespace OpenSim.Framework
void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
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,
LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, byte[] color,
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs
index 216633f..0a6431d 100644
--- a/OpenSim/Region/ClientStack/ClientView.cs
+++ b/OpenSim/Region/ClientStack/ClientView.cs
@@ -235,6 +235,7 @@ namespace OpenSim.Region.ClientStack
private ScriptAnswer handlerScriptAnswer = null;
private RequestPayPrice handlerRequestPayPrice = null;
+ private ObjectDeselect handlerObjectDetach = null;
/* Properties */
@@ -689,6 +690,7 @@ namespace OpenSim.Region.ClientStack
public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event ObjectAttach OnObjectAttach;
+ public event ObjectDeselect OnObjectDetach;
public event GenericCall2 OnCompleteMovementToRegion;
public event UpdateAgent OnAgentUpdate;
public event AgentRequestSit OnAgentRequestSit;
@@ -1989,6 +1991,7 @@ namespace OpenSim.Region.ClientStack
///
public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint)
{
+
ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach);
Console.WriteLine("Attach object!");
// 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,
objectID, ownerID, text, color, parentID, particleSystem,
- rotation, clickAction, textureanim);
+ rotation, clickAction, textureanim, false,(uint)0);
}
public void SendPrimitiveToClient(
ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos,
uint flags,
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);
// 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].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
outPacket.ObjectData[0].Radius = 20;
@@ -3438,6 +3453,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;
case PacketType.SetAlwaysRun:
SetAlwaysRunPacket run = (SetAlwaysRunPacket)Pack;
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs
index 2b28b2a..668e50f 100644
--- a/OpenSim/Region/Environment/Scenes/InnerScene.cs
+++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs
@@ -293,9 +293,46 @@ namespace OpenSim.Region.Environment.Scenes
}
}
}
+ public void DetachObject(uint objectLocalID, IClientAPI remoteClient)
+ {
+ List 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)
{
+ List 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);
SceneObjectPart p = GetSceneObjectPart(objectLocalID);
if (p != null)
@@ -1005,15 +1042,23 @@ namespace OpenSim.Region.Environment.Scenes
SceneObjectGroup group = GetGroupByPrim(localID);
if (group != null)
{
+
LLVector3 oldPos = group.AbsolutePosition;
- if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos))
+ if (group.RootPart.m_IsAttachment)
{
- group.SendGroupTerseUpdate();
- return;
+ group.UpdateGroupPosition(pos);
}
- if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
+ else
{
- group.UpdateGroupPosition(pos);
+ if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos))
+ {
+ group.SendGroupTerseUpdate();
+ return;
+ }
+ if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID))
+ {
+ group.UpdateGroupPosition(pos);
+ }
}
}
}
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index c41a445..21c8991 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -1528,6 +1528,7 @@ namespace OpenSim.Region.Environment.Scenes
client.OnRezObject += RezObject;
client.OnRezSingleAttachmentFromInv += RezSingleAttachment;
client.OnObjectAttach += m_innerScene.AttachObject;
+ client.OnObjectDetach += m_innerScene.DetachObject;
client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest;
client.OnObjectDescription += m_innerScene.PrimDescription;
client.OnObjectName += m_innerScene.PrimName;
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index 4f65cc7..27639ea 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -180,7 +180,7 @@ namespace OpenSim.Region.Environment.Scenes
set
{
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);
}
@@ -612,6 +612,42 @@ namespace OpenSim.Region.Environment.Scenes
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();
+ }
///
///
///
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
index e2cb3ac..099d0f0 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -99,6 +99,11 @@ namespace OpenSim.Region.Environment.Scenes
// TODO: This needs to be persisted in next XML version update!
[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 uint ParentID = 0;
@@ -1271,7 +1276,17 @@ namespace OpenSim.Region.Environment.Scenes
}
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;
+ }
///
///
///
@@ -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};
remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, lPos, clientFlags, m_uuid,
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
@@ -2271,15 +2286,22 @@ namespace OpenSim.Region.Environment.Scenes
public void SendTerseUpdateToClient(IClientAPI remoteClient, LLVector3 lPos)
{
LLQuaternion mRot = RotationOffset;
- if ((ObjectFlags & (uint) LLObject.ObjectFlags.Physics) == 0)
+ if (m_IsAttachment)
{
- 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, (byte)(((byte)m_attachmentPoint) << 4));
}
else
{
- remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity,
- RotationalVelocity);
- //System.Console.WriteLine("LID: " + LocalID + "RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString());
+ if ((ObjectFlags & (uint)LLObject.ObjectFlags.Physics) == 0)
+ {
+ remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Shape.State);
+ }
+ else
+ {
+ remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity,
+ RotationalVelocity);
+ //System.Console.WriteLine("LID: " + LocalID + "RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString());
+ }
}
}
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index c4409bc..0aa3240 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -61,6 +61,7 @@ namespace OpenSim.Region.Examples.SimpleModule
public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event ObjectAttach OnObjectAttach;
+ public event ObjectDeselect OnObjectDetach;
public event StartAnim OnStartAnim;
public event StopAnim OnStopAnim;
public event LinkObjects OnLinkObjects;
@@ -380,7 +381,8 @@ namespace OpenSim.Region.Examples.SimpleModule
PrimitiveBaseShape primShape, LLVector3 pos, uint flags,
LLUUID objectID, LLUUID ownerID, string text, byte[] color,
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,
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 7a9734c..947466f 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -819,7 +819,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim)
{
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);
m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup);
@@ -1098,7 +1098,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (_parent != null)
{
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);
d.JointAttach(m_linkJoint, Body, odParent.Body);
@@ -1978,12 +1978,14 @@ namespace OpenSim.Region.Physics.OdePlugin
{
_position = l_position;
//_parent_scene.remActivePrim(this);
- base.RequestPhysicsterseUpdate();
+ if (_parent == null)
+ base.RequestPhysicsterseUpdate();
return;
}
else
{
- base.RaiseOutOfBounds(l_position);
+ if (_parent == null)
+ base.RaiseOutOfBounds(l_position);
return;
}
}
@@ -1998,7 +2000,8 @@ namespace OpenSim.Region.Physics.OdePlugin
//IsPhysical = false;
- base.RaiseOutOfBounds(_position);
+ if (_parent == null)
+ base.RaiseOutOfBounds(_position);
_acceleration.X = 0;
_acceleration.Y = 0;
@@ -2010,7 +2013,10 @@ namespace OpenSim.Region.Physics.OdePlugin
m_rotationalVelocity.X = 0;
m_rotationalVelocity.Y = 0;
m_rotationalVelocity.Z = 0;
- base.RequestPhysicsterseUpdate();
+
+ if (_parent == null)
+ base.RequestPhysicsterseUpdate();
+
m_throttleUpdates = false;
throttleCounter = 0;
_zeroFlag = true;
@@ -2054,14 +2060,20 @@ namespace OpenSim.Region.Physics.OdePlugin
m_throttleUpdates = false;
throttleCounter = 0;
m_rotationalVelocity = pv;
- base.RequestPhysicsterseUpdate();
+
+ if (_parent == null)
+ base.RequestPhysicsterseUpdate();
+
m_lastUpdateSent = true;
}
}
else
{
if (lastZeroFlag != _zeroFlag)
- base.RequestPhysicsterseUpdate();
+ {
+ if (_parent == null)
+ base.RequestPhysicsterseUpdate();
+ }
m_lastVelocity = _velocity;
@@ -2092,8 +2104,8 @@ namespace OpenSim.Region.Physics.OdePlugin
m_lastUpdateSent = false;
if (!m_throttleUpdates || throttleCounter > 15)
{
-
- base.RequestPhysicsterseUpdate();
+ if (_parent == null)
+ base.RequestPhysicsterseUpdate();
}
else
{
--
cgit v1.1