From 6fe4b6fbe807672ec64700ff8c6307a2a3e4f084 Mon Sep 17 00:00:00 2001
From: Melanie
Date: Thu, 2 Feb 2012 02:51:59 +0100
Subject: 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.
---
.../InventoryAccess/InventoryAccessModule.cs | 12 +++
.../Region/Framework/Scenes/SceneObjectGroup.cs | 20 ++++-
.../Shared/Api/Implementation/LSL_Api.cs | 99 +++++++++++-----------
3 files changed, 81 insertions(+), 50 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 7ebf002..fe75271 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -367,6 +367,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
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;
// 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
{
SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
+ if (!attachment)
+ {
+ g.RootPart.AttachPoint = g.RootPart.Shape.State;
+ g.RootPart.AttachOffset = g.AbsolutePosition;
+ }
objlist.Add(g);
veclist.Add(new Vector3(0, 0, 0));
@@ -769,6 +779,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
foreach (XmlNode n in groups)
{
SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
+ g.RootPart.AttachPoint = g.RootPart.Shape.State;
+ g.RootPart.AttachOffset = g.AbsolutePosition;
objlist.Add(g);
XmlElement el = (XmlElement)n;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index c31cbab..6485710 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2351,6 +2351,11 @@ namespace OpenSim.Region.Framework.Scenes
/// The group of prims which should be linked to this group
public void LinkToGroup(SceneObjectGroup objectGroup)
{
+ LinkToGroup(objectGroup, false);
+ }
+
+ public void LinkToGroup(SceneObjectGroup objectGroup, bool insert)
+ {
// m_log.DebugFormat(
// "[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);
@@ -2380,7 +2385,20 @@ namespace OpenSim.Region.Framework.Scenes
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);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 7ed41f2..3e9529f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2223,11 +2223,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
else
{
- if (m_host.IsRoot)
+ if (part.IsRoot)
{
- return new LSL_Vector(m_host.AttachedPos.X,
- m_host.AttachedPos.Y,
- m_host.AttachedPos.Z);
+ return new LSL_Vector(part.AttachedPos.X,
+ part.AttachedPos.Y,
+ part.AttachedPos.Z);
}
else
{
@@ -2971,68 +2971,69 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
- if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
- return;
- float dist = (float)llVecDist(llGetPos(), pos);
+ Util.FireAndForget(delegate (object x)
+ {
+ 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;
+ if (dist > m_ScriptDistanceFactor * 10.0f)
+ return;
- //Clone is thread-safe
- TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
+ //Clone is thread-safe
+ TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
- foreach (KeyValuePair inv in partInventory)
- {
- if (inv.Value.Name == inventory)
+ foreach (KeyValuePair inv in partInventory)
{
- // make sure we're an object.
- if (inv.Value.InvType != (int)InventoryType.Object)
+ if (inv.Value.Name == inventory)
{
- llSay(0, "Unable to create requested object. Object is missing from database.");
- return;
- }
+ // 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);
+ 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);
+ // need the magnitude later
+ // float velmag = (float)Util.GetMagnitude(llvel);
- SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param);
+ 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;
+ // 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);
+ // 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]));
+ 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();
+ 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);
+ 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;
}
- // 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)
@@ -3938,7 +3939,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// Required for linking
childPrim.RootPart.ClearUpdateSchedule();
- parentPrim.LinkToGroup(childPrim);
+ parentPrim.LinkToGroup(childPrim, true);
}
parentPrim.TriggerScriptChangedEvent(Changed.LINK);
--
cgit v1.1