aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs89
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs150
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs63
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs154
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs130
10 files changed, 554 insertions, 85 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 3ef1e29..cf68ff4 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -38,8 +38,9 @@ namespace OpenSim.Region.Framework.Scenes
38{ 38{
39 public partial class Scene 39 public partial class Scene
40 { 40 {
41
41 protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, 42 protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
42 UUID fromID, bool fromAgent, bool broadcast) 43 UUID fromID, UUID targetID, bool fromAgent, bool broadcast)
43 { 44 {
44 OSChatMessage args = new OSChatMessage(); 45 OSChatMessage args = new OSChatMessage();
45 46
@@ -63,14 +64,20 @@ namespace OpenSim.Region.Framework.Scenes
63 } 64 }
64 65
65 args.From = fromName; 66 args.From = fromName;
66 //args. 67 args.TargetUUID = targetID;
67 68
68 if (broadcast) 69 if (broadcast)
69 EventManager.TriggerOnChatBroadcast(this, args); 70 EventManager.TriggerOnChatBroadcast(this, args);
70 else 71 else
71 EventManager.TriggerOnChatFromWorld(this, args); 72 EventManager.TriggerOnChatFromWorld(this, args);
72 } 73 }
73 74
75 protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
76 UUID fromID, bool fromAgent, bool broadcast)
77 {
78 SimChat(message, type, channel, fromPos, fromName, fromID, UUID.Zero, fromAgent, broadcast);
79 }
80
74 /// <summary> 81 /// <summary>
75 /// 82 ///
76 /// </summary> 83 /// </summary>
@@ -108,6 +115,19 @@ namespace OpenSim.Region.Framework.Scenes
108 { 115 {
109 SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true); 116 SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true);
110 } 117 }
118 /// <summary>
119 ///
120 /// </summary>
121 /// <param name="message"></param>
122 /// <param name="type"></param>
123 /// <param name="fromPos"></param>
124 /// <param name="fromName"></param>
125 /// <param name="fromAgentID"></param>
126 /// <param name="targetID"></param>
127 public void SimChatToAgent(UUID targetID, byte[] message, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent)
128 {
129 SimChat(message, ChatTypeEnum.Say, 0, fromPos, fromName, fromID, targetID, fromAgent, false);
130 }
111 131
112 /// <summary> 132 /// <summary>
113 /// Invoked when the client requests a prim. 133 /// Invoked when the client requests a prim.
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 3e08128..85b1242 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -833,13 +833,11 @@ namespace OpenSim.Region.Framework.Scenes
833 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; 833 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
834 } 834 }
835 835
836 /// <summary>
837 /// Mock constructor for scene group persistency unit tests.
838 /// SceneObjectGroup RegionId property is delegated to Scene.
839 /// </summary>
840 /// <param name="regInfo"></param>
841 public Scene(RegionInfo regInfo) 836 public Scene(RegionInfo regInfo)
842 { 837 {
838 PhysicalPrims = true;
839 CollidablePrims = true;
840
843 BordersLocked = true; 841 BordersLocked = true;
844 Border northBorder = new Border(); 842 Border northBorder = new Border();
845 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<--- 843 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
@@ -866,8 +864,6 @@ namespace OpenSim.Region.Framework.Scenes
866 m_eventManager = new EventManager(); 864 m_eventManager = new EventManager();
867 865
868 m_permissions = new ScenePermissions(this); 866 m_permissions = new ScenePermissions(this);
869
870// m_lastUpdate = Util.EnvironmentTickCount();
871 } 867 }
872 868
873 #endregion 869 #endregion
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index b806d91..77e808e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -156,7 +156,9 @@ namespace OpenSim.Region.Framework.Scenes
156 // that the region position is cached or performance will degrade 156 // that the region position is cached or performance will degrade
157 Utils.LongToUInts(regionHandle, out x, out y); 157 Utils.LongToUInts(regionHandle, out x, out y);
158 GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); 158 GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
159// bool v = true; 159 if (dest == null)
160 continue;
161
160 if (!simulatorList.Contains(dest.ServerURI)) 162 if (!simulatorList.Contains(dest.ServerURI))
161 { 163 {
162 // we havent seen this simulator before, add it to the list 164 // we havent seen this simulator before, add it to the list
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index b7dc335..f6f6a1a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -101,6 +101,9 @@ namespace OpenSim.Region.Framework.Scenes
101 /// </summary> 101 /// </summary>
102 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>(); 102 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>();
103 103
104 /// <summary>
105 /// Lock to prevent object group update, linking and delinking operations from running concurrently.
106 /// </summary>
104 private Object m_updateLock = new Object(); 107 private Object m_updateLock = new Object();
105 108
106 #endregion 109 #endregion
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 0100ab3..c47db97 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2629,6 +2629,10 @@ namespace OpenSim.Region.Framework.Scenes
2629 /// <summary> 2629 /// <summary>
2630 /// Link the prims in a given group to this group 2630 /// Link the prims in a given group to this group
2631 /// </summary> 2631 /// </summary>
2632 /// <remarks>
2633 /// Do not call this method directly - use Scene.LinkObjects() instead to avoid races between threads.
2634 /// FIXME: There are places where scripts call these methods directly without locking. This is a potential race condition.
2635 /// </remarks>
2632 /// <param name="objectGroup">The group of prims which should be linked to this group</param> 2636 /// <param name="objectGroup">The group of prims which should be linked to this group</param>
2633 public void LinkToGroup(SceneObjectGroup objectGroup) 2637 public void LinkToGroup(SceneObjectGroup objectGroup)
2634 { 2638 {
@@ -2708,6 +2712,7 @@ namespace OpenSim.Region.Framework.Scenes
2708 } 2712 }
2709 2713
2710 linkPart.LinkNum = linkNum++; 2714 linkPart.LinkNum = linkNum++;
2715 linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false);
2711 2716
2712 SceneObjectPart[] ogParts = objectGroup.Parts; 2717 SceneObjectPart[] ogParts = objectGroup.Parts;
2713 Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b) 2718 Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b)
@@ -2759,6 +2764,11 @@ namespace OpenSim.Region.Framework.Scenes
2759 /// Delink the given prim from this group. The delinked prim is established as 2764 /// Delink the given prim from this group. The delinked prim is established as
2760 /// an independent SceneObjectGroup. 2765 /// an independent SceneObjectGroup.
2761 /// </summary> 2766 /// </summary>
2767 /// <remarks>
2768 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2769 /// condition. But currently there is no
2770 /// alternative method that does take a lonk to delink a single prim.
2771 /// </remarks>
2762 /// <param name="partID"></param> 2772 /// <param name="partID"></param>
2763 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> 2773 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
2764 public SceneObjectGroup DelinkFromGroup(uint partID) 2774 public SceneObjectGroup DelinkFromGroup(uint partID)
@@ -2770,6 +2780,11 @@ namespace OpenSim.Region.Framework.Scenes
2770 /// Delink the given prim from this group. The delinked prim is established as 2780 /// Delink the given prim from this group. The delinked prim is established as
2771 /// an independent SceneObjectGroup. 2781 /// an independent SceneObjectGroup.
2772 /// </summary> 2782 /// </summary>
2783 /// <remarks>
2784 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2785 /// condition. But currently there is no
2786 /// alternative method that does take a lonk to delink a single prim.
2787 /// </remarks>
2773 /// <param name="partID"></param> 2788 /// <param name="partID"></param>
2774 /// <param name="sendEvents"></param> 2789 /// <param name="sendEvents"></param>
2775 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> 2790 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
@@ -2795,6 +2810,11 @@ namespace OpenSim.Region.Framework.Scenes
2795 /// Delink the given prim from this group. The delinked prim is established as 2810 /// Delink the given prim from this group. The delinked prim is established as
2796 /// an independent SceneObjectGroup. 2811 /// an independent SceneObjectGroup.
2797 /// </summary> 2812 /// </summary>
2813 /// <remarks>
2814 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2815 /// condition. But currently there is no
2816 /// alternative method that does take a lonk to delink a single prim.
2817 /// </remarks>
2798 /// <param name="partID"></param> 2818 /// <param name="partID"></param>
2799 /// <param name="sendEvents"></param> 2819 /// <param name="sendEvents"></param>
2800 /// <returns>The object group of the newly delinked prim.</returns> 2820 /// <returns>The object group of the newly delinked prim.</returns>
@@ -2928,6 +2948,8 @@ namespace OpenSim.Region.Framework.Scenes
2928 oldRot = part.RotationOffset; 2948 oldRot = part.RotationOffset;
2929 Quaternion newRot = Quaternion.Inverse(parentRot) * worldRot; 2949 Quaternion newRot = Quaternion.Inverse(parentRot) * worldRot;
2930 part.RotationOffset = newRot; 2950 part.RotationOffset = newRot;
2951
2952 part.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false);
2931 } 2953 }
2932 2954
2933 /// <summary> 2955 /// <summary>
@@ -4081,7 +4103,72 @@ namespace OpenSim.Region.Framework.Scenes
4081 for (int i = 0; i < parts.Length; i++) 4103 for (int i = 0; i < parts.Length; i++)
4082 parts[i].TriggerScriptChangedEvent(val); 4104 parts[i].TriggerScriptChangedEvent(val);
4083 } 4105 }
4084 4106
4107 /// <summary>
4108 /// Returns a count of the number of scripts in this groups parts.
4109 /// </summary>
4110 public int ScriptCount()
4111 {
4112 int count = 0;
4113 SceneObjectPart[] parts = m_parts.GetArray();
4114 for (int i = 0; i < parts.Length; i++)
4115 count += parts[i].Inventory.ScriptCount();
4116
4117 return count;
4118 }
4119
4120 /// <summary>
4121 /// A float the value is a representative execution time in milliseconds of all scripts in the link set.
4122 /// </summary>
4123 public float ScriptExecutionTime()
4124 {
4125 IScriptModule[] engines = Scene.RequestModuleInterfaces<IScriptModule>();
4126
4127 if (engines.Length == 0) // No engine at all
4128 return 0.0f;
4129
4130 float time = 0.0f;
4131
4132 // get all the scripts in all parts
4133 SceneObjectPart[] parts = m_parts.GetArray();
4134 List<TaskInventoryItem> scripts = new List<TaskInventoryItem>();
4135 for (int i = 0; i < parts.Length; i++)
4136 {
4137 scripts.AddRange(parts[i].Inventory.GetInventoryItems(InventoryType.LSL));
4138 }
4139 // extract the UUIDs
4140 List<UUID> ids = new List<UUID>(scripts.Count);
4141 foreach (TaskInventoryItem script in scripts)
4142 {
4143 if (!ids.Contains(script.ItemID))
4144 {
4145 ids.Add(script.ItemID);
4146 }
4147 }
4148 // Offer the list of script UUIDs to each engine found and accumulate the time
4149 foreach (IScriptModule e in engines)
4150 {
4151 if (e != null)
4152 {
4153 time += e.GetScriptExecutionTime(ids);
4154 }
4155 }
4156 return time;
4157 }
4158
4159 /// <summary>
4160 /// Returns a count of the number of running scripts in this groups parts.
4161 /// </summary>
4162 public int RunningScriptCount()
4163 {
4164 int count = 0;
4165 SceneObjectPart[] parts = m_parts.GetArray();
4166 for (int i = 0; i < parts.Length; i++)
4167 count += parts[i].Inventory.RunningScriptCount();
4168
4169 return count;
4170 }
4171
4085 public override string ToString() 4172 public override string ToString()
4086 { 4173 {
4087 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); 4174 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index c9659cb..37b5554 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2088,6 +2088,9 @@ namespace OpenSim.Region.Framework.Scenes
2088 /// <param name="isNew"></param> 2088 /// <param name="isNew"></param>
2089 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) 2089 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
2090 { 2090 {
2091 if (ParentGroup.Scene == null)
2092 return;
2093
2091 if (!ParentGroup.Scene.PhysicalPrims && UsePhysics) 2094 if (!ParentGroup.Scene.PhysicalPrims && UsePhysics)
2092 return; 2095 return;
2093 2096
@@ -4545,7 +4548,7 @@ namespace OpenSim.Region.Framework.Scenes
4545 // For now, we use the NINJA naming scheme for identifying joints. 4548 // For now, we use the NINJA naming scheme for identifying joints.
4546 // In the future, we can support other joint specification schemes such as a 4549 // In the future, we can support other joint specification schemes such as a
4547 // custom checkbox in the viewer GUI. 4550 // custom checkbox in the viewer GUI.
4548 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4551 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4549 { 4552 {
4550 string hingeString = "hingejoint"; 4553 string hingeString = "hingejoint";
4551 return (Name.Length >= hingeString.Length && Name.Substring(0, hingeString.Length) == hingeString); 4554 return (Name.Length >= hingeString.Length && Name.Substring(0, hingeString.Length) == hingeString);
@@ -4561,7 +4564,7 @@ namespace OpenSim.Region.Framework.Scenes
4561 // For now, we use the NINJA naming scheme for identifying joints. 4564 // For now, we use the NINJA naming scheme for identifying joints.
4562 // In the future, we can support other joint specification schemes such as a 4565 // In the future, we can support other joint specification schemes such as a
4563 // custom checkbox in the viewer GUI. 4566 // custom checkbox in the viewer GUI.
4564 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4567 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4565 { 4568 {
4566 string ballString = "balljoint"; 4569 string ballString = "balljoint";
4567 return (Name.Length >= ballString.Length && Name.Substring(0, ballString.Length) == ballString); 4570 return (Name.Length >= ballString.Length && Name.Substring(0, ballString.Length) == ballString);
@@ -4577,7 +4580,7 @@ namespace OpenSim.Region.Framework.Scenes
4577 // For now, we use the NINJA naming scheme for identifying joints. 4580 // For now, we use the NINJA naming scheme for identifying joints.
4578 // In the future, we can support other joint specification schemes such as a 4581 // In the future, we can support other joint specification schemes such as a
4579 // custom checkbox in the viewer GUI. 4582 // custom checkbox in the viewer GUI.
4580 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4583 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4581 { 4584 {
4582 return IsHingeJoint() || IsBallJoint(); 4585 return IsHingeJoint() || IsBallJoint();
4583 } 4586 }
@@ -4696,7 +4699,6 @@ namespace OpenSim.Region.Framework.Scenes
4696 } 4699 }
4697 } 4700 }
4698 } 4701 }
4699
4700 else // it already has a physical representation 4702 else // it already has a physical representation
4701 { 4703 {
4702 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. 4704 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index a2649ee..36cb09a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -267,14 +267,9 @@ namespace OpenSim.Region.Framework.Scenes
267 /// </summary> 267 /// </summary>
268 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 268 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
269 { 269 {
270 Items.LockItemsForRead(true); 270 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
271 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 271 foreach (TaskInventoryItem item in scripts)
272 Items.LockItemsForRead(false); 272 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
273 foreach (TaskInventoryItem item in items)
274 {
275 if ((int)InventoryType.LSL == item.InvType)
276 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
277 }
278 } 273 }
279 274
280 public ArrayList GetScriptErrors(UUID itemID) 275 public ArrayList GetScriptErrors(UUID itemID)
@@ -305,17 +300,11 @@ namespace OpenSim.Region.Framework.Scenes
305 /// </param> 300 /// </param>
306 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 301 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
307 { 302 {
308 Items.LockItemsForRead(true); 303 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
309 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 304 foreach (TaskInventoryItem item in scripts)
310 Items.LockItemsForRead(false);
311
312 foreach (TaskInventoryItem item in items)
313 { 305 {
314 if ((int)InventoryType.LSL == item.InvType) 306 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
315 { 307 m_part.RemoveScriptEvents(item.ItemID);
316 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
317 m_part.RemoveScriptEvents(item.ItemID);
318 }
319 } 308 }
320 } 309 }
321 310
@@ -1280,9 +1269,57 @@ namespace OpenSim.Region.Framework.Scenes
1280 return true; 1269 return true;
1281 } 1270 }
1282 } 1271 }
1272
1283 return false; 1273 return false;
1284 } 1274 }
1285 1275
1276 /// <summary>
1277 /// Returns the count of scripts in this parts inventory.
1278 /// </summary>
1279 /// <returns></returns>
1280 public int ScriptCount()
1281 {
1282 int count = 0;
1283 Items.LockItemsForRead(true);
1284 foreach (TaskInventoryItem item in m_items.Values)
1285 {
1286 if (item.InvType == (int)InventoryType.LSL)
1287 {
1288 count++;
1289 }
1290 }
1291 Items.LockItemsForRead(false);
1292 return count;
1293 }
1294 /// <summary>
1295 /// Returns the count of running scripts in this parts inventory.
1296 /// </summary>
1297 /// <returns></returns>
1298 public int RunningScriptCount()
1299 {
1300 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
1301 if (engines.Length == 0)
1302 return 0;
1303
1304 int count = 0;
1305 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
1306
1307 foreach (TaskInventoryItem item in scripts)
1308 {
1309 foreach (IScriptModule engine in engines)
1310 {
1311 if (engine != null)
1312 {
1313 if (engine.GetScriptState(item.ItemID))
1314 {
1315 count++;
1316 }
1317 }
1318 }
1319 }
1320 return count;
1321 }
1322
1286 public List<UUID> GetInventoryList() 1323 public List<UUID> GetInventoryList()
1287 { 1324 {
1288 List<UUID> ret = new List<UUID>(); 1325 List<UUID> ret = new List<UUID>();
@@ -1297,22 +1334,24 @@ namespace OpenSim.Region.Framework.Scenes
1297 { 1334 {
1298 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1335 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1299 1336
1300 lock (m_items) 1337 Items.LockItemsForRead(true);
1301 ret = new List<TaskInventoryItem>(m_items.Values); 1338 ret = new List<TaskInventoryItem>(m_items.Values);
1339 Items.LockItemsForRead(false);
1302 1340
1303 return ret; 1341 return ret;
1304 } 1342 }
1305 1343
1306 public List<TaskInventoryItem> GetInventoryScripts() 1344 public List<TaskInventoryItem> GetInventoryItems(InventoryType type)
1307 { 1345 {
1308 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1346 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1309 1347
1310 lock (m_items) 1348 Items.LockItemsForRead(true);
1311 { 1349
1312 foreach (TaskInventoryItem item in m_items.Values) 1350 foreach (TaskInventoryItem item in m_items.Values)
1313 if (item.InvType == (int)InventoryType.LSL) 1351 if (item.InvType == (int)type)
1314 ret.Add(item); 1352 ret.Add(item);
1315 } 1353
1354 Items.LockItemsForRead(false);
1316 1355
1317 return ret; 1356 return ret;
1318 } 1357 }
@@ -1334,35 +1373,32 @@ namespace OpenSim.Region.Framework.Scenes
1334 if (engines.Length == 0) // No engine at all 1373 if (engines.Length == 0) // No engine at all
1335 return ret; 1374 return ret;
1336 1375
1337 Items.LockItemsForRead(true); 1376 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
1338 foreach (TaskInventoryItem item in m_items.Values) 1377
1378 foreach (TaskInventoryItem item in scripts)
1339 { 1379 {
1340 if (item.InvType == (int)InventoryType.LSL) 1380 foreach (IScriptModule e in engines)
1341 { 1381 {
1342 foreach (IScriptModule e in engines) 1382 if (e != null)
1343 { 1383 {
1344 if (e != null) 1384 string n = e.GetXMLState(item.ItemID);
1385 if (n != String.Empty)
1345 { 1386 {
1346 string n = e.GetXMLState(item.ItemID); 1387 if (oldIDs)
1347 if (n != String.Empty) 1388 {
1389 if (!ret.ContainsKey(item.OldItemID))
1390 ret[item.OldItemID] = n;
1391 }
1392 else
1348 { 1393 {
1349 if (oldIDs) 1394 if (!ret.ContainsKey(item.ItemID))
1350 { 1395 ret[item.ItemID] = n;
1351 if (!ret.ContainsKey(item.OldItemID))
1352 ret[item.OldItemID] = n;
1353 }
1354 else
1355 {
1356 if (!ret.ContainsKey(item.ItemID))
1357 ret[item.ItemID] = n;
1358 }
1359 break;
1360 } 1396 }
1397 break;
1361 } 1398 }
1362 } 1399 }
1363 } 1400 }
1364 } 1401 }
1365 Items.LockItemsForRead(false);
1366 return ret; 1402 return ret;
1367 } 1403 }
1368 1404
@@ -1372,27 +1408,21 @@ namespace OpenSim.Region.Framework.Scenes
1372 if (engines.Length == 0) 1408 if (engines.Length == 0)
1373 return; 1409 return;
1374 1410
1411 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
1375 1412
1376 Items.LockItemsForRead(true); 1413 foreach (TaskInventoryItem item in scripts)
1377
1378 foreach (TaskInventoryItem item in m_items.Values)
1379 { 1414 {
1380 if (item.InvType == (int)InventoryType.LSL) 1415 foreach (IScriptModule engine in engines)
1381 { 1416 {
1382 foreach (IScriptModule engine in engines) 1417 if (engine != null)
1383 { 1418 {
1384 if (engine != null) 1419 if (item.OwnerChanged)
1385 { 1420 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1386 if (item.OwnerChanged) 1421 item.OwnerChanged = false;
1387 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1422 engine.ResumeScript(item.ItemID);
1388 item.OwnerChanged = false;
1389 engine.ResumeScript(item.ItemID);
1390 }
1391 } 1423 }
1392 } 1424 }
1393 } 1425 }
1394
1395 Items.LockItemsForRead(false);
1396 } 1426 }
1397 } 1427 }
1398} 1428}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 108b044..f3f03f5 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -3545,6 +3545,63 @@ namespace OpenSim.Region.Framework.Scenes
3545 return m_attachments.Count > 0; 3545 return m_attachments.Count > 0;
3546 } 3546 }
3547 3547
3548 /// <summary>
3549 /// Returns the total count of scripts in all parts inventories.
3550 /// </summary>
3551 public int ScriptCount()
3552 {
3553 int count = 0;
3554 lock (m_attachments)
3555 {
3556 foreach (SceneObjectGroup gobj in m_attachments)
3557 {
3558 if (gobj != null)
3559 {
3560 count += gobj.ScriptCount();
3561 }
3562 }
3563 }
3564 return count;
3565 }
3566
3567 /// <summary>
3568 /// A float the value is a representative execution time in milliseconds of all scripts in all attachments.
3569 /// </summary>
3570 public float ScriptExecutionTime()
3571 {
3572 float time = 0.0f;
3573 lock (m_attachments)
3574 {
3575 foreach (SceneObjectGroup gobj in m_attachments)
3576 {
3577 if (gobj != null)
3578 {
3579 time += gobj.ScriptExecutionTime();
3580 }
3581 }
3582 }
3583 return time;
3584 }
3585
3586 /// <summary>
3587 /// Returns the total count of running scripts in all parts.
3588 /// </summary>
3589 public int RunningScriptCount()
3590 {
3591 int count = 0;
3592 lock (m_attachments)
3593 {
3594 foreach (SceneObjectGroup gobj in m_attachments)
3595 {
3596 if (gobj != null)
3597 {
3598 count += gobj.RunningScriptCount();
3599 }
3600 }
3601 }
3602 return count;
3603 }
3604
3548 public bool HasScriptedAttachments() 3605 public bool HasScriptedAttachments()
3549 { 3606 {
3550 lock (m_attachments) 3607 lock (m_attachments)
@@ -3902,7 +3959,7 @@ namespace OpenSim.Region.Framework.Scenes
3902 land.LandData.UserLocation != Vector3.Zero && 3959 land.LandData.UserLocation != Vector3.Zero &&
3903 land.LandData.OwnerID != m_uuid && 3960 land.LandData.OwnerID != m_uuid &&
3904 (!m_scene.Permissions.IsGod(m_uuid)) && 3961 (!m_scene.Permissions.IsGod(m_uuid)) &&
3905 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) 3962 (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)))
3906 { 3963 {
3907 float curr = Vector3.Distance(AbsolutePosition, pos); 3964 float curr = Vector3.Distance(AbsolutePosition, pos);
3908 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) 3965 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
@@ -3922,7 +3979,7 @@ namespace OpenSim.Region.Framework.Scenes
3922 { 3979 {
3923 if (GodLevel < 200 && 3980 if (GodLevel < 200 &&
3924 ((!m_scene.Permissions.IsGod(m_uuid) && 3981 ((!m_scene.Permissions.IsGod(m_uuid) &&
3925 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 3982 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
3926 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 3983 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
3927 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 3984 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
3928 { 3985 {
@@ -3996,7 +4053,7 @@ namespace OpenSim.Region.Framework.Scenes
3996 GodLevel < 200 && 4053 GodLevel < 200 &&
3997 ((land.LandData.OwnerID != m_uuid && 4054 ((land.LandData.OwnerID != m_uuid &&
3998 !m_scene.Permissions.IsGod(m_uuid) && 4055 !m_scene.Permissions.IsGod(m_uuid) &&
3999 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4056 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4000 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4057 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4001 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4058 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4002 { 4059 {
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
new file mode 100644
index 0000000..9fea3c6
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
@@ -0,0 +1,154 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Threading;
31using NUnit.Framework;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38
39namespace OpenSim.Region.Framework.Scenes.Tests
40{
41 /// <summary>
42 /// Spatial scene object tests (will eventually cover root and child part position, rotation properties, etc.)
43 /// </summary>
44 [TestFixture]
45 public class SceneObjectSpatialTests
46 {
47 TestScene m_scene;
48 UUID m_ownerId = TestHelpers.ParseTail(0x1);
49
50 [SetUp]
51 public void SetUp()
52 {
53 m_scene = SceneHelpers.SetupScene();
54 }
55
56 [Test]
57 public void TestGetSceneObjectGroupPosition()
58 {
59 TestHelpers.InMethod();
60
61 Vector3 position = new Vector3(10, 20, 30);
62
63 SceneObjectGroup so
64 = SceneHelpers.CreateSceneObject(1, m_ownerId, "obj1", 0x10);
65 so.AbsolutePosition = position;
66 m_scene.AddNewSceneObject(so, false);
67
68 Assert.That(so.AbsolutePosition, Is.EqualTo(position));
69 }
70
71 [Test]
72 public void TestGetRootPartPosition()
73 {
74 TestHelpers.InMethod();
75
76 Vector3 partPosition = new Vector3(10, 20, 30);
77
78 SceneObjectGroup so
79 = SceneHelpers.CreateSceneObject(1, m_ownerId, "obj1", 0x10);
80 so.AbsolutePosition = partPosition;
81 m_scene.AddNewSceneObject(so, false);
82
83 Assert.That(so.RootPart.AbsolutePosition, Is.EqualTo(partPosition));
84 Assert.That(so.RootPart.GroupPosition, Is.EqualTo(partPosition));
85 Assert.That(so.RootPart.GetWorldPosition(), Is.EqualTo(partPosition));
86 Assert.That(so.RootPart.RelativePosition, Is.EqualTo(partPosition));
87 Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero));
88 }
89
90 [Test]
91 public void TestGetChildPartPosition()
92 {
93 TestHelpers.InMethod();
94
95 Vector3 rootPartPosition = new Vector3(10, 20, 30);
96 Vector3 childOffsetPosition = new Vector3(2, 3, 4);
97
98 SceneObjectGroup so
99 = SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10);
100 so.AbsolutePosition = rootPartPosition;
101 so.Parts[1].OffsetPosition = childOffsetPosition;
102
103 m_scene.AddNewSceneObject(so, false);
104
105 // Calculate child absolute position.
106 Vector3 childPosition = new Vector3(rootPartPosition + childOffsetPosition);
107
108 SceneObjectPart childPart = so.Parts[1];
109 Assert.That(childPart.AbsolutePosition, Is.EqualTo(childPosition));
110 Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition));
111 Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition));
112 Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition));
113 Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition));
114 }
115
116 [Test]
117 public void TestGetChildPartPositionAfterObjectRotation()
118 {
119 TestHelpers.InMethod();
120
121 Vector3 rootPartPosition = new Vector3(10, 20, 30);
122 Vector3 childOffsetPosition = new Vector3(2, 3, 4);
123
124 SceneObjectGroup so
125 = SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10);
126 so.AbsolutePosition = rootPartPosition;
127 so.Parts[1].OffsetPosition = childOffsetPosition;
128
129 m_scene.AddNewSceneObject(so, false);
130
131 so.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 0, -90 * Utils.DEG_TO_RAD));
132
133 // Calculate child absolute position.
134 Vector3 rotatedChildOffsetPosition
135 = new Vector3(childOffsetPosition.Y, -childOffsetPosition.X, childOffsetPosition.Z);
136
137 Vector3 childPosition = new Vector3(rootPartPosition + rotatedChildOffsetPosition);
138
139 SceneObjectPart childPart = so.Parts[1];
140
141 // FIXME: Should be childPosition after rotation?
142 Assert.That(childPart.AbsolutePosition, Is.EqualTo(rootPartPosition + childOffsetPosition));
143
144 Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition));
145 Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition));
146
147 // Relative to root part as (0, 0, 0)
148 Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition));
149
150 // Relative to root part as (0, 0, 0)
151 Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition));
152 }
153 }
154} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
index 2a342d5..360566d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using NUnit.Framework; 31using NUnit.Framework;
31using OpenMetaverse; 32using OpenMetaverse;
@@ -43,24 +44,141 @@ namespace OpenSim.Region.Framework.Scenes.Tests
43 [TestFixture] 44 [TestFixture]
44 public class SceneObjectStatusTests 45 public class SceneObjectStatusTests
45 { 46 {
47 private TestScene m_scene;
48 private UUID m_ownerId = TestHelpers.ParseTail(0x1);
49 private SceneObjectGroup m_so1;
50 private SceneObjectGroup m_so2;
51
52 [SetUp]
53 public void Init()
54 {
55 m_scene = SceneHelpers.SetupScene();
56 m_so1 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so1", 0x10);
57 m_so2 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so2", 0x20);
58 }
59
46 [Test] 60 [Test]
47 public void TestSetPhantom() 61 public void TestSetPhantomSinglePrim()
48 { 62 {
49 TestHelpers.InMethod(); 63 TestHelpers.InMethod();
50 64
51// Scene scene = SceneSetupHelpers.SetupScene(); 65 m_scene.AddSceneObject(m_so1);
52 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero); 66
53 SceneObjectPart rootPart = so.RootPart; 67 SceneObjectPart rootPart = m_so1.RootPart;
54 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); 68 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
55 69
56 so.ScriptSetPhantomStatus(true); 70 m_so1.ScriptSetPhantomStatus(true);
57 71
58// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); 72// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
59 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); 73 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom));
60 74
61 so.ScriptSetPhantomStatus(false); 75 m_so1.ScriptSetPhantomStatus(false);
62 76
63 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); 77 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
64 } 78 }
79
80 [Test]
81 public void TestSetPhysicsSinglePrim()
82 {
83 TestHelpers.InMethod();
84
85 m_scene.AddSceneObject(m_so1);
86
87 SceneObjectPart rootPart = m_so1.RootPart;
88 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
89
90 m_so1.ScriptSetPhysicsStatus(true);
91
92// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
93 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Physics));
94
95 m_so1.ScriptSetPhysicsStatus(false);
96
97 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
98 }
99
100 [Test]
101 public void TestSetPhysicsLinkset()
102 {
103 TestHelpers.InMethod();
104
105 m_scene.AddSceneObject(m_so1);
106 m_scene.AddSceneObject(m_so2);
107
108 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
109
110 m_so1.ScriptSetPhysicsStatus(true);
111
112 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
113 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
114
115 m_so1.ScriptSetPhysicsStatus(false);
116
117 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.None));
118 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.None));
119
120 m_so1.ScriptSetPhysicsStatus(true);
121
122 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
123 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
124 }
125
126 /// <summary>
127 /// Test that linking results in the correct physical status for all linkees.
128 /// </summary>
129 [Test]
130 public void TestLinkPhysicsBothPhysical()
131 {
132 TestHelpers.InMethod();
133
134 m_scene.AddSceneObject(m_so1);
135 m_scene.AddSceneObject(m_so2);
136
137 m_so1.ScriptSetPhysicsStatus(true);
138 m_so2.ScriptSetPhysicsStatus(true);
139
140 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
141
142 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
143 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
144 }
145
146 /// <summary>
147 /// Test that linking results in the correct physical status for all linkees.
148 /// </summary>
149 [Test]
150 public void TestLinkPhysicsRootPhysicalOnly()
151 {
152 TestHelpers.InMethod();
153
154 m_scene.AddSceneObject(m_so1);
155 m_scene.AddSceneObject(m_so2);
156
157 m_so1.ScriptSetPhysicsStatus(true);
158
159 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
160
161 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
162 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
163 }
164
165 /// <summary>
166 /// Test that linking results in the correct physical status for all linkees.
167 /// </summary>
168 [Test]
169 public void TestLinkPhysicsChildPhysicalOnly()
170 {
171 TestHelpers.InMethod();
172
173 m_scene.AddSceneObject(m_so1);
174 m_scene.AddSceneObject(m_so2);
175
176 m_so2.ScriptSetPhysicsStatus(true);
177
178 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
179
180 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.None));
181 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.None));
182 }
65 } 183 }
66} \ No newline at end of file 184} \ No newline at end of file