diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index dd0858a5c8..174d20aedc 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -643,14 +643,14 @@ 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, - bool attachment, uint AttachmentPoint); + bool attachment, uint AttachmentPoint, LLUUID AssetId); 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); void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, - LLQuaternion rotation, byte state); + LLQuaternion rotation, byte state, LLUUID AssetId); void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation, LLVector3 velocity, LLVector3 rotationalvelocity); diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 35b248a89e..fb9d638ec9 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -2018,13 +2018,13 @@ namespace OpenSim.Region.ClientStack SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, flags, objectID, ownerID, text, color, parentID, particleSystem, - rotation, clickAction, textureanim, false,(uint)0); + rotation, clickAction, textureanim, false,(uint)0, LLUUID.Zero); } 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, bool attachment, uint AttachPoint) + LLQuaternion rotation, byte clickAction, byte[] textureanim, bool attachment, uint AttachPoint, LLUUID AssetId) { ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); // TODO: don't create new blocks if recycling an old packet @@ -2063,7 +2063,7 @@ namespace OpenSim.Region.ClientStack // Item from inventory??? outPacket.ObjectData[0].NameValue = - Helpers.StringToField("AttachItemID STRING RW SV " + objectID.UUID); + Helpers.StringToField("AttachItemID STRING RW SV " + AssetId.UUID); outPacket.ObjectData[0].State = (byte)((AttachPoint % 16) * 16 + (AttachPoint / 16)); } @@ -2093,7 +2093,7 @@ namespace OpenSim.Region.ClientStack /// /// public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, - LLQuaternion rotation, byte state) + LLQuaternion rotation, byte state, LLUUID AssetId) { LLVector3 velocity = new LLVector3(0f, 0f, 0f); LLVector3 rotationalvelocity = new LLVector3(0f, 0f, 0f); @@ -2102,7 +2102,7 @@ namespace OpenSim.Region.ClientStack terse.RegionData.RegionHandle = regionHandle; terse.RegionData.TimeDilation = timeDilation; terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; - terse.ObjectData[0] = CreatePrimImprovedBlock(localID, position, rotation, velocity, rotationalvelocity, state); + terse.ObjectData[0] = CreatePrimImprovedBlock(localID, position, rotation, velocity, rotationalvelocity, state); // AssetID should fall into here probably somehow... terse.Header.Reliable = false; OutPacket(terse, ThrottleOutPacketType.Task); } @@ -2305,8 +2305,9 @@ namespace OpenSim.Region.ClientStack bytes[i++] = (byte)((rvely >> 8) % 256); bytes[i++] = (byte)(rvelz % 256); bytes[i++] = (byte)((rvelz >> 8) % 256); - dat.Data = bytes; + + return dat; } diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index cbe5798f2b..e76cf70e18 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs @@ -322,6 +322,22 @@ namespace OpenSim.Region.Environment.Scenes // Calls attach with a Zero position AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, LLVector3.Zero); } + public void RezSingleAttachment(IClientAPI remoteClient, LLUUID itemID, uint AttachmentPt, + uint ItemFlags, uint NextOwnerMask) + { + SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient, itemID, LLVector3.Zero, LLVector3.Zero, LLUUID.Zero, (byte)1, true, + (uint)(PermissionMask.Copy | PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer), + (uint)(PermissionMask.Copy | PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer), + (uint)(PermissionMask.Copy | PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer), + ItemFlags, false, false, remoteClient.AgentId, true); + + if (objatt != null) + { + AttachObject(remoteClient,objatt.LocalId,AttachmentPt,new LLQuaternion(0,0,0,1),objatt.AbsolutePosition); + objatt.ScheduleGroupForFullUpdate(); + } + + } public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot, LLVector3 attachPos) { @@ -338,14 +354,25 @@ namespace OpenSim.Region.Environment.Scenes // Check object for stored attachment point AttachmentPt = (uint)group.GetAttachmentPoint(); + // if we still didn't find a suitable attachment point....... if (AttachmentPt == 0) { AttachmentPt = (uint)AttachmentPoint.LeftHand; + attachPos = LLVector3.Zero; } + } + // Saves and gets assetID + if (group.GetFromAssetID() == LLUUID.Zero) + { + LLUUID newAssetID = m_parentScene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId); + + // sets assetID so client can show asset as 'attached' in inventory + group.SetFromAssetID(newAssetID); + } group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos); } diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index 67d3dfb9b8..a3e26b4f11 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -1002,9 +1002,65 @@ namespace OpenSim.Region.Environment.Scenes } } } + public LLUUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, LLUUID AgentId) + { + SceneObjectGroup objectGroup = grp; + if (objectGroup != null) + { + string sceneObjectXml = objectGroup.ToXmlString(); + + CachedUserInfo userInfo = + CommsManager.UserProfileCacheService.GetUserDetails(AgentId); + if (userInfo != null) + { + AssetBase asset = CreateAsset( + objectGroup.GetPartName(objectGroup.LocalId), + objectGroup.GetPartDescription(objectGroup.LocalId), + (sbyte)InventoryType.Object, + (sbyte)AssetType.Object, + Helpers.StringToField(sceneObjectXml)); + AssetCache.AddAsset(asset); + + InventoryItemBase item = new InventoryItemBase(); + item.Creator = objectGroup.RootPart.CreatorID; + item.Owner = remoteClient.AgentId; + item.ID = LLUUID.Random(); + item.AssetID = asset.FullID; + item.Description = asset.Description; + item.Name = asset.Name; + item.AssetType = asset.Type; + item.InvType = asset.InvType; + + // Sticking it in root folder for now.. objects folder later? + + item.Folder = userInfo.RootFolder.ID;// DeRezPacket.AgentBlock.DestinationID; + item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; + if (remoteClient.AgentId != objectGroup.RootPart.OwnerID) + { + item.BasePermissions = objectGroup.RootPart.NextOwnerMask; + item.CurrentPermissions = objectGroup.RootPart.NextOwnerMask; + item.NextPermissions = objectGroup.RootPart.NextOwnerMask; + } + else + { + item.BasePermissions = objectGroup.RootPart.BaseMask; + item.CurrentPermissions = objectGroup.RootPart.OwnerMask; + item.NextPermissions = objectGroup.RootPart.NextOwnerMask; + } + + userInfo.AddItem(remoteClient.AgentId, item); + remoteClient.SendInventoryItemCreateUpdate(item); + return item.AssetID; + } + return LLUUID.Zero; + } + return LLUUID.Zero; + + } /// - /// Rez an object into a scene + /// Event Handler Rez an object into a scene + /// Calls the non-void event handler /// /// /// @@ -1024,6 +1080,38 @@ namespace OpenSim.Region.Environment.Scenes LLUUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, uint EveryoneMask, uint GroupMask, uint NextOwnerMask, uint ItemFlags, bool RezSelected, bool RemoveItem, LLUUID fromTaskID) + { + SceneObjectGroup sog = RezObject(remoteClient, itemID, RayEnd, RayStart, + RayTargetID, BypassRayCast, RayEndIsIntersection, + EveryoneMask, GroupMask, NextOwnerMask, ItemFlags, + RezSelected, RemoveItem, fromTaskID, false); + } + + + + /// + /// Returns SceneObjectGroup or null from asset request. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, LLUUID itemID, LLVector3 RayEnd, LLVector3 RayStart, + LLUUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, + uint EveryoneMask, uint GroupMask, uint NextOwnerMask, uint ItemFlags, + bool RezSelected, bool RemoveItem, LLUUID fromTaskID, bool attachment) { // Work out position details byte bRayEndIsIntersection = (byte)0; @@ -1042,9 +1130,9 @@ namespace OpenSim.Region.Environment.Scenes RayStart, RayEnd, RayTargetID, new LLQuaternion(0, 0, 0, 1), BypassRayCast, bRayEndIsIntersection); - if (!PermissionsMngr.CanRezObject(remoteClient.AgentId, pos)) + if (!PermissionsMngr.CanRezObject(remoteClient.AgentId, pos) && !attachment) { - return; + return null; } // Rez object @@ -1064,7 +1152,14 @@ namespace OpenSim.Region.Environment.Scenes SceneObjectGroup group = new SceneObjectGroup(this, m_regionHandle, xmlData); group.ResetIDs(); AddEntity(group); - group.AbsolutePosition = pos; + + // if attachment we set it's asset id so object updates can reflect that + // if not, we set it's position in world. + if (!attachment) + group.AbsolutePosition = pos; + else + group.SetFromAssetID(itemID); + SceneObjectPart rootPart = group.GetChildPart(group.UUID); // Since renaming the item in the inventory does not affect the name stored @@ -1092,34 +1187,18 @@ namespace OpenSim.Region.Environment.Scenes group.ApplyPhysics(m_physicalPrim); group.StartScripts(); - //bool UsePhysics = (((rootPart.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) > 0)&& m_physicalPrim); - //if ((rootPart.ObjectFlags & (uint) LLObject.ObjectFlags.Phantom) == 0) - //{ - //PrimitiveBaseShape pbs = rootPart.Shape; - //rootPart.PhysActor = PhysicsScene.AddPrimShape( - //rootPart.Name, - //pbs, - //new PhysicsVector(rootPart.AbsolutePosition.X, rootPart.AbsolutePosition.Y, - // rootPart.AbsolutePosition.Z), - //new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z), - //new Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X, - // rootPart.RotationOffset.Y, rootPart.RotationOffset.Z), UsePhysics); + + if (!attachment) + rootPart.ScheduleFullUpdate(); - // rootPart.DoPhysicsPropertyUpdate(UsePhysics, true); - - // } - // - rootPart.ScheduleFullUpdate(); + return rootPart.ParentGroup; } } } } + return null; } - public void RezSingleAttachment(IClientAPI remoteClient, LLUUID itemID, uint AttachmentPt, - uint ItemFlags, uint NextOwnerMask) - { - Console.WriteLine("RezSingleAttachment: unimplemented yet"); - } + } } diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index b16b4aa428..a9fa93ec7e 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1559,7 +1559,7 @@ namespace OpenSim.Region.Environment.Scenes client.OnGrabUpdate += m_innerScene.MoveObject; client.OnDeRezObject += DeRezObject; client.OnRezObject += RezObject; - client.OnRezSingleAttachmentFromInv += RezSingleAttachment; + client.OnRezSingleAttachmentFromInv += m_innerScene.RezSingleAttachment; client.OnObjectAttach += m_innerScene.AttachObject; client.OnObjectDetach += m_innerScene.DetachObject; client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest; diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 7596e24594..2493ed824e 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Drawing; using System.IO; using System.Xml; +using System.Xml.Serialization; using Axiom.Math; using libsecondlife; using libsecondlife.Packets; @@ -89,6 +90,7 @@ namespace OpenSim.Region.Environment.Scenes /// since the group's last persistent backup /// public bool HasGroupChanged = false; + private LLVector3 lastPhysGroupPos; @@ -484,6 +486,26 @@ namespace OpenSim.Region.Environment.Scenes { } + public void SetFromAssetID(LLUUID AssetId) + { + lock (m_parts) + { + foreach (SceneObjectPart part in m_parts.Values) + { + part.fromAssetID = AssetId; + } + } + } + + public LLUUID GetFromAssetID() + { + if (m_rootPart != null) + { + return m_rootPart.fromAssetID; + } + return LLUUID.Zero; + } + /// /// Hooks this object up to the backup event so that it is persisted to the database when the update thread executes. /// diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 50c96e13d9..0db9b91ea6 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -104,6 +104,7 @@ namespace OpenSim.Region.Environment.Scenes [XmlIgnore] public uint m_attachmentPoint = (byte)0; [XmlIgnore] public LLUUID m_attachedAvatar = LLUUID.Zero; [XmlIgnore] public LLVector3 m_attachedPos = LLVector3.Zero; + [XmlIgnore] public LLUUID fromAssetID = LLUUID.Zero; public Int32 CreationDate; public uint ParentID = 0; @@ -2251,7 +2252,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_IsAttachment, m_attachmentPoint); + m_text, color, ParentID, m_particleSystem, lRot, m_clickAction, m_TextureAnimation, m_IsAttachment, m_attachmentPoint,fromAssetID); } /// Terse updates @@ -2297,7 +2298,7 @@ namespace OpenSim.Region.Environment.Scenes LLQuaternion mRot = RotationOffset; 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, fromAssetID); } else { @@ -2312,13 +2313,13 @@ namespace OpenSim.Region.Environment.Scenes LLQuaternion mRot = RotationOffset; if (m_IsAttachment) { - remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, (byte)((m_attachmentPoint % 16) * 16 + (m_attachmentPoint / 16))); + remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, (byte)((m_attachmentPoint % 16) * 16 + (m_attachmentPoint / 16)),fromAssetID); } else { 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, fromAssetID); } else { diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index a12404a53a..4dc13f574c 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -383,11 +383,11 @@ namespace OpenSim.Region.Examples.SimpleModule LLUUID objectID, LLUUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, LLQuaternion rotation, byte clickAction, byte[] textureanimation, - bool attachment, uint AttachmentPoint) + bool attachment, uint AttachmentPoint, LLUUID AssetId) { } public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, - LLVector3 position, LLQuaternion rotation, byte state) + LLVector3 position, LLQuaternion rotation, byte state, LLUUID AssetId) { }