diff options
Merge branch 'master' into careminster-presence-refactor
Integrate the next large patch.
Don't use this version, it has a ghost avatar issue. Next push
will fix it.
Diffstat (limited to 'OpenSim')
36 files changed, 1034 insertions, 1275 deletions
diff --git a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs index 8eae0a2..1da52b4 100644 --- a/OpenSim/Data/MSSQL/MSSQLSimulationData.cs +++ b/OpenSim/Data/MSSQL/MSSQLSimulationData.cs | |||
@@ -241,7 +241,7 @@ namespace OpenSim.Data.MSSQL | |||
241 | /// <param name="regionUUID"></param> | 241 | /// <param name="regionUUID"></param> |
242 | public void StoreObject(SceneObjectGroup obj, UUID regionUUID) | 242 | public void StoreObject(SceneObjectGroup obj, UUID regionUUID) |
243 | { | 243 | { |
244 | _Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); | 244 | _Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Parts.Length); |
245 | 245 | ||
246 | using (SqlConnection conn = new SqlConnection(m_connectionString)) | 246 | using (SqlConnection conn = new SqlConnection(m_connectionString)) |
247 | { | 247 | { |
@@ -250,7 +250,7 @@ namespace OpenSim.Data.MSSQL | |||
250 | 250 | ||
251 | try | 251 | try |
252 | { | 252 | { |
253 | foreach (SceneObjectPart sceneObjectPart in obj.Children.Values) | 253 | foreach (SceneObjectPart sceneObjectPart in obj.Parts) |
254 | { | 254 | { |
255 | //Update prim | 255 | //Update prim |
256 | using (SqlCommand sqlCommand = conn.CreateCommand()) | 256 | using (SqlCommand sqlCommand = conn.CreateCommand()) |
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 87f6d07..3450e2f 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs | |||
@@ -144,7 +144,7 @@ namespace OpenSim.Data.MySQL | |||
144 | dbcon.Open(); | 144 | dbcon.Open(); |
145 | MySqlCommand cmd = dbcon.CreateCommand(); | 145 | MySqlCommand cmd = dbcon.CreateCommand(); |
146 | 146 | ||
147 | foreach (SceneObjectPart prim in obj.Children.Values) | 147 | foreach (SceneObjectPart prim in obj.Parts) |
148 | { | 148 | { |
149 | cmd.Parameters.Clear(); | 149 | cmd.Parameters.Clear(); |
150 | 150 | ||
diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index 3e9bc3f..ebe6da8 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs | |||
@@ -368,7 +368,7 @@ namespace OpenSim.Data.SQLite | |||
368 | 368 | ||
369 | lock (ds) | 369 | lock (ds) |
370 | { | 370 | { |
371 | foreach (SceneObjectPart prim in obj.Children.Values) | 371 | foreach (SceneObjectPart prim in obj.Parts) |
372 | { | 372 | { |
373 | // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); | 373 | // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); |
374 | addPrim(prim, obj.UUID, regionUUID); | 374 | addPrim(prim, obj.UUID, regionUUID); |
diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteSimulationData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteSimulationData.cs index 2dde926..ce18a42 100644 --- a/OpenSim/Data/SQLiteLegacy/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteSimulationData.cs | |||
@@ -335,7 +335,7 @@ namespace OpenSim.Data.SQLiteLegacy | |||
335 | 335 | ||
336 | lock (ds) | 336 | lock (ds) |
337 | { | 337 | { |
338 | foreach (SceneObjectPart prim in obj.Children.Values) | 338 | foreach (SceneObjectPart prim in obj.Parts) |
339 | { | 339 | { |
340 | // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); | 340 | // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); |
341 | addPrim(prim, obj.UUID, regionUUID); | 341 | addPrim(prim, obj.UUID, regionUUID); |
diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index a081462..23d498d 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs | |||
@@ -232,15 +232,15 @@ namespace OpenSim.Data.Tests | |||
232 | sog.AddPart(p2); | 232 | sog.AddPart(p2); |
233 | sog.AddPart(p3); | 233 | sog.AddPart(p3); |
234 | 234 | ||
235 | SceneObjectPart[] parts = sog.GetParts(); | 235 | SceneObjectPart[] parts = sog.Parts; |
236 | Assert.That(parts.Length,Is.EqualTo(4), "Assert.That(parts.Length,Is.EqualTo(4))"); | 236 | Assert.That(parts.Length,Is.EqualTo(4), "Assert.That(parts.Length,Is.EqualTo(4))"); |
237 | 237 | ||
238 | db.StoreObject(sog, newregion); | 238 | db.StoreObject(sog, newregion); |
239 | List<SceneObjectGroup> sogs = db.LoadObjects(newregion); | 239 | List<SceneObjectGroup> sogs = db.LoadObjects(newregion); |
240 | Assert.That(sogs.Count,Is.EqualTo(1), "Assert.That(sogs.Count,Is.EqualTo(1))"); | 240 | Assert.That(sogs.Count,Is.EqualTo(1), "Assert.That(sogs.Count,Is.EqualTo(1))"); |
241 | SceneObjectGroup newsog = sogs[0]; | 241 | SceneObjectGroup newsog = sogs[0]; |
242 | 242 | ||
243 | SceneObjectPart[] newparts = newsog.GetParts(); | 243 | SceneObjectPart[] newparts = newsog.Parts; |
244 | Assert.That(newparts.Length,Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))"); | 244 | Assert.That(newparts.Length,Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))"); |
245 | 245 | ||
246 | Assert.That(newsog.HasChildPrim(tmp0), "Assert.That(newsog.HasChildPrim(tmp0))"); | 246 | Assert.That(newsog.HasChildPrim(tmp0), "Assert.That(newsog.HasChildPrim(tmp0))"); |
@@ -560,7 +560,7 @@ namespace OpenSim.Data.Tests | |||
560 | } | 560 | } |
561 | 561 | ||
562 | SceneObjectGroup retsog = FindSOG("Test SOG", region4); | 562 | SceneObjectGroup retsog = FindSOG("Test SOG", region4); |
563 | SceneObjectPart[] parts = retsog.GetParts(); | 563 | SceneObjectPart[] parts = retsog.Parts; |
564 | for (int i=0;i<30;i++) | 564 | for (int i=0;i<30;i++) |
565 | { | 565 | { |
566 | SceneObjectPart cursop = mydic[parts[i].UUID]; | 566 | SceneObjectPart cursop = mydic[parts[i].UUID]; |
@@ -607,7 +607,7 @@ namespace OpenSim.Data.Tests | |||
607 | sog.AddPart(p2); | 607 | sog.AddPart(p2); |
608 | sog.AddPart(p3); | 608 | sog.AddPart(p3); |
609 | 609 | ||
610 | SceneObjectPart[] parts = sog.GetParts(); | 610 | SceneObjectPart[] parts = sog.Parts; |
611 | Assert.That(parts.Length, Is.EqualTo(4), "Assert.That(parts.Length,Is.EqualTo(4))"); | 611 | Assert.That(parts.Length, Is.EqualTo(4), "Assert.That(parts.Length,Is.EqualTo(4))"); |
612 | 612 | ||
613 | db.StoreObject(sog, newregion); | 613 | db.StoreObject(sog, newregion); |
@@ -615,7 +615,7 @@ namespace OpenSim.Data.Tests | |||
615 | Assert.That(sogs.Count, Is.EqualTo(1), "Assert.That(sogs.Count,Is.EqualTo(1))"); | 615 | Assert.That(sogs.Count, Is.EqualTo(1), "Assert.That(sogs.Count,Is.EqualTo(1))"); |
616 | SceneObjectGroup newsog = sogs[0]; | 616 | SceneObjectGroup newsog = sogs[0]; |
617 | 617 | ||
618 | SceneObjectPart[] newparts = newsog.GetParts(); | 618 | SceneObjectPart[] newparts = newsog.Parts; |
619 | Assert.That(newparts.Length, Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))"); | 619 | Assert.That(newparts.Length, Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))"); |
620 | 620 | ||
621 | Assert.That(newsog, Constraints.PropertyCompareConstraint(sog) | 621 | Assert.That(newsog, Constraints.PropertyCompareConstraint(sog) |
@@ -625,7 +625,7 @@ namespace OpenSim.Data.Tests | |||
625 | .IgnoreProperty(x=>x.RegionHandle) | 625 | .IgnoreProperty(x=>x.RegionHandle) |
626 | .IgnoreProperty(x=>x.RegionUUID) | 626 | .IgnoreProperty(x=>x.RegionUUID) |
627 | .IgnoreProperty(x=>x.Scene) | 627 | .IgnoreProperty(x=>x.Scene) |
628 | .IgnoreProperty(x=>x.Children) | 628 | .IgnoreProperty(x=>x.Parts) |
629 | .IgnoreProperty(x=>x.PassCollision) | 629 | .IgnoreProperty(x=>x.PassCollision) |
630 | .IgnoreProperty(x=>x.RootPart)); | 630 | .IgnoreProperty(x=>x.RootPart)); |
631 | } | 631 | } |
diff --git a/OpenSim/Framework/MapAndArray.cs b/OpenSim/Framework/MapAndArray.cs new file mode 100644 index 0000000..bbe6a9e --- /dev/null +++ b/OpenSim/Framework/MapAndArray.cs | |||
@@ -0,0 +1,188 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | |||
31 | namespace OpenSim.Framework | ||
32 | { | ||
33 | /// <summary> | ||
34 | /// Stores two synchronized collections: a mutable dictionary and an | ||
35 | /// immutable array. Slower inserts/removes than a normal dictionary, | ||
36 | /// but provides safe iteration while maintaining fast hash lookups | ||
37 | /// </summary> | ||
38 | /// <typeparam name="TKey">Key type to use for hash lookups</typeparam> | ||
39 | /// <typeparam name="TValue">Value type to store</typeparam> | ||
40 | public sealed class MapAndArray<TKey, TValue> | ||
41 | { | ||
42 | private Dictionary<TKey, TValue> m_dict; | ||
43 | private TValue[] m_array; | ||
44 | private object m_syncRoot = new object(); | ||
45 | |||
46 | /// <summary>Number of values currently stored in the collection</summary> | ||
47 | public int Count { get { return m_array.Length; } } | ||
48 | /// <summary>NOTE: This collection is thread safe. You do not need to | ||
49 | /// acquire a lock to add, remove, or enumerate entries. This | ||
50 | /// synchronization object should only be locked for larger | ||
51 | /// transactions</summary> | ||
52 | public object SyncRoot { get { return m_syncRoot; } } | ||
53 | |||
54 | /// <summary> | ||
55 | /// Constructor | ||
56 | /// </summary> | ||
57 | public MapAndArray() | ||
58 | { | ||
59 | m_dict = new Dictionary<TKey, TValue>(); | ||
60 | m_array = new TValue[0]; | ||
61 | } | ||
62 | |||
63 | /// <summary> | ||
64 | /// Constructor | ||
65 | /// </summary> | ||
66 | /// <param name="capacity">Initial capacity of the dictionary</param> | ||
67 | public MapAndArray(int capacity) | ||
68 | { | ||
69 | m_dict = new Dictionary<TKey, TValue>(capacity); | ||
70 | m_array = new TValue[0]; | ||
71 | } | ||
72 | |||
73 | /// <summary> | ||
74 | /// Adds a key/value pair to the collection, or updates an existing key | ||
75 | /// with a new value | ||
76 | /// </summary> | ||
77 | /// <param name="key">Key to add or update</param> | ||
78 | /// <param name="value">Value to add</param> | ||
79 | /// <returns>True if a new key was added, false if an existing key was | ||
80 | /// updated</returns> | ||
81 | public bool AddOrReplace(TKey key, TValue value) | ||
82 | { | ||
83 | lock (m_syncRoot) | ||
84 | { | ||
85 | bool containedKey = m_dict.ContainsKey(key); | ||
86 | |||
87 | m_dict[key] = value; | ||
88 | CreateArray(); | ||
89 | |||
90 | return !containedKey; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | /// <summary> | ||
95 | /// Adds a key/value pair to the collection. This will throw an | ||
96 | /// exception if the key is already present in the collection | ||
97 | /// </summary> | ||
98 | /// <param name="key">Key to add or update</param> | ||
99 | /// <param name="value">Value to add</param> | ||
100 | /// <returns>Index of the inserted item</returns> | ||
101 | public int Add(TKey key, TValue value) | ||
102 | { | ||
103 | lock (m_syncRoot) | ||
104 | { | ||
105 | m_dict.Add(key, value); | ||
106 | CreateArray(); | ||
107 | return m_array.Length; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | /// <summary> | ||
112 | /// Removes a key/value pair from the collection | ||
113 | /// </summary> | ||
114 | /// <param name="key">Key to remove</param> | ||
115 | /// <returns>True if the key was found and removed, otherwise false</returns> | ||
116 | public bool Remove(TKey key) | ||
117 | { | ||
118 | lock (m_syncRoot) | ||
119 | { | ||
120 | bool removed = m_dict.Remove(key); | ||
121 | CreateArray(); | ||
122 | |||
123 | return removed; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | /// <summary> | ||
128 | /// Determines whether the collections contains a specified key | ||
129 | /// </summary> | ||
130 | /// <param name="key">Key to search for</param> | ||
131 | /// <returns>True if the key was found, otherwise false</returns> | ||
132 | public bool ContainsKey(TKey key) | ||
133 | { | ||
134 | return m_dict.ContainsKey(key); | ||
135 | } | ||
136 | |||
137 | /// <summary> | ||
138 | /// Gets the value associated with the specified key | ||
139 | /// </summary> | ||
140 | /// <param name="key">Key of the value to get</param> | ||
141 | /// <param name="value">Will contain the value associated with the | ||
142 | /// given key if the key is found. If the key is not found it will | ||
143 | /// contain the default value for the type of the value parameter</param> | ||
144 | /// <returns>True if the key was found and a value was retrieved, | ||
145 | /// otherwise false</returns> | ||
146 | public bool TryGetValue(TKey key, out TValue value) | ||
147 | { | ||
148 | lock (m_syncRoot) | ||
149 | return m_dict.TryGetValue(key, out value); | ||
150 | } | ||
151 | |||
152 | /// <summary> | ||
153 | /// Clears all key/value pairs from the collection | ||
154 | /// </summary> | ||
155 | public void Clear() | ||
156 | { | ||
157 | lock (m_syncRoot) | ||
158 | { | ||
159 | m_dict = new Dictionary<TKey, TValue>(); | ||
160 | m_array = new TValue[0]; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | /// <summary> | ||
165 | /// Gets a reference to the immutable array of values stored in this | ||
166 | /// collection. This array is thread safe for iteration | ||
167 | /// </summary> | ||
168 | /// <returns>A thread safe reference ton an array of all of the stored | ||
169 | /// values</returns> | ||
170 | public TValue[] GetArray() | ||
171 | { | ||
172 | return m_array; | ||
173 | } | ||
174 | |||
175 | private void CreateArray() | ||
176 | { | ||
177 | // Rebuild the array from the dictionary. This method must be | ||
178 | // called from inside a lock | ||
179 | TValue[] array = new TValue[m_dict.Count]; | ||
180 | int i = 0; | ||
181 | |||
182 | foreach (TValue value in m_dict.Values) | ||
183 | array[i++] = value; | ||
184 | |||
185 | m_array = array; | ||
186 | } | ||
187 | } | ||
188 | } | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 0f1a1ca..dca1346 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -1533,7 +1533,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1533 | lock (m_entityUpdates.SyncRoot) | 1533 | lock (m_entityUpdates.SyncRoot) |
1534 | { | 1534 | { |
1535 | m_killRecord.Add(localID); | 1535 | m_killRecord.Add(localID); |
1536 | OutPacket(kill, ThrottleOutPacketType.State); | 1536 | |
1537 | // The throttle queue used here must match that being used for updates. Otherwise, there is a | ||
1538 | // chance that a kill packet put on a separate queue will be sent to the client before an existing | ||
1539 | // update packet on another queue. Receiving updates after kills results in unowned and undeletable | ||
1540 | // scene objects in a viewer until that viewer is relogged in. | ||
1541 | OutPacket(kill, ThrottleOutPacketType.Task); | ||
1537 | } | 1542 | } |
1538 | } | 1543 | } |
1539 | } | 1544 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index eebbfa5..a4738ff 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -420,8 +420,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
420 | 420 | ||
421 | /// <summary> | 421 | /// <summary> |
422 | /// Loops through all of the packet queues for this client and tries to send | 422 | /// Loops through all of the packet queues for this client and tries to send |
423 | /// any outgoing packets, obeying the throttling bucket limits | 423 | /// an outgoing packet from each, obeying the throttling bucket limits |
424 | /// </summary> | 424 | /// </summary> |
425 | /// | ||
426 | /// Packet queues are inspected in ascending numerical order starting from 0. Therefore, queues with a lower | ||
427 | /// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have | ||
428 | /// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the | ||
429 | /// wind queue). | ||
430 | /// | ||
425 | /// <remarks>This function is only called from a synchronous loop in the | 431 | /// <remarks>This function is only called from a synchronous loop in the |
426 | /// UDPServer so we don't need to bother making this thread safe</remarks> | 432 | /// UDPServer so we don't need to bother making this thread safe</remarks> |
427 | /// <returns>True if any packets were sent, otherwise false</returns> | 433 | /// <returns>True if any packets were sent, otherwise false</returns> |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 5aeca83..e2cda6d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -500,6 +500,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
500 | // FIXME: Implement? | 500 | // FIXME: Implement? |
501 | } | 501 | } |
502 | 502 | ||
503 | /// <summary> | ||
504 | /// Actually send a packet to a client. | ||
505 | /// </summary> | ||
506 | /// <param name="outgoingPacket"></param> | ||
503 | internal void SendPacketFinal(OutgoingPacket outgoingPacket) | 507 | internal void SendPacketFinal(OutgoingPacket outgoingPacket) |
504 | { | 508 | { |
505 | UDPPacketBuffer buffer = outgoingPacket.Buffer; | 509 | UDPPacketBuffer buffer = outgoingPacket.Buffer; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 7c95658..6f7256e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -586,13 +586,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
586 | so.RootPart.AttachedAvatar = avatar.UUID; | 586 | so.RootPart.AttachedAvatar = avatar.UUID; |
587 | 587 | ||
588 | //Anakin Lohner bug #3839 | 588 | //Anakin Lohner bug #3839 |
589 | lock (so.Children) | 589 | SceneObjectPart[] parts = so.Parts; |
590 | { | 590 | for (int i = 0; i < parts.Length; i++) |
591 | foreach (SceneObjectPart p in so.Children.Values) | 591 | parts[i].AttachedAvatar = avatar.UUID; |
592 | { | ||
593 | p.AttachedAvatar = avatar.UUID; | ||
594 | } | ||
595 | } | ||
596 | 592 | ||
597 | if (so.RootPart.PhysActor != null) | 593 | if (so.RootPart.PhysActor != null) |
598 | { | 594 | { |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index a2ba498..42e3359 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -544,7 +544,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
544 | if (!attachment) | 544 | if (!attachment) |
545 | { | 545 | { |
546 | group.RootPart.CreateSelected = true; | 546 | group.RootPart.CreateSelected = true; |
547 | foreach (SceneObjectPart child in group.Children.Values) | 547 | foreach (SceneObjectPart child in group.Parts) |
548 | child.CreateSelected = true; | 548 | child.CreateSelected = true; |
549 | } | 549 | } |
550 | 550 | ||
@@ -629,10 +629,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
629 | rootPart.Name = item.Name; | 629 | rootPart.Name = item.Name; |
630 | rootPart.Description = item.Description; | 630 | rootPart.Description = item.Description; |
631 | 631 | ||
632 | List<SceneObjectPart> partList = null; | ||
633 | lock (group.Children) | ||
634 | partList = new List<SceneObjectPart>(group.Children.Values); | ||
635 | |||
636 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); | 632 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); |
637 | if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) | 633 | if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) |
638 | { | 634 | { |
@@ -642,7 +638,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
642 | 638 | ||
643 | if (m_Scene.Permissions.PropagatePermissions()) | 639 | if (m_Scene.Permissions.PropagatePermissions()) |
644 | { | 640 | { |
645 | foreach (SceneObjectPart part in partList) | 641 | foreach (SceneObjectPart part in group.Parts) |
646 | { | 642 | { |
647 | part.EveryoneMask = item.EveryOnePermissions; | 643 | part.EveryoneMask = item.EveryOnePermissions; |
648 | part.NextOwnerMask = item.NextPermissions; | 644 | part.NextOwnerMask = item.NextPermissions; |
@@ -656,7 +652,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
656 | { | 652 | { |
657 | m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 8"); | 653 | m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 8"); |
658 | } | 654 | } |
659 | foreach (SceneObjectPart part in partList) | 655 | |
656 | foreach (SceneObjectPart part in group.Parts) | ||
660 | { | 657 | { |
661 | if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) | 658 | if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) |
662 | { | 659 | { |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index e51f118..4af7a1b 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -243,11 +243,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
243 | // to the same scene (when this is possible). | 243 | // to the same scene (when this is possible). |
244 | sceneObject.ResetIDs(); | 244 | sceneObject.ResetIDs(); |
245 | 245 | ||
246 | List<SceneObjectPart> partList = null; | 246 | foreach (SceneObjectPart part in sceneObject.Parts) |
247 | lock (sceneObject.Children) | ||
248 | partList = new List<SceneObjectPart>(sceneObject.Children.Values); | ||
249 | |||
250 | foreach (SceneObjectPart part in partList) | ||
251 | { | 247 | { |
252 | if (!ResolveUserUuid(part.CreatorID)) | 248 | if (!ResolveUserUuid(part.CreatorID)) |
253 | part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 249 | part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index db50339..d91c36c 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs | |||
@@ -128,14 +128,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell | |||
128 | group.SetOwnerId(remoteClient.AgentId); | 128 | group.SetOwnerId(remoteClient.AgentId); |
129 | group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); | 129 | group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); |
130 | 130 | ||
131 | List<SceneObjectPart> partList = null; | ||
132 | |||
133 | lock (group.Children) | ||
134 | partList = new List<SceneObjectPart>(group.Children.Values); | ||
135 | |||
136 | if (m_scene.Permissions.PropagatePermissions()) | 131 | if (m_scene.Permissions.PropagatePermissions()) |
137 | { | 132 | { |
138 | foreach (SceneObjectPart child in partList) | 133 | foreach (SceneObjectPart child in group.Parts) |
139 | { | 134 | { |
140 | child.Inventory.ChangeInventoryOwner(remoteClient.AgentId); | 135 | child.Inventory.ChangeInventoryOwner(remoteClient.AgentId); |
141 | child.TriggerScriptChangedEvent(Changed.OWNER); | 136 | child.TriggerScriptChangedEvent(Changed.OWNER); |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs index 1bd1371..c83ac85 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs | |||
@@ -229,11 +229,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
229 | Color mapdotspot = Color.Gray; // Default color when prim color is white | 229 | Color mapdotspot = Color.Gray; // Default color when prim color is white |
230 | 230 | ||
231 | // Loop over prim in group | 231 | // Loop over prim in group |
232 | List<SceneObjectPart> partList = null; | 232 | foreach (SceneObjectPart part in mapdot.Parts) |
233 | lock (mapdot.Children) | ||
234 | partList = new List<SceneObjectPart>(mapdot.Children.Values); | ||
235 | |||
236 | foreach (SceneObjectPart part in partList) | ||
237 | { | 233 | { |
238 | if (part == null) | 234 | if (part == null) |
239 | continue; | 235 | continue; |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 867fb10..ac82fda 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -2064,9 +2064,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2064 | sog.SetGroup(groupID, remoteClient); | 2064 | sog.SetGroup(groupID, remoteClient); |
2065 | sog.ScheduleGroupForFullUpdate(); | 2065 | sog.ScheduleGroupForFullUpdate(); |
2066 | 2066 | ||
2067 | List<SceneObjectPart> partList = null; | 2067 | SceneObjectPart[] partList = sog.Parts; |
2068 | lock (sog.Children) | ||
2069 | partList = new List<SceneObjectPart>(sog.Children.Values); | ||
2070 | 2068 | ||
2071 | foreach (SceneObjectPart child in partList) | 2069 | foreach (SceneObjectPart child in partList) |
2072 | child.Inventory.ChangeInventoryOwner(ownerID); | 2070 | child.Inventory.ChangeInventoryOwner(ownerID); |
@@ -2079,9 +2077,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2079 | if (sog.GroupID != groupID) | 2077 | if (sog.GroupID != groupID) |
2080 | continue; | 2078 | continue; |
2081 | 2079 | ||
2082 | List<SceneObjectPart> partList = null; | 2080 | SceneObjectPart[] partList = sog.Parts; |
2083 | lock (sog.Children) | ||
2084 | partList = new List<SceneObjectPart>(sog.Children.Values); | ||
2085 | 2081 | ||
2086 | foreach (SceneObjectPart child in partList) | 2082 | foreach (SceneObjectPart child in partList) |
2087 | { | 2083 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 7788e43..4d97db7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | |||
@@ -161,11 +161,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
161 | bool foundPrim = false; | 161 | bool foundPrim = false; |
162 | 162 | ||
163 | SceneObjectGroup sog = ent as SceneObjectGroup; | 163 | SceneObjectGroup sog = ent as SceneObjectGroup; |
164 | |||
165 | List<SceneObjectPart> partList = null; | ||
166 | lock (sog.Children) | ||
167 | partList = new List<SceneObjectPart>(sog.Children.Values); | ||
168 | 164 | ||
165 | SceneObjectPart[] partList = sog.Parts; | ||
169 | foreach (SceneObjectPart part in partList) | 166 | foreach (SceneObjectPart part in partList) |
170 | { | 167 | { |
171 | if (part.LocalId == primLocalID) | 168 | if (part.LocalId == primLocalID) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 33e3e5d..240d33c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1819,7 +1819,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1819 | { | 1819 | { |
1820 | m_log.ErrorFormat( | 1820 | m_log.ErrorFormat( |
1821 | "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", | 1821 | "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", |
1822 | group.Children == null ? 0 : group.PrimCount); | 1822 | group.Parts == null ? 0 : group.PrimCount); |
1823 | } | 1823 | } |
1824 | 1824 | ||
1825 | AddRestoredSceneObject(group, true, true); | 1825 | AddRestoredSceneObject(group, true, true); |
@@ -2160,9 +2160,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2160 | group.RemoveScriptInstances(true); | 2160 | group.RemoveScriptInstances(true); |
2161 | } | 2161 | } |
2162 | 2162 | ||
2163 | List<SceneObjectPart> partList = null; | 2163 | SceneObjectPart[] partList = group.Parts; |
2164 | lock (group.Children) | ||
2165 | partList = new List<SceneObjectPart>(group.Children.Values); | ||
2166 | 2164 | ||
2167 | foreach (SceneObjectPart part in partList) | 2165 | foreach (SceneObjectPart part in partList) |
2168 | { | 2166 | { |
@@ -2540,11 +2538,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2540 | 2538 | ||
2541 | // Force allocation of new LocalId | 2539 | // Force allocation of new LocalId |
2542 | // | 2540 | // |
2543 | lock (sceneObject.Children) | 2541 | SceneObjectPart[] parts = sceneObject.Parts; |
2544 | { | 2542 | for (int i = 0; i < parts.Length; i++) |
2545 | foreach (SceneObjectPart p in sceneObject.Children.Values) | 2543 | parts[i].LocalId = 0; |
2546 | p.LocalId = 0; | ||
2547 | } | ||
2548 | 2544 | ||
2549 | if (sceneObject.IsAttachmentCheckFull()) // Attachment | 2545 | if (sceneObject.IsAttachmentCheckFull()) // Attachment |
2550 | { | 2546 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 9c3486e..5ef14bf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -270,7 +270,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
270 | if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; | 270 | if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; |
271 | if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; | 271 | if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; |
272 | 272 | ||
273 | foreach (SceneObjectPart part in sceneObject.Children.Values) | 273 | foreach (SceneObjectPart part in sceneObject.Parts) |
274 | { | 274 | { |
275 | part.GroupPosition = npos; | 275 | part.GroupPosition = npos; |
276 | } | 276 | } |
@@ -370,9 +370,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
370 | if (Entities.ContainsKey(sceneObject.UUID)) | 370 | if (Entities.ContainsKey(sceneObject.UUID)) |
371 | return false; | 371 | return false; |
372 | 372 | ||
373 | List<SceneObjectPart> children; | 373 | SceneObjectPart[] children = sceneObject.Parts; |
374 | lock (sceneObject.Children) | ||
375 | children = new List<SceneObjectPart>(sceneObject.Children.Values); | ||
376 | 374 | ||
377 | // Clamp child prim sizes and add child prims to the m_numPrim count | 375 | // Clamp child prim sizes and add child prims to the m_numPrim count |
378 | if (m_parentScene.m_clampPrimSize) | 376 | if (m_parentScene.m_clampPrimSize) |
@@ -391,7 +389,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
391 | part.Shape.Scale = scale; | 389 | part.Shape.Scale = scale; |
392 | } | 390 | } |
393 | } | 391 | } |
394 | m_numPrim += children.Count; | 392 | m_numPrim += children.Length; |
395 | 393 | ||
396 | sceneObject.AttachToScene(m_parentScene); | 394 | sceneObject.AttachToScene(m_parentScene); |
397 | 395 | ||
@@ -448,15 +446,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
448 | 446 | ||
449 | lock (SceneObjectGroupsByFullID) | 447 | lock (SceneObjectGroupsByFullID) |
450 | { | 448 | { |
451 | foreach (SceneObjectPart part in grp.Children.Values) | 449 | SceneObjectPart[] parts = grp.Parts; |
452 | SceneObjectGroupsByFullID.Remove(part.UUID); | 450 | for (int i = 0; i < parts.Length; i++) |
451 | SceneObjectGroupsByFullID.Remove(parts[i].UUID); | ||
453 | SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID); | 452 | SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID); |
454 | } | 453 | } |
455 | 454 | ||
456 | lock (SceneObjectGroupsByLocalID) | 455 | lock (SceneObjectGroupsByLocalID) |
457 | { | 456 | { |
458 | foreach (SceneObjectPart part in grp.Children.Values) | 457 | SceneObjectPart[] parts = grp.Parts; |
459 | SceneObjectGroupsByLocalID.Remove(part.LocalId); | 458 | for (int i = 0; i < parts.Length; i++) |
459 | SceneObjectGroupsByLocalID.Remove(parts[i].LocalId); | ||
460 | SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId); | 460 | SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId); |
461 | } | 461 | } |
462 | 462 | ||
@@ -943,11 +943,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
943 | 943 | ||
944 | if (sog != null) | 944 | if (sog != null) |
945 | { | 945 | { |
946 | lock (sog.Children) | 946 | if (sog.ContainsPart(fullID)) |
947 | { | 947 | return sog; |
948 | if (sog.Children.ContainsKey(fullID)) | ||
949 | return sog; | ||
950 | } | ||
951 | 948 | ||
952 | lock (SceneObjectGroupsByFullID) | 949 | lock (SceneObjectGroupsByFullID) |
953 | SceneObjectGroupsByFullID.Remove(fullID); | 950 | SceneObjectGroupsByFullID.Remove(fullID); |
@@ -1021,7 +1018,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1021 | { | 1018 | { |
1022 | if (entity is SceneObjectGroup) | 1019 | if (entity is SceneObjectGroup) |
1023 | { | 1020 | { |
1024 | foreach (SceneObjectPart p in ((SceneObjectGroup)entity).GetParts()) | 1021 | foreach (SceneObjectPart p in ((SceneObjectGroup)entity).Parts) |
1025 | { | 1022 | { |
1026 | if (p.Name == name) | 1023 | if (p.Name == name) |
1027 | { | 1024 | { |
@@ -1686,14 +1683,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1686 | SceneObjectGroup group = root.ParentGroup; | 1683 | SceneObjectGroup group = root.ParentGroup; |
1687 | group.areUpdatesSuspended = true; | 1684 | group.areUpdatesSuspended = true; |
1688 | 1685 | ||
1689 | List<SceneObjectPart> newSet = null; | 1686 | List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); |
1690 | int numChildren; | 1687 | int numChildren = newSet.Count; |
1691 | |||
1692 | lock (group.Children) | ||
1693 | { | ||
1694 | newSet = new List<SceneObjectPart>(group.Children.Values); | ||
1695 | numChildren = group.PrimCount; | ||
1696 | } | ||
1697 | 1688 | ||
1698 | if (numChildren == 1) | 1689 | if (numChildren == 1) |
1699 | break; | 1690 | break; |
@@ -1783,16 +1774,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1783 | if (ent is SceneObjectGroup) | 1774 | if (ent is SceneObjectGroup) |
1784 | { | 1775 | { |
1785 | SceneObjectGroup sog = ent as SceneObjectGroup; | 1776 | SceneObjectGroup sog = ent as SceneObjectGroup; |
1786 | 1777 | ||
1787 | lock (sog.Children) | 1778 | foreach (SceneObjectPart part in sog.Parts) |
1788 | { | 1779 | { |
1789 | foreach (KeyValuePair<UUID, SceneObjectPart> subent in sog.Children) | 1780 | if (part.LocalId == localID) |
1790 | { | 1781 | { |
1791 | if (subent.Value.LocalId == localID) | 1782 | objid = part.UUID; |
1792 | { | 1783 | obj = part; |
1793 | objid = subent.Key; | ||
1794 | obj = subent.Value; | ||
1795 | } | ||
1796 | } | 1784 | } |
1797 | } | 1785 | } |
1798 | } | 1786 | } |
@@ -1868,8 +1856,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1868 | copy.SetOwnerId(AgentID); | 1856 | copy.SetOwnerId(AgentID); |
1869 | copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID); | 1857 | copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID); |
1870 | 1858 | ||
1871 | List<SceneObjectPart> partList = | 1859 | SceneObjectPart[] partList = copy.Parts; |
1872 | new List<SceneObjectPart>(copy.Children.Values); | ||
1873 | 1860 | ||
1874 | if (m_parentScene.Permissions.PropagatePermissions()) | 1861 | if (m_parentScene.Permissions.PropagatePermissions()) |
1875 | { | 1862 | { |
@@ -1891,7 +1878,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1891 | // think it's selected, so it will never send a deselect... | 1878 | // think it's selected, so it will never send a deselect... |
1892 | copy.IsSelected = false; | 1879 | copy.IsSelected = false; |
1893 | 1880 | ||
1894 | m_numPrim += copy.Children.Count; | 1881 | m_numPrim += copy.Parts.Length; |
1895 | 1882 | ||
1896 | if (rot != Quaternion.Identity) | 1883 | if (rot != Quaternion.Identity) |
1897 | { | 1884 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index a7003c4..6cc7231 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | |||
@@ -46,13 +46,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
46 | /// </summary> | 46 | /// </summary> |
47 | public void ForceInventoryPersistence() | 47 | public void ForceInventoryPersistence() |
48 | { | 48 | { |
49 | lockPartsForRead(true); | 49 | SceneObjectPart[] parts = m_parts.GetArray(); |
50 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | 50 | for (int i = 0; i < parts.Length; i++) |
51 | lockPartsForRead(false); | 51 | parts[i].Inventory.ForceInventoryPersistence(); |
52 | foreach (SceneObjectPart part in values) | ||
53 | { | ||
54 | part.Inventory.ForceInventoryPersistence(); | ||
55 | } | ||
56 | } | 52 | } |
57 | 53 | ||
58 | /// <summary> | 54 | /// <summary> |
@@ -64,10 +60,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
64 | // Don't start scripts if they're turned off in the region! | 60 | // Don't start scripts if they're turned off in the region! |
65 | if (!m_scene.RegionInfo.RegionSettings.DisableScripts) | 61 | if (!m_scene.RegionInfo.RegionSettings.DisableScripts) |
66 | { | 62 | { |
67 | foreach (SceneObjectPart part in m_parts.Values) | 63 | SceneObjectPart[] parts = m_parts.GetArray(); |
68 | { | 64 | for (int i = 0; i < parts.Length; i++) |
69 | part.Inventory.CreateScriptInstances(startParam, postOnRez, engine, stateSource); | 65 | parts[i].Inventory.CreateScriptInstances(startParam, postOnRez, engine, stateSource); |
70 | } | ||
71 | } | 66 | } |
72 | } | 67 | } |
73 | 68 | ||
@@ -76,15 +71,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
76 | /// </summary> | 71 | /// </summary> |
77 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) | 72 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) |
78 | { | 73 | { |
79 | lockPartsForRead(true); | 74 | SceneObjectPart[] parts = m_parts.GetArray(); |
80 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | 75 | for (int i = 0; i < parts.Length; i++) |
81 | lockPartsForRead(false); | 76 | parts[i].Inventory.RemoveScriptInstances(sceneObjectBeingDeleted); |
82 | |||
83 | foreach (SceneObjectPart part in values) | ||
84 | { | ||
85 | part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted); | ||
86 | } | ||
87 | |||
88 | } | 77 | } |
89 | 78 | ||
90 | /// <summary> | 79 | /// <summary> |
@@ -281,8 +270,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
281 | PermissionMask.Transfer) | 7; | 270 | PermissionMask.Transfer) | 7; |
282 | 271 | ||
283 | uint ownerMask = 0x7fffffff; | 272 | uint ownerMask = 0x7fffffff; |
284 | foreach (SceneObjectPart part in m_parts.Values) | 273 | |
274 | SceneObjectPart[] parts = m_parts.GetArray(); | ||
275 | for (int i = 0; i < parts.Length; i++) | ||
285 | { | 276 | { |
277 | SceneObjectPart part = parts[i]; | ||
286 | ownerMask &= part.OwnerMask; | 278 | ownerMask &= part.OwnerMask; |
287 | perms &= part.Inventory.MaskEffectivePermissions(); | 279 | perms &= part.Inventory.MaskEffectivePermissions(); |
288 | } | 280 | } |
@@ -310,39 +302,40 @@ namespace OpenSim.Region.Framework.Scenes | |||
310 | 302 | ||
311 | public void ApplyNextOwnerPermissions() | 303 | public void ApplyNextOwnerPermissions() |
312 | { | 304 | { |
313 | foreach (SceneObjectPart part in m_parts.Values) | 305 | SceneObjectPart[] parts = m_parts.GetArray(); |
314 | { | 306 | for (int i = 0; i < parts.Length; i++) |
315 | part.ApplyNextOwnerPermissions(); | 307 | parts[i].ApplyNextOwnerPermissions(); |
316 | } | ||
317 | } | 308 | } |
318 | 309 | ||
319 | public string GetStateSnapshot() | 310 | public string GetStateSnapshot() |
320 | { | 311 | { |
321 | Dictionary<UUID, string> states = new Dictionary<UUID, string>(); | 312 | Dictionary<UUID, string> states = new Dictionary<UUID, string>(); |
322 | 313 | ||
323 | foreach (SceneObjectPart part in m_parts.Values) | 314 | SceneObjectPart[] parts = m_parts.GetArray(); |
315 | for (int i = 0; i < parts.Length; i++) | ||
324 | { | 316 | { |
317 | SceneObjectPart part = parts[i]; | ||
325 | foreach (KeyValuePair<UUID, string> s in part.Inventory.GetScriptStates()) | 318 | foreach (KeyValuePair<UUID, string> s in part.Inventory.GetScriptStates()) |
326 | states[s.Key] = s.Value; | 319 | states[s.Key] = s.Value; |
327 | } | 320 | } |
328 | 321 | ||
329 | if (states.Count < 1) | 322 | if (states.Count < 1) |
330 | return ""; | 323 | return String.Empty; |
331 | 324 | ||
332 | XmlDocument xmldoc = new XmlDocument(); | 325 | XmlDocument xmldoc = new XmlDocument(); |
333 | 326 | ||
334 | XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, | 327 | XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, |
335 | "", ""); | 328 | String.Empty, String.Empty); |
336 | 329 | ||
337 | xmldoc.AppendChild(xmlnode); | 330 | xmldoc.AppendChild(xmlnode); |
338 | XmlElement rootElement = xmldoc.CreateElement("", "ScriptData", | 331 | XmlElement rootElement = xmldoc.CreateElement("", "ScriptData", |
339 | ""); | 332 | String.Empty); |
340 | 333 | ||
341 | xmldoc.AppendChild(rootElement); | 334 | xmldoc.AppendChild(rootElement); |
342 | 335 | ||
343 | 336 | ||
344 | XmlElement wrapper = xmldoc.CreateElement("", "ScriptStates", | 337 | XmlElement wrapper = xmldoc.CreateElement("", "ScriptStates", |
345 | ""); | 338 | String.Empty); |
346 | 339 | ||
347 | rootElement.AppendChild(wrapper); | 340 | rootElement.AppendChild(wrapper); |
348 | 341 | ||
@@ -425,10 +418,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
425 | if (m_scene.RegionInfo.RegionSettings.DisableScripts) | 418 | if (m_scene.RegionInfo.RegionSettings.DisableScripts) |
426 | return; | 419 | return; |
427 | 420 | ||
428 | foreach (SceneObjectPart part in m_parts.Values) | 421 | SceneObjectPart[] parts = m_parts.GetArray(); |
429 | { | 422 | for (int i = 0; i < parts.Length; i++) |
430 | part.Inventory.ResumeScripts(); | 423 | parts[i].Inventory.ResumeScripts(); |
431 | } | ||
432 | } | 424 | } |
433 | } | 425 | } |
434 | } | 426 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 142f5d8..3bc7834 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -131,89 +131,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
131 | } | 131 | } |
132 | } | 132 | } |
133 | 133 | ||
134 | public void lockPartsForRead(bool locked) | ||
135 | { | ||
136 | if (locked) | ||
137 | { | ||
138 | if (m_partsLock.RecursiveReadCount > 0) | ||
139 | { | ||
140 | m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | ||
141 | try | ||
142 | { | ||
143 | StackTrace stackTrace = new StackTrace(); // get call stack | ||
144 | StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) | ||
145 | |||
146 | // write call stack method names | ||
147 | foreach (StackFrame stackFrame in stackFrames) | ||
148 | { | ||
149 | m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name | ||
150 | } | ||
151 | |||
152 | m_partsLock.ExitReadLock(); | ||
153 | } | ||
154 | catch { } // Ignore errors, to allow resync | ||
155 | } | ||
156 | if (m_partsLock.RecursiveWriteCount > 0) | ||
157 | { | ||
158 | m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested (write lock exists on this thread). This should not happen and means something needs to be fixed."); | ||
159 | try | ||
160 | { | ||
161 | m_partsLock.ExitWriteLock(); | ||
162 | } | ||
163 | catch { } | ||
164 | |||
165 | } | ||
166 | |||
167 | while (!m_partsLock.TryEnterReadLock(60000)) | ||
168 | { | ||
169 | m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
170 | if (m_partsLock.IsWriteLockHeld) | ||
171 | { | ||
172 | m_partsLock = new System.Threading.ReaderWriterLockSlim(); | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | else | ||
177 | { | ||
178 | if (m_partsLock.RecursiveReadCount > 0) | ||
179 | { | ||
180 | m_partsLock.ExitReadLock(); | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | public void lockPartsForWrite(bool locked) | ||
185 | { | ||
186 | if (locked) | ||
187 | { | ||
188 | if (m_partsLock.RecursiveReadCount > 0) | ||
189 | { | ||
190 | m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | ||
191 | m_partsLock.ExitReadLock(); | ||
192 | } | ||
193 | if (m_partsLock.RecursiveWriteCount > 0) | ||
194 | { | ||
195 | m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
196 | m_partsLock.ExitWriteLock(); | ||
197 | } | ||
198 | |||
199 | while (!m_partsLock.TryEnterWriteLock(60000)) | ||
200 | { | ||
201 | m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
202 | if (m_partsLock.IsWriteLockHeld) | ||
203 | { | ||
204 | m_partsLock = new System.Threading.ReaderWriterLockSlim(); | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | else | ||
209 | { | ||
210 | if (m_partsLock.RecursiveWriteCount > 0) | ||
211 | { | ||
212 | m_partsLock.ExitWriteLock(); | ||
213 | } | ||
214 | } | ||
215 | } | ||
216 | |||
217 | public bool HasGroupChanged | 134 | public bool HasGroupChanged |
218 | { | 135 | { |
219 | set | 136 | set |
@@ -305,17 +222,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
305 | } | 222 | } |
306 | } | 223 | } |
307 | 224 | ||
308 | public float scriptScore = 0f; | 225 | public float scriptScore; |
309 | 226 | ||
310 | private Vector3 lastPhysGroupPos; | 227 | private Vector3 lastPhysGroupPos; |
311 | private Quaternion lastPhysGroupRot; | 228 | private Quaternion lastPhysGroupRot; |
312 | 229 | ||
313 | private bool m_isBackedUp = false; | 230 | private bool m_isBackedUp; |
314 | 231 | ||
315 | /// <summary> | 232 | protected MapAndArray<UUID, SceneObjectPart> m_parts = new MapAndArray<UUID, SceneObjectPart>(); |
316 | /// The constituent parts of this group | ||
317 | /// </summary> | ||
318 | protected Dictionary<UUID, SceneObjectPart> m_parts = new Dictionary<UUID, SceneObjectPart>(); | ||
319 | 233 | ||
320 | protected ulong m_regionHandle; | 234 | protected ulong m_regionHandle; |
321 | protected SceneObjectPart m_rootPart; | 235 | protected SceneObjectPart m_rootPart; |
@@ -324,13 +238,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
324 | private Dictionary<uint, scriptPosTarget> m_targets = new Dictionary<uint, scriptPosTarget>(); | 238 | private Dictionary<uint, scriptPosTarget> m_targets = new Dictionary<uint, scriptPosTarget>(); |
325 | private Dictionary<uint, scriptRotTarget> m_rotTargets = new Dictionary<uint, scriptRotTarget>(); | 239 | private Dictionary<uint, scriptRotTarget> m_rotTargets = new Dictionary<uint, scriptRotTarget>(); |
326 | 240 | ||
327 | private bool m_scriptListens_atTarget = false; | 241 | private bool m_scriptListens_atTarget; |
328 | private bool m_scriptListens_notAtTarget = false; | 242 | private bool m_scriptListens_notAtTarget; |
243 | private bool m_scriptListens_atRotTarget; | ||
244 | private bool m_scriptListens_notAtRotTarget; | ||
329 | 245 | ||
330 | private bool m_scriptListens_atRotTarget = false; | ||
331 | private bool m_scriptListens_notAtRotTarget = false; | ||
332 | public bool m_dupeInProgress = false; | 246 | public bool m_dupeInProgress = false; |
333 | internal Dictionary<UUID, string> m_savedScriptState = null; | 247 | internal Dictionary<UUID, string> m_savedScriptState; |
334 | 248 | ||
335 | #region Properties | 249 | #region Properties |
336 | 250 | ||
@@ -341,7 +255,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
341 | { | 255 | { |
342 | get { | 256 | get { |
343 | if (RootPart == null) | 257 | if (RootPart == null) |
344 | return ""; | 258 | return String.Empty; |
345 | return RootPart.Name; | 259 | return RootPart.Name; |
346 | } | 260 | } |
347 | set { RootPart.Name = value; } | 261 | set { RootPart.Name = value; } |
@@ -361,7 +275,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
361 | /// </summary> | 275 | /// </summary> |
362 | public int PrimCount | 276 | public int PrimCount |
363 | { | 277 | { |
364 | get { lock (m_parts) { return m_parts.Count; } } | 278 | get { return m_parts.Count; } |
365 | } | 279 | } |
366 | 280 | ||
367 | protected Quaternion m_rotation = Quaternion.Identity; | 281 | protected Quaternion m_rotation = Quaternion.Identity; |
@@ -370,17 +284,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
370 | { | 284 | { |
371 | get { return m_rotation; } | 285 | get { return m_rotation; } |
372 | set { | 286 | set { |
373 | lockPartsForRead(true); | 287 | foreach(SceneObjectPart p in m_parts.GetArray()) |
374 | try | ||
375 | { | 288 | { |
376 | foreach(SceneObjectPart p in m_parts.Values) | 289 | p.StoreUndoState(UndoType.STATE_GROUP_ROTATION); |
377 | { | ||
378 | p.StoreUndoState(UndoType.STATE_GROUP_ROTATION); | ||
379 | } | ||
380 | } | ||
381 | finally | ||
382 | { | ||
383 | lockPartsForRead(false); | ||
384 | } | 290 | } |
385 | m_rotation = value; | 291 | m_rotation = value; |
386 | } | 292 | } |
@@ -397,16 +303,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
397 | set { m_rootPart.GroupID = value; } | 303 | set { m_rootPart.GroupID = value; } |
398 | } | 304 | } |
399 | 305 | ||
400 | /// <value> | 306 | public SceneObjectPart[] Parts |
401 | /// The parts of this scene object group. You must lock this property before using it. | 307 | { |
402 | /// If you're doing anything other than reading values, please take a copy of the values rather than locking | 308 | get { return m_parts.GetArray(); } |
403 | /// the dictionary for the entirety of the operation. This increases liveness and reduces the danger of deadlock | 309 | } |
404 | /// If you want to know the number of children, consider using the PrimCount property instead | 310 | |
405 | /// </value> | 311 | public bool ContainsPart(UUID partID) |
406 | public Dictionary<UUID, SceneObjectPart> Children | ||
407 | { | 312 | { |
408 | get { return m_parts; } | 313 | return m_parts.ContainsKey(partID); |
409 | set { m_parts = value; } | ||
410 | } | 314 | } |
411 | 315 | ||
412 | /// <value> | 316 | /// <value> |
@@ -423,16 +327,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
423 | set | 327 | set |
424 | { | 328 | { |
425 | m_regionHandle = value; | 329 | m_regionHandle = value; |
426 | lockPartsForRead(true); | 330 | SceneObjectPart[] parts = m_parts.GetArray(); |
427 | { | 331 | for (int i = 0; i < parts.Length; i++) |
428 | foreach (SceneObjectPart part in m_parts.Values) | 332 | parts[i].RegionHandle = value; |
429 | { | ||
430 | |||
431 | part.RegionHandle = m_regionHandle; | ||
432 | |||
433 | } | ||
434 | } | ||
435 | lockPartsForRead(false); | ||
436 | } | 333 | } |
437 | } | 334 | } |
438 | 335 | ||
@@ -467,8 +364,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
467 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 364 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); |
468 | } | 365 | } |
469 | 366 | ||
470 | lockPartsForRead(true); | 367 | foreach (SceneObjectPart part in m_parts.GetArray()) |
471 | foreach (SceneObjectPart part in m_parts.Values) | ||
472 | { | 368 | { |
473 | part.IgnoreUndoUpdate = true; | 369 | part.IgnoreUndoUpdate = true; |
474 | } | 370 | } |
@@ -479,12 +375,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
479 | RootPart.ScriptSetPhysicsStatus(false); | 375 | RootPart.ScriptSetPhysicsStatus(false); |
480 | Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), | 376 | Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), |
481 | ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); | 377 | ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); |
482 | lockPartsForRead(false); | ||
483 | return; | 378 | return; |
484 | } | 379 | } |
485 | } | 380 | } |
486 | List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values); | 381 | SceneObjectPart[] parts = m_parts.GetArray(); |
487 | lockPartsForRead(false); | ||
488 | foreach (SceneObjectPart part in parts) | 382 | foreach (SceneObjectPart part in parts) |
489 | { | 383 | { |
490 | part.IgnoreUndoUpdate = false; | 384 | part.IgnoreUndoUpdate = false; |
@@ -499,10 +393,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
499 | { | 393 | { |
500 | foreach (ScenePresence av in m_linkedAvatars) | 394 | foreach (ScenePresence av in m_linkedAvatars) |
501 | { | 395 | { |
502 | Vector3 offset = m_parts[av.LinkedPrim].GetWorldPosition() - av.ParentPosition; | 396 | SceneObjectPart p; |
503 | av.AbsolutePosition += offset; | 397 | if (m_parts.TryGetValue(av.LinkedPrim, out p)) |
504 | av.ParentPosition = m_parts[av.LinkedPrim].GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition | 398 | { |
505 | av.SendFullUpdateToAllClients(); | 399 | Vector3 offset = p.GetWorldPosition() - av.ParentPosition; |
400 | av.AbsolutePosition += offset; | ||
401 | av.ParentPosition = p.GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition | ||
402 | av.SendFullUpdateToAllClients(); | ||
403 | } | ||
506 | } | 404 | } |
507 | } | 405 | } |
508 | 406 | ||
@@ -526,14 +424,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
526 | { | 424 | { |
527 | get { return m_rootPart.UUID; } | 425 | get { return m_rootPart.UUID; } |
528 | set | 426 | set |
529 | { | 427 | { |
530 | m_rootPart.UUID = value; | 428 | m_rootPart.UUID = value; |
531 | 429 | m_parts.AddOrReplace(value, m_rootPart); | |
532 | lock (m_parts) | ||
533 | { | ||
534 | m_parts.Remove(m_rootPart.UUID); | ||
535 | m_parts.Add(m_rootPart.UUID, m_rootPart); | ||
536 | } | ||
537 | } | 430 | } |
538 | } | 431 | } |
539 | 432 | ||
@@ -595,12 +488,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
595 | { | 488 | { |
596 | m_rootPart.PhysActor.Selected = value; | 489 | m_rootPart.PhysActor.Selected = value; |
597 | // Pass it on to the children. | 490 | // Pass it on to the children. |
598 | foreach (SceneObjectPart child in Children.Values) | 491 | SceneObjectPart[] parts = m_parts.GetArray(); |
492 | for (int i = 0; i < parts.Length; i++) | ||
599 | { | 493 | { |
494 | SceneObjectPart child = parts[i]; | ||
600 | if (child.PhysActor != null) | 495 | if (child.PhysActor != null) |
601 | { | ||
602 | child.PhysActor.Selected = value; | 496 | child.PhysActor.Selected = value; |
603 | } | ||
604 | } | 497 | } |
605 | } | 498 | } |
606 | } | 499 | } |
@@ -704,16 +597,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
704 | 597 | ||
705 | public void SetFromItemID(UUID AssetId) | 598 | public void SetFromItemID(UUID AssetId) |
706 | { | 599 | { |
707 | lockPartsForRead(true); | 600 | SceneObjectPart[] parts = m_parts.GetArray(); |
708 | { | 601 | for (int i = 0; i < parts.Length; i++) |
709 | foreach (SceneObjectPart part in m_parts.Values) | 602 | parts[i].FromItemID = AssetId; |
710 | { | ||
711 | |||
712 | part.FromItemID = AssetId; | ||
713 | |||
714 | } | ||
715 | } | ||
716 | lockPartsForRead(false); | ||
717 | } | 603 | } |
718 | 604 | ||
719 | public UUID GetFromItemID() | 605 | public UUID GetFromItemID() |
@@ -755,23 +641,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
755 | if (m_rootPart.LocalId == 0) | 641 | if (m_rootPart.LocalId == 0) |
756 | m_rootPart.LocalId = m_scene.AllocateLocalId(); | 642 | m_rootPart.LocalId = m_scene.AllocateLocalId(); |
757 | 643 | ||
758 | lock (m_parts) | 644 | SceneObjectPart[] parts = m_parts.GetArray(); |
645 | for (int i = 0; i < parts.Length; i++) | ||
759 | { | 646 | { |
760 | foreach (SceneObjectPart part in m_parts.Values) | 647 | SceneObjectPart part = parts[i]; |
761 | { | 648 | if (Object.ReferenceEquals(part, m_rootPart)) |
762 | if (Object.ReferenceEquals(part, m_rootPart)) | 649 | continue; |
763 | { | 650 | |
764 | continue; | 651 | if (part.LocalId == 0) |
765 | } | 652 | part.LocalId = m_scene.AllocateLocalId(); |
766 | 653 | ||
767 | if (part.LocalId == 0) | 654 | part.ParentID = m_rootPart.LocalId; |
768 | { | 655 | //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); |
769 | part.LocalId = m_scene.AllocateLocalId(); | ||
770 | } | ||
771 | |||
772 | part.ParentID = m_rootPart.LocalId; | ||
773 | //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); | ||
774 | } | ||
775 | } | 656 | } |
776 | 657 | ||
777 | ApplyPhysics(m_scene.m_physicalPrim); | 658 | ApplyPhysics(m_scene.m_physicalPrim); |
@@ -787,24 +668,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
787 | Vector3 maxScale = Vector3.Zero; | 668 | Vector3 maxScale = Vector3.Zero; |
788 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | 669 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); |
789 | 670 | ||
790 | lockPartsForRead(true); | 671 | SceneObjectPart[] parts = m_parts.GetArray(); |
672 | for (int i = 0; i < parts.Length; i++) | ||
791 | { | 673 | { |
792 | foreach (SceneObjectPart part in m_parts.Values) | 674 | SceneObjectPart part = parts[i]; |
793 | { | 675 | Vector3 partscale = part.Scale; |
794 | Vector3 partscale = part.Scale; | 676 | Vector3 partoffset = part.OffsetPosition; |
795 | Vector3 partoffset = part.OffsetPosition; | ||
796 | 677 | ||
797 | minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; | 678 | minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; |
798 | minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; | 679 | minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; |
799 | minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; | 680 | minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; |
800 | 681 | ||
801 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; | 682 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; |
802 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; | 683 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; |
803 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; | 684 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; |
804 | |||
805 | } | ||
806 | } | 685 | } |
807 | lockPartsForRead(false); | ||
808 | 686 | ||
809 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; | 687 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; |
810 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; | 688 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; |
@@ -821,42 +699,40 @@ namespace OpenSim.Region.Framework.Scenes | |||
821 | 699 | ||
822 | EntityIntersection result = new EntityIntersection(); | 700 | EntityIntersection result = new EntityIntersection(); |
823 | 701 | ||
824 | lockPartsForRead(true); | 702 | SceneObjectPart[] parts = m_parts.GetArray(); |
703 | for (int i = 0; i < parts.Length; i++) | ||
825 | { | 704 | { |
826 | foreach (SceneObjectPart part in m_parts.Values) | 705 | SceneObjectPart part = parts[i]; |
827 | { | 706 | |
828 | 707 | // Temporary commented to stop compiler warning | |
829 | // Temporary commented to stop compiler warning | 708 | //Vector3 partPosition = |
830 | //Vector3 partPosition = | 709 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); |
831 | // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); | 710 | Quaternion parentrotation = GroupRotation; |
832 | Quaternion parentrotation = GroupRotation; | ||
833 | 711 | ||
834 | // Telling the prim to raytrace. | 712 | // Telling the prim to raytrace. |
835 | //EntityIntersection inter = part.TestIntersection(hRay, parentrotation); | 713 | //EntityIntersection inter = part.TestIntersection(hRay, parentrotation); |
836 | 714 | ||
837 | EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation,frontFacesOnly, faceCenters); | 715 | EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation, frontFacesOnly, faceCenters); |
838 | 716 | ||
839 | // This may need to be updated to the maximum draw distance possible.. | 717 | // This may need to be updated to the maximum draw distance possible.. |
840 | // We might (and probably will) be checking for prim creation from other sims | 718 | // We might (and probably will) be checking for prim creation from other sims |
841 | // when the camera crosses the border. | 719 | // when the camera crosses the border. |
842 | float idist = Constants.RegionSize; | 720 | float idist = Constants.RegionSize; |
843 | 721 | ||
844 | if (inter.HitTF) | 722 | if (inter.HitTF) |
723 | { | ||
724 | // We need to find the closest prim to return to the testcaller along the ray | ||
725 | if (inter.distance < idist) | ||
845 | { | 726 | { |
846 | // We need to find the closest prim to return to the testcaller along the ray | 727 | result.HitTF = true; |
847 | if (inter.distance < idist) | 728 | result.ipoint = inter.ipoint; |
848 | { | 729 | result.obj = part; |
849 | result.HitTF = true; | 730 | result.normal = inter.normal; |
850 | result.ipoint = inter.ipoint; | 731 | result.distance = inter.distance; |
851 | result.obj = part; | ||
852 | result.normal = inter.normal; | ||
853 | result.distance = inter.distance; | ||
854 | } | ||
855 | } | 732 | } |
856 | 733 | ||
857 | } | 734 | } |
858 | } | 735 | } |
859 | lockPartsForRead(false); | ||
860 | return result; | 736 | return result; |
861 | } | 737 | } |
862 | 738 | ||
@@ -875,243 +751,239 @@ namespace OpenSim.Region.Framework.Scenes | |||
875 | minY = 256f; | 751 | minY = 256f; |
876 | minZ = 8192f; | 752 | minZ = 8192f; |
877 | 753 | ||
878 | lockPartsForRead(true); | 754 | SceneObjectPart[] parts = m_parts.GetArray(); |
755 | foreach (SceneObjectPart part in parts) | ||
879 | { | 756 | { |
880 | foreach (SceneObjectPart part in m_parts.Values) | 757 | Vector3 worldPos = part.GetWorldPosition(); |
758 | Vector3 offset = worldPos - AbsolutePosition; | ||
759 | Quaternion worldRot; | ||
760 | if (part.ParentID == 0) | ||
881 | { | 761 | { |
882 | 762 | worldRot = part.RotationOffset; | |
883 | Vector3 worldPos = part.GetWorldPosition(); | 763 | } |
884 | Vector3 offset = worldPos - AbsolutePosition; | 764 | else |
885 | Quaternion worldRot; | 765 | { |
886 | if (part.ParentID == 0) | 766 | worldRot = part.GetWorldRotation(); |
887 | { | 767 | } |
888 | worldRot = part.RotationOffset; | ||
889 | } | ||
890 | else | ||
891 | { | ||
892 | worldRot = part.GetWorldRotation(); | ||
893 | } | ||
894 | 768 | ||
895 | Vector3 frontTopLeft; | 769 | Vector3 frontTopLeft; |
896 | Vector3 frontTopRight; | 770 | Vector3 frontTopRight; |
897 | Vector3 frontBottomLeft; | 771 | Vector3 frontBottomLeft; |
898 | Vector3 frontBottomRight; | 772 | Vector3 frontBottomRight; |
899 | 773 | ||
900 | Vector3 backTopLeft; | 774 | Vector3 backTopLeft; |
901 | Vector3 backTopRight; | 775 | Vector3 backTopRight; |
902 | Vector3 backBottomLeft; | 776 | Vector3 backBottomLeft; |
903 | Vector3 backBottomRight; | 777 | Vector3 backBottomRight; |
904 | 778 | ||
905 | // Vector3[] corners = new Vector3[8]; | 779 | // Vector3[] corners = new Vector3[8]; |
906 | 780 | ||
907 | Vector3 orig = Vector3.Zero; | 781 | Vector3 orig = Vector3.Zero; |
908 | 782 | ||
909 | frontTopLeft.X = orig.X - (part.Scale.X / 2); | 783 | frontTopLeft.X = orig.X - (part.Scale.X / 2); |
910 | frontTopLeft.Y = orig.Y - (part.Scale.Y / 2); | 784 | frontTopLeft.Y = orig.Y - (part.Scale.Y / 2); |
911 | frontTopLeft.Z = orig.Z + (part.Scale.Z / 2); | 785 | frontTopLeft.Z = orig.Z + (part.Scale.Z / 2); |
912 | 786 | ||
913 | frontTopRight.X = orig.X - (part.Scale.X / 2); | 787 | frontTopRight.X = orig.X - (part.Scale.X / 2); |
914 | frontTopRight.Y = orig.Y + (part.Scale.Y / 2); | 788 | frontTopRight.Y = orig.Y + (part.Scale.Y / 2); |
915 | frontTopRight.Z = orig.Z + (part.Scale.Z / 2); | 789 | frontTopRight.Z = orig.Z + (part.Scale.Z / 2); |
916 | 790 | ||
917 | frontBottomLeft.X = orig.X - (part.Scale.X / 2); | 791 | frontBottomLeft.X = orig.X - (part.Scale.X / 2); |
918 | frontBottomLeft.Y = orig.Y - (part.Scale.Y / 2); | 792 | frontBottomLeft.Y = orig.Y - (part.Scale.Y / 2); |
919 | frontBottomLeft.Z = orig.Z - (part.Scale.Z / 2); | 793 | frontBottomLeft.Z = orig.Z - (part.Scale.Z / 2); |
920 | 794 | ||
921 | frontBottomRight.X = orig.X - (part.Scale.X / 2); | 795 | frontBottomRight.X = orig.X - (part.Scale.X / 2); |
922 | frontBottomRight.Y = orig.Y + (part.Scale.Y / 2); | 796 | frontBottomRight.Y = orig.Y + (part.Scale.Y / 2); |
923 | frontBottomRight.Z = orig.Z - (part.Scale.Z / 2); | 797 | frontBottomRight.Z = orig.Z - (part.Scale.Z / 2); |
924 | 798 | ||
925 | backTopLeft.X = orig.X + (part.Scale.X / 2); | 799 | backTopLeft.X = orig.X + (part.Scale.X / 2); |
926 | backTopLeft.Y = orig.Y - (part.Scale.Y / 2); | 800 | backTopLeft.Y = orig.Y - (part.Scale.Y / 2); |
927 | backTopLeft.Z = orig.Z + (part.Scale.Z / 2); | 801 | backTopLeft.Z = orig.Z + (part.Scale.Z / 2); |
928 | 802 | ||
929 | backTopRight.X = orig.X + (part.Scale.X / 2); | 803 | backTopRight.X = orig.X + (part.Scale.X / 2); |
930 | backTopRight.Y = orig.Y + (part.Scale.Y / 2); | 804 | backTopRight.Y = orig.Y + (part.Scale.Y / 2); |
931 | backTopRight.Z = orig.Z + (part.Scale.Z / 2); | 805 | backTopRight.Z = orig.Z + (part.Scale.Z / 2); |
932 | 806 | ||
933 | backBottomLeft.X = orig.X + (part.Scale.X / 2); | 807 | backBottomLeft.X = orig.X + (part.Scale.X / 2); |
934 | backBottomLeft.Y = orig.Y - (part.Scale.Y / 2); | 808 | backBottomLeft.Y = orig.Y - (part.Scale.Y / 2); |
935 | backBottomLeft.Z = orig.Z - (part.Scale.Z / 2); | 809 | backBottomLeft.Z = orig.Z - (part.Scale.Z / 2); |
936 | 810 | ||
937 | backBottomRight.X = orig.X + (part.Scale.X / 2); | 811 | backBottomRight.X = orig.X + (part.Scale.X / 2); |
938 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); | 812 | backBottomRight.Y = orig.Y + (part.Scale.Y / 2); |
939 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); | 813 | backBottomRight.Z = orig.Z - (part.Scale.Z / 2); |
940 | 814 | ||
941 | 815 | ||
942 | 816 | ||
943 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); | 817 | //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); |
944 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); | 818 | //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); |
945 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); | 819 | //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); |
946 | //m_log.InfoFormat("pre corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z); | 820 | //m_log.InfoFormat("pre corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z); |
947 | //m_log.InfoFormat("pre corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z); | 821 | //m_log.InfoFormat("pre corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z); |
948 | //m_log.InfoFormat("pre corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z); | 822 | //m_log.InfoFormat("pre corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z); |
949 | //m_log.InfoFormat("pre corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z); | 823 | //m_log.InfoFormat("pre corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z); |
950 | //m_log.InfoFormat("pre corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z); | 824 | //m_log.InfoFormat("pre corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z); |
951 | |||
952 | //for (int i = 0; i < 8; i++) | ||
953 | //{ | ||
954 | // corners[i] = corners[i] * worldRot; | ||
955 | // corners[i] += offset; | ||
956 | |||
957 | // if (corners[i].X > maxX) | ||
958 | // maxX = corners[i].X; | ||
959 | // if (corners[i].X < minX) | ||
960 | // minX = corners[i].X; | ||
961 | |||
962 | // if (corners[i].Y > maxY) | ||
963 | // maxY = corners[i].Y; | ||
964 | // if (corners[i].Y < minY) | ||
965 | // minY = corners[i].Y; | ||
966 | |||
967 | // if (corners[i].Z > maxZ) | ||
968 | // maxZ = corners[i].Y; | ||
969 | // if (corners[i].Z < minZ) | ||
970 | // minZ = corners[i].Z; | ||
971 | //} | ||
972 | |||
973 | frontTopLeft = frontTopLeft * worldRot; | ||
974 | frontTopRight = frontTopRight * worldRot; | ||
975 | frontBottomLeft = frontBottomLeft * worldRot; | ||
976 | frontBottomRight = frontBottomRight * worldRot; | ||
977 | |||
978 | backBottomLeft = backBottomLeft * worldRot; | ||
979 | backBottomRight = backBottomRight * worldRot; | ||
980 | backTopLeft = backTopLeft * worldRot; | ||
981 | backTopRight = backTopRight * worldRot; | ||
982 | |||
983 | |||
984 | frontTopLeft += offset; | ||
985 | frontTopRight += offset; | ||
986 | frontBottomLeft += offset; | ||
987 | frontBottomRight += offset; | ||
988 | |||
989 | backBottomLeft += offset; | ||
990 | backBottomRight += offset; | ||
991 | backTopLeft += offset; | ||
992 | backTopRight += offset; | ||
993 | |||
994 | //m_log.InfoFormat("corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); | ||
995 | //m_log.InfoFormat("corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); | ||
996 | //m_log.InfoFormat("corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); | ||
997 | //m_log.InfoFormat("corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z); | ||
998 | //m_log.InfoFormat("corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z); | ||
999 | //m_log.InfoFormat("corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z); | ||
1000 | //m_log.InfoFormat("corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z); | ||
1001 | //m_log.InfoFormat("corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z); | ||
1002 | |||
1003 | if (frontTopRight.X > maxX) | ||
1004 | maxX = frontTopRight.X; | ||
1005 | if (frontTopLeft.X > maxX) | ||
1006 | maxX = frontTopLeft.X; | ||
1007 | if (frontBottomRight.X > maxX) | ||
1008 | maxX = frontBottomRight.X; | ||
1009 | if (frontBottomLeft.X > maxX) | ||
1010 | maxX = frontBottomLeft.X; | ||
1011 | |||
1012 | if (backTopRight.X > maxX) | ||
1013 | maxX = backTopRight.X; | ||
1014 | if (backTopLeft.X > maxX) | ||
1015 | maxX = backTopLeft.X; | ||
1016 | if (backBottomRight.X > maxX) | ||
1017 | maxX = backBottomRight.X; | ||
1018 | if (backBottomLeft.X > maxX) | ||
1019 | maxX = backBottomLeft.X; | ||
1020 | |||
1021 | if (frontTopRight.X < minX) | ||
1022 | minX = frontTopRight.X; | ||
1023 | if (frontTopLeft.X < minX) | ||
1024 | minX = frontTopLeft.X; | ||
1025 | if (frontBottomRight.X < minX) | ||
1026 | minX = frontBottomRight.X; | ||
1027 | if (frontBottomLeft.X < minX) | ||
1028 | minX = frontBottomLeft.X; | ||
1029 | |||
1030 | if (backTopRight.X < minX) | ||
1031 | minX = backTopRight.X; | ||
1032 | if (backTopLeft.X < minX) | ||
1033 | minX = backTopLeft.X; | ||
1034 | if (backBottomRight.X < minX) | ||
1035 | minX = backBottomRight.X; | ||
1036 | if (backBottomLeft.X < minX) | ||
1037 | minX = backBottomLeft.X; | ||
1038 | 825 | ||
1039 | // | 826 | //for (int i = 0; i < 8; i++) |
1040 | if (frontTopRight.Y > maxY) | 827 | //{ |
1041 | maxY = frontTopRight.Y; | 828 | // corners[i] = corners[i] * worldRot; |
1042 | if (frontTopLeft.Y > maxY) | 829 | // corners[i] += offset; |
1043 | maxY = frontTopLeft.Y; | 830 | |
1044 | if (frontBottomRight.Y > maxY) | 831 | // if (corners[i].X > maxX) |
1045 | maxY = frontBottomRight.Y; | 832 | // maxX = corners[i].X; |
1046 | if (frontBottomLeft.Y > maxY) | 833 | // if (corners[i].X < minX) |
1047 | maxY = frontBottomLeft.Y; | 834 | // minX = corners[i].X; |
1048 | 835 | ||
1049 | if (backTopRight.Y > maxY) | 836 | // if (corners[i].Y > maxY) |
1050 | maxY = backTopRight.Y; | 837 | // maxY = corners[i].Y; |
1051 | if (backTopLeft.Y > maxY) | 838 | // if (corners[i].Y < minY) |
1052 | maxY = backTopLeft.Y; | 839 | // minY = corners[i].Y; |
1053 | if (backBottomRight.Y > maxY) | 840 | |
1054 | maxY = backBottomRight.Y; | 841 | // if (corners[i].Z > maxZ) |
1055 | if (backBottomLeft.Y > maxY) | 842 | // maxZ = corners[i].Y; |
1056 | maxY = backBottomLeft.Y; | 843 | // if (corners[i].Z < minZ) |
1057 | 844 | // minZ = corners[i].Z; | |
1058 | if (frontTopRight.Y < minY) | 845 | //} |
1059 | minY = frontTopRight.Y; | ||
1060 | if (frontTopLeft.Y < minY) | ||
1061 | minY = frontTopLeft.Y; | ||
1062 | if (frontBottomRight.Y < minY) | ||
1063 | minY = frontBottomRight.Y; | ||
1064 | if (frontBottomLeft.Y < minY) | ||
1065 | minY = frontBottomLeft.Y; | ||
1066 | |||
1067 | if (backTopRight.Y < minY) | ||
1068 | minY = backTopRight.Y; | ||
1069 | if (backTopLeft.Y < minY) | ||
1070 | minY = backTopLeft.Y; | ||
1071 | if (backBottomRight.Y < minY) | ||
1072 | minY = backBottomRight.Y; | ||
1073 | if (backBottomLeft.Y < minY) | ||
1074 | minY = backBottomLeft.Y; | ||
1075 | 846 | ||
1076 | // | 847 | frontTopLeft = frontTopLeft * worldRot; |
1077 | if (frontTopRight.Z > maxZ) | 848 | frontTopRight = frontTopRight * worldRot; |
1078 | maxZ = frontTopRight.Z; | 849 | frontBottomLeft = frontBottomLeft * worldRot; |
1079 | if (frontTopLeft.Z > maxZ) | 850 | frontBottomRight = frontBottomRight * worldRot; |
1080 | maxZ = frontTopLeft.Z; | 851 | |
1081 | if (frontBottomRight.Z > maxZ) | 852 | backBottomLeft = backBottomLeft * worldRot; |
1082 | maxZ = frontBottomRight.Z; | 853 | backBottomRight = backBottomRight * worldRot; |
1083 | if (frontBottomLeft.Z > maxZ) | 854 | backTopLeft = backTopLeft * worldRot; |
1084 | maxZ = frontBottomLeft.Z; | 855 | backTopRight = backTopRight * worldRot; |
1085 | 856 | ||
1086 | if (backTopRight.Z > maxZ) | 857 | |
1087 | maxZ = backTopRight.Z; | 858 | frontTopLeft += offset; |
1088 | if (backTopLeft.Z > maxZ) | 859 | frontTopRight += offset; |
1089 | maxZ = backTopLeft.Z; | 860 | frontBottomLeft += offset; |
1090 | if (backBottomRight.Z > maxZ) | 861 | frontBottomRight += offset; |
1091 | maxZ = backBottomRight.Z; | 862 | |
1092 | if (backBottomLeft.Z > maxZ) | 863 | backBottomLeft += offset; |
1093 | maxZ = backBottomLeft.Z; | 864 | backBottomRight += offset; |
1094 | 865 | backTopLeft += offset; | |
1095 | if (frontTopRight.Z < minZ) | 866 | backTopRight += offset; |
1096 | minZ = frontTopRight.Z; | 867 | |
1097 | if (frontTopLeft.Z < minZ) | 868 | //m_log.InfoFormat("corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); |
1098 | minZ = frontTopLeft.Z; | 869 | //m_log.InfoFormat("corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); |
1099 | if (frontBottomRight.Z < minZ) | 870 | //m_log.InfoFormat("corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); |
1100 | minZ = frontBottomRight.Z; | 871 | //m_log.InfoFormat("corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z); |
1101 | if (frontBottomLeft.Z < minZ) | 872 | //m_log.InfoFormat("corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z); |
1102 | minZ = frontBottomLeft.Z; | 873 | //m_log.InfoFormat("corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z); |
1103 | 874 | //m_log.InfoFormat("corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z); | |
1104 | if (backTopRight.Z < minZ) | 875 | //m_log.InfoFormat("corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z); |
1105 | minZ = backTopRight.Z; | 876 | |
1106 | if (backTopLeft.Z < minZ) | 877 | if (frontTopRight.X > maxX) |
1107 | minZ = backTopLeft.Z; | 878 | maxX = frontTopRight.X; |
1108 | if (backBottomRight.Z < minZ) | 879 | if (frontTopLeft.X > maxX) |
1109 | minZ = backBottomRight.Z; | 880 | maxX = frontTopLeft.X; |
1110 | if (backBottomLeft.Z < minZ) | 881 | if (frontBottomRight.X > maxX) |
1111 | minZ = backBottomLeft.Z; | 882 | maxX = frontBottomRight.X; |
1112 | } | 883 | if (frontBottomLeft.X > maxX) |
884 | maxX = frontBottomLeft.X; | ||
885 | |||
886 | if (backTopRight.X > maxX) | ||
887 | maxX = backTopRight.X; | ||
888 | if (backTopLeft.X > maxX) | ||
889 | maxX = backTopLeft.X; | ||
890 | if (backBottomRight.X > maxX) | ||
891 | maxX = backBottomRight.X; | ||
892 | if (backBottomLeft.X > maxX) | ||
893 | maxX = backBottomLeft.X; | ||
894 | |||
895 | if (frontTopRight.X < minX) | ||
896 | minX = frontTopRight.X; | ||
897 | if (frontTopLeft.X < minX) | ||
898 | minX = frontTopLeft.X; | ||
899 | if (frontBottomRight.X < minX) | ||
900 | minX = frontBottomRight.X; | ||
901 | if (frontBottomLeft.X < minX) | ||
902 | minX = frontBottomLeft.X; | ||
903 | |||
904 | if (backTopRight.X < minX) | ||
905 | minX = backTopRight.X; | ||
906 | if (backTopLeft.X < minX) | ||
907 | minX = backTopLeft.X; | ||
908 | if (backBottomRight.X < minX) | ||
909 | minX = backBottomRight.X; | ||
910 | if (backBottomLeft.X < minX) | ||
911 | minX = backBottomLeft.X; | ||
912 | |||
913 | // | ||
914 | if (frontTopRight.Y > maxY) | ||
915 | maxY = frontTopRight.Y; | ||
916 | if (frontTopLeft.Y > maxY) | ||
917 | maxY = frontTopLeft.Y; | ||
918 | if (frontBottomRight.Y > maxY) | ||
919 | maxY = frontBottomRight.Y; | ||
920 | if (frontBottomLeft.Y > maxY) | ||
921 | maxY = frontBottomLeft.Y; | ||
922 | |||
923 | if (backTopRight.Y > maxY) | ||
924 | maxY = backTopRight.Y; | ||
925 | if (backTopLeft.Y > maxY) | ||
926 | maxY = backTopLeft.Y; | ||
927 | if (backBottomRight.Y > maxY) | ||
928 | maxY = backBottomRight.Y; | ||
929 | if (backBottomLeft.Y > maxY) | ||
930 | maxY = backBottomLeft.Y; | ||
931 | |||
932 | if (frontTopRight.Y < minY) | ||
933 | minY = frontTopRight.Y; | ||
934 | if (frontTopLeft.Y < minY) | ||
935 | minY = frontTopLeft.Y; | ||
936 | if (frontBottomRight.Y < minY) | ||
937 | minY = frontBottomRight.Y; | ||
938 | if (frontBottomLeft.Y < minY) | ||
939 | minY = frontBottomLeft.Y; | ||
940 | |||
941 | if (backTopRight.Y < minY) | ||
942 | minY = backTopRight.Y; | ||
943 | if (backTopLeft.Y < minY) | ||
944 | minY = backTopLeft.Y; | ||
945 | if (backBottomRight.Y < minY) | ||
946 | minY = backBottomRight.Y; | ||
947 | if (backBottomLeft.Y < minY) | ||
948 | minY = backBottomLeft.Y; | ||
949 | |||
950 | // | ||
951 | if (frontTopRight.Z > maxZ) | ||
952 | maxZ = frontTopRight.Z; | ||
953 | if (frontTopLeft.Z > maxZ) | ||
954 | maxZ = frontTopLeft.Z; | ||
955 | if (frontBottomRight.Z > maxZ) | ||
956 | maxZ = frontBottomRight.Z; | ||
957 | if (frontBottomLeft.Z > maxZ) | ||
958 | maxZ = frontBottomLeft.Z; | ||
959 | |||
960 | if (backTopRight.Z > maxZ) | ||
961 | maxZ = backTopRight.Z; | ||
962 | if (backTopLeft.Z > maxZ) | ||
963 | maxZ = backTopLeft.Z; | ||
964 | if (backBottomRight.Z > maxZ) | ||
965 | maxZ = backBottomRight.Z; | ||
966 | if (backBottomLeft.Z > maxZ) | ||
967 | maxZ = backBottomLeft.Z; | ||
968 | |||
969 | if (frontTopRight.Z < minZ) | ||
970 | minZ = frontTopRight.Z; | ||
971 | if (frontTopLeft.Z < minZ) | ||
972 | minZ = frontTopLeft.Z; | ||
973 | if (frontBottomRight.Z < minZ) | ||
974 | minZ = frontBottomRight.Z; | ||
975 | if (frontBottomLeft.Z < minZ) | ||
976 | minZ = frontBottomLeft.Z; | ||
977 | |||
978 | if (backTopRight.Z < minZ) | ||
979 | minZ = backTopRight.Z; | ||
980 | if (backTopLeft.Z < minZ) | ||
981 | minZ = backTopLeft.Z; | ||
982 | if (backBottomRight.Z < minZ) | ||
983 | minZ = backBottomRight.Z; | ||
984 | if (backBottomLeft.Z < minZ) | ||
985 | minZ = backBottomLeft.Z; | ||
1113 | } | 986 | } |
1114 | lockPartsForRead(false); | ||
1115 | } | 987 | } |
1116 | 988 | ||
1117 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) | 989 | public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) |
@@ -1155,21 +1027,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1155 | XmlDocument doc = new XmlDocument(); | 1027 | XmlDocument doc = new XmlDocument(); |
1156 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); | 1028 | Dictionary<UUID,string> states = new Dictionary<UUID,string>(); |
1157 | 1029 | ||
1158 | // Capture script state while holding the lock | 1030 | SceneObjectPart[] parts = m_parts.GetArray(); |
1159 | lockPartsForRead(true); | 1031 | for (int i = 0; i < parts.Length; i++) |
1160 | { | 1032 | { |
1161 | foreach (SceneObjectPart part in m_parts.Values) | 1033 | Dictionary<UUID, string> pstates = parts[i].Inventory.GetScriptStates(); |
1162 | { | 1034 | foreach (KeyValuePair<UUID, string> kvp in pstates) |
1163 | 1035 | states.Add(kvp.Key, kvp.Value); | |
1164 | Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(oldIDs); | ||
1165 | foreach (UUID itemid in pstates.Keys) | ||
1166 | { | ||
1167 | states.Add(itemid, pstates[itemid]); | ||
1168 | } | ||
1169 | |||
1170 | } | ||
1171 | } | 1036 | } |
1172 | lockPartsForRead(false); | ||
1173 | 1037 | ||
1174 | if (states.Count > 0) | 1038 | if (states.Count > 0) |
1175 | { | 1039 | { |
@@ -1255,7 +1119,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1255 | //Anakin Lohner bug #3839 | 1119 | //Anakin Lohner bug #3839 |
1256 | lock (m_parts) | 1120 | lock (m_parts) |
1257 | { | 1121 | { |
1258 | foreach (SceneObjectPart p in m_parts.Values) | 1122 | foreach (SceneObjectPart p in m_parts.GetArray()) |
1259 | { | 1123 | { |
1260 | p.AttachedAvatar = agentID; | 1124 | p.AttachedAvatar = agentID; |
1261 | } | 1125 | } |
@@ -1326,15 +1190,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1326 | 1190 | ||
1327 | AbsolutePosition = detachedpos; | 1191 | AbsolutePosition = detachedpos; |
1328 | m_rootPart.AttachedAvatar = UUID.Zero; | 1192 | m_rootPart.AttachedAvatar = UUID.Zero; |
1329 | 1193 | ||
1330 | //Anakin Lohner bug #3839 | 1194 | SceneObjectPart[] parts = m_parts.GetArray(); |
1331 | lock (m_parts) | 1195 | for (int i = 0; i < parts.Length; i++) |
1332 | { | 1196 | parts[i].AttachedAvatar = UUID.Zero; |
1333 | foreach (SceneObjectPart p in m_parts.Values) | ||
1334 | { | ||
1335 | p.AttachedAvatar = UUID.Zero; | ||
1336 | } | ||
1337 | } | ||
1338 | 1197 | ||
1339 | m_rootPart.SetParentLocalId(0); | 1198 | m_rootPart.SetParentLocalId(0); |
1340 | SetAttachmentPoint((byte)0); | 1199 | SetAttachmentPoint((byte)0); |
@@ -1359,15 +1218,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1359 | } | 1218 | } |
1360 | 1219 | ||
1361 | m_rootPart.AttachedAvatar = UUID.Zero; | 1220 | m_rootPart.AttachedAvatar = UUID.Zero; |
1362 | 1221 | ||
1363 | //Anakin Lohner bug #3839 | 1222 | SceneObjectPart[] parts = m_parts.GetArray(); |
1364 | lock (m_parts) | 1223 | for (int i = 0; i < parts.Length; i++) |
1365 | { | 1224 | parts[i].AttachedAvatar = UUID.Zero; |
1366 | foreach (SceneObjectPart p in m_parts.Values) | ||
1367 | { | ||
1368 | p.AttachedAvatar = UUID.Zero; | ||
1369 | } | ||
1370 | } | ||
1371 | 1225 | ||
1372 | m_rootPart.SetParentLocalId(0); | 1226 | m_rootPart.SetParentLocalId(0); |
1373 | //m_rootPart.SetAttachmentPoint((byte)0); | 1227 | //m_rootPart.SetAttachmentPoint((byte)0); |
@@ -1390,16 +1244,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1390 | 1244 | ||
1391 | public override void UpdateMovement() | 1245 | public override void UpdateMovement() |
1392 | { | 1246 | { |
1393 | lockPartsForRead(true); | 1247 | SceneObjectPart[] parts = m_parts.GetArray(); |
1394 | { | 1248 | for (int i = 0; i < parts.Length; i++) |
1395 | foreach (SceneObjectPart part in m_parts.Values) | 1249 | parts[i].UpdateMovement(); |
1396 | { | ||
1397 | |||
1398 | part.UpdateMovement(); | ||
1399 | |||
1400 | } | ||
1401 | } | ||
1402 | lockPartsForRead(false); | ||
1403 | } | 1250 | } |
1404 | 1251 | ||
1405 | public ushort GetTimeDilation() | 1252 | public ushort GetTimeDilation() |
@@ -1432,8 +1279,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1432 | part.ParentID = 0; | 1279 | part.ParentID = 0; |
1433 | part.LinkNum = 0; | 1280 | part.LinkNum = 0; |
1434 | 1281 | ||
1435 | lock (m_parts) | 1282 | m_parts.Add(m_rootPart.UUID, m_rootPart); |
1436 | m_parts.Add(m_rootPart.UUID, m_rootPart); | ||
1437 | } | 1283 | } |
1438 | 1284 | ||
1439 | /// <summary> | 1285 | /// <summary> |
@@ -1442,17 +1288,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1442 | /// <param name="part"></param> | 1288 | /// <param name="part"></param> |
1443 | public void AddPart(SceneObjectPart part) | 1289 | public void AddPart(SceneObjectPart part) |
1444 | { | 1290 | { |
1445 | lockPartsForWrite(true); | 1291 | part.SetParent(this); |
1446 | { | 1292 | m_parts.Add(part.UUID, part); |
1447 | part.SetParent(this); | ||
1448 | m_parts.Add(part.UUID, part); | ||
1449 | 1293 | ||
1450 | part.LinkNum = m_parts.Count; | 1294 | part.LinkNum = m_parts.Count; |
1451 | 1295 | ||
1452 | if (part.LinkNum == 2 && RootPart != null) | 1296 | if (part.LinkNum == 2 && RootPart != null) |
1453 | RootPart.LinkNum = 1; | 1297 | RootPart.LinkNum = 1; |
1454 | } | ||
1455 | lockPartsForWrite(false); | ||
1456 | } | 1298 | } |
1457 | 1299 | ||
1458 | /// <summary> | 1300 | /// <summary> |
@@ -1460,33 +1302,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1460 | /// </summary> | 1302 | /// </summary> |
1461 | private void UpdateParentIDs() | 1303 | private void UpdateParentIDs() |
1462 | { | 1304 | { |
1463 | lockPartsForRead(true); | 1305 | SceneObjectPart[] parts = m_parts.GetArray(); |
1306 | for (int i = 0; i < parts.Length; i++) | ||
1464 | { | 1307 | { |
1465 | foreach (SceneObjectPart part in m_parts.Values) | 1308 | SceneObjectPart part = parts[i]; |
1466 | { | 1309 | if (part.UUID != m_rootPart.UUID) |
1467 | 1310 | part.ParentID = m_rootPart.LocalId; | |
1468 | if (part.UUID != m_rootPart.UUID) | ||
1469 | { | ||
1470 | part.ParentID = m_rootPart.LocalId; | ||
1471 | } | ||
1472 | |||
1473 | } | ||
1474 | } | 1311 | } |
1475 | lockPartsForRead(false); | ||
1476 | } | 1312 | } |
1477 | 1313 | ||
1478 | public void RegenerateFullIDs() | 1314 | public void RegenerateFullIDs() |
1479 | { | 1315 | { |
1480 | lockPartsForRead(true); | 1316 | SceneObjectPart[] parts = m_parts.GetArray(); |
1481 | { | 1317 | for (int i = 0; i < parts.Length; i++) |
1482 | foreach (SceneObjectPart part in m_parts.Values) | 1318 | parts[i].UUID = UUID.Random(); |
1483 | { | ||
1484 | |||
1485 | part.UUID = UUID.Random(); | ||
1486 | |||
1487 | } | ||
1488 | } | ||
1489 | lockPartsForRead(false); | ||
1490 | } | 1319 | } |
1491 | 1320 | ||
1492 | // helper provided for parts. | 1321 | // helper provided for parts. |
@@ -1519,7 +1348,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1519 | 1348 | ||
1520 | // teravus: AbsolutePosition is NOT a normal property! | 1349 | // teravus: AbsolutePosition is NOT a normal property! |
1521 | // the code in the getter of AbsolutePosition is significantly different then the code in the setter! | 1350 | // the code in the getter of AbsolutePosition is significantly different then the code in the setter! |
1522 | 1351 | // jhurliman: Then why is it a property instead of two methods? | |
1523 | } | 1352 | } |
1524 | 1353 | ||
1525 | public UUID GetPartsFullID(uint localID) | 1354 | public UUID GetPartsFullID(uint localID) |
@@ -1572,18 +1401,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1572 | 1401 | ||
1573 | DetachFromBackup(); | 1402 | DetachFromBackup(); |
1574 | 1403 | ||
1575 | lockPartsForRead(true); | 1404 | SceneObjectPart[] parts = m_parts.GetArray(); |
1576 | List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values); | 1405 | for (int i = 0; i < parts.Length; i++) |
1577 | lockPartsForRead(false); | ||
1578 | |||
1579 | foreach (SceneObjectPart part in parts) | ||
1580 | { | 1406 | { |
1581 | Scene.ForEachScenePresence(delegate (ScenePresence avatar) | 1407 | SceneObjectPart part = parts[i]; |
1408 | |||
1409 | Scene.ForEachScenePresence(delegate(ScenePresence avatar) | ||
1582 | { | 1410 | { |
1583 | if (avatar.ParentID == LocalId) | 1411 | if (avatar.ParentID == LocalId) |
1584 | { | ||
1585 | avatar.StandUp(); | 1412 | avatar.StandUp(); |
1586 | } | ||
1587 | 1413 | ||
1588 | if (!silent) | 1414 | if (!silent) |
1589 | { | 1415 | { |
@@ -1619,20 +1445,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1619 | 1445 | ||
1620 | scriptEvents aggregateScriptEvents = 0; | 1446 | scriptEvents aggregateScriptEvents = 0; |
1621 | 1447 | ||
1622 | lockPartsForRead(true); | 1448 | SceneObjectPart[] parts = m_parts.GetArray(); |
1449 | for (int i = 0; i < parts.Length; i++) | ||
1623 | { | 1450 | { |
1624 | foreach (SceneObjectPart part in m_parts.Values) | 1451 | SceneObjectPart part = parts[i]; |
1625 | { | 1452 | if (part == null) |
1626 | 1453 | continue; | |
1627 | if (part == null) | 1454 | if (part != RootPart) |
1628 | continue; | 1455 | part.Flags = objectflagupdate; |
1629 | if (part != RootPart) | 1456 | aggregateScriptEvents |= part.AggregateScriptEvents; |
1630 | part.Flags = objectflagupdate; | ||
1631 | aggregateScriptEvents |= part.AggregateScriptEvents; | ||
1632 | |||
1633 | } | ||
1634 | } | 1457 | } |
1635 | lockPartsForRead(false); | ||
1636 | 1458 | ||
1637 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); | 1459 | m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); |
1638 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); | 1460 | m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); |
@@ -1674,30 +1496,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
1674 | /// <param name="m_physicalPrim"></param> | 1496 | /// <param name="m_physicalPrim"></param> |
1675 | public void ApplyPhysics(bool m_physicalPrim) | 1497 | public void ApplyPhysics(bool m_physicalPrim) |
1676 | { | 1498 | { |
1677 | lockPartsForRead(true); | 1499 | // Apply physics to the root prim |
1500 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1678 | 1501 | ||
1679 | if (m_parts.Count > 1) | 1502 | // Apply physics to child prims |
1503 | SceneObjectPart[] parts = m_parts.GetArray(); | ||
1504 | if (parts.Length > 1) | ||
1680 | { | 1505 | { |
1681 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | 1506 | for (int i = 0; i < parts.Length; i++) |
1682 | lockPartsForRead(false); | ||
1683 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1684 | foreach (SceneObjectPart part in values) | ||
1685 | { | 1507 | { |
1686 | 1508 | SceneObjectPart part = parts[i]; | |
1687 | if (part.LocalId != m_rootPart.LocalId) | 1509 | if (part.LocalId != m_rootPart.LocalId) |
1688 | { | ||
1689 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); | 1510 | part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); |
1690 | } | ||
1691 | |||
1692 | } | 1511 | } |
1512 | |||
1693 | // Hack to get the physics scene geometries in the right spot | 1513 | // Hack to get the physics scene geometries in the right spot |
1694 | ResetChildPrimPhysicsPositions(); | 1514 | ResetChildPrimPhysicsPositions(); |
1695 | } | 1515 | } |
1696 | else | ||
1697 | { | ||
1698 | lockPartsForRead(false); | ||
1699 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); | ||
1700 | } | ||
1701 | } | 1516 | } |
1702 | 1517 | ||
1703 | public void SetOwnerId(UUID userId) | 1518 | public void SetOwnerId(UUID userId) |
@@ -1712,15 +1527,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1712 | 1527 | ||
1713 | public void ForEachPart(Action<SceneObjectPart> whatToDo) | 1528 | public void ForEachPart(Action<SceneObjectPart> whatToDo) |
1714 | { | 1529 | { |
1715 | lockPartsForRead(true); | 1530 | SceneObjectPart[] parts = m_parts.GetArray(); |
1716 | List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values); | 1531 | for (int i = 0; i < parts.Length; i++) |
1717 | lockPartsForRead(false); | 1532 | whatToDo(parts[i]); |
1718 | foreach (SceneObjectPart part in values) | ||
1719 | { | ||
1720 | |||
1721 | whatToDo(part); | ||
1722 | |||
1723 | } | ||
1724 | } | 1533 | } |
1725 | 1534 | ||
1726 | #region Events | 1535 | #region Events |
@@ -1790,7 +1599,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1790 | // Possible ghost prim | 1599 | // Possible ghost prim |
1791 | if (m_rootPart.PhysActor.Position != m_rootPart.GroupPosition) | 1600 | if (m_rootPart.PhysActor.Position != m_rootPart.GroupPosition) |
1792 | { | 1601 | { |
1793 | foreach (SceneObjectPart part in Children.Values) | 1602 | foreach (SceneObjectPart part in m_parts.GetArray()) |
1794 | { | 1603 | { |
1795 | // Re-set physics actor positions and | 1604 | // Re-set physics actor positions and |
1796 | // orientations | 1605 | // orientations |
@@ -1842,17 +1651,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1842 | RootPart.SendFullUpdate( | 1651 | RootPart.SendFullUpdate( |
1843 | remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); | 1652 | remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); |
1844 | 1653 | ||
1845 | lockPartsForRead(true); | 1654 | SceneObjectPart[] parts = m_parts.GetArray(); |
1655 | for (int i = 0; i < parts.Length; i++) | ||
1846 | { | 1656 | { |
1847 | foreach (SceneObjectPart part in m_parts.Values) | 1657 | SceneObjectPart part = parts[i]; |
1848 | { | 1658 | if (part != RootPart) |
1849 | 1659 | part.SendFullUpdate(remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); | |
1850 | if (part != RootPart) | ||
1851 | part.SendFullUpdate( | ||
1852 | remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); | ||
1853 | } | ||
1854 | } | 1660 | } |
1855 | lockPartsForRead(false); | ||
1856 | } | 1661 | } |
1857 | 1662 | ||
1858 | #region Copying | 1663 | #region Copying |
@@ -1870,7 +1675,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1870 | m_dupeInProgress = true; | 1675 | m_dupeInProgress = true; |
1871 | dupe = (SceneObjectGroup)MemberwiseClone(); | 1676 | dupe = (SceneObjectGroup)MemberwiseClone(); |
1872 | dupe.m_isBackedUp = false; | 1677 | dupe.m_isBackedUp = false; |
1873 | dupe.m_parts = new Dictionary<UUID, SceneObjectPart>(); | 1678 | dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>(); |
1874 | 1679 | ||
1875 | // Warning, The following code related to previousAttachmentStatus is needed so that clones of | 1680 | // Warning, The following code related to previousAttachmentStatus is needed so that clones of |
1876 | // attachments do not bordercross while they're being duplicated. This is hacktastic! | 1681 | // attachments do not bordercross while they're being duplicated. This is hacktastic! |
@@ -1916,13 +1721,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1916 | dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); | 1721 | dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); |
1917 | } | 1722 | } |
1918 | 1723 | ||
1919 | lockPartsForRead(true); | 1724 | List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.GetArray()); |
1920 | |||
1921 | List<SceneObjectPart> partList; | ||
1922 | |||
1923 | partList = new List<SceneObjectPart>(m_parts.Values); | ||
1924 | |||
1925 | lockPartsForRead(false); | ||
1926 | 1725 | ||
1927 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) | 1726 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) |
1928 | { | 1727 | { |
@@ -2261,14 +2060,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2261 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); | 2060 | SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); |
2262 | newPart.SetParent(this); | 2061 | newPart.SetParent(this); |
2263 | 2062 | ||
2264 | lockPartsForWrite(true); | 2063 | AddPart(newPart); |
2265 | { | ||
2266 | m_parts.Add(newPart.UUID, newPart); | ||
2267 | } | ||
2268 | lockPartsForWrite(false); | ||
2269 | 2064 | ||
2270 | SetPartAsNonRoot(newPart); | 2065 | SetPartAsNonRoot(newPart); |
2271 | |||
2272 | return newPart; | 2066 | return newPart; |
2273 | } | 2067 | } |
2274 | 2068 | ||
@@ -2280,9 +2074,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2280 | /// </summary> | 2074 | /// </summary> |
2281 | public void ResetIDs() | 2075 | public void ResetIDs() |
2282 | { | 2076 | { |
2283 | lock (m_parts) | 2077 | lock (m_parts.SyncRoot) |
2284 | { | 2078 | { |
2285 | List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values); | 2079 | List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.GetArray()); |
2286 | m_parts.Clear(); | 2080 | m_parts.Clear(); |
2287 | foreach (SceneObjectPart part in partsList) | 2081 | foreach (SceneObjectPart part in partsList) |
2288 | { | 2082 | { |
@@ -2298,7 +2092,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2298 | /// <param name="part"></param> | 2092 | /// <param name="part"></param> |
2299 | public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) | 2093 | public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) |
2300 | { | 2094 | { |
2301 | |||
2302 | remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, | 2095 | remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, |
2303 | RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, | 2096 | RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, |
2304 | RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, | 2097 | RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, |
@@ -2329,8 +2122,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2329 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) | 2122 | //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) |
2330 | // return; | 2123 | // return; |
2331 | 2124 | ||
2332 | lockPartsForRead(true); | ||
2333 | |||
2334 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); | 2125 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); |
2335 | 2126 | ||
2336 | if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) | 2127 | if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) |
@@ -2345,16 +2136,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
2345 | lastPhysGroupRot = GroupRotation; | 2136 | lastPhysGroupRot = GroupRotation; |
2346 | } | 2137 | } |
2347 | 2138 | ||
2348 | List<SceneObjectPart> partList = null; | 2139 | SceneObjectPart[] parts = m_parts.GetArray(); |
2349 | partList = new List<SceneObjectPart>(m_parts.Values); | 2140 | for (int i = 0; i < parts.Length; i++) |
2350 | |||
2351 | foreach (SceneObjectPart part in partList) | ||
2352 | { | 2141 | { |
2142 | SceneObjectPart part = parts[i]; | ||
2353 | if (!IsSelected) | 2143 | if (!IsSelected) |
2354 | part.UpdateLookAt(); | 2144 | part.UpdateLookAt(); |
2355 | part.SendScheduledUpdates(); | 2145 | part.SendScheduledUpdates(); |
2356 | } | 2146 | } |
2357 | lockPartsForRead(false); | ||
2358 | } | 2147 | } |
2359 | 2148 | ||
2360 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) | 2149 | public void ScheduleFullUpdateToAvatar(ScenePresence presence) |
@@ -2363,29 +2152,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
2363 | 2152 | ||
2364 | RootPart.AddFullUpdateToAvatar(presence); | 2153 | RootPart.AddFullUpdateToAvatar(presence); |
2365 | 2154 | ||
2366 | lockPartsForRead(true); | 2155 | SceneObjectPart[] parts = m_parts.GetArray(); |
2156 | for (int i = 0; i < parts.Length; i++) | ||
2367 | { | 2157 | { |
2368 | foreach (SceneObjectPart part in m_parts.Values) | 2158 | SceneObjectPart part = parts[i]; |
2369 | { | 2159 | if (part != RootPart) |
2370 | 2160 | part.AddFullUpdateToAvatar(presence); | |
2371 | if (part != RootPart) | ||
2372 | part.AddFullUpdateToAvatar(presence); | ||
2373 | |||
2374 | } | ||
2375 | } | 2161 | } |
2376 | lockPartsForRead(false); | ||
2377 | } | 2162 | } |
2378 | 2163 | ||
2379 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) | 2164 | public void ScheduleTerseUpdateToAvatar(ScenePresence presence) |
2380 | { | 2165 | { |
2381 | lockPartsForRead(true); | 2166 | // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); |
2382 | |||
2383 | foreach (SceneObjectPart part in m_parts.Values) | ||
2384 | { | ||
2385 | part.AddTerseUpdateToAvatar(presence); | ||
2386 | } | ||
2387 | 2167 | ||
2388 | lockPartsForRead(false); | 2168 | SceneObjectPart[] parts = m_parts.GetArray(); |
2169 | for (int i = 0; i < parts.Length; i++) | ||
2170 | parts[i].AddTerseUpdateToAvatar(presence); | ||
2389 | } | 2171 | } |
2390 | 2172 | ||
2391 | /// <summary> | 2173 | /// <summary> |
@@ -2399,17 +2181,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2399 | checkAtTargets(); | 2181 | checkAtTargets(); |
2400 | RootPart.ScheduleFullUpdate(); | 2182 | RootPart.ScheduleFullUpdate(); |
2401 | 2183 | ||
2402 | lockPartsForRead(true); | 2184 | SceneObjectPart[] parts = m_parts.GetArray(); |
2185 | for (int i = 0; i < parts.Length; i++) | ||
2403 | { | 2186 | { |
2404 | foreach (SceneObjectPart part in m_parts.Values) | 2187 | SceneObjectPart part = parts[i]; |
2405 | { | 2188 | if (part != RootPart) |
2406 | 2189 | part.ScheduleFullUpdate(); | |
2407 | if (part != RootPart) | ||
2408 | part.ScheduleFullUpdate(); | ||
2409 | |||
2410 | } | ||
2411 | } | 2190 | } |
2412 | lockPartsForRead(false); | ||
2413 | } | 2191 | } |
2414 | 2192 | ||
2415 | /// <summary> | 2193 | /// <summary> |
@@ -2417,13 +2195,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2417 | /// </summary> | 2195 | /// </summary> |
2418 | public void ScheduleGroupForTerseUpdate() | 2196 | public void ScheduleGroupForTerseUpdate() |
2419 | { | 2197 | { |
2420 | lockPartsForRead(true); | 2198 | // m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); |
2421 | foreach (SceneObjectPart part in m_parts.Values) | ||
2422 | { | ||
2423 | part.ScheduleTerseUpdate(); | ||
2424 | } | ||
2425 | 2199 | ||
2426 | lockPartsForRead(false); | 2200 | SceneObjectPart[] parts = m_parts.GetArray(); |
2201 | for (int i = 0; i < parts.Length; i++) | ||
2202 | parts[i].ScheduleTerseUpdate(); | ||
2427 | } | 2203 | } |
2428 | 2204 | ||
2429 | /// <summary> | 2205 | /// <summary> |
@@ -2438,17 +2214,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2438 | 2214 | ||
2439 | RootPart.SendFullUpdateToAllClients(); | 2215 | RootPart.SendFullUpdateToAllClients(); |
2440 | 2216 | ||
2441 | lockPartsForRead(true); | 2217 | SceneObjectPart[] parts = m_parts.GetArray(); |
2218 | for (int i = 0; i < parts.Length; i++) | ||
2442 | { | 2219 | { |
2443 | foreach (SceneObjectPart part in m_parts.Values) | 2220 | SceneObjectPart part = parts[i]; |
2444 | { | 2221 | if (part != RootPart) |
2445 | 2222 | part.SendFullUpdateToAllClients(); | |
2446 | if (part != RootPart) | ||
2447 | part.SendFullUpdateToAllClients(); | ||
2448 | |||
2449 | } | ||
2450 | } | 2223 | } |
2451 | lockPartsForRead(false); | ||
2452 | } | 2224 | } |
2453 | 2225 | ||
2454 | /// <summary> | 2226 | /// <summary> |
@@ -2481,14 +2253,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2481 | if (IsDeleted) | 2253 | if (IsDeleted) |
2482 | return; | 2254 | return; |
2483 | 2255 | ||
2484 | lockPartsForRead(true); | 2256 | SceneObjectPart[] parts = m_parts.GetArray(); |
2485 | { | 2257 | for (int i = 0; i < parts.Length; i++) |
2486 | foreach (SceneObjectPart part in m_parts.Values) | 2258 | parts[i].SendTerseUpdateToAllClients(); |
2487 | { | ||
2488 | part.SendTerseUpdateToAllClients(); | ||
2489 | } | ||
2490 | } | ||
2491 | lockPartsForRead(false); | ||
2492 | } | 2259 | } |
2493 | 2260 | ||
2494 | #endregion | 2261 | #endregion |
@@ -2502,18 +2269,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2502 | /// <returns>null if no child part with that linknum or child part</returns> | 2269 | /// <returns>null if no child part with that linknum or child part</returns> |
2503 | public SceneObjectPart GetLinkNumPart(int linknum) | 2270 | public SceneObjectPart GetLinkNumPart(int linknum) |
2504 | { | 2271 | { |
2505 | lockPartsForRead(true); | 2272 | SceneObjectPart[] parts = m_parts.GetArray(); |
2273 | for (int i = 0; i < parts.Length; i++) | ||
2506 | { | 2274 | { |
2507 | foreach (SceneObjectPart part in m_parts.Values) | 2275 | if (parts[i].LinkNum == linknum) |
2508 | { | 2276 | return parts[i]; |
2509 | if (part.LinkNum == linknum) | ||
2510 | { | ||
2511 | lockPartsForRead(false); | ||
2512 | return part; | ||
2513 | } | ||
2514 | } | ||
2515 | } | 2277 | } |
2516 | lockPartsForRead(false); | ||
2517 | 2278 | ||
2518 | return null; | 2279 | return null; |
2519 | } | 2280 | } |
@@ -2526,8 +2287,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2526 | public SceneObjectPart GetChildPart(UUID primID) | 2287 | public SceneObjectPart GetChildPart(UUID primID) |
2527 | { | 2288 | { |
2528 | SceneObjectPart childPart; | 2289 | SceneObjectPart childPart; |
2529 | lock (m_parts) | 2290 | m_parts.TryGetValue(primID, out childPart); |
2530 | m_parts.TryGetValue(primID, out childPart); | ||
2531 | return childPart; | 2291 | return childPart; |
2532 | } | 2292 | } |
2533 | 2293 | ||
@@ -2538,20 +2298,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2538 | /// <returns>null if a child part with the local ID was not found</returns> | 2298 | /// <returns>null if a child part with the local ID was not found</returns> |
2539 | public SceneObjectPart GetChildPart(uint localID) | 2299 | public SceneObjectPart GetChildPart(uint localID) |
2540 | { | 2300 | { |
2541 | //m_log.DebugFormat("Entered looking for {0}", localID); | 2301 | SceneObjectPart[] parts = m_parts.GetArray(); |
2542 | lockPartsForRead(true); | 2302 | for (int i = 0; i < parts.Length; i++) |
2543 | { | 2303 | { |
2544 | foreach (SceneObjectPart part in m_parts.Values) | 2304 | if (parts[i].LocalId == localID) |
2545 | { | 2305 | return parts[i]; |
2546 | //m_log.DebugFormat("Found {0}", part.LocalId); | ||
2547 | if (part.LocalId == localID) | ||
2548 | { | ||
2549 | lockPartsForRead(false); | ||
2550 | return part; | ||
2551 | } | ||
2552 | } | ||
2553 | } | 2306 | } |
2554 | lockPartsForRead(false); | ||
2555 | 2307 | ||
2556 | return null; | 2308 | return null; |
2557 | } | 2309 | } |
@@ -2564,13 +2316,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2564 | /// <returns></returns> | 2316 | /// <returns></returns> |
2565 | public bool HasChildPrim(UUID primID) | 2317 | public bool HasChildPrim(UUID primID) |
2566 | { | 2318 | { |
2567 | lock (m_parts) | 2319 | return m_parts.ContainsKey(primID); |
2568 | { | ||
2569 | if (m_parts.ContainsKey(primID)) | ||
2570 | return true; | ||
2571 | } | ||
2572 | |||
2573 | return false; | ||
2574 | } | 2320 | } |
2575 | 2321 | ||
2576 | /// <summary> | 2322 | /// <summary> |
@@ -2581,20 +2327,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2581 | /// <returns></returns> | 2327 | /// <returns></returns> |
2582 | public bool HasChildPrim(uint localID) | 2328 | public bool HasChildPrim(uint localID) |
2583 | { | 2329 | { |
2584 | //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); | 2330 | SceneObjectPart[] parts = m_parts.GetArray(); |
2585 | lockPartsForRead(true); | 2331 | for (int i = 0; i < parts.Length; i++) |
2586 | { | 2332 | { |
2587 | foreach (SceneObjectPart part in m_parts.Values) | 2333 | if (parts[i].LocalId == localID) |
2588 | { | 2334 | return true; |
2589 | //m_log.DebugFormat("Found {0}", part.LocalId); | ||
2590 | if (part.LocalId == localID) | ||
2591 | { | ||
2592 | lockPartsForRead(false); | ||
2593 | return true; | ||
2594 | } | ||
2595 | } | ||
2596 | } | 2335 | } |
2597 | lockPartsForRead(false); | ||
2598 | 2336 | ||
2599 | return false; | 2337 | return false; |
2600 | } | 2338 | } |
@@ -2644,58 +2382,56 @@ namespace OpenSim.Region.Framework.Scenes | |||
2644 | if (m_rootPart.LinkNum == 0) | 2382 | if (m_rootPart.LinkNum == 0) |
2645 | m_rootPart.LinkNum = 1; | 2383 | m_rootPart.LinkNum = 1; |
2646 | 2384 | ||
2647 | lockPartsForWrite(true); | 2385 | lock (m_parts.SyncRoot) |
2648 | |||
2649 | m_parts.Add(linkPart.UUID, linkPart); | ||
2650 | |||
2651 | lockPartsForWrite(false); | ||
2652 | |||
2653 | // Insert in terms of link numbers, the new links | ||
2654 | // before the current ones (with the exception of | ||
2655 | // the root prim. Shuffle the old ones up | ||
2656 | lockPartsForRead(true); | ||
2657 | foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) | ||
2658 | { | 2386 | { |
2659 | if (kvp.Value.LinkNum != 1) | 2387 | m_parts.Add(linkPart.UUID, linkPart); |
2388 | |||
2389 | // Insert in terms of link numbers, the new links | ||
2390 | // before the current ones (with the exception of | ||
2391 | // the root prim. Shuffle the old ones up | ||
2392 | SceneObjectPart[] parts = m_parts.GetArray(); | ||
2393 | for (int i = 0; i < parts.Length; i++) | ||
2660 | { | 2394 | { |
2661 | // Don't update root prim link number | 2395 | SceneObjectPart part = parts[i]; |
2662 | kvp.Value.LinkNum += objectGroup.PrimCount; | 2396 | if (part.LinkNum != 1) |
2397 | { | ||
2398 | // Don't update root prim link number | ||
2399 | part.LinkNum += objectGroup.PrimCount; | ||
2400 | } | ||
2663 | } | 2401 | } |
2664 | } | 2402 | } |
2665 | lockPartsForRead(false); | ||
2666 | 2403 | ||
2667 | linkPart.LinkNum = 2; | 2404 | linkPart.LinkNum = 2; |
2668 | 2405 | ||
2669 | linkPart.SetParent(this); | 2406 | linkPart.SetParent(this); |
2670 | linkPart.CreateSelected = true; | 2407 | linkPart.CreateSelected = true; |
2671 | 2408 | ||
2672 | //if (linkPart.PhysActor != null) | 2409 | lock (m_parts.SyncRoot) |
2673 | //{ | ||
2674 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); | ||
2675 | |||
2676 | //linkPart.PhysActor = null; | ||
2677 | //} | ||
2678 | |||
2679 | //TODO: rest of parts | ||
2680 | int linkNum = 3; | ||
2681 | foreach (SceneObjectPart part in objectGroup.Children.Values) | ||
2682 | { | 2410 | { |
2683 | if (part.UUID != objectGroup.m_rootPart.UUID) | 2411 | //if (linkPart.PhysActor != null) |
2412 | //{ | ||
2413 | // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); | ||
2414 | |||
2415 | //linkPart.PhysActor = null; | ||
2416 | //} | ||
2417 | |||
2418 | //TODO: rest of parts | ||
2419 | int linkNum = 3; | ||
2420 | SceneObjectPart[] ogParts = objectGroup.Parts; | ||
2421 | for (int i = 0; i < ogParts.Length; i++) | ||
2684 | { | 2422 | { |
2685 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); | 2423 | SceneObjectPart part = ogParts[i]; |
2424 | if (part.UUID != objectGroup.m_rootPart.UUID) | ||
2425 | LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); | ||
2426 | part.ClearUndoState(); | ||
2686 | } | 2427 | } |
2687 | part.ClearUndoState(); | ||
2688 | } | 2428 | } |
2689 | 2429 | ||
2690 | m_scene.UnlinkSceneObject(objectGroup, true); | 2430 | m_scene.UnlinkSceneObject(objectGroup, true); |
2691 | objectGroup.m_isDeleted = true; | 2431 | objectGroup.m_isDeleted = true; |
2692 | 2432 | ||
2693 | objectGroup.lockPartsForWrite(true); | ||
2694 | |||
2695 | objectGroup.m_parts.Clear(); | 2433 | objectGroup.m_parts.Clear(); |
2696 | 2434 | ||
2697 | objectGroup.lockPartsForWrite(false); | ||
2698 | |||
2699 | // Can't do this yet since backup still makes use of the root part without any synchronization | 2435 | // Can't do this yet since backup still makes use of the root part without any synchronization |
2700 | // objectGroup.m_rootPart = null; | 2436 | // objectGroup.m_rootPart = null; |
2701 | 2437 | ||
@@ -2764,23 +2500,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
2764 | Quaternion worldRot = linkPart.GetWorldRotation(); | 2500 | Quaternion worldRot = linkPart.GetWorldRotation(); |
2765 | 2501 | ||
2766 | // Remove the part from this object | 2502 | // Remove the part from this object |
2767 | lockPartsForWrite(true); | 2503 | lock (m_parts.SyncRoot) |
2768 | { | 2504 | { |
2769 | m_parts.Remove(linkPart.UUID); | 2505 | m_parts.Remove(linkPart.UUID); |
2770 | } | 2506 | |
2771 | lockPartsForWrite(false); | 2507 | SceneObjectPart[] parts = m_parts.GetArray(); |
2772 | lockPartsForRead(true); | 2508 | |
2773 | if (m_parts.Count == 1 && RootPart != null) //Single prim is left | 2509 | if (parts.Length == 1 && RootPart != null) |
2774 | RootPart.LinkNum = 0; | ||
2775 | else | ||
2776 | { | ||
2777 | foreach (SceneObjectPart p in m_parts.Values) | ||
2778 | { | 2510 | { |
2779 | if (p.LinkNum > linkPart.LinkNum) | 2511 | // Single prim left |
2780 | p.LinkNum--; | 2512 | RootPart.LinkNum = 0; |
2513 | } | ||
2514 | else | ||
2515 | { | ||
2516 | for (int i = 0; i < parts.Length; i++) | ||
2517 | { | ||
2518 | SceneObjectPart part = parts[i]; | ||
2519 | if (part.LinkNum > linkPart.LinkNum) | ||
2520 | part.LinkNum--; | ||
2521 | } | ||
2781 | } | 2522 | } |
2782 | } | 2523 | } |
2783 | lockPartsForRead(false); | ||
2784 | 2524 | ||
2785 | linkPart.ParentID = 0; | 2525 | linkPart.ParentID = 0; |
2786 | linkPart.LinkNum = 0; | 2526 | linkPart.LinkNum = 0; |
@@ -2851,7 +2591,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2851 | part.SetParent(this); | 2591 | part.SetParent(this); |
2852 | part.ParentID = m_rootPart.LocalId; | 2592 | part.ParentID = m_rootPart.LocalId; |
2853 | 2593 | ||
2854 | // Caller locks m_parts for us | ||
2855 | m_parts.Add(part.UUID, part); | 2594 | m_parts.Add(part.UUID, part); |
2856 | 2595 | ||
2857 | part.LinkNum = linkNum; | 2596 | part.LinkNum = linkNum; |
@@ -3104,28 +2843,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
3104 | 2843 | ||
3105 | if (selectionPart != null) | 2844 | if (selectionPart != null) |
3106 | { | 2845 | { |
3107 | lockPartsForRead(true); | 2846 | SceneObjectPart[] parts = m_parts.GetArray(); |
3108 | List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values); | 2847 | for (int i = 0; i < parts.Length; i++) |
3109 | lockPartsForRead(false); | ||
3110 | foreach (SceneObjectPart part in parts) | ||
3111 | { | 2848 | { |
3112 | if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) | 2849 | SceneObjectPart part = parts[i]; |
2850 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || | ||
2851 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || | ||
2852 | part.Scale.Z > m_scene.RegionInfo.PhysPrimMax) | ||
3113 | { | 2853 | { |
3114 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || | 2854 | UsePhysics = false; // Reset physics |
3115 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || | 2855 | break; |
3116 | part.Scale.Z > m_scene.RegionInfo.PhysPrimMax) | ||
3117 | { | ||
3118 | UsePhysics = false; // Reset physics | ||
3119 | break; | ||
3120 | } | ||
3121 | } | 2856 | } |
3122 | } | 2857 | } |
3123 | 2858 | ||
3124 | foreach (SceneObjectPart part in parts) | 2859 | for (int i = 0; i < parts.Length; i++) |
3125 | { | 2860 | parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); |
3126 | part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); | ||
3127 | } | ||
3128 | |||
3129 | } | 2861 | } |
3130 | } | 2862 | } |
3131 | 2863 | ||
@@ -3146,19 +2878,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3146 | /// <returns></returns> | 2878 | /// <returns></returns> |
3147 | public int GetPartCount() | 2879 | public int GetPartCount() |
3148 | { | 2880 | { |
3149 | return Children.Count; | 2881 | return Parts.Count(); |
3150 | } | ||
3151 | |||
3152 | /// <summary> | ||
3153 | /// Get the parts of this scene object | ||
3154 | /// </summary> | ||
3155 | /// <returns></returns> | ||
3156 | public SceneObjectPart[] GetParts() | ||
3157 | { | ||
3158 | int numParts = Children.Count; | ||
3159 | SceneObjectPart[] partArray = new SceneObjectPart[numParts]; | ||
3160 | Children.Values.CopyTo(partArray, 0); | ||
3161 | return partArray; | ||
3162 | } | 2882 | } |
3163 | 2883 | ||
3164 | /// <summary> | 2884 | /// <summary> |
@@ -3178,12 +2898,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3178 | public void UpdatePermissions(UUID AgentID, byte field, uint localID, | 2898 | public void UpdatePermissions(UUID AgentID, byte field, uint localID, |
3179 | uint mask, byte addRemTF) | 2899 | uint mask, byte addRemTF) |
3180 | { | 2900 | { |
3181 | List<SceneObjectPart> partList = null; | 2901 | SceneObjectPart[] parts = m_parts.GetArray(); |
3182 | lock (m_parts) | 2902 | for (int i = 0; i < parts.Length; i++) |
3183 | partList = new List<SceneObjectPart>(m_parts.Values); | 2903 | parts[i].UpdatePermissions(AgentID, field, localID, mask, addRemTF); |
3184 | |||
3185 | foreach (SceneObjectPart part in partList) | ||
3186 | part.UpdatePermissions(AgentID, field, localID, mask, addRemTF); | ||
3187 | 2904 | ||
3188 | HasGroupChanged = true; | 2905 | HasGroupChanged = true; |
3189 | } | 2906 | } |
@@ -3283,15 +3000,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
3283 | float y = (scale.Y / part.Scale.Y); | 3000 | float y = (scale.Y / part.Scale.Y); |
3284 | float z = (scale.Z / part.Scale.Z); | 3001 | float z = (scale.Z / part.Scale.Z); |
3285 | 3002 | ||
3286 | lockPartsForRead(true); | 3003 | SceneObjectPart[] parts; |
3287 | if (x > 1.0f || y > 1.0f || z > 1.0f) | 3004 | if (x > 1.0f || y > 1.0f || z > 1.0f) |
3288 | { | 3005 | { |
3289 | foreach (SceneObjectPart obPart in m_parts.Values) | 3006 | parts = m_parts.GetArray(); |
3007 | for (int i = 0; i < parts.Length; i++) | ||
3290 | { | 3008 | { |
3009 | SceneObjectPart obPart = parts[i]; | ||
3291 | if (obPart.UUID != m_rootPart.UUID) | 3010 | if (obPart.UUID != m_rootPart.UUID) |
3292 | { | 3011 | { |
3293 | Vector3 oldSize = new Vector3(obPart.Scale); | ||
3294 | obPart.IgnoreUndoUpdate = true; | 3012 | obPart.IgnoreUndoUpdate = true; |
3013 | Vector3 oldSize = new Vector3(obPart.Scale); | ||
3295 | 3014 | ||
3296 | float f = 1.0f; | 3015 | float f = 1.0f; |
3297 | float a = 1.0f; | 3016 | float a = 1.0f; |
@@ -3349,12 +3068,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
3349 | y *= a; | 3068 | y *= a; |
3350 | z *= a; | 3069 | z *= a; |
3351 | } | 3070 | } |
3352 | |||
3353 | } | 3071 | } |
3072 | obPart.IgnoreUndoUpdate = false; | ||
3354 | } | 3073 | } |
3355 | } | 3074 | } |
3356 | } | 3075 | } |
3357 | lockPartsForRead(false); | ||
3358 | 3076 | ||
3359 | Vector3 prevScale = part.Scale; | 3077 | Vector3 prevScale = part.Scale; |
3360 | prevScale.X *= x; | 3078 | prevScale.X *= x; |
@@ -3367,9 +3085,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3367 | part.Resize(prevScale); | 3085 | part.Resize(prevScale); |
3368 | part.IgnoreUndoUpdate = false; | 3086 | part.IgnoreUndoUpdate = false; |
3369 | 3087 | ||
3370 | lockPartsForRead(true); | 3088 | parts = m_parts.GetArray(); |
3089 | for (int i = 0; i < parts.Length; i++) | ||
3371 | { | 3090 | { |
3372 | foreach (SceneObjectPart obPart in m_parts.Values) | 3091 | SceneObjectPart obPart = parts[i]; |
3092 | obPart.IgnoreUndoUpdate = true; | ||
3093 | if (obPart.UUID != m_rootPart.UUID) | ||
3373 | { | 3094 | { |
3374 | if (obPart.UUID != m_rootPart.UUID) | 3095 | if (obPart.UUID != m_rootPart.UUID) |
3375 | { | 3096 | { |
@@ -3390,8 +3111,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3390 | } | 3111 | } |
3391 | obPart.IgnoreUndoUpdate = false; | 3112 | obPart.IgnoreUndoUpdate = false; |
3392 | } | 3113 | } |
3114 | obPart.IgnoreUndoUpdate = false; | ||
3393 | } | 3115 | } |
3394 | lockPartsForRead(false); | ||
3395 | 3116 | ||
3396 | if (part.PhysActor != null) | 3117 | if (part.PhysActor != null) |
3397 | { | 3118 | { |
@@ -3450,10 +3171,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
3450 | public void UpdateSinglePosition(Vector3 pos, uint localID) | 3171 | public void UpdateSinglePosition(Vector3 pos, uint localID) |
3451 | { | 3172 | { |
3452 | SceneObjectPart part = GetChildPart(localID); | 3173 | SceneObjectPart part = GetChildPart(localID); |
3453 | foreach (SceneObjectPart parts in Children.Values) | 3174 | |
3454 | { | 3175 | SceneObjectPart[] parts = m_parts.GetArray(); |
3455 | parts.StoreUndoState(UndoType.STATE_PRIM_POSITION); | 3176 | for (int i = 0; i < parts.Length; i++) |
3456 | } | 3177 | parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION); |
3178 | |||
3457 | if (part != null) | 3179 | if (part != null) |
3458 | { | 3180 | { |
3459 | if (part.UUID == m_rootPart.UUID) | 3181 | if (part.UUID == m_rootPart.UUID) |
@@ -3475,10 +3197,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3475 | /// <param name="pos"></param> | 3197 | /// <param name="pos"></param> |
3476 | private void UpdateRootPosition(Vector3 pos) | 3198 | private void UpdateRootPosition(Vector3 pos) |
3477 | { | 3199 | { |
3478 | foreach (SceneObjectPart part in Children.Values) | 3200 | SceneObjectPart[] parts = m_parts.GetArray(); |
3479 | { | 3201 | for (int i = 0; i < parts.Length; i++) |
3480 | part.StoreUndoState(UndoType.STATE_PRIM_POSITION); | 3202 | parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION); |
3481 | } | 3203 | |
3482 | Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); | 3204 | Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); |
3483 | Vector3 oldPos = | 3205 | Vector3 oldPos = |
3484 | new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X, | 3206 | new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X, |
@@ -3490,17 +3212,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3490 | axDiff *= Quaternion.Inverse(partRotation); | 3212 | axDiff *= Quaternion.Inverse(partRotation); |
3491 | diff = axDiff; | 3213 | diff = axDiff; |
3492 | 3214 | ||
3493 | lockPartsForRead(true); | 3215 | parts = m_parts.GetArray(); |
3216 | for (int i = 0; i < parts.Length; i++) | ||
3494 | { | 3217 | { |
3495 | foreach (SceneObjectPart obPart in m_parts.Values) | 3218 | SceneObjectPart obPart = parts[i]; |
3496 | { | 3219 | if (obPart.UUID != m_rootPart.UUID) |
3497 | if (obPart.UUID != m_rootPart.UUID) | 3220 | obPart.OffsetPosition = obPart.OffsetPosition + diff; |
3498 | { | ||
3499 | obPart.OffsetPosition = obPart.OffsetPosition + diff; | ||
3500 | } | ||
3501 | } | ||
3502 | } | 3221 | } |
3503 | lockPartsForRead(false); | ||
3504 | 3222 | ||
3505 | //We have to set undoing here because otherwise an undo state will be saved | 3223 | //We have to set undoing here because otherwise an undo state will be saved |
3506 | if (!m_rootPart.Undoing) | 3224 | if (!m_rootPart.Undoing) |
@@ -3540,10 +3258,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3540 | /// <param name="rot"></param> | 3258 | /// <param name="rot"></param> |
3541 | public void UpdateGroupRotationR(Quaternion rot) | 3259 | public void UpdateGroupRotationR(Quaternion rot) |
3542 | { | 3260 | { |
3543 | foreach (SceneObjectPart parts in Children.Values) | 3261 | SceneObjectPart[] parts = m_parts.GetArray(); |
3544 | { | 3262 | for (int i = 0; i < parts.Length; i++) |
3545 | parts.StoreUndoState(UndoType.STATE_GROUP_ROTATION); | 3263 | parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION); |
3546 | } | 3264 | |
3547 | m_rootPart.UpdateRotation(rot); | 3265 | m_rootPart.UpdateRotation(rot); |
3548 | 3266 | ||
3549 | PhysicsActor actor = m_rootPart.PhysActor; | 3267 | PhysicsActor actor = m_rootPart.PhysActor; |
@@ -3564,10 +3282,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3564 | /// <param name="rot"></param> | 3282 | /// <param name="rot"></param> |
3565 | public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) | 3283 | public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) |
3566 | { | 3284 | { |
3567 | foreach (SceneObjectPart parts in Children.Values) | 3285 | SceneObjectPart[] parts = m_parts.GetArray(); |
3568 | { | 3286 | for (int i = 0; i < parts.Length; i++) |
3569 | parts.StoreUndoState(UndoType.STATE_GROUP_ROTATION); | 3287 | parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION); |
3570 | } | 3288 | |
3571 | m_rootPart.UpdateRotation(rot); | 3289 | m_rootPart.UpdateRotation(rot); |
3572 | 3290 | ||
3573 | PhysicsActor actor = m_rootPart.PhysActor; | 3291 | PhysicsActor actor = m_rootPart.PhysActor; |
@@ -3591,10 +3309,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3591 | public void UpdateSingleRotation(Quaternion rot, uint localID) | 3309 | public void UpdateSingleRotation(Quaternion rot, uint localID) |
3592 | { | 3310 | { |
3593 | SceneObjectPart part = GetChildPart(localID); | 3311 | SceneObjectPart part = GetChildPart(localID); |
3594 | foreach (SceneObjectPart parts in Children.Values) | 3312 | SceneObjectPart[] parts = m_parts.GetArray(); |
3595 | { | 3313 | for (int i = 0; i < parts.Length; i++) |
3596 | parts.StoreUndoState(UndoType.STATE_PRIM_ROTATION); | 3314 | parts[i].StoreUndoState(UndoType.STATE_PRIM_ROTATION); |
3597 | } | 3315 | |
3598 | if (part != null) | 3316 | if (part != null) |
3599 | { | 3317 | { |
3600 | if (part.UUID == m_rootPart.UUID) | 3318 | if (part.UUID == m_rootPart.UUID) |
@@ -3666,10 +3384,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3666 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | 3384 | m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); |
3667 | } | 3385 | } |
3668 | 3386 | ||
3669 | lockPartsForRead(true); | 3387 | SceneObjectPart[] parts = m_parts.GetArray(); |
3670 | 3388 | for (int i = 0; i < parts.Length; i++) | |
3671 | foreach (SceneObjectPart prim in m_parts.Values) | ||
3672 | { | 3389 | { |
3390 | SceneObjectPart prim = parts[i]; | ||
3673 | if (prim.UUID != m_rootPart.UUID) | 3391 | if (prim.UUID != m_rootPart.UUID) |
3674 | { | 3392 | { |
3675 | prim.IgnoreUndoUpdate = true; | 3393 | prim.IgnoreUndoUpdate = true; |
@@ -3689,7 +3407,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3689 | { | 3407 | { |
3690 | m_rootPart.Undoing = false; | 3408 | m_rootPart.Undoing = false; |
3691 | } | 3409 | } |
3692 | lockPartsForRead(false); | ||
3693 | 3410 | ||
3694 | m_rootPart.ScheduleTerseUpdate(); | 3411 | m_rootPart.ScheduleTerseUpdate(); |
3695 | } | 3412 | } |
@@ -3811,18 +3528,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3811 | 3528 | ||
3812 | if (atTargets.Count > 0) | 3529 | if (atTargets.Count > 0) |
3813 | { | 3530 | { |
3814 | uint[] localids = new uint[0]; | 3531 | SceneObjectPart[] parts = m_parts.GetArray(); |
3815 | lockPartsForRead(true); | 3532 | uint[] localids = new uint[parts.Length]; |
3816 | { | 3533 | for (int i = 0; i < parts.Length; i++) |
3817 | localids = new uint[m_parts.Count]; | 3534 | localids[i] = parts[i].LocalId; |
3818 | int cntr = 0; | ||
3819 | foreach (SceneObjectPart part in m_parts.Values) | ||
3820 | { | ||
3821 | localids[cntr] = part.LocalId; | ||
3822 | cntr++; | ||
3823 | } | ||
3824 | } | ||
3825 | lockPartsForRead(false); | ||
3826 | 3535 | ||
3827 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3536 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3828 | { | 3537 | { |
@@ -3840,19 +3549,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
3840 | if (m_scriptListens_notAtTarget && !at_target) | 3549 | if (m_scriptListens_notAtTarget && !at_target) |
3841 | { | 3550 | { |
3842 | //trigger not_at_target | 3551 | //trigger not_at_target |
3843 | uint[] localids = new uint[0]; | 3552 | SceneObjectPart[] parts = m_parts.GetArray(); |
3844 | lockPartsForRead(true); | 3553 | uint[] localids = new uint[parts.Length]; |
3845 | { | 3554 | for (int i = 0; i < parts.Length; i++) |
3846 | localids = new uint[m_parts.Count]; | 3555 | localids[i] = parts[i].LocalId; |
3847 | int cntr = 0; | 3556 | |
3848 | foreach (SceneObjectPart part in m_parts.Values) | ||
3849 | { | ||
3850 | localids[cntr] = part.LocalId; | ||
3851 | cntr++; | ||
3852 | } | ||
3853 | } | ||
3854 | lockPartsForRead(false); | ||
3855 | |||
3856 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3557 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3857 | { | 3558 | { |
3858 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); | 3559 | m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); |
@@ -3892,22 +3593,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3892 | 3593 | ||
3893 | if (atRotTargets.Count > 0) | 3594 | if (atRotTargets.Count > 0) |
3894 | { | 3595 | { |
3895 | uint[] localids = new uint[0]; | 3596 | SceneObjectPart[] parts = m_parts.GetArray(); |
3896 | lockPartsForRead(true); | 3597 | uint[] localids = new uint[parts.Length]; |
3897 | try | 3598 | for (int i = 0; i < parts.Length; i++) |
3898 | { | 3599 | localids[i] = parts[i].LocalId; |
3899 | localids = new uint[m_parts.Count]; | ||
3900 | int cntr = 0; | ||
3901 | foreach (SceneObjectPart part in m_parts.Values) | ||
3902 | { | ||
3903 | localids[cntr] = part.LocalId; | ||
3904 | cntr++; | ||
3905 | } | ||
3906 | } | ||
3907 | finally | ||
3908 | { | ||
3909 | lockPartsForRead(false); | ||
3910 | } | ||
3911 | 3600 | ||
3912 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3601 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3913 | { | 3602 | { |
@@ -3925,22 +3614,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
3925 | if (m_scriptListens_notAtRotTarget && !at_Rottarget) | 3614 | if (m_scriptListens_notAtRotTarget && !at_Rottarget) |
3926 | { | 3615 | { |
3927 | //trigger not_at_target | 3616 | //trigger not_at_target |
3928 | uint[] localids = new uint[0]; | 3617 | SceneObjectPart[] parts = m_parts.GetArray(); |
3929 | lockPartsForRead(true); | 3618 | uint[] localids = new uint[parts.Length]; |
3930 | try | 3619 | for (int i = 0; i < parts.Length; i++) |
3931 | { | 3620 | localids[i] = parts[i].LocalId; |
3932 | localids = new uint[m_parts.Count]; | ||
3933 | int cntr = 0; | ||
3934 | foreach (SceneObjectPart part in m_parts.Values) | ||
3935 | { | ||
3936 | localids[cntr] = part.LocalId; | ||
3937 | cntr++; | ||
3938 | } | ||
3939 | } | ||
3940 | finally | ||
3941 | { | ||
3942 | lockPartsForRead(false); | ||
3943 | } | ||
3944 | 3621 | ||
3945 | for (int ctr = 0; ctr < localids.Length; ctr++) | 3622 | for (int ctr = 0; ctr < localids.Length; ctr++) |
3946 | { | 3623 | { |
@@ -3954,45 +3631,38 @@ namespace OpenSim.Region.Framework.Scenes | |||
3954 | public float GetMass() | 3631 | public float GetMass() |
3955 | { | 3632 | { |
3956 | float retmass = 0f; | 3633 | float retmass = 0f; |
3957 | lockPartsForRead(true); | 3634 | SceneObjectPart[] parts = m_parts.GetArray(); |
3958 | { | 3635 | for (int i = 0; i < parts.Length; i++) |
3959 | foreach (SceneObjectPart part in m_parts.Values) | 3636 | retmass += parts[i].GetMass(); |
3960 | { | 3637 | |
3961 | retmass += part.GetMass(); | ||
3962 | } | ||
3963 | } | ||
3964 | lockPartsForRead(false); | ||
3965 | return retmass; | 3638 | return retmass; |
3966 | } | 3639 | } |
3967 | 3640 | ||
3968 | public void CheckSculptAndLoad() | 3641 | public void CheckSculptAndLoad() |
3969 | { | 3642 | { |
3970 | lockPartsForRead(true); | 3643 | if (IsDeleted) |
3644 | return; | ||
3645 | if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) | ||
3646 | return; | ||
3647 | |||
3648 | SceneObjectPart[] parts = m_parts.GetArray(); | ||
3649 | for (int i = 0; i < parts.Length; i++) | ||
3971 | { | 3650 | { |
3972 | if (!IsDeleted) | 3651 | SceneObjectPart part = parts[i]; |
3652 | if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero) | ||
3973 | { | 3653 | { |
3974 | if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == 0) | 3654 | // check if a previously decoded sculpt map has been cached |
3655 | if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString()))) | ||
3975 | { | 3656 | { |
3976 | foreach (SceneObjectPart part in m_parts.Values) | 3657 | part.SculptTextureCallback(part.Shape.SculptTexture, null); |
3977 | { | 3658 | } |
3978 | if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero) | 3659 | else |
3979 | { | 3660 | { |
3980 | // check if a previously decoded sculpt map has been cached | 3661 | m_scene.AssetService.Get( |
3981 | if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString()))) | 3662 | part.Shape.SculptTexture.ToString(), part, AssetReceived); |
3982 | { | ||
3983 | part.SculptTextureCallback(part.Shape.SculptTexture, null); | ||
3984 | } | ||
3985 | else | ||
3986 | { | ||
3987 | m_scene.AssetService.Get( | ||
3988 | part.Shape.SculptTexture.ToString(), part, AssetReceived); | ||
3989 | } | ||
3990 | } | ||
3991 | } | ||
3992 | } | 3663 | } |
3993 | } | 3664 | } |
3994 | } | 3665 | } |
3995 | lockPartsForRead(false); | ||
3996 | } | 3666 | } |
3997 | 3667 | ||
3998 | protected void AssetReceived(string id, Object sender, AssetBase asset) | 3668 | protected void AssetReceived(string id, Object sender, AssetBase asset) |
@@ -4013,17 +3683,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
4013 | /// <param name="client"></param> | 3683 | /// <param name="client"></param> |
4014 | public void SetGroup(UUID GroupID, IClientAPI client) | 3684 | public void SetGroup(UUID GroupID, IClientAPI client) |
4015 | { | 3685 | { |
4016 | lockPartsForRead(true); | 3686 | SceneObjectPart[] parts = m_parts.GetArray(); |
3687 | for (int i = 0; i < parts.Length; i++) | ||
4017 | { | 3688 | { |
4018 | foreach (SceneObjectPart part in m_parts.Values) | 3689 | SceneObjectPart part = parts[i]; |
4019 | { | 3690 | part.SetGroup(GroupID, client); |
4020 | part.SetGroup(GroupID, client); | 3691 | part.Inventory.ChangeInventoryGroup(GroupID); |
4021 | part.Inventory.ChangeInventoryGroup(GroupID); | ||
4022 | } | ||
4023 | |||
4024 | HasGroupChanged = true; | ||
4025 | } | 3692 | } |
4026 | lockPartsForRead(false); | ||
4027 | 3693 | ||
4028 | // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled | 3694 | // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled |
4029 | // for the same object with very different properties. The caller must schedule the update. | 3695 | // for the same object with very different properties. The caller must schedule the update. |
@@ -4032,10 +3698,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
4032 | 3698 | ||
4033 | public void TriggerScriptChangedEvent(Changed val) | 3699 | public void TriggerScriptChangedEvent(Changed val) |
4034 | { | 3700 | { |
4035 | foreach (SceneObjectPart part in Children.Values) | 3701 | SceneObjectPart[] parts = m_parts.GetArray(); |
4036 | { | 3702 | for (int i = 0; i < parts.Length; i++) |
4037 | part.TriggerScriptChangedEvent(val); | 3703 | parts[i].TriggerScriptChangedEvent(val); |
4038 | } | ||
4039 | } | 3704 | } |
4040 | 3705 | ||
4041 | public override string ToString() | 3706 | public override string ToString() |
@@ -4045,12 +3710,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
4045 | 3710 | ||
4046 | public void SetAttachmentPoint(byte point) | 3711 | public void SetAttachmentPoint(byte point) |
4047 | { | 3712 | { |
4048 | lockPartsForRead(true); | 3713 | SceneObjectPart[] parts = m_parts.GetArray(); |
4049 | { | 3714 | for (int i = 0; i < parts.Length; i++) |
4050 | foreach (SceneObjectPart part in m_parts.Values) | 3715 | parts[i].SetAttachmentPoint(point); |
4051 | part.SetAttachmentPoint(point); | ||
4052 | } | ||
4053 | lockPartsForRead(false); | ||
4054 | } | 3716 | } |
4055 | 3717 | ||
4056 | #region ISceneObject | 3718 | #region ISceneObject |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index b205503..8aa17a1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -780,10 +780,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
780 | rootPart.Name = item.Name; | 780 | rootPart.Name = item.Name; |
781 | rootPart.Description = item.Description; | 781 | rootPart.Description = item.Description; |
782 | 782 | ||
783 | List<SceneObjectPart> partList = null; | 783 | SceneObjectPart[] partList = group.Parts; |
784 | |||
785 | lock (group.Children) | ||
786 | partList = new List<SceneObjectPart>(group.Children.Values); | ||
787 | 784 | ||
788 | group.SetGroup(m_part.GroupID, null); | 785 | group.SetGroup(m_part.GroupID, null); |
789 | 786 | ||
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 8da9bdc..b3df1ea 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1884,7 +1884,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1884 | // If the primitive the player clicked on has no sit target, and one or more other linked objects have sit targets that are not full, the sit target of the object with the lowest link number will be used. | 1884 | // If the primitive the player clicked on has no sit target, and one or more other linked objects have sit targets that are not full, the sit target of the object with the lowest link number will be used. |
1885 | 1885 | ||
1886 | // Get our own copy of the part array, and sort into the order we want to test | 1886 | // Get our own copy of the part array, and sort into the order we want to test |
1887 | SceneObjectPart[] partArray = targetPart.ParentGroup.GetParts(); | 1887 | SceneObjectPart[] partArray = targetPart.ParentGroup.Parts; |
1888 | Array.Sort(partArray, delegate(SceneObjectPart p1, SceneObjectPart p2) | 1888 | Array.Sort(partArray, delegate(SceneObjectPart p1, SceneObjectPart p2) |
1889 | { | 1889 | { |
1890 | // we want the originally selected part first, then the rest in link order -- so make the selected part link num (-1) | 1890 | // we want the originally selected part first, then the rest in link order -- so make the selected part link num (-1) |
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 77e477f..dc8957c 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | |||
@@ -158,16 +158,15 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
158 | writer.WriteEndElement(); | 158 | writer.WriteEndElement(); |
159 | writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); | 159 | writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); |
160 | 160 | ||
161 | lock (sceneObject.Children) | 161 | SceneObjectPart[] parts = sceneObject.Parts; |
162 | for (int i = 0; i < parts.Length; i++) | ||
162 | { | 163 | { |
163 | foreach (SceneObjectPart part in sceneObject.Children.Values) | 164 | SceneObjectPart part = parts[i]; |
165 | if (part.UUID != sceneObject.RootPart.UUID) | ||
164 | { | 166 | { |
165 | if (part.UUID != sceneObject.RootPart.UUID) | 167 | writer.WriteStartElement(String.Empty, "Part", String.Empty); |
166 | { | 168 | ToOriginalXmlFormat(part, writer); |
167 | writer.WriteStartElement(String.Empty, "Part", String.Empty); | 169 | writer.WriteEndElement(); |
168 | ToOriginalXmlFormat(part, writer); | ||
169 | writer.WriteEndElement(); | ||
170 | } | ||
171 | } | 170 | } |
172 | } | 171 | } |
173 | 172 | ||
@@ -281,15 +280,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
281 | sceneObject.RootPart.ToXml(writer); | 280 | sceneObject.RootPart.ToXml(writer); |
282 | writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); | 281 | writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); |
283 | 282 | ||
284 | lock (sceneObject.Children) | 283 | SceneObjectPart[] parts = sceneObject.Parts; |
284 | for (int i = 0; i < parts.Length; i++) | ||
285 | { | 285 | { |
286 | foreach (SceneObjectPart part in sceneObject.Children.Values) | 286 | SceneObjectPart part = parts[i]; |
287 | { | 287 | if (part.UUID != sceneObject.RootPart.UUID) |
288 | if (part.UUID != sceneObject.RootPart.UUID) | 288 | part.ToXml(writer); |
289 | { | ||
290 | part.ToXml(writer); | ||
291 | } | ||
292 | } | ||
293 | } | 289 | } |
294 | 290 | ||
295 | writer.WriteEndElement(); // End of OtherParts | 291 | writer.WriteEndElement(); // End of OtherParts |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs index 7d9a6a9..9244bc3 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs | |||
@@ -68,7 +68,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
68 | SceneObjectGroup dupeSo | 68 | SceneObjectGroup dupeSo |
69 | = scene.SceneGraph.DuplicateObject( | 69 | = scene.SceneGraph.DuplicateObject( |
70 | part1.LocalId, new Vector3(10, 0, 0), 0, ownerId, UUID.Zero, Quaternion.Identity); | 70 | part1.LocalId, new Vector3(10, 0, 0), 0, ownerId, UUID.Zero, Quaternion.Identity); |
71 | Assert.That(dupeSo.Children.Count, Is.EqualTo(2)); | 71 | Assert.That(dupeSo.Parts.Length, Is.EqualTo(2)); |
72 | 72 | ||
73 | SceneObjectPart dupePart1 = dupeSo.GetLinkNumPart(1); | 73 | SceneObjectPart dupePart1 = dupeSo.GetLinkNumPart(1); |
74 | SceneObjectPart dupePart2 = dupeSo.GetLinkNumPart(2); | 74 | SceneObjectPart dupePart2 = dupeSo.GetLinkNumPart(2); |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index 60824be..f57cf98 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs | |||
@@ -81,12 +81,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
81 | // FIXME: Can't do this test yet since group 2 still has its root part! We can't yet null this since | 81 | // FIXME: Can't do this test yet since group 2 still has its root part! We can't yet null this since |
82 | // it might cause SOG.ProcessBackup() to fail due to the race condition. This really needs to be fixed. | 82 | // it might cause SOG.ProcessBackup() to fail due to the race condition. This really needs to be fixed. |
83 | Assert.That(grp2.IsDeleted, "SOG 2 was not registered as deleted after link."); | 83 | Assert.That(grp2.IsDeleted, "SOG 2 was not registered as deleted after link."); |
84 | Assert.That(grp2.Children.Count, Is.EqualTo(0), "Group 2 still contained children after delink."); | 84 | Assert.That(grp2.Parts.Length, Is.EqualTo(0), "Group 2 still contained children after delink."); |
85 | Assert.That(grp1.Children.Count == 2); | 85 | Assert.That(grp1.Parts.Length == 2); |
86 | 86 | ||
87 | if (debugtest) | 87 | if (debugtest) |
88 | { | 88 | { |
89 | m_log.Debug("parts: " + grp1.Children.Count); | 89 | m_log.Debug("parts: " + grp1.Parts.Length); |
90 | m_log.Debug("Group1: Pos:"+grp1.AbsolutePosition+", Rot:"+grp1.Rotation); | 90 | m_log.Debug("Group1: Pos:"+grp1.AbsolutePosition+", Rot:"+grp1.Rotation); |
91 | m_log.Debug("Group1: Prim1: OffsetPosition:"+ part1.OffsetPosition+", OffsetRotation:"+part1.RotationOffset); | 91 | m_log.Debug("Group1: Prim1: OffsetPosition:"+ part1.OffsetPosition+", OffsetRotation:"+part1.RotationOffset); |
92 | m_log.Debug("Group1: Prim2: OffsetPosition:"+part2.OffsetPosition+", OffsetRotation:"+part2.RotationOffset); | 92 | m_log.Debug("Group1: Prim2: OffsetPosition:"+part2.OffsetPosition+", OffsetRotation:"+part2.RotationOffset); |
@@ -126,7 +126,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
126 | if (debugtest) | 126 | if (debugtest) |
127 | m_log.Debug("Group2: Prim2: OffsetPosition:" + part2.AbsolutePosition + ", OffsetRotation:" + part2.RotationOffset); | 127 | m_log.Debug("Group2: Prim2: OffsetPosition:" + part2.AbsolutePosition + ", OffsetRotation:" + part2.RotationOffset); |
128 | 128 | ||
129 | Assert.That(grp1.Children.Count, Is.EqualTo(1), "Group 1 still contained part2 after delink."); | 129 | Assert.That(grp1.Parts.Length, Is.EqualTo(1), "Group 1 still contained part2 after delink."); |
130 | Assert.That(part2.AbsolutePosition == Vector3.Zero, "The absolute position should be zero"); | 130 | Assert.That(part2.AbsolutePosition == Vector3.Zero, "The absolute position should be zero"); |
131 | } | 131 | } |
132 | 132 | ||
@@ -177,22 +177,22 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
177 | grp3.LinkToGroup(grp4); | 177 | grp3.LinkToGroup(grp4); |
178 | 178 | ||
179 | // At this point we should have 4 parts total in two groups. | 179 | // At this point we should have 4 parts total in two groups. |
180 | Assert.That(grp1.Children.Count == 2, "Group1 children count should be 2"); | 180 | Assert.That(grp1.Parts.Length == 2, "Group1 children count should be 2"); |
181 | Assert.That(grp2.IsDeleted, "Group 2 was not registered as deleted after link."); | 181 | Assert.That(grp2.IsDeleted, "Group 2 was not registered as deleted after link."); |
182 | Assert.That(grp2.Children.Count, Is.EqualTo(0), "Group 2 still contained parts after delink."); | 182 | Assert.That(grp2.Parts.Length, Is.EqualTo(0), "Group 2 still contained parts after delink."); |
183 | Assert.That(grp3.Children.Count == 2, "Group3 children count should be 2"); | 183 | Assert.That(grp3.Parts.Length == 2, "Group3 children count should be 2"); |
184 | Assert.That(grp4.IsDeleted, "Group 4 was not registered as deleted after link."); | 184 | Assert.That(grp4.IsDeleted, "Group 4 was not registered as deleted after link."); |
185 | Assert.That(grp4.Children.Count, Is.EqualTo(0), "Group 4 still contained parts after delink."); | 185 | Assert.That(grp4.Parts.Length, Is.EqualTo(0), "Group 4 still contained parts after delink."); |
186 | 186 | ||
187 | if (debugtest) | 187 | if (debugtest) |
188 | { | 188 | { |
189 | m_log.Debug("--------After Link-------"); | 189 | m_log.Debug("--------After Link-------"); |
190 | m_log.Debug("Group1: parts:" + grp1.Children.Count); | 190 | m_log.Debug("Group1: parts:" + grp1.Parts.Length); |
191 | m_log.Debug("Group1: Pos:"+grp1.AbsolutePosition+", Rot:"+grp1.Rotation); | 191 | m_log.Debug("Group1: Pos:"+grp1.AbsolutePosition+", Rot:"+grp1.Rotation); |
192 | m_log.Debug("Group1: Prim1: OffsetPosition:" + part1.OffsetPosition + ", OffsetRotation:" + part1.RotationOffset); | 192 | m_log.Debug("Group1: Prim1: OffsetPosition:" + part1.OffsetPosition + ", OffsetRotation:" + part1.RotationOffset); |
193 | m_log.Debug("Group1: Prim2: OffsetPosition:"+part2.OffsetPosition+", OffsetRotation:"+ part2.RotationOffset); | 193 | m_log.Debug("Group1: Prim2: OffsetPosition:"+part2.OffsetPosition+", OffsetRotation:"+ part2.RotationOffset); |
194 | 194 | ||
195 | m_log.Debug("Group3: parts:"+grp3.Children.Count); | 195 | m_log.Debug("Group3: parts:" + grp3.Parts.Length); |
196 | m_log.Debug("Group3: Pos:"+grp3.AbsolutePosition+", Rot:"+grp3.Rotation); | 196 | m_log.Debug("Group3: Pos:"+grp3.AbsolutePosition+", Rot:"+grp3.Rotation); |
197 | m_log.Debug("Group3: Prim1: OffsetPosition:"+part3.OffsetPosition+", OffsetRotation:"+part3.RotationOffset); | 197 | m_log.Debug("Group3: Prim1: OffsetPosition:"+part3.OffsetPosition+", OffsetRotation:"+part3.RotationOffset); |
198 | m_log.Debug("Group3: Prim2: OffsetPosition:"+part4.OffsetPosition+", OffsetRotation:"+part4.RotationOffset); | 198 | m_log.Debug("Group3: Prim2: OffsetPosition:"+part4.OffsetPosition+", OffsetRotation:"+part4.RotationOffset); |
@@ -240,12 +240,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
240 | if (debugtest) | 240 | if (debugtest) |
241 | { | 241 | { |
242 | m_log.Debug("--------After De-Link-------"); | 242 | m_log.Debug("--------After De-Link-------"); |
243 | m_log.Debug("Group1: parts:" + grp1.Children.Count); | 243 | m_log.Debug("Group1: parts:" + grp1.Parts.Length); |
244 | m_log.Debug("Group1: Pos:" + grp1.AbsolutePosition + ", Rot:" + grp1.Rotation); | 244 | m_log.Debug("Group1: Pos:" + grp1.AbsolutePosition + ", Rot:" + grp1.Rotation); |
245 | m_log.Debug("Group1: Prim1: OffsetPosition:" + part1.OffsetPosition + ", OffsetRotation:" + part1.RotationOffset); | 245 | m_log.Debug("Group1: Prim1: OffsetPosition:" + part1.OffsetPosition + ", OffsetRotation:" + part1.RotationOffset); |
246 | m_log.Debug("Group1: Prim2: OffsetPosition:" + part2.OffsetPosition + ", OffsetRotation:" + part2.RotationOffset); | 246 | m_log.Debug("Group1: Prim2: OffsetPosition:" + part2.OffsetPosition + ", OffsetRotation:" + part2.RotationOffset); |
247 | 247 | ||
248 | m_log.Debug("Group3: parts:" + grp3.Children.Count); | 248 | m_log.Debug("Group3: parts:" + grp3.Parts.Length); |
249 | m_log.Debug("Group3: Pos:" + grp3.AbsolutePosition + ", Rot:" + grp3.Rotation); | 249 | m_log.Debug("Group3: Pos:" + grp3.AbsolutePosition + ", Rot:" + grp3.Rotation); |
250 | m_log.Debug("Group3: Prim1: OffsetPosition:" + part3.OffsetPosition + ", OffsetRotation:" + part3.RotationOffset); | 250 | m_log.Debug("Group3: Prim1: OffsetPosition:" + part3.OffsetPosition + ", OffsetRotation:" + part3.RotationOffset); |
251 | m_log.Debug("Group3: Prim2: OffsetPosition:" + part4.OffsetPosition + ", OffsetRotation:" + part4.RotationOffset); | 251 | m_log.Debug("Group3: Prim2: OffsetPosition:" + part4.OffsetPosition + ", OffsetRotation:" + part4.RotationOffset); |
@@ -295,9 +295,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
295 | List<SceneObjectGroup> storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID); | 295 | List<SceneObjectGroup> storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID); |
296 | 296 | ||
297 | Assert.That(storedObjects.Count, Is.EqualTo(1)); | 297 | Assert.That(storedObjects.Count, Is.EqualTo(1)); |
298 | Assert.That(storedObjects[0].Children.Count, Is.EqualTo(2)); | 298 | Assert.That(storedObjects[0].Parts.Length, Is.EqualTo(2)); |
299 | Assert.That(storedObjects[0].Children.ContainsKey(rootPartUuid)); | 299 | Assert.That(storedObjects[0].ContainsPart(rootPartUuid)); |
300 | Assert.That(storedObjects[0].Children.ContainsKey(linkPartUuid)); | 300 | Assert.That(storedObjects[0].ContainsPart(linkPartUuid)); |
301 | } | 301 | } |
302 | 302 | ||
303 | /// <summary> | 303 | /// <summary> |
@@ -338,8 +338,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
338 | List<SceneObjectGroup> storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID); | 338 | List<SceneObjectGroup> storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID); |
339 | 339 | ||
340 | Assert.That(storedObjects.Count, Is.EqualTo(1)); | 340 | Assert.That(storedObjects.Count, Is.EqualTo(1)); |
341 | Assert.That(storedObjects[0].Children.Count, Is.EqualTo(1)); | 341 | Assert.That(storedObjects[0].Parts.Length, Is.EqualTo(1)); |
342 | Assert.That(storedObjects[0].Children.ContainsKey(rootPartUuid)); | 342 | Assert.That(storedObjects[0].ContainsPart(rootPartUuid)); |
343 | } | 343 | } |
344 | } | 344 | } |
345 | } | 345 | } |
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index e3965ce..65baa52 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs | |||
@@ -121,8 +121,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
121 | // m_log.DebugFormat( | 121 | // m_log.DebugFormat( |
122 | // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); | 122 | // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); |
123 | 123 | ||
124 | foreach (SceneObjectPart part in sceneObject.GetParts()) | 124 | SceneObjectPart[] parts = sceneObject.Parts; |
125 | for (int i = 0; i < parts.Length; i++) | ||
125 | { | 126 | { |
127 | SceneObjectPart part = parts[i]; | ||
128 | |||
126 | // m_log.DebugFormat( | 129 | // m_log.DebugFormat( |
127 | // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); | 130 | // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); |
128 | 131 | ||
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs index d21b652..7f64ebd 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs | |||
@@ -121,19 +121,16 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
121 | continue; | 121 | continue; |
122 | temp = (SceneObjectGroup) currObj; | 122 | temp = (SceneObjectGroup) currObj; |
123 | 123 | ||
124 | lock (temp.Children) | 124 | if (m_CMEntityHash.ContainsKey(temp.UUID)) |
125 | { | 125 | { |
126 | if (m_CMEntityHash.ContainsKey(temp.UUID)) | 126 | foreach (SceneObjectPart part in temp.Parts) |
127 | { | 127 | if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) |
128 | foreach (SceneObjectPart part in temp.Children.Values) | ||
129 | if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) | ||
130 | missingList.Add(part); | ||
131 | } | ||
132 | else //Entire group is missing from revision. (and is a new part in region) | ||
133 | { | ||
134 | foreach (SceneObjectPart part in temp.Children.Values) | ||
135 | missingList.Add(part); | 128 | missingList.Add(part); |
136 | } | 129 | } |
130 | else //Entire group is missing from revision. (and is a new part in region) | ||
131 | { | ||
132 | foreach (SceneObjectPart part in temp.Parts) | ||
133 | missingList.Add(part); | ||
137 | } | 134 | } |
138 | } | 135 | } |
139 | return missingList; | 136 | return missingList; |
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs index 0b02a9f..3a6996e 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs | |||
@@ -167,11 +167,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
167 | public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) | 167 | public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) |
168 | { | 168 | { |
169 | // Deal with new parts not revisioned that have been deleted. | 169 | // Deal with new parts not revisioned that have been deleted. |
170 | lock (group.Children) | 170 | SceneObjectPart[] parts = group.Parts; |
171 | for (int i = 0; i < parts.Length; i++) | ||
171 | { | 172 | { |
172 | foreach (SceneObjectPart part in group.Children.Values) | 173 | if (m_MetaEntityCollection.Auras.ContainsKey(parts[i].UUID)) |
173 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) | 174 | m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(parts[i].UUID); |
174 | m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); | ||
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
@@ -210,12 +210,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
210 | { | 210 | { |
211 | temp = SceneObjectSerializer.FromXml2Format(xml); | 211 | temp = SceneObjectSerializer.FromXml2Format(xml); |
212 | temp.SetScene(scene); | 212 | temp.SetScene(scene); |
213 | 213 | ||
214 | lock (temp.Children) | 214 | SceneObjectPart[] parts = temp.Parts; |
215 | { | 215 | for (int i = 0; i < parts.Length; i++) |
216 | foreach (SceneObjectPart part in temp.Children.Values) | 216 | parts[i].RegionHandle = scene.RegionInfo.RegionHandle; |
217 | part.RegionHandle = scene.RegionInfo.RegionHandle; | ||
218 | } | ||
219 | 217 | ||
220 | ReplacementList.Add(temp.UUID, (EntityBase)temp); | 218 | ReplacementList.Add(temp.UUID, (EntityBase)temp); |
221 | } | 219 | } |
@@ -346,17 +344,16 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
346 | System.Collections.ArrayList auraList = new System.Collections.ArrayList(); | 344 | System.Collections.ArrayList auraList = new System.Collections.ArrayList(); |
347 | if (group == null) | 345 | if (group == null) |
348 | return null; | 346 | return null; |
349 | 347 | ||
350 | lock (group.Children) | 348 | SceneObjectPart[] parts = group.Parts; |
349 | for (int i = 0; i < parts.Length; i++) | ||
351 | { | 350 | { |
352 | foreach (SceneObjectPart part in group.Children.Values) | 351 | SceneObjectPart part = parts[i]; |
352 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) | ||
353 | { | 353 | { |
354 | if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) | 354 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0, 254, 0), part.Scale); |
355 | { | 355 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); |
356 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale); | 356 | auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); |
357 | ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); | ||
358 | auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); | ||
359 | } | ||
360 | } | 357 | } |
361 | } | 358 | } |
362 | 359 | ||
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs index f75f40a..3807ccd 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs | |||
@@ -186,12 +186,9 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
186 | ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); | 186 | ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); |
187 | 187 | ||
188 | // Deal with new parts not revisioned that have been deleted. | 188 | // Deal with new parts not revisioned that have been deleted. |
189 | lock (group.Children) | 189 | foreach (SceneObjectPart part in group.Parts) |
190 | { | 190 | if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) |
191 | foreach (SceneObjectPart part in group.Children.Values) | 191 | ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); |
192 | if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) | ||
193 | ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); | ||
194 | } | ||
195 | } | 192 | } |
196 | 193 | ||
197 | public void SendMetaEntitiesToNewClient(IClientAPI client) | 194 | public void SendMetaEntitiesToNewClient(IClientAPI client) |
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs index 49d20e1..0248f36 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs | |||
@@ -132,33 +132,30 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
132 | // if group is not contained in scene's list | 132 | // if group is not contained in scene's list |
133 | if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) | 133 | if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) |
134 | { | 134 | { |
135 | lock (m_UnchangedEntity.Children) | 135 | foreach (SceneObjectPart part in m_UnchangedEntity.Parts) |
136 | { | 136 | { |
137 | foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) | 137 | // if scene list no longer contains this part, display translucent part and mark with red aura |
138 | if (!ContainsKey(sceneEntityList, part.UUID)) | ||
138 | { | 139 | { |
139 | // if scene list no longer contains this part, display translucent part and mark with red aura | 140 | // if already displaying a red aura over part, make sure its red |
140 | if (!ContainsKey(sceneEntityList, part.UUID)) | 141 | if (m_AuraEntities.ContainsKey(part.UUID)) |
141 | { | 142 | { |
142 | // if already displaying a red aura over part, make sure its red | 143 | m_AuraEntities[part.UUID].SetAura(new Vector3(254, 0, 0), part.Scale); |
143 | if (m_AuraEntities.ContainsKey(part.UUID)) | 144 | } |
144 | { | 145 | else |
145 | m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale); | 146 | { |
146 | } | 147 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, |
147 | else | 148 | part.GetWorldPosition(), |
148 | { | 149 | MetaEntity.TRANSLUCENT, |
149 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | 150 | new Vector3(254, 0, 0), |
150 | part.GetWorldPosition(), | 151 | part.Scale |
151 | MetaEntity.TRANSLUCENT, | 152 | ); |
152 | new Vector3(254,0,0), | 153 | m_AuraEntities.Add(part.UUID, auraGroup); |
153 | part.Scale | ||
154 | ); | ||
155 | m_AuraEntities.Add(part.UUID, auraGroup); | ||
156 | } | ||
157 | SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); | ||
158 | SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); | ||
159 | } | 154 | } |
160 | // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id | 155 | SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); |
156 | SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); | ||
161 | } | 157 | } |
158 | // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id | ||
162 | } | 159 | } |
163 | 160 | ||
164 | // a deleted part has no where to point a beam particle system, | 161 | // a deleted part has no where to point a beam particle system, |
@@ -183,11 +180,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
183 | /// </summary> | 180 | /// </summary> |
184 | public bool HasChildPrim(UUID uuid) | 181 | public bool HasChildPrim(UUID uuid) |
185 | { | 182 | { |
186 | lock (m_UnchangedEntity.Children) | 183 | return m_UnchangedEntity.ContainsPart(uuid); |
187 | if (m_UnchangedEntity.Children.ContainsKey(uuid)) | ||
188 | return true; | ||
189 | |||
190 | return false; | ||
191 | } | 184 | } |
192 | 185 | ||
193 | /// <summary> | 186 | /// <summary> |
@@ -195,12 +188,9 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
195 | /// </summary> | 188 | /// </summary> |
196 | public bool HasChildPrim(uint localID) | 189 | public bool HasChildPrim(uint localID) |
197 | { | 190 | { |
198 | lock (m_UnchangedEntity.Children) | 191 | foreach (SceneObjectPart part in m_UnchangedEntity.Parts) |
199 | { | 192 | if (part.LocalId == localID) |
200 | foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) | 193 | return true; |
201 | if (part.LocalId == localID) | ||
202 | return true; | ||
203 | } | ||
204 | 194 | ||
205 | return false; | 195 | return false; |
206 | } | 196 | } |
@@ -237,72 +227,37 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
237 | // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user | 227 | // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user |
238 | // had originally saved. | 228 | // had originally saved. |
239 | // m_Entity will NOT necessarily be the same entity as the user had saved. | 229 | // m_Entity will NOT necessarily be the same entity as the user had saved. |
240 | lock (m_UnchangedEntity.Children) | 230 | foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Parts) |
241 | { | 231 | { |
242 | foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) | 232 | //This is the part that we use to show changes. |
233 | metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); | ||
234 | if (sceneEntityGroup.ContainsPart(UnchangedPart.UUID)) | ||
243 | { | 235 | { |
244 | //This is the part that we use to show changes. | 236 | sceneEntityPart = sceneEntityGroup.GetChildPart(UnchangedPart.UUID); |
245 | metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); | 237 | differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); |
246 | if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID)) | 238 | if (differences != Diff.NONE) |
239 | metaEntityPart.Text = "CHANGE: " + differences.ToString(); | ||
240 | if (differences != 0) | ||
247 | { | 241 | { |
248 | sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; | 242 | // Root Part that has been modified |
249 | differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); | 243 | if ((differences & Diff.POSITION) > 0) |
250 | if (differences != Diff.NONE) | ||
251 | metaEntityPart.Text = "CHANGE: " + differences.ToString(); | ||
252 | if (differences != 0) | ||
253 | { | ||
254 | // Root Part that has been modified | ||
255 | if ((differences&Diff.POSITION) > 0) | ||
256 | { | ||
257 | // If the position of any part has changed, make sure the RootPart of the | ||
258 | // meta entity is pointing with a beam particle system | ||
259 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | ||
260 | { | ||
261 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | ||
262 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | ||
263 | } | ||
264 | BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, | ||
265 | m_UnchangedEntity.RootPart.GetWorldPosition(), | ||
266 | MetaEntity.TRANSLUCENT, | ||
267 | sceneEntityPart, | ||
268 | new Vector3(0,0,254) | ||
269 | ); | ||
270 | m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); | ||
271 | } | ||
272 | |||
273 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
274 | { | ||
275 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
276 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
277 | } | ||
278 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
279 | UnchangedPart.GetWorldPosition(), | ||
280 | MetaEntity.TRANSLUCENT, | ||
281 | new Vector3(0,0,254), | ||
282 | UnchangedPart.Scale | ||
283 | ); | ||
284 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | ||
285 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | ||
286 | |||
287 | DiffersFromSceneGroup = true; | ||
288 | } | ||
289 | else // no differences between scene part and meta part | ||
290 | { | 244 | { |
245 | // If the position of any part has changed, make sure the RootPart of the | ||
246 | // meta entity is pointing with a beam particle system | ||
291 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | 247 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) |
292 | { | 248 | { |
293 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | 249 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); |
294 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | 250 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); |
295 | } | 251 | } |
296 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | 252 | BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, |
297 | { | 253 | m_UnchangedEntity.RootPart.GetWorldPosition(), |
298 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | 254 | MetaEntity.TRANSLUCENT, |
299 | m_AuraEntities.Remove(UnchangedPart.UUID); | 255 | sceneEntityPart, |
300 | } | 256 | new Vector3(0, 0, 254) |
301 | SetPartTransparency(metaEntityPart, MetaEntity.NONE); | 257 | ); |
258 | m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); | ||
302 | } | 259 | } |
303 | } | 260 | |
304 | else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. | ||
305 | { | ||
306 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | 261 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) |
307 | { | 262 | { |
308 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | 263 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); |
@@ -311,14 +266,46 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
311 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | 266 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, |
312 | UnchangedPart.GetWorldPosition(), | 267 | UnchangedPart.GetWorldPosition(), |
313 | MetaEntity.TRANSLUCENT, | 268 | MetaEntity.TRANSLUCENT, |
314 | new Vector3(254,0,0), | 269 | new Vector3(0, 0, 254), |
315 | UnchangedPart.Scale | 270 | UnchangedPart.Scale |
316 | ); | 271 | ); |
317 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | 272 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); |
318 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | 273 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); |
319 | 274 | ||
320 | DiffersFromSceneGroup = true; | 275 | DiffersFromSceneGroup = true; |
321 | } | 276 | } |
277 | else // no differences between scene part and meta part | ||
278 | { | ||
279 | if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) | ||
280 | { | ||
281 | m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); | ||
282 | m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); | ||
283 | } | ||
284 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
285 | { | ||
286 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
287 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
288 | } | ||
289 | SetPartTransparency(metaEntityPart, MetaEntity.NONE); | ||
290 | } | ||
291 | } | ||
292 | else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. | ||
293 | { | ||
294 | if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) | ||
295 | { | ||
296 | m_AuraEntities[UnchangedPart.UUID].HideFromAll(); | ||
297 | m_AuraEntities.Remove(UnchangedPart.UUID); | ||
298 | } | ||
299 | AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, | ||
300 | UnchangedPart.GetWorldPosition(), | ||
301 | MetaEntity.TRANSLUCENT, | ||
302 | new Vector3(254, 0, 0), | ||
303 | UnchangedPart.Scale | ||
304 | ); | ||
305 | m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); | ||
306 | SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); | ||
307 | |||
308 | DiffersFromSceneGroup = true; | ||
322 | } | 309 | } |
323 | } | 310 | } |
324 | 311 | ||
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs index d7838c5..c7b1ed7 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs | |||
@@ -98,10 +98,9 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
98 | 98 | ||
99 | #region Public Properties | 99 | #region Public Properties |
100 | 100 | ||
101 | public Dictionary<UUID, SceneObjectPart> Children | 101 | public SceneObjectPart[] Parts |
102 | { | 102 | { |
103 | get { return m_Entity.Children; } | 103 | get { return m_Entity.Parts; } |
104 | set { m_Entity.Children = value; } | ||
105 | } | 104 | } |
106 | 105 | ||
107 | public uint LocalId | 106 | public uint LocalId |
@@ -150,19 +149,17 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
150 | { | 149 | { |
151 | //make new uuids | 150 | //make new uuids |
152 | Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>(); | 151 | Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>(); |
153 | 152 | ||
154 | lock (m_Entity.Children) | 153 | foreach (SceneObjectPart part in m_Entity.Parts) |
155 | { | 154 | { |
156 | foreach (SceneObjectPart part in m_Entity.Children.Values) | 155 | part.ResetIDs(part.LinkNum); |
157 | { | 156 | parts.Add(part.UUID, part); |
158 | part.ResetIDs(part.LinkNum); | ||
159 | parts.Add(part.UUID, part); | ||
160 | } | ||
161 | |||
162 | //finalize | ||
163 | m_Entity.RootPart.PhysActor = null; | ||
164 | m_Entity.Children = parts; | ||
165 | } | 157 | } |
158 | |||
159 | //finalize | ||
160 | m_Entity.RootPart.PhysActor = null; | ||
161 | foreach (SceneObjectPart part in parts.Values) | ||
162 | m_Entity.AddPart(part); | ||
166 | } | 163 | } |
167 | 164 | ||
168 | #endregion Protected Methods | 165 | #endregion Protected Methods |
@@ -177,11 +174,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
177 | //This deletes the group without removing from any databases. | 174 | //This deletes the group without removing from any databases. |
178 | //This is important because we are not IN any database. | 175 | //This is important because we are not IN any database. |
179 | //m_Entity.FakeDeleteGroup(); | 176 | //m_Entity.FakeDeleteGroup(); |
180 | lock (m_Entity.Children) | 177 | foreach (SceneObjectPart part in m_Entity.Parts) |
181 | { | 178 | client.SendKillObject(m_Entity.RegionHandle, part.LocalId); |
182 | foreach (SceneObjectPart part in m_Entity.Children.Values) | ||
183 | client.SendKillObject(m_Entity.RegionHandle, part.LocalId); | ||
184 | } | ||
185 | } | 179 | } |
186 | 180 | ||
187 | /// <summary> | 181 | /// <summary> |
@@ -189,15 +183,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
189 | /// </summary> | 183 | /// </summary> |
190 | public virtual void HideFromAll() | 184 | public virtual void HideFromAll() |
191 | { | 185 | { |
192 | lock (m_Entity.Children) | 186 | foreach (SceneObjectPart part in m_Entity.Parts) |
193 | { | 187 | { |
194 | foreach (SceneObjectPart part in m_Entity.Children.Values) | 188 | m_Entity.Scene.ForEachClient( |
195 | { | 189 | delegate(IClientAPI controller) |
196 | m_Entity.Scene.ForEachClient( | 190 | { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } |
197 | delegate(IClientAPI controller) | 191 | ); |
198 | { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } | ||
199 | ); | ||
200 | } | ||
201 | } | 192 | } |
202 | } | 193 | } |
203 | 194 | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs index 59ad9d8..faed522 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs | |||
@@ -193,11 +193,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
193 | 193 | ||
194 | int i = 0; | 194 | int i = 0; |
195 | 195 | ||
196 | List<SceneObjectPart> partList = null; | 196 | foreach (SceneObjectPart part in my.ParentGroup.Parts) |
197 | lock (my.ParentGroup.Children) | ||
198 | partList = new List<SceneObjectPart>(my.ParentGroup.Children.Values); | ||
199 | |||
200 | foreach (SceneObjectPart part in partList) | ||
201 | { | 197 | { |
202 | rets[i++] = new SOPObject(m_rootScene, part.LocalId, m_security); | 198 | rets[i++] = new SOPObject(m_rootScene, part.LocalId, m_security); |
203 | } | 199 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0dd1787..caa39ba 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -294,8 +294,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
294 | case ScriptBaseClass.LINK_SET: | 294 | case ScriptBaseClass.LINK_SET: |
295 | if (m_host.ParentGroup != null) | 295 | if (m_host.ParentGroup != null) |
296 | { | 296 | { |
297 | lock (m_host.ParentGroup.Children) | 297 | return new List<SceneObjectPart>(m_host.ParentGroup.Parts); |
298 | return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | ||
299 | } | 298 | } |
300 | return ret; | 299 | return ret; |
301 | 300 | ||
@@ -312,8 +311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
312 | if (m_host.ParentGroup == null) | 311 | if (m_host.ParentGroup == null) |
313 | return new List<SceneObjectPart>(); | 312 | return new List<SceneObjectPart>(); |
314 | 313 | ||
315 | lock (m_host.ParentGroup.Children) | 314 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts); |
316 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | ||
317 | 315 | ||
318 | if (ret.Contains(m_host)) | 316 | if (ret.Contains(m_host)) |
319 | ret.Remove(m_host); | 317 | ret.Remove(m_host); |
@@ -323,8 +321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
323 | if (m_host.ParentGroup == null) | 321 | if (m_host.ParentGroup == null) |
324 | return new List<SceneObjectPart>(); | 322 | return new List<SceneObjectPart>(); |
325 | 323 | ||
326 | lock (m_host.ParentGroup.Children) | 324 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts); |
327 | ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); | ||
328 | 325 | ||
329 | if (ret.Contains(m_host.ParentGroup.RootPart)) | 326 | if (ret.Contains(m_host.ParentGroup.RootPart)) |
330 | ret.Remove(m_host.ParentGroup.RootPart); | 327 | ret.Remove(m_host.ParentGroup.RootPart); |
@@ -1281,16 +1278,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1281 | if (group == null) | 1278 | if (group == null) |
1282 | return; | 1279 | return; |
1283 | bool allow = true; | 1280 | bool allow = true; |
1284 | 1281 | ||
1285 | lock (group.Children) | 1282 | foreach (SceneObjectPart part in group.Parts) |
1286 | { | 1283 | { |
1287 | foreach (SceneObjectPart part in group.Children.Values) | 1284 | if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) |
1288 | { | 1285 | { |
1289 | if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) | 1286 | allow = false; |
1290 | { | 1287 | break; |
1291 | allow = false; | ||
1292 | break; | ||
1293 | } | ||
1294 | } | 1288 | } |
1295 | } | 1289 | } |
1296 | 1290 | ||
@@ -3889,18 +3883,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3889 | case ScriptBaseClass.LINK_ALL_OTHERS: | 3883 | case ScriptBaseClass.LINK_ALL_OTHERS: |
3890 | case ScriptBaseClass.LINK_ALL_CHILDREN: | 3884 | case ScriptBaseClass.LINK_ALL_CHILDREN: |
3891 | case ScriptBaseClass.LINK_THIS: | 3885 | case ScriptBaseClass.LINK_THIS: |
3892 | lock (parentPrim.Children) | 3886 | foreach (SceneObjectPart part in parentPrim.Parts) |
3893 | { | 3887 | { |
3894 | foreach (SceneObjectPart part in parentPrim.Children.Values) | 3888 | if (part.UUID != m_host.UUID) |
3895 | { | 3889 | { |
3896 | if (part.UUID != m_host.UUID) | 3890 | childPrim = part; |
3897 | { | 3891 | break; |
3898 | childPrim = part; | ||
3899 | break; | ||
3900 | } | ||
3901 | } | 3892 | } |
3902 | break; | ||
3903 | } | 3893 | } |
3894 | break; | ||
3904 | default: | 3895 | default: |
3905 | childPrim = parentPrim.GetLinkNumPart(linknum); | 3896 | childPrim = parentPrim.GetLinkNumPart(linknum); |
3906 | if (childPrim.UUID == m_host.UUID) | 3897 | if (childPrim.UUID == m_host.UUID) |
@@ -3911,7 +3902,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3911 | if (linknum == ScriptBaseClass.LINK_ROOT) | 3902 | if (linknum == ScriptBaseClass.LINK_ROOT) |
3912 | { | 3903 | { |
3913 | // Restructuring Multiple Prims. | 3904 | // Restructuring Multiple Prims. |
3914 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); | 3905 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); |
3915 | parts.Remove(parentPrim.RootPart); | 3906 | parts.Remove(parentPrim.RootPart); |
3916 | if (parts.Count > 0) | 3907 | if (parts.Count > 0) |
3917 | { | 3908 | { |
@@ -3976,19 +3967,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3976 | if (parentPrim.RootPart.AttachmentPoint != 0) | 3967 | if (parentPrim.RootPart.AttachmentPoint != 0) |
3977 | return; // Fail silently if attached | 3968 | return; // Fail silently if attached |
3978 | 3969 | ||
3979 | lock (parentPrim.Children) | 3970 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); |
3971 | parts.Remove(parentPrim.RootPart); | ||
3972 | |||
3973 | foreach (SceneObjectPart part in parts) | ||
3980 | { | 3974 | { |
3981 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); | 3975 | parentPrim.DelinkFromGroup(part.LocalId, true); |
3982 | parts.Remove(parentPrim.RootPart); | 3976 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); |
3983 | |||
3984 | foreach (SceneObjectPart part in parts) | ||
3985 | { | ||
3986 | parentPrim.DelinkFromGroup(part.LocalId, true); | ||
3987 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | ||
3988 | } | ||
3989 | parentPrim.HasGroupChanged = true; | ||
3990 | parentPrim.ScheduleGroupForFullUpdate(); | ||
3991 | } | 3977 | } |
3978 | parentPrim.HasGroupChanged = true; | ||
3979 | parentPrim.ScheduleGroupForFullUpdate(); | ||
3992 | } | 3980 | } |
3993 | 3981 | ||
3994 | public LSL_String llGetLinkKey(int linknum) | 3982 | public LSL_String llGetLinkKey(int linknum) |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs index 41501f2..3575889 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs | |||
@@ -209,15 +209,12 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
209 | else | 209 | else |
210 | Type = 0x02; // Passive | 210 | Type = 0x02; // Passive |
211 | 211 | ||
212 | lock (part.ParentGroup.Children) | 212 | foreach (SceneObjectPart p in part.ParentGroup.Parts) |
213 | { | 213 | { |
214 | foreach (SceneObjectPart p in part.ParentGroup.Children.Values) | 214 | if (p.Inventory.ContainsScripts()) |
215 | { | 215 | { |
216 | if (p.Inventory.ContainsScripts()) | 216 | Type |= 0x08; // Scripted |
217 | { | 217 | break; |
218 | Type |= 0x08; // Scripted | ||
219 | break; | ||
220 | } | ||
221 | } | 218 | } |
222 | } | 219 | } |
223 | 220 | ||
diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs index de6e815..2e5020b 100644 --- a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs | |||
@@ -163,7 +163,7 @@ namespace OpenSim.Data.Null | |||
163 | // We can't simply store groups here because on delinking, OpenSim will not update the original group | 163 | // We can't simply store groups here because on delinking, OpenSim will not update the original group |
164 | // directly. Rather, the newly delinked parts will be updated to be in their own scene object group | 164 | // directly. Rather, the newly delinked parts will be updated to be in their own scene object group |
165 | // Therefore, we need to store parts rather than groups. | 165 | // Therefore, we need to store parts rather than groups. |
166 | foreach (SceneObjectPart prim in obj.Children.Values) | 166 | foreach (SceneObjectPart prim in obj.Parts) |
167 | { | 167 | { |
168 | m_log.DebugFormat( | 168 | m_log.DebugFormat( |
169 | "[MOCK REGION DATA PLUGIN]: Storing part {0} {1} in object {2} {3} in region {4}", | 169 | "[MOCK REGION DATA PLUGIN]: Storing part {0} {1} in object {2} {3} in region {4}", |
diff --git a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs index b47ad5d..fc44358 100644 --- a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs | |||
@@ -84,7 +84,7 @@ namespace OpenSim.Tests.Common.Mock | |||
84 | 84 | ||
85 | public List<InventoryItemBase> getInventoryInFolder(UUID folderID) | 85 | public List<InventoryItemBase> getInventoryInFolder(UUID folderID) |
86 | { | 86 | { |
87 | InventoryFolderBase folder = m_folders[folderID]; | 87 | // InventoryFolderBase folder = m_folders[folderID]; |
88 | 88 | ||
89 | // m_log.DebugFormat("[MOCK INV DB]: Getting items in folder {0} {1}", folder.Name, folder.ID); | 89 | // m_log.DebugFormat("[MOCK INV DB]: Getting items in folder {0} {1}", folder.Name, folder.ID); |
90 | 90 | ||
@@ -116,7 +116,7 @@ namespace OpenSim.Tests.Common.Mock | |||
116 | 116 | ||
117 | public List<InventoryFolderBase> getInventoryFolders(UUID parentID) | 117 | public List<InventoryFolderBase> getInventoryFolders(UUID parentID) |
118 | { | 118 | { |
119 | InventoryFolderBase parentFolder = m_folders[parentID]; | 119 | // InventoryFolderBase parentFolder = m_folders[parentID]; |
120 | 120 | ||
121 | // m_log.DebugFormat("[MOCK INV DB]: Getting folders in folder {0} {1}", parentFolder.Name, parentFolder.ID); | 121 | // m_log.DebugFormat("[MOCK INV DB]: Getting folders in folder {0} {1}", parentFolder.Name, parentFolder.ID); |
122 | 122 | ||
@@ -185,7 +185,7 @@ namespace OpenSim.Tests.Common.Mock | |||
185 | 185 | ||
186 | public void addInventoryItem(InventoryItemBase item) | 186 | public void addInventoryItem(InventoryItemBase item) |
187 | { | 187 | { |
188 | InventoryFolderBase folder = m_folders[item.Folder]; | 188 | // InventoryFolderBase folder = m_folders[item.Folder]; |
189 | 189 | ||
190 | // m_log.DebugFormat( | 190 | // m_log.DebugFormat( |
191 | // "[MOCK INV DB]: Adding inventory item {0} {1} in {2} {3}", item.Name, item.ID, folder.Name, folder.ID); | 191 | // "[MOCK INV DB]: Adding inventory item {0} {1} in {2} {3}", item.Name, item.ID, folder.Name, folder.ID); |