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)
{
}