* Add a large amount of extra locking to m_parts in SceneObjectGroup
* Should help stop any InvalidOperationExceptions caused by concurrent read/write * The extra locking should be okay, but I'm really surprised we've got away without mucho crashes due to this...0.6.0-stable
parent
f77ab46184
commit
d135dad051
|
@ -48,6 +48,10 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
private Encoding enc = Encoding.ASCII;
|
private Encoding enc = Encoding.ASCII;
|
||||||
|
|
||||||
protected SceneObjectPart m_rootPart;
|
protected SceneObjectPart m_rootPart;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The constituent parts of this group
|
||||||
|
/// </summary>
|
||||||
protected Dictionary<LLUUID, SceneObjectPart> m_parts = new Dictionary<LLUUID, SceneObjectPart>();
|
protected Dictionary<LLUUID, SceneObjectPart> m_parts = new Dictionary<LLUUID, SceneObjectPart>();
|
||||||
|
|
||||||
protected ulong m_regionHandle;
|
protected ulong m_regionHandle;
|
||||||
|
@ -389,34 +393,37 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
EntityIntersection returnresult = new EntityIntersection();
|
EntityIntersection returnresult = new EntityIntersection();
|
||||||
|
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
// Temporary commented to stop compiler warning
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
//Vector3 partPosition =
|
|
||||||
// new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
|
|
||||||
Quaternion parentrotation =
|
|
||||||
new Quaternion(GroupRotation.W, GroupRotation.X, GroupRotation.Y, GroupRotation.Z);
|
|
||||||
|
|
||||||
// Telling the prim to raytrace.
|
|
||||||
EntityIntersection inter = part.TestIntersection(hRay, parentrotation);
|
|
||||||
|
|
||||||
// This may need to be updated to the maximum draw distance possible..
|
|
||||||
// We might (and probably will) be checking for prim creation from other sims
|
|
||||||
// when the camera crosses the border.
|
|
||||||
float idist = (float)Constants.RegionSize;
|
|
||||||
|
|
||||||
|
|
||||||
if (inter.HitTF)
|
|
||||||
{
|
{
|
||||||
// We need to find the closest prim to return to the testcaller along the ray
|
// Temporary commented to stop compiler warning
|
||||||
if (inter.distance < idist)
|
//Vector3 partPosition =
|
||||||
|
// new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
|
||||||
|
Quaternion parentrotation =
|
||||||
|
new Quaternion(GroupRotation.W, GroupRotation.X, GroupRotation.Y, GroupRotation.Z);
|
||||||
|
|
||||||
|
// Telling the prim to raytrace.
|
||||||
|
EntityIntersection inter = part.TestIntersection(hRay, parentrotation);
|
||||||
|
|
||||||
|
// This may need to be updated to the maximum draw distance possible..
|
||||||
|
// We might (and probably will) be checking for prim creation from other sims
|
||||||
|
// when the camera crosses the border.
|
||||||
|
float idist = (float)Constants.RegionSize;
|
||||||
|
|
||||||
|
|
||||||
|
if (inter.HitTF)
|
||||||
{
|
{
|
||||||
idist = inter.distance;
|
// We need to find the closest prim to return to the testcaller along the ray
|
||||||
returnresult.HitTF = true;
|
if (inter.distance < idist)
|
||||||
returnresult.ipoint = inter.ipoint;
|
{
|
||||||
returnresult.obj = part;
|
idist = inter.distance;
|
||||||
returnresult.normal = inter.normal;
|
returnresult.HitTF = true;
|
||||||
returnresult.distance = inter.distance;
|
returnresult.ipoint = inter.ipoint;
|
||||||
|
returnresult.obj = part;
|
||||||
|
returnresult.normal = inter.normal;
|
||||||
|
returnresult.distance = inter.distance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -476,15 +483,20 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
m_rootPart.ToXml(writer);
|
m_rootPart.ToXml(writer);
|
||||||
writer.WriteEndElement();
|
writer.WriteEndElement();
|
||||||
writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
|
writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
if (part.UUID != m_rootPart.UUID)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
writer.WriteStartElement(String.Empty, "Part", String.Empty);
|
if (part.UUID != m_rootPart.UUID)
|
||||||
part.ToXml(writer);
|
{
|
||||||
writer.WriteEndElement();
|
writer.WriteStartElement(String.Empty, "Part", String.Empty);
|
||||||
|
part.ToXml(writer);
|
||||||
|
writer.WriteEndElement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteEndElement();
|
writer.WriteEndElement();
|
||||||
writer.WriteEndElement();
|
writer.WriteEndElement();
|
||||||
}
|
}
|
||||||
|
@ -507,13 +519,18 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
|
writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
|
||||||
m_rootPart.ToXml(writer);
|
m_rootPart.ToXml(writer);
|
||||||
writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
|
writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
if (part.UUID != m_rootPart.UUID)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
part.ToXml(writer);
|
if (part.UUID != m_rootPart.UUID)
|
||||||
|
{
|
||||||
|
part.ToXml(writer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteEndElement();
|
writer.WriteEndElement();
|
||||||
writer.WriteEndElement();
|
writer.WriteEndElement();
|
||||||
}
|
}
|
||||||
|
@ -593,7 +610,12 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
|
SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
|
||||||
newPart.SetParent(this);
|
newPart.SetParent(this);
|
||||||
m_parts.Add(newPart.UUID, newPart);
|
|
||||||
|
lock (m_parts)
|
||||||
|
{
|
||||||
|
m_parts.Add(newPart.UUID, newPart);
|
||||||
|
}
|
||||||
|
|
||||||
SetPartAsRoot(newPart);
|
SetPartAsRoot(newPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,7 +707,12 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
|
SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate(), OwnerID, GroupID, m_parts.Count);
|
||||||
newPart.SetParent(this);
|
newPart.SetParent(this);
|
||||||
m_parts.Add(newPart.UUID, newPart);
|
|
||||||
|
lock (m_parts)
|
||||||
|
{
|
||||||
|
m_parts.Add(newPart.UUID, newPart);
|
||||||
|
}
|
||||||
|
|
||||||
SetPartAsNonRoot(newPart);
|
SetPartAsNonRoot(newPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,6 +724,8 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ResetIDs()
|
public void ResetIDs()
|
||||||
{
|
{
|
||||||
|
// As this is only ever called for prims which are not currently part of the scene (and hence
|
||||||
|
// not accessible by clients), there should be no need to lock
|
||||||
List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
|
List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
|
||||||
m_parts.Clear();
|
m_parts.Clear();
|
||||||
foreach (SceneObjectPart part in partsList)
|
foreach (SceneObjectPart part in partsList)
|
||||||
|
@ -754,46 +783,57 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
if (Util.GetDistanceTo(lastPhysGroupPos, AbsolutePosition) > 0.02)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
|
if (Util.GetDistanceTo(lastPhysGroupPos, AbsolutePosition) > 0.02)
|
||||||
|
{
|
||||||
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
if (part.UpdateFlag == 0) part.UpdateFlag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPhysGroupPos = AbsolutePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1)
|
||||||
|
|| (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
|
||||||
|
|| (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
|
||||||
|
|| (Math.Abs(lastPhysGroupRot.Z - GroupRotation.Z) > 0.1))
|
||||||
|
{
|
||||||
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
if (part.UpdateFlag == 0) part.UpdateFlag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPhysGroupRot = GroupRotation;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
if (part.UpdateFlag == 0) part.UpdateFlag = 1;
|
part.SendScheduledUpdates();
|
||||||
}
|
}
|
||||||
lastPhysGroupPos = AbsolutePosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1)
|
|
||||||
|| (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
|
|
||||||
|| (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
|
|
||||||
|| (Math.Abs(lastPhysGroupRot.Z - GroupRotation.Z) > 0.1))
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
{
|
|
||||||
if (part.UpdateFlag == 0) part.UpdateFlag = 1;
|
|
||||||
}
|
|
||||||
lastPhysGroupRot = GroupRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
{
|
|
||||||
part.SendScheduledUpdates();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScheduleFullUpdateToAvatar(ScenePresence presence)
|
public void ScheduleFullUpdateToAvatar(ScenePresence presence)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
part.AddFullUpdateToAvatar(presence);
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
part.AddFullUpdateToAvatar(presence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
|
public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
part.AddTerseUpdateToAvatar(presence);
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
part.AddTerseUpdateToAvatar(presence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,9 +843,13 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public void ScheduleGroupForFullUpdate()
|
public void ScheduleGroupForFullUpdate()
|
||||||
{
|
{
|
||||||
HasGroupChanged = true;
|
HasGroupChanged = true;
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
part.ScheduleFullUpdate();
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
part.ScheduleFullUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,9 +859,13 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public void ScheduleGroupForTerseUpdate()
|
public void ScheduleGroupForTerseUpdate()
|
||||||
{
|
{
|
||||||
HasGroupChanged = true;
|
HasGroupChanged = true;
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
part.ScheduleTerseUpdate();
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
part.ScheduleTerseUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -827,9 +875,13 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public void SendGroupFullUpdate()
|
public void SendGroupFullUpdate()
|
||||||
{
|
{
|
||||||
HasGroupChanged = true;
|
HasGroupChanged = true;
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
part.SendFullUpdateToAllClients();
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
part.SendFullUpdateToAllClients();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,9 +896,13 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public void SendGroupTerseUpdate()
|
public void SendGroupTerseUpdate()
|
||||||
{
|
{
|
||||||
HasGroupChanged = true;
|
HasGroupChanged = true;
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
part.SendTerseUpdateToAllClients();
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
part.SendTerseUpdateToAllClients();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,13 +917,17 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// <returns>null if no child part with that linknum or child part</returns>
|
/// <returns>null if no child part with that linknum or child part</returns>
|
||||||
public SceneObjectPart GetLinkNumPart(int linknum)
|
public SceneObjectPart GetLinkNumPart(int linknum)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
if (part.LinkNum == linknum)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
return part;
|
if (part.LinkNum == linknum)
|
||||||
|
{
|
||||||
|
return part;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,13 +953,17 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// <returns>null if a child part with the local ID was not found</returns>
|
/// <returns>null if a child part with the local ID was not found</returns>
|
||||||
public SceneObjectPart GetChildPart(uint localID)
|
public SceneObjectPart GetChildPart(uint localID)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
if (part.LocalId == localID)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
return part;
|
if (part.LocalId == localID)
|
||||||
|
{
|
||||||
|
return part;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,11 +990,14 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool HasChildPrim(uint localID)
|
public bool HasChildPrim(uint localID)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
if (part.LocalId == localID)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
return true;
|
if (part.LocalId == localID)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -988,7 +1055,11 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
linkPart.LinkNum = m_parts.Count;
|
linkPart.LinkNum = m_parts.Count;
|
||||||
|
|
||||||
m_parts.Add(linkPart.UUID, linkPart);
|
lock (m_parts)
|
||||||
|
{
|
||||||
|
m_parts.Add(linkPart.UUID, linkPart);
|
||||||
|
}
|
||||||
|
|
||||||
linkPart.SetParent(this);
|
linkPart.SetParent(this);
|
||||||
|
|
||||||
//if (linkPart.PhysActor != null)
|
//if (linkPart.PhysActor != null)
|
||||||
|
@ -1038,7 +1109,11 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
LLQuaternion worldRot = linkPart.GetWorldRotation();
|
LLQuaternion worldRot = linkPart.GetWorldRotation();
|
||||||
|
|
||||||
// Remove the part from this object
|
// Remove the part from this object
|
||||||
m_parts.Remove(linkPart.UUID);
|
lock (m_parts)
|
||||||
|
{
|
||||||
|
m_parts.Remove(linkPart.UUID);
|
||||||
|
}
|
||||||
|
|
||||||
linkPart.ParentID = 0;
|
linkPart.ParentID = 0;
|
||||||
|
|
||||||
if (linkPart.PhysActor != null)
|
if (linkPart.PhysActor != null)
|
||||||
|
@ -1121,7 +1196,11 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
part.SetParent(this);
|
part.SetParent(this);
|
||||||
part.ParentID = m_rootPart.LocalId;
|
part.ParentID = m_rootPart.LocalId;
|
||||||
part.LinkNum = m_parts.Count;
|
part.LinkNum = m_parts.Count;
|
||||||
m_parts.Add(part.UUID, part);
|
|
||||||
|
lock (m_parts)
|
||||||
|
{
|
||||||
|
m_parts.Add(part.UUID, part);
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 axiomOldPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z);
|
Vector3 axiomOldPos = new Vector3(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z);
|
||||||
axiomOldPos = oldGroupRotation*axiomOldPos;
|
axiomOldPos = oldGroupRotation*axiomOldPos;
|
||||||
|
@ -1297,16 +1376,19 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
if (part != null)
|
if (part != null)
|
||||||
{
|
{
|
||||||
// If we have children
|
// If we have children
|
||||||
if (m_parts.Count > 1)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart parts in m_parts.Values)
|
if (m_parts.Count > 1)
|
||||||
{
|
{
|
||||||
parts.UpdatePrimFlags(type, inUse, data);
|
foreach (SceneObjectPart parts in m_parts.Values)
|
||||||
|
{
|
||||||
|
parts.UpdatePrimFlags(type, inUse, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
part.UpdatePrimFlags(type, inUse, data);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
part.UpdatePrimFlags(type, inUse, data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1465,13 +1547,17 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
diff.Y = axDiff.y;
|
diff.Y = axDiff.y;
|
||||||
diff.Z = axDiff.z;
|
diff.Z = axDiff.z;
|
||||||
|
|
||||||
foreach (SceneObjectPart obPart in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
if (obPart.UUID != m_rootPart.UUID)
|
foreach (SceneObjectPart obPart in m_parts.Values)
|
||||||
{
|
{
|
||||||
obPart.OffsetPosition = obPart.OffsetPosition + diff;
|
if (obPart.UUID != m_rootPart.UUID)
|
||||||
|
{
|
||||||
|
obPart.OffsetPosition = obPart.OffsetPosition + diff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AbsolutePosition = newPos;
|
AbsolutePosition = newPos;
|
||||||
ScheduleGroupForTerseUpdate();
|
ScheduleGroupForTerseUpdate();
|
||||||
}
|
}
|
||||||
|
@ -1562,23 +1648,27 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
|
m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (SceneObjectPart prim in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
if (prim.UUID != m_rootPart.UUID)
|
foreach (SceneObjectPart prim in m_parts.Values)
|
||||||
{
|
{
|
||||||
Vector3 axPos = new Vector3(prim.OffsetPosition.X, prim.OffsetPosition.Y, prim.OffsetPosition.Z);
|
if (prim.UUID != m_rootPart.UUID)
|
||||||
axPos = oldParentRot*axPos;
|
{
|
||||||
axPos = axRot.Inverse()*axPos;
|
Vector3 axPos = new Vector3(prim.OffsetPosition.X, prim.OffsetPosition.Y, prim.OffsetPosition.Z);
|
||||||
prim.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
|
axPos = oldParentRot*axPos;
|
||||||
Quaternion primsRot =
|
axPos = axRot.Inverse()*axPos;
|
||||||
new Quaternion(prim.RotationOffset.W, prim.RotationOffset.X, prim.RotationOffset.Y,
|
prim.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z);
|
||||||
prim.RotationOffset.Z);
|
Quaternion primsRot =
|
||||||
Quaternion newRot = oldParentRot*primsRot;
|
new Quaternion(prim.RotationOffset.W, prim.RotationOffset.X, prim.RotationOffset.Y,
|
||||||
newRot = axRot.Inverse()*newRot;
|
prim.RotationOffset.Z);
|
||||||
prim.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
|
Quaternion newRot = oldParentRot*primsRot;
|
||||||
prim.ScheduleTerseUpdate();
|
newRot = axRot.Inverse()*newRot;
|
||||||
|
prim.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w);
|
||||||
|
prim.ScheduleTerseUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rootPart.ScheduleTerseUpdate();
|
m_rootPart.ScheduleTerseUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1693,15 +1783,20 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
public override void UpdateMovement()
|
public override void UpdateMovement()
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
part.UpdateMovement();
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
part.UpdateMovement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetTimeDilation()
|
public float GetTimeDilation()
|
||||||
{
|
{
|
||||||
return m_scene.TimeDilation;
|
return m_scene.TimeDilation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Added as a way for the storage provider to reset the scene,
|
/// Added as a way for the storage provider to reset the scene,
|
||||||
/// most likely a better way to do this sort of thing but for now...
|
/// most likely a better way to do this sort of thing but for now...
|
||||||
|
@ -1719,12 +1814,17 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// <param name="part"></param>
|
/// <param name="part"></param>
|
||||||
public void AddPart(SceneObjectPart part)
|
public void AddPart(SceneObjectPart part)
|
||||||
{
|
{
|
||||||
lock (m_parts) {
|
lock (m_parts)
|
||||||
|
{
|
||||||
part.SetParent(this);
|
part.SetParent(this);
|
||||||
part.LinkNum = m_parts.Count;
|
part.LinkNum = m_parts.Count;
|
||||||
try {
|
|
||||||
|
try
|
||||||
|
{
|
||||||
m_parts.Add(part.UUID, part);
|
m_parts.Add(part.UUID, part);
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
m_log.Error("Failed to add scened object part", e);
|
m_log.Error("Failed to add scened object part", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1735,20 +1835,26 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdateParentIDs()
|
public void UpdateParentIDs()
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
if (part.UUID != m_rootPart.UUID)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
part.ParentID = m_rootPart.LocalId;
|
if (part.UUID != m_rootPart.UUID)
|
||||||
|
{
|
||||||
|
part.ParentID = m_rootPart.LocalId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegenerateFullIDs()
|
public void RegenerateFullIDs()
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
part.UUID = LLUUID.Random();
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
{
|
||||||
|
part.UUID = LLUUID.Random();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1803,17 +1909,21 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
public void DeleteGroup()
|
public void DeleteGroup()
|
||||||
{
|
{
|
||||||
DetachFromBackup(this);
|
DetachFromBackup(this);
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
List<ScenePresence> avatars = GetScenePresences();
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
for (int i = 0; i < avatars.Count; i++)
|
|
||||||
{
|
{
|
||||||
if (avatars[i].ParentID == LocalId)
|
List<ScenePresence> avatars = GetScenePresences();
|
||||||
|
for (int i = 0; i < avatars.Count; i++)
|
||||||
{
|
{
|
||||||
avatars[i].StandUp();
|
if (avatars[i].ParentID == LocalId)
|
||||||
}
|
{
|
||||||
|
avatars[i].StandUp();
|
||||||
|
}
|
||||||
|
|
||||||
avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
|
avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1829,10 +1939,10 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
part.StopScripts();
|
part.StopScripts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_rootPart = null;
|
||||||
|
m_parts.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rootPart = null;
|
|
||||||
m_parts.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddScriptLPS(int count)
|
public void AddScriptLPS(int count)
|
||||||
|
@ -1858,9 +1968,9 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
public void ApplyPhysics(bool m_physicalPrim)
|
public void ApplyPhysics(bool m_physicalPrim)
|
||||||
{
|
{
|
||||||
if (m_parts.Count > 1)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
lock (m_parts)
|
if (m_parts.Count > 1)
|
||||||
{
|
{
|
||||||
m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
|
m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
@ -1874,10 +1984,10 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
|
||||||
m_rootPart.ApplyPhysics(m_rootPart.ObjectFlags, m_physicalPrim);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue