diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 205 |
1 files changed, 130 insertions, 75 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 94ec534..b86a564 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -104,7 +104,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
104 | 104 | ||
105 | protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalID = new Dictionary<uint, SceneObjectGroup>(); | 105 | protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalID = new Dictionary<uint, SceneObjectGroup>(); |
106 | protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>(); | 106 | protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>(); |
107 | private readonly Object m_dictionary_lock = new Object(); | ||
108 | 107 | ||
109 | private Object m_updateLock = new Object(); | 108 | private Object m_updateLock = new Object(); |
110 | 109 | ||
@@ -150,11 +149,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
150 | m_scenePresencesLock.ExitWriteLock(); | 149 | m_scenePresencesLock.ExitWriteLock(); |
151 | } | 150 | } |
152 | 151 | ||
153 | lock (m_dictionary_lock) | 152 | lock (SceneObjectGroupsByFullID) |
154 | { | ||
155 | SceneObjectGroupsByFullID.Clear(); | 153 | SceneObjectGroupsByFullID.Clear(); |
154 | lock (SceneObjectGroupsByLocalID) | ||
156 | SceneObjectGroupsByLocalID.Clear(); | 155 | SceneObjectGroupsByLocalID.Clear(); |
157 | } | ||
158 | 156 | ||
159 | Entities.Clear(); | 157 | Entities.Clear(); |
160 | } | 158 | } |
@@ -314,6 +312,42 @@ namespace OpenSim.Region.Framework.Scenes | |||
314 | 312 | ||
315 | return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); | 313 | return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); |
316 | } | 314 | } |
315 | |||
316 | /// <summary> | ||
317 | /// Add a newly created object to the scene. | ||
318 | /// </summary> | ||
319 | /// | ||
320 | /// This method does not send updates to the client - callers need to handle this themselves. | ||
321 | /// <param name="sceneObject"></param> | ||
322 | /// <param name="attachToBackup"></param> | ||
323 | /// <param name="pos">Position of the object</param> | ||
324 | /// <param name="rot">Rotation of the object</param> | ||
325 | /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param> | ||
326 | /// <returns></returns> | ||
327 | public bool AddNewSceneObject( | ||
328 | SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel) | ||
329 | { | ||
330 | AddNewSceneObject(sceneObject, true, false); | ||
331 | |||
332 | // we set it's position in world. | ||
333 | sceneObject.AbsolutePosition = pos; | ||
334 | |||
335 | if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) | ||
336 | { | ||
337 | sceneObject.ClearPartAttachmentData(); | ||
338 | } | ||
339 | |||
340 | sceneObject.UpdateGroupRotationR(rot); | ||
341 | |||
342 | //group.ApplyPhysics(m_physicalPrim); | ||
343 | if (sceneObject.RootPart.PhysActor != null && sceneObject.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) | ||
344 | { | ||
345 | sceneObject.RootPart.ApplyImpulse((vel * sceneObject.GetMass()), false); | ||
346 | sceneObject.Velocity = vel; | ||
347 | } | ||
348 | |||
349 | return true; | ||
350 | } | ||
317 | 351 | ||
318 | /// <summary> | 352 | /// <summary> |
319 | /// Add an object to the scene. This will both update the scene, and send information about the | 353 | /// Add an object to the scene. This will both update the scene, and send information about the |
@@ -350,50 +384,53 @@ namespace OpenSim.Region.Framework.Scenes | |||
350 | // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", | 384 | // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", |
351 | // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); | 385 | // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); |
352 | 386 | ||
353 | if (m_parentScene.m_clampPrimSize) | 387 | lock (sceneObject.Children) |
354 | { | 388 | { |
355 | foreach (SceneObjectPart part in sceneObject.Children.Values) | 389 | if (m_parentScene.m_clampPrimSize) |
356 | { | 390 | { |
357 | Vector3 scale = part.Shape.Scale; | 391 | foreach (SceneObjectPart part in sceneObject.Children.Values) |
358 | 392 | { | |
359 | if (scale.X > m_parentScene.m_maxNonphys) | 393 | Vector3 scale = part.Shape.Scale; |
360 | scale.X = m_parentScene.m_maxNonphys; | 394 | |
361 | if (scale.Y > m_parentScene.m_maxNonphys) | 395 | if (scale.X > m_parentScene.m_maxNonphys) |
362 | scale.Y = m_parentScene.m_maxNonphys; | 396 | scale.X = m_parentScene.m_maxNonphys; |
363 | if (scale.Z > m_parentScene.m_maxNonphys) | 397 | if (scale.Y > m_parentScene.m_maxNonphys) |
364 | scale.Z = m_parentScene.m_maxNonphys; | 398 | scale.Y = m_parentScene.m_maxNonphys; |
365 | 399 | if (scale.Z > m_parentScene.m_maxNonphys) | |
366 | part.Shape.Scale = scale; | 400 | scale.Z = m_parentScene.m_maxNonphys; |
401 | |||
402 | part.Shape.Scale = scale; | ||
403 | } | ||
367 | } | 404 | } |
405 | |||
406 | m_numPrim += sceneObject.Children.Count; | ||
368 | } | 407 | } |
369 | 408 | ||
370 | sceneObject.AttachToScene(m_parentScene); | 409 | sceneObject.AttachToScene(m_parentScene); |
371 | 410 | ||
372 | if (sendClientUpdates) | 411 | if (sendClientUpdates) |
373 | sceneObject.ScheduleGroupForFullUpdate(); | 412 | sceneObject.ScheduleGroupForFullUpdate(); |
374 | 413 | ||
375 | Entities.Add(sceneObject); | 414 | Entities.Add(sceneObject); |
376 | m_numPrim += sceneObject.Children.Count; | ||
377 | 415 | ||
378 | if (attachToBackup) | 416 | if (attachToBackup) |
379 | { | ||
380 | sceneObject.AttachToBackup(); | 417 | sceneObject.AttachToBackup(); |
381 | } | ||
382 | 418 | ||
383 | if (OnObjectCreate != null) | 419 | if (OnObjectCreate != null) |
384 | { | ||
385 | OnObjectCreate(sceneObject); | 420 | OnObjectCreate(sceneObject); |
386 | } | ||
387 | 421 | ||
388 | lock (m_dictionary_lock) | 422 | lock (SceneObjectGroupsByFullID) |
389 | { | 423 | { |
390 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; | 424 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; |
391 | SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; | ||
392 | foreach (SceneObjectPart part in sceneObject.Children.Values) | 425 | foreach (SceneObjectPart part in sceneObject.Children.Values) |
393 | { | ||
394 | SceneObjectGroupsByFullID[part.UUID] = sceneObject; | 426 | SceneObjectGroupsByFullID[part.UUID] = sceneObject; |
427 | } | ||
428 | |||
429 | lock (SceneObjectGroupsByLocalID) | ||
430 | { | ||
431 | SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; | ||
432 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
395 | SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; | 433 | SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; |
396 | } | ||
397 | } | 434 | } |
398 | } | 435 | } |
399 | 436 | ||
@@ -408,24 +445,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
408 | { | 445 | { |
409 | if (Entities.ContainsKey(uuid)) | 446 | if (Entities.ContainsKey(uuid)) |
410 | { | 447 | { |
448 | SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid]; | ||
449 | |||
411 | if (!resultOfObjectLinked) | 450 | if (!resultOfObjectLinked) |
412 | { | 451 | { |
413 | m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; | 452 | m_numPrim -= grp.PrimCount; |
414 | 453 | ||
415 | if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) | 454 | if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) |
416 | { | 455 | RemovePhysicalPrim(grp.PrimCount); |
417 | RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count); | ||
418 | } | ||
419 | } | 456 | } |
420 | 457 | ||
421 | if (OnObjectRemove != null) | 458 | if (OnObjectRemove != null) |
422 | OnObjectRemove(Entities[uuid]); | 459 | OnObjectRemove(Entities[uuid]); |
423 | 460 | ||
424 | lock (m_dictionary_lock) | 461 | lock (SceneObjectGroupsByFullID) |
425 | { | 462 | { |
426 | SceneObjectGroupsByFullID.Remove(uuid); | 463 | foreach (SceneObjectPart part in grp.Children.Values) |
427 | SceneObjectGroupsByLocalID.Remove(((SceneObjectGroup)Entities[uuid]).LocalId); | 464 | SceneObjectGroupsByFullID.Remove(part.UUID); |
465 | SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID); | ||
428 | } | 466 | } |
467 | lock (SceneObjectGroupsByLocalID) | ||
468 | { | ||
469 | foreach (SceneObjectPart part in grp.Children.Values) | ||
470 | SceneObjectGroupsByLocalID.Remove(part.LocalId); | ||
471 | SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId); | ||
472 | } | ||
473 | |||
429 | Entities.Remove(uuid); | 474 | Entities.Remove(uuid); |
430 | //SceneObjectGroup part; | 475 | //SceneObjectGroup part; |
431 | //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) | 476 | //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) |
@@ -884,7 +929,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
884 | { | 929 | { |
885 | if (SceneObjectGroupsByLocalID.TryGetValue(localID, out sog)) | 930 | if (SceneObjectGroupsByLocalID.TryGetValue(localID, out sog)) |
886 | { | 931 | { |
887 | return sog; | 932 | if (sog.HasChildPrim(localID)) |
933 | return sog; | ||
934 | SceneObjectGroupsByLocalID.Remove(localID); | ||
888 | } | 935 | } |
889 | } | 936 | } |
890 | 937 | ||
@@ -920,7 +967,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
920 | { | 967 | { |
921 | if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog)) | 968 | if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog)) |
922 | { | 969 | { |
923 | return sog; | 970 | lock (sog.Children) |
971 | { | ||
972 | if (sog.Children.ContainsKey(fullID)) | ||
973 | return sog; | ||
974 | } | ||
975 | |||
976 | SceneObjectGroupsByFullID.Remove(fullID); | ||
924 | } | 977 | } |
925 | } | 978 | } |
926 | 979 | ||
@@ -1087,9 +1140,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1087 | /// <param name="action"></param> | 1140 | /// <param name="action"></param> |
1088 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) | 1141 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) |
1089 | { | 1142 | { |
1090 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); | 1143 | List<EntityBase> objlist = Entities.GetAllByType<SceneObjectGroup>(); |
1091 | foreach (SceneObjectGroup obj in objlist) | 1144 | foreach (EntityBase ent in objlist) |
1092 | { | 1145 | { |
1146 | SceneObjectGroup obj = (SceneObjectGroup)ent; | ||
1147 | |||
1093 | try | 1148 | try |
1094 | { | 1149 | { |
1095 | action(obj); | 1150 | action(obj); |
@@ -1293,37 +1348,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1293 | /// <param name="localID"></param> | 1348 | /// <param name="localID"></param> |
1294 | /// <param name="pos"></param> | 1349 | /// <param name="pos"></param> |
1295 | /// <param name="remoteClient"></param> | 1350 | /// <param name="remoteClient"></param> |
1296 | protected internal void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) | 1351 | public void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) |
1297 | { | 1352 | { |
1298 | SceneObjectGroup group = GetGroupByPrim(localID); | 1353 | SceneObjectGroup group = GetGroupByPrim(localID); |
1354 | |||
1299 | if (group != null) | 1355 | if (group != null) |
1300 | { | 1356 | { |
1301 | |||
1302 | // Vector3 oldPos = group.AbsolutePosition; | ||
1303 | if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) | 1357 | if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) |
1304 | { | 1358 | { |
1305 | 1359 | if (m_parentScene.AttachmentsModule != null) | |
1306 | // If this is an attachment, then we need to save the modified | 1360 | m_parentScene.AttachmentsModule.UpdateAttachmentPosition(remoteClient, group, pos); |
1307 | // object back into the avatar's inventory. First we save the | ||
1308 | // attachment point information, then we update the relative | ||
1309 | // positioning (which caused this method to get driven in the | ||
1310 | // first place. Then we have to mark the object as NOT an | ||
1311 | // attachment. This is necessary in order to correctly save | ||
1312 | // and retrieve GroupPosition information for the attachment. | ||
1313 | // Then we save the asset back into the appropriate inventory | ||
1314 | // entry. Finally, we restore the object's attachment status. | ||
1315 | |||
1316 | byte attachmentPoint = group.GetAttachmentPoint(); | ||
1317 | group.UpdateGroupPosition(pos); | ||
1318 | group.RootPart.IsAttachment = false; | ||
1319 | group.AbsolutePosition = group.RootPart.AttachedPos; | ||
1320 | m_parentScene.UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); | ||
1321 | group.SetAttachmentPoint(attachmentPoint); | ||
1322 | |||
1323 | } | 1361 | } |
1324 | else | 1362 | else |
1325 | { | 1363 | { |
1326 | if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId) && m_parentScene.Permissions.CanObjectEntry(group.UUID, false, pos)) | 1364 | if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId) |
1365 | && m_parentScene.Permissions.CanObjectEntry(group.UUID, false, pos)) | ||
1327 | { | 1366 | { |
1328 | group.UpdateGroupPosition(pos); | 1367 | group.UpdateGroupPosition(pos); |
1329 | } | 1368 | } |
@@ -1332,14 +1371,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1332 | } | 1371 | } |
1333 | 1372 | ||
1334 | /// <summary> | 1373 | /// <summary> |
1335 | /// | 1374 | /// Update the texture entry of the given prim. |
1336 | /// </summary> | 1375 | /// </summary> |
1376 | /// | ||
1377 | /// A texture entry is an object that contains details of all the textures of the prim's face. In this case, | ||
1378 | /// the texture is given in its byte serialized form. | ||
1379 | /// | ||
1337 | /// <param name="localID"></param> | 1380 | /// <param name="localID"></param> |
1338 | /// <param name="texture"></param> | 1381 | /// <param name="texture"></param> |
1339 | /// <param name="remoteClient"></param> | 1382 | /// <param name="remoteClient"></param> |
1340 | protected internal void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient) | 1383 | protected internal void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient) |
1341 | { | 1384 | { |
1342 | SceneObjectGroup group = GetGroupByPrim(localID); | 1385 | SceneObjectGroup group = GetGroupByPrim(localID); |
1386 | |||
1343 | if (group != null) | 1387 | if (group != null) |
1344 | { | 1388 | { |
1345 | if (m_parentScene.Permissions.CanEditObject(group.UUID,remoteClient.AgentId)) | 1389 | if (m_parentScene.Permissions.CanEditObject(group.UUID,remoteClient.AgentId)) |
@@ -1630,7 +1674,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1630 | { | 1674 | { |
1631 | if (part != null) | 1675 | if (part != null) |
1632 | { | 1676 | { |
1633 | if (part.ParentGroup.Children.Count != 1) // Skip single | 1677 | if (part.ParentGroup.PrimCount != 1) // Skip single |
1634 | { | 1678 | { |
1635 | if (part.LinkNum < 2) // Root | 1679 | if (part.LinkNum < 2) // Root |
1636 | rootParts.Add(part); | 1680 | rootParts.Add(part); |
@@ -1669,8 +1713,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1669 | // However, editing linked parts and unlinking may be different | 1713 | // However, editing linked parts and unlinking may be different |
1670 | // | 1714 | // |
1671 | SceneObjectGroup group = root.ParentGroup; | 1715 | SceneObjectGroup group = root.ParentGroup; |
1672 | List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values); | 1716 | |
1673 | int numChildren = group.Children.Count; | 1717 | List<SceneObjectPart> newSet = null; |
1718 | int numChildren = -1; | ||
1719 | |||
1720 | lock (group.Children) | ||
1721 | { | ||
1722 | newSet = new List<SceneObjectPart>(group.Children.Values); | ||
1723 | numChildren = group.PrimCount; | ||
1724 | } | ||
1674 | 1725 | ||
1675 | // If there are prims left in a link set, but the root is | 1726 | // If there are prims left in a link set, but the root is |
1676 | // slated for unlink, we need to do this | 1727 | // slated for unlink, we need to do this |
@@ -1722,8 +1773,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1722 | SceneObjectPart newRoot = newSet[0]; | 1773 | SceneObjectPart newRoot = newSet[0]; |
1723 | newSet.RemoveAt(0); | 1774 | newSet.RemoveAt(0); |
1724 | 1775 | ||
1725 | List<uint> linkIDs = new List<uint>(); | ||
1726 | |||
1727 | foreach (SceneObjectPart newChild in newSet) | 1776 | foreach (SceneObjectPart newChild in newSet) |
1728 | newChild.UpdateFlag = 0; | 1777 | newChild.UpdateFlag = 0; |
1729 | 1778 | ||
@@ -1760,12 +1809,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1760 | { | 1809 | { |
1761 | if (ent is SceneObjectGroup) | 1810 | if (ent is SceneObjectGroup) |
1762 | { | 1811 | { |
1763 | foreach (KeyValuePair<UUID, SceneObjectPart> subent in ((SceneObjectGroup)ent).Children) | 1812 | SceneObjectGroup sog = ent as SceneObjectGroup; |
1813 | |||
1814 | lock (sog.Children) | ||
1764 | { | 1815 | { |
1765 | if (subent.Value.LocalId == localID) | 1816 | foreach (KeyValuePair<UUID, SceneObjectPart> subent in sog.Children) |
1766 | { | 1817 | { |
1767 | objid = subent.Key; | 1818 | if (subent.Value.LocalId == localID) |
1768 | obj = subent.Value; | 1819 | { |
1820 | objid = subent.Key; | ||
1821 | obj = subent.Value; | ||
1822 | } | ||
1769 | } | 1823 | } |
1770 | } | 1824 | } |
1771 | } | 1825 | } |
@@ -1830,7 +1884,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1830 | SceneObjectGroup original = GetGroupByPrim(originalPrimID); | 1884 | SceneObjectGroup original = GetGroupByPrim(originalPrimID); |
1831 | if (original != null) | 1885 | if (original != null) |
1832 | { | 1886 | { |
1833 | if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition)) | 1887 | if (m_parentScene.Permissions.CanDuplicateObject( |
1888 | original.PrimCount, original.UUID, AgentID, original.AbsolutePosition)) | ||
1834 | { | 1889 | { |
1835 | SceneObjectGroup copy = original.Copy(true); | 1890 | SceneObjectGroup copy = original.Copy(true); |
1836 | copy.AbsolutePosition = copy.AbsolutePosition + offset; | 1891 | copy.AbsolutePosition = copy.AbsolutePosition + offset; |