public ISceneEntity RezObject(
ISceneChildEntity sourcePart, TaskInventoryItem item,
Vector3 pos, Quaternion rot, Vector3 vel, int param, UUID RezzedFrom, bool RezObjectAtRoot)
{
if (item != null)
{
UUID ownerID = item.OwnerID;
AssetBase rezAsset = World.AssetService.Get(item.AssetID.ToString());
if (rezAsset != null)
{
string xmlData = Utils.BytesToString(rezAsset.Data);
SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData, World);
if (group == null)
return null;
string reason;
if (!World.Permissions.CanRezObject(group.ChildrenList.Count, ownerID, pos, out reason))
{
World.GetScenePresence(ownerID).ControllingClient.SendAlertMessage("You do not have permission to rez objects here: " + reason);
return null;
}
List<ISceneChildEntity> partList = group.ChildrenEntities();
// we set it's position in world.
// llRezObject sets the whole group at the position, while llRezAtRoot rezzes the group based on the root prim's position
// See: http://lslwiki.net/lslwiki/wakka.php?wakka=llRezAtRoot
// Shorthand: llRezAtRoot rezzes the root prim of the group at the position
// llRezObject rezzes the center of group at the position
if (RezObjectAtRoot)
//This sets it right...
group.AbsolutePosition = pos;
else
{
// center is on average of all positions
// less root prim position
#if (!ISWIN)
Vector3 offset = Vector3.Zero;
foreach (ISceneChildEntity child in partList)
{
offset += child.AbsolutePosition;
}
#else
Vector3 offset = partList.Aggregate(Vector3.Zero, (current, child) => current + child.AbsolutePosition);
#endif
offset /= partList.Count;
offset -= group.AbsolutePosition;
offset += pos;
group.AbsolutePosition = offset;
}
ISceneChildEntity rootPart = group.GetChildPart(group.UUID);
// 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(sourcePart.GroupID, group.OwnerID, false);
if (rootPart.OwnerID != item.OwnerID)
{
if (World.Permissions.PropagatePermissions())
{
if ((item.CurrentPermissions & 8) != 0)
{
foreach (ISceneChildEntity part in partList)
{
part.EveryoneMask = item.EveryonePermissions;
part.NextOwnerMask = item.NextPermissions;
}
}
group.ApplyNextOwnerPermissions();
}
}
foreach (ISceneChildEntity part in partList)
{
if (part.OwnerID != item.OwnerID)
{
part.LastOwnerID = part.OwnerID;
part.OwnerID = item.OwnerID;
part.Inventory.ChangeInventoryOwner(item.OwnerID);
}
else if ((item.CurrentPermissions & 8) != 0) // Slam!
{
part.EveryoneMask = item.EveryonePermissions;
part.NextOwnerMask = item.NextPermissions;
}
}
rootPart.TrimPermissions();
if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
{
group.ClearPartAttachmentData();
}
group.UpdateGroupRotationR(rot);
//group.ApplyPhysics(m_physicalPrim);
World.SceneGraph.AddPrimToScene(group);
if ((group.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
{
group.RootPart.PhysActor.OnPhysicalRepresentationChanged += delegate
{
float groupmass = group.GetMass();
//Apply the velocity to the object
//llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0);
// @Above: Err.... no. Read http://lslwiki.net/lslwiki/wakka.php?wakka=llRezObject
// Notice the "Creates ("rezzes") object's inventory object centered at position pos (in region coordinates) with velocity vel"
// This means SET the velocity to X, not just temperarily add it!
// -- Revolution Smythe
llSetForce(new LSL_Vector(vel * groupmass), 0);
group.RootPart.PhysActor.ForceSetVelocity(vel * groupmass);
group.RootPart.PhysActor.Velocity = vel * groupmass;
};
}
group.CreateScriptInstances(param, true, StateSource.ScriptedRez, RezzedFrom, false);
if (!World.Permissions.BypassPermissions())
{
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
}
group.ScheduleGroupUpdate(PrimUpdateFlags.FullUpdate);
return rootPart.ParentEntity;
}
}
return null;
}