Implement rezzing coalesced objects

avinationmerge
Melanie 2010-10-07 05:12:39 +02:00
parent 2db0ac74c7
commit ba0afa53d3
1 changed files with 189 additions and 143 deletions

View File

@ -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<SceneObjectGroup> objlist =
new List<SceneObjectGroup>();
List<Vector3> veclist = new List<Vector3>();
// 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;