Fix remembering attachment point and position when an item is rezzed in world.

Also fix PRIM_LOCAL_POS returning 0 when used on child prims from a script
in the root.
avinationmerge
Melanie 2012-02-02 02:51:59 +01:00
parent dbc3f1ff92
commit 6fe4b6fbe8
3 changed files with 92 additions and 61 deletions

View File

@ -367,6 +367,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
// Restore attachment data after trip through the sim
if (objectGroup.RootPart.AttachPoint > 0)
inventoryStoredPosition = objectGroup.RootPart.AttachOffset;
objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
objectGroup.AbsolutePosition = inventoryStoredPosition; objectGroup.AbsolutePosition = inventoryStoredPosition;
// Make sure all bits but the ones we want are clear // Make sure all bits but the ones we want are clear
@ -740,6 +745,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (e == null || attachment) // Single if (e == null || attachment) // Single
{ {
SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
if (!attachment)
{
g.RootPart.AttachPoint = g.RootPart.Shape.State;
g.RootPart.AttachOffset = g.AbsolutePosition;
}
objlist.Add(g); objlist.Add(g);
veclist.Add(new Vector3(0, 0, 0)); veclist.Add(new Vector3(0, 0, 0));
@ -769,6 +779,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
foreach (XmlNode n in groups) foreach (XmlNode n in groups)
{ {
SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
g.RootPart.AttachPoint = g.RootPart.Shape.State;
g.RootPart.AttachOffset = g.AbsolutePosition;
objlist.Add(g); objlist.Add(g);
XmlElement el = (XmlElement)n; XmlElement el = (XmlElement)n;

View File

@ -2351,6 +2351,11 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="objectGroup">The group of prims which should be linked to this group</param> /// <param name="objectGroup">The group of prims which should be linked to this group</param>
public void LinkToGroup(SceneObjectGroup objectGroup) public void LinkToGroup(SceneObjectGroup objectGroup)
{ {
LinkToGroup(objectGroup, false);
}
public void LinkToGroup(SceneObjectGroup objectGroup, bool insert)
{
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", // "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
// objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
@ -2380,7 +2385,20 @@ namespace OpenSim.Region.Framework.Scenes
lock (m_parts.SyncRoot) lock (m_parts.SyncRoot)
{ {
int linkNum = PrimCount + 1; int linkNum;
if (insert)
{
linkNum = 2;
foreach (SceneObjectPart part in Parts)
{
if (part.LinkNum > 1)
part.LinkNum++;
}
}
else
{
linkNum = PrimCount + 1;
}
m_parts.Add(linkPart.UUID, linkPart); m_parts.Add(linkPart.UUID, linkPart);

View File

@ -2223,11 +2223,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
else else
{ {
if (m_host.IsRoot) if (part.IsRoot)
{ {
return new LSL_Vector(m_host.AttachedPos.X, return new LSL_Vector(part.AttachedPos.X,
m_host.AttachedPos.Y, part.AttachedPos.Y,
m_host.AttachedPos.Z); part.AttachedPos.Z);
} }
else else
{ {
@ -2971,68 +2971,69 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) Util.FireAndForget(delegate (object x)
return;
float dist = (float)llVecDist(llGetPos(), pos);
if (dist > m_ScriptDistanceFactor * 10.0f)
return;
//Clone is thread-safe
TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
{ {
if (inv.Value.Name == inventory) if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
return;
float dist = (float)llVecDist(llGetPos(), pos);
if (dist > m_ScriptDistanceFactor * 10.0f)
return;
//Clone is thread-safe
TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
{ {
// make sure we're an object. if (inv.Value.Name == inventory)
if (inv.Value.InvType != (int)InventoryType.Object)
{ {
llSay(0, "Unable to create requested object. Object is missing from database."); // make sure we're an object.
if (inv.Value.InvType != (int)InventoryType.Object)
{
llSay(0, "Unable to create requested object. Object is missing from database.");
return;
}
Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
// need the magnitude later
// float velmag = (float)Util.GetMagnitude(llvel);
SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param);
// If either of these are null, then there was an unknown error.
if (new_group == null)
continue;
// objects rezzed with this method are die_at_edge by default.
new_group.RootPart.SetDieAtEdge(true);
new_group.ResumeScripts();
m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
"object_rez", new Object[] {
new LSL_String(
new_group.RootPart.UUID.ToString()) },
new DetectParams[0]));
float groupmass = new_group.GetMass();
if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero)
{
//Recoil.
llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0);
}
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
return; return;
} }
Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
// need the magnitude later
float velmag = (float)Util.GetMagnitude(llvel);
SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param);
// If either of these are null, then there was an unknown error.
if (new_group == null)
continue;
// objects rezzed with this method are die_at_edge by default.
new_group.RootPart.SetDieAtEdge(true);
Util.FireAndForget(delegate (object x)
{
new_group.ResumeScripts();
});
m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
"object_rez", new Object[] {
new LSL_String(
new_group.RootPart.UUID.ToString()) },
new DetectParams[0]));
float groupmass = new_group.GetMass();
if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero)
{
//Recoil.
llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0);
}
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
ScriptSleep((int)((groupmass * velmag) / 10));
ScriptSleep(100);
return;
} }
}
llSay(0, "Could not find object " + inventory); llSay(0, "Could not find object " + inventory);
});
//ScriptSleep((int)((groupmass * velmag) / 10));
ScriptSleep(100);
} }
public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
@ -3938,7 +3939,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// Required for linking // Required for linking
childPrim.RootPart.ClearUpdateSchedule(); childPrim.RootPart.ClearUpdateSchedule();
parentPrim.LinkToGroup(childPrim); parentPrim.LinkToGroup(childPrim, true);
} }
parentPrim.TriggerScriptChangedEvent(Changed.LINK); parentPrim.TriggerScriptChangedEvent(Changed.LINK);