From a4b3439025f7ae8cf3a795f540675714d6324122 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 | 287 +++++++++++------- 1 file changed, 177 insertions(+), 110 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 88dff022c3..a7d59c71b9 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -458,7 +458,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( @@ -522,7 +529,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; @@ -598,6 +604,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; @@ -606,34 +614,78 @@ 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; + } } string xmlData = Utils.BytesToString(rezAsset.Data); - SceneObjectGroup group - = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); + List objlist = + new List(); + List veclist = new List(); - Util.FireAndForget(delegate { AddUserData(group); }); - - group.RootPart.FromFolderID = item.Folder; + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xmlData); + XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); + if (e == null || attachment) // Single + { + SceneObjectGroup g = + SceneObjectSerializer.FromOriginalXmlFormat( + itemId, xmlData); + objlist.Add(g); + veclist.Add(new Vector3(0, 0, 0)); - // If it's rezzed in world, select it. Much easier to - // find small items. - // - if (!attachment) - group.RootPart.CreateSelected = true; + 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 @@ -646,123 +698,139 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return null; } - group.ResetIDs(); - - if (attachment) + for (int i = 0 ; i < objlist.Count ; i++ ) { - group.RootPart.Flags |= PrimFlags.Phantom; - group.RootPart.IsAttachment = true; + group = objlist[i]; + + 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; + + // 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) + { + 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. - // Also, don't persist attachments. - m_Scene.AddNewSceneObject(group, false, false); - } - else - { + // 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); - } - // 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); + // 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); + } - } - else - { - group.SetFromItemID(itemID); - } + SceneObjectPart rootPart = null; - SceneObjectPart rootPart = null; - try - { - rootPart = group.GetChildPart(group.UUID); - } - catch (NullReferenceException) - { - string isAttachment = ""; + try + { + rootPart = group.GetChildPart(group.UUID); + } + catch (NullReferenceException) + { + string isAttachment = ""; - if (attachment) - isAttachment = " Object was an attachment"; + if (attachment) + isAttachment = " Object was an attachment"; - m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); - } + 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; - - if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0) - { + // 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 || // Magic number - (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) - { - //Need to kill the for sale here - rootPart.ObjectSaleType = 0; - rootPart.SalePrice = 10; - - if (m_Scene.Permissions.PropagatePermissions()) + group.SetGroup(remoteClient.ActiveGroupId, remoteClient); + if ((rootPart.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) { - foreach (SceneObjectPart part in group.Parts) - { - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) - part.EveryoneMask = item.EveryOnePermissions; - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) - part.NextOwnerMask = item.NextPermissions; - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) - part.GroupMask = item.GroupPermissions; - } + //Need to kill the for sale here + rootPart.ObjectSaleType = 0; + rootPart.SalePrice = 10; - foreach (SceneObjectPart part in group.Parts) + if (m_Scene.Permissions.PropagatePermissions()) + { + 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(); + // Fire on_rez + group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); + rootPart.ParentGroup.ResumeScripts(); + + rootPart.ScheduleFullUpdate(); } } - rootPart.TrimPermissions(); - - if (!attachment) - { - if (group.RootPart.Shape.PCode == (byte)PCode.Prim) - { - group.ClearPartAttachmentData(); - } - - // Fire on_rez - group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); - rootPart.ParentGroup.ResumeScripts(); - - rootPart.ScheduleFullUpdate(); - } - if (!m_Scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) @@ -778,9 +846,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } } - - return rootPart.ParentGroup; } + return group; } return null;