From ba0afa53d30566381d5757fb5a7b1ce55fe4521a Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Oct 2010 05:12:39 +0200 Subject: [PATCH] Implement rezzing coalesced objects --- .../InventoryAccess/InventoryAccessModule.cs | 332 ++++++++++-------- 1 file changed, 189 insertions(+), 143 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 753aadae3d..d429979245 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -444,7 +444,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess item.Folder = folder.ID; item.Owner = userID; if (objlist.Count > 1) + { item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; + } + else + { + item.SaleType = objlist[0].RootPart.ObjectSaleType; + item.SalePrice = objlist[0].RootPart.SalePrice; + } } AssetBase asset = CreateAsset( @@ -508,7 +515,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess 7); // Preserve folded permissions } - // TODO: add the new fields (Flags, Sale info, etc) item.CreationDate = Util.UnixTimeSinceEpoch(); item.Description = asset.Description; item.Name = asset.Name; @@ -587,6 +593,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); + SceneObjectGroup group = null; + if (rezAsset != null) { UUID itemId = UUID.Zero; @@ -595,16 +603,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // item that it came from. This allows us to enable 'save object to inventory' if (!m_Scene.Permissions.BypassPermissions()) { - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy) + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { itemId = item.ID; } } else { - // Brave new fullperm world - // - itemId = item.ID; + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + // Brave new fullperm world + itemId = item.ID; + } } if (item.ID == UUID.Zero) @@ -613,27 +623,63 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } string xmlData = Utils.BytesToString(rezAsset.Data); - SceneObjectGroup group - = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); - Vector3 storedPosition = group.AbsolutePosition; - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); - } - group.RootPart.FromFolderID = item.Folder; + List objlist = + new List(); + List veclist = new List(); - // If it's rezzed in world, select it. Much easier to - // find small items. - // - if (!attachment) + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xmlData); + XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); + if (e == null || attachment) // Single { - group.RootPart.CreateSelected = true; - foreach (SceneObjectPart child in group.Parts) - child.CreateSelected = true; + SceneObjectGroup g = + SceneObjectSerializer.FromOriginalXmlFormat( + itemId, xmlData); + objlist.Add(g); + veclist.Add(new Vector3(0, 0, 0)); + + float offsetHeight = 0; + pos = m_Scene.GetNewRezLocation( + RayStart, RayEnd, RayTargetID, Quaternion.Identity, + BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); + pos.Z += offsetHeight; } + else + { + XmlElement coll = (XmlElement)e; + float bx = Convert.ToSingle(coll.GetAttribute("x")); + float by = Convert.ToSingle(coll.GetAttribute("y")); + float bz = Convert.ToSingle(coll.GetAttribute("z")); + Vector3 bbox = new Vector3(bx, by, bz); + + pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, + RayTargetID, Quaternion.Identity, + BypassRayCast, bRayEndIsIntersection, true, + bbox, false); + + pos -= bbox / 2; + + XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); + foreach (XmlNode n in groups) + { + SceneObjectGroup g = + SceneObjectSerializer.FromOriginalXmlFormat( + itemId, n.OuterXml); + objlist.Add(g); + XmlElement el = (XmlElement)n; + float x = Convert.ToSingle(el.GetAttribute("offsetx")); + float y = Convert.ToSingle(el.GetAttribute("offsety")); + float z = Convert.ToSingle(el.GetAttribute("offsetz")); + veclist.Add(new Vector3(x, y, z)); + } + } + + int primcount = 0; + foreach (SceneObjectGroup g in objlist) + primcount += g.PrimCount; if (!m_Scene.Permissions.CanRezObject( - group.PrimCount, remoteClient.AgentId, pos) + primcount, remoteClient.AgentId, pos) && !attachment) { // The client operates in no fail mode. It will @@ -645,135 +691,139 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess remoteClient.SendBulkUpdateInventory(item); return null; } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 4"); - } - group.ResetIDs(); - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 5"); - } - if (attachment) - { - group.RootPart.Flags |= PrimFlags.Phantom; - group.RootPart.IsAttachment = true; - } - // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since - // we'll be doing that later on. Scheduling more than one full update during the attachment - // process causes some clients to fail to display the attachment properly. - m_Scene.AddNewSceneObject(group, true, false); + for (int i = 0 ; i < objlist.Count ; i++ ) + { + group = objlist[i]; - // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); - // 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.ScheduleGroupForFullUpdate(); - - float offsetHeight = 0; - pos = m_Scene.GetNewRezLocation( - RayStart, RayEnd, RayTargetID, Quaternion.Identity, - BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false); - pos.Z += offsetHeight; - group.AbsolutePosition = pos; - // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight); + Vector3 storedPosition = group.AbsolutePosition; + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); + } + group.RootPart.FromFolderID = item.Folder; - } - else - { - group.SetFromItemID(itemID); - } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 6"); - } - SceneObjectPart rootPart = null; - try - { - rootPart = group.GetChildPart(group.UUID); - } - catch (NullReferenceException) - { - string isAttachment = ""; + // If it's rezzed in world, select it. Much easier to + // find small items. + // + if (!attachment) + { + group.RootPart.CreateSelected = true; + foreach (SceneObjectPart child in group.Parts) + child.CreateSelected = true; + } + + group.ResetIDs(); if (attachment) - isAttachment = " Object was an attachment"; - - m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); - } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 7"); - } - // Since renaming the item in the inventory does not affect the name stored - // in the serialization, transfer the correct name from the inventory to the - // object itself before we rez. - rootPart.Name = item.Name; - rootPart.Description = item.Description; - - group.SetGroup(remoteClient.ActiveGroupId, remoteClient); - if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) - { - //Need to kill the for sale here - rootPart.ObjectSaleType = 0; - rootPart.SalePrice = 10; - - if (m_Scene.Permissions.PropagatePermissions()) { - foreach (SceneObjectPart part in group.Parts) + group.RootPart.Flags |= PrimFlags.Phantom; + group.RootPart.IsAttachment = true; + } + + // If we're rezzing an attachment then don't ask + // AddNewSceneObject() to update the client since + // we'll be doing that later on. Scheduling more than + // one full update during the attachment + // process causes some clients to fail to display the + // attachment properly. + m_Scene.AddNewSceneObject(group, true, false); + + // 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.ScheduleGroupForFullUpdate(); + + group.AbsolutePosition = pos + veclist[i]; + } + else + { + group.SetFromItemID(itemID); + } + + SceneObjectPart rootPart = null; + + try + { + rootPart = group.GetChildPart(group.UUID); + } + catch (NullReferenceException) + { + string isAttachment = ""; + + if (attachment) + isAttachment = " Object was an attachment"; + + m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); + } + + // Since renaming the item in the inventory does not + // affect the name stored in the serialization, transfer + // the correct name from the inventory to the + // object itself before we rez. + rootPart.Name = item.Name; + rootPart.Description = item.Description; + rootPart.ObjectSaleType = item.SaleType; + rootPart.SalePrice = item.SalePrice; + + group.SetGroup(remoteClient.ActiveGroupId, remoteClient); + if ((rootPart.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) + { + //Need to kill the for sale here + rootPart.ObjectSaleType = 0; + rootPart.SalePrice = 10; + + if (m_Scene.Permissions.PropagatePermissions()) { - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; + foreach (SceneObjectPart part in group.Parts) + { + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; + } + part.GroupMask = 0; // DO NOT propagate here + } + + group.ApplyNextOwnerPermissions(); + } + } + + foreach (SceneObjectPart part in group.Parts) + { + if ((part.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.Owner; + part.Inventory.ChangeInventoryOwner(item.Owner); part.GroupMask = 0; // DO NOT propagate here } + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; + } + + rootPart.TrimPermissions(); + + if (!attachment) + { + if (group.RootPart.Shape.PCode == (byte)PCode.Prim) + { + // Save attachment data + group.RootPart.AttachPoint = group.RootPart.Shape.State; + group.RootPart.AttachOffset = storedPosition; + + group.ClearPartAttachmentData(); + } - group.ApplyNextOwnerPermissions(); - } - } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 8"); - } + // Fire on_rez + group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); + rootPart.ParentGroup.ResumeScripts(); - foreach (SceneObjectPart part in group.Parts) - { - if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) - { - part.LastOwnerID = part.OwnerID; - part.OwnerID = item.Owner; - part.Inventory.ChangeInventoryOwner(item.Owner); - part.GroupMask = 0; // DO NOT propagate here + rootPart.ScheduleFullUpdate(); } - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; - } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 9"); - } - rootPart.TrimPermissions(); - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 10"); - } - if (!attachment) - { - if (group.RootPart.Shape.PCode == (byte)PCode.Prim) - { - // Save attachment data - group.RootPart.AttachPoint = group.RootPart.Shape.State; - group.RootPart.AttachOffset = storedPosition; - - group.ClearPartAttachmentData(); - } - - // Fire on_rez - group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); - rootPart.ParentGroup.ResumeScripts(); - - rootPart.ScheduleFullUpdate(); } if (!m_Scene.Permissions.BypassPermissions()) @@ -791,12 +841,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 11"); - } - return group; } + return group; } return null;