From d0c17808391e93964dcaf0ffcf06899c5669f4ff Mon Sep 17 00:00:00 2001
From: Oren Hurvitz
Date: Wed, 25 Sep 2013 10:56:05 +0300
Subject: Fixed rezzing coalesced objects from a prim's inventory
Previously only the first object in the Coalesced Object was rezzed. Now all the objects are rezzed.
---
OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 119 +++++++++++++++++----
.../Framework/Scenes/SceneObjectPartInventory.cs | 101 +++++++++--------
2 files changed, 152 insertions(+), 68 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes')
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 4bebbe8..65536db 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -31,6 +31,7 @@ using System.Collections;
using System.Reflection;
using System.Text;
using System.Timers;
+using System.Xml;
using OpenMetaverse;
using OpenMetaverse.Packets;
using log4net;
@@ -2135,6 +2136,69 @@ namespace OpenSim.Region.Framework.Scenes
}
///
+ /// Returns the list of Scene Objects in an asset.
+ ///
+ ///
+ /// Returns one object if the asset is a regular object, and multiple objects for a coalesced object.
+ ///
+ /// Asset data
+ /// Whether the item is an attachment
+ /// The objects included in the asset
+ /// Relative positions of the objects
+ /// Bounding box of all the objects
+ /// Offset in the Z axis from the centre of the bounding box
+ /// to the centre of the root prim (relevant only when returning a single object)
+ /// true = returning a single object; false = multiple objects
+ public bool GetObjectsToRez(byte[] assetData, bool attachment, out List objlist, out List veclist,
+ out Vector3 bbox, out float offsetHeight)
+ {
+ objlist = new List();
+ veclist = new List();
+
+ XmlDocument doc = new XmlDocument();
+ string xmlData = Utils.BytesToString(assetData);
+ doc.LoadXml(xmlData);
+ XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
+
+ if (e == null || attachment) // Single
+ {
+ SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
+ objlist.Add(g);
+ veclist.Add(new Vector3(0, 0, 0));
+ bbox = g.GetAxisAlignedBoundingBox(out offsetHeight);
+ return true;
+ }
+ 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"));
+ bbox = new Vector3(bx, by, bz);
+ offsetHeight = 0;
+
+ XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
+ foreach (XmlNode n in groups)
+ {
+ SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
+ objlist.Add(g);
+
+ XmlElement el = (XmlElement)n;
+ string rawX = el.GetAttribute("offsetx");
+ string rawY = el.GetAttribute("offsety");
+ string rawZ = el.GetAttribute("offsetz");
+
+ float x = Convert.ToSingle(rawX);
+ float y = Convert.ToSingle(rawY);
+ float z = Convert.ToSingle(rawZ);
+ veclist.Add(new Vector3(x, y, z));
+ }
+ }
+
+ return false;
+ }
+
+ ///
/// Event Handler Rez an object into a scene
/// Calls the non-void event handler
///
@@ -2209,19 +2273,25 @@ namespace OpenSim.Region.Framework.Scenes
/// will be used if it exists.
/// The velocity of the rezzed object.
///
- /// The SceneObjectGroup rezzed or null if rez was unsuccessful
- public virtual SceneObjectGroup RezObject(
+ /// The SceneObjectGroup(s) rezzed, or null if rez was unsuccessful
+ public virtual List RezObject(
SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param)
{
if (null == item)
return null;
+
+ List objlist;
+ List veclist;
- SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item);
-
- if (null == group)
+ bool success = sourcePart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist);
+ if (!success)
return null;
-
- if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos))
+
+ int totalPrims = 0;
+ foreach (SceneObjectGroup group in objlist)
+ totalPrims += group.PrimCount;
+
+ if (!Permissions.CanRezObject(totalPrims, item.OwnerID, pos))
return null;
if (!Permissions.BypassPermissions())
@@ -2230,23 +2300,28 @@ namespace OpenSim.Region.Framework.Scenes
sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
}
-
- if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
+ for (int i = 0; i < objlist.Count; i++)
{
- group.RootPart.AttachedPos = group.AbsolutePosition;
- group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
+ SceneObjectGroup group = objlist[i];
+ Vector3 curpos = pos + veclist[i];
+
+ if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
+ {
+ group.RootPart.AttachedPos = group.AbsolutePosition;
+ group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
+ }
+
+ group.FromPartID = sourcePart.UUID;
+ AddNewSceneObject(group, true, curpos, rot, vel);
+
+ // We can only call this after adding the scene object, since the scene object references the scene
+ // to find out if scripts should be activated at all.
+ group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
+
+ group.ScheduleGroupForFullUpdate();
}
-
- group.FromPartID = sourcePart.UUID;
- AddNewSceneObject(group, true, pos, rot, vel);
-
- // We can only call this after adding the scene object, since the scene object references the scene
- // to find out if scripts should be activated at all.
- group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
-
- group.ScheduleGroupForFullUpdate();
-
- return group;
+
+ return objlist;
}
public virtual bool returnObjects(SceneObjectGroup[] returnobjects,
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 3f223a3..380e402 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -733,8 +733,8 @@ namespace OpenSim.Region.Framework.Scenes
return items;
}
-
- public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item)
+
+ public bool GetRezReadySceneObjects(TaskInventoryItem item, out List objlist, out List veclist)
{
AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
@@ -743,66 +743,75 @@ namespace OpenSim.Region.Framework.Scenes
m_log.WarnFormat(
"[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}",
item.AssetID, item.Name, m_part.Name);
- return null;
+ objlist = null;
+ veclist = null;
+ return false;
}
- string xmlData = Utils.BytesToString(rezAsset.Data);
- SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
+ Vector3 bbox;
+ float offsetHeight;
- group.ResetIDs();
+ bool single = m_part.ParentGroup.Scene.GetObjectsToRez(rezAsset.Data, false, out objlist, out veclist, out bbox, out offsetHeight);
- SceneObjectPart rootPart = group.GetPart(group.UUID);
+ for (int i = 0; i < objlist.Count; i++)
+ {
+ SceneObjectGroup group = objlist[i];
- // 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.ResetIDs();
- SceneObjectPart[] partList = group.Parts;
+ SceneObjectPart rootPart = group.GetPart(group.UUID);
- group.SetGroup(m_part.GroupID, null);
+ // 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;
- // TODO: Remove magic number badness
- if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
- {
- if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions())
+ SceneObjectPart[] partList = group.Parts;
+
+ group.SetGroup(m_part.GroupID, null);
+
+ // TODO: Remove magic number badness
+ if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
{
- foreach (SceneObjectPart part in partList)
+ if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions())
{
- 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;
+ foreach (SceneObjectPart part in partList)
+ {
+ 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;
+ }
+
+ group.ApplyNextOwnerPermissions();
}
-
- group.ApplyNextOwnerPermissions();
}
- }
- foreach (SceneObjectPart part in partList)
- {
- // TODO: Remove magic number badness
- if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
+ foreach (SceneObjectPart part in partList)
{
- part.LastOwnerID = part.OwnerID;
- part.OwnerID = item.OwnerID;
- part.Inventory.ChangeInventoryOwner(item.OwnerID);
+ // TODO: Remove magic number badness
+ if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number
+ {
+ part.LastOwnerID = part.OwnerID;
+ part.OwnerID = item.OwnerID;
+ part.Inventory.ChangeInventoryOwner(item.OwnerID);
+ }
+
+ 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;
}
-
- 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;
+
+ rootPart.TrimPermissions();
}
-
- rootPart.TrimPermissions();
-
- return group;
+
+ return true;
}
///
--
cgit v1.1