* Single Attachments now work from inventory. You can attach from inventory and detach from inventory.

* Detaching from right clicking in world, detaches to your inventory.
* If you go up to a prim and attach it from in world, it appears in your inventory.
* Attachment placement is saved when you detach them. 
* Choosing wear remembers your last attachment point from inventory.
* Wrote a method to update an inventory item's asset and sends the updated inventory item to the Client
* Wrote a recursive method to find the folder of a known existing inventory item.
* Removed a block on physics object position on creation.  This might crash a region or two, let us know via Mantis if your region crashes because of a physics out of bounds error.
* Drop doesn't work.  The menu item doesn't even come up.  Don't know why :P.
0.6.0-stable
Teravus Ovares 2008-04-27 20:10:28 +00:00
parent 56497c9615
commit 911e63765c
10 changed files with 241 additions and 34 deletions

View File

@ -272,8 +272,13 @@ namespace OpenSim.Framework.Communications.Cache
{ {
if (!RootFolder.Items.ContainsKey(itemInfo.ID)) if (!RootFolder.Items.ContainsKey(itemInfo.ID))
{ {
RootFolder.Items.Add(itemInfo.ID, itemInfo); RootFolder.Items.Add(itemInfo.ID, itemInfo);
} }
else
{
RootFolder.Items[itemInfo.ID] = itemInfo;
}
} }
} }
else else
@ -287,6 +292,10 @@ namespace OpenSim.Framework.Communications.Cache
{ {
folder.Items.Add(itemInfo.ID, itemInfo); folder.Items.Add(itemInfo.ID, itemInfo);
} }
else
{
folder.Items[itemInfo.ID] = itemInfo;
}
} }
} }
} }

View File

@ -455,6 +455,7 @@ namespace OpenSim.Framework
event SetAppearance OnSetAppearance; event SetAppearance OnSetAppearance;
event AvatarNowWearing OnAvatarNowWearing; event AvatarNowWearing OnAvatarNowWearing;
event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
event UUIDNameRequest OnDetachAttachmentIntoInv;
event ObjectAttach OnObjectAttach; event ObjectAttach OnObjectAttach;
event ObjectDeselect OnObjectDetach; event ObjectDeselect OnObjectDetach;
event StartAnim OnStartAnim; event StartAnim OnStartAnim;

View File

@ -145,6 +145,7 @@ namespace OpenSim.Region.ClientStack
private SetAppearance handlerSetAppearance = null; //OnSetAppearance; private SetAppearance handlerSetAppearance = null; //OnSetAppearance;
private AvatarNowWearing handlerAvatarNowWearing = null; //OnAvatarNowWearing; private AvatarNowWearing handlerAvatarNowWearing = null; //OnAvatarNowWearing;
private RezSingleAttachmentFromInv handlerRezSingleAttachment = null; //OnRezSingleAttachmentFromInv; private RezSingleAttachmentFromInv handlerRezSingleAttachment = null; //OnRezSingleAttachmentFromInv;
private UUIDNameRequest handlerDetachAttachmentIntoInv = null; // Detach attachment!
private ObjectAttach handlerObjectAttach = null; //OnObjectAttach; private ObjectAttach handlerObjectAttach = null; //OnObjectAttach;
private SetAlwaysRun handlerSetAlwaysRun = null; //OnSetAlwaysRun; private SetAlwaysRun handlerSetAlwaysRun = null; //OnSetAlwaysRun;
private GenericCall2 handlerCompleteMovementToRegion = null; //OnCompleteMovementToRegion; private GenericCall2 handlerCompleteMovementToRegion = null; //OnCompleteMovementToRegion;
@ -690,6 +691,7 @@ namespace OpenSim.Region.ClientStack
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event UUIDNameRequest OnDetachAttachmentIntoInv;
public event ObjectAttach OnObjectAttach; public event ObjectAttach OnObjectAttach;
public event ObjectDeselect OnObjectDetach; public event ObjectDeselect OnObjectDetach;
public event GenericCall2 OnCompleteMovementToRegion; public event GenericCall2 OnCompleteMovementToRegion;
@ -3441,6 +3443,18 @@ namespace OpenSim.Region.ClientStack
rez.ObjectData.AttachmentPt, rez.ObjectData.ItemFlags, rez.ObjectData.NextOwnerMask); rez.ObjectData.AttachmentPt, rez.ObjectData.ItemFlags, rez.ObjectData.NextOwnerMask);
} }
break;
case PacketType.DetachAttachmentIntoInv:
handlerDetachAttachmentIntoInv = OnDetachAttachmentIntoInv;
if (handlerDetachAttachmentIntoInv != null)
{
DetachAttachmentIntoInvPacket detachtoInv = (DetachAttachmentIntoInvPacket)Pack;
LLUUID itemID = detachtoInv.ObjectData.ItemID;
LLUUID ATTACH_agentID = detachtoInv.ObjectData.AgentID;
handlerDetachAttachmentIntoInv(itemID, this);
}
break; break;
case PacketType.ObjectAttach: case PacketType.ObjectAttach:
if (OnObjectAttach != null) if (OnObjectAttach != null)
@ -3451,7 +3465,10 @@ namespace OpenSim.Region.ClientStack
if (handlerObjectAttach != null) if (handlerObjectAttach != null)
{ {
handlerObjectAttach(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, att.ObjectData[0].Rotation); if (att.ObjectData.Length > 0)
{
handlerObjectAttach(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, att.ObjectData[0].Rotation);
}
} }
} }

View File

@ -304,7 +304,9 @@ namespace OpenSim.Region.Environment.Scenes
if (((SceneObjectGroup)obj).LocalId == objectLocalID) if (((SceneObjectGroup)obj).LocalId == objectLocalID)
{ {
SceneObjectGroup group = (SceneObjectGroup)obj; SceneObjectGroup group = (SceneObjectGroup)obj;
group.DetachToGround();
//group.DetachToGround();
DetachSingleAttachmentToInv(group.GetFromAssetID(),remoteClient);
} }
} }
} }
@ -339,6 +341,33 @@ namespace OpenSim.Region.Environment.Scenes
} }
// What makes this method odd and unique is it tries to detach using an LLUUID.... Yay for standards.
// To LocalId or LLUUID, *THAT* is the question. How now Brown LLUUID??
public void DetachSingleAttachmentToInv(LLUUID itemID, IClientAPI remoteClient)
{
if (itemID == LLUUID.Zero) // If this happened, someone made a mistake....
return;
List<EntityBase> EntityList = GetEntities();
foreach (EntityBase obj in EntityList)
{
if (obj is SceneObjectGroup)
{
if (((SceneObjectGroup)obj).GetFromAssetID() == itemID)
{
SceneObjectGroup group = (SceneObjectGroup)obj;
group.DetachToInventoryPrep();
m_log.Debug("[DETACH]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
m_parentScene.updateKnownAsset(remoteClient, group, group.GetFromAssetID(),group.OwnerID);
m_parentScene.DeleteSceneObjectGroup(group);
}
}
}
}
public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot, LLVector3 attachPos) public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot, LLVector3 attachPos)
{ {
List<EntityBase> EntityList = GetEntities(); List<EntityBase> EntityList = GetEntities();
@ -349,22 +378,37 @@ namespace OpenSim.Region.Environment.Scenes
if (((SceneObjectGroup)obj).LocalId == objectLocalID) if (((SceneObjectGroup)obj).LocalId == objectLocalID)
{ {
SceneObjectGroup group = (SceneObjectGroup)obj; SceneObjectGroup group = (SceneObjectGroup)obj;
// If the attachment point isn't the same as the one previously used
// set it's offset position = 0 so that it appears on the attachment point
// and not in a weird location somewhere unknown.
if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
{
attachPos = LLVector3.Zero;
}
// AttachmentPt 0 means the client chose to 'wear' the attachment.
if (AttachmentPt == 0) if (AttachmentPt == 0)
{ {
// Check object for stored attachment point // Check object for stored attachment point
AttachmentPt = (uint)group.GetAttachmentPoint(); AttachmentPt = (uint)group.GetAttachmentPoint();
// if we still didn't find a suitable attachment point.......
if (AttachmentPt == 0)
{
AttachmentPt = (uint)AttachmentPoint.LeftHand;
attachPos = LLVector3.Zero;
}
} }
// if we still didn't find a suitable attachment point.......
if (AttachmentPt == 0)
{
// Stick it on left hand with Zero Offset from the attachment point.
AttachmentPt = (uint)AttachmentPoint.LeftHand;
attachPos = LLVector3.Zero;
}
m_log.Debug("[ATTACH]: Using attachpoint: " + AttachmentPt.ToString());
// Saves and gets assetID // Saves and gets assetID
if (group.GetFromAssetID() == LLUUID.Zero) if (group.GetFromAssetID() == LLUUID.Zero)
{ {
@ -1071,12 +1115,12 @@ namespace OpenSim.Region.Environment.Scenes
if (group != null) if (group != null)
{ {
LLVector3 oldPos = group.AbsolutePosition; LLVector3 oldPos = group.AbsolutePosition;
if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos)) if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos) && !group.RootPart.m_IsAttachment)
{ {
group.SendGroupTerseUpdate(); group.SendGroupTerseUpdate();
return; return;
} }
if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID)) if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID) || group.RootPart.m_IsAttachment)
{ {
group.UpdateSinglePosition(pos, localID); group.UpdateSinglePosition(pos, localID);
} }
@ -1102,12 +1146,12 @@ namespace OpenSim.Region.Environment.Scenes
} }
else else
{ {
if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos)) if (!PermissionsMngr.CanObjectEntry(remoteClient.AgentId, oldPos, pos) && !group.RootPart.m_IsAttachment)
{ {
group.SendGroupTerseUpdate(); group.SendGroupTerseUpdate();
return; return;
} }
if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID)) if (PermissionsMngr.CanEditObjectPosition(remoteClient.AgentId, group.UUID) || group.RootPart.m_IsAttachment)
{ {
group.UpdateGroupPosition(pos); group.UpdateGroupPosition(pos);
} }

View File

@ -1002,6 +1002,93 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
} }
public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, LLUUID assetID, LLUUID agentID)
{
SceneObjectGroup objectGroup = grp;
if (objectGroup != null)
{
string sceneObjectXml = objectGroup.ToXmlString();
CachedUserInfo userInfo =
CommsManager.UserProfileCacheService.GetUserDetails(agentID);
if (userInfo != null)
{
Queue<InventoryFolderImpl> searchfolders = new Queue<InventoryFolderImpl>();
searchfolders.Enqueue(userInfo.RootFolder);
LLUUID foundFolder = userInfo.RootFolder.ID;
// search through folders to find the asset.
while (searchfolders.Count > 0)
{
InventoryFolderImpl fld = searchfolders.Dequeue();
lock (fld)
{
if (fld != null)
{
if (fld.Items.ContainsKey(assetID))
{
foundFolder = fld.ID;
searchfolders.Clear();
break;
}
else
{
foreach (InventoryFolderImpl subfld in fld.SubFolders.Values)
{
searchfolders.Enqueue(subfld);
}
}
}
}
}
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 = agentID;
item.ID = assetID;
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 = foundFolder;// DeRezPacket.AgentBlock.DestinationID;
item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
if (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(agentID, item);
// this gets called when the agent loggs off!
if (remoteClient != null)
{
remoteClient.SendInventoryItemCreateUpdate(item);
}
}
}
}
public LLUUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, LLUUID AgentId) public LLUUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, LLUUID AgentId)
{ {
SceneObjectGroup objectGroup = grp; SceneObjectGroup objectGroup = grp;
@ -1184,7 +1271,17 @@ namespace OpenSim.Region.Environment.Scenes
} }
rootPart.TrimPermissions(); rootPart.TrimPermissions();
group.ApplyPhysics(m_physicalPrim);
if (!attachment)
{
if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
{
group.RootPart.Shape.State = (byte)0;
}
group.ApplyPhysics(m_physicalPrim);
}
group.StartScripts(); group.StartScripts();

View File

@ -1471,6 +1471,11 @@ namespace OpenSim.Region.Environment.Scenes
ScenePresence sp = GetScenePresence(grp.OwnerID); ScenePresence sp = GetScenePresence(grp.OwnerID);
if (sp != null) if (sp != null)
{ {
// hack assetID until we get assetID into the XML format.
// LastOwnerID is used for group deeding, so when you do stuff
// with the deeded object, it goes back to them
grp.SetFromAssetID(grp.RootPart.LastOwnerID);
m_innerScene.AttachObject(sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition); m_innerScene.AttachObject(sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition);
} }
} }
@ -1560,6 +1565,7 @@ namespace OpenSim.Region.Environment.Scenes
client.OnDeRezObject += DeRezObject; client.OnDeRezObject += DeRezObject;
client.OnRezObject += RezObject; client.OnRezObject += RezObject;
client.OnRezSingleAttachmentFromInv += m_innerScene.RezSingleAttachment; client.OnRezSingleAttachmentFromInv += m_innerScene.RezSingleAttachment;
client.OnDetachAttachmentIntoInv += m_innerScene.DetachSingleAttachmentToInv;
client.OnObjectAttach += m_innerScene.AttachObject; client.OnObjectAttach += m_innerScene.AttachObject;
client.OnObjectDetach += m_innerScene.DetachObject; client.OnObjectDetach += m_innerScene.DetachObject;
client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest; client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest;

View File

@ -663,9 +663,11 @@ namespace OpenSim.Region.Environment.Scenes
{ {
m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor); m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor);
m_rootPart.PhysActor = null; m_rootPart.PhysActor = null;
AbsolutePosition = AttachOffset;
m_rootPart.m_attachedPos = AttachOffset;
} }
AbsolutePosition = AttachOffset;
m_rootPart.m_attachedPos = AttachOffset;
m_rootPart.m_IsAttachment = true; m_rootPart.m_IsAttachment = true;
m_rootPart.SetParentLocalId(avatar.LocalId); m_rootPart.SetParentLocalId(avatar.LocalId);
@ -702,6 +704,26 @@ namespace OpenSim.Region.Environment.Scenes
AttachToBackup(); AttachToBackup();
m_rootPart.ScheduleFullUpdate(); m_rootPart.ScheduleFullUpdate();
} }
public void DetachToInventoryPrep()
{
ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.m_attachedAvatar);
//LLVector3 detachedpos = new LLVector3(127f, 127f, 127f);
if (avatar != null)
{
//detachedpos = avatar.AbsolutePosition;
avatar.RemoveAttachment(this);
}
m_rootPart.m_attachedAvatar = LLUUID.Zero;
m_rootPart.SetParentLocalId(0);
//m_rootPart.SetAttachmentPoint((byte)0);
m_rootPart.m_IsAttachment = false;
AbsolutePosition = m_rootPart.m_attachedPos;
//m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_scene.m_physicalPrim);
//AttachToBackup();
//m_rootPart.ScheduleFullUpdate();
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

View File

@ -1906,6 +1906,15 @@ namespace OpenSim.Region.Environment.Scenes
internal void Close() internal void Close()
{ {
lock (m_attachments)
{
foreach (SceneObjectGroup grp in m_attachments)
{
// ControllingClient may be null at this point!
m_scene.m_innerScene.DetachSingleAttachmentToInv(grp.GetFromAssetID(), ControllingClient);
}
m_attachments.Clear();
}
lock (m_knownPrimUUID) lock (m_knownPrimUUID)
{ {
m_knownPrimUUID.Clear(); m_knownPrimUUID.Clear();
@ -1972,6 +1981,7 @@ namespace OpenSim.Region.Environment.Scenes
gobj.RootPart.SetParentLocalId(0); gobj.RootPart.SetParentLocalId(0);
gobj.RootPart.m_IsAttachment = false; gobj.RootPart.m_IsAttachment = false;
gobj.AbsolutePosition = gobj.RootPart.m_attachedPos; gobj.AbsolutePosition = gobj.RootPart.m_attachedPos;
gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj); m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj);
} }
} }

View File

@ -60,6 +60,7 @@ namespace OpenSim.Region.Examples.SimpleModule
public event SetAppearance OnSetAppearance; public event SetAppearance OnSetAppearance;
public event AvatarNowWearing OnAvatarNowWearing; public event AvatarNowWearing OnAvatarNowWearing;
public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
public event UUIDNameRequest OnDetachAttachmentIntoInv;
public event ObjectAttach OnObjectAttach; public event ObjectAttach OnObjectAttach;
public event ObjectDeselect OnObjectDetach; public event ObjectDeselect OnObjectDetach;
public event StartAnim OnStartAnim; public event StartAnim OnStartAnim;

View File

@ -150,22 +150,22 @@ namespace OpenSim.Region.Physics.OdePlugin
_velocity = new PhysicsVector(); _velocity = new PhysicsVector();
_position = pos; _position = pos;
m_taintposition = pos; m_taintposition = pos;
if (_position.X > 257) //if (_position.X > 257)
{ //{
_position.X = 257; //_position.X = 257;
} //}
if (_position.X < 0) //if (_position.X < 0)
{ //{
_position.X = 0; //_position.X = 0;
} //}
if (_position.Y > 257) //if (_position.Y > 257)
{ //{
_position.Y = 257; //_position.Y = 257;
} //}
if (_position.Y < 0) //if (_position.Y < 0)
{ //{
_position.Y = 0; // _position.Y = 0;
} //}
prim_geom = (IntPtr)0; prim_geom = (IntPtr)0;
prev_geom = (IntPtr)0; prev_geom = (IntPtr)0;