aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneGraph.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs205
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;