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