Improve consistency of locking for SOG.m_parts in order to avoid race conditions in linking and unlinking
parent
22fd00b002
commit
8031f8ec09
|
@ -232,66 +232,68 @@ namespace OpenSim.Data.MSSQL
|
||||||
/// <param name="regionUUID"></param>
|
/// <param name="regionUUID"></param>
|
||||||
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
||||||
{
|
{
|
||||||
_Log.InfoFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count);
|
lock (obj.Children)
|
||||||
|
|
||||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
|
||||||
{
|
{
|
||||||
conn.Open();
|
_Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count);
|
||||||
SqlTransaction transaction = conn.BeginTransaction();
|
|
||||||
|
|
||||||
try
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart sceneObjectPart in obj.Children.Values)
|
conn.Open();
|
||||||
{
|
SqlTransaction transaction = conn.BeginTransaction();
|
||||||
//Update prim
|
|
||||||
using (SqlCommand sqlCommand = conn.CreateCommand())
|
|
||||||
{
|
|
||||||
sqlCommand.Transaction = transaction;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID);
|
|
||||||
}
|
|
||||||
catch (SqlException sqlEx)
|
|
||||||
{
|
|
||||||
_Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Update primshapes
|
|
||||||
using (SqlCommand sqlCommand = conn.CreateCommand())
|
|
||||||
{
|
|
||||||
sqlCommand.Transaction = transaction;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID);
|
|
||||||
}
|
|
||||||
catch (SqlException sqlEx)
|
|
||||||
{
|
|
||||||
_Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction.Commit();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
transaction.Rollback();
|
foreach (SceneObjectPart sceneObjectPart in obj.Children.Values)
|
||||||
}
|
{
|
||||||
catch (Exception ex2)
|
//Update prim
|
||||||
{
|
using (SqlCommand sqlCommand = conn.CreateCommand())
|
||||||
//Show error
|
{
|
||||||
_Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message);
|
sqlCommand.Transaction = transaction;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID);
|
||||||
|
}
|
||||||
|
catch (SqlException sqlEx)
|
||||||
|
{
|
||||||
|
_Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Update primshapes
|
||||||
|
using (SqlCommand sqlCommand = conn.CreateCommand())
|
||||||
|
{
|
||||||
|
sqlCommand.Transaction = transaction;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID);
|
||||||
|
}
|
||||||
|
catch (SqlException sqlEx)
|
||||||
|
{
|
||||||
|
_Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
|
}
|
||||||
|
catch (Exception ex2)
|
||||||
|
{
|
||||||
|
//Show error
|
||||||
|
_Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -135,111 +135,115 @@ namespace OpenSim.Data.MySQL
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
MySqlCommand cmd = dbcon.CreateCommand();
|
MySqlCommand cmd = dbcon.CreateCommand();
|
||||||
|
|
||||||
foreach (SceneObjectPart prim in obj.Children.Values)
|
lock (obj.Children)
|
||||||
{
|
{
|
||||||
cmd.Parameters.Clear();
|
foreach (SceneObjectPart prim in obj.Children.Values)
|
||||||
|
{
|
||||||
|
cmd.Parameters.Clear();
|
||||||
|
|
||||||
cmd.CommandText = "replace into prims (" +
|
cmd.CommandText = "replace into prims (" +
|
||||||
"UUID, CreationDate, " +
|
"UUID, CreationDate, " +
|
||||||
"Name, Text, Description, " +
|
"Name, Text, Description, " +
|
||||||
"SitName, TouchName, ObjectFlags, " +
|
"SitName, TouchName, ObjectFlags, " +
|
||||||
"OwnerMask, NextOwnerMask, GroupMask, " +
|
"OwnerMask, NextOwnerMask, GroupMask, " +
|
||||||
"EveryoneMask, BaseMask, PositionX, " +
|
"EveryoneMask, BaseMask, PositionX, " +
|
||||||
"PositionY, PositionZ, GroupPositionX, " +
|
"PositionY, PositionZ, GroupPositionX, " +
|
||||||
"GroupPositionY, GroupPositionZ, VelocityX, " +
|
"GroupPositionY, GroupPositionZ, VelocityX, " +
|
||||||
"VelocityY, VelocityZ, AngularVelocityX, " +
|
"VelocityY, VelocityZ, AngularVelocityX, " +
|
||||||
"AngularVelocityY, AngularVelocityZ, " +
|
"AngularVelocityY, AngularVelocityZ, " +
|
||||||
"AccelerationX, AccelerationY, " +
|
"AccelerationX, AccelerationY, " +
|
||||||
"AccelerationZ, RotationX, " +
|
"AccelerationZ, RotationX, " +
|
||||||
"RotationY, RotationZ, " +
|
"RotationY, RotationZ, " +
|
||||||
"RotationW, SitTargetOffsetX, " +
|
"RotationW, SitTargetOffsetX, " +
|
||||||
"SitTargetOffsetY, SitTargetOffsetZ, " +
|
"SitTargetOffsetY, SitTargetOffsetZ, " +
|
||||||
"SitTargetOrientW, SitTargetOrientX, " +
|
"SitTargetOrientW, SitTargetOrientX, " +
|
||||||
"SitTargetOrientY, SitTargetOrientZ, " +
|
"SitTargetOrientY, SitTargetOrientZ, " +
|
||||||
"RegionUUID, CreatorID, " +
|
"RegionUUID, CreatorID, " +
|
||||||
"OwnerID, GroupID, " +
|
"OwnerID, GroupID, " +
|
||||||
"LastOwnerID, SceneGroupID, " +
|
"LastOwnerID, SceneGroupID, " +
|
||||||
"PayPrice, PayButton1, " +
|
"PayPrice, PayButton1, " +
|
||||||
"PayButton2, PayButton3, " +
|
"PayButton2, PayButton3, " +
|
||||||
"PayButton4, LoopedSound, " +
|
"PayButton4, LoopedSound, " +
|
||||||
"LoopedSoundGain, TextureAnimation, " +
|
"LoopedSoundGain, TextureAnimation, " +
|
||||||
"OmegaX, OmegaY, OmegaZ, " +
|
"OmegaX, OmegaY, OmegaZ, " +
|
||||||
"CameraEyeOffsetX, CameraEyeOffsetY, " +
|
"CameraEyeOffsetX, CameraEyeOffsetY, " +
|
||||||
"CameraEyeOffsetZ, CameraAtOffsetX, " +
|
"CameraEyeOffsetZ, CameraAtOffsetX, " +
|
||||||
"CameraAtOffsetY, CameraAtOffsetZ, " +
|
"CameraAtOffsetY, CameraAtOffsetZ, " +
|
||||||
"ForceMouselook, ScriptAccessPin, " +
|
"ForceMouselook, ScriptAccessPin, " +
|
||||||
"AllowedDrop, DieAtEdge, " +
|
"AllowedDrop, DieAtEdge, " +
|
||||||
"SalePrice, SaleType, " +
|
"SalePrice, SaleType, " +
|
||||||
"ColorR, ColorG, ColorB, ColorA, " +
|
"ColorR, ColorG, ColorB, ColorA, " +
|
||||||
"ParticleSystem, ClickAction, Material, " +
|
"ParticleSystem, ClickAction, Material, " +
|
||||||
"CollisionSound, CollisionSoundVolume, " +
|
"CollisionSound, CollisionSoundVolume, " +
|
||||||
"PassTouches, " +
|
"PassTouches, " +
|
||||||
"LinkNumber, MediaURL) values (" + "?UUID, " +
|
"LinkNumber, MediaURL) values (" + "?UUID, " +
|
||||||
"?CreationDate, ?Name, ?Text, " +
|
"?CreationDate, ?Name, ?Text, " +
|
||||||
"?Description, ?SitName, ?TouchName, " +
|
"?Description, ?SitName, ?TouchName, " +
|
||||||
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
|
"?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " +
|
||||||
"?GroupMask, ?EveryoneMask, ?BaseMask, " +
|
"?GroupMask, ?EveryoneMask, ?BaseMask, " +
|
||||||
"?PositionX, ?PositionY, ?PositionZ, " +
|
"?PositionX, ?PositionY, ?PositionZ, " +
|
||||||
"?GroupPositionX, ?GroupPositionY, " +
|
"?GroupPositionX, ?GroupPositionY, " +
|
||||||
"?GroupPositionZ, ?VelocityX, " +
|
"?GroupPositionZ, ?VelocityX, " +
|
||||||
"?VelocityY, ?VelocityZ, ?AngularVelocityX, " +
|
"?VelocityY, ?VelocityZ, ?AngularVelocityX, " +
|
||||||
"?AngularVelocityY, ?AngularVelocityZ, " +
|
"?AngularVelocityY, ?AngularVelocityZ, " +
|
||||||
"?AccelerationX, ?AccelerationY, " +
|
"?AccelerationX, ?AccelerationY, " +
|
||||||
"?AccelerationZ, ?RotationX, " +
|
"?AccelerationZ, ?RotationX, " +
|
||||||
"?RotationY, ?RotationZ, " +
|
"?RotationY, ?RotationZ, " +
|
||||||
"?RotationW, ?SitTargetOffsetX, " +
|
"?RotationW, ?SitTargetOffsetX, " +
|
||||||
"?SitTargetOffsetY, ?SitTargetOffsetZ, " +
|
"?SitTargetOffsetY, ?SitTargetOffsetZ, " +
|
||||||
"?SitTargetOrientW, ?SitTargetOrientX, " +
|
"?SitTargetOrientW, ?SitTargetOrientX, " +
|
||||||
"?SitTargetOrientY, ?SitTargetOrientZ, " +
|
"?SitTargetOrientY, ?SitTargetOrientZ, " +
|
||||||
"?RegionUUID, ?CreatorID, ?OwnerID, " +
|
"?RegionUUID, ?CreatorID, ?OwnerID, " +
|
||||||
"?GroupID, ?LastOwnerID, ?SceneGroupID, " +
|
"?GroupID, ?LastOwnerID, ?SceneGroupID, " +
|
||||||
"?PayPrice, ?PayButton1, ?PayButton2, " +
|
"?PayPrice, ?PayButton1, ?PayButton2, " +
|
||||||
"?PayButton3, ?PayButton4, ?LoopedSound, " +
|
"?PayButton3, ?PayButton4, ?LoopedSound, " +
|
||||||
"?LoopedSoundGain, ?TextureAnimation, " +
|
"?LoopedSoundGain, ?TextureAnimation, " +
|
||||||
"?OmegaX, ?OmegaY, ?OmegaZ, " +
|
"?OmegaX, ?OmegaY, ?OmegaZ, " +
|
||||||
"?CameraEyeOffsetX, ?CameraEyeOffsetY, " +
|
"?CameraEyeOffsetX, ?CameraEyeOffsetY, " +
|
||||||
"?CameraEyeOffsetZ, ?CameraAtOffsetX, " +
|
"?CameraEyeOffsetZ, ?CameraAtOffsetX, " +
|
||||||
"?CameraAtOffsetY, ?CameraAtOffsetZ, " +
|
"?CameraAtOffsetY, ?CameraAtOffsetZ, " +
|
||||||
"?ForceMouselook, ?ScriptAccessPin, " +
|
"?ForceMouselook, ?ScriptAccessPin, " +
|
||||||
"?AllowedDrop, ?DieAtEdge, ?SalePrice, " +
|
"?AllowedDrop, ?DieAtEdge, ?SalePrice, " +
|
||||||
"?SaleType, ?ColorR, ?ColorG, " +
|
"?SaleType, ?ColorR, ?ColorG, " +
|
||||||
"?ColorB, ?ColorA, ?ParticleSystem, " +
|
"?ColorB, ?ColorA, ?ParticleSystem, " +
|
||||||
"?ClickAction, ?Material, ?CollisionSound, " +
|
"?ClickAction, ?Material, ?CollisionSound, " +
|
||||||
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)";
|
"?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)";
|
||||||
|
|
||||||
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
|
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
ExecuteNonQuery(cmd);
|
||||||
|
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
|
|
||||||
cmd.CommandText = "replace into primshapes (" +
|
cmd.CommandText = "replace into primshapes (" +
|
||||||
"UUID, Shape, ScaleX, ScaleY, " +
|
"UUID, Shape, ScaleX, ScaleY, " +
|
||||||
"ScaleZ, PCode, PathBegin, PathEnd, " +
|
"ScaleZ, PCode, PathBegin, PathEnd, " +
|
||||||
"PathScaleX, PathScaleY, PathShearX, " +
|
"PathScaleX, PathScaleY, PathShearX, " +
|
||||||
"PathShearY, PathSkew, PathCurve, " +
|
"PathShearY, PathSkew, PathCurve, " +
|
||||||
"PathRadiusOffset, PathRevolutions, " +
|
"PathRadiusOffset, PathRevolutions, " +
|
||||||
"PathTaperX, PathTaperY, PathTwist, " +
|
"PathTaperX, PathTaperY, PathTwist, " +
|
||||||
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
|
"PathTwistBegin, ProfileBegin, ProfileEnd, " +
|
||||||
"ProfileCurve, ProfileHollow, Texture, " +
|
"ProfileCurve, ProfileHollow, Texture, " +
|
||||||
"ExtraParams, State, Media) values (?UUID, " +
|
"ExtraParams, State, Media) values (?UUID, " +
|
||||||
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
|
"?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " +
|
||||||
"?PCode, ?PathBegin, ?PathEnd, " +
|
"?PCode, ?PathBegin, ?PathEnd, " +
|
||||||
"?PathScaleX, ?PathScaleY, " +
|
"?PathScaleX, ?PathScaleY, " +
|
||||||
"?PathShearX, ?PathShearY, " +
|
"?PathShearX, ?PathShearY, " +
|
||||||
"?PathSkew, ?PathCurve, ?PathRadiusOffset, " +
|
"?PathSkew, ?PathCurve, ?PathRadiusOffset, " +
|
||||||
"?PathRevolutions, ?PathTaperX, " +
|
"?PathRevolutions, ?PathTaperX, " +
|
||||||
"?PathTaperY, ?PathTwist, " +
|
"?PathTaperY, ?PathTwist, " +
|
||||||
"?PathTwistBegin, ?ProfileBegin, " +
|
"?PathTwistBegin, ?ProfileBegin, " +
|
||||||
"?ProfileEnd, ?ProfileCurve, " +
|
"?ProfileEnd, ?ProfileCurve, " +
|
||||||
"?ProfileHollow, ?Texture, ?ExtraParams, " +
|
"?ProfileHollow, ?Texture, ?ExtraParams, " +
|
||||||
"?State, ?Media)";
|
"?State, ?Media)";
|
||||||
|
|
||||||
FillShapeCommand(cmd, prim);
|
FillShapeCommand(cmd, prim);
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
ExecuteNonQuery(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Dispose();
|
||||||
}
|
}
|
||||||
cmd.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,10 +360,13 @@ namespace OpenSim.Data.SQLite
|
||||||
|
|
||||||
lock (ds)
|
lock (ds)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart prim in obj.Children.Values)
|
lock (obj.Children)
|
||||||
{
|
{
|
||||||
// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
foreach (SceneObjectPart prim in obj.Children.Values)
|
||||||
addPrim(prim, obj.UUID, regionUUID);
|
{
|
||||||
|
// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
||||||
|
addPrim(prim, obj.UUID, regionUUID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -327,10 +327,13 @@ namespace OpenSim.Data.SQLiteLegacy
|
||||||
|
|
||||||
lock (ds)
|
lock (ds)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart prim in obj.Children.Values)
|
lock (obj.Children)
|
||||||
{
|
{
|
||||||
// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
foreach (SceneObjectPart prim in obj.Children.Values)
|
||||||
addPrim(prim, obj.UUID, regionUUID);
|
{
|
||||||
|
// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
|
||||||
|
addPrim(prim, obj.UUID, regionUUID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -406,7 +406,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
||||||
{
|
{
|
||||||
if (!m_scene.Permissions.CanRezObject(
|
if (!m_scene.Permissions.CanRezObject(
|
||||||
part.ParentGroup.Children.Count, remoteClient.AgentId, presence.AbsolutePosition))
|
part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
presence.Appearance.DetachAttachment(itemID);
|
presence.Appearance.DetachAttachment(itemID);
|
||||||
|
|
|
@ -526,7 +526,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
group.RootPart.CreateSelected = true;
|
group.RootPart.CreateSelected = true;
|
||||||
|
|
||||||
if (!m_Scene.Permissions.CanRezObject(
|
if (!m_Scene.Permissions.CanRezObject(
|
||||||
group.Children.Count, remoteClient.AgentId, pos)
|
group.PrimCount, remoteClient.AgentId, pos)
|
||||||
&& !attachment)
|
&& !attachment)
|
||||||
{
|
{
|
||||||
// The client operates in no fail mode. It will
|
// The client operates in no fail mode. It will
|
||||||
|
@ -594,7 +594,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
rootPart.Name = item.Name;
|
rootPart.Name = item.Name;
|
||||||
rootPart.Description = item.Description;
|
rootPart.Description = item.Description;
|
||||||
|
|
||||||
List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
|
List<SceneObjectPart> partList = null;
|
||||||
|
lock (group.Children)
|
||||||
|
partList = new List<SceneObjectPart>(group.Children.Values);
|
||||||
|
|
||||||
group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
|
group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
|
||||||
if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0)
|
if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0)
|
||||||
|
|
|
@ -243,36 +243,39 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
// to the same scene (when this is possible).
|
// to the same scene (when this is possible).
|
||||||
sceneObject.ResetIDs();
|
sceneObject.ResetIDs();
|
||||||
|
|
||||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
lock (sceneObject.Children)
|
||||||
{
|
{
|
||||||
if (!ResolveUserUuid(part.CreatorID))
|
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||||
part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
|
||||||
|
|
||||||
if (!ResolveUserUuid(part.OwnerID))
|
|
||||||
part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
|
||||||
|
|
||||||
if (!ResolveUserUuid(part.LastOwnerID))
|
|
||||||
part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
|
||||||
|
|
||||||
// And zap any troublesome sit target information
|
|
||||||
part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
|
|
||||||
part.SitTargetPosition = new Vector3(0, 0, 0);
|
|
||||||
|
|
||||||
// Fix ownership/creator of inventory items
|
|
||||||
// Not doing so results in inventory items
|
|
||||||
// being no copy/no mod for everyone
|
|
||||||
lock (part.TaskInventory)
|
|
||||||
{
|
{
|
||||||
TaskInventoryDictionary inv = part.TaskInventory;
|
if (!ResolveUserUuid(part.CreatorID))
|
||||||
foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
|
part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||||
|
|
||||||
|
if (!ResolveUserUuid(part.OwnerID))
|
||||||
|
part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||||
|
|
||||||
|
if (!ResolveUserUuid(part.LastOwnerID))
|
||||||
|
part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||||
|
|
||||||
|
// And zap any troublesome sit target information
|
||||||
|
part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
|
||||||
|
part.SitTargetPosition = new Vector3(0, 0, 0);
|
||||||
|
|
||||||
|
// Fix ownership/creator of inventory items
|
||||||
|
// Not doing so results in inventory items
|
||||||
|
// being no copy/no mod for everyone
|
||||||
|
lock (part.TaskInventory)
|
||||||
{
|
{
|
||||||
if (!ResolveUserUuid(kvp.Value.OwnerID))
|
TaskInventoryDictionary inv = part.TaskInventory;
|
||||||
|
foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
|
||||||
{
|
{
|
||||||
kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
if (!ResolveUserUuid(kvp.Value.OwnerID))
|
||||||
}
|
{
|
||||||
if (!ResolveUserUuid(kvp.Value.CreatorID))
|
kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||||
{
|
}
|
||||||
kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
if (!ResolveUserUuid(kvp.Value.CreatorID))
|
||||||
|
{
|
||||||
|
kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,10 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
|
||||||
group.SetOwnerId(remoteClient.AgentId);
|
group.SetOwnerId(remoteClient.AgentId);
|
||||||
group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId);
|
group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId);
|
||||||
|
|
||||||
List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
|
List<SceneObjectPart> partList = null;
|
||||||
|
|
||||||
|
lock (group.Children)
|
||||||
|
partList = new List<SceneObjectPart>(group.Children.Values);
|
||||||
|
|
||||||
if (m_scene.Permissions.PropagatePermissions())
|
if (m_scene.Permissions.PropagatePermissions())
|
||||||
{
|
{
|
||||||
|
|
|
@ -227,277 +227,281 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||||
{
|
{
|
||||||
SceneObjectGroup mapdot = (SceneObjectGroup)obj;
|
SceneObjectGroup mapdot = (SceneObjectGroup)obj;
|
||||||
Color mapdotspot = Color.Gray; // Default color when prim color is white
|
Color mapdotspot = Color.Gray; // Default color when prim color is white
|
||||||
|
|
||||||
// Loop over prim in group
|
// Loop over prim in group
|
||||||
foreach (SceneObjectPart part in mapdot.Children.Values)
|
lock (mapdot.Children)
|
||||||
{
|
{
|
||||||
if (part == null)
|
foreach (SceneObjectPart part in mapdot.Children.Values)
|
||||||
continue;
|
|
||||||
|
|
||||||
// Draw if the object is at least 1 meter wide in any direction
|
|
||||||
if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f)
|
|
||||||
{
|
{
|
||||||
// Try to get the RGBA of the default texture entry..
|
if (part == null)
|
||||||
//
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// get the null checks out of the way
|
|
||||||
// skip the ones that break
|
|
||||||
if (part == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (part.Shape == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass)
|
|
||||||
continue; // eliminates trees from this since we don't really have a good tree representation
|
|
||||||
// if you want tree blocks on the map comment the above line and uncomment the below line
|
|
||||||
//mapdotspot = Color.PaleGreen;
|
|
||||||
|
|
||||||
Primitive.TextureEntry textureEntry = part.Shape.Textures;
|
|
||||||
|
|
||||||
if (textureEntry == null || textureEntry.DefaultTexture == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Color4 texcolor = textureEntry.DefaultTexture.RGBA;
|
|
||||||
|
|
||||||
// Not sure why some of these are null, oh well.
|
|
||||||
|
|
||||||
int colorr = 255 - (int)(texcolor.R * 255f);
|
|
||||||
int colorg = 255 - (int)(texcolor.G * 255f);
|
|
||||||
int colorb = 255 - (int)(texcolor.B * 255f);
|
|
||||||
|
|
||||||
if (!(colorr == 255 && colorg == 255 && colorb == 255))
|
|
||||||
{
|
|
||||||
//Try to set the map spot color
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// If the color gets goofy somehow, skip it *shakes fist at Color4
|
|
||||||
mapdotspot = Color.FromArgb(colorr, colorg, colorb);
|
|
||||||
}
|
|
||||||
catch (ArgumentException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IndexOutOfRangeException)
|
|
||||||
{
|
|
||||||
// Windows Array
|
|
||||||
}
|
|
||||||
catch (ArgumentOutOfRangeException)
|
|
||||||
{
|
|
||||||
// Mono Array
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 pos = part.GetWorldPosition();
|
|
||||||
|
|
||||||
// skip prim outside of retion
|
|
||||||
if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// skip prim in non-finite position
|
// Draw if the object is at least 1 meter wide in any direction
|
||||||
if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) ||
|
if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f)
|
||||||
Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Figure out if object is under 256m above the height of the terrain
|
|
||||||
bool isBelow256AboveTerrain = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f));
|
// Try to get the RGBA of the default texture entry..
|
||||||
}
|
//
|
||||||
catch (Exception)
|
try
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isBelow256AboveTerrain)
|
|
||||||
{
|
|
||||||
// Translate scale by rotation so scale is represented properly when object is rotated
|
|
||||||
Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z);
|
|
||||||
Vector3 scale = new Vector3();
|
|
||||||
Vector3 tScale = new Vector3();
|
|
||||||
Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z);
|
|
||||||
|
|
||||||
Quaternion llrot = part.GetWorldRotation();
|
|
||||||
Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z);
|
|
||||||
scale = lscale * rot;
|
|
||||||
|
|
||||||
// negative scales don't work in this situation
|
|
||||||
scale.X = Math.Abs(scale.X);
|
|
||||||
scale.Y = Math.Abs(scale.Y);
|
|
||||||
scale.Z = Math.Abs(scale.Z);
|
|
||||||
|
|
||||||
// This scaling isn't very accurate and doesn't take into account the face rotation :P
|
|
||||||
int mapdrawstartX = (int)(pos.X - scale.X);
|
|
||||||
int mapdrawstartY = (int)(pos.Y - scale.Y);
|
|
||||||
int mapdrawendX = (int)(pos.X + scale.X);
|
|
||||||
int mapdrawendY = (int)(pos.Y + scale.Y);
|
|
||||||
|
|
||||||
// If object is beyond the edge of the map, don't draw it to avoid errors
|
|
||||||
if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1)
|
|
||||||
|| mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0
|
|
||||||
|| mapdrawendY > ((int)Constants.RegionSize - 1))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
#region obb face reconstruction part duex
|
|
||||||
Vector3[] vertexes = new Vector3[8];
|
|
||||||
|
|
||||||
// float[] distance = new float[6];
|
|
||||||
Vector3[] FaceA = new Vector3[6]; // vertex A for Facei
|
|
||||||
Vector3[] FaceB = new Vector3[6]; // vertex B for Facei
|
|
||||||
Vector3[] FaceC = new Vector3[6]; // vertex C for Facei
|
|
||||||
Vector3[] FaceD = new Vector3[6]; // vertex D for Facei
|
|
||||||
|
|
||||||
tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z);
|
|
||||||
scale = ((tScale * rot));
|
|
||||||
vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
|
||||||
// vertexes[0].x = pos.X + vertexes[0].x;
|
|
||||||
//vertexes[0].y = pos.Y + vertexes[0].y;
|
|
||||||
//vertexes[0].z = pos.Z + vertexes[0].z;
|
|
||||||
|
|
||||||
FaceA[0] = vertexes[0];
|
|
||||||
FaceB[3] = vertexes[0];
|
|
||||||
FaceA[4] = vertexes[0];
|
|
||||||
|
|
||||||
tScale = lscale;
|
|
||||||
scale = ((tScale * rot));
|
|
||||||
vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
|
||||||
|
|
||||||
// vertexes[1].x = pos.X + vertexes[1].x;
|
|
||||||
// vertexes[1].y = pos.Y + vertexes[1].y;
|
|
||||||
//vertexes[1].z = pos.Z + vertexes[1].z;
|
|
||||||
|
|
||||||
FaceB[0] = vertexes[1];
|
|
||||||
FaceA[1] = vertexes[1];
|
|
||||||
FaceC[4] = vertexes[1];
|
|
||||||
|
|
||||||
tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z);
|
|
||||||
scale = ((tScale * rot));
|
|
||||||
|
|
||||||
vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
|
||||||
|
|
||||||
//vertexes[2].x = pos.X + vertexes[2].x;
|
|
||||||
//vertexes[2].y = pos.Y + vertexes[2].y;
|
|
||||||
//vertexes[2].z = pos.Z + vertexes[2].z;
|
|
||||||
|
|
||||||
FaceC[0] = vertexes[2];
|
|
||||||
FaceD[3] = vertexes[2];
|
|
||||||
FaceC[5] = vertexes[2];
|
|
||||||
|
|
||||||
tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z);
|
|
||||||
scale = ((tScale * rot));
|
|
||||||
vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
|
||||||
|
|
||||||
//vertexes[3].x = pos.X + vertexes[3].x;
|
|
||||||
// vertexes[3].y = pos.Y + vertexes[3].y;
|
|
||||||
// vertexes[3].z = pos.Z + vertexes[3].z;
|
|
||||||
|
|
||||||
FaceD[0] = vertexes[3];
|
|
||||||
FaceC[1] = vertexes[3];
|
|
||||||
FaceA[5] = vertexes[3];
|
|
||||||
|
|
||||||
tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z);
|
|
||||||
scale = ((tScale * rot));
|
|
||||||
vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
|
||||||
|
|
||||||
// vertexes[4].x = pos.X + vertexes[4].x;
|
|
||||||
// vertexes[4].y = pos.Y + vertexes[4].y;
|
|
||||||
// vertexes[4].z = pos.Z + vertexes[4].z;
|
|
||||||
|
|
||||||
FaceB[1] = vertexes[4];
|
|
||||||
FaceA[2] = vertexes[4];
|
|
||||||
FaceD[4] = vertexes[4];
|
|
||||||
|
|
||||||
tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z);
|
|
||||||
scale = ((tScale * rot));
|
|
||||||
vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
|
||||||
|
|
||||||
// vertexes[5].x = pos.X + vertexes[5].x;
|
|
||||||
// vertexes[5].y = pos.Y + vertexes[5].y;
|
|
||||||
// vertexes[5].z = pos.Z + vertexes[5].z;
|
|
||||||
|
|
||||||
FaceD[1] = vertexes[5];
|
|
||||||
FaceC[2] = vertexes[5];
|
|
||||||
FaceB[5] = vertexes[5];
|
|
||||||
|
|
||||||
tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z);
|
|
||||||
scale = ((tScale * rot));
|
|
||||||
vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
|
||||||
|
|
||||||
// vertexes[6].x = pos.X + vertexes[6].x;
|
|
||||||
// vertexes[6].y = pos.Y + vertexes[6].y;
|
|
||||||
// vertexes[6].z = pos.Z + vertexes[6].z;
|
|
||||||
|
|
||||||
FaceB[2] = vertexes[6];
|
|
||||||
FaceA[3] = vertexes[6];
|
|
||||||
FaceB[4] = vertexes[6];
|
|
||||||
|
|
||||||
tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z);
|
|
||||||
scale = ((tScale * rot));
|
|
||||||
vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
|
||||||
|
|
||||||
// vertexes[7].x = pos.X + vertexes[7].x;
|
|
||||||
// vertexes[7].y = pos.Y + vertexes[7].y;
|
|
||||||
// vertexes[7].z = pos.Z + vertexes[7].z;
|
|
||||||
|
|
||||||
FaceD[2] = vertexes[7];
|
|
||||||
FaceC[3] = vertexes[7];
|
|
||||||
FaceD[5] = vertexes[7];
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
//int wy = 0;
|
|
||||||
|
|
||||||
//bool breakYN = false; // If we run into an error drawing, break out of the
|
|
||||||
// loop so we don't lag to death on error handling
|
|
||||||
DrawStruct ds = new DrawStruct();
|
|
||||||
ds.brush = new SolidBrush(mapdotspot);
|
|
||||||
//ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY);
|
|
||||||
|
|
||||||
ds.trns = new face[FaceA.Length];
|
|
||||||
|
|
||||||
for (int i = 0; i < FaceA.Length; i++)
|
|
||||||
{
|
{
|
||||||
Point[] working = new Point[5];
|
// get the null checks out of the way
|
||||||
working[0] = project(FaceA[i], axPos);
|
// skip the ones that break
|
||||||
working[1] = project(FaceB[i], axPos);
|
if (part == null)
|
||||||
working[2] = project(FaceD[i], axPos);
|
continue;
|
||||||
working[3] = project(FaceC[i], axPos);
|
|
||||||
working[4] = project(FaceA[i], axPos);
|
|
||||||
|
|
||||||
face workingface = new face();
|
if (part.Shape == null)
|
||||||
workingface.pts = working;
|
continue;
|
||||||
|
|
||||||
ds.trns[i] = workingface;
|
if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass)
|
||||||
|
continue; // eliminates trees from this since we don't really have a good tree representation
|
||||||
|
// if you want tree blocks on the map comment the above line and uncomment the below line
|
||||||
|
//mapdotspot = Color.PaleGreen;
|
||||||
|
|
||||||
|
Primitive.TextureEntry textureEntry = part.Shape.Textures;
|
||||||
|
|
||||||
|
if (textureEntry == null || textureEntry.DefaultTexture == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Color4 texcolor = textureEntry.DefaultTexture.RGBA;
|
||||||
|
|
||||||
|
// Not sure why some of these are null, oh well.
|
||||||
|
|
||||||
|
int colorr = 255 - (int)(texcolor.R * 255f);
|
||||||
|
int colorg = 255 - (int)(texcolor.G * 255f);
|
||||||
|
int colorb = 255 - (int)(texcolor.B * 255f);
|
||||||
|
|
||||||
|
if (!(colorr == 255 && colorg == 255 && colorb == 255))
|
||||||
|
{
|
||||||
|
//Try to set the map spot color
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// If the color gets goofy somehow, skip it *shakes fist at Color4
|
||||||
|
mapdotspot = Color.FromArgb(colorr, colorg, colorb);
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IndexOutOfRangeException)
|
||||||
|
{
|
||||||
|
// Windows Array
|
||||||
|
}
|
||||||
|
catch (ArgumentOutOfRangeException)
|
||||||
|
{
|
||||||
|
// Mono Array
|
||||||
}
|
}
|
||||||
|
|
||||||
z_sort.Add(part.LocalId, ds);
|
Vector3 pos = part.GetWorldPosition();
|
||||||
z_localIDs.Add(part.LocalId);
|
|
||||||
z_sortheights.Add(pos.Z);
|
|
||||||
|
|
||||||
//for (int wx = mapdrawstartX; wx < mapdrawendX; wx++)
|
// skip prim outside of retion
|
||||||
//{
|
if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f)
|
||||||
//for (wy = mapdrawstartY; wy < mapdrawendY; wy++)
|
continue;
|
||||||
|
|
||||||
|
// skip prim in non-finite position
|
||||||
|
if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) ||
|
||||||
|
Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Figure out if object is under 256m above the height of the terrain
|
||||||
|
bool isBelow256AboveTerrain = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBelow256AboveTerrain)
|
||||||
|
{
|
||||||
|
// Translate scale by rotation so scale is represented properly when object is rotated
|
||||||
|
Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z);
|
||||||
|
Vector3 scale = new Vector3();
|
||||||
|
Vector3 tScale = new Vector3();
|
||||||
|
Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z);
|
||||||
|
|
||||||
|
Quaternion llrot = part.GetWorldRotation();
|
||||||
|
Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z);
|
||||||
|
scale = lscale * rot;
|
||||||
|
|
||||||
|
// negative scales don't work in this situation
|
||||||
|
scale.X = Math.Abs(scale.X);
|
||||||
|
scale.Y = Math.Abs(scale.Y);
|
||||||
|
scale.Z = Math.Abs(scale.Z);
|
||||||
|
|
||||||
|
// This scaling isn't very accurate and doesn't take into account the face rotation :P
|
||||||
|
int mapdrawstartX = (int)(pos.X - scale.X);
|
||||||
|
int mapdrawstartY = (int)(pos.Y - scale.Y);
|
||||||
|
int mapdrawendX = (int)(pos.X + scale.X);
|
||||||
|
int mapdrawendY = (int)(pos.Y + scale.Y);
|
||||||
|
|
||||||
|
// If object is beyond the edge of the map, don't draw it to avoid errors
|
||||||
|
if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1)
|
||||||
|
|| mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0
|
||||||
|
|| mapdrawendY > ((int)Constants.RegionSize - 1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#region obb face reconstruction part duex
|
||||||
|
Vector3[] vertexes = new Vector3[8];
|
||||||
|
|
||||||
|
// float[] distance = new float[6];
|
||||||
|
Vector3[] FaceA = new Vector3[6]; // vertex A for Facei
|
||||||
|
Vector3[] FaceB = new Vector3[6]; // vertex B for Facei
|
||||||
|
Vector3[] FaceC = new Vector3[6]; // vertex C for Facei
|
||||||
|
Vector3[] FaceD = new Vector3[6]; // vertex D for Facei
|
||||||
|
|
||||||
|
tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z);
|
||||||
|
scale = ((tScale * rot));
|
||||||
|
vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
||||||
|
// vertexes[0].x = pos.X + vertexes[0].x;
|
||||||
|
//vertexes[0].y = pos.Y + vertexes[0].y;
|
||||||
|
//vertexes[0].z = pos.Z + vertexes[0].z;
|
||||||
|
|
||||||
|
FaceA[0] = vertexes[0];
|
||||||
|
FaceB[3] = vertexes[0];
|
||||||
|
FaceA[4] = vertexes[0];
|
||||||
|
|
||||||
|
tScale = lscale;
|
||||||
|
scale = ((tScale * rot));
|
||||||
|
vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
||||||
|
|
||||||
|
// vertexes[1].x = pos.X + vertexes[1].x;
|
||||||
|
// vertexes[1].y = pos.Y + vertexes[1].y;
|
||||||
|
//vertexes[1].z = pos.Z + vertexes[1].z;
|
||||||
|
|
||||||
|
FaceB[0] = vertexes[1];
|
||||||
|
FaceA[1] = vertexes[1];
|
||||||
|
FaceC[4] = vertexes[1];
|
||||||
|
|
||||||
|
tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z);
|
||||||
|
scale = ((tScale * rot));
|
||||||
|
|
||||||
|
vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
||||||
|
|
||||||
|
//vertexes[2].x = pos.X + vertexes[2].x;
|
||||||
|
//vertexes[2].y = pos.Y + vertexes[2].y;
|
||||||
|
//vertexes[2].z = pos.Z + vertexes[2].z;
|
||||||
|
|
||||||
|
FaceC[0] = vertexes[2];
|
||||||
|
FaceD[3] = vertexes[2];
|
||||||
|
FaceC[5] = vertexes[2];
|
||||||
|
|
||||||
|
tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z);
|
||||||
|
scale = ((tScale * rot));
|
||||||
|
vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
||||||
|
|
||||||
|
//vertexes[3].x = pos.X + vertexes[3].x;
|
||||||
|
// vertexes[3].y = pos.Y + vertexes[3].y;
|
||||||
|
// vertexes[3].z = pos.Z + vertexes[3].z;
|
||||||
|
|
||||||
|
FaceD[0] = vertexes[3];
|
||||||
|
FaceC[1] = vertexes[3];
|
||||||
|
FaceA[5] = vertexes[3];
|
||||||
|
|
||||||
|
tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z);
|
||||||
|
scale = ((tScale * rot));
|
||||||
|
vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
||||||
|
|
||||||
|
// vertexes[4].x = pos.X + vertexes[4].x;
|
||||||
|
// vertexes[4].y = pos.Y + vertexes[4].y;
|
||||||
|
// vertexes[4].z = pos.Z + vertexes[4].z;
|
||||||
|
|
||||||
|
FaceB[1] = vertexes[4];
|
||||||
|
FaceA[2] = vertexes[4];
|
||||||
|
FaceD[4] = vertexes[4];
|
||||||
|
|
||||||
|
tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z);
|
||||||
|
scale = ((tScale * rot));
|
||||||
|
vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
||||||
|
|
||||||
|
// vertexes[5].x = pos.X + vertexes[5].x;
|
||||||
|
// vertexes[5].y = pos.Y + vertexes[5].y;
|
||||||
|
// vertexes[5].z = pos.Z + vertexes[5].z;
|
||||||
|
|
||||||
|
FaceD[1] = vertexes[5];
|
||||||
|
FaceC[2] = vertexes[5];
|
||||||
|
FaceB[5] = vertexes[5];
|
||||||
|
|
||||||
|
tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z);
|
||||||
|
scale = ((tScale * rot));
|
||||||
|
vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
||||||
|
|
||||||
|
// vertexes[6].x = pos.X + vertexes[6].x;
|
||||||
|
// vertexes[6].y = pos.Y + vertexes[6].y;
|
||||||
|
// vertexes[6].z = pos.Z + vertexes[6].z;
|
||||||
|
|
||||||
|
FaceB[2] = vertexes[6];
|
||||||
|
FaceA[3] = vertexes[6];
|
||||||
|
FaceB[4] = vertexes[6];
|
||||||
|
|
||||||
|
tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z);
|
||||||
|
scale = ((tScale * rot));
|
||||||
|
vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z)));
|
||||||
|
|
||||||
|
// vertexes[7].x = pos.X + vertexes[7].x;
|
||||||
|
// vertexes[7].y = pos.Y + vertexes[7].y;
|
||||||
|
// vertexes[7].z = pos.Z + vertexes[7].z;
|
||||||
|
|
||||||
|
FaceD[2] = vertexes[7];
|
||||||
|
FaceC[3] = vertexes[7];
|
||||||
|
FaceD[5] = vertexes[7];
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
//int wy = 0;
|
||||||
|
|
||||||
|
//bool breakYN = false; // If we run into an error drawing, break out of the
|
||||||
|
// loop so we don't lag to death on error handling
|
||||||
|
DrawStruct ds = new DrawStruct();
|
||||||
|
ds.brush = new SolidBrush(mapdotspot);
|
||||||
|
//ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY);
|
||||||
|
|
||||||
|
ds.trns = new face[FaceA.Length];
|
||||||
|
|
||||||
|
for (int i = 0; i < FaceA.Length; i++)
|
||||||
|
{
|
||||||
|
Point[] working = new Point[5];
|
||||||
|
working[0] = project(FaceA[i], axPos);
|
||||||
|
working[1] = project(FaceB[i], axPos);
|
||||||
|
working[2] = project(FaceD[i], axPos);
|
||||||
|
working[3] = project(FaceC[i], axPos);
|
||||||
|
working[4] = project(FaceA[i], axPos);
|
||||||
|
|
||||||
|
face workingface = new face();
|
||||||
|
workingface.pts = working;
|
||||||
|
|
||||||
|
ds.trns[i] = workingface;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_sort.Add(part.LocalId, ds);
|
||||||
|
z_localIDs.Add(part.LocalId);
|
||||||
|
z_sortheights.Add(pos.Z);
|
||||||
|
|
||||||
|
//for (int wx = mapdrawstartX; wx < mapdrawendX; wx++)
|
||||||
//{
|
//{
|
||||||
//m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy);
|
//for (wy = mapdrawstartY; wy < mapdrawendY; wy++)
|
||||||
//try
|
|
||||||
//{
|
//{
|
||||||
// Remember, flip the y!
|
//m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy);
|
||||||
// mapbmp.SetPixel(wx, (255 - wy), mapdotspot);
|
//try
|
||||||
//}
|
//{
|
||||||
//catch (ArgumentException)
|
// Remember, flip the y!
|
||||||
//{
|
// mapbmp.SetPixel(wx, (255 - wy), mapdotspot);
|
||||||
// breakYN = true;
|
//}
|
||||||
|
//catch (ArgumentException)
|
||||||
|
//{
|
||||||
|
// breakYN = true;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (breakYN)
|
||||||
|
// break;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//if (breakYN)
|
//if (breakYN)
|
||||||
// break;
|
// break;
|
||||||
//}
|
//}
|
||||||
|
} // Object is within 256m Z of terrain
|
||||||
//if (breakYN)
|
} // object is at least a meter wide
|
||||||
// break;
|
} // mapdot.Children lock
|
||||||
//}
|
|
||||||
} // Object is within 256m Z of terrain
|
|
||||||
} // object is at least a meter wide
|
|
||||||
} // loop over group children
|
} // loop over group children
|
||||||
} // entitybase is sceneobject group
|
} // entitybase is sceneobject group
|
||||||
} // foreach loop over entities
|
} // foreach loop over entities
|
||||||
|
|
|
@ -1974,7 +1974,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (null == group)
|
if (null == group)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (!Permissions.CanRezObject(group.Children.Count, item.OwnerID, pos))
|
if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (!Permissions.BypassPermissions())
|
if (!Permissions.BypassPermissions())
|
||||||
|
@ -2051,8 +2051,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
sog.SetGroup(groupID, remoteClient);
|
sog.SetGroup(groupID, remoteClient);
|
||||||
sog.ScheduleGroupForFullUpdate();
|
sog.ScheduleGroupForFullUpdate();
|
||||||
|
|
||||||
foreach (SceneObjectPart child in sog.Children.Values)
|
lock (sog.Children)
|
||||||
child.Inventory.ChangeInventoryOwner(ownerID);
|
{
|
||||||
|
foreach (SceneObjectPart child in sog.Children.Values)
|
||||||
|
child.Inventory.ChangeInventoryOwner(ownerID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2062,16 +2065,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (sog.GroupID != groupID)
|
if (sog.GroupID != groupID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
foreach (SceneObjectPart child in sog.Children.Values)
|
lock (sog.Children)
|
||||||
{
|
{
|
||||||
child.LastOwnerID = child.OwnerID;
|
foreach (SceneObjectPart child in sog.Children.Values)
|
||||||
child.Inventory.ChangeInventoryOwner(groupID);
|
{
|
||||||
|
child.LastOwnerID = child.OwnerID;
|
||||||
|
child.Inventory.ChangeInventoryOwner(groupID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sog.SetOwnerId(groupID);
|
sog.SetOwnerId(groupID);
|
||||||
sog.ApplyNextOwnerPermissions();
|
sog.ApplyNextOwnerPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (uint localID in localIDs)
|
foreach (uint localID in localIDs)
|
||||||
|
|
|
@ -156,21 +156,29 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We also need to check the children of this prim as they
|
// We also need to check the children of this prim as they
|
||||||
// can be selected as well and send property information
|
// can be selected as well and send property information
|
||||||
bool foundPrim = false;
|
bool foundPrim = false;
|
||||||
foreach (KeyValuePair<UUID, SceneObjectPart> child in ((SceneObjectGroup) ent).Children)
|
|
||||||
{
|
SceneObjectGroup sog = ent as SceneObjectGroup;
|
||||||
if (child.Value.LocalId == primLocalID)
|
|
||||||
{
|
lock (sog.Children)
|
||||||
child.Value.GetProperties(remoteClient);
|
{
|
||||||
foundPrim = true;
|
foreach (KeyValuePair<UUID, SceneObjectPart> child in (sog.Children))
|
||||||
break;
|
{
|
||||||
}
|
if (child.Value.LocalId == primLocalID)
|
||||||
}
|
{
|
||||||
if (foundPrim) break;
|
child.Value.GetProperties(remoteClient);
|
||||||
|
foundPrim = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundPrim)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1756,8 +1756,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (group.RootPart == null)
|
if (group.RootPart == null)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
|
m_log.ErrorFormat(
|
||||||
group.Children == null ? 0 : group.Children.Count);
|
"[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
|
||||||
|
group.Children == null ? 0 : group.PrimCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddRestoredSceneObject(group, true, true);
|
AddRestoredSceneObject(group, true, true);
|
||||||
|
@ -2064,18 +2065,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
group.RemoveScriptInstances(true);
|
group.RemoveScriptInstances(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (SceneObjectPart part in group.Children.Values)
|
lock (group.Children)
|
||||||
{
|
{
|
||||||
if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
|
foreach (SceneObjectPart part in group.Children.Values)
|
||||||
{
|
{
|
||||||
PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
|
if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
|
||||||
}
|
{
|
||||||
else if (part.PhysActor != null)
|
PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
|
||||||
{
|
}
|
||||||
PhysicsScene.RemovePrim(part.PhysActor);
|
else if (part.PhysActor != null)
|
||||||
part.PhysActor = null;
|
{
|
||||||
|
PhysicsScene.RemovePrim(part.PhysActor);
|
||||||
|
part.PhysActor = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (rootPart.PhysActor != null)
|
// if (rootPart.PhysActor != null)
|
||||||
// {
|
// {
|
||||||
// PhysicsScene.RemovePrim(rootPart.PhysActor);
|
// PhysicsScene.RemovePrim(rootPart.PhysActor);
|
||||||
|
@ -2426,15 +2431,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// Force allocation of new LocalId
|
// Force allocation of new LocalId
|
||||||
//
|
//
|
||||||
foreach (SceneObjectPart p in sceneObject.Children.Values)
|
lock (sceneObject.Children)
|
||||||
p.LocalId = 0;
|
{
|
||||||
|
foreach (SceneObjectPart p in sceneObject.Children.Values)
|
||||||
|
p.LocalId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (sceneObject.IsAttachmentCheckFull()) // Attachment
|
if (sceneObject.IsAttachmentCheckFull()) // Attachment
|
||||||
{
|
{
|
||||||
sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
|
sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
|
||||||
sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
|
sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
|
||||||
|
|
||||||
|
|
||||||
// Don't sent a full update here because this will cause full updates to be sent twice for
|
// Don't sent a full update here because this will cause full updates to be sent twice for
|
||||||
// attachments on region crossings, resulting in viewer glitches.
|
// attachments on region crossings, resulting in viewer glitches.
|
||||||
AddRestoredSceneObject(sceneObject, false, false, false);
|
AddRestoredSceneObject(sceneObject, false, false, false);
|
||||||
|
@ -2447,7 +2454,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (sp != null)
|
if (sp != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
SceneObjectGroup grp = sceneObject;
|
SceneObjectGroup grp = sceneObject;
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
|
@ -2459,7 +2465,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (AttachmentsModule != null)
|
if (AttachmentsModule != null)
|
||||||
AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false);
|
AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -364,45 +364,48 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
|
// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
|
||||||
// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
|
// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
|
||||||
|
|
||||||
if (m_parentScene.m_clampPrimSize)
|
lock (sceneObject.Children)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
if (m_parentScene.m_clampPrimSize)
|
||||||
{
|
{
|
||||||
Vector3 scale = part.Shape.Scale;
|
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||||
|
{
|
||||||
|
Vector3 scale = part.Shape.Scale;
|
||||||
|
|
||||||
if (scale.X > m_parentScene.m_maxNonphys)
|
if (scale.X > m_parentScene.m_maxNonphys)
|
||||||
scale.X = m_parentScene.m_maxNonphys;
|
scale.X = m_parentScene.m_maxNonphys;
|
||||||
if (scale.Y > m_parentScene.m_maxNonphys)
|
if (scale.Y > m_parentScene.m_maxNonphys)
|
||||||
scale.Y = m_parentScene.m_maxNonphys;
|
scale.Y = m_parentScene.m_maxNonphys;
|
||||||
if (scale.Z > m_parentScene.m_maxNonphys)
|
if (scale.Z > m_parentScene.m_maxNonphys)
|
||||||
scale.Z = m_parentScene.m_maxNonphys;
|
scale.Z = m_parentScene.m_maxNonphys;
|
||||||
|
|
||||||
part.Shape.Scale = scale;
|
part.Shape.Scale = scale;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sceneObject.AttachToScene(m_parentScene);
|
sceneObject.AttachToScene(m_parentScene);
|
||||||
|
|
||||||
if (sendClientUpdates)
|
if (sendClientUpdates)
|
||||||
sceneObject.ScheduleGroupForFullUpdate();
|
sceneObject.ScheduleGroupForFullUpdate();
|
||||||
|
|
||||||
Entities.Add(sceneObject);
|
Entities.Add(sceneObject);
|
||||||
m_numPrim += sceneObject.Children.Count;
|
m_numPrim += sceneObject.Children.Count;
|
||||||
|
|
||||||
if (attachToBackup)
|
if (attachToBackup)
|
||||||
sceneObject.AttachToBackup();
|
sceneObject.AttachToBackup();
|
||||||
|
|
||||||
if (OnObjectCreate != null)
|
if (OnObjectCreate != null)
|
||||||
OnObjectCreate(sceneObject);
|
OnObjectCreate(sceneObject);
|
||||||
|
|
||||||
lock (m_dictionary_lock)
|
lock (m_dictionary_lock)
|
||||||
{
|
|
||||||
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
|
|
||||||
SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
|
|
||||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
|
||||||
{
|
{
|
||||||
SceneObjectGroupsByFullID[part.UUID] = sceneObject;
|
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
|
||||||
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
|
SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
|
||||||
|
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||||
|
{
|
||||||
|
SceneObjectGroupsByFullID[part.UUID] = sceneObject;
|
||||||
|
SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,11 +423,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (!resultOfObjectLinked)
|
if (!resultOfObjectLinked)
|
||||||
{
|
{
|
||||||
m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count;
|
SceneObjectGroup sog = Entities[uuid] as SceneObjectGroup;
|
||||||
|
|
||||||
if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
|
lock (sog.Children)
|
||||||
{
|
{
|
||||||
RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count);
|
m_numPrim -= sog.PrimCount;
|
||||||
|
|
||||||
|
if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
|
||||||
|
{
|
||||||
|
RemovePhysicalPrim(sog.PrimCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1603,7 +1611,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (part != null)
|
if (part != null)
|
||||||
{
|
{
|
||||||
if (part.ParentGroup.Children.Count != 1) // Skip single
|
if (part.ParentGroup.PrimCount != 1) // Skip single
|
||||||
{
|
{
|
||||||
if (part.LinkNum < 2) // Root
|
if (part.LinkNum < 2) // Root
|
||||||
rootParts.Add(part);
|
rootParts.Add(part);
|
||||||
|
@ -1631,8 +1639,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// However, editing linked parts and unlinking may be different
|
// However, editing linked parts and unlinking may be different
|
||||||
//
|
//
|
||||||
SceneObjectGroup group = root.ParentGroup;
|
SceneObjectGroup group = root.ParentGroup;
|
||||||
List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values);
|
|
||||||
int numChildren = group.Children.Count;
|
List<SceneObjectPart> newSet = null;
|
||||||
|
int numChildren = -1;
|
||||||
|
|
||||||
|
lock (group.Children)
|
||||||
|
{
|
||||||
|
newSet = new List<SceneObjectPart>(group.Children.Values);
|
||||||
|
numChildren = group.PrimCount;
|
||||||
|
}
|
||||||
|
|
||||||
// If there are prims left in a link set, but the root is
|
// If there are prims left in a link set, but the root is
|
||||||
// slated for unlink, we need to do this
|
// slated for unlink, we need to do this
|
||||||
|
@ -1711,12 +1726,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
if (ent is SceneObjectGroup)
|
if (ent is SceneObjectGroup)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<UUID, SceneObjectPart> subent in ((SceneObjectGroup)ent).Children)
|
SceneObjectGroup sog = ent as SceneObjectGroup;
|
||||||
|
|
||||||
|
lock (sog.Children)
|
||||||
{
|
{
|
||||||
if (subent.Value.LocalId == localID)
|
foreach (KeyValuePair<UUID, SceneObjectPart> subent in sog.Children)
|
||||||
{
|
{
|
||||||
objid = subent.Key;
|
if (subent.Value.LocalId == localID)
|
||||||
obj = subent.Value;
|
{
|
||||||
|
objid = subent.Key;
|
||||||
|
obj = subent.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1781,7 +1801,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SceneObjectGroup original = GetGroupByPrim(originalPrimID);
|
SceneObjectGroup original = GetGroupByPrim(originalPrimID);
|
||||||
if (original != null)
|
if (original != null)
|
||||||
{
|
{
|
||||||
if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition))
|
if (m_parentScene.Permissions.CanDuplicateObject(
|
||||||
|
original.PrimCount, original.UUID, AgentID, original.AbsolutePosition))
|
||||||
{
|
{
|
||||||
SceneObjectGroup copy = original.Copy(true);
|
SceneObjectGroup copy = original.Copy(true);
|
||||||
copy.AbsolutePosition = copy.AbsolutePosition + offset;
|
copy.AbsolutePosition = copy.AbsolutePosition + offset;
|
||||||
|
|
|
@ -213,7 +213,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int PrimCount
|
public int PrimCount
|
||||||
{
|
{
|
||||||
get { return m_parts.Count; }
|
get { lock (m_parts) { return m_parts.Count; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Quaternion m_rotation = Quaternion.Identity;
|
protected Quaternion m_rotation = Quaternion.Identity;
|
||||||
|
@ -237,6 +237,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// The parts of this scene object group. You must lock this property before using it.
|
/// The parts of this scene object group. You must lock this property before using it.
|
||||||
|
/// If you want to know the number of children, consider using the PrimCount property instead
|
||||||
/// </value>
|
/// </value>
|
||||||
public Dictionary<UUID, SceneObjectPart> Children
|
public Dictionary<UUID, SceneObjectPart> Children
|
||||||
{
|
{
|
||||||
|
@ -298,6 +299,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
|
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RootPart.GetStatusSandbox())
|
if (RootPart.GetStatusSandbox())
|
||||||
{
|
{
|
||||||
if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
|
if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
|
||||||
|
@ -308,6 +310,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_parts)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
@ -558,21 +561,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (m_rootPart.LocalId == 0)
|
if (m_rootPart.LocalId == 0)
|
||||||
m_rootPart.LocalId = m_scene.AllocateLocalId();
|
m_rootPart.LocalId = m_scene.AllocateLocalId();
|
||||||
|
|
||||||
// No need to lock here since the object isn't yet in a scene
|
lock (m_parts)
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
|
||||||
{
|
{
|
||||||
if (Object.ReferenceEquals(part, m_rootPart))
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
continue;
|
if (Object.ReferenceEquals(part, m_rootPart))
|
||||||
}
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (part.LocalId == 0)
|
if (part.LocalId == 0)
|
||||||
{
|
{
|
||||||
part.LocalId = m_scene.AllocateLocalId();
|
part.LocalId = m_scene.AllocateLocalId();
|
||||||
}
|
}
|
||||||
|
|
||||||
part.ParentID = m_rootPart.LocalId;
|
part.ParentID = m_rootPart.LocalId;
|
||||||
//m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
|
//m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyPhysics(m_scene.m_physicalPrim);
|
ApplyPhysics(m_scene.m_physicalPrim);
|
||||||
|
@ -670,7 +675,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
minY = 256f;
|
minY = 256f;
|
||||||
minZ = 8192f;
|
minZ = 8192f;
|
||||||
|
|
||||||
lock(m_parts);
|
lock(m_parts)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
{
|
{
|
||||||
|
@ -995,9 +1000,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_rootPart.AttachedAvatar = agentID;
|
m_rootPart.AttachedAvatar = agentID;
|
||||||
|
|
||||||
//Anakin Lohner bug #3839
|
//Anakin Lohner bug #3839
|
||||||
foreach (SceneObjectPart p in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
p.AttachedAvatar = agentID;
|
foreach (SceneObjectPart p in m_parts.Values)
|
||||||
|
{
|
||||||
|
p.AttachedAvatar = agentID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rootPart.PhysActor != null)
|
if (m_rootPart.PhysActor != null)
|
||||||
|
@ -1065,10 +1073,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
AbsolutePosition = detachedpos;
|
AbsolutePosition = detachedpos;
|
||||||
m_rootPart.AttachedAvatar = UUID.Zero;
|
m_rootPart.AttachedAvatar = UUID.Zero;
|
||||||
|
|
||||||
//Anakin Lohner bug #3839
|
//Anakin Lohner bug #3839
|
||||||
foreach (SceneObjectPart p in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
p.AttachedAvatar = UUID.Zero;
|
foreach (SceneObjectPart p in m_parts.Values)
|
||||||
|
{
|
||||||
|
p.AttachedAvatar = UUID.Zero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rootPart.SetParentLocalId(0);
|
m_rootPart.SetParentLocalId(0);
|
||||||
|
@ -1094,10 +1106,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rootPart.AttachedAvatar = UUID.Zero;
|
m_rootPart.AttachedAvatar = UUID.Zero;
|
||||||
|
|
||||||
//Anakin Lohner bug #3839
|
//Anakin Lohner bug #3839
|
||||||
foreach (SceneObjectPart p in m_parts.Values)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
p.AttachedAvatar = UUID.Zero;
|
foreach (SceneObjectPart p in m_parts.Values)
|
||||||
|
{
|
||||||
|
p.AttachedAvatar = UUID.Zero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rootPart.SetParentLocalId(0);
|
m_rootPart.SetParentLocalId(0);
|
||||||
|
@ -1160,9 +1176,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
part.ParentID = 0;
|
part.ParentID = 0;
|
||||||
part.LinkNum = 0;
|
part.LinkNum = 0;
|
||||||
|
|
||||||
// No locking required since the SOG should not be in the scene yet - one can't change root parts after
|
lock (m_parts)
|
||||||
// the scene object has been attached to the scene
|
m_parts.Add(m_rootPart.UUID, m_rootPart);
|
||||||
m_parts.Add(m_rootPart.UUID, m_rootPart);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1625,7 +1640,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Copy the given part as the root part of this scene object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="part"></param>
|
/// <param name="part"></param>
|
||||||
/// <param name="cAgentID"></param>
|
/// <param name="cAgentID"></param>
|
||||||
|
@ -1882,11 +1897,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="cGroupID"></param>
|
/// <param name="cGroupID"></param>
|
||||||
public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
|
public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
|
||||||
{
|
{
|
||||||
SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
|
SceneObjectPart newPart = null;
|
||||||
newPart.SetParent(this);
|
|
||||||
|
|
||||||
lock (m_parts)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
|
newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
|
||||||
|
newPart.SetParent(this);
|
||||||
m_parts.Add(newPart.UUID, newPart);
|
m_parts.Add(newPart.UUID, newPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1903,14 +1919,15 @@ namespace OpenSim.Region.Framework.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
|
lock (m_parts)
|
||||||
// not accessible by clients), there should be no need to lock
|
|
||||||
List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
|
|
||||||
m_parts.Clear();
|
|
||||||
foreach (SceneObjectPart part in partsList)
|
|
||||||
{
|
{
|
||||||
part.ResetIDs(part.LinkNum); // Don't change link nums
|
List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
|
||||||
m_parts.Add(part.UUID, part);
|
m_parts.Clear();
|
||||||
|
foreach (SceneObjectPart part in partsList)
|
||||||
|
{
|
||||||
|
part.ResetIDs(part.LinkNum); // Don't change link nums
|
||||||
|
m_parts.Add(part.UUID, part);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2136,10 +2153,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public SceneObjectPart GetChildPart(UUID primID)
|
public SceneObjectPart GetChildPart(UUID primID)
|
||||||
{
|
{
|
||||||
SceneObjectPart childPart = null;
|
SceneObjectPart childPart = null;
|
||||||
if (m_parts.ContainsKey(primID))
|
|
||||||
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
childPart = m_parts[primID];
|
if (m_parts.ContainsKey(primID))
|
||||||
|
{
|
||||||
|
childPart = m_parts[primID];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return childPart;
|
return childPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2174,9 +2196,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool HasChildPrim(UUID primID)
|
public bool HasChildPrim(UUID primID)
|
||||||
{
|
{
|
||||||
if (m_parts.ContainsKey(primID))
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
return true;
|
if (m_parts.ContainsKey(primID))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -2370,16 +2393,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
lock (m_parts)
|
lock (m_parts)
|
||||||
{
|
{
|
||||||
m_parts.Remove(linkPart.UUID);
|
m_parts.Remove(linkPart.UUID);
|
||||||
}
|
|
||||||
|
|
||||||
if (m_parts.Count == 1 && RootPart != null) //Single prim is left
|
if (m_parts.Count == 1 && RootPart != null) //Single prim is left
|
||||||
RootPart.LinkNum = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart p in m_parts.Values)
|
|
||||||
{
|
{
|
||||||
if (p.LinkNum > linkPart.LinkNum)
|
RootPart.LinkNum = 0;
|
||||||
p.LinkNum--;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (SceneObjectPart p in m_parts.Values)
|
||||||
|
{
|
||||||
|
if (p.LinkNum > linkPart.LinkNum)
|
||||||
|
p.LinkNum--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2762,9 +2787,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public void UpdatePermissions(UUID AgentID, byte field, uint localID,
|
public void UpdatePermissions(UUID AgentID, byte field, uint localID,
|
||||||
uint mask, byte addRemTF)
|
uint mask, byte addRemTF)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_parts.Values)
|
lock (m_parts)
|
||||||
part.UpdatePermissions(AgentID, field, localID, mask,
|
{
|
||||||
addRemTF);
|
foreach (SceneObjectPart part in m_parts.Values)
|
||||||
|
part.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
|
||||||
|
}
|
||||||
|
|
||||||
HasGroupChanged = true;
|
HasGroupChanged = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -601,7 +601,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
rootPart.Name = item.Name;
|
rootPart.Name = item.Name;
|
||||||
rootPart.Description = item.Description;
|
rootPart.Description = item.Description;
|
||||||
|
|
||||||
List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
|
List<SceneObjectPart> partList = null;
|
||||||
|
|
||||||
|
lock (group.Children)
|
||||||
|
partList = new List<SceneObjectPart>(group.Children.Values);
|
||||||
|
|
||||||
group.SetGroup(m_part.GroupID, null);
|
group.SetGroup(m_part.GroupID, null);
|
||||||
|
|
||||||
|
|
|
@ -121,16 +121,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
continue;
|
continue;
|
||||||
temp = (SceneObjectGroup) currObj;
|
temp = (SceneObjectGroup) currObj;
|
||||||
|
|
||||||
if (m_CMEntityHash.ContainsKey(temp.UUID))
|
lock (temp.Children)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in temp.Children.Values)
|
if (m_CMEntityHash.ContainsKey(temp.UUID))
|
||||||
if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
|
{
|
||||||
|
foreach (SceneObjectPart part in temp.Children.Values)
|
||||||
|
if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
|
||||||
|
missingList.Add(part);
|
||||||
|
}
|
||||||
|
else //Entire group is missing from revision. (and is a new part in region)
|
||||||
|
{
|
||||||
|
foreach (SceneObjectPart part in temp.Children.Values)
|
||||||
missingList.Add(part);
|
missingList.Add(part);
|
||||||
}
|
}
|
||||||
else //Entire group is missing from revision. (and is a new part in region)
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in temp.Children.Values)
|
|
||||||
missingList.Add(part);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return missingList;
|
return missingList;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -167,9 +167,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
|
public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
|
||||||
{
|
{
|
||||||
// Deal with new parts not revisioned that have been deleted.
|
// Deal with new parts not revisioned that have been deleted.
|
||||||
foreach (SceneObjectPart part in group.Children.Values)
|
lock (group.Children)
|
||||||
if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
{
|
||||||
m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID);
|
foreach (SceneObjectPart part in group.Children.Values)
|
||||||
|
if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
||||||
|
m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -207,8 +210,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
{
|
{
|
||||||
temp = SceneObjectSerializer.FromXml2Format(xml);
|
temp = SceneObjectSerializer.FromXml2Format(xml);
|
||||||
temp.SetScene(scene);
|
temp.SetScene(scene);
|
||||||
foreach (SceneObjectPart part in temp.Children.Values)
|
|
||||||
part.RegionHandle = scene.RegionInfo.RegionHandle;
|
lock (temp.Children)
|
||||||
|
{
|
||||||
|
foreach (SceneObjectPart part in temp.Children.Values)
|
||||||
|
part.RegionHandle = scene.RegionInfo.RegionHandle;
|
||||||
|
}
|
||||||
|
|
||||||
ReplacementList.Add(temp.UUID, (EntityBase)temp);
|
ReplacementList.Add(temp.UUID, (EntityBase)temp);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -338,15 +346,20 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
System.Collections.ArrayList auraList = new System.Collections.ArrayList();
|
System.Collections.ArrayList auraList = new System.Collections.ArrayList();
|
||||||
if (group == null)
|
if (group == null)
|
||||||
return null;
|
return null;
|
||||||
foreach (SceneObjectPart part in group.Children.Values)
|
|
||||||
|
lock (group.Children)
|
||||||
{
|
{
|
||||||
if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
foreach (SceneObjectPart part in group.Children.Values)
|
||||||
{
|
{
|
||||||
((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale);
|
if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
||||||
((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
|
{
|
||||||
auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
|
((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale);
|
||||||
|
((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
|
||||||
|
auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return auraList;
|
return auraList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,9 +186,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
|
((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
|
||||||
|
|
||||||
// Deal with new parts not revisioned that have been deleted.
|
// Deal with new parts not revisioned that have been deleted.
|
||||||
foreach (SceneObjectPart part in group.Children.Values)
|
lock (group.Children)
|
||||||
if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
{
|
||||||
((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
|
foreach (SceneObjectPart part in group.Children.Values)
|
||||||
|
if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
||||||
|
((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendMetaEntitiesToNewClient(IClientAPI client)
|
public void SendMetaEntitiesToNewClient(IClientAPI client)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -132,30 +132,33 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
// if group is not contained in scene's list
|
// if group is not contained in scene's list
|
||||||
if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
|
if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
|
lock (m_UnchangedEntity.Children)
|
||||||
{
|
{
|
||||||
// if scene list no longer contains this part, display translucent part and mark with red aura
|
foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
|
||||||
if (!ContainsKey(sceneEntityList, part.UUID))
|
|
||||||
{
|
{
|
||||||
// if already displaying a red aura over part, make sure its red
|
// if scene list no longer contains this part, display translucent part and mark with red aura
|
||||||
if (m_AuraEntities.ContainsKey(part.UUID))
|
if (!ContainsKey(sceneEntityList, part.UUID))
|
||||||
{
|
{
|
||||||
m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
|
// if already displaying a red aura over part, make sure its red
|
||||||
|
if (m_AuraEntities.ContainsKey(part.UUID))
|
||||||
|
{
|
||||||
|
m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
||||||
|
part.GetWorldPosition(),
|
||||||
|
MetaEntity.TRANSLUCENT,
|
||||||
|
new Vector3(254,0,0),
|
||||||
|
part.Scale
|
||||||
|
);
|
||||||
|
m_AuraEntities.Add(part.UUID, auraGroup);
|
||||||
|
}
|
||||||
|
SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
|
||||||
|
SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
|
||||||
}
|
}
|
||||||
else
|
// otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
|
||||||
{
|
|
||||||
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
|
||||||
part.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
new Vector3(254,0,0),
|
|
||||||
part.Scale
|
|
||||||
);
|
|
||||||
m_AuraEntities.Add(part.UUID, auraGroup);
|
|
||||||
}
|
|
||||||
SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
|
|
||||||
SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
|
|
||||||
}
|
}
|
||||||
// otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// a deleted part has no where to point a beam particle system,
|
// a deleted part has no where to point a beam particle system,
|
||||||
|
@ -180,8 +183,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HasChildPrim(UUID uuid)
|
public bool HasChildPrim(UUID uuid)
|
||||||
{
|
{
|
||||||
if (m_UnchangedEntity.Children.ContainsKey(uuid))
|
lock (m_UnchangedEntity.Children)
|
||||||
return true;
|
if (m_UnchangedEntity.Children.ContainsKey(uuid))
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,9 +195,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HasChildPrim(uint localID)
|
public bool HasChildPrim(uint localID)
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
|
lock (m_UnchangedEntity.Children)
|
||||||
if (part.LocalId == localID)
|
{
|
||||||
return true;
|
foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
|
||||||
|
if (part.LocalId == localID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,37 +237,72 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
// Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
|
// Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
|
||||||
// had originally saved.
|
// had originally saved.
|
||||||
// m_Entity will NOT necessarily be the same entity as the user had saved.
|
// m_Entity will NOT necessarily be the same entity as the user had saved.
|
||||||
foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
|
lock (m_UnchangedEntity.Children)
|
||||||
{
|
{
|
||||||
//This is the part that we use to show changes.
|
foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
|
||||||
metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
|
|
||||||
if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
|
|
||||||
{
|
{
|
||||||
sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
|
//This is the part that we use to show changes.
|
||||||
differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
|
metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
|
||||||
if (differences != Diff.NONE)
|
if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
|
||||||
metaEntityPart.Text = "CHANGE: " + differences.ToString();
|
|
||||||
if (differences != 0)
|
|
||||||
{
|
{
|
||||||
// Root Part that has been modified
|
sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
|
||||||
if ((differences&Diff.POSITION) > 0)
|
differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
|
||||||
|
if (differences != Diff.NONE)
|
||||||
|
metaEntityPart.Text = "CHANGE: " + differences.ToString();
|
||||||
|
if (differences != 0)
|
||||||
|
{
|
||||||
|
// Root Part that has been modified
|
||||||
|
if ((differences&Diff.POSITION) > 0)
|
||||||
|
{
|
||||||
|
// If the position of any part has changed, make sure the RootPart of the
|
||||||
|
// meta entity is pointing with a beam particle system
|
||||||
|
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
|
||||||
|
{
|
||||||
|
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
|
||||||
|
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
|
||||||
|
}
|
||||||
|
BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
|
||||||
|
m_UnchangedEntity.RootPart.GetWorldPosition(),
|
||||||
|
MetaEntity.TRANSLUCENT,
|
||||||
|
sceneEntityPart,
|
||||||
|
new Vector3(0,0,254)
|
||||||
|
);
|
||||||
|
m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
||||||
|
{
|
||||||
|
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
||||||
|
m_AuraEntities.Remove(UnchangedPart.UUID);
|
||||||
|
}
|
||||||
|
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
||||||
|
UnchangedPart.GetWorldPosition(),
|
||||||
|
MetaEntity.TRANSLUCENT,
|
||||||
|
new Vector3(0,0,254),
|
||||||
|
UnchangedPart.Scale
|
||||||
|
);
|
||||||
|
m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
|
||||||
|
SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
|
||||||
|
|
||||||
|
DiffersFromSceneGroup = true;
|
||||||
|
}
|
||||||
|
else // no differences between scene part and meta part
|
||||||
{
|
{
|
||||||
// If the position of any part has changed, make sure the RootPart of the
|
|
||||||
// meta entity is pointing with a beam particle system
|
|
||||||
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
|
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
|
||||||
{
|
{
|
||||||
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
|
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
|
||||||
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
|
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
|
||||||
}
|
}
|
||||||
BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
|
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
||||||
m_UnchangedEntity.RootPart.GetWorldPosition(),
|
{
|
||||||
MetaEntity.TRANSLUCENT,
|
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
||||||
sceneEntityPart,
|
m_AuraEntities.Remove(UnchangedPart.UUID);
|
||||||
new Vector3(0,0,254)
|
}
|
||||||
);
|
SetPartTransparency(metaEntityPart, MetaEntity.NONE);
|
||||||
m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
|
||||||
|
{
|
||||||
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
||||||
{
|
{
|
||||||
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
||||||
|
@ -267,7 +311,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
||||||
UnchangedPart.GetWorldPosition(),
|
UnchangedPart.GetWorldPosition(),
|
||||||
MetaEntity.TRANSLUCENT,
|
MetaEntity.TRANSLUCENT,
|
||||||
new Vector3(0,0,254),
|
new Vector3(254,0,0),
|
||||||
UnchangedPart.Scale
|
UnchangedPart.Scale
|
||||||
);
|
);
|
||||||
m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
|
m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
|
||||||
|
@ -275,40 +319,9 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
|
|
||||||
DiffersFromSceneGroup = true;
|
DiffersFromSceneGroup = true;
|
||||||
}
|
}
|
||||||
else // no differences between scene part and meta part
|
|
||||||
{
|
|
||||||
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
|
|
||||||
{
|
|
||||||
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
|
|
||||||
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
|
|
||||||
}
|
|
||||||
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
|
||||||
{
|
|
||||||
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
|
||||||
m_AuraEntities.Remove(UnchangedPart.UUID);
|
|
||||||
}
|
|
||||||
SetPartTransparency(metaEntityPart, MetaEntity.NONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
|
|
||||||
{
|
|
||||||
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
|
||||||
{
|
|
||||||
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
|
||||||
m_AuraEntities.Remove(UnchangedPart.UUID);
|
|
||||||
}
|
|
||||||
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
|
||||||
UnchangedPart.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
new Vector3(254,0,0),
|
|
||||||
UnchangedPart.Scale
|
|
||||||
);
|
|
||||||
m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
|
|
||||||
SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
|
|
||||||
|
|
||||||
DiffersFromSceneGroup = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,15 +150,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
{
|
{
|
||||||
//make new uuids
|
//make new uuids
|
||||||
Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>();
|
Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>();
|
||||||
foreach (SceneObjectPart part in m_Entity.Children.Values)
|
|
||||||
{
|
|
||||||
part.ResetIDs(part.LinkNum);
|
|
||||||
parts.Add(part.UUID, part);
|
|
||||||
}
|
|
||||||
|
|
||||||
//finalize
|
lock (m_Entity.Children)
|
||||||
m_Entity.RootPart.PhysActor = null;
|
{
|
||||||
m_Entity.Children = parts;
|
foreach (SceneObjectPart part in m_Entity.Children.Values)
|
||||||
|
{
|
||||||
|
part.ResetIDs(part.LinkNum);
|
||||||
|
parts.Add(part.UUID, part);
|
||||||
|
}
|
||||||
|
|
||||||
|
//finalize
|
||||||
|
m_Entity.RootPart.PhysActor = null;
|
||||||
|
m_Entity.Children = parts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Protected Methods
|
#endregion Protected Methods
|
||||||
|
@ -173,8 +177,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
//This deletes the group without removing from any databases.
|
//This deletes the group without removing from any databases.
|
||||||
//This is important because we are not IN any database.
|
//This is important because we are not IN any database.
|
||||||
//m_Entity.FakeDeleteGroup();
|
//m_Entity.FakeDeleteGroup();
|
||||||
foreach (SceneObjectPart part in m_Entity.Children.Values)
|
lock (m_Entity.Children)
|
||||||
client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
|
{
|
||||||
|
foreach (SceneObjectPart part in m_Entity.Children.Values)
|
||||||
|
client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -182,12 +189,15 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void HideFromAll()
|
public virtual void HideFromAll()
|
||||||
{
|
{
|
||||||
foreach (SceneObjectPart part in m_Entity.Children.Values)
|
lock (m_Entity.Children)
|
||||||
{
|
{
|
||||||
m_Entity.Scene.ForEachClient(
|
foreach (SceneObjectPart part in m_Entity.Children.Values)
|
||||||
delegate(IClientAPI controller)
|
{
|
||||||
{ controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); }
|
m_Entity.Scene.ForEachClient(
|
||||||
);
|
delegate(IClientAPI controller)
|
||||||
|
{ controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); }
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,14 +185,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
SceneObjectPart my = GetSOP();
|
SceneObjectPart my = GetSOP();
|
||||||
int total = my.ParentGroup.Children.Count;
|
IObject[] rets = null;
|
||||||
|
|
||||||
IObject[] rets = new IObject[total];
|
lock (my.ParentGroup.Children)
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
foreach (KeyValuePair<UUID, SceneObjectPart> pair in my.ParentGroup.Children)
|
|
||||||
{
|
{
|
||||||
rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security);
|
int total = my.ParentGroup.Children.Count;
|
||||||
|
|
||||||
|
rets = new IObject[total];
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
foreach (KeyValuePair<UUID, SceneObjectPart> pair in my.ParentGroup.Children)
|
||||||
|
{
|
||||||
|
rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rets;
|
return rets;
|
||||||
|
|
|
@ -235,7 +235,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
case ScriptBaseClass.LINK_SET:
|
case ScriptBaseClass.LINK_SET:
|
||||||
if (m_host.ParentGroup != null)
|
if (m_host.ParentGroup != null)
|
||||||
return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
|
{
|
||||||
|
lock (m_host.ParentGroup.Children)
|
||||||
|
return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
case ScriptBaseClass.LINK_ROOT:
|
case ScriptBaseClass.LINK_ROOT:
|
||||||
|
@ -250,7 +253,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case ScriptBaseClass.LINK_ALL_OTHERS:
|
case ScriptBaseClass.LINK_ALL_OTHERS:
|
||||||
if (m_host.ParentGroup == null)
|
if (m_host.ParentGroup == null)
|
||||||
return new List<SceneObjectPart>();
|
return new List<SceneObjectPart>();
|
||||||
ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
|
|
||||||
|
lock (m_host.ParentGroup.Children)
|
||||||
|
ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
|
||||||
|
|
||||||
if (ret.Contains(m_host))
|
if (ret.Contains(m_host))
|
||||||
ret.Remove(m_host);
|
ret.Remove(m_host);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -258,7 +264,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case ScriptBaseClass.LINK_ALL_CHILDREN:
|
case ScriptBaseClass.LINK_ALL_CHILDREN:
|
||||||
if (m_host.ParentGroup == null)
|
if (m_host.ParentGroup == null)
|
||||||
return new List<SceneObjectPart>();
|
return new List<SceneObjectPart>();
|
||||||
ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
|
|
||||||
|
lock (m_host.ParentGroup.Children)
|
||||||
|
ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
|
||||||
|
|
||||||
if (ret.Contains(m_host.ParentGroup.RootPart))
|
if (ret.Contains(m_host.ParentGroup.RootPart))
|
||||||
ret.Remove(m_host.ParentGroup.RootPart);
|
ret.Remove(m_host.ParentGroup.RootPart);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1178,12 +1187,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (group == null)
|
if (group == null)
|
||||||
return;
|
return;
|
||||||
bool allow = true;
|
bool allow = true;
|
||||||
foreach (SceneObjectPart part in group.Children.Values)
|
|
||||||
|
lock (group.Children)
|
||||||
{
|
{
|
||||||
if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
|
foreach (SceneObjectPart part in group.Children.Values)
|
||||||
{
|
{
|
||||||
allow = false;
|
if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
|
||||||
break;
|
{
|
||||||
|
allow = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3492,7 +3505,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
if (m_host.ParentGroup.Children.Count > 1)
|
if (m_host.ParentGroup.PrimCount > 1)
|
||||||
{
|
{
|
||||||
return m_host.LinkNum;
|
return m_host.LinkNum;
|
||||||
}
|
}
|
||||||
|
@ -3604,15 +3617,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case ScriptBaseClass.LINK_ALL_OTHERS:
|
case ScriptBaseClass.LINK_ALL_OTHERS:
|
||||||
case ScriptBaseClass.LINK_ALL_CHILDREN:
|
case ScriptBaseClass.LINK_ALL_CHILDREN:
|
||||||
case ScriptBaseClass.LINK_THIS:
|
case ScriptBaseClass.LINK_THIS:
|
||||||
foreach (SceneObjectPart part in parentPrim.Children.Values)
|
lock (parentPrim.Children)
|
||||||
{
|
{
|
||||||
if (part.UUID != m_host.UUID)
|
foreach (SceneObjectPart part in parentPrim.Children.Values)
|
||||||
{
|
{
|
||||||
childPrim = part;
|
if (part.UUID != m_host.UUID)
|
||||||
break;
|
{
|
||||||
|
childPrim = part;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
childPrim = parentPrim.GetLinkNumPart(linknum);
|
childPrim = parentPrim.GetLinkNumPart(linknum);
|
||||||
if (childPrim.UUID == m_host.UUID)
|
if (childPrim.UUID == m_host.UUID)
|
||||||
|
@ -3623,27 +3639,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (linknum == ScriptBaseClass.LINK_ROOT)
|
if (linknum == ScriptBaseClass.LINK_ROOT)
|
||||||
{
|
{
|
||||||
// Restructuring Multiple Prims.
|
// Restructuring Multiple Prims.
|
||||||
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
|
lock (parentPrim.Children)
|
||||||
parts.Remove(parentPrim.RootPart);
|
|
||||||
foreach (SceneObjectPart part in parts)
|
|
||||||
{
|
{
|
||||||
parentPrim.DelinkFromGroup(part.LocalId, true);
|
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
|
||||||
}
|
parts.Remove(parentPrim.RootPart);
|
||||||
parentPrim.HasGroupChanged = true;
|
|
||||||
parentPrim.ScheduleGroupForFullUpdate();
|
|
||||||
parentPrim.TriggerScriptChangedEvent(Changed.LINK);
|
|
||||||
|
|
||||||
if (parts.Count > 0)
|
|
||||||
{
|
|
||||||
SceneObjectPart newRoot = parts[0];
|
|
||||||
parts.Remove(newRoot);
|
|
||||||
foreach (SceneObjectPart part in parts)
|
foreach (SceneObjectPart part in parts)
|
||||||
{
|
{
|
||||||
part.UpdateFlag = 0;
|
parentPrim.DelinkFromGroup(part.LocalId, true);
|
||||||
newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
|
}
|
||||||
|
parentPrim.HasGroupChanged = true;
|
||||||
|
parentPrim.ScheduleGroupForFullUpdate();
|
||||||
|
parentPrim.TriggerScriptChangedEvent(Changed.LINK);
|
||||||
|
|
||||||
|
if (parts.Count > 0)
|
||||||
|
{
|
||||||
|
SceneObjectPart newRoot = parts[0];
|
||||||
|
parts.Remove(newRoot);
|
||||||
|
foreach (SceneObjectPart part in parts)
|
||||||
|
{
|
||||||
|
part.UpdateFlag = 0;
|
||||||
|
newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
|
||||||
|
}
|
||||||
|
newRoot.ParentGroup.HasGroupChanged = true;
|
||||||
|
newRoot.ParentGroup.ScheduleGroupForFullUpdate();
|
||||||
}
|
}
|
||||||
newRoot.ParentGroup.HasGroupChanged = true;
|
|
||||||
newRoot.ParentGroup.ScheduleGroupForFullUpdate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3665,16 +3684,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (parentPrim.RootPart.AttachmentPoint != 0)
|
if (parentPrim.RootPart.AttachmentPoint != 0)
|
||||||
return; // Fail silently if attached
|
return; // Fail silently if attached
|
||||||
|
|
||||||
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
|
lock (parentPrim.Children)
|
||||||
parts.Remove(parentPrim.RootPart);
|
|
||||||
|
|
||||||
foreach (SceneObjectPart part in parts)
|
|
||||||
{
|
{
|
||||||
parentPrim.DelinkFromGroup(part.LocalId, true);
|
List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
|
||||||
parentPrim.TriggerScriptChangedEvent(Changed.LINK);
|
parts.Remove(parentPrim.RootPart);
|
||||||
|
|
||||||
|
foreach (SceneObjectPart part in parts)
|
||||||
|
{
|
||||||
|
parentPrim.DelinkFromGroup(part.LocalId, true);
|
||||||
|
parentPrim.TriggerScriptChangedEvent(Changed.LINK);
|
||||||
|
}
|
||||||
|
parentPrim.HasGroupChanged = true;
|
||||||
|
parentPrim.ScheduleGroupForFullUpdate();
|
||||||
}
|
}
|
||||||
parentPrim.HasGroupChanged = true;
|
|
||||||
parentPrim.ScheduleGroupForFullUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_String llGetLinkKey(int linknum)
|
public LSL_String llGetLinkKey(int linknum)
|
||||||
|
@ -4200,7 +4222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
partItemID = item.ItemID;
|
partItemID = item.ItemID;
|
||||||
int linkNumber = m_host.LinkNum;
|
int linkNumber = m_host.LinkNum;
|
||||||
if (m_host.ParentGroup.Children.Count == 1)
|
if (m_host.ParentGroup.PrimCount == 1)
|
||||||
linkNumber = 0;
|
linkNumber = 0;
|
||||||
|
|
||||||
object[] resobj = new object[]
|
object[] resobj = new object[]
|
||||||
|
|
|
@ -209,12 +209,15 @@ namespace OpenSim.Region.ScriptEngine.Shared
|
||||||
else
|
else
|
||||||
Type = 0x02; // Passive
|
Type = 0x02; // Passive
|
||||||
|
|
||||||
foreach (SceneObjectPart p in part.ParentGroup.Children.Values)
|
lock (part.ParentGroup.Children)
|
||||||
{
|
{
|
||||||
if (p.Inventory.ContainsScripts())
|
foreach (SceneObjectPart p in part.ParentGroup.Children.Values)
|
||||||
{
|
{
|
||||||
Type |= 0x08; // Scripted
|
if (p.Inventory.ContainsScripts())
|
||||||
break;
|
{
|
||||||
|
Type |= 0x08; // Scripted
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue