aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityBase.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/Prioritizer.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs62
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs493
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs155
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs233
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs13
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs1064
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs973
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs1093
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs92
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs53
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs172
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs80
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs28
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs104
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs66
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs (renamed from OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs)224
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs (renamed from OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs)14
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs18
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/UndoState.cs298
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs11
36 files changed, 2717 insertions, 2677 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 9c103cb..4925175 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -27,6 +27,8 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
30using OpenMetaverse; 32using OpenMetaverse;
31using OpenSim.Framework; 33using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
@@ -40,6 +42,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
40 /// </summary> 42 /// </summary>
41 public class ScenePresenceAnimator 43 public class ScenePresenceAnimator
42 { 44 {
45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
43 public AnimationSet Animations 47 public AnimationSet Animations
44 { 48 {
45 get { return m_animations; } 49 get { return m_animations; }
@@ -79,6 +83,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
79 if (m_scenePresence.IsChildAgent) 83 if (m_scenePresence.IsChildAgent)
80 return; 84 return;
81 85
86// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name);
87
82 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID)) 88 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID))
83 SendAnimPack(); 89 SendAnimPack();
84 } 90 }
@@ -93,6 +99,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
93 if (animID == UUID.Zero) 99 if (animID == UUID.Zero)
94 return; 100 return;
95 101
102// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} {1} for {2}", animID, name, m_scenePresence.Name);
103
96 AddAnimation(animID, objectID); 104 AddAnimation(animID, objectID);
97 } 105 }
98 106
@@ -136,6 +144,10 @@ TrySetMovementAnimation("STAND");
136 if (m_animations.TrySetDefaultAnimation( 144 if (m_animations.TrySetDefaultAnimation(
137 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) 145 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
138 { 146 {
147// m_log.DebugFormat(
148// "[SCENE PRESENCE ANIMATOR]: Updating movement animation to {0} for {1}",
149// anim, m_scenePresence.Name);
150
139 // 16384 is CHANGED_ANIMATION 151 // 16384 is CHANGED_ANIMATION
140 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION}); 152 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION});
141 SendAnimPack(); 153 SendAnimPack();
@@ -353,7 +365,7 @@ TrySetMovementAnimation("STAND");
353/* This section removed, replaced by jumping section 365/* This section removed, replaced by jumping section
354 m_animTickFall = 0; 366 m_animTickFall = 0;
355 367
356 if (move.Z > 0f) 368 if (move.Z > 0.2f)
357 { 369 {
358 // Jumping 370 // Jumping
359 if (!jumping) 371 if (!jumping)
diff --git a/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs b/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs
index 06cd14b..9cb5674 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs
@@ -70,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes
70 /// </remarks> 70 /// </remarks>
71 public class AsyncInventorySender 71 public class AsyncInventorySender
72 { 72 {
73 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 73// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
74 74
75 protected Scene m_scene; 75 protected Scene m_scene;
76 76
diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs
index 6fd38e5..213431a 100644
--- a/OpenSim/Region/Framework/Scenes/EntityBase.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs
@@ -66,12 +66,7 @@ namespace OpenSim.Region.Framework.Scenes
66 /// <summary> 66 /// <summary>
67 /// Signals whether this entity was in a scene but has since been removed from it. 67 /// Signals whether this entity was in a scene but has since been removed from it.
68 /// </summary> 68 /// </summary>
69 public bool IsDeleted 69 public bool IsDeleted { get; protected internal set; }
70 {
71 get { return m_isDeleted; }
72 set { m_isDeleted = value; }
73 }
74 protected bool m_isDeleted;
75 70
76 protected Vector3 m_pos; 71 protected Vector3 m_pos;
77 72
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 3ec4e59..65c6a29 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -169,8 +169,7 @@ namespace OpenSim.Region.Framework.Scenes
169 public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID); 169 public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID);
170 public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel; 170 public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel;
171 171
172 public delegate void SignificantClientMovement(IClientAPI remote_client); 172 public event Action<ScenePresence> OnSignificantClientMovement;
173 public event SignificantClientMovement OnSignificantClientMovement;
174 173
175 public delegate void IncomingInstantMessage(GridInstantMessage message); 174 public delegate void IncomingInstantMessage(GridInstantMessage message);
176 public event IncomingInstantMessage OnIncomingInstantMessage; 175 public event IncomingInstantMessage OnIncomingInstantMessage;
@@ -1616,16 +1615,16 @@ namespace OpenSim.Region.Framework.Scenes
1616 } 1615 }
1617 } 1616 }
1618 1617
1619 public void TriggerSignificantClientMovement(IClientAPI client) 1618 public void TriggerSignificantClientMovement(ScenePresence presence)
1620 { 1619 {
1621 SignificantClientMovement handlerSignificantClientMovement = OnSignificantClientMovement; 1620 Action<ScenePresence> handlerSignificantClientMovement = OnSignificantClientMovement;
1622 if (handlerSignificantClientMovement != null) 1621 if (handlerSignificantClientMovement != null)
1623 { 1622 {
1624 foreach (SignificantClientMovement d in handlerSignificantClientMovement.GetInvocationList()) 1623 foreach (Action<ScenePresence> d in handlerSignificantClientMovement.GetInvocationList())
1625 { 1624 {
1626 try 1625 try
1627 { 1626 {
1628 d(client); 1627 d(presence);
1629 } 1628 }
1630 catch (Exception e) 1629 catch (Exception e)
1631 { 1630 {
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
index 657df15..0a34a4c 100644
--- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs
+++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
@@ -116,14 +116,13 @@ namespace OpenSim.Region.Framework.Scenes
116 return priority; 116 return priority;
117 } 117 }
118 118
119
120 private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity) 119 private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity)
121 { 120 {
122 // And anything attached to this avatar gets top priority as well 121 // And anything attached to this avatar gets top priority as well
123 if (entity is SceneObjectPart) 122 if (entity is SceneObjectPart)
124 { 123 {
125 SceneObjectPart sop = (SceneObjectPart)entity; 124 SceneObjectPart sop = (SceneObjectPart)entity;
126 if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) 125 if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
127 return 1; 126 return 1;
128 } 127 }
129 128
@@ -136,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes
136 if (entity is SceneObjectPart) 135 if (entity is SceneObjectPart)
137 { 136 {
138 SceneObjectPart sop = (SceneObjectPart)entity; 137 SceneObjectPart sop = (SceneObjectPart)entity;
139 if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) 138 if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
140 return 1; 139 return 1;
141 } 140 }
142 141
@@ -149,7 +148,7 @@ namespace OpenSim.Region.Framework.Scenes
149 if (entity is SceneObjectPart) 148 if (entity is SceneObjectPart)
150 { 149 {
151 SceneObjectPart sop = (SceneObjectPart)entity; 150 SceneObjectPart sop = (SceneObjectPart)entity;
152 if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.RootPart.AttachedAvatar) 151 if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
153 return 1; 152 return 1;
154 } 153 }
155 154
@@ -172,7 +171,7 @@ namespace OpenSim.Region.Framework.Scenes
172 if (entity is SceneObjectPart) 171 if (entity is SceneObjectPart)
173 { 172 {
174 // Attachments are high priority, 173 // Attachments are high priority,
175 if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) 174 if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
176 return 1; 175 return 1;
177 176
178 // Non physical prims are lower priority than physical prims 177 // Non physical prims are lower priority than physical prims
@@ -209,8 +208,7 @@ namespace OpenSim.Region.Framework.Scenes
209 if (entity is SceneObjectPart) 208 if (entity is SceneObjectPart)
210 { 209 {
211 SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; 210 SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup;
212 if (group != null) 211 entityPos = group.AbsolutePosition;
213 entityPos = group.AbsolutePosition;
214 } 212 }
215 213
216 // Use the camera position for local agents and avatar position for remote agents 214 // Use the camera position for local agents and avatar position for remote agents
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index dbefb4a..c2ec5d0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -57,11 +57,11 @@ namespace OpenSim.Region.Framework.Scenes
57 protected AsyncInventorySender m_asyncInventorySender; 57 protected AsyncInventorySender m_asyncInventorySender;
58 58
59 /// <summary> 59 /// <summary>
60 /// Start all the scripts in the scene which should be started. 60 /// Creates all the scripts in the scene which should be started.
61 /// </summary> 61 /// </summary>
62 public void CreateScriptInstances() 62 public void CreateScriptInstances()
63 { 63 {
64 m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); 64 m_log.Info("[PRIM INVENTORY]: Creating scripts in scene");
65 65
66 EntityBase[] entities = Entities.GetEntities(); 66 EntityBase[] entities = Entities.GetEntities();
67 foreach (EntityBase group in entities) 67 foreach (EntityBase group in entities)
@@ -74,6 +74,26 @@ namespace OpenSim.Region.Framework.Scenes
74 } 74 }
75 } 75 }
76 76
77 /// <summary>
78 /// Lets the script engines start processing scripts.
79 /// </summary>
80 public void StartScripts()
81 {
82 m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
83
84 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
85 if (engines != null)
86 {
87 foreach (IScriptModule engine in engines)
88 {
89 if (engine != null)
90 {
91 engine.StartProcessing();
92 }
93 }
94 }
95 }
96
77 public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) 97 public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item)
78 { 98 {
79 IMoneyModule money = RequestModuleInterface<IMoneyModule>(); 99 IMoneyModule money = RequestModuleInterface<IMoneyModule>();
@@ -211,16 +231,10 @@ namespace OpenSim.Region.Framework.Scenes
211 231
212 // Retrieve group 232 // Retrieve group
213 SceneObjectPart part = GetSceneObjectPart(primId); 233 SceneObjectPart part = GetSceneObjectPart(primId);
214 SceneObjectGroup group = part.ParentGroup; 234 if (part == null)
215 if (null == group)
216 {
217 m_log.ErrorFormat(
218 "[PRIM INVENTORY]: " +
219 "Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
220 itemId, primId);
221
222 return new ArrayList(); 235 return new ArrayList();
223 } 236
237 SceneObjectGroup group = part.ParentGroup;
224 238
225 // Retrieve item 239 // Retrieve item
226 TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemId); 240 TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemId);
@@ -709,7 +723,10 @@ namespace OpenSim.Region.Framework.Scenes
709 newName = item.Name; 723 newName = item.Name;
710 } 724 }
711 725
712 if (remoteClient.AgentId == oldAgentID || (LibraryService != null && LibraryService.LibraryRootFolder != null && oldAgentID == LibraryService.LibraryRootFolder.Owner)) 726 if (remoteClient.AgentId == oldAgentID
727 || (LibraryService != null
728 && LibraryService.LibraryRootFolder != null
729 && oldAgentID == LibraryService.LibraryRootFolder.Owner))
713 { 730 {
714 CreateNewInventoryItem( 731 CreateNewInventoryItem(
715 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, 732 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
@@ -971,12 +988,12 @@ namespace OpenSim.Region.Framework.Scenes
971 if (part != null) 988 if (part != null)
972 { 989 {
973 group = part.ParentGroup; 990 group = part.ParentGroup;
974 } 991 }
975 if (part != null && group != null) 992 if (part != null && group != null)
976 { 993 {
977 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) 994 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
978 return; 995 return;
979 996
980 TaskInventoryItem item = group.GetInventoryItem(localID, itemID); 997 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
981 if (item == null) 998 if (item == null)
982 return; 999 return;
@@ -986,18 +1003,10 @@ namespace OpenSim.Region.Framework.Scenes
986 part.RemoveScriptEvents(itemID); 1003 part.RemoveScriptEvents(itemID);
987 EventManager.TriggerRemoveScript(localID, itemID); 1004 EventManager.TriggerRemoveScript(localID, itemID);
988 } 1005 }
989 1006
990 group.RemoveInventoryItem(localID, itemID); 1007 group.RemoveInventoryItem(localID, itemID);
991 part.GetProperties(remoteClient); 1008 part.GetProperties(remoteClient);
992 } 1009 }
993 else
994 {
995 m_log.ErrorFormat(
996 "[PRIM INVENTORY]: " +
997 "Removal of item {0} requested of prim {1} but this prim does not exist",
998 itemID,
999 localID);
1000 }
1001 } 1010 }
1002 1011
1003 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) 1012 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
@@ -1780,7 +1789,7 @@ namespace OpenSim.Region.Framework.Scenes
1780 } 1789 }
1781 1790
1782 // Already deleted by someone else 1791 // Already deleted by someone else
1783 if (part.ParentGroup == null || part.ParentGroup.IsDeleted) 1792 if (part.ParentGroup.IsDeleted)
1784 { 1793 {
1785 //Client still thinks the object exists, kill it 1794 //Client still thinks the object exists, kill it
1786 deleteIDs.Add(localID); 1795 deleteIDs.Add(localID);
@@ -2158,6 +2167,9 @@ namespace OpenSim.Region.Framework.Scenes
2158 foreach (uint localID in localIDs) 2167 foreach (uint localID in localIDs)
2159 { 2168 {
2160 SceneObjectPart part = GetSceneObjectPart(localID); 2169 SceneObjectPart part = GetSceneObjectPart(localID);
2170 if (part == null)
2171 continue;
2172
2161 if (!groups.Contains(part.ParentGroup)) 2173 if (!groups.Contains(part.ParentGroup))
2162 groups.Add(part.ParentGroup); 2174 groups.Add(part.ParentGroup);
2163 } 2175 }
@@ -2203,6 +2215,8 @@ namespace OpenSim.Region.Framework.Scenes
2203 foreach (uint localID in localIDs) 2215 foreach (uint localID in localIDs)
2204 { 2216 {
2205 SceneObjectPart part = GetSceneObjectPart(localID); 2217 SceneObjectPart part = GetSceneObjectPart(localID);
2218 if (part == null)
2219 continue;
2206 part.GetProperties(remoteClient); 2220 part.GetProperties(remoteClient);
2207 } 2221 }
2208 } 2222 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 9bef443..9da57a8 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -191,10 +191,6 @@ namespace OpenSim.Region.Framework.Scenes
191 if (part == null) 191 if (part == null)
192 return; 192 return;
193 193
194 // The prim is in the process of being deleted.
195 if (null == part.ParentGroup.RootPart)
196 return;
197
198 // A deselect packet contains all the local prims being deselected. However, since selection is still 194 // A deselect packet contains all the local prims being deselected. However, since selection is still
199 // group based we only want the root prim to trigger a full update - otherwise on objects with many prims 195 // group based we only want the root prim to trigger a full update - otherwise on objects with many prims
200 // we end up sending many duplicate ObjectUpdates 196 // we end up sending many duplicate ObjectUpdates
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index ec82cc3..c5bb2b2 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -610,9 +610,42 @@ namespace OpenSim.Region.Framework.Scenes
610 #region Region Settings 610 #region Region Settings
611 611
612 // Load region settings 612 // Load region settings
613 m_regInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(m_regInfo.RegionID); 613 // LoadRegionSettings creates new region settings in persistence if they don't already exist for this region.
614 // However, in this case, the default textures are not set in memory properly, so we need to do it here and
615 // resave.
616 // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
617 // region is set up and avoid these gyrations.
618 RegionSettings rs = simDataService.LoadRegionSettings(m_regInfo.RegionID);
619 bool updatedTerrainTextures = false;
620 if (rs.TerrainTexture1 == UUID.Zero)
621 {
622 rs.TerrainTexture1 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_1;
623 updatedTerrainTextures = true;
624 }
625
626 if (rs.TerrainTexture2 == UUID.Zero)
627 {
628 rs.TerrainTexture2 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_2;
629 updatedTerrainTextures = true;
630 }
631
632 if (rs.TerrainTexture3 == UUID.Zero)
633 {
634 rs.TerrainTexture3 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_3;
635 updatedTerrainTextures = true;
636 }
637
638 if (rs.TerrainTexture4 == UUID.Zero)
639 {
640 rs.TerrainTexture4 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_4;
641 updatedTerrainTextures = true;
642 }
643
644 if (updatedTerrainTextures)
645 rs.Save();
646
647 m_regInfo.RegionSettings = rs;
614 648
615 m_regInfo.RegionSettings = simDataService.LoadRegionSettings(m_regInfo.RegionID);
616 if (estateDataService != null) 649 if (estateDataService != null)
617 m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false); 650 m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false);
618 651
@@ -635,13 +668,17 @@ namespace OpenSim.Region.Framework.Scenes
635 "delete object name <name>", 668 "delete object name <name>",
636 "Delete object by name", HandleDeleteObject); 669 "Delete object by name", HandleDeleteObject);
637 670
671 MainConsole.Instance.Commands.AddCommand("region", false, "delete object outside",
672 "delete object outside",
673 "Delete all objects outside boundaries", HandleDeleteObject);
674
638 //Bind Storage Manager functions to some land manager functions for this scene 675 //Bind Storage Manager functions to some land manager functions for this scene
639 EventManager.OnLandObjectAdded += 676 EventManager.OnLandObjectAdded +=
640 new EventManager.LandObjectAdded(simDataService.StoreLandObject); 677 new EventManager.LandObjectAdded(simDataService.StoreLandObject);
641 EventManager.OnLandObjectRemoved += 678 EventManager.OnLandObjectRemoved +=
642 new EventManager.LandObjectRemoved(simDataService.RemoveLandObject); 679 new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
643 680
644 m_sceneGraph = new SceneGraph(this, m_regInfo); 681 m_sceneGraph = new SceneGraph(this);
645 682
646 // If the scene graph has an Unrecoverable error, restart this sim. 683 // If the scene graph has an Unrecoverable error, restart this sim.
647 // Currently the only thing that causes it to happen is two kinds of specific 684 // Currently the only thing that causes it to happen is two kinds of specific
@@ -1571,7 +1608,9 @@ namespace OpenSim.Region.Framework.Scenes
1571 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; 1608 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
1572 msg.Position = Vector3.Zero; 1609 msg.Position = Vector3.Zero;
1573 msg.RegionID = RegionInfo.RegionID.Guid; 1610 msg.RegionID = RegionInfo.RegionID.Guid;
1574 msg.binaryBucket = new byte[0]; 1611
1612 // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
1613 msg.binaryBucket = Util.StringToBytes256("\0");
1575 if (ret.Value.count > 1) 1614 if (ret.Value.count > 1)
1576 msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); 1615 msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
1577 else 1616 else
@@ -1703,20 +1742,20 @@ namespace OpenSim.Region.Framework.Scenes
1703 1742
1704 m_sceneGridService.SetScene(this); 1743 m_sceneGridService.SetScene(this);
1705 1744
1706 // If we generate maptiles internally at all, the maptile generator 1745 GridRegion region = new GridRegion(RegionInfo);
1707 // will register the region. If not, do it here 1746 string error = GridService.RegisterRegion(RegionInfo.ScopeID, region);
1708 if (m_generateMaptiles) 1747 if (error != String.Empty)
1709 { 1748 {
1710 RegenerateMaptile(null, null); 1749 throw new Exception(error);
1711 } 1750 }
1712 else 1751
1752 // Generate the maptile asynchronously, because sometimes it can be very slow and we
1753 // don't want this to delay starting the region.
1754 if (m_generateMaptiles)
1713 { 1755 {
1714 GridRegion region = new GridRegion(RegionInfo); 1756 Util.FireAndForget(delegate {
1715 string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); 1757 RegenerateMaptile(null, null);
1716 if (error != String.Empty) 1758 });
1717 {
1718 throw new Exception(error);
1719 }
1720 } 1759 }
1721 } 1760 }
1722 1761
@@ -1757,6 +1796,7 @@ namespace OpenSim.Region.Framework.Scenes
1757 /// <summary> 1796 /// <summary>
1758 /// Loads the World's objects 1797 /// Loads the World's objects
1759 /// </summary> 1798 /// </summary>
1799 /// <param name="regionID"></param>
1760 public virtual void LoadPrimsFromStorage(UUID regionID) 1800 public virtual void LoadPrimsFromStorage(UUID regionID)
1761 { 1801 {
1762 LoadingPrims = true; 1802 LoadingPrims = true;
@@ -1769,20 +1809,13 @@ namespace OpenSim.Region.Framework.Scenes
1769 foreach (SceneObjectGroup group in PrimsFromDB) 1809 foreach (SceneObjectGroup group in PrimsFromDB)
1770 { 1810 {
1771 EventManager.TriggerOnSceneObjectLoaded(group); 1811 EventManager.TriggerOnSceneObjectLoaded(group);
1772
1773 if (group.RootPart == null)
1774 {
1775 m_log.ErrorFormat(
1776 "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
1777 group.Parts == null ? 0 : group.PrimCount);
1778 }
1779
1780 AddRestoredSceneObject(group, true, true); 1812 AddRestoredSceneObject(group, true, true);
1781 SceneObjectPart rootPart = group.GetChildPart(group.UUID); 1813 SceneObjectPart rootPart = group.GetChildPart(group.UUID);
1782 rootPart.Flags &= ~PrimFlags.Scripted; 1814 rootPart.Flags &= ~PrimFlags.Scripted;
1783 rootPart.TrimPermissions(); 1815 rootPart.TrimPermissions();
1784 group.CheckSculptAndLoad(); 1816
1785 //rootPart.DoPhysicsPropertyUpdate(UsePhysics, true); 1817 // Don't do this here - it will get done later on when sculpt data is loaded.
1818// group.CheckSculptAndLoad();
1786 } 1819 }
1787 1820
1788 m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); 1821 m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
@@ -2494,14 +2527,16 @@ namespace OpenSim.Region.Framework.Scenes
2494 /// <returns>False</returns> 2527 /// <returns>False</returns>
2495 public virtual bool IncomingCreateObject(UUID userID, UUID itemID) 2528 public virtual bool IncomingCreateObject(UUID userID, UUID itemID)
2496 { 2529 {
2497 //m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID); 2530 m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
2498 2531
2499 ScenePresence sp = GetScenePresence(userID); 2532 // Commented out since this is as yet unused and is arguably not the appropriate place to do this, as
2500 if (sp != null && AttachmentsModule != null) 2533 // attachments are being rezzed elsewhere in AddNewClient()
2501 { 2534// ScenePresence sp = GetScenePresence(userID);
2502 uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID); 2535// if (sp != null && AttachmentsModule != null)
2503 AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt); 2536// {
2504 } 2537// uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
2538// AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
2539// }
2505 2540
2506 return false; 2541 return false;
2507 } 2542 }
@@ -2643,10 +2678,11 @@ namespace OpenSim.Region.Framework.Scenes
2643 #region Add/Remove Avatar Methods 2678 #region Add/Remove Avatar Methods
2644 2679
2645 /// <summary> 2680 /// <summary>
2646 /// Adding a New Client and Create a Presence for it. 2681 /// Add a new client and create a child agent for it.
2647 /// </summary> 2682 /// </summary>
2648 /// <param name="client"></param> 2683 /// <param name="client"></param>
2649 public override void AddNewClient(IClientAPI client) 2684 /// <param name="type">The type of agent to add.</param>
2685 public override void AddNewClient(IClientAPI client, PresenceType type)
2650 { 2686 {
2651 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2687 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2652 bool vialogin = false; 2688 bool vialogin = false;
@@ -2667,7 +2703,7 @@ namespace OpenSim.Region.Framework.Scenes
2667 m_clientManager.Add(client); 2703 m_clientManager.Add(client);
2668 SubscribeToClientEvents(client); 2704 SubscribeToClientEvents(client);
2669 2705
2670 ScenePresence sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance); 2706 ScenePresence sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2671 m_eventManager.TriggerOnNewPresence(sp); 2707 m_eventManager.TriggerOnNewPresence(sp);
2672 2708
2673 sp.TeleportFlags = (TeleportFlags)aCircuit.teleportFlags; 2709 sp.TeleportFlags = (TeleportFlags)aCircuit.teleportFlags;
@@ -2678,16 +2714,17 @@ namespace OpenSim.Region.Framework.Scenes
2678 if (aCircuit.child == false) 2714 if (aCircuit.child == false)
2679 { 2715 {
2680 sp.IsChildAgent = false; 2716 sp.IsChildAgent = false;
2681 Util.FireAndForget(delegate(object o) { sp.RezAttachments(); }); 2717 Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
2682 } 2718 }
2683 } 2719 }
2684 2720
2685 if (TryGetScenePresence(client.AgentId, out presence)) 2721 ScenePresence createdSp = GetScenePresence(client.AgentId);
2722 if (createdSp != null)
2686 { 2723 {
2687 m_LastLogin = Util.EnvironmentTickCount(); 2724 m_LastLogin = Util.EnvironmentTickCount();
2688 2725
2689 // Cache the user's name 2726 // Cache the user's name
2690 CacheUserName(aCircuit); 2727 CacheUserName(createdSp, aCircuit);
2691 2728
2692 EventManager.TriggerOnNewClient(client); 2729 EventManager.TriggerOnNewClient(client);
2693 if (vialogin) 2730 if (vialogin)
@@ -2695,35 +2732,48 @@ namespace OpenSim.Region.Framework.Scenes
2695 EventManager.TriggerOnClientLogin(client); 2732 EventManager.TriggerOnClientLogin(client);
2696 2733
2697 // Send initial parcel data 2734 // Send initial parcel data
2698 Vector3 pos = presence.AbsolutePosition; 2735 Vector3 pos = createdSp.AbsolutePosition;
2699 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y); 2736 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2700 land.SendLandUpdateToClient(presence.ControllingClient); 2737 land.SendLandUpdateToClient(client);
2701 } 2738 }
2702 } 2739 }
2703 } 2740 }
2704 2741
2705 private void CacheUserName(AgentCircuitData aCircuit) 2742 /// <summary>
2743 /// Cache the user name for later use.
2744 /// </summary>
2745 /// <param name="sp"></param>
2746 /// <param name="aCircuit"></param>
2747 private void CacheUserName(ScenePresence sp, AgentCircuitData aCircuit)
2706 { 2748 {
2707 IUserManagement uMan = RequestModuleInterface<IUserManagement>(); 2749 IUserManagement uMan = RequestModuleInterface<IUserManagement>();
2708 if (uMan != null) 2750 if (uMan != null)
2709 { 2751 {
2710 string homeURL = string.Empty;
2711 string first = aCircuit.firstname, last = aCircuit.lastname; 2752 string first = aCircuit.firstname, last = aCircuit.lastname;
2712 2753
2713 if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) 2754 if (sp.PresenceType == PresenceType.Npc)
2714 homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
2715
2716 if (aCircuit.lastname.StartsWith("@"))
2717 { 2755 {
2718 string[] parts = aCircuit.firstname.Split('.'); 2756 uMan.AddUser(aCircuit.AgentID, first, last);
2719 if (parts.Length >= 2) 2757 }
2758 else
2759 {
2760 string homeURL = string.Empty;
2761
2762 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
2763 homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
2764
2765 if (aCircuit.lastname.StartsWith("@"))
2720 { 2766 {
2721 first = parts[0]; 2767 string[] parts = aCircuit.firstname.Split('.');
2722 last = parts[1]; 2768 if (parts.Length >= 2)
2769 {
2770 first = parts[0];
2771 last = parts[1];
2772 }
2723 } 2773 }
2724 }
2725 2774
2726 uMan.AddUser(aCircuit.AgentID, first, last, homeURL); 2775 uMan.AddUser(aCircuit.AgentID, first, last, homeURL);
2776 }
2727 } 2777 }
2728 } 2778 }
2729 2779
@@ -2821,12 +2871,14 @@ namespace OpenSim.Region.Framework.Scenes
2821 2871
2822 public virtual void SubscribeToClientPrimEvents(IClientAPI client) 2872 public virtual void SubscribeToClientPrimEvents(IClientAPI client)
2823 { 2873 {
2824 client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimPosition; 2874 client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition;
2825 client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition; 2875 client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition;
2826 client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimRotation; 2876
2827 client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimRotation; 2877 client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation;
2878 client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation;
2828 client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation; 2879 client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation;
2829 client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition; 2880 client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition;
2881
2830 client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale; 2882 client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale;
2831 client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale; 2883 client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale;
2832 client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam; 2884 client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam;
@@ -2856,7 +2908,6 @@ namespace OpenSim.Region.Framework.Scenes
2856 client.OnUndo += m_sceneGraph.HandleUndo; 2908 client.OnUndo += m_sceneGraph.HandleUndo;
2857 client.OnRedo += m_sceneGraph.HandleRedo; 2909 client.OnRedo += m_sceneGraph.HandleRedo;
2858 client.OnObjectDescription += m_sceneGraph.PrimDescription; 2910 client.OnObjectDescription += m_sceneGraph.PrimDescription;
2859 client.OnObjectDrop += m_sceneGraph.DropObject;
2860 client.OnObjectIncludeInSearch += m_sceneGraph.MakeObjectSearchable; 2911 client.OnObjectIncludeInSearch += m_sceneGraph.MakeObjectSearchable;
2861 client.OnObjectOwner += ObjectOwner; 2912 client.OnObjectOwner += ObjectOwner;
2862 } 2913 }
@@ -2949,12 +3000,14 @@ namespace OpenSim.Region.Framework.Scenes
2949 3000
2950 public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) 3001 public virtual void UnSubscribeToClientPrimEvents(IClientAPI client)
2951 { 3002 {
2952 client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimPosition; 3003 client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition;
2953 client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition; 3004 client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition;
2954 client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimRotation; 3005
2955 client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimRotation; 3006 client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation;
3007 client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation;
2956 client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation; 3008 client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation;
2957 client.OnUpdatePrimSingleRotationPosition -= m_sceneGraph.UpdatePrimSingleRotationPosition; 3009 client.OnUpdatePrimSingleRotationPosition -= m_sceneGraph.UpdatePrimSingleRotationPosition;
3010
2958 client.OnUpdatePrimScale -= m_sceneGraph.UpdatePrimScale; 3011 client.OnUpdatePrimScale -= m_sceneGraph.UpdatePrimScale;
2959 client.OnUpdatePrimGroupScale -= m_sceneGraph.UpdatePrimGroupScale; 3012 client.OnUpdatePrimGroupScale -= m_sceneGraph.UpdatePrimGroupScale;
2960 client.OnUpdateExtraParams -= m_sceneGraph.UpdateExtraParam; 3013 client.OnUpdateExtraParams -= m_sceneGraph.UpdateExtraParam;
@@ -2982,7 +3035,6 @@ namespace OpenSim.Region.Framework.Scenes
2982 client.OnUndo -= m_sceneGraph.HandleUndo; 3035 client.OnUndo -= m_sceneGraph.HandleUndo;
2983 client.OnRedo -= m_sceneGraph.HandleRedo; 3036 client.OnRedo -= m_sceneGraph.HandleRedo;
2984 client.OnObjectDescription -= m_sceneGraph.PrimDescription; 3037 client.OnObjectDescription -= m_sceneGraph.PrimDescription;
2985 client.OnObjectDrop -= m_sceneGraph.DropObject;
2986 client.OnObjectIncludeInSearch -= m_sceneGraph.MakeObjectSearchable; 3038 client.OnObjectIncludeInSearch -= m_sceneGraph.MakeObjectSearchable;
2987 client.OnObjectOwner -= ObjectOwner; 3039 client.OnObjectOwner -= ObjectOwner;
2988 } 3040 }
@@ -3098,58 +3150,51 @@ namespace OpenSim.Region.Framework.Scenes
3098 Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z); 3150 Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
3099 Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z); 3151 Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
3100 3152
3101 if (target2.ParentGroup != null) 3153 pos = target2.AbsolutePosition;
3102 { 3154 //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString());
3103 pos = target2.AbsolutePosition;
3104 //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString());
3105 3155
3106 // TODO: Raytrace better here 3156 // TODO: Raytrace better here
3107 3157
3108 //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); 3158 //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
3109 Ray NewRay = new Ray(AXOrigin, AXdirection); 3159 Ray NewRay = new Ray(AXOrigin, AXdirection);
3110 3160
3111 // Ray Trace against target here 3161 // Ray Trace against target here
3112 EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters); 3162 EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters);
3113 3163
3114 // Un-comment out the following line to Get Raytrace results printed to the console. 3164 // Un-comment out the following line to Get Raytrace results printed to the console.
3115 //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 3165 //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
3116 float ScaleOffset = 0.5f; 3166 float ScaleOffset = 0.5f;
3117 3167
3118 // If we hit something 3168 // If we hit something
3119 if (ei.HitTF) 3169 if (ei.HitTF)
3120 { 3170 {
3121 Vector3 scale = target.Scale; 3171 Vector3 scale = target.Scale;
3122 Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z); 3172 Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z);
3123 if (scaleComponent.X != 0) ScaleOffset = scale.X; 3173 if (scaleComponent.X != 0) ScaleOffset = scale.X;
3124 if (scaleComponent.Y != 0) ScaleOffset = scale.Y; 3174 if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
3125 if (scaleComponent.Z != 0) ScaleOffset = scale.Z; 3175 if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
3126 ScaleOffset = Math.Abs(ScaleOffset); 3176 ScaleOffset = Math.Abs(ScaleOffset);
3127 Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 3177 Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
3128 Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z); 3178 Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z);
3129 Vector3 offset = normal * (ScaleOffset / 2f); 3179 Vector3 offset = normal * (ScaleOffset / 2f);
3130 pos = intersectionpoint + offset; 3180 pos = intersectionpoint + offset;
3131 3181
3132 // stick in offset format from the original prim 3182 // stick in offset format from the original prim
3133 pos = pos - target.ParentGroup.AbsolutePosition; 3183 pos = pos - target.ParentGroup.AbsolutePosition;
3134 if (CopyRotates) 3184 if (CopyRotates)
3135 { 3185 {
3136 Quaternion worldRot = target2.GetWorldRotation(); 3186 Quaternion worldRot = target2.GetWorldRotation();
3137 3187
3138 // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); 3188 // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
3139 m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot); 3189 m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
3140 //obj.Rotation = worldRot; 3190 //obj.Rotation = worldRot;
3141 //obj.UpdateGroupRotationR(worldRot); 3191 //obj.UpdateGroupRotationR(worldRot);
3142 } 3192 }
3143 else 3193 else
3144 { 3194 {
3145 m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID); 3195 m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID);
3146 }
3147 } 3196 }
3148
3149 return;
3150 } 3197 }
3151
3152 return;
3153 } 3198 }
3154 } 3199 }
3155 3200
@@ -3192,7 +3237,7 @@ namespace OpenSim.Region.Framework.Scenes
3192 if (aCircuit == null) 3237 if (aCircuit == null)
3193 { 3238 {
3194 m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance."); 3239 m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance.");
3195 appearance = new AvatarAppearance(client.AgentId); 3240 appearance = new AvatarAppearance();
3196 return; 3241 return;
3197 } 3242 }
3198 3243
@@ -3200,15 +3245,11 @@ namespace OpenSim.Region.Framework.Scenes
3200 if (appearance == null) 3245 if (appearance == null)
3201 { 3246 {
3202 m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName); 3247 m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName);
3203 appearance = new AvatarAppearance(client.AgentId); 3248 appearance = new AvatarAppearance();
3204 } 3249 }
3205 } 3250 }
3206 3251
3207 /// <summary> 3252 public override void RemoveClient(UUID agentID, bool closeChildAgents)
3208 /// Remove the given client from the scene.
3209 /// </summary>
3210 /// <param name="agentID"></param>
3211 public override void RemoveClient(UUID agentID)
3212 { 3253 {
3213 CheckHeartbeat(); 3254 CheckHeartbeat();
3214 bool childagentYN = false; 3255 bool childagentYN = false;
@@ -3229,15 +3270,17 @@ namespace OpenSim.Region.Framework.Scenes
3229 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName); 3270 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
3230 3271
3231 m_sceneGraph.removeUserCount(!childagentYN); 3272 m_sceneGraph.removeUserCount(!childagentYN);
3232 3273
3233 if (CapsModule != null) 3274 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3275 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3276 if (closeChildAgents && CapsModule != null)
3234 CapsModule.RemoveCaps(agentID); 3277 CapsModule.RemoveCaps(agentID);
3235 3278
3236 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever 3279 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3237 // this method is doing is HORRIBLE!!! 3280 // this method is doing is HORRIBLE!!!
3238 avatar.Scene.NeedSceneCacheClear(avatar.UUID); 3281 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3239 3282
3240 if (!avatar.IsChildAgent) 3283 if (closeChildAgents && !avatar.IsChildAgent)
3241 { 3284 {
3242 //List<ulong> childknownRegions = new List<ulong>(); 3285 //List<ulong> childknownRegions = new List<ulong>();
3243 //List<ulong> ckn = avatar.KnownChildRegionHandles; 3286 //List<ulong> ckn = avatar.KnownChildRegionHandles;
@@ -3263,11 +3306,11 @@ namespace OpenSim.Region.Framework.Scenes
3263 m_eventManager.TriggerOnRemovePresence(agentID); 3306 m_eventManager.TriggerOnRemovePresence(agentID);
3264 m_log.Debug("[Scene] Finished OnRemovePresence"); 3307 m_log.Debug("[Scene] Finished OnRemovePresence");
3265 3308
3266 if (avatar != null && (!avatar.IsChildAgent)) 3309 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3267 avatar.SaveChangedAttachments(); 3310 AttachmentsModule.SaveChangedAttachments(avatar);
3268 3311
3269 if (avatar != null && (!avatar.IsChildAgent)) 3312 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3270 avatar.SaveChangedAttachments(); 3313 AttachmentsModule.SaveChangedAttachments(avatar);
3271 3314
3272 ForEachClient( 3315 ForEachClient(
3273 delegate(IClientAPI client) 3316 delegate(IClientAPI client)
@@ -3304,7 +3347,7 @@ namespace OpenSim.Region.Framework.Scenes
3304 } 3347 }
3305 m_log.Debug("[Scene] Done. Firing RemoveCircuit"); 3348 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3306 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3349 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3307 CleanDroppedAttachments(); 3350// CleanDroppedAttachments();
3308 m_log.Debug("[Scene] The avatar has left the building"); 3351 m_log.Debug("[Scene] The avatar has left the building");
3309 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3352 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3310 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3353 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -3494,7 +3537,7 @@ namespace OpenSim.Region.Framework.Scenes
3494 // check if banned regions are to be blacked out. 3537 // check if banned regions are to be blacked out.
3495 if (vialogin || (!m_seeIntoBannedRegion)) 3538 if (vialogin || (!m_seeIntoBannedRegion))
3496 { 3539 {
3497 if (!AuthorizeUser(agent.AgentID, out reason)) 3540 if (!AuthorizeUser(agent, out reason))
3498 return false; 3541 return false;
3499 } 3542 }
3500 } 3543 }
@@ -3540,7 +3583,7 @@ namespace OpenSim.Region.Framework.Scenes
3540 3583
3541 if (vialogin) 3584 if (vialogin)
3542 { 3585 {
3543 CleanDroppedAttachments(); 3586// CleanDroppedAttachments();
3544 3587
3545 if (TestBorderCross(agent.startpos, Cardinals.E)) 3588 if (TestBorderCross(agent.startpos, Cardinals.E))
3546 { 3589 {
@@ -3690,46 +3733,31 @@ namespace OpenSim.Region.Framework.Scenes
3690 /// <param name="reason">outputs the reason to this string</param> 3733 /// <param name="reason">outputs the reason to this string</param>
3691 /// <returns>True if the region accepts this agent. False if it does not. False will 3734 /// <returns>True if the region accepts this agent. False if it does not. False will
3692 /// also return a reason.</returns> 3735 /// also return a reason.</returns>
3693 protected virtual bool AuthorizeUser(UUID agentID, out string reason) 3736 protected virtual bool AuthorizeUser(AgentCircuitData agent, out string reason)
3694 { 3737 {
3695 reason = String.Empty; 3738 reason = String.Empty;
3696 3739
3697 if (!m_strictAccessControl) return true; 3740 if (!m_strictAccessControl) return true;
3698 if (Permissions.IsGod(agentID)) return true; 3741 if (Permissions.IsGod(agent.AgentID)) return true;
3699 3742
3700 if (AuthorizationService != null) 3743 if (AuthorizationService != null)
3701 { 3744 {
3702 if (!AuthorizationService.IsAuthorizedForRegion(agentID.ToString(), RegionInfo.RegionID.ToString(),out reason)) 3745 if (!AuthorizationService.IsAuthorizedForRegion(
3746 agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason))
3703 { 3747 {
3704 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} at {1} because the user does not have access to the region", 3748 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3705 agentID, RegionInfo.RegionName); 3749 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3706 //reason = String.Format("You are not currently on the access list for {0}",RegionInfo.RegionName); 3750
3707 return false; 3751 return false;
3708 } 3752 }
3709 } 3753 }
3710 3754
3711 if (m_regInfo.EstateSettings != null) 3755 if (m_regInfo.EstateSettings != null)
3712 { 3756 {
3713 int flags = GetUserFlags(agentID); 3757 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3714 if (m_regInfo.EstateSettings.IsBanned(agentID, flags))
3715 { 3758 {
3716 //Add some more info to help users 3759 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3717 if (!m_regInfo.EstateSettings.IsBanned(agentID, 32)) 3760 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3718 {
3719 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} at {1} because the region requires age verification",
3720 agentID, RegionInfo.RegionName);
3721 reason = String.Format("Denied access to region {0}: Region requires age verification", RegionInfo.RegionName);
3722 return false;
3723 }
3724 if (!m_regInfo.EstateSettings.IsBanned(agentID, 4))
3725 {
3726 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} {1} because the region requires payment info on file",
3727 agentID, RegionInfo.RegionName);
3728 reason = String.Format("Denied access to region {0}: Region requires payment info on file", RegionInfo.RegionName);
3729 return false;
3730 }
3731 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} at {3} because the user is on the banlist",
3732 agentID, RegionInfo.RegionName);
3733 reason = String.Format("Denied access to region {0}: You have been banned from that region.", 3761 reason = String.Format("Denied access to region {0}: You have been banned from that region.",
3734 RegionInfo.RegionName); 3762 RegionInfo.RegionName);
3735 return false; 3763 return false;
@@ -3746,7 +3774,7 @@ namespace OpenSim.Region.Framework.Scenes
3746 if (groupsModule != null) 3774 if (groupsModule != null)
3747 { 3775 {
3748 GroupMembershipData[] GroupMembership = 3776 GroupMembershipData[] GroupMembership =
3749 groupsModule.GetMembershipData(agentID); 3777 groupsModule.GetMembershipData(agent.AgentID);
3750 3778
3751 if (GroupMembership != null) 3779 if (GroupMembership != null)
3752 { 3780 {
@@ -3775,16 +3803,44 @@ namespace OpenSim.Region.Framework.Scenes
3775 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!"); 3803 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!");
3776 3804
3777 if (!m_regInfo.EstateSettings.PublicAccess && 3805 if (!m_regInfo.EstateSettings.PublicAccess &&
3778 !m_regInfo.EstateSettings.HasAccess(agentID) && 3806 !m_regInfo.EstateSettings.HasAccess(agent.AgentID) &&
3779 !groupAccess) 3807 !groupAccess)
3780 { 3808 {
3781 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} at {1} because the user does not have access to the estate", 3809 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
3782 agentID, RegionInfo.RegionName); 3810 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3783 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", 3811 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
3784 RegionInfo.RegionName); 3812 RegionInfo.RegionName);
3785 return false; 3813 return false;
3786 } 3814 }
3787 3815
3816 // TODO: estate/region settings are not properly hooked up
3817 // to ILandObject.isRestrictedFromLand()
3818 // if (null != LandChannel)
3819 // {
3820 // // region seems to have local Id of 1
3821 // ILandObject land = LandChannel.GetLandObject(1);
3822 // if (null != land)
3823 // {
3824 // if (land.isBannedFromLand(agent.AgentID))
3825 // {
3826 // m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user has been banned from land",
3827 // agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3828 // reason = String.Format("Denied access to private region {0}: You are banned from that region.",
3829 // RegionInfo.RegionName);
3830 // return false;
3831 // }
3832
3833 // if (land.isRestrictedFromLand(agent.AgentID))
3834 // {
3835 // m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3836 // agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3837 // reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
3838 // RegionInfo.RegionName);
3839 // return false;
3840 // }
3841 // }
3842 // }
3843
3788 return true; 3844 return true;
3789 } 3845 }
3790 3846
@@ -4033,8 +4089,11 @@ namespace OpenSim.Region.Framework.Scenes
4033 } 4089 }
4034 4090
4035 /// <summary> 4091 /// <summary>
4036 /// Tries to teleport agent to other region. 4092 /// Tries to teleport agent to another region.
4037 /// </summary> 4093 /// </summary>
4094 /// <remarks>
4095 /// The region name must exactly match that given.
4096 /// </remarks>
4038 /// <param name="remoteClient"></param> 4097 /// <param name="remoteClient"></param>
4039 /// <param name="regionName"></param> 4098 /// <param name="regionName"></param>
4040 /// <param name="position"></param> 4099 /// <param name="position"></param>
@@ -4043,15 +4102,16 @@ namespace OpenSim.Region.Framework.Scenes
4043 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, 4102 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
4044 Vector3 lookat, uint teleportFlags) 4103 Vector3 lookat, uint teleportFlags)
4045 { 4104 {
4046 List<GridRegion> regions = GridService.GetRegionsByName(RegionInfo.ScopeID, regionName, 1); 4105 GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
4047 if (regions == null || regions.Count == 0) 4106
4107 if (region == null)
4048 { 4108 {
4049 // can't find the region: Tell viewer and abort 4109 // can't find the region: Tell viewer and abort
4050 remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found."); 4110 remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
4051 return; 4111 return;
4052 } 4112 }
4053 4113
4054 RequestTeleportLocation(remoteClient, regions[0].RegionHandle, position, lookat, teleportFlags); 4114 RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags);
4055 } 4115 }
4056 4116
4057 /// <summary> 4117 /// <summary>
@@ -4353,7 +4413,7 @@ namespace OpenSim.Region.Framework.Scenes
4353 // their scripts will actually run. 4413 // their scripts will actually run.
4354 // -- Leaf, Tue Aug 12 14:17:05 EDT 2008 4414 // -- Leaf, Tue Aug 12 14:17:05 EDT 2008
4355 SceneObjectPart parent = part.ParentGroup.RootPart; 4415 SceneObjectPart parent = part.ParentGroup.RootPart;
4356 if (parent != null && parent.IsAttachment) 4416 if (part.ParentGroup.IsAttachment)
4357 return ScriptDanger(parent, parent.GetWorldPosition()); 4417 return ScriptDanger(parent, parent.GetWorldPosition());
4358 else 4418 else
4359 return ScriptDanger(part, part.GetWorldPosition()); 4419 return ScriptDanger(part, part.GetWorldPosition());
@@ -5122,11 +5182,19 @@ namespace OpenSim.Region.Framework.Scenes
5122 5182
5123 private void HandleDeleteObject(string module, string[] cmd) 5183 private void HandleDeleteObject(string module, string[] cmd)
5124 { 5184 {
5125 if (cmd.Length < 4) 5185 if (cmd.Length < 3)
5126 return; 5186 return;
5127 5187
5128 string mode = cmd[2]; 5188 string mode = cmd[2];
5129 string o = cmd[3]; 5189 string o = "";
5190
5191 if (mode != "outside")
5192 {
5193 if (cmd.Length < 4)
5194 return;
5195
5196 o = cmd[3];
5197 }
5130 5198
5131 List<SceneObjectGroup> deletes = new List<SceneObjectGroup>(); 5199 List<SceneObjectGroup> deletes = new List<SceneObjectGroup>();
5132 5200
@@ -5168,10 +5236,35 @@ namespace OpenSim.Region.Framework.Scenes
5168 deletes.Add(g); 5236 deletes.Add(g);
5169 }); 5237 });
5170 break; 5238 break;
5239 case "outside":
5240 ForEachSOG(delegate (SceneObjectGroup g)
5241 {
5242 SceneObjectPart rootPart = g.RootPart;
5243 bool delete = false;
5244
5245 if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0)
5246 {
5247 delete = true;
5248 }
5249 else
5250 {
5251 ILandObject parcel = LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y);
5252
5253 if (parcel == null || parcel.LandData.Name == "NO LAND")
5254 delete = true;
5255 }
5256
5257 if (delete && !g.IsAttachment && !deletes.Contains(g))
5258 deletes.Add(g);
5259 });
5260 break;
5171 } 5261 }
5172 5262
5173 foreach (SceneObjectGroup g in deletes) 5263 foreach (SceneObjectGroup g in deletes)
5264 {
5265 m_log.InfoFormat("[SCENE]: Deleting object {0}", g.UUID);
5174 DeleteSceneObject(g, false); 5266 DeleteSceneObject(g, false);
5267 }
5175 } 5268 }
5176 5269
5177 private void HandleReloadEstate(string module, string[] cmd) 5270 private void HandleReloadEstate(string module, string[] cmd)
@@ -5268,45 +5361,40 @@ namespace OpenSim.Region.Framework.Scenes
5268 } 5361 }
5269 } 5362 }
5270 5363
5271 public void CleanDroppedAttachments() 5364// public void CleanDroppedAttachments()
5272 { 5365// {
5273 List<SceneObjectGroup> objectsToDelete = 5366// List<SceneObjectGroup> objectsToDelete =
5274 new List<SceneObjectGroup>(); 5367// new List<SceneObjectGroup>();
5275 5368//
5276 lock (m_cleaningAttachments) 5369// lock (m_cleaningAttachments)
5277 { 5370// {
5278 ForEachSOG(delegate (SceneObjectGroup grp) 5371// ForEachSOG(delegate (SceneObjectGroup grp)
5279 { 5372// {
5280 if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) 5373// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5281 { 5374// {
5282 UUID agentID = grp.OwnerID; 5375// UUID agentID = grp.OwnerID;
5283 if (agentID == UUID.Zero) 5376// if (agentID == UUID.Zero)
5284 { 5377// {
5285 objectsToDelete.Add(grp); 5378// objectsToDelete.Add(grp);
5286 return; 5379// return;
5287 } 5380// }
5288 5381//
5289 ScenePresence sp = GetScenePresence(agentID); 5382// ScenePresence sp = GetScenePresence(agentID);
5290 if (sp == null) 5383// if (sp == null)
5291 { 5384// {
5292 objectsToDelete.Add(grp); 5385// objectsToDelete.Add(grp);
5293 return; 5386// return;
5294 } 5387// }
5295 } 5388// }
5296 }); 5389// });
5297 } 5390// }
5298 5391//
5299 if (objectsToDelete.Count > 0) 5392// foreach (SceneObjectGroup grp in objectsToDelete)
5300 { 5393// {
5301 m_log.DebugFormat("[SCENE]: Starting delete of {0} dropped attachments", objectsToDelete.Count); 5394// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5302 foreach (SceneObjectGroup grp in objectsToDelete) 5395// DeleteSceneObject(grp, true);
5303 { 5396// }
5304 m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); 5397// }
5305 DeleteSceneObject(grp, true);
5306 }
5307 m_log.Debug("[SCENE]: Finished dropped attachment deletion");
5308 }
5309 }
5310 5398
5311 public void ThreadAlive(int threadCode) 5399 public void ThreadAlive(int threadCode)
5312 { 5400 {
@@ -5348,9 +5436,16 @@ namespace OpenSim.Region.Framework.Scenes
5348 } 5436 }
5349 } 5437 }
5350 5438
5351 if (!AuthorizeUser(agentID, out reason)) 5439 try
5440 {
5441 if (!AuthorizeUser(GetScenePresence(agentID).ControllingClient.RequestClientInfo(), out reason))
5442 {
5443 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5444 return false;
5445 }
5446 }
5447 catch
5352 { 5448 {
5353 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5354 return false; 5449 return false;
5355 } 5450 }
5356 5451
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index f343bc8..bf861b8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -177,18 +177,8 @@ namespace OpenSim.Region.Framework.Scenes
177 177
178 #region Add/Remove Agent/Avatar 178 #region Add/Remove Agent/Avatar
179 179
180 /// <summary> 180 public abstract void AddNewClient(IClientAPI client, PresenceType type);
181 /// Register the new client with the scene. The client starts off as a child agent - the later agent crossing 181 public abstract void RemoveClient(UUID agentID, bool closeChildAgents);
182 /// will promote it to a root agent during login.
183 /// </summary>
184 /// <param name="client"></param
185 public abstract void AddNewClient(IClientAPI client);
186
187 /// <summary>
188 /// Remove a client from the scene
189 /// </summary>
190 /// <param name="agentID"></param>
191 public abstract void RemoveClient(UUID agentID);
192 182
193 public bool TryGetScenePresence(UUID agentID, out object scenePresence) 183 public bool TryGetScenePresence(UUID agentID, out object scenePresence)
194 { 184 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 39d4a29..d1ee990 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -83,7 +83,6 @@ namespace OpenSim.Region.Framework.Scenes
83 83
84 protected internal EntityManager Entities = new EntityManager(); 84 protected internal EntityManager Entities = new EntityManager();
85 85
86 protected RegionInfo m_regInfo;
87 protected Scene m_parentScene; 86 protected Scene m_parentScene;
88 protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>(); 87 protected Dictionary<UUID, SceneObjectGroup> m_updateList = new Dictionary<UUID, SceneObjectGroup>();
89 protected int m_numRootAgents = 0; 88 protected int m_numRootAgents = 0;
@@ -117,10 +116,9 @@ namespace OpenSim.Region.Framework.Scenes
117 116
118 #endregion 117 #endregion
119 118
120 protected internal SceneGraph(Scene parent, RegionInfo regInfo) 119 protected internal SceneGraph(Scene parent)
121 { 120 {
122 m_parentScene = parent; 121 m_parentScene = parent;
123 m_regInfo = regInfo;
124 } 122 }
125 123
126 public PhysicsScene PhysicsScene 124 public PhysicsScene PhysicsScene
@@ -131,7 +129,6 @@ namespace OpenSim.Region.Framework.Scenes
131 // If we're not doing the initial set 129 // If we're not doing the initial set
132 // Then we've got to remove the previous 130 // Then we've got to remove the previous
133 // event handler 131 // event handler
134
135 if (_PhyScene != null) 132 if (_PhyScene != null)
136 _PhyScene.OnPhysicsCrash -= physicsBasedCrash; 133 _PhyScene.OnPhysicsCrash -= physicsBasedCrash;
137 134
@@ -403,7 +400,7 @@ namespace OpenSim.Region.Framework.Scenes
403 /// </returns> 400 /// </returns>
404 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) 401 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
405 { 402 {
406 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) 403 if (sceneObject == null || sceneObject.RootPart.UUID == UUID.Zero)
407 return false; 404 return false;
408 405
409 if (Entities.ContainsKey(sceneObject.UUID)) 406 if (Entities.ContainsKey(sceneObject.UUID))
@@ -413,12 +410,12 @@ namespace OpenSim.Region.Framework.Scenes
413// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", 410// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
414// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); 411// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);
415 412
416 SceneObjectPart[] children = sceneObject.Parts; 413 SceneObjectPart[] parts = sceneObject.Parts;
417 414
418 // Clamp child prim sizes and add child prims to the m_numPrim count 415 // Clamp child prim sizes and add child prims to the m_numPrim count
419 if (m_parentScene.m_clampPrimSize) 416 if (m_parentScene.m_clampPrimSize)
420 { 417 {
421 foreach (SceneObjectPart part in children) 418 foreach (SceneObjectPart part in parts)
422 { 419 {
423 Vector3 scale = part.Shape.Scale; 420 Vector3 scale = part.Shape.Scale;
424 421
@@ -432,7 +429,7 @@ namespace OpenSim.Region.Framework.Scenes
432 part.Shape.Scale = scale; 429 part.Shape.Scale = scale;
433 } 430 }
434 } 431 }
435 m_numPrim += children.Length; 432 m_numPrim += parts.Length;
436 433
437 sceneObject.AttachToScene(m_parentScene); 434 sceneObject.AttachToScene(m_parentScene);
438 435
@@ -452,15 +449,17 @@ namespace OpenSim.Region.Framework.Scenes
452 449
453 lock (SceneObjectGroupsByFullPartID) 450 lock (SceneObjectGroupsByFullPartID)
454 { 451 {
455 SceneObjectGroupsByFullPartID[sceneObject.UUID] = sceneObject; 452 foreach (SceneObjectPart part in parts)
456 foreach (SceneObjectPart part in children)
457 SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; 453 SceneObjectGroupsByFullPartID[part.UUID] = sceneObject;
458 } 454 }
459 455
460 lock (SceneObjectGroupsByLocalPartID) 456 lock (SceneObjectGroupsByLocalPartID)
461 { 457 {
462 SceneObjectGroupsByLocalPartID[sceneObject.LocalId] = sceneObject; 458// m_log.DebugFormat(
463 foreach (SceneObjectPart part in children) 459// "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}",
460// sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName);
461
462 foreach (SceneObjectPart part in parts)
464 SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; 463 SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject;
465 } 464 }
466 465
@@ -473,6 +472,10 @@ namespace OpenSim.Region.Framework.Scenes
473 /// <returns>true if the object was deleted, false if there was no object to delete</returns> 472 /// <returns>true if the object was deleted, false if there was no object to delete</returns>
474 public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked) 473 public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
475 { 474 {
475// m_log.DebugFormat(
476// "[SCENE GRAPH]: Deleting scene object with uuid {0}, resultOfObjectLinked = {1}",
477// uuid, resultOfObjectLinked);
478
476 EntityBase entity; 479 EntityBase entity;
477 if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup))) 480 if (!Entities.TryGetValue(uuid, out entity) || (!(entity is SceneObjectGroup)))
478 return false; 481 return false;
@@ -501,7 +504,6 @@ namespace OpenSim.Region.Framework.Scenes
501 SceneObjectPart[] parts = grp.Parts; 504 SceneObjectPart[] parts = grp.Parts;
502 for (int i = 0; i < parts.Length; i++) 505 for (int i = 0; i < parts.Length; i++)
503 SceneObjectGroupsByFullPartID.Remove(parts[i].UUID); 506 SceneObjectGroupsByFullPartID.Remove(parts[i].UUID);
504 SceneObjectGroupsByFullPartID.Remove(grp.RootPart.UUID);
505 } 507 }
506 508
507 lock (SceneObjectGroupsByLocalPartID) 509 lock (SceneObjectGroupsByLocalPartID)
@@ -509,7 +511,6 @@ namespace OpenSim.Region.Framework.Scenes
509 SceneObjectPart[] parts = grp.Parts; 511 SceneObjectPart[] parts = grp.Parts;
510 for (int i = 0; i < parts.Length; i++) 512 for (int i = 0; i < parts.Length; i++)
511 SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId); 513 SceneObjectGroupsByLocalPartID.Remove(parts[i].LocalId);
512 SceneObjectGroupsByLocalPartID.Remove(grp.RootPart.LocalId);
513 } 514 }
514 515
515 return Entities.Remove(uuid); 516 return Entities.Remove(uuid);
@@ -613,13 +614,6 @@ namespace OpenSim.Region.Framework.Scenes
613 m_activeScripts += number; 614 m_activeScripts += number;
614 } 615 }
615 616
616 public void DropObject(uint objectLocalID, IClientAPI remoteClient)
617 {
618 SceneObjectGroup group = GetGroupByPrim(objectLocalID);
619 if (group != null)
620 m_parentScene.AttachmentsModule.DetachSingleAttachmentToGround(group.UUID, remoteClient);
621 }
622
623 protected internal void HandleUndo(IClientAPI remoteClient, UUID primId) 617 protected internal void HandleUndo(IClientAPI remoteClient, UUID primId)
624 { 618 {
625 if (primId != UUID.Zero) 619 if (primId != UUID.Zero)
@@ -629,11 +623,13 @@ namespace OpenSim.Region.Framework.Scenes
629 part.Undo(); 623 part.Undo();
630 } 624 }
631 } 625 }
626
632 protected internal void HandleRedo(IClientAPI remoteClient, UUID primId) 627 protected internal void HandleRedo(IClientAPI remoteClient, UUID primId)
633 { 628 {
634 if (primId != UUID.Zero) 629 if (primId != UUID.Zero)
635 { 630 {
636 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId); 631 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primId);
632
637 if (part != null) 633 if (part != null)
638 part.Redo(); 634 part.Redo();
639 } 635 }
@@ -653,12 +649,13 @@ namespace OpenSim.Region.Framework.Scenes
653 } 649 }
654 } 650 }
655 651
656 protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) 652 protected internal ScenePresence CreateAndAddChildScenePresence(
653 IClientAPI client, AvatarAppearance appearance, PresenceType type)
657 { 654 {
658 ScenePresence newAvatar = null; 655 ScenePresence newAvatar = null;
659 656
660 // ScenePresence always defaults to child agent 657 // ScenePresence always defaults to child agent
661 newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance); 658 newAvatar = new ScenePresence(client, m_parentScene, appearance, type);
662 659
663 AddScenePresence(newAvatar); 660 AddScenePresence(newAvatar);
664 661
@@ -725,7 +722,7 @@ namespace OpenSim.Region.Framework.Scenes
725 if (!Entities.Remove(agentID)) 722 if (!Entities.Remove(agentID))
726 { 723 {
727 m_log.WarnFormat( 724 m_log.WarnFormat(
728 "[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list", 725 "[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene Entities list",
729 agentID); 726 agentID);
730 } 727 }
731 728
@@ -749,7 +746,7 @@ namespace OpenSim.Region.Framework.Scenes
749 } 746 }
750 else 747 else
751 { 748 {
752 m_log.WarnFormat("[SCENEGRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 749 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
753 } 750 }
754 } 751 }
755 finally 752 finally
@@ -960,7 +957,8 @@ namespace OpenSim.Region.Framework.Scenes
960 if (Entities.TryGetValue(localID, out entity)) 957 if (Entities.TryGetValue(localID, out entity))
961 return entity as SceneObjectGroup; 958 return entity as SceneObjectGroup;
962 959
963 //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID); 960// m_log.DebugFormat("[SCENE GRAPH]: Entered GetGroupByPrim with localID {0}", localID);
961
964 SceneObjectGroup sog; 962 SceneObjectGroup sog;
965 lock (SceneObjectGroupsByLocalPartID) 963 lock (SceneObjectGroupsByLocalPartID)
966 SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog); 964 SceneObjectGroupsByLocalPartID.TryGetValue(localID, out sog);
@@ -968,8 +966,24 @@ namespace OpenSim.Region.Framework.Scenes
968 if (sog != null) 966 if (sog != null)
969 { 967 {
970 if (sog.HasChildPrim(localID)) 968 if (sog.HasChildPrim(localID))
969 {
970// m_log.DebugFormat(
971// "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.",
972// sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
973
971 return sog; 974 return sog;
972 SceneObjectGroupsByLocalPartID.Remove(localID); 975 }
976 else
977 {
978 lock (SceneObjectGroupsByLocalPartID)
979 {
980 m_log.WarnFormat(
981 "[SCENE GRAPH]: Found scene object {0} {1} {2} via SceneObjectGroupsByLocalPartID index but it doesn't contain part with local id {3}. Removing from entry from index in {4}.",
982 sog.Name, sog.UUID, sog.LocalId, localID, m_parentScene.RegionInfo.RegionName);
983
984 SceneObjectGroupsByLocalPartID.Remove(localID);
985 }
986 }
973 } 987 }
974 988
975 EntityBase[] entityList = GetEntities(); 989 EntityBase[] entityList = GetEntities();
@@ -1285,19 +1299,20 @@ namespace OpenSim.Region.Framework.Scenes
1285 #region Client Event handlers 1299 #region Client Event handlers
1286 1300
1287 /// <summary> 1301 /// <summary>
1288 /// 1302 /// Update the scale of an individual prim.
1289 /// </summary> 1303 /// </summary>
1290 /// <param name="localID"></param> 1304 /// <param name="localID"></param>
1291 /// <param name="scale"></param> 1305 /// <param name="scale"></param>
1292 /// <param name="remoteClient"></param> 1306 /// <param name="remoteClient"></param>
1293 protected internal void UpdatePrimScale(uint localID, Vector3 scale, IClientAPI remoteClient) 1307 protected internal void UpdatePrimScale(uint localID, Vector3 scale, IClientAPI remoteClient)
1294 { 1308 {
1295 SceneObjectGroup group = GetGroupByPrim(localID); 1309 SceneObjectPart part = GetSceneObjectPart(localID);
1296 if (group != null) 1310
1311 if (part != null)
1297 { 1312 {
1298 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1313 if (m_parentScene.Permissions.CanEditObject(part.ParentGroup.UUID, remoteClient.AgentId))
1299 { 1314 {
1300 group.Resize(scale, localID); 1315 part.Resize(scale);
1301 } 1316 }
1302 } 1317 }
1303 } 1318 }
@@ -1309,7 +1324,7 @@ namespace OpenSim.Region.Framework.Scenes
1309 { 1324 {
1310 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1325 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1311 { 1326 {
1312 group.GroupResize(scale, localID); 1327 group.GroupResize(scale);
1313 } 1328 }
1314 } 1329 }
1315 } 1330 }
@@ -1363,19 +1378,18 @@ namespace OpenSim.Region.Framework.Scenes
1363 { 1378 {
1364 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)) 1379 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId))
1365 { 1380 {
1366 group.UpdateSingleRotation(rot,pos, localID); 1381 group.UpdateSingleRotation(rot, pos, localID);
1367 } 1382 }
1368 } 1383 }
1369 } 1384 }
1370 1385
1371
1372 /// <summary> 1386 /// <summary>
1373 /// 1387 /// Update the rotation of a whole group.
1374 /// </summary> 1388 /// </summary>
1375 /// <param name="localID"></param> 1389 /// <param name="localID"></param>
1376 /// <param name="rot"></param> 1390 /// <param name="rot"></param>
1377 /// <param name="remoteClient"></param> 1391 /// <param name="remoteClient"></param>
1378 protected internal void UpdatePrimRotation(uint localID, Quaternion rot, IClientAPI remoteClient) 1392 protected internal void UpdatePrimGroupRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
1379 { 1393 {
1380 SceneObjectGroup group = GetGroupByPrim(localID); 1394 SceneObjectGroup group = GetGroupByPrim(localID);
1381 if (group != null) 1395 if (group != null)
@@ -1394,7 +1408,7 @@ namespace OpenSim.Region.Framework.Scenes
1394 /// <param name="pos"></param> 1408 /// <param name="pos"></param>
1395 /// <param name="rot"></param> 1409 /// <param name="rot"></param>
1396 /// <param name="remoteClient"></param> 1410 /// <param name="remoteClient"></param>
1397 protected internal void UpdatePrimRotation(uint localID, Vector3 pos, Quaternion rot, IClientAPI remoteClient) 1411 protected internal void UpdatePrimGroupRotation(uint localID, Vector3 pos, Quaternion rot, IClientAPI remoteClient)
1398 { 1412 {
1399 SceneObjectGroup group = GetGroupByPrim(localID); 1413 SceneObjectGroup group = GetGroupByPrim(localID);
1400 if (group != null) 1414 if (group != null)
@@ -1425,12 +1439,12 @@ namespace OpenSim.Region.Framework.Scenes
1425 } 1439 }
1426 1440
1427 /// <summary> 1441 /// <summary>
1428 /// Update the position of the given part 1442 /// Update the position of the given group.
1429 /// </summary> 1443 /// </summary>
1430 /// <param name="localID"></param> 1444 /// <param name="localID"></param>
1431 /// <param name="pos"></param> 1445 /// <param name="pos"></param>
1432 /// <param name="remoteClient"></param> 1446 /// <param name="remoteClient"></param>
1433 public void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) 1447 public void UpdatePrimGroupPosition(uint localID, Vector3 pos, IClientAPI remoteClient)
1434 { 1448 {
1435 SceneObjectGroup group = GetGroupByPrim(localID); 1449 SceneObjectGroup group = GetGroupByPrim(localID);
1436 1450
@@ -1441,9 +1455,9 @@ namespace OpenSim.Region.Framework.Scenes
1441 // Set the new attachment point data in the object 1455 // Set the new attachment point data in the object
1442 byte attachmentPoint = group.GetAttachmentPoint(); 1456 byte attachmentPoint = group.GetAttachmentPoint();
1443 group.UpdateGroupPosition(pos); 1457 group.UpdateGroupPosition(pos);
1444 group.RootPart.IsAttachment = false; 1458 group.IsAttachment = false;
1445 group.AbsolutePosition = group.RootPart.AttachedPos; 1459 group.AbsolutePosition = group.RootPart.AttachedPos;
1446 group.SetAttachmentPoint(attachmentPoint); 1460 group.AttachmentPoint = attachmentPoint;
1447 group.HasGroupChanged = true; 1461 group.HasGroupChanged = true;
1448 } 1462 }
1449 else 1463 else
@@ -1481,21 +1495,26 @@ namespace OpenSim.Region.Framework.Scenes
1481 } 1495 }
1482 1496
1483 /// <summary> 1497 /// <summary>
1484 /// 1498 /// Update the flags on a scene object. This covers properties such as phantom, physics and temporary.
1485 /// </summary> 1499 /// </summary>
1500 /// <remarks>
1501 /// This is currently handling the incoming call from the client stack (e.g. LLClientView).
1502 /// </remarks>
1486 /// <param name="localID"></param> 1503 /// <param name="localID"></param>
1487 /// <param name="packet"></param> 1504 /// <param name="UsePhysics"></param>
1505 /// <param name="SetTemporary"></param>
1506 /// <param name="SetPhantom"></param>
1488 /// <param name="remoteClient"></param> 1507 /// <param name="remoteClient"></param>
1489 /// This routine seems to get called when a user changes object settings in the viewer. 1508 protected internal void UpdatePrimFlags(
1490 /// If some one can confirm that, please change the comment according. 1509 uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, IClientAPI remoteClient)
1491 protected internal void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, IClientAPI remoteClient)
1492 { 1510 {
1493 SceneObjectGroup group = GetGroupByPrim(localID); 1511 SceneObjectGroup group = GetGroupByPrim(localID);
1494 if (group != null) 1512 if (group != null)
1495 { 1513 {
1496 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1514 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1497 { 1515 {
1498 group.UpdatePrimFlags(localID, UsePhysics, IsTemporary, IsPhantom, false); // VolumeDetect can't be set via UI and will always be off when a change is made there 1516 // VolumeDetect can't be set via UI and will always be off when a change is made there
1517 group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, false);
1499 } 1518 }
1500 } 1519 }
1501 } 1520 }
@@ -1618,8 +1637,11 @@ namespace OpenSim.Region.Framework.Scenes
1618 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1637 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1619 { 1638 {
1620 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); 1639 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID);
1621 part.ClickAction = Convert.ToByte(clickAction); 1640 if (part != null)
1622 group.HasGroupChanged = true; 1641 {
1642 part.ClickAction = Convert.ToByte(clickAction);
1643 group.HasGroupChanged = true;
1644 }
1623 } 1645 }
1624 } 1646 }
1625 } 1647 }
@@ -1632,8 +1654,11 @@ namespace OpenSim.Region.Framework.Scenes
1632 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId)) 1654 if (m_parentScene.Permissions.CanEditObject(group.UUID, remoteClient.AgentId))
1633 { 1655 {
1634 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID); 1656 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primLocalID);
1635 part.Material = Convert.ToByte(material); 1657 if (part != null)
1636 group.HasGroupChanged = true; 1658 {
1659 part.Material = Convert.ToByte(material);
1660 group.HasGroupChanged = true;
1661 }
1637 } 1662 }
1638 } 1663 }
1639 } 1664 }
@@ -1706,23 +1731,23 @@ namespace OpenSim.Region.Framework.Scenes
1706 parentGroup.areUpdatesSuspended = true; 1731 parentGroup.areUpdatesSuspended = true;
1707 1732
1708 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1733 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1709 if (parentGroup != null) 1734
1735 // We do this in reverse to get the link order of the prims correct
1736 for (int i = children.Count - 1; i >= 0; i--)
1710 { 1737 {
1711 // We do this in reverse to get the link order of the prims correct 1738 SceneObjectGroup child = children[i].ParentGroup;
1712 for (int i = children.Count - 1; i >= 0; i--)
1713 {
1714 SceneObjectGroup child = children[i].ParentGroup;
1715 1739
1716 if (child != null) 1740 // Make sure no child prim is set for sale
1717 { 1741 // So that, on delink, no prims are unwittingly
1718 childGroups.Add(child); 1742 // left for sale and sold off
1719 } 1743
1744 if (child != null)
1745 {
1746 child.RootPart.ObjectSaleType = 0;
1747 child.RootPart.SalePrice = 10;
1748 childGroups.Add(child);
1720 } 1749 }
1721 } 1750 }
1722 else
1723 {
1724 return; // parent is null so not in this region
1725 }
1726 1751
1727 foreach (SceneObjectGroup child in childGroups) 1752 foreach (SceneObjectGroup child in childGroups)
1728 { 1753 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index 86ba2aa..7fada4b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -47,12 +47,18 @@ namespace OpenSim.Region.Framework.Scenes
47 47
48 public event RestartSim OnRestartSim; 48 public event RestartSim OnRestartSim;
49 49
50 private readonly List<Scene> m_localScenes; 50 private static SceneManager m_instance = null;
51 public static SceneManager Instance
52 {
53 get { return m_instance; }
54 }
55
56 private readonly List<Scene> m_localScenes = new List<Scene>();
51 private Scene m_currentScene = null; 57 private Scene m_currentScene = null;
52 58
53 public List<Scene> Scenes 59 public List<Scene> Scenes
54 { 60 {
55 get { return m_localScenes; } 61 get { return new List<Scene>(m_localScenes); }
56 } 62 }
57 63
58 public Scene CurrentScene 64 public Scene CurrentScene
@@ -66,13 +72,12 @@ namespace OpenSim.Region.Framework.Scenes
66 { 72 {
67 if (m_currentScene == null) 73 if (m_currentScene == null)
68 { 74 {
69 if (m_localScenes.Count > 0) 75 lock (m_localScenes)
70 { 76 {
71 return m_localScenes[0]; 77 if (m_localScenes.Count > 0)
72 } 78 return m_localScenes[0];
73 else 79 else
74 { 80 return null;
75 return null;
76 } 81 }
77 } 82 }
78 else 83 else
@@ -84,6 +89,7 @@ namespace OpenSim.Region.Framework.Scenes
84 89
85 public SceneManager() 90 public SceneManager()
86 { 91 {
92 m_instance = this;
87 m_localScenes = new List<Scene>(); 93 m_localScenes = new List<Scene>();
88 } 94 }
89 95
@@ -91,17 +97,21 @@ namespace OpenSim.Region.Framework.Scenes
91 { 97 {
92 // collect known shared modules in sharedModules 98 // collect known shared modules in sharedModules
93 Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>(); 99 Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>();
94 for (int i = 0; i < m_localScenes.Count; i++) 100
101 lock (m_localScenes)
95 { 102 {
96 // extract known shared modules from scene 103 for (int i = 0; i < m_localScenes.Count; i++)
97 foreach (string k in m_localScenes[i].Modules.Keys)
98 { 104 {
99 if (m_localScenes[i].Modules[k].IsSharedModule && 105 // extract known shared modules from scene
100 !sharedModules.ContainsKey(k)) 106 foreach (string k in m_localScenes[i].Modules.Keys)
101 sharedModules[k] = m_localScenes[i].Modules[k]; 107 {
108 if (m_localScenes[i].Modules[k].IsSharedModule &&
109 !sharedModules.ContainsKey(k))
110 sharedModules[k] = m_localScenes[i].Modules[k];
111 }
112 // close scene/region
113 m_localScenes[i].Close();
102 } 114 }
103 // close scene/region
104 m_localScenes[i].Close();
105 } 115 }
106 116
107 // all regions/scenes are now closed, we can now safely 117 // all regions/scenes are now closed, we can now safely
@@ -114,13 +124,16 @@ namespace OpenSim.Region.Framework.Scenes
114 124
115 public void Close(Scene cscene) 125 public void Close(Scene cscene)
116 { 126 {
117 if (m_localScenes.Contains(cscene)) 127 lock (m_localScenes)
118 { 128 {
119 for (int i = 0; i < m_localScenes.Count; i++) 129 if (m_localScenes.Contains(cscene))
120 { 130 {
121 if (m_localScenes[i].Equals(cscene)) 131 for (int i = 0; i < m_localScenes.Count; i++)
122 { 132 {
123 m_localScenes[i].Close(); 133 if (m_localScenes[i].Equals(cscene))
134 {
135 m_localScenes[i].Close();
136 }
124 } 137 }
125 } 138 }
126 } 139 }
@@ -129,27 +142,33 @@ namespace OpenSim.Region.Framework.Scenes
129 public void Add(Scene scene) 142 public void Add(Scene scene)
130 { 143 {
131 scene.OnRestart += HandleRestart; 144 scene.OnRestart += HandleRestart;
132 m_localScenes.Add(scene); 145
146 lock (m_localScenes)
147 m_localScenes.Add(scene);
133 } 148 }
134 149
135 public void HandleRestart(RegionInfo rdata) 150 public void HandleRestart(RegionInfo rdata)
136 { 151 {
137 m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); 152 m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main");
138 int RegionSceneElement = -1; 153 int RegionSceneElement = -1;
139 for (int i = 0; i < m_localScenes.Count; i++) 154
155 lock (m_localScenes)
140 { 156 {
141 if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName) 157 for (int i = 0; i < m_localScenes.Count; i++)
142 { 158 {
143 RegionSceneElement = i; 159 if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName)
160 {
161 RegionSceneElement = i;
162 }
144 } 163 }
145 }
146 164
147 // Now we make sure the region is no longer known about by the SceneManager 165 // Now we make sure the region is no longer known about by the SceneManager
148 // Prevents duplicates. 166 // Prevents duplicates.
149 167
150 if (RegionSceneElement >= 0) 168 if (RegionSceneElement >= 0)
151 { 169 {
152 m_localScenes.RemoveAt(RegionSceneElement); 170 m_localScenes.RemoveAt(RegionSceneElement);
171 }
153 } 172 }
154 173
155 // Send signal to main that we're restarting this sim. 174 // Send signal to main that we're restarting this sim.
@@ -160,28 +179,32 @@ namespace OpenSim.Region.Framework.Scenes
160 { 179 {
161 RegionInfo Result = null; 180 RegionInfo Result = null;
162 181
163 for (int i = 0; i < m_localScenes.Count; i++) 182 lock (m_localScenes)
164 {
165 if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle)
166 {
167 // Inform other regions to tell their avatar about me
168 Result = m_localScenes[i].RegionInfo;
169 }
170 }
171 if (Result != null)
172 { 183 {
173 for (int i = 0; i < m_localScenes.Count; i++) 184 for (int i = 0; i < m_localScenes.Count; i++)
174 { 185 {
175 if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle) 186 if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle)
176 { 187 {
177 // Inform other regions to tell their avatar about me 188 // Inform other regions to tell their avatar about me
178 //m_localScenes[i].OtherRegionUp(Result); 189 Result = m_localScenes[i].RegionInfo;
179 } 190 }
180 } 191 }
181 } 192
182 else 193 if (Result != null)
183 { 194 {
184 m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up"); 195 for (int i = 0; i < m_localScenes.Count; i++)
196 {
197 if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle)
198 {
199 // Inform other regions to tell their avatar about me
200 //m_localScenes[i].OtherRegionUp(Result);
201 }
202 }
203 }
204 else
205 {
206 m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up");
207 }
185 } 208 }
186 } 209 }
187 210
@@ -285,7 +308,8 @@ namespace OpenSim.Region.Framework.Scenes
285 { 308 {
286 if (m_currentScene == null) 309 if (m_currentScene == null)
287 { 310 {
288 m_localScenes.ForEach(func); 311 lock (m_localScenes)
312 m_localScenes.ForEach(func);
289 } 313 }
290 else 314 else
291 { 315 {
@@ -314,12 +338,15 @@ namespace OpenSim.Region.Framework.Scenes
314 } 338 }
315 else 339 else
316 { 340 {
317 foreach (Scene scene in m_localScenes) 341 lock (m_localScenes)
318 { 342 {
319 if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0) 343 foreach (Scene scene in m_localScenes)
320 { 344 {
321 m_currentScene = scene; 345 if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0)
322 return true; 346 {
347 m_currentScene = scene;
348 return true;
349 }
323 } 350 }
324 } 351 }
325 352
@@ -331,12 +358,15 @@ namespace OpenSim.Region.Framework.Scenes
331 { 358 {
332 m_log.Debug("Searching for Region: '" + regionID + "'"); 359 m_log.Debug("Searching for Region: '" + regionID + "'");
333 360
334 foreach (Scene scene in m_localScenes) 361 lock (m_localScenes)
335 { 362 {
336 if (scene.RegionInfo.RegionID == regionID) 363 foreach (Scene scene in m_localScenes)
337 { 364 {
338 m_currentScene = scene; 365 if (scene.RegionInfo.RegionID == regionID)
339 return true; 366 {
367 m_currentScene = scene;
368 return true;
369 }
340 } 370 }
341 } 371 }
342 372
@@ -345,26 +375,33 @@ namespace OpenSim.Region.Framework.Scenes
345 375
346 public bool TryGetScene(string regionName, out Scene scene) 376 public bool TryGetScene(string regionName, out Scene scene)
347 { 377 {
348 foreach (Scene mscene in m_localScenes) 378 lock (m_localScenes)
349 { 379 {
350 if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0) 380 foreach (Scene mscene in m_localScenes)
351 { 381 {
352 scene = mscene; 382 if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0)
353 return true; 383 {
384 scene = mscene;
385 return true;
386 }
354 } 387 }
355 } 388 }
389
356 scene = null; 390 scene = null;
357 return false; 391 return false;
358 } 392 }
359 393
360 public bool TryGetScene(UUID regionID, out Scene scene) 394 public bool TryGetScene(UUID regionID, out Scene scene)
361 { 395 {
362 foreach (Scene mscene in m_localScenes) 396 lock (m_localScenes)
363 { 397 {
364 if (mscene.RegionInfo.RegionID == regionID) 398 foreach (Scene mscene in m_localScenes)
365 { 399 {
366 scene = mscene; 400 if (mscene.RegionInfo.RegionID == regionID)
367 return true; 401 {
402 scene = mscene;
403 return true;
404 }
368 } 405 }
369 } 406 }
370 407
@@ -374,13 +411,16 @@ namespace OpenSim.Region.Framework.Scenes
374 411
375 public bool TryGetScene(uint locX, uint locY, out Scene scene) 412 public bool TryGetScene(uint locX, uint locY, out Scene scene)
376 { 413 {
377 foreach (Scene mscene in m_localScenes) 414 lock (m_localScenes)
378 { 415 {
379 if (mscene.RegionInfo.RegionLocX == locX && 416 foreach (Scene mscene in m_localScenes)
380 mscene.RegionInfo.RegionLocY == locY)
381 { 417 {
382 scene = mscene; 418 if (mscene.RegionInfo.RegionLocX == locX &&
383 return true; 419 mscene.RegionInfo.RegionLocY == locY)
420 {
421 scene = mscene;
422 return true;
423 }
384 } 424 }
385 } 425 }
386 426
@@ -390,13 +430,16 @@ namespace OpenSim.Region.Framework.Scenes
390 430
391 public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene) 431 public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene)
392 { 432 {
393 foreach (Scene mscene in m_localScenes) 433 lock (m_localScenes)
394 { 434 {
395 if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) && 435 foreach (Scene mscene in m_localScenes)
396 (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port))
397 { 436 {
398 scene = mscene; 437 if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) &&
399 return true; 438 (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port))
439 {
440 scene = mscene;
441 return true;
442 }
400 } 443 }
401 } 444 }
402 445
@@ -465,11 +508,14 @@ namespace OpenSim.Region.Framework.Scenes
465 508
466 public RegionInfo GetRegionInfo(UUID regionID) 509 public RegionInfo GetRegionInfo(UUID regionID)
467 { 510 {
468 foreach (Scene scene in m_localScenes) 511 lock (m_localScenes)
469 { 512 {
470 if (scene.RegionInfo.RegionID == regionID) 513 foreach (Scene scene in m_localScenes)
471 { 514 {
472 return scene.RegionInfo; 515 if (scene.RegionInfo.RegionID == regionID)
516 {
517 return scene.RegionInfo;
518 }
473 } 519 }
474 } 520 }
475 521
@@ -488,11 +534,14 @@ namespace OpenSim.Region.Framework.Scenes
488 534
489 public bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar) 535 public bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar)
490 { 536 {
491 foreach (Scene scene in m_localScenes) 537 lock (m_localScenes)
492 { 538 {
493 if (scene.TryGetScenePresence(avatarId, out avatar)) 539 foreach (Scene scene in m_localScenes)
494 { 540 {
495 return true; 541 if (scene.TryGetScenePresence(avatarId, out avatar))
542 {
543 return true;
544 }
496 } 545 }
497 } 546 }
498 547
@@ -503,12 +552,16 @@ namespace OpenSim.Region.Framework.Scenes
503 public bool TryGetAvatarsScene(UUID avatarId, out Scene scene) 552 public bool TryGetAvatarsScene(UUID avatarId, out Scene scene)
504 { 553 {
505 ScenePresence avatar = null; 554 ScenePresence avatar = null;
506 foreach (Scene mScene in m_localScenes) 555
556 lock (m_localScenes)
507 { 557 {
508 if (mScene.TryGetScenePresence(avatarId, out avatar)) 558 foreach (Scene mScene in m_localScenes)
509 { 559 {
510 scene = mScene; 560 if (mScene.TryGetScenePresence(avatarId, out avatar))
511 return true; 561 {
562 scene = mScene;
563 return true;
564 }
512 } 565 }
513 } 566 }
514 567
@@ -518,17 +571,22 @@ namespace OpenSim.Region.Framework.Scenes
518 571
519 public void CloseScene(Scene scene) 572 public void CloseScene(Scene scene)
520 { 573 {
521 m_localScenes.Remove(scene); 574 lock (m_localScenes)
575 m_localScenes.Remove(scene);
576
522 scene.Close(); 577 scene.Close();
523 } 578 }
524 579
525 public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) 580 public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
526 { 581 {
527 foreach (Scene scene in m_localScenes) 582 lock (m_localScenes)
528 { 583 {
529 if (scene.TryGetAvatarByName(avatarName, out avatar)) 584 foreach (Scene scene in m_localScenes)
530 { 585 {
531 return true; 586 if (scene.TryGetAvatarByName(avatarName, out avatar))
587 {
588 return true;
589 }
532 } 590 }
533 } 591 }
534 592
@@ -538,7 +596,8 @@ namespace OpenSim.Region.Framework.Scenes
538 596
539 public void ForEachScene(Action<Scene> action) 597 public void ForEachScene(Action<Scene> action)
540 { 598 {
541 m_localScenes.ForEach(action); 599 lock (m_localScenes)
600 m_localScenes.ForEach(action);
542 } 601 }
543 } 602 }
544} 603}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 9f0ac4f..6bd9183 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -388,5 +388,18 @@ namespace OpenSim.Region.Framework.Scenes
388 for (int i = 0; i < parts.Length; i++) 388 for (int i = 0; i < parts.Length; i++)
389 parts[i].Inventory.ResumeScripts(); 389 parts[i].Inventory.ResumeScripts();
390 } 390 }
391
392 /// <summary>
393 /// Returns true if any part in the scene object contains scripts, false otherwise.
394 /// </summary>
395 /// <returns></returns>
396 public bool ContainsScripts()
397 {
398 foreach (SceneObjectPart part in Parts)
399 if (part.Inventory.ContainsScripts())
400 return true;
401
402 return false;
403 }
391 } 404 }
392} 405}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 58f2586..3e1439d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -209,27 +209,89 @@ namespace OpenSim.Region.Framework.Scenes
209 return true; 209 return true;
210 return false; 210 return false;
211 } 211 }
212 212
213 /// <value> 213 /// <summary>
214 /// Is this scene object acting as an attachment? 214 /// Is this scene object acting as an attachment?
215 /// 215 /// </summary>
216 /// We return false if the group has already been deleted. 216 public bool IsAttachment { get; set; }
217 /// 217
218 /// TODO: At the moment set must be done on the part itself. There may be a case for doing it here since I 218 /// <summary>
219 /// presume either all or no parts in a linkset can be part of an attachment (in which 219 /// The avatar to which this scene object is attached.
220 /// case the value would get proprogated down into all the descendent parts). 220 /// </summary>
221 /// </value> 221 /// <remarks>
222 public bool IsAttachment 222 /// If we're not attached to an avatar then this is UUID.Zero
223 /// </remarks>
224 public UUID AttachedAvatar { get; set; }
225
226 /// <summary>
227 /// Attachment point of this scene object to an avatar.
228 /// </summary>
229 /// <remarks>
230 /// 0 if we're not attached to anything
231 /// </remarks>
232 public uint AttachmentPoint
223 { 233 {
224 get 234 get
225 { 235 {
226 if (!IsDeleted) 236 return m_rootPart.Shape.State;
227 return m_rootPart.IsAttachment; 237 }
228 238
229 return false; 239 set
240 {
241 IsAttachment = value != 0;
242 m_rootPart.Shape.State = (byte)value;
230 } 243 }
231 } 244 }
232 245
246 public void ClearPartAttachmentData()
247 {
248 AttachmentPoint = 0;
249
250 // Even though we don't use child part state parameters for attachments any more, we still need to set
251 // these to zero since having them non-zero in rezzed scene objects will crash some clients. Even if
252 // we store them correctly, scene objects that we receive from elsewhere might not.
253 foreach (SceneObjectPart part in Parts)
254 part.Shape.State = 0;
255 }
256
257 /// <summary>
258 /// Is this scene object phantom?
259 /// </summary>
260 /// <remarks>
261 /// Updating must currently take place through UpdatePrimFlags()
262 /// </remarks>
263 public bool IsPhantom
264 {
265 get { return (RootPart.Flags & PrimFlags.Phantom) != 0; }
266 }
267
268 /// <summary>
269 /// Does this scene object use physics?
270 /// </summary>
271 /// <remarks>
272 /// Updating must currently take place through UpdatePrimFlags()
273 /// </remarks>
274 public bool UsesPhysics
275 {
276 get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; }
277 }
278
279 /// <summary>
280 /// Is this scene object temporary?
281 /// </summary>
282 /// <remarks>
283 /// Updating must currently take place through UpdatePrimFlags()
284 /// </remarks>
285 public bool IsTemporary
286 {
287 get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; }
288 }
289
290 public bool IsVolumeDetect
291 {
292 get { return RootPart.VolumeDetectActive; }
293 }
294
233 public float scriptScore; 295 public float scriptScore;
234 296
235 private Vector3 lastPhysGroupPos; 297 private Vector3 lastPhysGroupPos;
@@ -261,11 +323,7 @@ namespace OpenSim.Region.Framework.Scenes
261 /// </summary> 323 /// </summary>
262 public override string Name 324 public override string Name
263 { 325 {
264 get { 326 get { return RootPart.Name; }
265 if (RootPart == null)
266 return String.Empty;
267 return RootPart.Name;
268 }
269 set { RootPart.Name = value; } 327 set { RootPart.Name = value; }
270 } 328 }
271 329
@@ -292,10 +350,6 @@ namespace OpenSim.Region.Framework.Scenes
292 { 350 {
293 get { return m_rotation; } 351 get { return m_rotation; }
294 set { 352 set {
295 foreach(SceneObjectPart p in m_parts.GetArray())
296 {
297 p.StoreUndoState(UndoType.STATE_GROUP_ROTATION);
298 }
299 m_rotation = value; 353 m_rotation = value;
300 } 354 }
301 } 355 }
@@ -305,6 +359,38 @@ namespace OpenSim.Region.Framework.Scenes
305 get { return m_rootPart.RotationOffset; } 359 get { return m_rootPart.RotationOffset; }
306 } 360 }
307 361
362 public Vector3 GroupScale
363 {
364 get
365 {
366 Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);
367 Vector3 maxScale = Vector3.Zero;
368 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
369
370 SceneObjectPart[] parts = m_parts.GetArray();
371 for (int i = 0; i < parts.Length; i++)
372 {
373 SceneObjectPart part = parts[i];
374 Vector3 partscale = part.Scale;
375 Vector3 partoffset = part.OffsetPosition;
376
377 minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X;
378 minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y;
379 minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z;
380
381 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
382 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
383 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
384 }
385
386 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
387 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
388 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
389
390 return finalScale;
391 }
392 }
393
308 public UUID GroupID 394 public UUID GroupID
309 { 395 {
310 get { return m_rootPart.GroupID; } 396 get { return m_rootPart.GroupID; }
@@ -344,11 +430,13 @@ namespace OpenSim.Region.Framework.Scenes
344 /// <summary> 430 /// <summary>
345 /// Check both the attachment property and the relevant properties of the underlying root part. 431 /// Check both the attachment property and the relevant properties of the underlying root part.
346 /// </summary> 432 /// </summary>
433 /// <remarks>
347 /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't 434 /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't
348 /// have the IsAttachment property yet checked. 435 /// have the IsAttachment property yet checked.
349 /// 436 ///
350 /// FIXME: However, this should be fixed so that this property 437 /// FIXME: However, this should be fixed so that this property
351 /// propertly reflects the underlying status. 438 /// propertly reflects the underlying status.
439 /// </remarks>
352 /// <returns></returns> 440 /// <returns></returns>
353 public bool IsAttachmentCheckFull() 441 public bool IsAttachmentCheckFull()
354 { 442 {
@@ -395,8 +483,6 @@ namespace OpenSim.Region.Framework.Scenes
395 SceneObjectPart[] parts = m_parts.GetArray(); 483 SceneObjectPart[] parts = m_parts.GetArray();
396 foreach (SceneObjectPart part in parts) 484 foreach (SceneObjectPart part in parts)
397 { 485 {
398 part.IgnoreUndoUpdate = false;
399 part.StoreUndoState(UndoType.STATE_GROUP_POSITION);
400 part.GroupPosition = val; 486 part.GroupPosition = val;
401 if (!m_dupeInProgress) 487 if (!m_dupeInProgress)
402 { 488 {
@@ -682,7 +768,7 @@ namespace OpenSim.Region.Framework.Scenes
682 part.ParentID = m_rootPart.LocalId; 768 part.ParentID = m_rootPart.LocalId;
683 //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 //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);
684 } 770 }
685 771
686 ApplyPhysics(m_scene.m_physicalPrim); 772 ApplyPhysics(m_scene.m_physicalPrim);
687 773
688 if (RootPart.PhysActor != null) 774 if (RootPart.PhysActor != null)
@@ -693,34 +779,6 @@ namespace OpenSim.Region.Framework.Scenes
693 //ScheduleGroupForFullUpdate(); 779 //ScheduleGroupForFullUpdate();
694 } 780 }
695 781
696 public Vector3 GroupScale()
697 {
698 Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize);
699 Vector3 maxScale = Vector3.Zero;
700 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
701
702 SceneObjectPart[] parts = m_parts.GetArray();
703 for (int i = 0; i < parts.Length; i++)
704 {
705 SceneObjectPart part = parts[i];
706 Vector3 partscale = part.Scale;
707 Vector3 partoffset = part.OffsetPosition;
708
709 minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X;
710 minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y;
711 minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z;
712
713 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
714 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
715 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
716 }
717
718 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
719 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
720 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
721 return finalScale;
722
723 }
724 public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters) 782 public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters)
725 { 783 {
726 // We got a request from the inner_scene to raytrace along the Ray hRay 784 // We got a request from the inner_scene to raytrace along the Ray hRay
@@ -1129,45 +1187,31 @@ namespace OpenSim.Region.Framework.Scenes
1129 /// <param name="agentID"></param> 1187 /// <param name="agentID"></param>
1130 /// <param name="attachmentpoint"></param> 1188 /// <param name="attachmentpoint"></param>
1131 /// <param name="AttachOffset"></param> 1189 /// <param name="AttachOffset"></param>
1132 public void AttachToAgent(UUID agentID, uint attachmentpoint, Vector3 AttachOffset, bool silent) 1190 private void AttachToAgent(
1191 ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
1133 { 1192 {
1134 ScenePresence avatar = m_scene.GetScenePresence(agentID);
1135 if (avatar != null) 1193 if (avatar != null)
1136 { 1194 {
1137 // don't attach attachments to child agents 1195 // don't attach attachments to child agents
1138 if (avatar.IsChildAgent) return; 1196 if (avatar.IsChildAgent) return;
1139 1197
1140// m_log.DebugFormat("[SOG]: Adding attachment {0} to avatar {1}", Name, avatar.Name);
1141
1142 DetachFromBackup();
1143
1144 // Remove from database and parcel prim count 1198 // Remove from database and parcel prim count
1145 m_scene.DeleteFromStorage(UUID); 1199 m_scene.DeleteFromStorage(so.UUID);
1146 m_scene.EventManager.TriggerParcelPrimCountTainted(); 1200 m_scene.EventManager.TriggerParcelPrimCountTainted();
1147 1201
1148 m_rootPart.AttachedAvatar = agentID; 1202 so.AttachedAvatar = avatar.UUID;
1149
1150 //Anakin Lohner bug #3839
1151 lock (m_parts)
1152 {
1153 foreach (SceneObjectPart p in m_parts.GetArray())
1154 {
1155 p.AttachedAvatar = agentID;
1156 }
1157 }
1158 1203
1159 if (m_rootPart.PhysActor != null) 1204 if (so.RootPart.PhysActor != null)
1160 { 1205 {
1161 m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor); 1206 m_scene.PhysicsScene.RemovePrim(so.RootPart.PhysActor);
1162 m_rootPart.PhysActor = null; 1207 so.RootPart.PhysActor = null;
1163 } 1208 }
1164 1209
1165 AbsolutePosition = AttachOffset; 1210 so.AbsolutePosition = attachOffset;
1166 m_rootPart.AttachedPos = AttachOffset; 1211 so.RootPart.AttachedPos = attachOffset;
1167 m_rootPart.IsAttachment = true; 1212 so.IsAttachment = true;
1168 1213 so.RootPart.SetParentLocalId(avatar.LocalId);
1169 m_rootPart.SetParentLocalId(avatar.LocalId); 1214 so.AttachmentPoint = attachmentpoint;
1170 SetAttachmentPoint(Convert.ToByte(attachmentpoint));
1171 1215
1172 avatar.AddAttachment(this); 1216 avatar.AddAttachment(this);
1173 1217
@@ -1190,7 +1234,7 @@ namespace OpenSim.Region.Framework.Scenes
1190 { 1234 {
1191 m_log.WarnFormat( 1235 m_log.WarnFormat(
1192 "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present", 1236 "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present",
1193 UUID, agentID, Scene.RegionInfo.RegionName); 1237 UUID, avatar.ControllingClient.AgentId, Scene.RegionInfo.RegionName);
1194 } 1238 }
1195 } 1239 }
1196 1240
@@ -1199,14 +1243,9 @@ namespace OpenSim.Region.Framework.Scenes
1199 return m_rootPart.Shape.State; 1243 return m_rootPart.Shape.State;
1200 } 1244 }
1201 1245
1202 public void ClearPartAttachmentData()
1203 {
1204 SetAttachmentPoint((Byte)0);
1205 }
1206
1207 public void DetachToGround() 1246 public void DetachToGround()
1208 { 1247 {
1209 ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar); 1248 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1210 if (avatar == null) 1249 if (avatar == null)
1211 return; 1250 return;
1212 1251
@@ -1220,14 +1259,14 @@ namespace OpenSim.Region.Framework.Scenes
1220 RootPart.FromItemID = UUID.Zero; 1259 RootPart.FromItemID = UUID.Zero;
1221 1260
1222 AbsolutePosition = detachedpos; 1261 AbsolutePosition = detachedpos;
1223 m_rootPart.AttachedAvatar = UUID.Zero; 1262 AttachedAvatar = UUID.Zero;
1224 1263
1225 SceneObjectPart[] parts = m_parts.GetArray(); 1264 //SceneObjectPart[] parts = m_parts.GetArray();
1226 for (int i = 0; i < parts.Length; i++) 1265 //for (int i = 0; i < parts.Length; i++)
1227 parts[i].AttachedAvatar = UUID.Zero; 1266 // parts[i].AttachedAvatar = UUID.Zero;
1228 1267
1229 m_rootPart.SetParentLocalId(0); 1268 m_rootPart.SetParentLocalId(0);
1230 SetAttachmentPoint((byte)0); 1269 AttachmentPoint = (byte)0;
1231 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_scene.m_physicalPrim); 1270 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
1232 HasGroupChanged = true; 1271 HasGroupChanged = true;
1233 RootPart.Rezzed = DateTime.Now; 1272 RootPart.Rezzed = DateTime.Now;
@@ -1240,7 +1279,7 @@ namespace OpenSim.Region.Framework.Scenes
1240 1279
1241 public void DetachToInventoryPrep() 1280 public void DetachToInventoryPrep()
1242 { 1281 {
1243 ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar); 1282 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1244 //Vector3 detachedpos = new Vector3(127f, 127f, 127f); 1283 //Vector3 detachedpos = new Vector3(127f, 127f, 127f);
1245 if (avatar != null) 1284 if (avatar != null)
1246 { 1285 {
@@ -1248,15 +1287,15 @@ namespace OpenSim.Region.Framework.Scenes
1248 avatar.RemoveAttachment(this); 1287 avatar.RemoveAttachment(this);
1249 } 1288 }
1250 1289
1251 m_rootPart.AttachedAvatar = UUID.Zero; 1290 AttachedAvatar = UUID.Zero;
1252 1291
1253 SceneObjectPart[] parts = m_parts.GetArray(); 1292 /*SceneObjectPart[] parts = m_parts.GetArray();
1254 for (int i = 0; i < parts.Length; i++) 1293 for (int i = 0; i < parts.Length; i++)
1255 parts[i].AttachedAvatar = UUID.Zero; 1294 parts[i].AttachedAvatar = UUID.Zero;*/
1256 1295
1257 m_rootPart.SetParentLocalId(0); 1296 m_rootPart.SetParentLocalId(0);
1258 //m_rootPart.SetAttachmentPoint((byte)0); 1297 //m_rootPart.SetAttachmentPoint((byte)0);
1259 m_rootPart.IsAttachment = false; 1298 IsAttachment = false;
1260 AbsolutePosition = m_rootPart.AttachedPos; 1299 AbsolutePosition = m_rootPart.AttachedPos;
1261 //m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_scene.m_physicalPrim); 1300 //m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_scene.m_physicalPrim);
1262 //AttachToBackup(); 1301 //AttachToBackup();
@@ -1324,7 +1363,7 @@ namespace OpenSim.Region.Framework.Scenes
1324 1363
1325 part.LinkNum = m_parts.Count; 1364 part.LinkNum = m_parts.Count;
1326 1365
1327 if (part.LinkNum == 2 && RootPart != null) 1366 if (part.LinkNum == 2)
1328 RootPart.LinkNum = 1; 1367 RootPart.LinkNum = 1;
1329 } 1368 }
1330 1369
@@ -1407,7 +1446,11 @@ namespace OpenSim.Region.Framework.Scenes
1407 1446
1408 public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) 1447 public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient)
1409 { 1448 {
1410 part.StoreUndoState(UndoType.STATE_PRIM_ALL); 1449// m_log.DebugFormat(
1450// "[SCENE OBJECT GROUP]: Processing OnGrabPart for {0} on {1} {2}, offsetPos {3}",
1451// remoteClient.Name, part.Name, part.LocalId, offsetPos);
1452
1453 part.StoreUndoState();
1411 part.OnGrab(offsetPos, remoteClient); 1454 part.OnGrab(offsetPos, remoteClient);
1412 } 1455 }
1413 1456
@@ -1428,7 +1471,7 @@ namespace OpenSim.Region.Framework.Scenes
1428 public void DeleteGroupFromScene(bool silent) 1471 public void DeleteGroupFromScene(bool silent)
1429 { 1472 {
1430 // We need to keep track of this state in case this group is still queued for backup. 1473 // We need to keep track of this state in case this group is still queued for backup.
1431 m_isDeleted = true; 1474 IsDeleted = true;
1432 1475
1433 DetachFromBackup(); 1476 DetachFromBackup();
1434 1477
@@ -1703,91 +1746,86 @@ namespace OpenSim.Region.Framework.Scenes
1703 /// <returns></returns> 1746 /// <returns></returns>
1704 public SceneObjectGroup Copy(bool userExposed) 1747 public SceneObjectGroup Copy(bool userExposed)
1705 { 1748 {
1706 SceneObjectGroup dupe; 1749 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
1707 try 1750 dupe.m_isBackedUp = false;
1708 { 1751 dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
1709 m_dupeInProgress = true;
1710 dupe = (SceneObjectGroup)MemberwiseClone();
1711 dupe.m_isBackedUp = false;
1712 dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
1713 1752
1714 // Warning, The following code related to previousAttachmentStatus is needed so that clones of 1753 // Warning, The following code related to previousAttachmentStatus is needed so that clones of
1715 // attachments do not bordercross while they're being duplicated. This is hacktastic! 1754 // attachments do not bordercross while they're being duplicated. This is hacktastic!
1716 // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! 1755 // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region!
1717 // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state 1756 // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state
1718 // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, 1757 // (which should be false anyway) set it as an Attachment and then set it's Absolute Position,
1719 // then restore it's attachment state 1758 // then restore it's attachment state
1720 1759
1721 // This is only necessary when userExposed is false! 1760 // This is only necessary when userExposed is false!
1722 1761
1723 bool previousAttachmentStatus = dupe.RootPart.IsAttachment; 1762 bool previousAttachmentStatus = dupe.IsAttachment;
1724 1763
1725 if (!userExposed) 1764 if (!userExposed)
1726 dupe.RootPart.IsAttachment = true; 1765 dupe.IsAttachment = true;
1727 1766
1728 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); 1767 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
1729 1768
1730 if (!userExposed) 1769 if (!userExposed)
1731 { 1770 {
1732 dupe.RootPart.IsAttachment = previousAttachmentStatus; 1771 dupe.IsAttachment = previousAttachmentStatus;
1733 } 1772 }
1734 1773
1735 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); 1774 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed);
1736 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; 1775 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum;
1737 1776
1738 if (userExposed) 1777 if (userExposed)
1739 dupe.m_rootPart.TrimPermissions(); 1778 dupe.m_rootPart.TrimPermissions();
1740 1779
1741 List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.GetArray()); 1780 List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.GetArray());
1742 1781
1743 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1782 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1744 { 1783 {
1745 return p1.LinkNum.CompareTo(p2.LinkNum); 1784 return p1.LinkNum.CompareTo(p2.LinkNum);
1746 } 1785 }
1747 ); 1786 );
1748 1787
1749 foreach (SceneObjectPart part in partList) 1788 foreach (SceneObjectPart part in partList)
1789 {
1790 SceneObjectPart newPart;
1791 if (part.UUID != m_rootPart.UUID)
1750 { 1792 {
1751 if (part.UUID != m_rootPart.UUID) 1793 newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed);
1752 { 1794 newPart.LinkNum = part.LinkNum;
1753 SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed);
1754
1755 newPart.LinkNum = part.LinkNum;
1756 }
1757
1758 // Need to duplicate the physics actor as well
1759 if (part.PhysActor != null && userExposed)
1760 {
1761 PrimitiveBaseShape pbs = part.Shape;
1762
1763 part.PhysActor
1764 = m_scene.PhysicsScene.AddPrimShape(
1765 string.Format("{0}/{1}", part.Name, part.UUID),
1766 pbs,
1767 part.AbsolutePosition,
1768 part.Scale,
1769 part.RotationOffset,
1770 part.PhysActor.IsPhysical,
1771 m_localId);
1772 part.PhysActor.SetMaterial((int)part.Material);
1773
1774 part.PhysActor.LocalID = part.LocalId;
1775 part.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
1776 }
1777 } 1795 }
1778 if (userExposed) 1796 else
1779 { 1797 {
1780 dupe.UpdateParentIDs(); 1798 newPart = dupe.m_rootPart;
1781 dupe.HasGroupChanged = true; 1799 }
1782 dupe.AttachToBackup();
1783 1800
1784 ScheduleGroupForFullUpdate(); 1801 // Need to duplicate the physics actor as well
1802 if (part.PhysActor != null && userExposed)
1803 {
1804 PrimitiveBaseShape pbs = newPart.Shape;
1805
1806 newPart.PhysActor
1807 = m_scene.PhysicsScene.AddPrimShape(
1808 string.Format("{0}/{1}", newPart.Name, newPart.UUID),
1809 pbs,
1810 newPart.AbsolutePosition,
1811 newPart.Scale,
1812 newPart.RotationOffset,
1813 part.PhysActor.IsPhysical,
1814 newPart.LocalId);
1815
1816 newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
1785 } 1817 }
1786 } 1818 }
1787 finally 1819
1820 if (userExposed)
1788 { 1821 {
1789 m_dupeInProgress = false; 1822 dupe.UpdateParentIDs();
1823 dupe.HasGroupChanged = true;
1824 dupe.AttachToBackup();
1825
1826 ScheduleGroupForFullUpdate();
1790 } 1827 }
1828
1791 return dupe; 1829 return dupe;
1792 } 1830 }
1793 1831
@@ -1802,36 +1840,24 @@ namespace OpenSim.Region.Framework.Scenes
1802 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); 1840 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
1803 } 1841 }
1804 1842
1805 public void ScriptSetPhysicsStatus(bool UsePhysics) 1843 public void ScriptSetPhysicsStatus(bool usePhysics)
1806 { 1844 {
1807 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); 1845 UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
1808 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1809 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1810 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
1811 } 1846 }
1812 1847
1813 public void ScriptSetTemporaryStatus(bool TemporaryStatus) 1848 public void ScriptSetTemporaryStatus(bool makeTemporary)
1814 { 1849 {
1815 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1850 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect);
1816 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1817 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1818 UpdatePrimFlags(RootPart.LocalId, UsePhysics, TemporaryStatus, IsPhantom, IsVolumeDetect);
1819 } 1851 }
1820 1852
1821 public void ScriptSetPhantomStatus(bool PhantomStatus) 1853 public void ScriptSetPhantomStatus(bool makePhantom)
1822 { 1854 {
1823 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1855 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect);
1824 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
1825 bool IsVolumeDetect = RootPart.VolumeDetectActive;
1826 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, PhantomStatus, IsVolumeDetect);
1827 } 1856 }
1828 1857
1829 public void ScriptSetVolumeDetect(bool VDStatus) 1858 public void ScriptSetVolumeDetect(bool makeVolumeDetect)
1830 { 1859 {
1831 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 1860 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect);
1832 bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0);
1833 bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0);
1834 UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, VDStatus);
1835 1861
1836 /* 1862 /*
1837 ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore 1863 ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore
@@ -1849,142 +1875,88 @@ namespace OpenSim.Region.Framework.Scenes
1849 1875
1850 public void applyImpulse(Vector3 impulse) 1876 public void applyImpulse(Vector3 impulse)
1851 { 1877 {
1852 // We check if rootpart is null here because scripts don't delete if you delete the host. 1878 if (IsAttachment)
1853 // This means that unfortunately, we can pass a null physics actor to Simulate!
1854 // Make sure we don't do that!
1855 SceneObjectPart rootpart = m_rootPart;
1856 if (rootpart != null)
1857 { 1879 {
1858 if (IsAttachment) 1880 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1881 if (avatar != null)
1859 { 1882 {
1860 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); 1883 avatar.PushForce(impulse);
1861 if (avatar != null)
1862 {
1863 avatar.PushForce(impulse);
1864 }
1865 } 1884 }
1866 else 1885 }
1886 else
1887 {
1888 if (RootPart.PhysActor != null)
1867 { 1889 {
1868 if (rootpart.PhysActor != null) 1890 RootPart.PhysActor.AddForce(impulse, true);
1869 { 1891 m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor);
1870 rootpart.PhysActor.AddForce(impulse, true);
1871 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
1872 }
1873 } 1892 }
1874 } 1893 }
1875 } 1894 }
1876 1895
1877 public void applyAngularImpulse(Vector3 impulse) 1896 public void applyAngularImpulse(Vector3 impulse)
1878 { 1897 {
1879 // We check if rootpart is null here because scripts don't delete if you delete the host. 1898 if (RootPart.PhysActor != null)
1880 // This means that unfortunately, we can pass a null physics actor to Simulate!
1881 // Make sure we don't do that!
1882 SceneObjectPart rootpart = m_rootPart;
1883 if (rootpart != null)
1884 { 1899 {
1885 if (rootpart.PhysActor != null) 1900 if (!IsAttachment)
1886 { 1901 {
1887 if (!IsAttachment) 1902 RootPart.PhysActor.AddAngularForce(impulse, true);
1888 { 1903 m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor);
1889 rootpart.PhysActor.AddAngularForce(impulse, true);
1890 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
1891 }
1892 } 1904 }
1893 } 1905 }
1894 } 1906 }
1895 1907
1896 public void setAngularImpulse(Vector3 impulse) 1908 public void setAngularImpulse(Vector3 impulse)
1897 { 1909 {
1898 // We check if rootpart is null here because scripts don't delete if you delete the host. 1910 if (RootPart.PhysActor != null)
1899 // This means that unfortunately, we can pass a null physics actor to Simulate!
1900 // Make sure we don't do that!
1901 SceneObjectPart rootpart = m_rootPart;
1902 if (rootpart != null)
1903 { 1911 {
1904 if (rootpart.PhysActor != null) 1912 if (!IsAttachment)
1905 { 1913 {
1906 if (!IsAttachment) 1914 RootPart.PhysActor.Torque = impulse;
1907 { 1915 m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor);
1908 rootpart.PhysActor.Torque = impulse;
1909 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
1910 }
1911 } 1916 }
1912 } 1917 }
1913 } 1918 }
1914 1919
1915 public Vector3 GetTorque() 1920 public Vector3 GetTorque()
1916 { 1921 {
1917 // We check if rootpart is null here because scripts don't delete if you delete the host. 1922 if (RootPart.PhysActor != null)
1918 // This means that unfortunately, we can pass a null physics actor to Simulate!
1919 // Make sure we don't do that!
1920 SceneObjectPart rootpart = m_rootPart;
1921 if (rootpart != null)
1922 { 1923 {
1923 if (rootpart.PhysActor != null) 1924 if (!IsAttachment)
1924 { 1925 {
1925 if (!IsAttachment) 1926 Vector3 torque = RootPart.PhysActor.Torque;
1926 { 1927 return torque;
1927 Vector3 torque = rootpart.PhysActor.Torque;
1928 return torque;
1929 }
1930 } 1928 }
1931 } 1929 }
1930
1932 return Vector3.Zero; 1931 return Vector3.Zero;
1933 } 1932 }
1934 1933
1935 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object 1934 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object
1936 public void moveToTarget(Vector3 target, float tau) 1935 public void moveToTarget(Vector3 target, float tau)
1937 { 1936 {
1938 SceneObjectPart rootpart = m_rootPart; 1937 if (IsAttachment)
1939 if (rootpart != null)
1940 { 1938 {
1941 if (IsAttachment) 1939 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1940 if (avatar != null)
1942 { 1941 {
1943 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); 1942 avatar.MoveToTarget(target, false);
1944 if (avatar != null)
1945 {
1946 List<string> coords = new List<string>();
1947 uint regionX = 0;
1948 uint regionY = 0;
1949 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY);
1950 target.X += regionX;
1951 target.Y += regionY;
1952 coords.Add(target.X.ToString());
1953 coords.Add(target.Y.ToString());
1954 coords.Add(target.Z.ToString());
1955 avatar.DoMoveToPosition(avatar, "", coords);
1956 }
1957 } 1943 }
1958 else 1944 }
1945 else
1946 {
1947 if (RootPart.PhysActor != null)
1959 { 1948 {
1960 if (rootpart.PhysActor != null) 1949 RootPart.PhysActor.PIDTarget = target;
1961 { 1950 RootPart.PhysActor.PIDTau = tau;
1962 rootpart.PhysActor.PIDTarget = target; 1951 RootPart.PhysActor.PIDActive = true;
1963 rootpart.PhysActor.PIDTau = tau;
1964 rootpart.PhysActor.PIDActive = true;
1965 }
1966 } 1952 }
1967 } 1953 }
1968 } 1954 }
1969 1955
1970 public void stopMoveToTarget() 1956 public void stopMoveToTarget()
1971 { 1957 {
1972 SceneObjectPart rootpart = m_rootPart; 1958 if (RootPart.PhysActor != null)
1973 if (rootpart != null) 1959 RootPart.PhysActor.PIDActive = false;
1974 {
1975 if (IsAttachment)
1976 {
1977 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1978 if (avatar != null) avatar.StopMoveToPosition();
1979 }
1980 else
1981 {
1982 if (rootpart.PhysActor != null)
1983 {
1984 rootpart.PhysActor.PIDActive = false;
1985 }
1986 }
1987 }
1988 } 1960 }
1989 1961
1990 public void rotLookAt(Quaternion target, float strength, float damping) 1962 public void rotLookAt(Quaternion target, float strength, float damping)
@@ -2035,22 +2007,18 @@ namespace OpenSim.Region.Framework.Scenes
2035 /// <param name="tau">Number of seconds over which to reach target</param> 2007 /// <param name="tau">Number of seconds over which to reach target</param>
2036 public void SetHoverHeight(float height, PIDHoverType hoverType, float tau) 2008 public void SetHoverHeight(float height, PIDHoverType hoverType, float tau)
2037 { 2009 {
2038 SceneObjectPart rootpart = m_rootPart; 2010 if (RootPart.PhysActor != null)
2039 if (rootpart != null)
2040 { 2011 {
2041 if (rootpart.PhysActor != null) 2012 if (height != 0f)
2042 { 2013 {
2043 if (height != 0f) 2014 RootPart.PhysActor.PIDHoverHeight = height;
2044 { 2015 RootPart.PhysActor.PIDHoverType = hoverType;
2045 rootpart.PhysActor.PIDHoverHeight = height; 2016 RootPart.PhysActor.PIDTau = tau;
2046 rootpart.PhysActor.PIDHoverType = hoverType; 2017 RootPart.PhysActor.PIDHoverActive = true;
2047 rootpart.PhysActor.PIDTau = tau; 2018 }
2048 rootpart.PhysActor.PIDHoverActive = true; 2019 else
2049 } 2020 {
2050 else 2021 RootPart.PhysActor.PIDHoverActive = false;
2051 {
2052 rootpart.PhysActor.PIDHoverActive = false;
2053 }
2054 } 2022 }
2055 } 2023 }
2056 } 2024 }
@@ -2145,7 +2113,7 @@ namespace OpenSim.Region.Framework.Scenes
2145 // an object has been deleted from a scene before update was processed. 2113 // an object has been deleted from a scene before update was processed.
2146 // A more fundamental overhaul of the update mechanism is required to eliminate all 2114 // A more fundamental overhaul of the update mechanism is required to eliminate all
2147 // the race conditions. 2115 // the race conditions.
2148 if (m_isDeleted) 2116 if (IsDeleted)
2149 return; 2117 return;
2150 2118
2151 // Even temporary objects take part in physics (e.g. temp-on-rez bullets) 2119 // Even temporary objects take part in physics (e.g. temp-on-rez bullets)
@@ -2459,7 +2427,7 @@ namespace OpenSim.Region.Framework.Scenes
2459 } 2427 }
2460 2428
2461 m_scene.UnlinkSceneObject(objectGroup, true); 2429 m_scene.UnlinkSceneObject(objectGroup, true);
2462 objectGroup.m_isDeleted = true; 2430 objectGroup.IsDeleted = true;
2463 2431
2464 objectGroup.m_parts.Clear(); 2432 objectGroup.m_parts.Clear();
2465 2433
@@ -2597,8 +2565,7 @@ namespace OpenSim.Region.Framework.Scenes
2597 public virtual void DetachFromBackup() 2565 public virtual void DetachFromBackup()
2598 { 2566 {
2599 m_scene.SceneGraph.FireDetachFromBackup(this); 2567 m_scene.SceneGraph.FireDetachFromBackup(this);
2600 2568 if (m_isBackedUp && Scene != null)
2601 if (m_isBackedUp)
2602 m_scene.EventManager.OnBackup -= ProcessBackup; 2569 m_scene.EventManager.OnBackup -= ProcessBackup;
2603 2570
2604 m_isBackedUp = false; 2571 m_isBackedUp = false;
@@ -2858,14 +2825,15 @@ namespace OpenSim.Region.Framework.Scenes
2858 /// Update prim flags for this group. 2825 /// Update prim flags for this group.
2859 /// </summary> 2826 /// </summary>
2860 /// <param name="localID"></param> 2827 /// <param name="localID"></param>
2861 /// <param name="type"></param> 2828 /// <param name="UsePhysics"></param>
2862 /// <param name="inUse"></param> 2829 /// <param name="SetTemporary"></param>
2863 /// <param name="data"></param> 2830 /// <param name="SetPhantom"></param>
2864 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVolumeDetect) 2831 /// <param name="SetVolumeDetect"></param>
2832 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
2865 { 2833 {
2866 SceneObjectPart selectionPart = GetChildPart(localID); 2834 SceneObjectPart selectionPart = GetChildPart(localID);
2867 2835
2868 if (IsTemporary) 2836 if (SetTemporary && Scene != null)
2869 { 2837 {
2870 DetachFromBackup(); 2838 DetachFromBackup();
2871 // Remove from database and parcel prim count 2839 // Remove from database and parcel prim count
@@ -2877,23 +2845,27 @@ namespace OpenSim.Region.Framework.Scenes
2877 if (selectionPart != null) 2845 if (selectionPart != null)
2878 { 2846 {
2879 SceneObjectPart[] parts = m_parts.GetArray(); 2847 SceneObjectPart[] parts = m_parts.GetArray();
2880 for (int i = 0; i < parts.Length; i++) 2848
2849 if (Scene != null)
2881 { 2850 {
2882 SceneObjectPart part = parts[i]; 2851 for (int i = 0; i < parts.Length; i++)
2883 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2884 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
2885 part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
2886 { 2852 {
2887 UsePhysics = false; // Reset physics 2853 SceneObjectPart part = parts[i];
2888 break; 2854 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2855 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
2856 part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
2857 {
2858 UsePhysics = false; // Reset physics
2859 break;
2860 }
2889 } 2861 }
2890 } 2862 }
2891 2863
2892 RootPart.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2864 RootPart.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, SetVolumeDetect);
2893 for (int i = 0; i < parts.Length; i++) 2865 for (int i = 0; i < parts.Length; i++)
2894 { 2866 {
2895 if (parts[i] != RootPart) 2867 if (parts[i] != RootPart)
2896 parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2868 parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, SetVolumeDetect);
2897 } 2869 }
2898 } 2870 }
2899 } 2871 }
@@ -2967,202 +2939,150 @@ namespace OpenSim.Region.Framework.Scenes
2967 #region Resize 2939 #region Resize
2968 2940
2969 /// <summary> 2941 /// <summary>
2970 /// Resize the given part 2942 /// Resize the entire group of prims.
2971 /// </summary> 2943 /// </summary>
2972 /// <param name="scale"></param> 2944 /// <param name="scale"></param>
2973 /// <param name="localID"></param> 2945 public void GroupResize(Vector3 scale)
2974 public void Resize(Vector3 scale, uint localID) 2946 {
2975 { 2947// m_log.DebugFormat(
2976 if (scale.X > m_scene.m_maxNonphys) 2948// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
2977 scale.X = m_scene.m_maxNonphys; 2949 RootPart.StoreUndoState(true);
2978 if (scale.Y > m_scene.m_maxNonphys)
2979 scale.Y = m_scene.m_maxNonphys;
2980 if (scale.Z > m_scene.m_maxNonphys)
2981 scale.Z = m_scene.m_maxNonphys;
2982 SceneObjectPart part = GetChildPart(localID);
2983 if (part != null)
2984 {
2985 if (part.PhysActor != null)
2986 {
2987 if (part.PhysActor.IsPhysical)
2988 {
2989 if (scale.X > m_scene.m_maxPhys)
2990 scale.X = m_scene.m_maxPhys;
2991 if (scale.Y > m_scene.m_maxPhys)
2992 scale.Y = m_scene.m_maxPhys;
2993 if (scale.Z > m_scene.m_maxPhys)
2994 scale.Z = m_scene.m_maxPhys;
2995 }
2996 part.PhysActor.Size = scale;
2997 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2998 }
2999 part.Resize(scale);
3000 2950
3001 HasGroupChanged = true; 2951 scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
3002 part.TriggerScriptChangedEvent(Changed.SCALE); 2952 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys);
3003 ScheduleGroupForFullUpdate(); 2953 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
3004 2954
3005 //if (part.UUID == m_rootPart.UUID) 2955 if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical)
3006 //{ 2956 {
3007 //if (m_rootPart.PhysActor != null) 2957 scale.X = Math.Min(scale.X, Scene.m_maxPhys);
3008 //{ 2958 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys);
3009 //m_rootPart.PhysActor.Size = 2959 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys);
3010 //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z);
3011 //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3012 //}
3013 //}
3014 } 2960 }
3015 }
3016 2961
3017 public void GroupResize(Vector3 scale, uint localID) 2962 float x = (scale.X / RootPart.Scale.X);
3018 { 2963 float y = (scale.Y / RootPart.Scale.Y);
3019 SceneObjectPart part = GetChildPart(localID); 2964 float z = (scale.Z / RootPart.Scale.Z);
3020 if (part != null)
3021 {
3022 if (scale.X > m_scene.m_maxNonphys)
3023 scale.X = m_scene.m_maxNonphys;
3024 if (scale.Y > m_scene.m_maxNonphys)
3025 scale.Y = m_scene.m_maxNonphys;
3026 if (scale.Z > m_scene.m_maxNonphys)
3027 scale.Z = m_scene.m_maxNonphys;
3028 if (part.PhysActor != null && part.PhysActor.IsPhysical)
3029 {
3030 if (scale.X > m_scene.m_maxPhys)
3031 scale.X = m_scene.m_maxPhys;
3032 if (scale.Y > m_scene.m_maxPhys)
3033 scale.Y = m_scene.m_maxPhys;
3034 if (scale.Z > m_scene.m_maxPhys)
3035 scale.Z = m_scene.m_maxPhys;
3036 }
3037 float x = (scale.X / part.Scale.X);
3038 float y = (scale.Y / part.Scale.Y);
3039 float z = (scale.Z / part.Scale.Z);
3040 2965
3041 SceneObjectPart[] parts; 2966 SceneObjectPart[] parts;
3042 if (x > 1.0f || y > 1.0f || z > 1.0f) 2967 if (x > 1.0f || y > 1.0f || z > 1.0f)
2968 {
2969 parts = m_parts.GetArray();
2970 for (int i = 0; i < parts.Length; i++)
3043 { 2971 {
3044 parts = m_parts.GetArray(); 2972 SceneObjectPart obPart = parts[i];
3045 for (int i = 0; i < parts.Length; i++) 2973 if (obPart.UUID != m_rootPart.UUID)
3046 { 2974 {
3047 SceneObjectPart obPart = parts[i]; 2975// obPart.IgnoreUndoUpdate = true;
3048 if (obPart.UUID != m_rootPart.UUID) 2976 Vector3 oldSize = new Vector3(obPart.Scale);
2977
2978 float f = 1.0f;
2979 float a = 1.0f;
2980
2981 if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical)
3049 { 2982 {
3050 obPart.IgnoreUndoUpdate = true; 2983 if (oldSize.X * x > m_scene.m_maxPhys)
3051 Vector3 oldSize = new Vector3(obPart.Scale); 2984 {
2985 f = m_scene.m_maxPhys / oldSize.X;
2986 a = f / x;
2987 x *= a;
2988 y *= a;
2989 z *= a;
2990 }
3052 2991
3053 float f = 1.0f; 2992 if (oldSize.Y * y > m_scene.m_maxPhys)
3054 float a = 1.0f; 2993 {
2994 f = m_scene.m_maxPhys / oldSize.Y;
2995 a = f / y;
2996 x *= a;
2997 y *= a;
2998 z *= a;
2999 }
3055 3000
3056 if (part.PhysActor != null && part.PhysActor.IsPhysical) 3001 if (oldSize.Z * z > m_scene.m_maxPhys)
3057 { 3002 {
3058 if (oldSize.X*x > m_scene.m_maxPhys) 3003 f = m_scene.m_maxPhys / oldSize.Z;
3059 { 3004 a = f / z;
3060 f = m_scene.m_maxPhys / oldSize.X; 3005 x *= a;
3061 a = f / x; 3006 y *= a;
3062 x *= a; 3007 z *= a;
3063 y *= a;
3064 z *= a;
3065 }
3066 if (oldSize.Y*y > m_scene.m_maxPhys)
3067 {
3068 f = m_scene.m_maxPhys / oldSize.Y;
3069 a = f / y;
3070 x *= a;
3071 y *= a;
3072 z *= a;
3073 }
3074 if (oldSize.Z*z > m_scene.m_maxPhys)
3075 {
3076 f = m_scene.m_maxPhys / oldSize.Z;
3077 a = f / z;
3078 x *= a;
3079 y *= a;
3080 z *= a;
3081 }
3082 } 3008 }
3083 else 3009 }
3010 else
3011 {
3012 if (oldSize.X * x > m_scene.m_maxNonphys)
3084 { 3013 {
3085 if (oldSize.X*x > m_scene.m_maxNonphys) 3014 f = m_scene.m_maxNonphys / oldSize.X;
3086 { 3015 a = f / x;
3087 f = m_scene.m_maxNonphys / oldSize.X; 3016 x *= a;
3088 a = f / x; 3017 y *= a;
3089 x *= a; 3018 z *= a;
3090 y *= a; 3019 }
3091 z *= a; 3020
3092 } 3021 if (oldSize.Y * y > m_scene.m_maxNonphys)
3093 if (oldSize.Y*y > m_scene.m_maxNonphys) 3022 {
3094 { 3023 f = m_scene.m_maxNonphys / oldSize.Y;
3095 f = m_scene.m_maxNonphys / oldSize.Y; 3024 a = f / y;
3096 a = f / y; 3025 x *= a;
3097 x *= a; 3026 y *= a;
3098 y *= a; 3027 z *= a;
3099 z *= a; 3028 }
3100 } 3029
3101 if (oldSize.Z*z > m_scene.m_maxNonphys) 3030 if (oldSize.Z * z > m_scene.m_maxNonphys)
3102 { 3031 {
3103 f = m_scene.m_maxNonphys / oldSize.Z; 3032 f = m_scene.m_maxNonphys / oldSize.Z;
3104 a = f / z; 3033 a = f / z;
3105 x *= a; 3034 x *= a;
3106 y *= a; 3035 y *= a;
3107 z *= a; 3036 z *= a;
3108 }
3109 } 3037 }
3110 obPart.IgnoreUndoUpdate = false;
3111 } 3038 }
3039
3040// obPart.IgnoreUndoUpdate = false;
3112 } 3041 }
3113 } 3042 }
3043 }
3114 3044
3115 Vector3 prevScale = part.Scale; 3045 Vector3 prevScale = RootPart.Scale;
3116 prevScale.X *= x; 3046 prevScale.X *= x;
3117 prevScale.Y *= y; 3047 prevScale.Y *= y;
3118 prevScale.Z *= z;; 3048 prevScale.Z *= z;
3049// RootPart.IgnoreUndoUpdate = true;
3050 RootPart.Resize(prevScale);
3051// RootPart.IgnoreUndoUpdate = false;
3119 3052
3120 part.IgnoreUndoUpdate = false; 3053 parts = m_parts.GetArray();
3121 part.StoreUndoState(UndoType.STATE_GROUP_SCALE); 3054 for (int i = 0; i < parts.Length; i++)
3122 part.IgnoreUndoUpdate = true; 3055 {
3123 part.Resize(prevScale); 3056 SceneObjectPart obPart = parts[i];
3124 part.IgnoreUndoUpdate = false;
3125 3057
3126 parts = m_parts.GetArray(); 3058 if (obPart.UUID != m_rootPart.UUID)
3127 for (int i = 0; i < parts.Length; i++)
3128 { 3059 {
3129 SceneObjectPart obPart = parts[i];
3130 obPart.IgnoreUndoUpdate = true; 3060 obPart.IgnoreUndoUpdate = true;
3131 if (obPart.UUID != m_rootPart.UUID)
3132 {
3133 if (obPart.UUID != m_rootPart.UUID)
3134 {
3135 obPart.IgnoreUndoUpdate = false;
3136 obPart.StoreUndoState(UndoType.STATE_GROUP_SCALE);
3137 obPart.IgnoreUndoUpdate = true;
3138
3139 Vector3 currentpos = new Vector3(obPart.OffsetPosition);
3140 currentpos.X *= x;
3141 currentpos.Y *= y;
3142 currentpos.Z *= z;
3143 Vector3 newSize = new Vector3(obPart.Scale);
3144 newSize.X *= x;
3145 newSize.Y *= y;
3146 newSize.Z *= z;
3147 obPart.Resize(newSize);
3148 obPart.UpdateOffSet(currentpos);
3149 }
3150 obPart.IgnoreUndoUpdate = false;
3151 }
3152 obPart.IgnoreUndoUpdate = false;
3153 }
3154 3061
3155 if (part.PhysActor != null) 3062 Vector3 currentpos = new Vector3(obPart.OffsetPosition);
3156 { 3063 currentpos.X *= x;
3157 part.PhysActor.Size = prevScale; 3064 currentpos.Y *= y;
3158 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 3065 currentpos.Z *= z;
3066
3067 Vector3 newSize = new Vector3(obPart.Scale);
3068 newSize.X *= x;
3069 newSize.Y *= y;
3070 newSize.Z *= z;
3071
3072 obPart.Resize(newSize);
3073 obPart.UpdateOffSet(currentpos);
3074
3075 obPart.IgnoreUndoUpdate = false;
3159 } 3076 }
3160 3077
3161 part.IgnoreUndoUpdate = false; 3078// obPart.IgnoreUndoUpdate = false;
3162 HasGroupChanged = true; 3079 HasGroupChanged = true;
3163 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); 3080 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
3164 ScheduleGroupForTerseUpdate(); 3081 ScheduleGroupForTerseUpdate();
3165 } 3082 }
3083
3084// m_log.DebugFormat(
3085// "[SCENE OBJECT GROUP]: Finished group resizing {0} {1} to {2}", Name, LocalId, RootPart.Scale);
3166 } 3086 }
3167 3087
3168 #endregion 3088 #endregion
@@ -3175,11 +3095,18 @@ namespace OpenSim.Region.Framework.Scenes
3175 /// <param name="pos"></param> 3095 /// <param name="pos"></param>
3176 public void UpdateGroupPosition(Vector3 pos) 3096 public void UpdateGroupPosition(Vector3 pos)
3177 { 3097 {
3098// m_log.DebugFormat("[SCENE OBJECT GROUP]: Updating group position on {0} {1} to {2}", Name, LocalId, pos);
3099
3100 RootPart.StoreUndoState(true);
3101
3102// SceneObjectPart[] parts = m_parts.GetArray();
3103// for (int i = 0; i < parts.Length; i++)
3104// parts[i].StoreUndoState();
3105
3178 if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) 3106 if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
3179 { 3107 {
3180 if (IsAttachment) 3108 if (IsAttachment)
3181 { 3109 {
3182 m_rootPart.StoreUndoState(UndoType.STATE_GROUP_POSITION);
3183 m_rootPart.AttachedPos = pos; 3110 m_rootPart.AttachedPos = pos;
3184 } 3111 }
3185 if (RootPart.GetStatusSandbox()) 3112 if (RootPart.GetStatusSandbox())
@@ -3213,10 +3140,16 @@ namespace OpenSim.Region.Framework.Scenes
3213 3140
3214 SceneObjectPart[] parts = m_parts.GetArray(); 3141 SceneObjectPart[] parts = m_parts.GetArray();
3215 for (int i = 0; i < parts.Length; i++) 3142 for (int i = 0; i < parts.Length; i++)
3216 parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION); 3143 parts[i].StoreUndoState();
3217 3144
3218 if (part != null) 3145 if (part != null)
3219 { 3146 {
3147// m_log.DebugFormat(
3148// "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos);
3149
3150 part.StoreUndoState(false);
3151 part.IgnoreUndoUpdate = true;
3152
3220 if (part.UUID == m_rootPart.UUID) 3153 if (part.UUID == m_rootPart.UUID)
3221 { 3154 {
3222 UpdateRootPosition(pos); 3155 UpdateRootPosition(pos);
@@ -3227,18 +3160,22 @@ namespace OpenSim.Region.Framework.Scenes
3227 } 3160 }
3228 3161
3229 HasGroupChanged = true; 3162 HasGroupChanged = true;
3163 part.IgnoreUndoUpdate = false;
3230 } 3164 }
3231 } 3165 }
3232 3166
3233 /// <summary> 3167 /// <summary>
3234 /// 3168 /// Update just the root prim position in a linkset
3235 /// </summary> 3169 /// </summary>
3236 /// <param name="pos"></param> 3170 /// <param name="pos"></param>
3237 private void UpdateRootPosition(Vector3 pos) 3171 public void UpdateRootPosition(Vector3 pos)
3238 { 3172 {
3239 SceneObjectPart[] parts = m_parts.GetArray(); 3173// m_log.DebugFormat(
3240 for (int i = 0; i < parts.Length; i++) 3174// "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos);
3241 parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION); 3175
3176// SceneObjectPart[] parts = m_parts.GetArray();
3177// for (int i = 0; i < parts.Length; i++)
3178// parts[i].StoreUndoState();
3242 3179
3243 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); 3180 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
3244 Vector3 oldPos = 3181 Vector3 oldPos =
@@ -3251,7 +3188,7 @@ namespace OpenSim.Region.Framework.Scenes
3251 axDiff *= Quaternion.Inverse(partRotation); 3188 axDiff *= Quaternion.Inverse(partRotation);
3252 diff = axDiff; 3189 diff = axDiff;
3253 3190
3254 parts = m_parts.GetArray(); 3191 SceneObjectPart[] parts = m_parts.GetArray();
3255 for (int i = 0; i < parts.Length; i++) 3192 for (int i = 0; i < parts.Length; i++)
3256 { 3193 {
3257 SceneObjectPart obPart = parts[i]; 3194 SceneObjectPart obPart = parts[i];
@@ -3297,9 +3234,14 @@ namespace OpenSim.Region.Framework.Scenes
3297 /// <param name="rot"></param> 3234 /// <param name="rot"></param>
3298 public void UpdateGroupRotationR(Quaternion rot) 3235 public void UpdateGroupRotationR(Quaternion rot)
3299 { 3236 {
3300 SceneObjectPart[] parts = m_parts.GetArray(); 3237// m_log.DebugFormat(
3301 for (int i = 0; i < parts.Length; i++) 3238// "[SCENE OBJECT GROUP]: Updating group rotation R of {0} {1} to {2}", Name, LocalId, rot);
3302 parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION); 3239
3240// SceneObjectPart[] parts = m_parts.GetArray();
3241// for (int i = 0; i < parts.Length; i++)
3242// parts[i].StoreUndoState();
3243
3244 m_rootPart.StoreUndoState(true);
3303 3245
3304 m_rootPart.UpdateRotation(rot); 3246 m_rootPart.UpdateRotation(rot);
3305 3247
@@ -3321,9 +3263,15 @@ namespace OpenSim.Region.Framework.Scenes
3321 /// <param name="rot"></param> 3263 /// <param name="rot"></param>
3322 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) 3264 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
3323 { 3265 {
3324 SceneObjectPart[] parts = m_parts.GetArray(); 3266// m_log.DebugFormat(
3325 for (int i = 0; i < parts.Length; i++) 3267// "[SCENE OBJECT GROUP]: Updating group rotation PR of {0} {1} to {2}", Name, LocalId, rot);
3326 parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION); 3268
3269// SceneObjectPart[] parts = m_parts.GetArray();
3270// for (int i = 0; i < parts.Length; i++)
3271// parts[i].StoreUndoState();
3272
3273 RootPart.StoreUndoState(true);
3274 RootPart.IgnoreUndoUpdate = true;
3327 3275
3328 m_rootPart.UpdateRotation(rot); 3276 m_rootPart.UpdateRotation(rot);
3329 3277
@@ -3338,6 +3286,8 @@ namespace OpenSim.Region.Framework.Scenes
3338 3286
3339 HasGroupChanged = true; 3287 HasGroupChanged = true;
3340 ScheduleGroupForTerseUpdate(); 3288 ScheduleGroupForTerseUpdate();
3289
3290 RootPart.IgnoreUndoUpdate = false;
3341 } 3291 }
3342 3292
3343 /// <summary> 3293 /// <summary>
@@ -3349,11 +3299,12 @@ namespace OpenSim.Region.Framework.Scenes
3349 { 3299 {
3350 SceneObjectPart part = GetChildPart(localID); 3300 SceneObjectPart part = GetChildPart(localID);
3351 SceneObjectPart[] parts = m_parts.GetArray(); 3301 SceneObjectPart[] parts = m_parts.GetArray();
3352 for (int i = 0; i < parts.Length; i++)
3353 parts[i].StoreUndoState(UndoType.STATE_PRIM_ROTATION);
3354 3302
3355 if (part != null) 3303 if (part != null)
3356 { 3304 {
3305// m_log.DebugFormat(
3306// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot);
3307
3357 if (part.UUID == m_rootPart.UUID) 3308 if (part.UUID == m_rootPart.UUID)
3358 { 3309 {
3359 UpdateRootRotation(rot); 3310 UpdateRootRotation(rot);
@@ -3375,6 +3326,13 @@ namespace OpenSim.Region.Framework.Scenes
3375 SceneObjectPart part = GetChildPart(localID); 3326 SceneObjectPart part = GetChildPart(localID);
3376 if (part != null) 3327 if (part != null)
3377 { 3328 {
3329// m_log.DebugFormat(
3330// "[SCENE OBJECT GROUP]: Updating single position and rotation of {0} {1} to {2}",
3331// part.Name, part.LocalId, rot);
3332
3333 part.StoreUndoState();
3334 part.IgnoreUndoUpdate = true;
3335
3378 if (part.UUID == m_rootPart.UUID) 3336 if (part.UUID == m_rootPart.UUID)
3379 { 3337 {
3380 UpdateRootRotation(rot); 3338 UpdateRootRotation(rot);
@@ -3391,12 +3349,11 @@ namespace OpenSim.Region.Framework.Scenes
3391 } 3349 }
3392 else 3350 else
3393 { 3351 {
3394 part.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
3395 part.IgnoreUndoUpdate = true;
3396 part.UpdateRotation(rot); 3352 part.UpdateRotation(rot);
3397 part.OffsetPosition = pos; 3353 part.OffsetPosition = pos;
3398 part.IgnoreUndoUpdate = false;
3399 } 3354 }
3355
3356 part.IgnoreUndoUpdate = false;
3400 } 3357 }
3401 } 3358 }
3402 3359
@@ -3404,18 +3361,15 @@ namespace OpenSim.Region.Framework.Scenes
3404 /// 3361 ///
3405 /// </summary> 3362 /// </summary>
3406 /// <param name="rot"></param> 3363 /// <param name="rot"></param>
3407 private void UpdateRootRotation(Quaternion rot) 3364 public void UpdateRootRotation(Quaternion rot)
3408 { 3365 {
3366// m_log.DebugFormat(
3367// "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}",
3368// Name, LocalId, rot);
3369
3409 Quaternion axRot = rot; 3370 Quaternion axRot = rot;
3410 Quaternion oldParentRot = m_rootPart.RotationOffset; 3371 Quaternion oldParentRot = m_rootPart.RotationOffset;
3411 3372 m_rootPart.StoreUndoState();
3412 m_rootPart.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
3413 bool cancelUndo = false;
3414 if (!m_rootPart.Undoing)
3415 {
3416 m_rootPart.Undoing = true;
3417 cancelUndo = true;
3418 }
3419 3373
3420 //Don't use UpdateRotation because it schedules an update prematurely 3374 //Don't use UpdateRotation because it schedules an update prematurely
3421 m_rootPart.RotationOffset = rot; 3375 m_rootPart.RotationOffset = rot;
@@ -3444,14 +3398,25 @@ namespace OpenSim.Region.Framework.Scenes
3444 prim.OffsetPosition = axPos; 3398 prim.OffsetPosition = axPos;
3445 3399
3446 prim.IgnoreUndoUpdate = false; 3400 prim.IgnoreUndoUpdate = false;
3401 prim.IgnoreUndoUpdate = false;
3447 } 3402 }
3448 } 3403 }
3449 if (cancelUndo == true) 3404
3450 { 3405// for (int i = 0; i < parts.Length; i++)
3451 m_rootPart.Undoing = false; 3406// {
3452 } 3407// SceneObjectPart childpart = parts[i];
3408// if (childpart != m_rootPart)
3409// {
3410//// childpart.IgnoreUndoUpdate = false;
3411//// childpart.StoreUndoState();
3412// }
3413// }
3453 HasGroupChanged = true; 3414 HasGroupChanged = true;
3454 ScheduleGroupForFullUpdate(); 3415 ScheduleGroupForFullUpdate();
3416
3417// m_log.DebugFormat(
3418// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}",
3419// Name, LocalId, rot);
3455 } 3420 }
3456 3421
3457 #endregion 3422 #endregion
@@ -3466,28 +3431,23 @@ namespace OpenSim.Region.Framework.Scenes
3466 int yaxis = 4; 3431 int yaxis = 4;
3467 int zaxis = 8; 3432 int zaxis = 8;
3468 3433
3469 if (m_rootPart != null) 3434 setX = ((axis & xaxis) != 0) ? true : false;
3470 { 3435 setY = ((axis & yaxis) != 0) ? true : false;
3471 setX = ((axis & xaxis) != 0) ? true : false; 3436 setZ = ((axis & zaxis) != 0) ? true : false;
3472 setY = ((axis & yaxis) != 0) ? true : false;
3473 setZ = ((axis & zaxis) != 0) ? true : false;
3474
3475 float setval = (rotate10 > 0) ? 1f : 0f;
3476 3437
3477 if (setX) 3438 float setval = (rotate10 > 0) ? 1f : 0f;
3478 m_rootPart.RotationAxis.X = setval;
3479 if (setY)
3480 m_rootPart.RotationAxis.Y = setval;
3481 if (setZ)
3482 m_rootPart.RotationAxis.Z = setval;
3483 3439
3484 if (setX || setY || setZ) 3440 if (setX)
3485 { 3441 RootPart.RotationAxis.X = setval;
3486 m_rootPart.SetPhysicsAxisRotation(); 3442 if (setY)
3487 } 3443 RootPart.RotationAxis.Y = setval;
3444 if (setZ)
3445 RootPart.RotationAxis.Z = setval;
3488 3446
3489 } 3447 if (setX || setY || setZ)
3448 RootPart.SetPhysicsAxisRotation();
3490 } 3449 }
3450
3491 public int registerRotTargetWaypoint(Quaternion target, float tolerance) 3451 public int registerRotTargetWaypoint(Quaternion target, float tolerance)
3492 { 3452 {
3493 scriptRotTarget waypoint = new scriptRotTarget(); 3453 scriptRotTarget waypoint = new scriptRotTarget();
@@ -3615,7 +3575,13 @@ namespace OpenSim.Region.Framework.Scenes
3615 foreach (uint idx in m_rotTargets.Keys) 3575 foreach (uint idx in m_rotTargets.Keys)
3616 { 3576 {
3617 scriptRotTarget target = m_rotTargets[idx]; 3577 scriptRotTarget target = m_rotTargets[idx];
3618 double angle = Math.Acos(target.targetRot.X * m_rootPart.RotationOffset.X + target.targetRot.Y * m_rootPart.RotationOffset.Y + target.targetRot.Z * m_rootPart.RotationOffset.Z + target.targetRot.W * m_rootPart.RotationOffset.W) * 2; 3578 double angle
3579 = Math.Acos(
3580 target.targetRot.X * m_rootPart.RotationOffset.X
3581 + target.targetRot.Y * m_rootPart.RotationOffset.Y
3582 + target.targetRot.Z * m_rootPart.RotationOffset.Z
3583 + target.targetRot.W * m_rootPart.RotationOffset.W)
3584 * 2;
3619 if (angle < 0) angle = -angle; 3585 if (angle < 0) angle = -angle;
3620 if (angle > Math.PI) angle = (Math.PI * 2 - angle); 3586 if (angle > Math.PI) angle = (Math.PI * 2 - angle);
3621 if (angle <= target.tolerance) 3587 if (angle <= target.tolerance)
@@ -3680,43 +3646,28 @@ namespace OpenSim.Region.Framework.Scenes
3680 3646
3681 return retmass; 3647 return retmass;
3682 } 3648 }
3683 3649
3650 /// <summary>
3651 /// If the object is a sculpt/mesh, retrieve the mesh data for each part and reinsert it into each shape so that
3652 /// the physics engine can use it.
3653 /// </summary>
3654 /// <remarks>
3655 /// When the physics engine has finished with it, the sculpt data is discarded to save memory.
3656 /// </remarks>
3684 public void CheckSculptAndLoad() 3657 public void CheckSculptAndLoad()
3685 { 3658 {
3686 if (IsDeleted) 3659 if (IsDeleted)
3687 return; 3660 return;
3661
3688 if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) 3662 if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
3689 return; 3663 return;
3690 3664
3691 SceneObjectPart[] parts = m_parts.GetArray(); 3665// m_log.Debug("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
3692 for (int i = 0; i < parts.Length; i++)
3693 {
3694 SceneObjectPart part = parts[i];
3695 if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero)
3696 {
3697 // check if a previously decoded sculpt map has been cached
3698 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString())))
3699 {
3700 part.SculptTextureCallback(part.Shape.SculptTexture, null);
3701 }
3702 else
3703 {
3704 m_scene.AssetService.Get(
3705 part.Shape.SculptTexture.ToString(), part, AssetReceived);
3706 }
3707 }
3708 }
3709 }
3710 3666
3711 protected void AssetReceived(string id, Object sender, AssetBase asset) 3667 SceneObjectPart[] parts = m_parts.GetArray();
3712 {
3713 SceneObjectPart sop = (SceneObjectPart)sender;
3714 3668
3715 if (sop != null) 3669 for (int i = 0; i < parts.Length; i++)
3716 { 3670 parts[i].CheckSculptAndLoad();
3717 if (asset != null)
3718 sop.SculptTextureCallback(asset.FullID, asset);
3719 }
3720 } 3671 }
3721 3672
3722 /// <summary> 3673 /// <summary>
@@ -3751,19 +3702,12 @@ namespace OpenSim.Region.Framework.Scenes
3751 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); 3702 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition);
3752 } 3703 }
3753 3704
3754 public void SetAttachmentPoint(byte point)
3755 {
3756 SceneObjectPart[] parts = m_parts.GetArray();
3757 for (int i = 0; i < parts.Length; i++)
3758 parts[i].SetAttachmentPoint(point);
3759 }
3760
3761 #region ISceneObject 3705 #region ISceneObject
3762 3706
3763 public virtual ISceneObject CloneForNewScene() 3707 public virtual ISceneObject CloneForNewScene()
3764 { 3708 {
3765 SceneObjectGroup sog = Copy(false); 3709 SceneObjectGroup sog = Copy(false);
3766 sog.m_isDeleted = false; 3710 sog.IsDeleted = false;
3767 return sog; 3711 return sog;
3768 } 3712 }
3769 3713
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 037f384..0c3b404 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Drawing; 30using System.Drawing;
31using System.IO;
31using System.Reflection; 32using System.Reflection;
32using System.Runtime.Serialization; 33using System.Runtime.Serialization;
33using System.Security.Permissions; 34using System.Security.Permissions;
@@ -216,28 +217,18 @@ namespace OpenSim.Region.Framework.Scenes
216 /// </value> 217 /// </value>
217 private UUID m_fromUserInventoryItemID; 218 private UUID m_fromUserInventoryItemID;
218 219
219
220 public UUID FromUserInventoryItemID 220 public UUID FromUserInventoryItemID
221 { 221 {
222 get { return m_fromUserInventoryItemID; } 222 get { return m_fromUserInventoryItemID; }
223 set { m_fromUserInventoryItemID = value; }
223 } 224 }
224 225
225
226 public bool IsAttachment;
227
228
229 public scriptEvents AggregateScriptEvents; 226 public scriptEvents AggregateScriptEvents;
230 227
231 228
232 public UUID AttachedAvatar;
233
234
235 public Vector3 AttachedPos; 229 public Vector3 AttachedPos;
236 230
237 231
238 public uint AttachmentPoint;
239
240
241 public Vector3 RotationAxis = Vector3.One; 232 public Vector3 RotationAxis = Vector3.One;
242 233
243 234
@@ -269,12 +260,9 @@ namespace OpenSim.Region.Framework.Scenes
269 } 260 }
270 protected SceneObjectPartInventory m_inventory; 261 protected SceneObjectPartInventory m_inventory;
271 262
272
273 public bool Undoing; 263 public bool Undoing;
274
275 264
276 public bool IgnoreUndoUpdate = false; 265 public bool IgnoreUndoUpdate = false;
277
278 266
279 private PrimFlags LocalFlags; 267 private PrimFlags LocalFlags;
280 268
@@ -296,8 +284,8 @@ namespace OpenSim.Region.Framework.Scenes
296 private bool m_occupied; // KF if any av is sitting on this prim 284 private bool m_occupied; // KF if any av is sitting on this prim
297 private string m_text = String.Empty; 285 private string m_text = String.Empty;
298 private string m_touchName = String.Empty; 286 private string m_touchName = String.Empty;
299 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 287 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5);
300 private readonly UndoStack<UndoState> m_redo = new UndoStack<UndoState>(5); 288 private readonly Stack<UndoState> m_redo = new Stack<UndoState>(5);
301 private UUID _creatorID; 289 private UUID _creatorID;
302 290
303 private bool m_passTouches; 291 private bool m_passTouches;
@@ -323,7 +311,6 @@ namespace OpenSim.Region.Framework.Scenes
323 protected string m_name; 311 protected string m_name;
324 protected Vector3 m_offsetPosition; 312 protected Vector3 m_offsetPosition;
325 313
326 // FIXME, TODO, ERROR: 'ParentGroup' can't be in here, move it out.
327 protected SceneObjectGroup m_parentGroup; 314 protected SceneObjectGroup m_parentGroup;
328 protected byte[] m_particleSystem = Utils.EmptyBytes; 315 protected byte[] m_particleSystem = Utils.EmptyBytes;
329 protected ulong m_regionHandle; 316 protected ulong m_regionHandle;
@@ -424,7 +411,6 @@ namespace OpenSim.Region.Framework.Scenes
424 CreateSelected = true; 411 CreateSelected = true;
425 412
426 TrimPermissions(); 413 TrimPermissions();
427 //m_undo = new UndoStack<UndoState>(ParentGroup.GetSceneMaxUndo());
428 414
429 m_inventory = new SceneObjectPartInventory(this); 415 m_inventory = new SceneObjectPartInventory(this);
430 } 416 }
@@ -619,6 +605,7 @@ namespace OpenSim.Region.Framework.Scenes
619 set 605 set
620 { 606 {
621 m_passTouches = value; 607 m_passTouches = value;
608
622 if (ParentGroup != null) 609 if (ParentGroup != null)
623 ParentGroup.HasGroupChanged = true; 610 ParentGroup.HasGroupChanged = true;
624 } 611 }
@@ -744,9 +731,9 @@ namespace OpenSim.Region.Framework.Scenes
744 return m_groupPosition; 731 return m_groupPosition;
745 } 732 }
746 733
747 if (IsAttachment) 734 if (m_parentGroup.IsAttachment)
748 { 735 {
749 ScenePresence sp = m_parentGroup.Scene.GetScenePresence(AttachedAvatar); 736 ScenePresence sp = m_parentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
750 if (sp != null) 737 if (sp != null)
751 return sp.AbsolutePosition; 738 return sp.AbsolutePosition;
752 } 739 }
@@ -794,7 +781,6 @@ namespace OpenSim.Region.Framework.Scenes
794 set 781 set
795 { 782 {
796 Vector3 oldpos = m_offsetPosition; 783 Vector3 oldpos = m_offsetPosition;
797 StoreUndoState(UndoType.STATE_PRIM_POSITION);
798 m_offsetPosition = value; 784 m_offsetPosition = value;
799 785
800 if (ParentGroup != null && !ParentGroup.IsDeleted) 786 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -834,7 +820,7 @@ namespace OpenSim.Region.Framework.Scenes
834 { 820 {
835 if (IsRoot) 821 if (IsRoot)
836 { 822 {
837 if (IsAttachment) 823 if (m_parentGroup.IsAttachment)
838 return AttachedPos; 824 return AttachedPos;
839 else 825 else
840 return AbsolutePosition; 826 return AbsolutePosition;
@@ -866,7 +852,7 @@ namespace OpenSim.Region.Framework.Scenes
866 852
867 set 853 set
868 { 854 {
869 StoreUndoState(UndoType.STATE_PRIM_ROTATION); 855 StoreUndoState();
870 m_rotationOffset = value; 856 m_rotationOffset = value;
871 857
872 PhysicsActor actor = PhysActor; 858 PhysicsActor actor = PhysActor;
@@ -887,7 +873,9 @@ namespace OpenSim.Region.Framework.Scenes
887 actor.Orientation = resultingrotation; 873 actor.Orientation = resultingrotation;
888 //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString()); 874 //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString());
889 } 875 }
890 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 876
877 if (m_parentGroup != null)
878 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
891 //} 879 //}
892 } 880 }
893 catch (Exception ex) 881 catch (Exception ex)
@@ -895,7 +883,6 @@ namespace OpenSim.Region.Framework.Scenes
895 m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message); 883 m_log.Error("[SCENEOBJECTPART]: ROTATIONOFFSET" + ex.Message);
896 } 884 }
897 } 885 }
898
899 } 886 }
900 } 887 }
901 888
@@ -1044,30 +1031,39 @@ namespace OpenSim.Region.Framework.Scenes
1044 get { return m_shape; } 1031 get { return m_shape; }
1045 set { m_shape = value; } 1032 set { m_shape = value; }
1046 } 1033 }
1047 1034
1035 /// <summary>
1036 /// Change the scale of this part.
1037 /// </summary>
1048 public Vector3 Scale 1038 public Vector3 Scale
1049 { 1039 {
1050 get { return m_shape.Scale; } 1040 get { return m_shape.Scale; }
1051 set 1041 set
1052 { 1042 {
1053 StoreUndoState(UndoType.STATE_PRIM_SCALE);
1054 if (m_shape != null) 1043 if (m_shape != null)
1055 { 1044 {
1045 StoreUndoState();
1046
1056 m_shape.Scale = value; 1047 m_shape.Scale = value;
1057 1048
1058 PhysicsActor actor = PhysActor; 1049 PhysicsActor actor = PhysActor;
1059 if (actor != null && m_parentGroup != null) 1050 if (actor != null)
1060 { 1051 {
1061 if (m_parentGroup.Scene != null) 1052 if (m_parentGroup.Scene != null)
1062 { 1053 {
1063 if (m_parentGroup.Scene.PhysicsScene != null) 1054 if (m_parentGroup.Scene.PhysicsScene != null)
1064 { 1055 {
1065 actor.Size = m_shape.Scale; 1056 actor.Size = m_shape.Scale;
1066 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 1057
1058 if (Shape.SculptEntry)
1059 CheckSculptAndLoad();
1060 else
1061 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
1067 } 1062 }
1068 } 1063 }
1069 } 1064 }
1070 } 1065 }
1066
1071 TriggerScriptChangedEvent(Changed.SCALE); 1067 TriggerScriptChangedEvent(Changed.SCALE);
1072 } 1068 }
1073 } 1069 }
@@ -1092,13 +1088,12 @@ namespace OpenSim.Region.Framework.Scenes
1092 set 1088 set
1093 { 1089 {
1094 m_mediaUrl = value; 1090 m_mediaUrl = value;
1095 1091
1096 if (ParentGroup != null) 1092 if (ParentGroup != null)
1097 ParentGroup.HasGroupChanged = true; 1093 ParentGroup.HasGroupChanged = true;
1098 } 1094 }
1099 } 1095 }
1100 1096
1101
1102 public bool CreateSelected 1097 public bool CreateSelected
1103 { 1098 {
1104 get { return m_createSelected; } 1099 get { return m_createSelected; }
@@ -1118,7 +1113,10 @@ namespace OpenSim.Region.Framework.Scenes
1118 { 1113 {
1119 get 1114 get
1120 { 1115 {
1121 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset); 1116 if (m_parentGroup.IsAttachment)
1117 return GroupPosition;
1118
1119 return m_offsetPosition + m_groupPosition;
1122 } 1120 }
1123 } 1121 }
1124 1122
@@ -1138,7 +1136,6 @@ namespace OpenSim.Region.Framework.Scenes
1138 set { m_sitTargetOrientation = value; } 1136 set { m_sitTargetOrientation = value; }
1139 } 1137 }
1140 1138
1141
1142 public Vector3 SitTargetPosition 1139 public Vector3 SitTargetPosition
1143 { 1140 {
1144 get { return m_sitTargetPosition; } 1141 get { return m_sitTargetPosition; }
@@ -1268,7 +1265,9 @@ namespace OpenSim.Region.Framework.Scenes
1268 /// <summary> 1265 /// <summary>
1269 /// Property flags. See OpenMetaverse.PrimFlags 1266 /// Property flags. See OpenMetaverse.PrimFlags
1270 /// </summary> 1267 /// </summary>
1268 /// <remarks>
1271 /// Example properties are PrimFlags.Phantom and PrimFlags.DieAtEdge 1269 /// Example properties are PrimFlags.Phantom and PrimFlags.DieAtEdge
1270 /// </remarks>
1272 public PrimFlags Flags 1271 public PrimFlags Flags
1273 { 1272 {
1274 get { return _flags; } 1273 get { return _flags; }
@@ -1298,7 +1297,7 @@ namespace OpenSim.Region.Framework.Scenes
1298 { 1297 {
1299 get 1298 get
1300 { 1299 {
1301 if (ParentGroup != null && ParentGroup.Scene != null) 1300 if (ParentGroup.Scene != null)
1302 return ParentGroup.Scene.RegionInfo.RegionID; 1301 return ParentGroup.Scene.RegionInfo.RegionID;
1303 else 1302 else
1304 return UUID.Zero; 1303 return UUID.Zero;
@@ -1313,14 +1312,13 @@ namespace OpenSim.Region.Framework.Scenes
1313 get 1312 get
1314 { 1313 {
1315 if (ParentGroup != null) 1314 if (ParentGroup != null)
1316 {
1317 _parentUUID = ParentGroup.UUID; 1315 _parentUUID = ParentGroup.UUID;
1318 } 1316
1319 return _parentUUID; 1317 return _parentUUID;
1320 } 1318 }
1319
1321 set { _parentUUID = value; } 1320 set { _parentUUID = value; }
1322 } 1321 }
1323
1324 1322
1325 public string SitAnimation 1323 public string SitAnimation
1326 { 1324 {
@@ -1555,10 +1553,7 @@ namespace OpenSim.Region.Framework.Scenes
1555 impulse = newimpulse; 1553 impulse = newimpulse;
1556 } 1554 }
1557 1555
1558 if (m_parentGroup != null) 1556 m_parentGroup.applyAngularImpulse(impulse);
1559 {
1560 m_parentGroup.applyAngularImpulse(impulse);
1561 }
1562 } 1557 }
1563 1558
1564 /// <summary> 1559 /// <summary>
@@ -1581,19 +1576,7 @@ namespace OpenSim.Region.Framework.Scenes
1581 impulse = newimpulse; 1576 impulse = newimpulse;
1582 } 1577 }
1583 1578
1584 if (m_parentGroup != null) 1579 m_parentGroup.setAngularImpulse(impulse);
1585 {
1586 m_parentGroup.setAngularImpulse(impulse);
1587 }
1588 }
1589
1590 public Vector3 GetTorque()
1591 {
1592 if (m_parentGroup != null)
1593 {
1594 m_parentGroup.GetTorque();
1595 }
1596 return Vector3.Zero;
1597 } 1580 }
1598 1581
1599 /// <summary> 1582 /// <summary>
@@ -1623,7 +1606,7 @@ namespace OpenSim.Region.Framework.Scenes
1623 1606
1624 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition 1607 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition
1625 // or flexible 1608 // or flexible
1626 if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) 1609 if (!isPhantom && !m_parentGroup.IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible))
1627 { 1610 {
1628 try 1611 try
1629 { 1612 {
@@ -1635,7 +1618,6 @@ namespace OpenSim.Region.Framework.Scenes
1635 RotationOffset, 1618 RotationOffset,
1636 RigidBody, 1619 RigidBody,
1637 m_localId); 1620 m_localId);
1638 PhysActor.SetMaterial(Material);
1639 } 1621 }
1640 catch 1622 catch
1641 { 1623 {
@@ -1647,6 +1629,7 @@ namespace OpenSim.Region.Framework.Scenes
1647 { 1629 {
1648 PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info 1630 PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
1649 PhysActor.SOPDescription = this.Description; 1631 PhysActor.SOPDescription = this.Description;
1632 PhysActor.SetMaterial(Material);
1650 DoPhysicsPropertyUpdate(RigidBody, true); 1633 DoPhysicsPropertyUpdate(RigidBody, true);
1651 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); 1634 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
1652 } 1635 }
@@ -1658,19 +1641,6 @@ namespace OpenSim.Region.Framework.Scenes
1658 } 1641 }
1659 } 1642 }
1660 1643
1661 public void ClearUndoState()
1662 {
1663 lock (m_undo)
1664 {
1665 m_undo.Clear();
1666 }
1667 lock (m_redo)
1668 {
1669 m_redo.Clear();
1670 }
1671 StoreUndoState(UndoType.STATE_ALL);
1672 }
1673
1674 public byte ConvertScriptUintToByte(uint indata) 1644 public byte ConvertScriptUintToByte(uint indata)
1675 { 1645 {
1676 byte outdata = (byte)TextureAnimFlags.NONE; 1646 byte outdata = (byte)TextureAnimFlags.NONE;
@@ -1751,7 +1721,8 @@ namespace OpenSim.Region.Framework.Scenes
1751 { 1721 {
1752 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero) 1722 if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero)
1753 { 1723 {
1754 m_parentGroup.Scene.AssetService.Get(dupe.m_shape.SculptTexture.ToString(), dupe, AssetReceived); 1724 ParentGroup.Scene.AssetService.Get(
1725 dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived);
1755 } 1726 }
1756 1727
1757 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0); 1728 bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
@@ -1765,14 +1736,20 @@ namespace OpenSim.Region.Framework.Scenes
1765 return dupe; 1736 return dupe;
1766 } 1737 }
1767 1738
1739 /// <summary>
1740 /// Called back by asynchronous asset fetch.
1741 /// </summary>
1742 /// <param name="id">ID of asset received</param>
1743 /// <param name="sender">Register</param>
1744 /// <param name="asset"></param>
1768 protected void AssetReceived(string id, Object sender, AssetBase asset) 1745 protected void AssetReceived(string id, Object sender, AssetBase asset)
1769 { 1746 {
1770 if (asset != null) 1747 if (asset != null)
1771 { 1748 SculptTextureCallback(asset);
1772 SceneObjectPart sop = (SceneObjectPart)sender; 1749 else
1773 if (sop != null) 1750 m_log.WarnFormat(
1774 sop.SculptTextureCallback(asset.FullID, asset); 1751 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
1775 } 1752 Name, LocalId, id);
1776 } 1753 }
1777 1754
1778 public static SceneObjectPart Create() 1755 public static SceneObjectPart Create()
@@ -1789,97 +1766,111 @@ namespace OpenSim.Region.Framework.Scenes
1789 return part; 1766 return part;
1790 } 1767 }
1791 1768
1792 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) 1769 /// <summary>
1770 /// Do a physics property update for a NINJA joint.
1771 /// </summary>
1772 /// <param name="UsePhysics"></param>
1773 /// <param name="isNew"></param>
1774 protected void DoPhysicsPropertyUpdateForNinjaJoint(bool UsePhysics, bool isNew)
1793 { 1775 {
1794 if (IsJoint()) 1776 if (UsePhysics)
1795 { 1777 {
1796 if (UsePhysics) 1778 // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene.
1797 { 1779 // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical.
1798 // by turning a joint proxy object physical, we cause creation of a joint in the ODE scene.
1799 // note that, as a special case, joints have no bodies or geoms in the physics scene, even though they are physical.
1800 1780
1801 PhysicsJointType jointType; 1781 PhysicsJointType jointType;
1802 if (IsHingeJoint()) 1782 if (IsHingeJoint())
1803 { 1783 {
1804 jointType = PhysicsJointType.Hinge; 1784 jointType = PhysicsJointType.Hinge;
1805 } 1785 }
1806 else if (IsBallJoint()) 1786 else if (IsBallJoint())
1807 { 1787 {
1808 jointType = PhysicsJointType.Ball; 1788 jointType = PhysicsJointType.Ball;
1809 } 1789 }
1810 else 1790 else
1811 { 1791 {
1812 jointType = PhysicsJointType.Ball; 1792 jointType = PhysicsJointType.Ball;
1813 } 1793 }
1814 1794
1815 List<string> bodyNames = new List<string>(); 1795 List<string> bodyNames = new List<string>();
1816 string RawParams = Description; 1796 string RawParams = Description;
1817 string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); 1797 string[] jointParams = RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries);
1818 string trackedBodyName = null; 1798 string trackedBodyName = null;
1819 if (jointParams.Length >= 2) 1799 if (jointParams.Length >= 2)
1800 {
1801 for (int iBodyName = 0; iBodyName < 2; iBodyName++)
1820 { 1802 {
1821 for (int iBodyName = 0; iBodyName < 2; iBodyName++) 1803 string bodyName = jointParams[iBodyName];
1804 bodyNames.Add(bodyName);
1805 if (bodyName != "NULL")
1822 { 1806 {
1823 string bodyName = jointParams[iBodyName]; 1807 if (trackedBodyName == null)
1824 bodyNames.Add(bodyName);
1825 if (bodyName != "NULL")
1826 { 1808 {
1827 if (trackedBodyName == null) 1809 trackedBodyName = bodyName;
1828 {
1829 trackedBodyName = bodyName;
1830 }
1831 } 1810 }
1832 } 1811 }
1833 } 1812 }
1813 }
1834 1814
1835 SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup 1815 SceneObjectPart trackedBody = m_parentGroup.Scene.GetSceneObjectPart(trackedBodyName); // FIXME: causes a sequential lookup
1836 Quaternion localRotation = Quaternion.Identity; 1816 Quaternion localRotation = Quaternion.Identity;
1837 if (trackedBody != null) 1817 if (trackedBody != null)
1838 { 1818 {
1839 localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset; 1819 localRotation = Quaternion.Inverse(trackedBody.RotationOffset) * this.RotationOffset;
1840 } 1820 }
1841 else 1821 else
1842 { 1822 {
1843 // error, output it below 1823 // error, output it below
1844 } 1824 }
1845
1846 PhysicsJoint joint;
1847 1825
1848 joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType, 1826 PhysicsJoint joint;
1849 AbsolutePosition,
1850 this.RotationOffset,
1851 Description,
1852 bodyNames,
1853 trackedBodyName,
1854 localRotation);
1855 1827
1856 if (trackedBody == null) 1828 joint = m_parentGroup.Scene.PhysicsScene.RequestJointCreation(Name, jointType,
1857 { 1829 AbsolutePosition,
1858 ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name); 1830 this.RotationOffset,
1859 } 1831 Description,
1832 bodyNames,
1833 trackedBodyName,
1834 localRotation);
1860 1835
1836 if (trackedBody == null)
1837 {
1838 ParentGroup.Scene.jointErrorMessage(joint, "warning: tracked body name not found! joint location will not be updated properly. joint: " + Name);
1839 }
1840 }
1841 else
1842 {
1843 if (isNew)
1844 {
1845 // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to
1846 // delete, and if we try to delete it, due to asynchronous processing, the deletion request
1847 // will get processed later at an indeterminate time, which could cancel a later-arriving
1848 // joint creation request.
1861 } 1849 }
1862 else 1850 else
1863 { 1851 {
1864 if (isNew) 1852 // here we turn off the joint object, so remove the joint from the physics scene
1865 { 1853 m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed?
1866 // if the joint proxy is new, and it is not physical, do nothing. There is no joint in ODE to
1867 // delete, and if we try to delete it, due to asynchronous processing, the deletion request
1868 // will get processed later at an indeterminate time, which could cancel a later-arriving
1869 // joint creation request.
1870 }
1871 else
1872 {
1873 // here we turn off the joint object, so remove the joint from the physics scene
1874 m_parentGroup.Scene.PhysicsScene.RequestJointDeletion(Name); // FIXME: what if the name changed?
1875 1854
1876 // make sure client isn't interpolating the joint proxy object 1855 // make sure client isn't interpolating the joint proxy object
1877 Velocity = Vector3.Zero; 1856 Velocity = Vector3.Zero;
1878 AngularVelocity = Vector3.Zero; 1857 AngularVelocity = Vector3.Zero;
1879 Acceleration = Vector3.Zero; 1858 Acceleration = Vector3.Zero;
1880 }
1881 } 1859 }
1882 } 1860 }
1861 }
1862
1863 /// <summary>
1864 /// Do a physics propery update for this part.
1865 /// </summary>
1866 /// <param name="UsePhysics"></param>
1867 /// <param name="isNew"></param>
1868 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
1869 {
1870 if (IsJoint())
1871 {
1872 DoPhysicsPropertyUpdateForNinjaJoint(UsePhysics, isNew);
1873 }
1883 else 1874 else
1884 { 1875 {
1885 if (PhysActor != null) 1876 if (PhysActor != null)
@@ -1919,7 +1910,6 @@ namespace OpenSim.Region.Framework.Scenes
1919 1910
1920 PhysActor.IsPhysical = UsePhysics; 1911 PhysActor.IsPhysical = UsePhysics;
1921 1912
1922
1923 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 1913 // If we're not what we're supposed to be in the physics scene, recreate ourselves.
1924 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 1914 //m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
1925 /// that's not wholesome. Had to make Scene public 1915 /// that's not wholesome. Had to make Scene public
@@ -1943,7 +1933,13 @@ namespace OpenSim.Region.Framework.Scenes
1943 } 1933 }
1944 } 1934 }
1945 } 1935 }
1946 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 1936
1937 // If this part is a sculpt then delay the physics update until we've asynchronously loaded the
1938 // mesh data.
1939 if (Shape.SculptEntry)
1940 CheckSculptAndLoad();
1941 else
1942 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
1947 } 1943 }
1948 } 1944 }
1949 } 1945 }
@@ -1955,22 +1951,11 @@ namespace OpenSim.Region.Framework.Scenes
1955 /// <returns></returns> 1951 /// <returns></returns>
1956 public static SceneObjectPart FromXml(XmlTextReader xmlReader) 1952 public static SceneObjectPart FromXml(XmlTextReader xmlReader)
1957 { 1953 {
1958 return FromXml(UUID.Zero, xmlReader);
1959 }
1960
1961 /// <summary>
1962 /// Restore this part from the serialized xml representation.
1963 /// </summary>
1964 /// <param name="fromUserInventoryItemId">The inventory id from which this part came, if applicable</param>
1965 /// <param name="xmlReader"></param>
1966 /// <returns></returns>
1967 public static SceneObjectPart FromXml(UUID fromUserInventoryItemId, XmlTextReader xmlReader)
1968 {
1969 SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader); 1954 SceneObjectPart part = SceneObjectSerializer.Xml2ToSOP(xmlReader);
1970 part.m_fromUserInventoryItemID = fromUserInventoryItemId;
1971 1955
1972 // for tempOnRez objects, we have to fix the Expire date. 1956 // for tempOnRez objects, we have to fix the Expire date.
1973 if ((part.Flags & PrimFlags.TemporaryOnRez) != 0) part.ResetExpire(); 1957 if ((part.Flags & PrimFlags.TemporaryOnRez) != 0)
1958 part.ResetExpire();
1974 1959
1975 return part; 1960 return part;
1976 } 1961 }
@@ -1982,8 +1967,6 @@ namespace OpenSim.Region.Framework.Scenes
1982 1967
1983 public bool GetDieAtEdge() 1968 public bool GetDieAtEdge()
1984 { 1969 {
1985 if (m_parentGroup == null)
1986 return false;
1987 if (m_parentGroup.IsDeleted) 1970 if (m_parentGroup.IsDeleted)
1988 return false; 1971 return false;
1989 1972
@@ -1992,8 +1975,6 @@ namespace OpenSim.Region.Framework.Scenes
1992 1975
1993 public bool GetReturnAtEdge() 1976 public bool GetReturnAtEdge()
1994 { 1977 {
1995 if (m_parentGroup == null)
1996 return false;
1997 if (m_parentGroup.IsDeleted) 1978 if (m_parentGroup.IsDeleted)
1998 return false; 1979 return false;
1999 1980
@@ -2002,8 +1983,6 @@ namespace OpenSim.Region.Framework.Scenes
2002 1983
2003 public void SetReturnAtEdge(bool p) 1984 public void SetReturnAtEdge(bool p)
2004 { 1985 {
2005 if (m_parentGroup == null)
2006 return;
2007 if (m_parentGroup.IsDeleted) 1986 if (m_parentGroup.IsDeleted)
2008 return; 1987 return;
2009 1988
@@ -2012,8 +1991,6 @@ namespace OpenSim.Region.Framework.Scenes
2012 1991
2013 public bool GetBlockGrab() 1992 public bool GetBlockGrab()
2014 { 1993 {
2015 if (m_parentGroup == null)
2016 return false;
2017 if (m_parentGroup.IsDeleted) 1994 if (m_parentGroup.IsDeleted)
2018 return false; 1995 return false;
2019 1996
@@ -2022,8 +1999,6 @@ namespace OpenSim.Region.Framework.Scenes
2022 1999
2023 public void SetBlockGrab(bool p) 2000 public void SetBlockGrab(bool p)
2024 { 2001 {
2025 if (m_parentGroup == null)
2026 return;
2027 if (m_parentGroup.IsDeleted) 2002 if (m_parentGroup.IsDeleted)
2028 return; 2003 return;
2029 2004
@@ -2032,8 +2007,6 @@ namespace OpenSim.Region.Framework.Scenes
2032 2007
2033 public void SetStatusSandbox(bool p) 2008 public void SetStatusSandbox(bool p)
2034 { 2009 {
2035 if (m_parentGroup == null)
2036 return;
2037 if (m_parentGroup.IsDeleted) 2010 if (m_parentGroup.IsDeleted)
2038 return; 2011 return;
2039 StatusSandboxPos = m_parentGroup.RootPart.AbsolutePosition; 2012 StatusSandboxPos = m_parentGroup.RootPart.AbsolutePosition;
@@ -2042,8 +2015,6 @@ namespace OpenSim.Region.Framework.Scenes
2042 2015
2043 public bool GetStatusSandbox() 2016 public bool GetStatusSandbox()
2044 { 2017 {
2045 if (m_parentGroup == null)
2046 return false;
2047 if (m_parentGroup.IsDeleted) 2018 if (m_parentGroup.IsDeleted)
2048 return false; 2019 return false;
2049 2020
@@ -2085,25 +2056,17 @@ namespace OpenSim.Region.Framework.Scenes
2085 public Vector3 GetGeometricCenter() 2056 public Vector3 GetGeometricCenter()
2086 { 2057 {
2087 if (PhysActor != null) 2058 if (PhysActor != null)
2088 {
2089 return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); 2059 return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z);
2090 }
2091 else 2060 else
2092 {
2093 return new Vector3(0, 0, 0); 2061 return new Vector3(0, 0, 0);
2094 }
2095 } 2062 }
2096 2063
2097 public float GetMass() 2064 public float GetMass()
2098 { 2065 {
2099 if (PhysActor != null) 2066 if (PhysActor != null)
2100 {
2101 return PhysActor.Mass; 2067 return PhysActor.Mass;
2102 }
2103 else 2068 else
2104 {
2105 return 0; 2069 return 0;
2106 }
2107 } 2070 }
2108 2071
2109 public Vector3 GetForce() 2072 public Vector3 GetForce()
@@ -2119,19 +2082,12 @@ namespace OpenSim.Region.Framework.Scenes
2119 client.SendObjectPropertiesReply(this); 2082 client.SendObjectPropertiesReply(this);
2120 } 2083 }
2121 2084
2122 public UUID GetRootPartUUID()
2123 {
2124 if (m_parentGroup != null)
2125 {
2126 return m_parentGroup.UUID;
2127 }
2128 return UUID.Zero;
2129 }
2130
2131 /// <summary> 2085 /// <summary>
2132 /// Method for a prim to get it's world position from the group. 2086 /// Method for a prim to get it's world position from the group.
2133 /// Remember, the Group Position simply gives the position of the group itself
2134 /// </summary> 2087 /// </summary>
2088 /// <remarks>
2089 /// Remember, the Group Position simply gives the position of the group itself
2090 /// </remarks>
2135 /// <returns>A Linked Child Prim objects position in world</returns> 2091 /// <returns>A Linked Child Prim objects position in world</returns>
2136 public Vector3 GetWorldPosition() 2092 public Vector3 GetWorldPosition()
2137 { 2093 {
@@ -2249,8 +2205,6 @@ namespace OpenSim.Region.Framework.Scenes
2249 m_lastColliders.Remove(localID); 2205 m_lastColliders.Remove(localID);
2250 } 2206 }
2251 2207
2252 if (m_parentGroup == null)
2253 return;
2254 if (m_parentGroup.IsDeleted) 2208 if (m_parentGroup.IsDeleted)
2255 return; 2209 return;
2256 2210
@@ -2271,9 +2225,6 @@ namespace OpenSim.Region.Framework.Scenes
2271 { 2225 {
2272 if (localId == 0) 2226 if (localId == 0)
2273 continue; 2227 continue;
2274 // always running this check because if the user deletes the object it would return a null reference.
2275 if (m_parentGroup == null)
2276 return;
2277 2228
2278 if (m_parentGroup.Scene == null) 2229 if (m_parentGroup.Scene == null)
2279 return; 2230 return;
@@ -2282,7 +2233,8 @@ namespace OpenSim.Region.Framework.Scenes
2282 string data = ""; 2233 string data = "";
2283 if (obj != null) 2234 if (obj != null)
2284 { 2235 {
2285 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) 2236 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
2237 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2286 { 2238 {
2287 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); 2239 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2288 //If it is 1, it is to accept ONLY collisions from this object 2240 //If it is 1, it is to accept ONLY collisions from this object
@@ -2329,7 +2281,8 @@ namespace OpenSim.Region.Framework.Scenes
2329 { 2281 {
2330 if (av.LocalId == localId) 2282 if (av.LocalId == localId)
2331 { 2283 {
2332 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) 2284 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2285 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2333 { 2286 {
2334 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2287 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2335 //If it is 1, it is to accept ONLY collisions from this avatar 2288 //If it is 1, it is to accept ONLY collisions from this avatar
@@ -2377,12 +2330,10 @@ namespace OpenSim.Region.Framework.Scenes
2377 if (colliding.Count > 0) 2330 if (colliding.Count > 0)
2378 { 2331 {
2379 StartCollidingMessage.Colliders = colliding; 2332 StartCollidingMessage.Colliders = colliding;
2380 // always running this check because if the user deletes the object it would return a null reference.
2381 if (m_parentGroup == null)
2382 return;
2383 2333
2384 if (m_parentGroup.Scene == null) 2334 if (m_parentGroup.Scene == null)
2385 return; 2335 return;
2336
2386 if (m_parentGroup.PassCollision == true) 2337 if (m_parentGroup.PassCollision == true)
2387 { 2338 {
2388 //TODO: Add pass to root prim! 2339 //TODO: Add pass to root prim!
@@ -2403,9 +2354,6 @@ namespace OpenSim.Region.Framework.Scenes
2403 // always running this check because if the user deletes the object it would return a null reference. 2354 // always running this check because if the user deletes the object it would return a null reference.
2404 if (localId == 0) 2355 if (localId == 0)
2405 continue; 2356 continue;
2406
2407 if (m_parentGroup == null)
2408 return;
2409 2357
2410 if (m_parentGroup.Scene == null) 2358 if (m_parentGroup.Scene == null)
2411 return; 2359 return;
@@ -2414,7 +2362,8 @@ namespace OpenSim.Region.Framework.Scenes
2414 string data = ""; 2362 string data = "";
2415 if (obj != null) 2363 if (obj != null)
2416 { 2364 {
2417 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) 2365 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
2366 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
2418 { 2367 {
2419 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); 2368 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
2420 //If it is 1, it is to accept ONLY collisions from this object 2369 //If it is 1, it is to accept ONLY collisions from this object
@@ -2461,7 +2410,8 @@ namespace OpenSim.Region.Framework.Scenes
2461 { 2410 {
2462 if (av.LocalId == localId) 2411 if (av.LocalId == localId)
2463 { 2412 {
2464 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) 2413 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2414 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2465 { 2415 {
2466 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2416 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2467 //If it is 1, it is to accept ONLY collisions from this avatar 2417 //If it is 1, it is to accept ONLY collisions from this avatar
@@ -2509,9 +2459,6 @@ namespace OpenSim.Region.Framework.Scenes
2509 if (colliding.Count > 0) 2459 if (colliding.Count > 0)
2510 { 2460 {
2511 CollidingMessage.Colliders = colliding; 2461 CollidingMessage.Colliders = colliding;
2512 // always running this check because if the user deletes the object it would return a null reference.
2513 if (m_parentGroup == null)
2514 return;
2515 2462
2516 if (m_parentGroup.Scene == null) 2463 if (m_parentGroup.Scene == null)
2517 return; 2464 return;
@@ -2532,11 +2479,9 @@ namespace OpenSim.Region.Framework.Scenes
2532 if (localId == 0) 2479 if (localId == 0)
2533 continue; 2480 continue;
2534 2481
2535 // always running this check because if the user deletes the object it would return a null reference.
2536 if (m_parentGroup == null)
2537 return;
2538 if (m_parentGroup.Scene == null) 2482 if (m_parentGroup.Scene == null)
2539 return; 2483 return;
2484
2540 SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId); 2485 SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId);
2541 string data = ""; 2486 string data = "";
2542 if (obj != null) 2487 if (obj != null)
@@ -2588,7 +2533,8 @@ namespace OpenSim.Region.Framework.Scenes
2588 { 2533 {
2589 if (av.LocalId == localId) 2534 if (av.LocalId == localId)
2590 { 2535 {
2591 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) 2536 if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
2537 || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
2592 { 2538 {
2593 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); 2539 bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
2594 //If it is 1, it is to accept ONLY collisions from this avatar 2540 //If it is 1, it is to accept ONLY collisions from this avatar
@@ -2637,9 +2583,6 @@ namespace OpenSim.Region.Framework.Scenes
2637 if (colliding.Count > 0) 2583 if (colliding.Count > 0)
2638 { 2584 {
2639 EndCollidingMessage.Colliders = colliding; 2585 EndCollidingMessage.Colliders = colliding;
2640 // always running this check because if the user deletes the object it would return a null reference.
2641 if (m_parentGroup == null)
2642 return;
2643 2586
2644 if (m_parentGroup.Scene == null) 2587 if (m_parentGroup.Scene == null)
2645 return; 2588 return;
@@ -2648,6 +2591,7 @@ namespace OpenSim.Region.Framework.Scenes
2648 } 2591 }
2649 } 2592 }
2650 } 2593 }
2594
2651 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) 2595 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0)
2652 { 2596 {
2653 if (startedColliders.Count > 0) 2597 if (startedColliders.Count > 0)
@@ -2675,9 +2619,6 @@ namespace OpenSim.Region.Framework.Scenes
2675 if (colliding.Count > 0) 2619 if (colliding.Count > 0)
2676 { 2620 {
2677 LandStartCollidingMessage.Colliders = colliding; 2621 LandStartCollidingMessage.Colliders = colliding;
2678 // always running this check because if the user deletes the object it would return a null reference.
2679 if (m_parentGroup == null)
2680 return;
2681 2622
2682 if (m_parentGroup.Scene == null) 2623 if (m_parentGroup.Scene == null)
2683 return; 2624 return;
@@ -2686,6 +2627,7 @@ namespace OpenSim.Region.Framework.Scenes
2686 } 2627 }
2687 } 2628 }
2688 } 2629 }
2630
2689 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0) 2631 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0)
2690 { 2632 {
2691 if (m_lastColliders.Count > 0) 2633 if (m_lastColliders.Count > 0)
@@ -2713,9 +2655,6 @@ namespace OpenSim.Region.Framework.Scenes
2713 if (colliding.Count > 0) 2655 if (colliding.Count > 0)
2714 { 2656 {
2715 LandCollidingMessage.Colliders = colliding; 2657 LandCollidingMessage.Colliders = colliding;
2716 // always running this check because if the user deletes the object it would return a null reference.
2717 if (m_parentGroup == null)
2718 return;
2719 2658
2720 if (m_parentGroup.Scene == null) 2659 if (m_parentGroup.Scene == null)
2721 return; 2660 return;
@@ -2724,6 +2663,7 @@ namespace OpenSim.Region.Framework.Scenes
2724 } 2663 }
2725 } 2664 }
2726 } 2665 }
2666
2727 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) 2667 if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0)
2728 { 2668 {
2729 if (endedColliders.Count > 0) 2669 if (endedColliders.Count > 0)
@@ -2751,9 +2691,6 @@ namespace OpenSim.Region.Framework.Scenes
2751 if (colliding.Count > 0) 2691 if (colliding.Count > 0)
2752 { 2692 {
2753 LandEndCollidingMessage.Colliders = colliding; 2693 LandEndCollidingMessage.Colliders = colliding;
2754 // always running this check because if the user deletes the object it would return a null reference.
2755 if (m_parentGroup == null)
2756 return;
2757 2694
2758 if (m_parentGroup.Scene == null) 2695 if (m_parentGroup.Scene == null)
2759 return; 2696 return;
@@ -2777,10 +2714,12 @@ namespace OpenSim.Region.Framework.Scenes
2777 { 2714 {
2778 if (PhysActor != null) 2715 if (PhysActor != null)
2779 { 2716 {
2780
2781 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); 2717 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
2782 2718
2783 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2719 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2720 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2721 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2722 | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2784 { 2723 {
2785 m_parentGroup.AbsolutePosition = newpos; 2724 m_parentGroup.AbsolutePosition = newpos;
2786 return; 2725 return;
@@ -2869,13 +2808,29 @@ namespace OpenSim.Region.Framework.Scenes
2869 } 2808 }
2870 2809
2871 /// <summary> 2810 /// <summary>
2872 /// Resize this part. 2811 /// Set the scale of this part.
2873 /// </summary> 2812 /// </summary>
2813 /// <remarks>
2814 /// Unlike the scale property, this checks the new size against scene limits and schedules a full property
2815 /// update to viewers.
2816 /// </remarks>
2874 /// <param name="scale"></param> 2817 /// <param name="scale"></param>
2875 public void Resize(Vector3 scale) 2818 public void Resize(Vector3 scale)
2876 { 2819 {
2877 StoreUndoState(UndoType.STATE_PRIM_SCALE); 2820 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys);
2878 m_shape.Scale = scale; 2821 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys);
2822 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys);
2823
2824 if (PhysActor != null && PhysActor.IsPhysical)
2825 {
2826 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys);
2827 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys);
2828 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys);
2829 }
2830
2831// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
2832
2833 Scale = scale;
2879 2834
2880 ParentGroup.HasGroupChanged = true; 2835 ParentGroup.HasGroupChanged = true;
2881 ScheduleFullUpdate(); 2836 ScheduleFullUpdate();
@@ -2886,20 +2841,48 @@ namespace OpenSim.Region.Framework.Scenes
2886 m_parentGroup.rotLookAt(target, strength, damping); // This calls method in SceneObjectGroup. 2841 m_parentGroup.rotLookAt(target, strength, damping); // This calls method in SceneObjectGroup.
2887 } 2842 }
2888 2843
2844 public void rotLookAt(Quaternion target, float strength, float damping)
2845 {
2846 if (m_parentGroup.IsAttachment)
2847 {
2848 /*
2849 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
2850 if (avatar != null)
2851 {
2852 Rotate the Av?
2853 } */
2854 }
2855 else
2856 {
2857 APIDDamp = damping;
2858 APIDStrength = strength;
2859 APIDTarget = target;
2860 }
2861 }
2862
2863 public void startLookAt(Quaternion rot, float damp, float strength)
2864 {
2865 APIDDamp = damp;
2866 APIDStrength = strength;
2867 APIDTarget = rot;
2868 }
2869
2870 public void stopLookAt()
2871 {
2872 APIDTarget = Quaternion.Identity;
2873 }
2874
2889 /// <summary> 2875 /// <summary>
2890 /// Schedules this prim for a full update 2876 /// Schedules this prim for a full update
2891 /// </summary> 2877 /// </summary>
2892 public void ScheduleFullUpdate() 2878 public void ScheduleFullUpdate()
2893 { 2879 {
2894// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); 2880// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId);
2895 2881
2896 if (m_parentGroup != null) 2882 if (m_parentGroup == null)
2897 { 2883 return;
2898 if (!m_parentGroup.areUpdatesSuspended) 2884
2899 { 2885 m_parentGroup.QueueForUpdateCheck();
2900 m_parentGroup.QueueForUpdateCheck();
2901 }
2902 }
2903 2886
2904 int timeNow = Util.UnixTimeSinceEpoch(); 2887 int timeNow = Util.UnixTimeSinceEpoch();
2905 2888
@@ -2928,13 +2911,14 @@ namespace OpenSim.Region.Framework.Scenes
2928 /// </summary> 2911 /// </summary>
2929 public void ScheduleTerseUpdate() 2912 public void ScheduleTerseUpdate()
2930 { 2913 {
2914 if (m_parentGroup == null)
2915 return;
2916
2931 if (m_updateFlag < 1) 2917 if (m_updateFlag < 1)
2932 { 2918 {
2933 if (m_parentGroup != null) 2919 m_parentGroup.HasGroupChanged = true;
2934 { 2920 m_parentGroup.QueueForUpdateCheck();
2935 m_parentGroup.HasGroupChanged = true; 2921
2936 m_parentGroup.QueueForUpdateCheck();
2937 }
2938 TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); 2922 TimeStampTerse = (uint) Util.UnixTimeSinceEpoch();
2939 m_updateFlag = 1; 2923 m_updateFlag = 1;
2940 2924
@@ -2944,40 +2928,16 @@ namespace OpenSim.Region.Framework.Scenes
2944 } 2928 }
2945 } 2929 }
2946 2930
2947 public void ScriptSetPhantomStatus(bool Phantom)
2948 {
2949 if (m_parentGroup != null)
2950 {
2951 m_parentGroup.ScriptSetPhantomStatus(Phantom);
2952 }
2953 }
2954
2955 public void ScriptSetTemporaryStatus(bool Temporary)
2956 {
2957 if (m_parentGroup != null)
2958 {
2959 m_parentGroup.ScriptSetTemporaryStatus(Temporary);
2960 }
2961 }
2962
2963 public void ScriptSetPhysicsStatus(bool UsePhysics) 2931 public void ScriptSetPhysicsStatus(bool UsePhysics)
2964 { 2932 {
2965 if (m_parentGroup == null) 2933 m_parentGroup.ScriptSetPhysicsStatus(UsePhysics);
2966 DoPhysicsPropertyUpdate(UsePhysics, false);
2967 else
2968 m_parentGroup.ScriptSetPhysicsStatus(UsePhysics);
2969 }
2970
2971 public void ScriptSetVolumeDetect(bool SetVD)
2972 {
2973
2974 if (m_parentGroup != null)
2975 {
2976 m_parentGroup.ScriptSetVolumeDetect(SetVD);
2977 }
2978 } 2934 }
2979 2935
2980 public void SculptTextureCallback(UUID textureID, AssetBase texture) 2936 /// <summary>
2937 /// Set sculpt and mesh data, and tell the physics engine to process the change.
2938 /// </summary>
2939 /// <param name="texture">The mesh itself.</param>
2940 public void SculptTextureCallback(AssetBase texture)
2981 { 2941 {
2982 if (m_shape.SculptEntry) 2942 if (m_shape.SculptEntry)
2983 { 2943 {
@@ -2985,14 +2945,17 @@ namespace OpenSim.Region.Framework.Scenes
2985 //if (texture != null) 2945 //if (texture != null)
2986 { 2946 {
2987 if (texture != null) 2947 if (texture != null)
2948 {
2949// m_log.DebugFormat(
2950// "[SCENE OBJECT PART]: Setting sculpt data for {0} on SculptTextureCallback()", Name);
2951
2988 m_shape.SculptData = texture.Data; 2952 m_shape.SculptData = texture.Data;
2953 }
2989 2954
2990 if (PhysActor != null) 2955 if (PhysActor != null)
2991 { 2956 {
2992 // Tricks physics engine into thinking we've changed the part shape. 2957 // Update the physics actor with the new loaded sculpt data and set the taint signal.
2993 PrimitiveBaseShape m_newshape = m_shape.Copy(); 2958 PhysActor.Shape = m_shape;
2994 PhysActor.Shape = m_newshape;
2995 m_shape = m_newshape;
2996 2959
2997 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 2960 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
2998 } 2961 }
@@ -3000,16 +2963,6 @@ namespace OpenSim.Region.Framework.Scenes
3000 } 2963 }
3001 } 2964 }
3002 2965
3003// /// <summary>
3004// ///
3005// /// </summary>
3006// /// <param name="remoteClient"></param>
3007// public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags)
3008// {
3009// m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags);
3010// }
3011
3012
3013 /// <summary> 2966 /// <summary>
3014 /// Send a full update to the client for the given part 2967 /// Send a full update to the client for the given part
3015 /// </summary> 2968 /// </summary>
@@ -3017,12 +2970,15 @@ namespace OpenSim.Region.Framework.Scenes
3017 /// <param name="clientFlags"></param> 2970 /// <param name="clientFlags"></param>
3018 protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) 2971 protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags)
3019 { 2972 {
2973 if (m_parentGroup == null)
2974 return;
2975
3020// m_log.DebugFormat( 2976// m_log.DebugFormat(
3021// "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); 2977// "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId);
3022 2978
3023 if (IsRoot) 2979 if (IsRoot)
3024 { 2980 {
3025 if (IsAttachment) 2981 if (m_parentGroup.IsAttachment)
3026 { 2982 {
3027 SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags); 2983 SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags);
3028 } 2984 }
@@ -3042,6 +2998,9 @@ namespace OpenSim.Region.Framework.Scenes
3042 /// </summary> 2998 /// </summary>
3043 public void SendFullUpdateToAllClients() 2999 public void SendFullUpdateToAllClients()
3044 { 3000 {
3001 if (m_parentGroup == null)
3002 return;
3003
3045 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3004 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3046 { 3005 {
3047 SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID)); 3006 SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID));
@@ -3054,6 +3013,9 @@ namespace OpenSim.Region.Framework.Scenes
3054 /// <param name="agentID"></param> 3013 /// <param name="agentID"></param>
3055 public void SendFullUpdateToAllClientsExcept(UUID agentID) 3014 public void SendFullUpdateToAllClientsExcept(UUID agentID)
3056 { 3015 {
3016 if (m_parentGroup == null)
3017 return;
3018
3057 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3019 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3058 { 3020 {
3059 // Ugly reference :( 3021 // Ugly reference :(
@@ -3082,9 +3044,12 @@ namespace OpenSim.Region.Framework.Scenes
3082 /// <param name="clientFlags"></param> 3044 /// <param name="clientFlags"></param>
3083 public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos, uint clientFlags) 3045 public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos, uint clientFlags)
3084 { 3046 {
3047 if (ParentGroup == null)
3048 return;
3049
3085 // Suppress full updates during attachment editing 3050 // Suppress full updates during attachment editing
3086 // 3051 //
3087 if (ParentGroup.IsSelected && IsAttachment) 3052 if (ParentGroup.IsSelected && ParentGroup.IsAttachment)
3088 return; 3053 return;
3089 3054
3090 if (ParentGroup.IsDeleted) 3055 if (ParentGroup.IsDeleted)
@@ -3177,7 +3142,7 @@ namespace OpenSim.Region.Framework.Scenes
3177 3142
3178 UUID ownerID = _ownerID; 3143 UUID ownerID = _ownerID;
3179 UUID objectID = ParentGroup.RootPart.UUID; 3144 UUID objectID = ParentGroup.RootPart.UUID;
3180 UUID parentID = GetRootPartUUID(); 3145 UUID parentID = ParentGroup.UUID;
3181 3146
3182 UUID soundID = UUID.Zero; 3147 UUID soundID = UUID.Zero;
3183 Vector3 position = AbsolutePosition; // region local 3148 Vector3 position = AbsolutePosition; // region local
@@ -3215,7 +3180,7 @@ namespace OpenSim.Region.Framework.Scenes
3215 ParentGroup.PlaySoundMasterPrim = this; 3180 ParentGroup.PlaySoundMasterPrim = this;
3216 ownerID = _ownerID; 3181 ownerID = _ownerID;
3217 objectID = ParentGroup.RootPart.UUID; 3182 objectID = ParentGroup.RootPart.UUID;
3218 parentID = GetRootPartUUID(); 3183 parentID = ParentGroup.UUID;
3219 position = AbsolutePosition; // region local 3184 position = AbsolutePosition; // region local
3220 regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle; 3185 regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle;
3221 if (triggered) 3186 if (triggered)
@@ -3226,7 +3191,7 @@ namespace OpenSim.Region.Framework.Scenes
3226 { 3191 {
3227 ownerID = prim._ownerID; 3192 ownerID = prim._ownerID;
3228 objectID = prim.ParentGroup.RootPart.UUID; 3193 objectID = prim.ParentGroup.RootPart.UUID;
3229 parentID = prim.GetRootPartUUID(); 3194 parentID = prim.ParentGroup.UUID;
3230 position = prim.AbsolutePosition; // region local 3195 position = prim.AbsolutePosition; // region local
3231 regionHandle = prim.ParentGroup.Scene.RegionInfo.RegionHandle; 3196 regionHandle = prim.ParentGroup.Scene.RegionInfo.RegionHandle;
3232 if (triggered) 3197 if (triggered)
@@ -3263,45 +3228,31 @@ namespace OpenSim.Region.Framework.Scenes
3263 }); 3228 });
3264 } 3229 }
3265 3230
3266 public void SetAttachmentPoint(uint AttachmentPoint)
3267 {
3268 this.AttachmentPoint = AttachmentPoint;
3269
3270 if (AttachmentPoint != 0)
3271 {
3272 IsAttachment = true;
3273 }
3274 else
3275 {
3276 IsAttachment = false;
3277 }
3278
3279 // save the attachment point.
3280 //if (AttachmentPoint != 0)
3281 //{
3282 m_shape.State = (byte)AttachmentPoint;
3283 //}
3284 }
3285
3286 public void SetAxisRotation(int axis, int rotate) 3231 public void SetAxisRotation(int axis, int rotate)
3287 { 3232 {
3288 if (m_parentGroup != null) 3233 m_parentGroup.SetAxisRotation(axis, rotate);
3289 { 3234
3290 m_parentGroup.SetAxisRotation(axis, rotate);
3291 }
3292 //Cannot use ScriptBaseClass constants as no referance to it currently. 3235 //Cannot use ScriptBaseClass constants as no referance to it currently.
3293 if (axis == 2)//STATUS_ROTATE_X 3236 if (axis == 2)//STATUS_ROTATE_X
3294 STATUS_ROTATE_X = rotate; 3237 STATUS_ROTATE_X = rotate;
3238
3295 if (axis == 4)//STATUS_ROTATE_Y 3239 if (axis == 4)//STATUS_ROTATE_Y
3296 STATUS_ROTATE_Y = rotate; 3240 STATUS_ROTATE_Y = rotate;
3241
3297 if (axis == 8)//STATUS_ROTATE_Z 3242 if (axis == 8)//STATUS_ROTATE_Z
3298 STATUS_ROTATE_Z = rotate; 3243 STATUS_ROTATE_Z = rotate;
3299 } 3244 }
3300 3245
3246 public void SetBuoyancy(float fvalue)
3247 {
3248 if (PhysActor != null)
3249 {
3250 PhysActor.Buoyancy = fvalue;
3251 }
3252 }
3253
3301 public void SetDieAtEdge(bool p) 3254 public void SetDieAtEdge(bool p)
3302 { 3255 {
3303 if (m_parentGroup == null)
3304 return;
3305 if (m_parentGroup.IsDeleted) 3256 if (m_parentGroup.IsDeleted)
3306 return; 3257 return;
3307 3258
@@ -3554,7 +3505,7 @@ namespace OpenSim.Region.Framework.Scenes
3554 } 3505 }
3555 3506
3556 /// <summary> 3507 /// <summary>
3557 /// 3508 /// Set the parent group of this prim.
3558 /// </summary> 3509 /// </summary>
3559 public void SetParent(SceneObjectGroup parent) 3510 public void SetParent(SceneObjectGroup parent)
3560 { 3511 {
@@ -3611,8 +3562,11 @@ namespace OpenSim.Region.Framework.Scenes
3611 { 3562 {
3612 Text = text; 3563 Text = text;
3613 3564
3614 ParentGroup.HasGroupChanged = true; 3565 if (ParentGroup != null)
3615 ScheduleFullUpdate(); 3566 {
3567 ParentGroup.HasGroupChanged = true;
3568 ScheduleFullUpdate();
3569 }
3616 } 3570 }
3617 3571
3618 public void StopLookAt() 3572 public void StopLookAt()
@@ -3644,44 +3598,156 @@ namespace OpenSim.Region.Framework.Scenes
3644 m_parentGroup.ScheduleGroupForTerseUpdate(); 3598 m_parentGroup.ScheduleGroupForTerseUpdate();
3645 //m_parentGroup.ScheduleGroupForFullUpdate(); 3599 //m_parentGroup.ScheduleGroupForFullUpdate();
3646 } 3600 }
3647 public void StoreUndoState(UndoType type) 3601
3602 public void StoreUndoState()
3603 {
3604 StoreUndoState(false);
3605 }
3606
3607 public void StoreUndoState(bool forGroup)
3648 { 3608 {
3649 if (!Undoing && (m_parentGroup == null || m_parentGroup.RootPart == null || !m_parentGroup.RootPart.Undoing)) 3609 if (!Undoing)
3650 { 3610 {
3651 if (!IgnoreUndoUpdate) 3611 if (!IgnoreUndoUpdate)
3652 { 3612 {
3653 if (m_parentGroup != null) 3613 if (ParentGroup != null)
3654 { 3614 {
3655 lock (m_undo) 3615 lock (m_undo)
3656 { 3616 {
3657 if (m_undo.Count > 0) 3617 if (m_undo.Count > 0)
3658 { 3618 {
3659 UndoState last = m_undo.Peek(); 3619 UndoState last = m_undo.Peek();
3660 3620 if (last != null)
3621 {
3622 // TODO: May need to fix for group comparison
3623 if (last.Compare(this))
3624 {
3625 // m_log.DebugFormat(
3626 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3627 // Name, LocalId, m_undo.Count);
3628
3629 return;
3630 }
3631 }
3661 } 3632 }
3662 3633
3634 // m_log.DebugFormat(
3635 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3636 // Name, LocalId, forGroup, m_undo.Count);
3637
3663 if (m_parentGroup.GetSceneMaxUndo() > 0) 3638 if (m_parentGroup.GetSceneMaxUndo() > 0)
3664 { 3639 {
3665 UndoState lastUndo = m_undo.Peek(); 3640 UndoState nUndo = new UndoState(this, forGroup);
3666
3667 UndoState nUndo = new UndoState(this, type);
3668 3641
3669 if (lastUndo != null)
3670 {
3671 TimeSpan ts = DateTime.Now.Subtract(lastUndo.LastUpdated);
3672 if (ts.TotalMilliseconds < 500)
3673 {
3674 //Delete the last entry since it was less than 500 milliseconds ago
3675 nUndo.Merge(lastUndo);
3676 m_undo.Pop();
3677 }
3678 }
3679 m_undo.Push(nUndo); 3642 m_undo.Push(nUndo);
3643
3644 if (m_redo.Count > 0)
3645 m_redo.Clear();
3646
3647 // m_log.DebugFormat(
3648 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3649 // Name, LocalId, forGroup, m_undo.Count);
3680 } 3650 }
3651 }
3652 }
3653 }
3654 // else
3655 // {
3656 // m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3657 // }
3658 }
3659 // else
3660 // {
3661 // m_log.DebugFormat(
3662 // "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3663 // }
3664 }
3681 3665
3666 /// <summary>
3667 /// Return number of undos on the stack. Here temporarily pending a refactor.
3668 /// </summary>
3669 public int UndoCount
3670 {
3671 get
3672 {
3673 lock (m_undo)
3674 return m_undo.Count;
3675 }
3676 }
3677
3678 public void Undo()
3679 {
3680 lock (m_undo)
3681 {
3682// m_log.DebugFormat(
3683// "[SCENE OBJECT PART]: Handling undo request for {0} {1}, stack size {2}",
3684// Name, LocalId, m_undo.Count);
3685
3686 if (m_undo.Count > 0)
3687 {
3688 UndoState goback = m_undo.Pop();
3689
3690 if (goback != null)
3691 {
3692 UndoState nUndo = null;
3693
3694 if (m_parentGroup.GetSceneMaxUndo() > 0)
3695 {
3696 nUndo = new UndoState(this, goback.ForGroup);
3682 } 3697 }
3698
3699 goback.PlaybackState(this);
3700
3701 if (nUndo != null)
3702 m_redo.Push(nUndo);
3683 } 3703 }
3684 } 3704 }
3705
3706// m_log.DebugFormat(
3707// "[SCENE OBJECT PART]: Handled undo request for {0} {1}, stack size now {2}",
3708// Name, LocalId, m_undo.Count);
3709 }
3710 }
3711
3712 public void Redo()
3713 {
3714 lock (m_undo)
3715 {
3716// m_log.DebugFormat(
3717// "[SCENE OBJECT PART]: Handling redo request for {0} {1}, stack size {2}",
3718// Name, LocalId, m_redo.Count);
3719
3720 if (m_redo.Count > 0)
3721 {
3722 UndoState gofwd = m_redo.Pop();
3723
3724 if (gofwd != null)
3725 {
3726 if (m_parentGroup.GetSceneMaxUndo() > 0)
3727 {
3728 UndoState nUndo = new UndoState(this, gofwd.ForGroup);
3729
3730 m_undo.Push(nUndo);
3731 }
3732
3733 gofwd.PlayfwdState(this);
3734 }
3735
3736// m_log.DebugFormat(
3737// "[SCENE OBJECT PART]: Handled redo request for {0} {1}, stack size now {2}",
3738// Name, LocalId, m_redo.Count);
3739 }
3740 }
3741 }
3742
3743 public void ClearUndoState()
3744 {
3745// m_log.DebugFormat("[SCENE OBJECT PART]: Clearing undo and redo stacks in {0} {1}", Name, LocalId);
3746
3747 lock (m_undo)
3748 {
3749 m_undo.Clear();
3750 m_redo.Clear();
3685 } 3751 }
3686 } 3752 }
3687 3753
@@ -4145,46 +4211,6 @@ namespace OpenSim.Region.Framework.Scenes
4145 _nextOwnerMask &= (uint)PermissionMask.All; 4211 _nextOwnerMask &= (uint)PermissionMask.All;
4146 } 4212 }
4147 4213
4148 public void Undo()
4149 {
4150 lock (m_undo)
4151 {
4152 if (m_undo.Count > 0)
4153 {
4154 UndoState nUndo = null;
4155 UndoState goback = m_undo.Pop();
4156 if (m_parentGroup.GetSceneMaxUndo() > 0)
4157 {
4158 nUndo = new UndoState(this, goback.Type);
4159 }
4160
4161
4162 if (goback != null)
4163 {
4164 goback.PlaybackState(this);
4165 if (nUndo != null)
4166 m_redo.Push(nUndo);
4167 }
4168 }
4169 }
4170 }
4171
4172 public void Redo()
4173 {
4174 lock (m_redo)
4175 {
4176 UndoState gofwd = m_redo.Pop();
4177 if (m_parentGroup.GetSceneMaxUndo() > 0)
4178 {
4179 UndoState nUndo = new UndoState(this, gofwd.Type);
4180
4181 m_undo.Push(nUndo);
4182 }
4183 if (gofwd != null)
4184 gofwd.PlayfwdState(this);
4185 }
4186 }
4187
4188 public void UpdateExtraParam(ushort type, bool inUse, byte[] data) 4214 public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
4189 { 4215 {
4190 m_shape.ReadInUpdateExtraParam(type, inUse, data); 4216 m_shape.ReadInUpdateExtraParam(type, inUse, data);
@@ -4197,8 +4223,11 @@ namespace OpenSim.Region.Framework.Scenes
4197 } 4223 }
4198 } 4224 }
4199 4225
4200 ParentGroup.HasGroupChanged = true; 4226 if (ParentGroup != null)
4201 ScheduleFullUpdate(); 4227 {
4228 ParentGroup.HasGroupChanged = true;
4229 ScheduleFullUpdate();
4230 }
4202 } 4231 }
4203 4232
4204 public void UpdateGroupPosition(Vector3 pos) 4233 public void UpdateGroupPosition(Vector3 pos)
@@ -4345,14 +4374,21 @@ namespace OpenSim.Region.Framework.Scenes
4345 } 4374 }
4346 } 4375 }
4347 4376
4348 public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD) 4377 /// <summary>
4378 /// Update the flags on this prim. This covers properties such as phantom, physics and temporary.
4379 /// </summary>
4380 /// <param name="UsePhysics"></param>
4381 /// <param name="SetTemporary"></param>
4382 /// <param name="SetPhantom"></param>
4383 /// <param name="SetVD"></param>
4384 public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
4349 { 4385 {
4350 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); 4386 bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
4351 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); 4387 bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
4352 bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0); 4388 bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0);
4353 bool wasVD = VolumeDetectActive; 4389 bool wasVD = VolumeDetectActive;
4354 4390
4355 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) && (IsVD==wasVD)) 4391 if ((UsePhysics == wasUsingPhysics) && (wasTemporary == SetTemporary) && (wasPhantom == SetPhantom) && (SetVD == wasVD))
4356 { 4392 {
4357 return; 4393 return;
4358 } 4394 }
@@ -4362,32 +4398,31 @@ namespace OpenSim.Region.Framework.Scenes
4362 // that... 4398 // that...
4363 // ... if VD is changed, all others are not. 4399 // ... if VD is changed, all others are not.
4364 // ... if one of the others is changed, VD is not. 4400 // ... if one of the others is changed, VD is not.
4365 if (IsVD) // VD is active, special logic applies 4401 if (SetVD) // VD is active, special logic applies
4366 { 4402 {
4367 // State machine logic for VolumeDetect 4403 // State machine logic for VolumeDetect
4368 // More logic below 4404 // More logic below
4369 bool phanReset = (IsPhantom != wasPhantom) && !IsPhantom; 4405 bool phanReset = (SetPhantom != wasPhantom) && !SetPhantom;
4370 4406
4371 if (phanReset) // Phantom changes from on to off switch VD off too 4407 if (phanReset) // Phantom changes from on to off switch VD off too
4372 { 4408 {
4373 IsVD = false; // Switch it of for the course of this routine 4409 SetVD = false; // Switch it of for the course of this routine
4374 VolumeDetectActive = false; // and also permanently 4410 VolumeDetectActive = false; // and also permanently
4375 if (PhysActor != null) 4411 if (PhysActor != null)
4376 PhysActor.SetVolumeDetect(0); // Let physics know about it too 4412 PhysActor.SetVolumeDetect(0); // Let physics know about it too
4377 } 4413 }
4378 else 4414 else
4379 { 4415 {
4380 IsPhantom = false;
4381 // If volumedetect is active we don't want phantom to be applied. 4416 // If volumedetect is active we don't want phantom to be applied.
4382 // If this is a new call to VD out of the state "phantom" 4417 // If this is a new call to VD out of the state "phantom"
4383 // this will also cause the prim to be visible to physics 4418 // this will also cause the prim to be visible to physics
4419 SetPhantom = false;
4384 } 4420 }
4385
4386 } 4421 }
4387 4422
4388 if (UsePhysics && IsJoint()) 4423 if (UsePhysics && IsJoint())
4389 { 4424 {
4390 IsPhantom = true; 4425 SetPhantom = true;
4391 } 4426 }
4392 4427
4393 if (UsePhysics) 4428 if (UsePhysics)
@@ -4396,14 +4431,12 @@ namespace OpenSim.Region.Framework.Scenes
4396 if (!wasUsingPhysics) 4431 if (!wasUsingPhysics)
4397 { 4432 {
4398 DoPhysicsPropertyUpdate(UsePhysics, false); 4433 DoPhysicsPropertyUpdate(UsePhysics, false);
4399 if (m_parentGroup != null) 4434
4435 if (!m_parentGroup.IsDeleted)
4400 { 4436 {
4401 if (!m_parentGroup.IsDeleted) 4437 if (LocalId == m_parentGroup.RootPart.LocalId)
4402 { 4438 {
4403 if (LocalId == m_parentGroup.RootPart.LocalId) 4439 m_parentGroup.CheckSculptAndLoad();
4404 {
4405 m_parentGroup.CheckSculptAndLoad();
4406 }
4407 } 4440 }
4408 } 4441 }
4409 } 4442 }
@@ -4417,8 +4450,9 @@ namespace OpenSim.Region.Framework.Scenes
4417 } 4450 }
4418 } 4451 }
4419 4452
4420 4453 if (SetPhantom
4421 if (IsPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints 4454 || ParentGroup.IsAttachment
4455 || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
4422 { 4456 {
4423 AddFlag(PrimFlags.Phantom); 4457 AddFlag(PrimFlags.Phantom);
4424 if (PhysActor != null) 4458 if (PhysActor != null)
@@ -4432,7 +4466,11 @@ namespace OpenSim.Region.Framework.Scenes
4432 { 4466 {
4433 RemFlag(PrimFlags.Phantom); 4467 RemFlag(PrimFlags.Phantom);
4434 4468
4469 if (ParentGroup.Scene == null)
4470 return;
4471
4435 PhysicsActor pa = PhysActor; 4472 PhysicsActor pa = PhysActor;
4473
4436 if (pa == null) 4474 if (pa == null)
4437 { 4475 {
4438 // It's not phantom anymore. So make sure the physics engine get's knowledge of it 4476 // It's not phantom anymore. So make sure the physics engine get's knowledge of it
@@ -4444,22 +4482,21 @@ namespace OpenSim.Region.Framework.Scenes
4444 RotationOffset, 4482 RotationOffset,
4445 UsePhysics, 4483 UsePhysics,
4446 m_localId); 4484 m_localId);
4447 PhysActor.SetMaterial(Material);
4448 4485
4449 pa = PhysActor; 4486 pa = PhysActor;
4450 if (pa != null) 4487 if (pa != null)
4451 { 4488 {
4489 PhysActor.SetMaterial(Material);
4452 DoPhysicsPropertyUpdate(UsePhysics, true); 4490 DoPhysicsPropertyUpdate(UsePhysics, true);
4453 if (m_parentGroup != null) 4491
4492 if (!m_parentGroup.IsDeleted)
4454 { 4493 {
4455 if (!m_parentGroup.IsDeleted) 4494 if (LocalId == m_parentGroup.RootPart.LocalId)
4456 { 4495 {
4457 if (LocalId == m_parentGroup.RootPart.LocalId) 4496 m_parentGroup.CheckSculptAndLoad();
4458 {
4459 m_parentGroup.CheckSculptAndLoad();
4460 }
4461 } 4497 }
4462 } 4498 }
4499
4463 if ( 4500 if (
4464 ((AggregateScriptEvents & scriptEvents.collision) != 0) || 4501 ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
4465 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || 4502 ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
@@ -4470,8 +4507,8 @@ namespace OpenSim.Region.Framework.Scenes
4470 (CollisionSound != UUID.Zero) 4507 (CollisionSound != UUID.Zero)
4471 ) 4508 )
4472 { 4509 {
4473 PhysActor.OnCollisionUpdate += PhysicsCollision; 4510 PhysActor.OnCollisionUpdate += PhysicsCollision;
4474 PhysActor.SubscribeEvents(1000); 4511 PhysActor.SubscribeEvents(1000);
4475 } 4512 }
4476 } 4513 }
4477 } 4514 }
@@ -4480,20 +4517,18 @@ namespace OpenSim.Region.Framework.Scenes
4480 pa.IsPhysical = UsePhysics; 4517 pa.IsPhysical = UsePhysics;
4481 4518
4482 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim 4519 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
4483 if (m_parentGroup != null) 4520
4521 if (!m_parentGroup.IsDeleted)
4484 { 4522 {
4485 if (!m_parentGroup.IsDeleted) 4523 if (LocalId == m_parentGroup.RootPart.LocalId)
4486 { 4524 {
4487 if (LocalId == m_parentGroup.RootPart.LocalId) 4525 m_parentGroup.CheckSculptAndLoad();
4488 {
4489 m_parentGroup.CheckSculptAndLoad();
4490 }
4491 } 4526 }
4492 } 4527 }
4493 } 4528 }
4494 } 4529 }
4495 4530
4496 if (IsVD) 4531 if (SetVD)
4497 { 4532 {
4498 // If the above logic worked (this is urgent candidate to unit tests!) 4533 // If the above logic worked (this is urgent candidate to unit tests!)
4499 // we now have a physicsactor. 4534 // we now have a physicsactor.
@@ -4508,18 +4543,19 @@ namespace OpenSim.Region.Framework.Scenes
4508 } 4543 }
4509 } 4544 }
4510 else 4545 else
4511 { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like 4546 {
4547 // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
4512 // (mumbles, well, at least if you have infinte CPU powers :-)) 4548 // (mumbles, well, at least if you have infinte CPU powers :-))
4513 PhysicsActor pa = this.PhysActor; 4549 PhysicsActor pa = this.PhysActor;
4514 if (pa != null) 4550 if (pa != null)
4515 { 4551 {
4516 PhysActor.SetVolumeDetect(0); 4552 PhysActor.SetVolumeDetect(0);
4517 } 4553 }
4554
4518 this.VolumeDetectActive = false; 4555 this.VolumeDetectActive = false;
4519 } 4556 }
4520 4557
4521 4558 if (SetTemporary)
4522 if (IsTemporary)
4523 { 4559 {
4524 AddFlag(PrimFlags.TemporaryOnRez); 4560 AddFlag(PrimFlags.TemporaryOnRez);
4525 } 4561 }
@@ -4529,8 +4565,13 @@ namespace OpenSim.Region.Framework.Scenes
4529 } 4565 }
4530 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); 4566 // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
4531 4567
4532 ParentGroup.HasGroupChanged = true; 4568 if (ParentGroup != null)
4533 ScheduleFullUpdate(); 4569 {
4570 ParentGroup.HasGroupChanged = true;
4571 ScheduleFullUpdate();
4572 }
4573
4574// m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags);
4534 } 4575 }
4535 4576
4536 public void UpdateRotation(Quaternion rot) 4577 public void UpdateRotation(Quaternion rot)
@@ -4541,8 +4582,12 @@ namespace OpenSim.Region.Framework.Scenes
4541 (rot.W != RotationOffset.W)) 4582 (rot.W != RotationOffset.W))
4542 { 4583 {
4543 RotationOffset = rot; 4584 RotationOffset = rot;
4544 ParentGroup.HasGroupChanged = true; 4585
4545 ScheduleTerseUpdate(); 4586 if (ParentGroup != null)
4587 {
4588 ParentGroup.HasGroupChanged = true;
4589 ScheduleTerseUpdate();
4590 }
4546 } 4591 }
4547 } 4592 }
4548 4593
@@ -4570,6 +4615,7 @@ namespace OpenSim.Region.Framework.Scenes
4570 m_shape.PathTaperY = shapeBlock.PathTaperY; 4615 m_shape.PathTaperY = shapeBlock.PathTaperY;
4571 m_shape.PathTwist = shapeBlock.PathTwist; 4616 m_shape.PathTwist = shapeBlock.PathTwist;
4572 m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; 4617 m_shape.PathTwistBegin = shapeBlock.PathTwistBegin;
4618
4573 if (PhysActor != null) 4619 if (PhysActor != null)
4574 { 4620 {
4575 PhysActor.Shape = m_shape; 4621 PhysActor.Shape = m_shape;
@@ -4591,11 +4637,46 @@ namespace OpenSim.Region.Framework.Scenes
4591 } 4637 }
4592 4638
4593 /// <summary> 4639 /// <summary>
4640 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
4641 /// engine can use it.
4642 /// </summary>
4643 /// <remarks>
4644 /// When the physics engine has finished with it, the sculpt data is discarded to save memory.
4645 /// </remarks>
4646 public void CheckSculptAndLoad()
4647 {
4648// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
4649
4650 if (ParentGroup.IsDeleted)
4651 return;
4652
4653 if ((ParentGroup.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
4654 return;
4655
4656 if (Shape.SculptEntry && Shape.SculptTexture != UUID.Zero)
4657 {
4658 // check if a previously decoded sculpt map has been cached
4659 // We don't read the file here - the meshmerizer will do that later.
4660 // TODO: Could we simplify the meshmerizer code by reading and setting the data here?
4661 if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + Shape.SculptTexture.ToString())))
4662 {
4663 SculptTextureCallback(null);
4664 }
4665 else
4666 {
4667 ParentGroup.Scene.AssetService.Get(Shape.SculptTexture.ToString(), this, AssetReceived);
4668 }
4669 }
4670 }
4671
4672 /// <summary>
4594 /// Update the textures on the part. 4673 /// Update the textures on the part.
4595 /// </summary> 4674 /// </summary>
4675 /// <remarks>
4596 /// Added to handle bug in libsecondlife's TextureEntry.ToBytes() 4676 /// Added to handle bug in libsecondlife's TextureEntry.ToBytes()
4597 /// not handling RGBA properly. Cycles through, and "fixes" the color 4677 /// not handling RGBA properly. Cycles through, and "fixes" the color
4598 /// info 4678 /// info
4679 /// </remarks>
4599 /// <param name="tex"></param> 4680 /// <param name="tex"></param>
4600 public void UpdateTexture(Primitive.TextureEntry tex) 4681 public void UpdateTexture(Primitive.TextureEntry tex)
4601 { 4682 {
@@ -4687,7 +4768,6 @@ namespace OpenSim.Region.Framework.Scenes
4687 { 4768 {
4688 PhysActor.OnCollisionUpdate += PhysicsCollision; 4769 PhysActor.OnCollisionUpdate += PhysicsCollision;
4689 PhysActor.SubscribeEvents(1000); 4770 PhysActor.SubscribeEvents(1000);
4690
4691 } 4771 }
4692 } 4772 }
4693 else 4773 else
@@ -4699,14 +4779,6 @@ namespace OpenSim.Region.Framework.Scenes
4699 } 4779 }
4700 } 4780 }
4701 4781
4702 if (m_parentGroup == null)
4703 {
4704// m_log.DebugFormat(
4705// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId);
4706 ScheduleFullUpdate();
4707 return;
4708 }
4709
4710 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 4782 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
4711 //{ 4783 //{
4712 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; 4784 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
@@ -4716,7 +4788,7 @@ namespace OpenSim.Region.Framework.Scenes
4716 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting; 4788 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting;
4717 //} 4789 //}
4718 4790
4719 LocalFlags=(PrimFlags)objectflagupdate; 4791 LocalFlags = (PrimFlags)objectflagupdate;
4720 4792
4721 if (m_parentGroup != null && m_parentGroup.RootPart == this) 4793 if (m_parentGroup != null && m_parentGroup.RootPart == this)
4722 { 4794 {
@@ -4730,40 +4802,6 @@ namespace OpenSim.Region.Framework.Scenes
4730 } 4802 }
4731 } 4803 }
4732 4804
4733 public int registerTargetWaypoint(Vector3 target, float tolerance)
4734 {
4735 if (m_parentGroup != null)
4736 {
4737 return m_parentGroup.registerTargetWaypoint(target, tolerance);
4738 }
4739 return 0;
4740 }
4741
4742 public void unregisterTargetWaypoint(int handle)
4743 {
4744 if (m_parentGroup != null)
4745 {
4746 m_parentGroup.unregisterTargetWaypoint(handle);
4747 }
4748 }
4749
4750 public int registerRotTargetWaypoint(Quaternion target, float tolerance)
4751 {
4752 if (m_parentGroup != null)
4753 {
4754 return m_parentGroup.registerRotTargetWaypoint(target, tolerance);
4755 }
4756 return 0;
4757 }
4758
4759 public void unregisterRotTargetWaypoint(int handle)
4760 {
4761 if (m_parentGroup != null)
4762 {
4763 m_parentGroup.unregisterRotTargetWaypoint(handle);
4764 }
4765 }
4766
4767 public void SetCameraAtOffset(Vector3 v) 4805 public void SetCameraAtOffset(Vector3 v)
4768 { 4806 {
4769 m_cameraAtOffset = v; 4807 m_cameraAtOffset = v;
@@ -4803,10 +4841,10 @@ namespace OpenSim.Region.Framework.Scenes
4803 4841
4804 public void SendTerseUpdateToClient(IClientAPI remoteClient) 4842 public void SendTerseUpdateToClient(IClientAPI remoteClient)
4805 { 4843 {
4806 if (ParentGroup == null || ParentGroup.IsDeleted) 4844 if (ParentGroup.IsDeleted)
4807 return; 4845 return;
4808 4846
4809 if (IsAttachment && ParentGroup.RootPart != this) 4847 if (ParentGroup.IsAttachment && ParentGroup.RootPart != this)
4810 return; 4848 return;
4811 4849
4812 // Causes this thread to dig into the Client Thread Data. 4850 // Causes this thread to dig into the Client Thread Data.
@@ -4827,6 +4865,7 @@ namespace OpenSim.Region.Framework.Scenes
4827 4865
4828 Inventory.ApplyNextOwnerPermissions(); 4866 Inventory.ApplyNextOwnerPermissions();
4829 } 4867 }
4868
4830 public void UpdateLookAt() 4869 public void UpdateLookAt()
4831 { 4870 {
4832 try 4871 try
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 56680df..f6b690c 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -118,14 +118,17 @@ namespace OpenSim.Region.Framework.Scenes
118 } 118 }
119 119
120 /// <summary> 120 /// <summary>
121 /// Reset UUIDs for all the items in the prim's inventory. This involves either generating 121 /// Reset UUIDs for all the items in the prim's inventory.
122 /// </summary>
123 /// <remarks>
124 /// This involves either generating
122 /// new ones or setting existing UUIDs to the correct parent UUIDs. 125 /// new ones or setting existing UUIDs to the correct parent UUIDs.
123 /// 126 ///
124 /// If this method is called and there are inventory items, then we regard the inventory as having changed. 127 /// If this method is called and there are inventory items, then we regard the inventory as having changed.
125 /// </summary> 128 /// </remarks>
126 /// <param name="linkNum">Link number for the part</param>
127 public void ResetInventoryIDs() 129 public void ResetInventoryIDs()
128 { 130 {
131 if (null == m_part)
129 m_items.LockItemsForWrite(true); 132 m_items.LockItemsForWrite(true);
130 133
131 if (Items.Count == 0) 134 if (Items.Count == 0)
@@ -212,7 +215,7 @@ namespace OpenSim.Region.Framework.Scenes
212 // Don't let this set the HasGroupChanged flag for attachments 215 // Don't let this set the HasGroupChanged flag for attachments
213 // as this happens during rez and we don't want a new asset 216 // as this happens during rez and we don't want a new asset
214 // for each attachment each time 217 // for each attachment each time
215 if (!m_part.ParentGroup.RootPart.IsAttachment) 218 if (!m_part.ParentGroup.IsAttachment)
216 { 219 {
217 HasInventoryChanged = true; 220 HasInventoryChanged = true;
218 m_part.ParentGroup.HasGroupChanged = true; 221 m_part.ParentGroup.HasGroupChanged = true;
@@ -1236,10 +1239,15 @@ namespace OpenSim.Region.Framework.Scenes
1236 item.CurrentPermissions = perms; 1239 item.CurrentPermissions = perms;
1237 item.BasePermissions = perms; 1240 item.BasePermissions = perms;
1238 } 1241 }
1242
1239 m_inventorySerial++; 1243 m_inventorySerial++;
1240 HasInventoryChanged = true; 1244 HasInventoryChanged = true;
1241 } 1245 }
1242 1246
1247 /// <summary>
1248 /// Returns true if this part inventory contains any scripts. False otherwise.
1249 /// </summary>
1250 /// <returns></returns>
1243 public bool ContainsScripts() 1251 public bool ContainsScripts()
1244 { 1252 {
1245 foreach (TaskInventoryItem item in m_items.Values) 1253 foreach (TaskInventoryItem item in m_items.Values)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index d2f84e3..fa6945c 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.Framework.Scenes
67 67
68 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs); 68 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs);
69 69
70 public class ScenePresence : EntityBase, ISceneEntity 70 public class ScenePresence : EntityBase, IScenePresence
71 { 71 {
72// ~ScenePresence() 72// ~ScenePresence()
73// { 73// {
@@ -76,6 +76,8 @@ namespace OpenSim.Region.Framework.Scenes
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 public PresenceType PresenceType { get; private set; }
80
79// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 81// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
80 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); 82 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
81 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); 83 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
@@ -92,6 +94,13 @@ namespace OpenSim.Region.Framework.Scenes
92 // Value revised by KF 091121 by comparison with SL. 94 // Value revised by KF 091121 by comparison with SL.
93 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); 95 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
94 96
97 /// <summary>
98 /// Movement updates for agents in neighboring regions are sent directly to clients.
99 /// This value only affects how often agent positions are sent to neighbor regions
100 /// for things such as distance-based update prioritization
101 /// </summary>
102 public static readonly float SIGNIFICANT_MOVEMENT = 2.0f;
103
95 public UUID currentParcelUUID = UUID.Zero; 104 public UUID currentParcelUUID = UUID.Zero;
96 105
97 private ISceneViewer m_sceneViewer; 106 private ISceneViewer m_sceneViewer;
@@ -105,24 +114,26 @@ namespace OpenSim.Region.Framework.Scenes
105 } 114 }
106 protected ScenePresenceAnimator m_animator; 115 protected ScenePresenceAnimator m_animator;
107 116
108 /// <value> 117 /// <summary>
109 /// The scene objects attached to this avatar. Do not change this list directly - use methods such as 118 /// Attachments recorded on this avatar.
110 /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. 119 /// </summary>
111 /// </value> 120 /// <remarks>
112 public List<SceneObjectGroup> Attachments 121 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
113 { 122 /// necessary.
114 get { return m_attachments; } 123 /// </remarks>
115 }
116 124
117 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 125 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
118 126
127 public Object AttachmentsSyncLock { get; private set; }
128
119 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>(); 129 private Dictionary<UUID, ScriptControllers> scriptedcontrols = new Dictionary<UUID, ScriptControllers>();
120 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; 130 private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
121 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; 131 private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
122 private bool MouseDown = false; 132 private bool MouseDown = false;
123 private SceneObjectGroup proxyObjectGroup; 133// private SceneObjectGroup proxyObjectGroup;
124 //private SceneObjectPart proxyObjectPart = null; 134 //private SceneObjectPart proxyObjectPart = null;
125 public Vector3 lastKnownAllowedPosition; 135 public Vector3 lastKnownAllowedPosition;
136 public bool sentMessageAboutRestrictedParcelFlyingDown;
126 public Vector4 CollisionPlane = Vector4.UnitW; 137 public Vector4 CollisionPlane = Vector4.UnitW;
127 138
128 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation 139 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
@@ -178,7 +189,7 @@ namespace OpenSim.Region.Framework.Scenes
178 189
179 private float m_speedModifier = 1.0f; 190 private float m_speedModifier = 1.0f;
180 191
181 private Quaternion m_bodyRot= Quaternion.Identity; 192 private Quaternion m_bodyRot = Quaternion.Identity;
182 193
183 private Quaternion m_bodyRotPrevious = Quaternion.Identity; 194 private Quaternion m_bodyRotPrevious = Quaternion.Identity;
184 195
@@ -190,7 +201,6 @@ namespace OpenSim.Region.Framework.Scenes
190 201
191 private float m_health = 100f; 202 private float m_health = 100f;
192 203
193 protected RegionInfo m_regionInfo;
194 protected ulong crossingFromRegion; 204 protected ulong crossingFromRegion;
195 205
196 private readonly Vector3[] Dir_Vectors = new Vector3[11]; 206 private readonly Vector3[] Dir_Vectors = new Vector3[11];
@@ -224,8 +234,8 @@ namespace OpenSim.Region.Framework.Scenes
224 private string m_nextSitAnimation = String.Empty; 234 private string m_nextSitAnimation = String.Empty;
225 235
226 //PauPaw:Proper PID Controler for autopilot************ 236 //PauPaw:Proper PID Controler for autopilot************
227 private bool m_moveToPositionInProgress; 237 public bool MovingToTarget { get; private set; }
228 private Vector3 m_moveToPositionTarget; 238 public Vector3 MoveToPositionTarget { get; private set; }
229 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); 239 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
230 240
231 private bool m_followCamAuto; 241 private bool m_followCamAuto;
@@ -455,9 +465,6 @@ namespace OpenSim.Region.Framework.Scenes
455 465
456 protected PhysicsActor m_physicsActor; 466 protected PhysicsActor m_physicsActor;
457 467
458 /// <value>
459 /// The client controlling this presence
460 /// </value>
461 public IClientAPI ControllingClient 468 public IClientAPI ControllingClient
462 { 469 {
463 get { return m_controllingClient; } 470 get { return m_controllingClient; }
@@ -764,25 +771,24 @@ namespace OpenSim.Region.Framework.Scenes
764 #endregion 771 #endregion
765 772
766 #region Constructor(s) 773 #region Constructor(s)
767 774
768 public ScenePresence() 775 public ScenePresence(
776 IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type)
769 { 777 {
778 AttachmentsSyncLock = new Object();
779
770 m_sendCourseLocationsMethod = SendCoarseLocationsDefault; 780 m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
771 CreateSceneViewer(); 781 m_sceneViewer = new SceneViewer(this);
772 m_animator = new ScenePresenceAnimator(this); 782 m_animator = new ScenePresenceAnimator(this);
773 } 783 PresenceType = type;
774
775 private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this()
776 {
777 m_DrawDistance = world.DefaultDrawDistance; 784 m_DrawDistance = world.DefaultDrawDistance;
778 m_rootRegionHandle = reginfo.RegionHandle; 785 m_rootRegionHandle = world.RegionInfo.RegionHandle;
779 m_controllingClient = client; 786 m_controllingClient = client;
780 m_firstname = m_controllingClient.FirstName; 787 m_firstname = m_controllingClient.FirstName;
781 m_lastname = m_controllingClient.LastName; 788 m_lastname = m_controllingClient.LastName;
782 m_name = String.Format("{0} {1}", m_firstname, m_lastname); 789 m_name = String.Format("{0} {1}", m_firstname, m_lastname);
783 m_scene = world; 790 m_scene = world;
784 m_uuid = client.AgentId; 791 m_uuid = client.AgentId;
785 m_regionInfo = reginfo;
786 m_localId = m_scene.AllocateLocalId(); 792 m_localId = m_scene.AllocateLocalId();
787 793
788 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 794 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
@@ -817,19 +823,10 @@ namespace OpenSim.Region.Framework.Scenes
817 823
818 RegisterToEvents(); 824 RegisterToEvents();
819 SetDirectionVectors(); 825 SetDirectionVectors();
820 }
821 826
822 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
823 : this(client, world, reginfo)
824 {
825 m_appearance = appearance; 827 m_appearance = appearance;
826 } 828 }
827 829
828 private void CreateSceneViewer()
829 {
830 m_sceneViewer = new SceneViewer(this);
831 }
832
833 public void RegisterToEvents() 830 public void RegisterToEvents()
834 { 831 {
835 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; 832 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
@@ -841,8 +838,7 @@ namespace OpenSim.Region.Framework.Scenes
841 m_controllingClient.OnStartAnim += HandleStartAnim; 838 m_controllingClient.OnStartAnim += HandleStartAnim;
842 m_controllingClient.OnStopAnim += HandleStopAnim; 839 m_controllingClient.OnStopAnim += HandleStopAnim;
843 m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; 840 m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls;
844 m_controllingClient.OnAutoPilotGo += DoAutoPilot; 841 m_controllingClient.OnAutoPilotGo += MoveToTarget;
845 m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition);
846 842
847 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 843 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
848 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 844 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
@@ -1029,11 +1025,8 @@ namespace OpenSim.Region.Framework.Scenes
1029 } 1025 }
1030 1026
1031 float localAVHeight = 1.56f; 1027 float localAVHeight = 1.56f;
1032 if (m_appearance != null) 1028 if (m_appearance.AvatarHeight > 0)
1033 { 1029 localAVHeight = m_appearance.AvatarHeight;
1034 if (m_appearance.AvatarHeight > 0)
1035 localAVHeight = m_appearance.AvatarHeight;
1036 }
1037 1030
1038 float posZLimit = 0; 1031 float posZLimit = 0;
1039 1032
@@ -1047,26 +1040,8 @@ namespace OpenSim.Region.Framework.Scenes
1047 } 1040 }
1048 AbsolutePosition = pos; 1041 AbsolutePosition = pos;
1049 1042
1050 if (m_appearance != null)
1051 {
1052 if (m_appearance.AvatarHeight > 0)
1053 SetHeight(m_appearance.AvatarHeight);
1054 }
1055 else
1056 {
1057 m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName);
1058 // emergency; this really shouldn't happen
1059 m_appearance = new AvatarAppearance(UUID);
1060 }
1061
1062 AddToPhysicalScene(isFlying); 1043 AddToPhysicalScene(isFlying);
1063 1044
1064 if (m_appearance != null)
1065 {
1066 if (m_appearance.AvatarHeight > 0)
1067 SetHeight(m_appearance.AvatarHeight);
1068 }
1069
1070 if (m_forceFly) 1045 if (m_forceFly)
1071 { 1046 {
1072 m_physicsActor.Flying = true; 1047 m_physicsActor.Flying = true;
@@ -1087,15 +1062,18 @@ namespace OpenSim.Region.Framework.Scenes
1087 // and it has already rezzed the attachments and started their scripts. 1062 // and it has already rezzed the attachments and started their scripts.
1088 // We do the following only for non-login agents, because their scripts 1063 // We do the following only for non-login agents, because their scripts
1089 // haven't started yet. 1064 // haven't started yet.
1090 if (wasChild && Attachments != null && Attachments.Count > 0) 1065 lock (m_attachments)
1091 { 1066 {
1092 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); 1067 if (wasChild && HasAttachments())
1093 // Resume scripts
1094 Attachments.ForEach(delegate(SceneObjectGroup sog)
1095 { 1068 {
1096 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1069 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
1097 sog.ResumeScripts(); 1070 // Resume scripts
1098 }); 1071 foreach (SceneObjectGroup sog in m_attachments)
1072 {
1073 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1074 sog.ResumeScripts();
1075 }
1076 }
1099 } 1077 }
1100 1078
1101 // send the animations of the other presences to me 1079 // send the animations of the other presences to me
@@ -1105,6 +1083,11 @@ namespace OpenSim.Region.Framework.Scenes
1105 presence.Animator.SendAnimPackToClient(ControllingClient); 1083 presence.Animator.SendAnimPackToClient(ControllingClient);
1106 }); 1084 });
1107 1085
1086 // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
1087 // stall on the border crossing since the existing child agent will still have the last movement
1088 // recorded, which stops the input from being processed.
1089 m_movementflag = 0;
1090
1108 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1091 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1109 } 1092 }
1110 1093
@@ -1196,11 +1179,6 @@ namespace OpenSim.Region.Framework.Scenes
1196 CheckLandingPoint(ref pos); 1179 CheckLandingPoint(ref pos);
1197 AbsolutePosition = pos; 1180 AbsolutePosition = pos;
1198 AddToPhysicalScene(isFlying); 1181 AddToPhysicalScene(isFlying);
1199 if (m_appearance != null)
1200 {
1201 if (m_appearance.AvatarHeight > 0)
1202 SetHeight(m_appearance.AvatarHeight);
1203 }
1204 1182
1205 SendTerseUpdateToAllClients(); 1183 SendTerseUpdateToAllClients();
1206 1184
@@ -1216,22 +1194,10 @@ namespace OpenSim.Region.Framework.Scenes
1216 CheckLandingPoint(ref pos); 1194 CheckLandingPoint(ref pos);
1217 AbsolutePosition = pos; 1195 AbsolutePosition = pos;
1218 AddToPhysicalScene(isFlying); 1196 AddToPhysicalScene(isFlying);
1219 if (m_appearance != null)
1220 {
1221 if (m_appearance.AvatarHeight > 0)
1222 SetHeight(m_appearance.AvatarHeight);
1223 }
1224 1197
1225 SendTerseUpdateToAllClients(); 1198 SendTerseUpdateToAllClients();
1226 } 1199 }
1227 1200
1228 /// <summary>
1229 ///
1230 /// </summary>
1231 public void StopMovement()
1232 {
1233 }
1234
1235 public void StopFlying() 1201 public void StopFlying()
1236 { 1202 {
1237 ControllingClient.StopFlying(this); 1203 ControllingClient.StopFlying(this);
@@ -1281,7 +1247,7 @@ namespace OpenSim.Region.Framework.Scenes
1281 #region Event Handlers 1247 #region Event Handlers
1282 1248
1283 /// <summary> 1249 /// <summary>
1284 /// Sets avatar height in the phyiscs plugin 1250 /// Sets avatar height in the physics plugin
1285 /// </summary> 1251 /// </summary>
1286 public void SetHeight(float height) 1252 public void SetHeight(float height)
1287 { 1253 {
@@ -1294,10 +1260,14 @@ namespace OpenSim.Region.Framework.Scenes
1294 1260
1295 /// <summary> 1261 /// <summary>
1296 /// Complete Avatar's movement into the region. 1262 /// Complete Avatar's movement into the region.
1297 /// This is called upon a very important packet sent from the client,
1298 /// so it's client-controlled. Never call this method directly.
1299 /// </summary> 1263 /// </summary>
1300 public void CompleteMovement(IClientAPI client) 1264 /// <param name="client"></param>
1265 /// <param name="openChildAgents">
1266 /// If true, send notification to neighbour regions to expect
1267 /// a child agent from the client. These neighbours can be some distance away, depending right now on the
1268 /// configuration of DefaultDrawDistance in the [Startup] section of config
1269 /// </param>
1270 public void CompleteMovement(IClientAPI client, bool openChildAgents)
1301 { 1271 {
1302// DateTime startTime = DateTime.Now; 1272// DateTime startTime = DateTime.Now;
1303 1273
@@ -1334,19 +1304,15 @@ namespace OpenSim.Region.Framework.Scenes
1334 1304
1335 //m_log.DebugFormat("Completed movement"); 1305 //m_log.DebugFormat("Completed movement");
1336 1306
1337 m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); 1307 m_controllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1338 SendInitialData(); 1308 SendInitialData();
1339 1309
1340 // Create child agents in neighbouring regions 1310 // Create child agents in neighbouring regions
1341 if (!m_isChildAgent) 1311 if (openChildAgents && !m_isChildAgent)
1342 { 1312 {
1343 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1313 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1344 if (m_agentTransfer != null) 1314 if (m_agentTransfer != null)
1345 m_agentTransfer.EnableChildAgents(this); 1315 m_agentTransfer.EnableChildAgents(this);
1346 else
1347 m_log.DebugFormat(
1348 "[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active for region {0}",
1349 m_scene.RegionInfo.RegionName);
1350 1316
1351 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1317 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1352 if (friendsModule != null) 1318 if (friendsModule != null)
@@ -1401,8 +1367,13 @@ namespace OpenSim.Region.Framework.Scenes
1401 /// <summary> 1367 /// <summary>
1402 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1368 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1403 /// </summary> 1369 /// </summary>
1370 /// <summary>
1371 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1372 /// </summary>
1404 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1373 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1405 { 1374 {
1375 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1376
1406 //if (m_isChildAgent) 1377 //if (m_isChildAgent)
1407 //{ 1378 //{
1408 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); 1379 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
@@ -1424,7 +1395,6 @@ namespace OpenSim.Region.Framework.Scenes
1424 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1395 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1425 1396
1426 m_pos = m_LastFinitePos; 1397 m_pos = m_LastFinitePos;
1427
1428 if (!m_pos.IsFinite()) 1398 if (!m_pos.IsFinite())
1429 { 1399 {
1430 m_pos.X = 127f; 1400 m_pos.X = 127f;
@@ -1445,7 +1415,6 @@ namespace OpenSim.Region.Framework.Scenes
1445 #region Inputs 1415 #region Inputs
1446 1416
1447 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; 1417 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
1448 Quaternion bodyRotation = agentData.BodyRotation;
1449 1418
1450 // Camera location in world. We'll need to raytrace 1419 // Camera location in world. We'll need to raytrace
1451 // from this location from time to time. 1420 // from this location from time to time.
@@ -1495,6 +1464,7 @@ namespace OpenSim.Region.Framework.Scenes
1495 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1464 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1496 } 1465 }
1497 } 1466 }
1467
1498 lock (scriptedcontrols) 1468 lock (scriptedcontrols)
1499 { 1469 {
1500 if (scriptedcontrols.Count > 0) 1470 if (scriptedcontrols.Count > 0)
@@ -1509,9 +1479,6 @@ namespace OpenSim.Region.Framework.Scenes
1509 1479
1510 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1480 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1511 { 1481 {
1512 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1513 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1514
1515 // TODO: This doesn't prevent the user from walking yet. 1482 // TODO: This doesn't prevent the user from walking yet.
1516 // Setting parent ID would fix this, if we knew what value 1483 // Setting parent ID would fix this, if we knew what value
1517 // to use. Or we could add a m_isSitting variable. 1484 // to use. Or we could add a m_isSitting variable.
@@ -1530,23 +1497,29 @@ namespace OpenSim.Region.Framework.Scenes
1530 { 1497 {
1531 return; 1498 return;
1532 } 1499 }
1533
1534 bool update_movementflag = false;
1535 1500
1536 if (m_allowMovement && !SitGround) 1501 if (m_allowMovement && !SitGround)
1537 { 1502 {
1503 Quaternion bodyRotation = agentData.BodyRotation;
1504 bool update_rotation = false;
1505
1506 if (bodyRotation != m_bodyRot)
1507 {
1508 Rotation = bodyRotation;
1509 update_rotation = true;
1510 }
1511
1512 bool update_movementflag = false;
1513
1538 if (agentData.UseClientAgentPosition) 1514 if (agentData.UseClientAgentPosition)
1539 { 1515 {
1540 m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; 1516 MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
1541 m_moveToPositionTarget = agentData.ClientAgentPosition; 1517 MoveToPositionTarget = agentData.ClientAgentPosition;
1542 } 1518 }
1543 1519
1544 int i = 0; 1520 int i = 0;
1545
1546 bool update_rotation = false;
1547 bool DCFlagKeyPressed = false; 1521 bool DCFlagKeyPressed = false;
1548 Vector3 agent_control_v3 = Vector3.Zero; 1522 Vector3 agent_control_v3 = Vector3.Zero;
1549 Quaternion q = bodyRotation;
1550 1523
1551 bool oldflying = PhysicsActor.Flying; 1524 bool oldflying = PhysicsActor.Flying;
1552 1525
@@ -1560,24 +1533,9 @@ namespace OpenSim.Region.Framework.Scenes
1560 if (actor.Flying != oldflying) 1533 if (actor.Flying != oldflying)
1561 update_movementflag = true; 1534 update_movementflag = true;
1562 1535
1563 if (m_animator.m_jumping) // add for jumping
1564 update_movementflag = true;
1565
1566 if (q != m_bodyRot)
1567 {
1568 m_bodyRot = q;
1569 update_rotation = true;
1570 }
1571
1572 //guilty until proven innocent..
1573 bool Nudging = true;
1574 //Basically, if there is at least one non-nudge control then we don't need
1575 //to worry about stopping the avatar
1576
1577 if (m_parentID == 0) 1536 if (m_parentID == 0)
1578 { 1537 {
1579 bool bAllowUpdateMoveToPosition = false; 1538 bool bAllowUpdateMoveToPosition = false;
1580 bool bResetMoveToPosition = false;
1581 1539
1582 Vector3[] dirVectors; 1540 Vector3[] dirVectors;
1583 1541
@@ -1588,176 +1546,78 @@ namespace OpenSim.Region.Framework.Scenes
1588 else 1546 else
1589 dirVectors = Dir_Vectors; 1547 dirVectors = Dir_Vectors;
1590 1548
1591 bool[] isNudge = GetDirectionIsNudge(); 1549 // The fact that m_movementflag is a byte needs to be fixed
1592 1550 // it really should be a uint
1593 1551 // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
1594 1552 uint nudgehack = 250;
1595
1596
1597 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1553 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1598 { 1554 {
1599 if (((uint)flags & (uint)DCF) != 0) 1555 if (((uint)flags & (uint)DCF) != 0)
1600 { 1556 {
1601 bResetMoveToPosition = true;
1602 DCFlagKeyPressed = true; 1557 DCFlagKeyPressed = true;
1558
1603 try 1559 try
1604 { 1560 {
1605 agent_control_v3 += dirVectors[i]; 1561 agent_control_v3 += dirVectors[i];
1606 if (isNudge[i] == false) 1562 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
1607 {
1608 Nudging = false;
1609 }
1610 } 1563 }
1611 catch (IndexOutOfRangeException) 1564 catch (IndexOutOfRangeException)
1612 { 1565 {
1613 // Why did I get this? 1566 // Why did I get this?
1614 } 1567 }
1615 1568
1616 if ((m_movementflag & (uint)DCF) == 0) 1569 if ((m_movementflag & (byte)(uint)DCF) == 0)
1617 { 1570 {
1571 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1572 {
1573 m_movementflag |= (byte)nudgehack;
1574 }
1575
1576 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF);
1618 m_movementflag += (byte)(uint)DCF; 1577 m_movementflag += (byte)(uint)DCF;
1619 update_movementflag = true; 1578 update_movementflag = true;
1620 } 1579 }
1621 } 1580 }
1622 else 1581 else
1623 { 1582 {
1624 if ((m_movementflag & (uint)DCF) != 0) 1583 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1584 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1585 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1586 ) // This or is for Nudge forward
1625 { 1587 {
1626 m_movementflag -= (byte)(uint)DCF; 1588 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1589 m_movementflag -= ((byte)(uint)DCF);
1627 update_movementflag = true; 1590 update_movementflag = true;
1591
1592 /*
1593 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1594 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1595 {
1596 m_log.Debug("Removed Hack flag");
1597 }
1598 */
1628 } 1599 }
1629 else 1600 else
1630 { 1601 {
1631 bAllowUpdateMoveToPosition = true; 1602 bAllowUpdateMoveToPosition = true;
1632 } 1603 }
1633 } 1604 }
1605
1634 i++; 1606 i++;
1635 } 1607 }
1636 //Paupaw:Do Proper PID for Autopilot here
1637 if (bResetMoveToPosition)
1638 {
1639 m_moveToPositionTarget = Vector3.Zero;
1640 m_moveToPositionInProgress = false;
1641 update_movementflag = true;
1642 bAllowUpdateMoveToPosition = false;
1643 }
1644 1608
1645 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) 1609 if (MovingToTarget)
1646 { 1610 {
1647/* 1611 // If the user has pressed a key then we want to cancel any move to target.
1648 bool twoD = false; 1612 if (DCFlagKeyPressed)
1649 bool there = false;
1650 if (Animator != null)
1651 { 1613 {
1652 switch (Animator.CurrentMovementAnimation) 1614 ResetMoveToTarget();
1653 {
1654 case "STAND":
1655 case "WALK":
1656 case "RUN":
1657 case "CROUCH":
1658 case "CROUCHWALK":
1659 {
1660 twoD = true;
1661 }
1662 break;
1663 }
1664 }
1665
1666 if (twoD)
1667 {
1668*/
1669 Vector3 abspos = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, 0.0f);
1670 Vector3 tgt = new Vector3(m_moveToPositionTarget.X, m_moveToPositionTarget.Y, 0.0f);
1671/* if (Util.GetDistanceTo(abspos, tgt) <= 0.5f) there = true;
1672 }
1673 else
1674 {
1675 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) there = true;
1676 }
1677*/
1678 //Check the error term of the current position in relation to the target position
1679// if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f)
1680// if (there)
1681 if (Util.GetDistanceTo(abspos, tgt) <= 0.5f)
1682 {
1683 // we are close enough to the target
1684 m_moveToPositionTarget = Vector3.Zero;
1685 m_moveToPositionInProgress = false;
1686 update_movementflag = true; 1615 update_movementflag = true;
1687 } 1616 }
1688 else 1617 else if (bAllowUpdateMoveToPosition)
1689 { 1618 {
1690 try 1619 if (HandleMoveToTargetUpdate(ref agent_control_v3))
1691 { 1620 update_movementflag = true;
1692 // move avatar in 2D at one meter/second towards target, in avatar coordinate frame.
1693 // This movement vector gets added to the velocity through AddNewMovement().
1694 // Theoretically we might need a more complex PID approach here if other
1695 // unknown forces are acting on the avatar and we need to adaptively respond
1696 // to such forces, but the following simple approach seems to works fine.
1697 Vector3 LocalVectorToTarget3D =
1698// (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1699 (tgt - abspos)
1700 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords
1701 // Ignore z component of vector
1702 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1703 LocalVectorToTarget2D.Normalize();
1704
1705 //We're not nudging
1706 Nudging = false;
1707 agent_control_v3 += LocalVectorToTarget2D;
1708
1709 // update avatar movement flags. the avatar coordinate system is as follows:
1710 //
1711 // +X (forward)
1712 //
1713 // ^
1714 // |
1715 // |
1716 // |
1717 // |
1718 // (left) +Y <--------o--------> -Y
1719 // avatar
1720 // |
1721 // |
1722 // |
1723 // |
1724 // v
1725 // -X
1726 //
1727
1728 // based on the above avatar coordinate system, classify the movement into
1729 // one of left/right/back/forward.
1730 if (LocalVectorToTarget2D.Y > 0)//MoveLeft
1731 {
1732 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1733 //AgentControlFlags
1734 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1735 update_movementflag = true;
1736 }
1737 else if (LocalVectorToTarget2D.Y < 0) //MoveRight
1738 {
1739 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1740 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1741 update_movementflag = true;
1742 }
1743 if (LocalVectorToTarget2D.X < 0) //MoveBack
1744 {
1745 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1746 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1747 update_movementflag = true;
1748 }
1749 else if (LocalVectorToTarget2D.X > 0) //Move Forward
1750 {
1751 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1752 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1753 update_movementflag = true;
1754 }
1755 }
1756 catch (Exception e)
1757 {
1758 //Avoid system crash, can be slower but...
1759 m_log.DebugFormat("Crash! {0}", e.ToString());
1760 }
1761 } 1621 }
1762 } 1622 }
1763 } 1623 }
@@ -1790,85 +1650,231 @@ namespace OpenSim.Region.Framework.Scenes
1790 // which occurs later in the main scene loop 1650 // which occurs later in the main scene loop
1791 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1651 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1792 { 1652 {
1793 // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed));
1794 // m_log.DebugFormat( 1653 // m_log.DebugFormat(
1795 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1654 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1796 1655 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1797 AddNewMovement(agent_control_v3, q, Nudging);
1798 1656
1799 1657 AddNewMovement(agent_control_v3);
1800 } 1658 }
1801 } 1659 // else
1660 // {
1661 // if (!update_movementflag)
1662 // {
1663 // m_log.DebugFormat(
1664 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1665 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1666 // }
1667 // }
1802 1668
1803 if (update_movementflag && !SitGround) 1669 if (update_movementflag && m_parentID == 0)
1804 Animator.UpdateMovementAnimations(); 1670 Animator.UpdateMovementAnimations();
1671 }
1805 1672
1806 m_scene.EventManager.TriggerOnClientMovement(this); 1673 m_scene.EventManager.TriggerOnClientMovement(this);
1807 1674
1808 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 1675 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
1809 } 1676 }
1810 1677
1811 public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) 1678 /// <summary>
1679 /// Calculate an update to move the presence to the set target.
1680 /// </summary>
1681 /// <remarks>
1682 /// This doesn't actually perform the movement. Instead, it adds its vector to agent_control_v3.
1683 /// </remarks>
1684 /// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param>
1685 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1686 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1812 { 1687 {
1813 m_autopilotMoving = true; 1688 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1814 m_autoPilotTarget = Pos;
1815 m_sitAtAutoTarget = false;
1816 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1817 //proxy.PCode = (byte)PCode.ParticleSystem;
1818 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1819 proxyObjectGroup.AttachToScene(m_scene);
1820
1821 // Commented out this code since it could never have executed, but might still be informative.
1822// if (proxyObjectGroup != null)
1823// {
1824 proxyObjectGroup.SendGroupFullUpdate();
1825 remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false);
1826 m_scene.DeleteSceneObject(proxyObjectGroup, false);
1827// }
1828// else
1829// {
1830// m_autopilotMoving = false;
1831// m_autoPilotTarget = Vector3.Zero;
1832// ControllingClient.SendAlertMessage("Autopilot cancelled");
1833// }
1834 }
1835 1689
1836 public void StopMoveToPosition() 1690 bool updated = false;
1837 {
1838 m_moveToPositionTarget = Vector3.Zero;
1839 m_moveToPositionInProgress = false;
1840 }
1841 1691
1842 public void DoMoveToPosition(Object sender, string method, List<String> args) 1692 // m_log.DebugFormat(
1843 { 1693 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1844//Console.WriteLine("SP:DoMoveToPosition"); 1694 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1845 try 1695
1696 if (!m_autopilotMoving)
1846 { 1697 {
1847 float locx = 0f; 1698 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1848 float locy = 0f; 1699 // m_log.DebugFormat(
1849 float locz = 0f; 1700 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1850 uint regionX = 0; 1701 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1851 uint regionY = 0; 1702
1852 try 1703 // Check the error term of the current position in relation to the target position
1704 if (distanceToTarget <= 1)
1853 { 1705 {
1854 Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); 1706 // We are close enough to the target
1855 locx = Convert.ToSingle(args[0]) - (float)regionX; 1707 AbsolutePosition = MoveToPositionTarget;
1856 locy = Convert.ToSingle(args[1]) - (float)regionY; 1708 ResetMoveToTarget();
1857 locz = Convert.ToSingle(args[2]); 1709 updated = true;
1858 } 1710 }
1859 catch (InvalidCastException) 1711 else
1860 { 1712 {
1861 m_log.Error("[CLIENT]: Invalid autopilot request"); 1713 try
1862 return; 1714 {
1715 // move avatar in 3D at one meter/second towards target, in avatar coordinate frame.
1716 // This movement vector gets added to the velocity through AddNewMovement().
1717 // Theoretically we might need a more complex PID approach here if other
1718 // unknown forces are acting on the avatar and we need to adaptively respond
1719 // to such forces, but the following simple approach seems to works fine.
1720 Vector3 LocalVectorToTarget3D =
1721 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1722 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1723 // Ignore z component of vector
1724 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1725 LocalVectorToTarget3D.Normalize();
1726
1727 // update avatar movement flags. the avatar coordinate system is as follows:
1728 //
1729 // +X (forward)
1730 //
1731 // ^
1732 // |
1733 // |
1734 // |
1735 // |
1736 // (left) +Y <--------o--------> -Y
1737 // avatar
1738 // |
1739 // |
1740 // |
1741 // |
1742 // v
1743 // -X
1744 //
1745
1746 // based on the above avatar coordinate system, classify the movement into
1747 // one of left/right/back/forward.
1748 if (LocalVectorToTarget3D.X < 0) //MoveBack
1749 {
1750 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1751 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1752 updated = true;
1753 }
1754 else if (LocalVectorToTarget3D.X > 0) //Move Forward
1755 {
1756 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1757 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1758 updated = true;
1759 }
1760
1761 if (LocalVectorToTarget3D.Y > 0) //MoveLeft
1762 {
1763 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1764 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1765 updated = true;
1766 }
1767 else if (LocalVectorToTarget3D.Y < 0) //MoveRight
1768 {
1769 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1770 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1771 updated = true;
1772 }
1773
1774 if (LocalVectorToTarget3D.Z > 0) //Up
1775 {
1776 // Don't set these flags for up or down - doing so will make the avatar crouch or
1777 // keep trying to jump even if walking along level ground
1778 //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
1779 //AgentControlFlags
1780 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP;
1781 updated = true;
1782 }
1783 else if (LocalVectorToTarget3D.Z < 0) //Down
1784 {
1785 //m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
1786 //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN;
1787 updated = true;
1788 }
1789
1790 // m_log.DebugFormat(
1791 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1792 // LocalVectorToTarget3D, agent_control_v3, Name);
1793
1794 agent_control_v3 += LocalVectorToTarget3D;
1795 }
1796 catch (Exception e)
1797 {
1798 //Avoid system crash, can be slower but...
1799 m_log.DebugFormat("Crash! {0}", e.ToString());
1800 }
1863 } 1801 }
1864 m_moveToPositionInProgress = true;
1865 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1866 }
1867 catch (Exception ex)
1868 {
1869 //Why did I get this error?
1870 m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex);
1871 } 1802 }
1803
1804 return updated;
1805 }
1806
1807 /// <summary>
1808 /// Move to the given target over time.
1809 /// </summary>
1810 /// <param name="pos"></param>
1811 /// <param name="noFly">
1812 /// If true, then don't allow the avatar to fly to the target, even if it's up in the air.
1813 /// This is to allow movement to targets that are known to be on an elevated platform with a continuous path
1814 /// from start to finish.
1815 /// </param>
1816 public void MoveToTarget(Vector3 pos, bool noFly)
1817 {
1818 m_log.DebugFormat(
1819 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1820 Name, pos, m_scene.RegionInfo.RegionName);
1821
1822 if (pos.X < 0 || pos.X >= Constants.RegionSize
1823 || pos.Y < 0 || pos.Y >= Constants.RegionSize
1824 || pos.Z < 0)
1825 return;
1826
1827// Vector3 heightAdjust = new Vector3(0, 0, Appearance.AvatarHeight / 2);
1828// pos += heightAdjust;
1829//
1830// // Anti duck-walking measure
1831// if (Math.Abs(pos.Z - AbsolutePosition.Z) < 0.2f)
1832// {
1833//// m_log.DebugFormat("[SCENE PRESENCE]: Adjusting MoveToPosition from {0} to {1}", pos, AbsolutePosition);
1834// pos.Z = AbsolutePosition.Z;
1835// }
1836
1837 float terrainHeight = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
1838 pos.Z = Math.Max(terrainHeight, pos.Z);
1839
1840 // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is
1841 // always slightly higher than the actual terrain height.
1842 // FIXME: This constrains NOC movements as well, so should be somewhere else.
1843 if (pos.Z - terrainHeight < 0.2)
1844 pos.Z = terrainHeight;
1845
1846 m_log.DebugFormat(
1847 "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
1848 Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
1849
1850 if (noFly)
1851 PhysicsActor.Flying = false;
1852 else if (pos.Z > terrainHeight)
1853 PhysicsActor.Flying = true;
1854
1855 MovingToTarget = true;
1856 MoveToPositionTarget = pos;
1857
1858 Vector3 agent_control_v3 = new Vector3();
1859 HandleMoveToTargetUpdate(ref agent_control_v3);
1860 AddNewMovement(agent_control_v3);
1861 }
1862
1863 /// <summary>
1864 /// Reset the move to target.
1865 /// </summary>
1866 public void ResetMoveToTarget()
1867 {
1868 m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1869
1870 MovingToTarget = false;
1871 MoveToPositionTarget = Vector3.Zero;
1872
1873 // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
1874 // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
1875 // However, the line is here rather than in the NPC module since it also appears necessary to stop a
1876 // viewer that uses "go here" from juddering on all subsequent avatar movements.
1877 AgentControlFlags = (uint)AgentManager.ControlFlags.NONE;
1872 } 1878 }
1873 1879
1874 private void CheckAtSitTarget() 1880 private void CheckAtSitTarget()
@@ -1997,11 +2003,6 @@ namespace OpenSim.Region.Framework.Scenes
1997 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); 2003 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1998 SendAvatarDataToAllAgents(); 2004 SendAvatarDataToAllAgents();
1999 m_requestedSitTargetID = 0; 2005 m_requestedSitTargetID = 0;
2000 if (m_physicsActor != null && m_appearance != null)
2001 {
2002 if (m_appearance.AvatarHeight > 0)
2003 SetHeight(m_appearance.AvatarHeight);
2004 }
2005 } 2006 }
2006 Animator.TrySetMovementAnimation("STAND"); 2007 Animator.TrySetMovementAnimation("STAND");
2007 } 2008 }
@@ -2057,7 +2058,7 @@ namespace OpenSim.Region.Framework.Scenes
2057 bool forceMouselook = false; 2058 bool forceMouselook = false;
2058 2059
2059 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2060 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
2060 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2061 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2061 if (part == null) return; 2062 if (part == null) return;
2062 2063
2063 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2064 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
@@ -2215,14 +2216,23 @@ namespace OpenSim.Region.Framework.Scenes
2215 HandleAgentSit(remoteClient, UUID); 2216 HandleAgentSit(remoteClient, UUID);
2216 } 2217 }
2217 2218
2219 // public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
2218 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) 2220 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
2219 { 2221 {
2220 if (m_parentID != 0) 2222 if (m_parentID != 0)
2221 { 2223 {
2222 StandUp(); 2224 StandUp();
2223 } 2225 }
2226
2227// if (!String.IsNullOrEmpty(sitAnimation))
2228// {
2229// m_nextSitAnimation = sitAnimation;
2230// }
2231// else
2232// {
2224 m_nextSitAnimation = "SIT"; 2233 m_nextSitAnimation = "SIT";
2225 2234// }
2235
2226 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2236 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
2227 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2237 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2228 2238
@@ -2247,7 +2257,6 @@ namespace OpenSim.Region.Framework.Scenes
2247 } 2257 }
2248 else 2258 else
2249 { 2259 {
2250
2251 m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); 2260 m_log.Warn("Sit requested on unknown object: " + targetID.ToString());
2252 } 2261 }
2253 2262
@@ -2445,44 +2454,7 @@ namespace OpenSim.Region.Framework.Scenes
2445 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2454 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity);
2446 } 2455 }
2447 */ 2456 */
2448 public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation)
2449 {
2450 if (m_parentID != 0)
2451 {
2452 StandUp();
2453 }
2454 if (!String.IsNullOrEmpty(sitAnimation))
2455 {
2456 m_nextSitAnimation = sitAnimation;
2457 }
2458 else
2459 {
2460 m_nextSitAnimation = "SIT";
2461 }
2462 2457
2463 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
2464 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
2465 if (part != null)
2466 {
2467 m_requestedSitTargetID = part.LocalId;
2468 //m_requestedSitOffset = offset;
2469 m_requestedSitTargetUUID = targetID;
2470
2471 m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
2472
2473 if (m_scene.PhysicsScene.SupportsRayCast())
2474 {
2475 //SitRayCastAvatarPosition(part);
2476 //return;
2477 }
2478 }
2479 else
2480 {
2481 m_log.Warn("Sit requested on unknown object: " + targetID);
2482 }
2483
2484 SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity);
2485 }
2486 2458
2487 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2459 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2488 { 2460 {
@@ -2656,42 +2628,21 @@ namespace OpenSim.Region.Framework.Scenes
2656 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2628 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2657 /// </summary> 2629 /// </summary>
2658 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2630 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2659 /// <param name="rotation">The direction in which this avatar should now face. 2631 public void AddNewMovement(Vector3 vec)
2660 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2661 { 2632 {
2662 if (m_isChildAgent)
2663 {
2664 // WHAT???
2665 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent");
2666
2667 return;
2668 }
2669
2670 m_perfMonMS = Util.EnvironmentTickCount(); 2633 m_perfMonMS = Util.EnvironmentTickCount();
2671 2634
2672 Rotation = rotation; 2635 Vector3 direc = vec * Rotation;
2673 Vector3 direc = vec * rotation;
2674 direc.Normalize(); 2636 direc.Normalize();
2675 PhysicsActor actor = m_physicsActor;
2676
2677 if (actor.Flying != m_flyingOld) // add for fly velocity control
2678 {
2679 m_flyingOld = actor.Flying; // add for fly velocity control
2680 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2681 }
2682
2683 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2684
2685 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2686 2637
2687 direc *= 0.03f * 128f * m_speedModifier; 2638 direc *= 0.03f * 128f * m_speedModifier;
2688 2639
2640 PhysicsActor actor = m_physicsActor;
2689 if (actor != null) 2641 if (actor != null)
2690 { 2642 {
2691 if (actor.Flying) 2643 if (actor.Flying)
2692 { 2644 {
2693// rm speed mod direc *= 4.0f; 2645 direc *= 4.0f;
2694 direc *= 5.2f; // for speed mod
2695 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2646 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2696 //bool colliding = (m_physicsActor.IsColliding==true); 2647 //bool colliding = (m_physicsActor.IsColliding==true);
2697 //if (controlland) 2648 //if (controlland)
@@ -2704,34 +2655,22 @@ namespace OpenSim.Region.Framework.Scenes
2704 // m_log.Info("[AGENT]: Stop FLying"); 2655 // m_log.Info("[AGENT]: Stop FLying");
2705 //} 2656 //}
2706 } 2657 }
2707 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2708 {
2709 direc *= 0.0f;
2710 }
2711 /* This jumping section removed to SPA
2712 else if (!actor.Flying && actor.IsColliding) 2658 else if (!actor.Flying && actor.IsColliding)
2713 { 2659 {
2714 if (direc.Z > 2.0f) 2660 if (direc.Z > 2.0f)
2715 { 2661 {
2716 if(m_animator.m_animTickJump == -1) 2662 direc.Z *= 3.0f;
2717 { 2663
2718 direc.Z *= 3.0f; // jump 2664 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2719 } 2665 Animator.TrySetMovementAnimation("PREJUMP");
2720 else 2666 Animator.TrySetMovementAnimation("JUMP");
2721 {
2722 direc.Z *= 0.1f; // prejump
2723 }
2724 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2725 Animator.TrySetMovementAnimation("PREJUMP");
2726 Animator.TrySetMovementAnimation("JUMP");
2727 * /
2728 } 2667 }
2729 } */ 2668 }
2730 } 2669 }
2731 2670
2732 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2671 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2733 m_forceToApply = direc; 2672 m_forceToApply = direc;
2734 m_isNudging = Nudging; 2673
2735 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2674 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2736 } 2675 }
2737 2676
@@ -2901,13 +2840,7 @@ namespace OpenSim.Region.Framework.Scenes
2901 // We have an appearance but we may not have the baked textures. Check the asset cache 2840 // We have an appearance but we may not have the baked textures. Check the asset cache
2902 // to see if all the baked textures are already here. 2841 // to see if all the baked textures are already here.
2903 if (m_scene.AvatarFactory != null) 2842 if (m_scene.AvatarFactory != null)
2904 {
2905 cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient); 2843 cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient);
2906 }
2907 else
2908 {
2909 m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name);
2910 }
2911 2844
2912 // If we aren't using a cached appearance, then clear out the baked textures 2845 // If we aren't using a cached appearance, then clear out the baked textures
2913 if (!cachedappearance) 2846 if (!cachedappearance)
@@ -3064,19 +2997,21 @@ namespace OpenSim.Region.Framework.Scenes
3064 /// <param name="avatar"></param> 2997 /// <param name="avatar"></param>
3065 public void SendAppearanceToAgent(ScenePresence avatar) 2998 public void SendAppearanceToAgent(ScenePresence avatar)
3066 { 2999 {
3067// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); 3000// m_log.DebugFormat(
3001// "[SCENE PRESENCE] Send appearance from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID);
3068 3002
3069 avatar.ControllingClient.SendAppearance( 3003 avatar.ControllingClient.SendAppearance(
3070 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); 3004 UUID, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
3071 } 3005 }
3072 3006
3073 // Because appearance setting is in a module, we actually need
3074 // to give it access to our appearance directly, otherwise we
3075 // get a synchronization issue.
3076 public AvatarAppearance Appearance 3007 public AvatarAppearance Appearance
3077 { 3008 {
3078 get { return m_appearance; } 3009 get { return m_appearance; }
3079 set { m_appearance = value; } 3010 set
3011 {
3012 m_appearance = value;
3013// m_log.DebugFormat("[SCENE PRESENCE]: Set appearance for {0} to {1}", Name, value);
3014 }
3080 } 3015 }
3081 3016
3082 #endregion 3017 #endregion
@@ -3088,15 +3023,10 @@ namespace OpenSim.Region.Framework.Scenes
3088 /// </summary> 3023 /// </summary>
3089 protected void CheckForSignificantMovement() 3024 protected void CheckForSignificantMovement()
3090 { 3025 {
3091 // Movement updates for agents in neighboring regions are sent directly to clients.
3092 // This value only affects how often agent positions are sent to neighbor regions
3093 // for things such as distance-based update prioritization
3094 const float SIGNIFICANT_MOVEMENT = 2.0f;
3095
3096 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) 3026 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT)
3097 { 3027 {
3098 posLastSignificantMove = AbsolutePosition; 3028 posLastSignificantMove = AbsolutePosition;
3099 m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); 3029 m_scene.EventManager.TriggerSignificantClientMovement(this);
3100 } 3030 }
3101 3031
3102 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 3032 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
@@ -3298,8 +3228,8 @@ namespace OpenSim.Region.Framework.Scenes
3298 /// </returns> 3228 /// </returns>
3299 protected int HaveNeighbor(Cardinals car, ref int[] fix) 3229 protected int HaveNeighbor(Cardinals car, ref int[] fix)
3300 { 3230 {
3301 uint neighbourx = m_regionInfo.RegionLocX; 3231 uint neighbourx = m_scene.RegionInfo.RegionLocX;
3302 uint neighboury = m_regionInfo.RegionLocY; 3232 uint neighboury = m_scene.RegionInfo.RegionLocY;
3303 3233
3304 int dir = (int)car; 3234 int dir = (int)car;
3305 3235
@@ -3319,8 +3249,8 @@ namespace OpenSim.Region.Framework.Scenes
3319 3249
3320 if (neighbourRegion == null) 3250 if (neighbourRegion == null)
3321 { 3251 {
3322 fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx); 3252 fix[0] = (int)(m_scene.RegionInfo.RegionLocX - neighbourx);
3323 fix[1] = (int)(m_regionInfo.RegionLocY - neighboury); 3253 fix[1] = (int)(m_scene.RegionInfo.RegionLocY - neighboury);
3324 return dir * (-1); 3254 return dir * (-1);
3325 } 3255 }
3326 else 3256 else
@@ -3566,26 +3496,30 @@ namespace OpenSim.Region.Framework.Scenes
3566 catch { } 3496 catch { }
3567 3497
3568 // Attachment objects 3498 // Attachment objects
3569 if (m_attachments != null && m_attachments.Count > 0) 3499 lock (m_attachments)
3570 { 3500 {
3571 cAgent.AttachmentObjects = new List<ISceneObject>(); 3501 if (m_attachments.Count > 0)
3572 cAgent.AttachmentObjectStates = new List<string>();
3573// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
3574 m_InTransitScriptStates.Clear();
3575 foreach (SceneObjectGroup sog in m_attachments)
3576 { 3502 {
3577 // We need to make a copy and pass that copy 3503 cAgent.AttachmentObjects = new List<ISceneObject>();
3578 // because of transfers withn the same sim 3504 cAgent.AttachmentObjectStates = new List<string>();
3579 ISceneObject clone = sog.CloneForNewScene(); 3505 // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
3580 // Attachment module assumes that GroupPosition holds the offsets...! 3506 m_InTransitScriptStates.Clear();
3581 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; 3507
3582 ((SceneObjectGroup)clone).RootPart.IsAttachment = false; 3508 foreach (SceneObjectGroup sog in m_attachments)
3583 cAgent.AttachmentObjects.Add(clone); 3509 {
3584 string state = sog.GetStateSnapshot(); 3510 // We need to make a copy and pass that copy
3585 cAgent.AttachmentObjectStates.Add(state); 3511 // because of transfers withn the same sim
3586 m_InTransitScriptStates.Add(state); 3512 ISceneObject clone = sog.CloneForNewScene();
3587 // Let's remove the scripts of the original object here 3513 // Attachment module assumes that GroupPosition holds the offsets...!
3588 sog.RemoveScriptInstances(true); 3514 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
3515 ((SceneObjectGroup)clone).IsAttachment = false;
3516 cAgent.AttachmentObjects.Add(clone);
3517 string state = sog.GetStateSnapshot();
3518 cAgent.AttachmentObjectStates.Add(state);
3519 m_InTransitScriptStates.Add(state);
3520 // Let's remove the scripts of the original object here
3521 sog.RemoveScriptInstances(true);
3522 }
3589 } 3523 }
3590 } 3524 }
3591 } 3525 }
@@ -3686,45 +3620,17 @@ namespace OpenSim.Region.Framework.Scenes
3686 /// </summary> 3620 /// </summary>
3687 public override void UpdateMovement() 3621 public override void UpdateMovement()
3688 { 3622 {
3689 if (Animator!=null) // add for jumping 3623 if (m_forceToApply.HasValue)
3690 { // add for jumping 3624 {
3691 // if (!m_animator.m_jumping) // add for jumping 3625 Vector3 force = m_forceToApply.Value;
3692 // { // add for jumping
3693 3626
3694 if (m_forceToApply.HasValue) // this section realigned 3627 m_updateflag = true;
3695 {
3696 3628
3697 Vector3 force = m_forceToApply.Value; 3629 Velocity = force;
3698 m_updateflag = true; 3630
3699if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping 3631 m_forceToApply = null;
3700 Velocity = force; 3632 }
3701//Console.WriteLine("UM1 {0}", Velocity); 3633 }
3702 m_forceToApply = null;
3703 }
3704 else
3705 {
3706 if (m_isNudging)
3707 {
3708 Vector3 force = Vector3.Zero;
3709
3710 m_updateflag = true;
3711if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3712 Velocity = force;
3713//Console.WriteLine("UM2 {0}", Velocity);
3714 m_isNudging = false;
3715 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3716 }
3717 else // add for jumping
3718 { // add for jumping
3719 Vector3 force = Vector3.Zero; // add for jumping
3720if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping
3721//Console.WriteLine("UM3 {0}", Velocity);
3722 Velocity = force; // add for jumping
3723 }
3724 }
3725 // } // end realign
3726 } // add for jumping
3727 } // add for jumping
3728 3634
3729 /// <summary> 3635 /// <summary>
3730 /// Adds a physical representation of the avatar to the Physics plugin 3636 /// Adds a physical representation of the avatar to the Physics plugin
@@ -3746,6 +3652,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
3746 m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong 3652 m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
3747 m_physicsActor.SubscribeEvents(500); 3653 m_physicsActor.SubscribeEvents(500);
3748 m_physicsActor.LocalID = LocalId; 3654 m_physicsActor.LocalID = LocalId;
3655
3656 SetHeight(m_appearance.AvatarHeight);
3749 } 3657 }
3750 3658
3751 private void OutOfBoundsCall(Vector3 pos) 3659 private void OutOfBoundsCall(Vector3 pos)
@@ -3879,7 +3787,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
3879 { 3787 {
3880 StartCollidingMessage.Colliders = colliding; 3788 StartCollidingMessage.Colliders = colliding;
3881 3789
3882 foreach (SceneObjectGroup att in Attachments) 3790 foreach (SceneObjectGroup att in GetAttachments())
3883 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); 3791 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3884 } 3792 }
3885 } 3793 }
@@ -3914,7 +3822,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
3914 { 3822 {
3915 EndCollidingMessage.Colliders = colliding; 3823 EndCollidingMessage.Colliders = colliding;
3916 3824
3917 foreach (SceneObjectGroup att in Attachments) 3825 foreach (SceneObjectGroup att in GetAttachments())
3918 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); 3826 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3919 } 3827 }
3920 } 3828 }
@@ -4001,19 +3909,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4001 3909
4002 public void Close() 3910 public void Close()
4003 { 3911 {
4004 lock (m_attachments) 3912 if (!IsChildAgent)
4005 { 3913 m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
4006 // Delete attachments from scene
4007 // Don't try to save, as this thread won't live long
4008 // enough to complete the save. This would cause no copy
4009 // attachments to poof!
4010 //
4011 foreach (SceneObjectGroup grp in m_attachments)
4012 {
4013 m_scene.DeleteSceneObject(grp, false);
4014 }
4015 m_attachments.Clear();
4016 }
4017 3914
4018 lock (m_knownChildRegions) 3915 lock (m_knownChildRegions)
4019 { 3916 {
@@ -4048,9 +3945,19 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4048 m_attachments.Add(gobj); 3945 m_attachments.Add(gobj);
4049 } 3946 }
4050 } 3947 }
4051 3948
4052 /// <summary> 3949 /// <summary>
4053 /// Get the scene object attached to the given point. 3950 /// Get all the presence's attachments.
3951 /// </summary>
3952 /// <returns>A copy of the list which contains the attachments.</returns>
3953 public List<SceneObjectGroup> GetAttachments()
3954 {
3955 lock (m_attachments)
3956 return new List<SceneObjectGroup>(m_attachments);
3957 }
3958
3959 /// <summary>
3960 /// Get the scene objects attached to the given point.
4054 /// </summary> 3961 /// </summary>
4055 /// <param name="attachmentPoint"></param> 3962 /// <param name="attachmentPoint"></param>
4056 /// <returns>Returns an empty list if there were no attachments at the point.</returns> 3963 /// <returns>Returns an empty list if there were no attachments at the point.</returns>
@@ -4062,7 +3969,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4062 { 3969 {
4063 foreach (SceneObjectGroup so in m_attachments) 3970 foreach (SceneObjectGroup so in m_attachments)
4064 { 3971 {
4065 if (attachmentPoint == so.RootPart.AttachmentPoint) 3972 if (attachmentPoint == so.AttachmentPoint)
4066 attachments.Add(so); 3973 attachments.Add(so);
4067 } 3974 }
4068 } 3975 }
@@ -4072,7 +3979,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4072 3979
4073 public bool HasAttachments() 3980 public bool HasAttachments()
4074 { 3981 {
4075 return m_attachments.Count > 0; 3982 lock (m_attachments)
3983 return m_attachments.Count > 0;
4076 } 3984 }
4077 3985
4078 public bool HasScriptedAttachments() 3986 public bool HasScriptedAttachments()
@@ -4094,29 +4002,49 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4094 public void RemoveAttachment(SceneObjectGroup gobj) 4002 public void RemoveAttachment(SceneObjectGroup gobj)
4095 { 4003 {
4096 lock (m_attachments) 4004 lock (m_attachments)
4097 { 4005 m_attachments.Remove(gobj);
4098 if (m_attachments.Contains(gobj))
4099 {
4100 m_attachments.Remove(gobj);
4101 }
4102 }
4103 } 4006 }
4104 4007
4008 /// <summary>
4009 /// Clear all attachments
4010 /// </summary>
4011 public void ClearAttachments()
4012 {
4013 lock (m_attachments)
4014 m_attachments.Clear();
4015 }
4016
4017 /// <summary>
4018 /// This is currently just being done for information.
4019 /// </summary>
4105 public bool ValidateAttachments() 4020 public bool ValidateAttachments()
4106 { 4021 {
4022 bool validated = true;
4023
4107 lock (m_attachments) 4024 lock (m_attachments)
4108 { 4025 {
4109 // Validate 4026 // Validate
4110 foreach (SceneObjectGroup gobj in m_attachments) 4027 foreach (SceneObjectGroup gobj in m_attachments)
4111 { 4028 {
4112 if (gobj == null) 4029 if (gobj == null)
4113 return false; 4030 {
4031 m_log.WarnFormat(
4032 "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null. Continuing", Name);
4114 4033
4115 if (gobj.IsDeleted) 4034 validated = false;
4116 return false; 4035 }
4036 else if (gobj.IsDeleted)
4037 {
4038 m_log.WarnFormat(
4039 "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted. Continuing",
4040 gobj.Name, gobj.UUID, Name);
4041
4042 validated = false;
4043 }
4117 } 4044 }
4118 } 4045 }
4119 return true; 4046
4047 return validated;
4120 } 4048 }
4121 4049
4122 /// <summary> 4050 /// <summary>
@@ -4148,29 +4076,6 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4148 } 4076 }
4149 } 4077 }
4150 4078
4151
4152 public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene)
4153 {
4154 m_controllingClient = client;
4155 m_regionInfo = region;
4156 m_scene = scene;
4157
4158 RegisterToEvents();
4159
4160 /*
4161 AbsolutePosition = client.StartPos;
4162
4163 Animations = new AvatarAnimations();
4164 Animations.LoadAnims();
4165
4166 m_animations = new List<UUID>();
4167 m_animations.Add(Animations.AnimsUUID["STAND"]);
4168 m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber);
4169
4170 SetDirectionVectors();
4171 */
4172 }
4173
4174 internal void PushForce(Vector3 impulse) 4079 internal void PushForce(Vector3 impulse)
4175 { 4080 {
4176 if (PhysicsActor != null) 4081 if (PhysicsActor != null)
@@ -4198,6 +4103,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4198 obj.ignoreControls = (ScriptControlled)controls; 4103 obj.ignoreControls = (ScriptControlled)controls;
4199 obj.eventControls = (ScriptControlled)controls; 4104 obj.eventControls = (ScriptControlled)controls;
4200 } 4105 }
4106
4201 if (pass_on == 1 && accept == 1) 4107 if (pass_on == 1 && accept == 1)
4202 { 4108 {
4203 IgnoredControls = ScriptControlled.CONTROL_ZERO; 4109 IgnoredControls = ScriptControlled.CONTROL_ZERO;
@@ -4218,6 +4124,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4218 scriptedcontrols[Script_item_UUID] = obj; 4124 scriptedcontrols[Script_item_UUID] = obj;
4219 } 4125 }
4220 } 4126 }
4127
4221 ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); 4128 ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true);
4222 } 4129 }
4223 4130
@@ -4374,103 +4281,6 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4374 return flags; 4281 return flags;
4375 } 4282 }
4376 4283
4377 /// <summary>
4378 /// RezAttachments. This should only be called upon login on the first region.
4379 /// Attachment rezzings on crossings and TPs are done in a different way.
4380 /// </summary>
4381 public void RezAttachments()
4382 {
4383 if (null == m_appearance)
4384 {
4385 m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", UUID);
4386 return;
4387 }
4388
4389 XmlDocument doc = new XmlDocument();
4390 string stateData = String.Empty;
4391
4392 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
4393 if (attServ != null)
4394 {
4395 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
4396 stateData = attServ.Get(ControllingClient.AgentId.ToString());
4397 if (stateData != String.Empty)
4398 {
4399 try
4400 {
4401 doc.LoadXml(stateData);
4402 }
4403 catch { }
4404 }
4405 }
4406
4407 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
4408
4409 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
4410 if (nodes.Count > 0)
4411 {
4412 foreach (XmlNode n in nodes)
4413 {
4414 XmlElement elem = (XmlElement)n;
4415 string itemID = elem.GetAttribute("ItemID");
4416 string xml = elem.InnerXml;
4417
4418 itemData[new UUID(itemID)] = xml;
4419 }
4420 }
4421
4422 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
4423 foreach (AvatarAttachment attach in attachments)
4424 {
4425 if (m_isDeleted)
4426 return;
4427
4428 int p = attach.AttachPoint;
4429 UUID itemID = attach.ItemID;
4430
4431 //UUID assetID = attach.AssetID;
4432 // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down
4433 // But they're not used anyway, the item is being looked up for now, so let's proceed.
4434 //if (UUID.Zero == assetID)
4435 //{
4436 // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID);
4437 // continue;
4438 //}
4439
4440 try
4441 {
4442 string xmlData;
4443 XmlDocument d = new XmlDocument();
4444 UUID asset;
4445 if (itemData.TryGetValue(itemID, out xmlData))
4446 {
4447 d.LoadXml(xmlData);
4448 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID);
4449
4450 // Rez from inventory
4451 asset
4452 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d);
4453
4454 }
4455 else
4456 {
4457 // Rez from inventory (with a null doc to let
4458 // CHANGED_OWNER happen)
4459 asset
4460 = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null);
4461 }
4462
4463 m_log.InfoFormat(
4464 "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}",
4465 p, itemID, asset);
4466 }
4467 catch (Exception e)
4468 {
4469 m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace);
4470 }
4471 }
4472 }
4473
4474 private void ReprioritizeUpdates() 4284 private void ReprioritizeUpdates()
4475 { 4285 {
4476 if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) 4286 if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time)
@@ -4505,29 +4315,6 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4505 return(new Vector3(x,y,z)); 4315 return(new Vector3(x,y,z));
4506 } 4316 }
4507 4317
4508 public void SaveChangedAttachments()
4509 {
4510 // Need to copy this list because DetachToInventoryPrep mods it
4511 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(Attachments.ToArray());
4512
4513 IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule;
4514 if (attachmentsModule != null)
4515 {
4516 foreach (SceneObjectGroup grp in attachments)
4517 {
4518 if (grp.HasGroupChanged) // Resizer scripts?
4519 {
4520 grp.RootPart.IsAttachment = false;
4521 grp.AbsolutePosition = grp.RootPart.AttachedPos;
4522// grp.DetachToInventoryPrep();
4523 attachmentsModule.UpdateKnownItem(ControllingClient,
4524 grp, grp.GetFromItemID(), grp.OwnerID);
4525 grp.RootPart.IsAttachment = true;
4526 }
4527 }
4528 }
4529 }
4530
4531 private void CheckLandingPoint(ref Vector3 pos) 4318 private void CheckLandingPoint(ref Vector3 pos)
4532 { 4319 {
4533 // Never constrain lures 4320 // Never constrain lures
@@ -4553,4 +4340,4 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4553 } 4340 }
4554 } 4341 }
4555 } 4342 }
4556} 4343} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index f04ed4d..8a0d288 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -38,27 +38,42 @@ namespace OpenSim.Region.Framework.Scenes
38{ 38{
39 public class SceneViewer : ISceneViewer 39 public class SceneViewer : ISceneViewer
40 { 40 {
41 /// <summary>
42 /// Is this scene viewer enabled?
43 /// </summary>
44 private bool IsEnabled { get; set; }
45
46 /// <summary>
47 /// The scene presence serviced by this viewer.
48 /// </summary>
41 protected ScenePresence m_presence; 49 protected ScenePresence m_presence;
50
51 /// <summary>
52 /// The queue of parts for which we need to send out updates.
53 /// </summary>
42 protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); 54 protected UpdateQueue m_partsUpdateQueue = new UpdateQueue();
55
56 /// <summary>
57 /// The queue of objects for which we need to send out updates.
58 /// </summary>
43 protected Queue<SceneObjectGroup> m_pendingObjects; 59 protected Queue<SceneObjectGroup> m_pendingObjects;
44 60
61 /// <summary>
62 /// The last update assocated with a given part update.
63 /// </summary>
45 protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); 64 protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>();
46 65
47 public SceneViewer()
48 {
49 }
50
51 public SceneViewer(ScenePresence presence) 66 public SceneViewer(ScenePresence presence)
52 { 67 {
53 m_presence = presence; 68 m_presence = presence;
69 IsEnabled = true;
54 } 70 }
55 71
56 /// <summary>
57 /// Add the part to the queue of parts for which we need to send an update to the client
58 /// </summary>
59 /// <param name="part"></param>
60 public void QueuePartForUpdate(SceneObjectPart part) 72 public void QueuePartForUpdate(SceneObjectPart part)
61 { 73 {
74 if (!IsEnabled)
75 return;
76
62 lock (m_partsUpdateQueue) 77 lock (m_partsUpdateQueue)
63 { 78 {
64 m_partsUpdateQueue.Enqueue(part); 79 m_partsUpdateQueue.Enqueue(part);
@@ -87,6 +102,11 @@ namespace OpenSim.Region.Framework.Scenes
87 102
88 lock (m_pendingObjects) 103 lock (m_pendingObjects)
89 { 104 {
105 // We must do this under lock so that we don't suffer a race condition if another thread closes the
106 // viewer
107 if (!IsEnabled)
108 return;
109
90 while (m_pendingObjects != null && m_pendingObjects.Count > 0) 110 while (m_pendingObjects != null && m_pendingObjects.Count > 0)
91 { 111 {
92 SceneObjectGroup g = m_pendingObjects.Dequeue(); 112 SceneObjectGroup g = m_pendingObjects.Dequeue();
@@ -110,7 +130,7 @@ namespace OpenSim.Region.Framework.Scenes
110 { 130 {
111 SceneObjectPart part = m_partsUpdateQueue.Dequeue(); 131 SceneObjectPart part = m_partsUpdateQueue.Dequeue();
112 132
113 if (part.ParentGroup == null || part.ParentGroup.IsDeleted) 133 if (part.ParentGroup.IsDeleted)
114 continue; 134 continue;
115 135
116 if (m_updateTimes.ContainsKey(part.UUID)) 136 if (m_updateTimes.ContainsKey(part.UUID))
@@ -119,9 +139,7 @@ namespace OpenSim.Region.Framework.Scenes
119 139
120 // We deal with the possibility that two updates occur at 140 // We deal with the possibility that two updates occur at
121 // the same unix time at the update point itself. 141 // the same unix time at the update point itself.
122 142 if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment)
123 if ((update.LastFullUpdateTime < part.TimeStampFull) ||
124 part.IsAttachment)
125 { 143 {
126 // m_log.DebugFormat( 144 // m_log.DebugFormat(
127 // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", 145 // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}",
@@ -136,9 +154,7 @@ namespace OpenSim.Region.Framework.Scenes
136 // this update. If this happened, then subsequent 154 // this update. If this happened, then subsequent
137 // updates which occurred on the same tick or the 155 // updates which occurred on the same tick or the
138 // next tick of the last update would be ignored. 156 // next tick of the last update would be ignored.
139
140 update.LastFullUpdateTime = part.TimeStampFull; 157 update.LastFullUpdateTime = part.TimeStampFull;
141
142 } 158 }
143 else if (update.LastTerseUpdateTime <= part.TimeStampTerse) 159 else if (update.LastTerseUpdateTime <= part.TimeStampTerse)
144 { 160 {
@@ -177,38 +193,46 @@ namespace OpenSim.Region.Framework.Scenes
177 } 193 }
178 } 194 }
179 195
180 public void Reset() 196// public void Reset()
181 { 197// {
182 if (m_pendingObjects == null) 198// if (m_pendingObjects == null)
183 return; 199// return;
200//
201// lock (m_pendingObjects)
202// {
203// if (m_pendingObjects != null)
204// {
205// m_pendingObjects.Clear();
206// m_pendingObjects = null;
207// }
208// }
209// }
184 210
211 public void Close()
212 {
185 lock (m_pendingObjects) 213 lock (m_pendingObjects)
186 { 214 {
187 if (m_pendingObjects != null) 215 // We perform this under the m_pendingObjects lock in order to avoid a race condition with another
216 // thread on SendPrimUpdates()
217 IsEnabled = false;
218
219 lock (m_updateTimes)
188 { 220 {
189 m_pendingObjects.Clear(); 221 m_updateTimes.Clear();
190 m_pendingObjects = null;
191 } 222 }
192 }
193 }
194 223
195 public void Close() 224 lock (m_partsUpdateQueue)
196 { 225 {
197 lock (m_updateTimes) 226 m_partsUpdateQueue.Clear();
198 { 227 }
199 m_updateTimes.Clear();
200 }
201 lock (m_partsUpdateQueue)
202 {
203 m_partsUpdateQueue.Clear();
204 } 228 }
205 Reset();
206 } 229 }
207 230
208 public int GetPendingObjectsCount() 231 public int GetPendingObjectsCount()
209 { 232 {
210 if (m_pendingObjects != null) 233 if (m_pendingObjects != null)
211 return m_pendingObjects.Count; 234 lock (m_pendingObjects)
235 return m_pendingObjects.Count;
212 236
213 return 0; 237 return 0;
214 } 238 }
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index d6e8223..11dad6c 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -53,19 +53,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
53 /// <summary> 53 /// <summary>
54 /// Deserialize a scene object from the original xml format 54 /// Deserialize a scene object from the original xml format
55 /// </summary> 55 /// </summary>
56 /// <param name="serialization"></param> 56 /// <param name="xmlData"></param>
57 /// <returns></returns> 57 /// <returns></returns>
58 public static SceneObjectGroup FromOriginalXmlFormat(string serialization) 58 public static SceneObjectGroup FromOriginalXmlFormat(string xmlData)
59 {
60 return FromOriginalXmlFormat(UUID.Zero, serialization);
61 }
62
63 /// <summary>
64 /// Deserialize a scene object from the original xml format
65 /// </summary>
66 /// <param name="serialization"></param>
67 /// <returns></returns>
68 public static SceneObjectGroup FromOriginalXmlFormat(UUID fromUserInventoryItemID, string xmlData)
69 { 59 {
70 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); 60 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
71 //int time = System.Environment.TickCount; 61 //int time = System.Environment.TickCount;
@@ -87,7 +77,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
87 77
88 sr = new StringReader(parts[0].InnerXml); 78 sr = new StringReader(parts[0].InnerXml);
89 reader = new XmlTextReader(sr); 79 reader = new XmlTextReader(sr);
90 SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(fromUserInventoryItemID, reader)); 80 SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader));
91 reader.Close(); 81 reader.Close();
92 sr.Close(); 82 sr.Close();
93 83
@@ -102,7 +92,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
102 sceneObject.AddPart(part); 92 sceneObject.AddPart(part);
103 part.LinkNum = linkNum; 93 part.LinkNum = linkNum;
104 part.TrimPermissions(); 94 part.TrimPermissions();
105 part.StoreUndoState(UndoType.STATE_ALL);
106 reader.Close(); 95 reader.Close();
107 sr.Close(); 96 sr.Close();
108 } 97 }
@@ -128,26 +117,36 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
128 /// <returns></returns> 117 /// <returns></returns>
129 public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject) 118 public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject)
130 { 119 {
120 return ToOriginalXmlFormat(sceneObject, true);
121 }
122
123 /// <summary>
124 /// Serialize a scene object to the original xml format
125 /// </summary>
126 /// <param name="sceneObject"></param>
127 /// <param name="doScriptStates">Control whether script states are also serialized.</para>
128 /// <returns></returns>
129 public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject, bool doScriptStates)
130 {
131 using (StringWriter sw = new StringWriter()) 131 using (StringWriter sw = new StringWriter())
132 { 132 {
133 using (XmlTextWriter writer = new XmlTextWriter(sw)) 133 using (XmlTextWriter writer = new XmlTextWriter(sw))
134 { 134 {
135 ToOriginalXmlFormat(sceneObject, writer); 135 ToOriginalXmlFormat(sceneObject, writer, doScriptStates);
136 } 136 }
137 137
138 return sw.ToString(); 138 return sw.ToString();
139 } 139 }
140 } 140 }
141
142 141
143 /// <summary> 142 /// <summary>
144 /// Serialize a scene object to the original xml format 143 /// Serialize a scene object to the original xml format
145 /// </summary> 144 /// </summary>
146 /// <param name="sceneObject"></param> 145 /// <param name="sceneObject"></param>
147 /// <returns></returns> 146 /// <returns></returns>
148 public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer) 147 public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer, bool doScriptStates)
149 { 148 {
150 ToOriginalXmlFormat(sceneObject, writer, false); 149 ToOriginalXmlFormat(sceneObject, writer, doScriptStates, false);
151 } 150 }
152 151
153 /// <summary> 152 /// <summary>
@@ -157,10 +156,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
157 /// <param name="writer"></param> 156 /// <param name="writer"></param>
158 /// <param name="noRootElement">If false, don't write the enclosing SceneObjectGroup element</param> 157 /// <param name="noRootElement">If false, don't write the enclosing SceneObjectGroup element</param>
159 /// <returns></returns> 158 /// <returns></returns>
160 public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer, bool noRootElement) 159 public static void ToOriginalXmlFormat(
160 SceneObjectGroup sceneObject, XmlTextWriter writer, bool doScriptStates, bool noRootElement)
161 { 161 {
162 //m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", Name); 162// m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", sceneObject.Name);
163 //int time = System.Environment.TickCount; 163// int time = System.Environment.TickCount;
164 164
165 if (!noRootElement) 165 if (!noRootElement)
166 writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); 166 writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
@@ -183,12 +183,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
183 } 183 }
184 184
185 writer.WriteEndElement(); // OtherParts 185 writer.WriteEndElement(); // OtherParts
186 sceneObject.SaveScriptedState(writer); 186
187 if (doScriptStates)
188 sceneObject.SaveScriptedState(writer);
187 189
188 if (!noRootElement) 190 if (!noRootElement)
189 writer.WriteEndElement(); // SceneObjectGroup 191 writer.WriteEndElement(); // SceneObjectGroup
190 192
191 //m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); 193// m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", sceneObject.Name, System.Environment.TickCount - time);
192 } 194 }
193 195
194 protected static void ToXmlFormat(SceneObjectPart part, XmlTextWriter writer) 196 protected static void ToXmlFormat(SceneObjectPart part, XmlTextWriter writer)
@@ -236,15 +238,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
236 if (originalLinkNum != 0) 238 if (originalLinkNum != 0)
237 part.LinkNum = originalLinkNum; 239 part.LinkNum = originalLinkNum;
238 240
239 part.StoreUndoState(UndoType.STATE_ALL);
240 reader.Close(); 241 reader.Close();
241 sr.Close(); 242 sr.Close();
242 } 243 }
243 244
244 // Script state may, or may not, exist. Not having any, is NOT 245 // Script state may, or may not, exist. Not having any, is NOT
245 // ever a problem. 246 // ever a problem.
246
247 sceneObject.LoadScriptState(doc); 247 sceneObject.LoadScriptState(doc);
248
248 return sceneObject; 249 return sceneObject;
249 } 250 }
250 catch (Exception e) 251 catch (Exception e)
@@ -1592,4 +1593,4 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1592 1593
1593 #endregion 1594 #endregion
1594 } 1595 }
1595} 1596} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs
deleted file mode 100644
index cff649b..0000000
--- a/OpenSim/Region/Framework/Scenes/Tests/AttachmentTests.cs
+++ /dev/null
@@ -1,172 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using System.Threading;
33using System.Timers;
34using Timer=System.Timers.Timer;
35using Nini.Config;
36using NUnit.Framework;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Communications;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.CoreModules.World.Serialiser;
43using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
44using OpenSim.Tests.Common;
45using OpenSim.Tests.Common.Mock;
46
47namespace OpenSim.Region.Framework.Scenes.Tests
48{
49 /// <summary>
50 /// Attachment tests
51 /// </summary>
52 [TestFixture]
53 public class AttachmentTests
54 {
55 public Scene scene, scene2;
56 public UUID agent1;
57 public static Random random;
58 public ulong region1, region2;
59 public AgentCircuitData acd1;
60 public SceneObjectGroup sog1, sog2, sog3;
61
62 [TestFixtureSetUp]
63 public void Init()
64 {
65 TestHelper.InMethod();
66
67 scene = SceneSetupHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000);
68 scene2 = SceneSetupHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000);
69
70 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule();
71 interregionComms.Initialise(new IniConfigSource());
72 interregionComms.PostInitialise();
73 SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms);
74 SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms);
75
76 agent1 = UUID.Random();
77 random = new Random();
78 sog1 = NewSOG(UUID.Random(), scene, agent1);
79 sog2 = NewSOG(UUID.Random(), scene, agent1);
80 sog3 = NewSOG(UUID.Random(), scene, agent1);
81
82 //ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
83 region1 = scene.RegionInfo.RegionHandle;
84 region2 = scene2.RegionInfo.RegionHandle;
85
86 SceneSetupHelpers.AddRootAgent(scene, agent1);
87 }
88
89 [Test]
90 public void T030_TestAddAttachments()
91 {
92 TestHelper.InMethod();
93
94 ScenePresence presence = scene.GetScenePresence(agent1);
95
96 presence.AddAttachment(sog1);
97 presence.AddAttachment(sog2);
98 presence.AddAttachment(sog3);
99
100 Assert.That(presence.HasAttachments(), Is.True);
101 Assert.That(presence.ValidateAttachments(), Is.True);
102 }
103
104 [Test]
105 public void T031_RemoveAttachments()
106 {
107 TestHelper.InMethod();
108
109 ScenePresence presence = scene.GetScenePresence(agent1);
110 presence.RemoveAttachment(sog1);
111 presence.RemoveAttachment(sog2);
112 presence.RemoveAttachment(sog3);
113 Assert.That(presence.HasAttachments(), Is.False);
114 }
115
116 // I'm commenting this test because scene setup NEEDS InventoryService to
117 // be non-null
118 //[Test]
119 public void T032_CrossAttachments()
120 {
121 TestHelper.InMethod();
122
123 ScenePresence presence = scene.GetScenePresence(agent1);
124 ScenePresence presence2 = scene2.GetScenePresence(agent1);
125 presence2.AddAttachment(sog1);
126 presence2.AddAttachment(sog2);
127
128 ISharedRegionModule serialiser = new SerialiserModule();
129 SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser);
130 SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser);
131
132 Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross");
133
134 //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful");
135 Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted");
136 Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
137 }
138
139 private SceneObjectGroup NewSOG(UUID uuid, Scene scene, UUID agent)
140 {
141 SceneObjectPart sop = new SceneObjectPart();
142 sop.Name = RandomName();
143 sop.Description = RandomName();
144 sop.Text = RandomName();
145 sop.SitName = RandomName();
146 sop.TouchName = RandomName();
147 sop.UUID = uuid;
148 sop.Shape = PrimitiveBaseShape.Default;
149 sop.Shape.State = 1;
150 sop.OwnerID = agent;
151
152 SceneObjectGroup sog = new SceneObjectGroup(sop);
153 sog.SetScene(scene);
154
155 return sog;
156 }
157
158 private static string RandomName()
159 {
160 StringBuilder name = new StringBuilder();
161 int size = random.Next(5,12);
162 char ch;
163 for (int i = 0; i < size; i++)
164 {
165 ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ;
166 name.Append(ch);
167 }
168
169 return name.ToString();
170 }
171 }
172} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
index 3a0dd00..ab6311b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
@@ -41,7 +41,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
41 [Test] 41 [Test]
42 public void TestCross() 42 public void TestCross()
43 { 43 {
44 TestHelper.InMethod(); 44 TestHelpers.InMethod();
45 45
46 List<Border> testborders = new List<Border>(); 46 List<Border> testborders = new List<Border>();
47 47
@@ -99,7 +99,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
99 [Test] 99 [Test]
100 public void TestCrossSquare512() 100 public void TestCrossSquare512()
101 { 101 {
102 TestHelper.InMethod(); 102 TestHelpers.InMethod();
103 103
104 List<Border> testborders = new List<Border>(); 104 List<Border> testborders = new List<Border>();
105 105
@@ -179,7 +179,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
179 [Test] 179 [Test]
180 public void TestCrossRectangle512x256() 180 public void TestCrossRectangle512x256()
181 { 181 {
182 TestHelper.InMethod(); 182 TestHelpers.InMethod();
183 183
184 List<Border> testborders = new List<Border>(); 184 List<Border> testborders = new List<Border>();
185 185
@@ -259,7 +259,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
259 [Test] 259 [Test]
260 public void TestCrossOdd512x512w256hole() 260 public void TestCrossOdd512x512w256hole()
261 { 261 {
262 TestHelper.InMethod(); 262 TestHelpers.InMethod();
263 263
264 List<Border> testborders = new List<Border>(); 264 List<Border> testborders = new List<Border>();
265 // 512____ 265 // 512____
diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
index f69a4b4..a5d2b23 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
@@ -45,12 +45,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests
45 { 45 {
46 static public Random random; 46 static public Random random;
47 SceneObjectGroup found; 47 SceneObjectGroup found;
48 Scene scene = SceneSetupHelpers.SetupScene(); 48 Scene scene = SceneHelpers.SetupScene();
49 49
50 [Test] 50 [Test]
51 public void T010_AddObjects() 51 public void T010_AddObjects()
52 { 52 {
53 TestHelper.InMethod(); 53 TestHelpers.InMethod();
54 54
55 random = new Random(); 55 random = new Random();
56 SceneObjectGroup found; 56 SceneObjectGroup found;
@@ -85,7 +85,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
85 [Test] 85 [Test]
86 public void T011_ThreadAddRemoveTest() 86 public void T011_ThreadAddRemoveTest()
87 { 87 {
88 TestHelper.InMethod(); 88 TestHelpers.InMethod();
89 89
90 // This test adds and removes with mutiple threads, attempting to break the 90 // This test adds and removes with mutiple threads, attempting to break the
91 // uuid and localid dictionary coherence. 91 // uuid and localid dictionary coherence.
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
index 895f2bb..9a60e50 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
@@ -43,8 +43,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
43 [Test] 43 [Test]
44 public void TestDuplicateObject() 44 public void TestDuplicateObject()
45 { 45 {
46 TestHelper.InMethod(); 46 TestHelpers.InMethod();
47 Scene scene = SceneSetupHelpers.SetupScene(); 47 Scene scene = SceneHelpers.SetupScene();
48 48
49 UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010"); 49 UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010");
50 string part1Name = "part1"; 50 string part1Name = "part1";
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
index 0a82c4f..80f198d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
@@ -49,25 +49,28 @@ namespace OpenSim.Region.Framework.Scenes.Tests
49 [Test] 49 [Test]
50 public void TestAddSceneObject() 50 public void TestAddSceneObject()
51 { 51 {
52 TestHelper.InMethod(); 52 TestHelpers.InMethod();
53 53
54 Scene scene = SceneSetupHelpers.SetupScene(); 54 Scene scene = SceneHelpers.SetupScene();
55 int partsToTestCount = 3;
55 56
56 string objName = "obj1"; 57 SceneObjectGroup so
57 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); 58 = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10);
58 59 SceneObjectPart[] parts = so.Parts;
59 SceneObjectPart part
60 = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
61 { Name = objName, UUID = objUuid };
62 60
63 Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part), false), Is.True); 61 Assert.That(scene.AddNewSceneObject(so, false), Is.True);
64 62 SceneObjectGroup retrievedSo = scene.GetSceneObjectGroup(so.UUID);
65 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid); 63 SceneObjectPart[] retrievedParts = retrievedSo.Parts;
66 64
67 //m_log.Debug("retrievedPart : {0}", retrievedPart); 65 //m_log.Debug("retrievedPart : {0}", retrievedPart);
68 // If the parts have the same UUID then we will consider them as one and the same 66 // If the parts have the same UUID then we will consider them as one and the same
69 Assert.That(retrievedPart.Name, Is.EqualTo(objName)); 67 Assert.That(retrievedSo.PrimCount, Is.EqualTo(partsToTestCount));
70 Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); 68
69 for (int i = 0; i < partsToTestCount; i++)
70 {
71 Assert.That(retrievedParts[i].Name, Is.EqualTo(parts[i].Name));
72 Assert.That(retrievedParts[i].UUID, Is.EqualTo(parts[i].UUID));
73 }
71 } 74 }
72 75
73 [Test] 76 [Test]
@@ -76,9 +79,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
76 /// </summary> 79 /// </summary>
77 public void TestAddExistingSceneObjectUuid() 80 public void TestAddExistingSceneObjectUuid()
78 { 81 {
79 TestHelper.InMethod(); 82 TestHelpers.InMethod();
80 83
81 Scene scene = SceneSetupHelpers.SetupScene(); 84 Scene scene = SceneHelpers.SetupScene();
82 85
83 string obj1Name = "Alfred"; 86 string obj1Name = "Alfred";
84 string obj2Name = "Betty"; 87 string obj2Name = "Betty";
@@ -103,6 +106,39 @@ namespace OpenSim.Region.Framework.Scenes.Tests
103 Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name)); 106 Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name));
104 Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); 107 Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
105 } 108 }
109
110 /// <summary>
111 /// Test retrieving a scene object via the local id of one of its parts.
112 /// </summary>
113 [Test]
114 public void TestGetSceneObjectByPartLocalId()
115 {
116 TestHelpers.InMethod();
117
118 Scene scene = SceneHelpers.SetupScene();
119 int partsToTestCount = 3;
120
121 SceneObjectGroup so
122 = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10);
123 SceneObjectPart[] parts = so.Parts;
124
125 scene.AddNewSceneObject(so, false);
126
127 // Test getting via the root part's local id
128 Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Not.Null);
129
130 // Test getting via a non root part's local id
131 Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Not.Null);
132
133 // Test that we don't get back an object for a local id that doesn't exist
134 Assert.That(scene.GetGroupByPrim(999), Is.Null);
135
136 // Now delete the scene object and check again
137 scene.DeleteSceneObject(so, false);
138
139 Assert.That(scene.GetGroupByPrim(so.LocalId), Is.Null);
140 Assert.That(scene.GetGroupByPrim(parts[partsToTestCount - 1].LocalId), Is.Null);
141 }
106 142
107 /// <summary> 143 /// <summary>
108 /// Test deleting an object from a scene. 144 /// Test deleting an object from a scene.
@@ -110,10 +146,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
110 [Test] 146 [Test]
111 public void TestDeleteSceneObject() 147 public void TestDeleteSceneObject()
112 { 148 {
113 TestHelper.InMethod(); 149 TestHelpers.InMethod();
114 150
115 TestScene scene = SceneSetupHelpers.SetupScene(); 151 TestScene scene = SceneHelpers.SetupScene();
116 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); 152 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
117 scene.DeleteSceneObject(part.ParentGroup, false); 153 scene.DeleteSceneObject(part.ParentGroup, false);
118 154
119 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); 155 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
@@ -126,20 +162,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests
126 [Test] 162 [Test]
127 public void TestDeleteSceneObjectAsync() 163 public void TestDeleteSceneObjectAsync()
128 { 164 {
129 TestHelper.InMethod(); 165 TestHelpers.InMethod();
130 //log4net.Config.XmlConfigurator.Configure(); 166 //log4net.Config.XmlConfigurator.Configure();
131 167
132 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); 168 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001");
133 169
134 TestScene scene = SceneSetupHelpers.SetupScene(); 170 TestScene scene = SceneHelpers.SetupScene();
135 171
136 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. 172 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
137 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; 173 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
138 sogd.Enabled = false; 174 sogd.Enabled = false;
139 175
140 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); 176 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
141 177
142 IClientAPI client = SceneSetupHelpers.AddRootAgent(scene, agentId); 178 IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient;
143 scene.DeRezObjects(client, new System.Collections.Generic.List<uint>() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero); 179 scene.DeRezObjects(client, new System.Collections.Generic.List<uint>() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero);
144 180
145 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); 181 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
index 5357a06..654b1a2 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
@@ -56,17 +56,17 @@ namespace OpenSim.Region.Framework.Scenes.Tests
56 [Test] 56 [Test]
57 public void TestDeRezSceneObject() 57 public void TestDeRezSceneObject()
58 { 58 {
59 TestHelper.InMethod(); 59 TestHelpers.InMethod();
60// log4net.Config.XmlConfigurator.Configure(); 60// log4net.Config.XmlConfigurator.Configure();
61 61
62 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 62 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
63 63
64 TestScene scene = SceneSetupHelpers.SetupScene(); 64 TestScene scene = SceneHelpers.SetupScene();
65 IConfigSource configSource = new IniConfigSource(); 65 IConfigSource configSource = new IniConfigSource();
66 IConfig config = configSource.AddConfig("Startup"); 66 IConfig config = configSource.AddConfig("Startup");
67 config.Set("serverside_object_permissions", true); 67 config.Set("serverside_object_permissions", true);
68 SceneSetupHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); 68 SceneHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() });
69 TestClient client = SceneSetupHelpers.AddRootAgent(scene, userId); 69 IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
70 70
71 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. 71 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
72 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; 72 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
@@ -94,18 +94,18 @@ namespace OpenSim.Region.Framework.Scenes.Tests
94 [Test] 94 [Test]
95 public void TestDeRezSceneObjectNotOwner() 95 public void TestDeRezSceneObjectNotOwner()
96 { 96 {
97 TestHelper.InMethod(); 97 TestHelpers.InMethod();
98// log4net.Config.XmlConfigurator.Configure(); 98// log4net.Config.XmlConfigurator.Configure();
99 99
100 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 100 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
101 UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001"); 101 UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001");
102 102
103 TestScene scene = SceneSetupHelpers.SetupScene(); 103 TestScene scene = SceneHelpers.SetupScene();
104 IConfigSource configSource = new IniConfigSource(); 104 IConfigSource configSource = new IniConfigSource();
105 IConfig config = configSource.AddConfig("Startup"); 105 IConfig config = configSource.AddConfig("Startup");
106 config.Set("serverside_object_permissions", true); 106 config.Set("serverside_object_permissions", true);
107 SceneSetupHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() }); 107 SceneHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() });
108 TestClient client = SceneSetupHelpers.AddRootAgent(scene, userId); 108 IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
109 109
110 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. 110 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
111 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; 111 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index cb1d531..2912a46 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -50,14 +50,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests
50 [Test] 50 [Test]
51 public void TestLinkDelink2SceneObjects() 51 public void TestLinkDelink2SceneObjects()
52 { 52 {
53 TestHelper.InMethod(); 53 TestHelpers.InMethod();
54 54
55 bool debugtest = false; 55 bool debugtest = false;
56 56
57 Scene scene = SceneSetupHelpers.SetupScene(); 57 Scene scene = SceneHelpers.SetupScene();
58 SceneObjectPart part1 = SceneSetupHelpers.AddSceneObject(scene); 58 SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene);
59 SceneObjectGroup grp1 = part1.ParentGroup; 59 SceneObjectGroup grp1 = part1.ParentGroup;
60 SceneObjectPart part2 = SceneSetupHelpers.AddSceneObject(scene); 60 SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene);
61 SceneObjectGroup grp2 = part2.ParentGroup; 61 SceneObjectGroup grp2 = part2.ParentGroup;
62 62
63 grp1.AbsolutePosition = new Vector3(10, 10, 10); 63 grp1.AbsolutePosition = new Vector3(10, 10, 10);
@@ -132,18 +132,18 @@ namespace OpenSim.Region.Framework.Scenes.Tests
132 [Test] 132 [Test]
133 public void TestLinkDelink2groups4SceneObjects() 133 public void TestLinkDelink2groups4SceneObjects()
134 { 134 {
135 TestHelper.InMethod(); 135 TestHelpers.InMethod();
136 136
137 bool debugtest = false; 137 bool debugtest = false;
138 138
139 Scene scene = SceneSetupHelpers.SetupScene(); 139 Scene scene = SceneHelpers.SetupScene();
140 SceneObjectPart part1 = SceneSetupHelpers.AddSceneObject(scene); 140 SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene);
141 SceneObjectGroup grp1 = part1.ParentGroup; 141 SceneObjectGroup grp1 = part1.ParentGroup;
142 SceneObjectPart part2 = SceneSetupHelpers.AddSceneObject(scene); 142 SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene);
143 SceneObjectGroup grp2 = part2.ParentGroup; 143 SceneObjectGroup grp2 = part2.ParentGroup;
144 SceneObjectPart part3 = SceneSetupHelpers.AddSceneObject(scene); 144 SceneObjectPart part3 = SceneHelpers.AddSceneObject(scene);
145 SceneObjectGroup grp3 = part3.ParentGroup; 145 SceneObjectGroup grp3 = part3.ParentGroup;
146 SceneObjectPart part4 = SceneSetupHelpers.AddSceneObject(scene); 146 SceneObjectPart part4 = SceneHelpers.AddSceneObject(scene);
147 SceneObjectGroup grp4 = part4.ParentGroup; 147 SceneObjectGroup grp4 = part4.ParentGroup;
148 148
149 grp1.AbsolutePosition = new Vector3(10, 10, 10); 149 grp1.AbsolutePosition = new Vector3(10, 10, 10);
@@ -266,10 +266,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
266 [Test] 266 [Test]
267 public void TestNewSceneObjectLinkPersistence() 267 public void TestNewSceneObjectLinkPersistence()
268 { 268 {
269 TestHelper.InMethod(); 269 TestHelpers.InMethod();
270 //log4net.Config.XmlConfigurator.Configure(); 270 //log4net.Config.XmlConfigurator.Configure();
271 271
272 TestScene scene = SceneSetupHelpers.SetupScene(); 272 TestScene scene = SceneHelpers.SetupScene();
273 273
274 string rootPartName = "rootpart"; 274 string rootPartName = "rootpart";
275 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); 275 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001");
@@ -305,10 +305,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
305 [Test] 305 [Test]
306 public void TestDelinkPersistence() 306 public void TestDelinkPersistence()
307 { 307 {
308 TestHelper.InMethod(); 308 TestHelpers.InMethod();
309 //log4net.Config.XmlConfigurator.Configure(); 309 //log4net.Config.XmlConfigurator.Configure();
310 310
311 TestScene scene = SceneSetupHelpers.SetupScene(); 311 TestScene scene = SceneHelpers.SetupScene();
312 312
313 string rootPartName = "rootpart"; 313 string rootPartName = "rootpart";
314 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); 314 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
new file mode 100644
index 0000000..b49c6e7
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using NUnit.Framework;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Framework.Communications;
34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock;
37
38namespace OpenSim.Region.Framework.Scenes.Tests
39{
40 /// <summary>
41 /// Basic scene object resize tests
42 /// </summary>
43 [TestFixture]
44 public class SceneObjectResizeTests
45 {
46 /// <summary>
47 /// Test resizing an object
48 /// </summary>
49 [Test]
50 public void TestResizeSceneObject()
51 {
52 TestHelpers.InMethod();
53// log4net.Config.XmlConfigurator.Configure();
54
55 Scene scene = SceneHelpers.SetupScene();
56 SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene).ParentGroup;
57
58 g1.GroupResize(new Vector3(2, 3, 4));
59
60 SceneObjectGroup g1Post = scene.GetSceneObjectGroup(g1.UUID);
61
62 Assert.That(g1Post.RootPart.Scale.X, Is.EqualTo(2));
63 Assert.That(g1Post.RootPart.Scale.Y, Is.EqualTo(3));
64 Assert.That(g1Post.RootPart.Scale.Z, Is.EqualTo(4));
65
66 Assert.That(g1Post.RootPart.UndoCount, Is.EqualTo(1));
67 }
68
69 /// <summary>
70 /// Test resizing an individual part in a scene object.
71 /// </summary>
72 [Test]
73 public void TestResizeSceneObjectPart()
74 {
75 TestHelpers.InMethod();
76 //log4net.Config.XmlConfigurator.Configure();
77
78 Scene scene = SceneHelpers.SetupScene();
79
80 SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(2, UUID.Zero);
81 g1.RootPart.Scale = new Vector3(2, 3, 4);
82 g1.Parts[1].Scale = new Vector3(5, 6, 7);
83
84 scene.AddSceneObject(g1);
85
86 SceneObjectGroup g1Post = scene.GetSceneObjectGroup(g1.UUID);
87
88 g1Post.Parts[1].Resize(new Vector3(8, 9, 10));
89
90 SceneObjectGroup g1PostPost = scene.GetSceneObjectGroup(g1.UUID);
91
92 SceneObjectPart g1RootPart = g1PostPost.RootPart;
93 SceneObjectPart g1ChildPart = g1PostPost.Parts[1];
94
95 Assert.That(g1RootPart.Scale.X, Is.EqualTo(2));
96 Assert.That(g1RootPart.Scale.Y, Is.EqualTo(3));
97 Assert.That(g1RootPart.Scale.Z, Is.EqualTo(4));
98
99 Assert.That(g1ChildPart.Scale.X, Is.EqualTo(8));
100 Assert.That(g1ChildPart.Scale.Y, Is.EqualTo(9));
101 Assert.That(g1ChildPart.Scale.Z, Is.EqualTo(10));
102 }
103 }
104} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
new file mode 100644
index 0000000..2a342d5
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using NUnit.Framework;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Framework.Communications;
34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock;
37
38namespace OpenSim.Region.Framework.Scenes.Tests
39{
40 /// <summary>
41 /// Basic scene object status tests
42 /// </summary>
43 [TestFixture]
44 public class SceneObjectStatusTests
45 {
46 [Test]
47 public void TestSetPhantom()
48 {
49 TestHelpers.InMethod();
50
51// Scene scene = SceneSetupHelpers.SetupScene();
52 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero);
53 SceneObjectPart rootPart = so.RootPart;
54 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
55
56 so.ScriptSetPhantomStatus(true);
57
58// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
59 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom));
60
61 so.ScriptSetPhantomStatus(false);
62
63 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
64 }
65 }
66} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
index 77bd4c2..c13d82e 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
@@ -53,12 +53,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests
53 [Test] 53 [Test]
54 public void TestShareWithGroup() 54 public void TestShareWithGroup()
55 { 55 {
56 TestHelper.InMethod(); 56 TestHelpers.InMethod();
57// log4net.Config.XmlConfigurator.Configure(); 57// log4net.Config.XmlConfigurator.Configure();
58 58
59 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 59 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
60 60
61 TestScene scene = SceneSetupHelpers.SetupScene(); 61 TestScene scene = SceneHelpers.SetupScene();
62 IConfigSource configSource = new IniConfigSource(); 62 IConfigSource configSource = new IniConfigSource();
63 63
64 IConfig startupConfig = configSource.AddConfig("Startup"); 64 IConfig startupConfig = configSource.AddConfig("Startup");
@@ -69,13 +69,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
69 groupsConfig.Set("Module", "GroupsModule"); 69 groupsConfig.Set("Module", "GroupsModule");
70 groupsConfig.Set("DebugEnabled", true); 70 groupsConfig.Set("DebugEnabled", true);
71 71
72 SceneSetupHelpers.SetupSceneModules( 72 SceneHelpers.SetupSceneModules(
73 scene, configSource, new object[] 73 scene, configSource, new object[]
74 { new PermissionsModule(), 74 { new PermissionsModule(),
75 new GroupsModule(), 75 new GroupsModule(),
76 new MockGroupsServicesConnector() }); 76 new MockGroupsServicesConnector() });
77 77
78 TestClient client = SceneSetupHelpers.AddRootAgent(scene, userId); 78 IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
79 79
80 IGroupsModule groupsModule = scene.RequestModuleInterface<IGroupsModule>(); 80 IGroupsModule groupsModule = scene.RequestModuleInterface<IGroupsModule>();
81 81
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index 03ac252..ce9d418 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
51 /// Scene presence tests 51 /// Scene presence tests
52 /// </summary> 52 /// </summary>
53 [TestFixture] 53 [TestFixture]
54 public class ScenePresenceTests 54 public class ScenePresenceAgentTests
55 { 55 {
56 public Scene scene, scene2, scene3; 56 public Scene scene, scene2, scene3;
57 public UUID agent1, agent2, agent3; 57 public UUID agent1, agent2, agent3;
@@ -64,90 +64,140 @@ namespace OpenSim.Region.Framework.Scenes.Tests
64 [TestFixtureSetUp] 64 [TestFixtureSetUp]
65 public void Init() 65 public void Init()
66 { 66 {
67 TestHelper.InMethod(); 67 TestHelpers.InMethod();
68 68
69 scene = SceneSetupHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); 69 scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000);
70 scene2 = SceneSetupHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); 70 scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000);
71 scene3 = SceneSetupHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); 71 scene3 = SceneHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000);
72 72
73 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); 73 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule();
74 interregionComms.Initialise(new IniConfigSource()); 74 interregionComms.Initialise(new IniConfigSource());
75 interregionComms.PostInitialise(); 75 interregionComms.PostInitialise();
76 SceneSetupHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); 76 SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms);
77 SceneSetupHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); 77 SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms);
78 SceneSetupHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms); 78 SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms);
79 79
80 agent1 = UUID.Random(); 80 agent1 = UUID.Random();
81 agent2 = UUID.Random(); 81 agent2 = UUID.Random();
82 agent3 = UUID.Random(); 82 agent3 = UUID.Random();
83 random = new Random(); 83 random = new Random();
84 sog1 = NewSOG(UUID.Random(), scene, agent1); 84 sog1 = SceneHelpers.CreateSceneObject(1, agent1);
85 sog2 = NewSOG(UUID.Random(), scene, agent1); 85 scene.AddSceneObject(sog1);
86 sog3 = NewSOG(UUID.Random(), scene, agent1); 86 sog2 = SceneHelpers.CreateSceneObject(1, agent1);
87 scene.AddSceneObject(sog2);
88 sog3 = SceneHelpers.CreateSceneObject(1, agent1);
89 scene.AddSceneObject(sog3);
87 90
88 //ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
89 region1 = scene.RegionInfo.RegionHandle; 91 region1 = scene.RegionInfo.RegionHandle;
90 region2 = scene2.RegionInfo.RegionHandle; 92 region2 = scene2.RegionInfo.RegionHandle;
91 region3 = scene3.RegionInfo.RegionHandle; 93 region3 = scene3.RegionInfo.RegionHandle;
92 } 94 }
93 95
94 /// <summary>
95 /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene.
96 /// </summary>
97 [Test] 96 [Test]
98 public void T010_TestAddRootAgent() 97 public void TestCloseAgent()
99 { 98 {
100 TestHelper.InMethod(); 99 TestHelpers.InMethod();
101 100// log4net.Config.XmlConfigurator.Configure();
102 string firstName = "testfirstname";
103
104 AgentCircuitData agent = new AgentCircuitData();
105 agent.AgentID = agent1;
106 agent.firstname = firstName;
107 agent.lastname = "testlastname";
108 agent.SessionID = UUID.Random();
109 agent.SecureSessionID = UUID.Random();
110 agent.circuitcode = 123;
111 agent.BaseFolder = UUID.Zero;
112 agent.InventoryFolder = UUID.Zero;
113 agent.startpos = Vector3.Zero;
114 agent.CapsPath = GetRandomCapsObjectPath();
115 agent.ChildrenCapSeeds = new Dictionary<ulong, string>();
116 agent.child = true;
117 101
118 scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID); 102 TestScene scene = SceneHelpers.SetupScene();
103 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
119 104
120 string reason; 105 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null);
121 scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason);
122 testclient = new TestClient(agent, scene);
123 scene.AddNewClient(testclient);
124 106
125 ScenePresence presence = scene.GetScenePresence(agent1); 107 scene.IncomingCloseAgent(sp.UUID);
126 108
127 Assert.That(presence, Is.Not.Null, "presence is null"); 109 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
128 Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same"); 110 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
129 acd1 = agent;
130 } 111 }
131 112
132 /// <summary> 113 /// <summary>
133 /// Test removing an uncrossed root agent from a scene. 114 /// Test that if a root agent logs into a region, a child agent is also established in the neighbouring region
134 /// </summary> 115 /// </summary>
116 /// <remarks>
117 /// Please note that unlike the other tests here, this doesn't rely on structures
118 /// </remarks>
135 [Test] 119 [Test]
136 public void T011_TestRemoveRootAgent() 120 public void TestChildAgentEstablished()
137 { 121 {
138 TestHelper.InMethod(); 122 TestHelpers.InMethod();
139 123// log4net.Config.XmlConfigurator.Configure();
140 scene.RemoveClient(agent1); 124
141 125 UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001");
142 ScenePresence presence = scene.GetScenePresence(agent1); 126
127 TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000);
128// TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000);
129
130 IConfigSource configSource = new IniConfigSource();
131 configSource.AddConfig("Modules").Set("EntityTransferModule", "BasicEntityTransferModule");
132 EntityTransferModule etm = new EntityTransferModule();
133
134 SceneHelpers.SetupSceneModules(myScene1, configSource, etm);
135
136 SceneHelpers.AddScenePresence(myScene1, agent1Id);
137// ScenePresence childPresence = myScene2.GetScenePresence(agent1);
143 138
144 Assert.That(presence, Is.Null, "presence is not null"); 139 // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents
140// Assert.That(childPresence, Is.Not.Null);
141// Assert.That(childPresence.IsChildAgent, Is.True);
145 } 142 }
146 143
144// /// <summary>
145// /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene.
146// /// </summary>
147// [Test]
148// public void T010_TestAddRootAgent()
149// {
150// TestHelpers.InMethod();
151//
152// string firstName = "testfirstname";
153//
154// AgentCircuitData agent = new AgentCircuitData();
155// agent.AgentID = agent1;
156// agent.firstname = firstName;
157// agent.lastname = "testlastname";
158// agent.SessionID = UUID.Random();
159// agent.SecureSessionID = UUID.Random();
160// agent.circuitcode = 123;
161// agent.BaseFolder = UUID.Zero;
162// agent.InventoryFolder = UUID.Zero;
163// agent.startpos = Vector3.Zero;
164// agent.CapsPath = GetRandomCapsObjectPath();
165// agent.ChildrenCapSeeds = new Dictionary<ulong, string>();
166// agent.child = true;
167//
168// scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID);
169//
170// string reason;
171// scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason);
172// testclient = new TestClient(agent, scene);
173// scene.AddNewClient(testclient);
174//
175// ScenePresence presence = scene.GetScenePresence(agent1);
176//
177// Assert.That(presence, Is.Not.Null, "presence is null");
178// Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same");
179// acd1 = agent;
180// }
181//
182// /// <summary>
183// /// Test removing an uncrossed root agent from a scene.
184// /// </summary>
185// [Test]
186// public void T011_TestRemoveRootAgent()
187// {
188// TestHelpers.InMethod();
189//
190// scene.RemoveClient(agent1);
191//
192// ScenePresence presence = scene.GetScenePresence(agent1);
193//
194// Assert.That(presence, Is.Null, "presence is not null");
195// }
196
147 [Test] 197 [Test]
148 public void T012_TestAddNeighbourRegion() 198 public void T012_TestAddNeighbourRegion()
149 { 199 {
150 TestHelper.InMethod(); 200 TestHelpers.InMethod();
151 201
152 string reason; 202 string reason;
153 203
@@ -157,7 +207,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
157 scene.NewUserConnection(acd1, 0, out reason); 207 scene.NewUserConnection(acd1, 0, out reason);
158 if (testclient == null) 208 if (testclient == null)
159 testclient = new TestClient(acd1, scene); 209 testclient = new TestClient(acd1, scene);
160 scene.AddNewClient(testclient); 210 scene.AddNewClient(testclient, PresenceType.User);
161 211
162 ScenePresence presence = scene.GetScenePresence(agent1); 212 ScenePresence presence = scene.GetScenePresence(agent1);
163 presence.MakeRootAgent(new Vector3(90,90,90),false); 213 presence.MakeRootAgent(new Vector3(90,90,90),false);
@@ -175,7 +225,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
175 [Test] 225 [Test]
176 public void T013_TestRemoveNeighbourRegion() 226 public void T013_TestRemoveNeighbourRegion()
177 { 227 {
178 TestHelper.InMethod(); 228 TestHelpers.InMethod();
179 229
180 ScenePresence presence = scene.GetScenePresence(agent1); 230 ScenePresence presence = scene.GetScenePresence(agent1);
181 presence.RemoveNeighbourRegion(region3); 231 presence.RemoveNeighbourRegion(region3);
@@ -188,37 +238,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
188 CompleteAvatarMovement 238 CompleteAvatarMovement
189 */ 239 */
190 } 240 }
191
192 /// <summary>
193 /// Test that if a root agent logs into a region, a child agent is also established in the neighbouring region
194 /// </summary>
195 /// <remarks>
196 /// Please note that unlike the other tests here, this doesn't rely on structures
197 /// </remarks>
198 [Test]
199 public void TestChildAgentEstablished()
200 {
201 TestHelper.InMethod();
202// log4net.Config.XmlConfigurator.Configure();
203
204 UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001");
205
206 TestScene myScene1 = SceneSetupHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000);
207 TestScene myScene2 = SceneSetupHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000);
208
209 IConfigSource configSource = new IniConfigSource();
210 configSource.AddConfig("Modules").Set("EntityTransferModule", "BasicEntityTransferModule");
211 EntityTransferModule etm = new EntityTransferModule();
212
213 SceneSetupHelpers.SetupSceneModules(myScene1, configSource, etm);
214
215 SceneSetupHelpers.AddRootAgent(myScene1, agent1Id);
216 ScenePresence childPresence = myScene2.GetScenePresence(agent1);
217
218 // TODO: Need to do a fair amount of work to allow synchronous establishment of child agents
219// Assert.That(childPresence, Is.Not.Null);
220// Assert.That(childPresence.IsChildAgent, Is.True);
221 }
222 241
223 // I'm commenting this test because it does not represent 242 // I'm commenting this test because it does not represent
224 // crossings. The Thread.Sleep's in here are not meaningful mocks, 243 // crossings. The Thread.Sleep's in here are not meaningful mocks,
@@ -230,7 +249,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
230 //[Test] 249 //[Test]
231 public void T021_TestCrossToNewRegion() 250 public void T021_TestCrossToNewRegion()
232 { 251 {
233 TestHelper.InMethod(); 252 TestHelpers.InMethod();
234 253
235 scene.RegisterRegionWithGrid(); 254 scene.RegisterRegionWithGrid();
236 scene2.RegisterRegionWithGrid(); 255 scene2.RegisterRegionWithGrid();
@@ -238,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
238 // Adding child agent to region 1001 257 // Adding child agent to region 1001
239 string reason; 258 string reason;
240 scene2.NewUserConnection(acd1,0, out reason); 259 scene2.NewUserConnection(acd1,0, out reason);
241 scene2.AddNewClient(testclient); 260 scene2.AddNewClient(testclient, PresenceType.User);
242 261
243 ScenePresence presence = scene.GetScenePresence(agent1); 262 ScenePresence presence = scene.GetScenePresence(agent1);
244 presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); 263 presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true);
@@ -338,6 +357,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
338 agent.InventoryFolder = UUID.Zero; 357 agent.InventoryFolder = UUID.Zero;
339 agent.startpos = Vector3.Zero; 358 agent.startpos = Vector3.Zero;
340 agent.CapsPath = GetRandomCapsObjectPath(); 359 agent.CapsPath = GetRandomCapsObjectPath();
360 agent.Appearance = new AvatarAppearance();
341 361
342 acd1 = agent; 362 acd1 = agent;
343 } 363 }
@@ -349,37 +369,5 @@ namespace OpenSim.Region.Framework.Scenes.Tests
349 capsPath = capsPath.Remove(capsPath.Length - 4, 4); 369 capsPath = capsPath.Remove(capsPath.Length - 4, 4);
350 return capsPath; 370 return capsPath;
351 } 371 }
352
353 private SceneObjectGroup NewSOG(UUID uuid, Scene scene, UUID agent)
354 {
355 SceneObjectPart sop = new SceneObjectPart();
356 sop.Name = RandomName();
357 sop.Description = RandomName();
358 sop.Text = RandomName();
359 sop.SitName = RandomName();
360 sop.TouchName = RandomName();
361 sop.UUID = uuid;
362 sop.Shape = PrimitiveBaseShape.Default;
363 sop.Shape.State = 1;
364 sop.OwnerID = agent;
365
366 SceneObjectGroup sog = new SceneObjectGroup(sop);
367 sog.SetScene(scene);
368
369 return sog;
370 }
371
372 private static string RandomName()
373 {
374 StringBuilder name = new StringBuilder();
375 int size = random.Next(5,12);
376 char ch ;
377 for (int i=0; i<size; i++)
378 {
379 ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ;
380 name.Append(ch);
381 }
382 return name.ToString();
383 }
384 } 372 }
385} \ No newline at end of file 373} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index 1b5a54e..39bb43a 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -44,7 +44,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
44 /// Teleport tests in a standalone OpenSim 44 /// Teleport tests in a standalone OpenSim
45 /// </summary> 45 /// </summary>
46 [TestFixture] 46 [TestFixture]
47 public class StandaloneTeleportTests 47 public class ScenePresenceTeleportTests
48 { 48 {
49 /// <summary> 49 /// <summary>
50 /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common. 50 /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common.
@@ -54,7 +54,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
54 //[Test, LongRunning] 54 //[Test, LongRunning]
55 public void TestSimpleNotNeighboursTeleport() 55 public void TestSimpleNotNeighboursTeleport()
56 { 56 {
57 TestHelper.InMethod(); 57 TestHelpers.InMethod();
58 ThreadRunResults results = new ThreadRunResults(); 58 ThreadRunResults results = new ThreadRunResults();
59 results.Result = false; 59 results.Result = false;
60 results.Message = "Test did not run"; 60 results.Message = "Test did not run";
@@ -116,16 +116,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests
116 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); 116 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule();
117 117
118 118
119 Scene sceneB = SceneSetupHelpers.SetupScene("sceneB", sceneBId, 1010, 1010); 119 Scene sceneB = SceneHelpers.SetupScene("sceneB", sceneBId, 1010, 1010);
120 SceneSetupHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); 120 SceneHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms);
121 sceneB.RegisterRegionWithGrid(); 121 sceneB.RegisterRegionWithGrid();
122 122
123 Scene sceneA = SceneSetupHelpers.SetupScene("sceneA", sceneAId, 1000, 1000); 123 Scene sceneA = SceneHelpers.SetupScene("sceneA", sceneAId, 1000, 1000);
124 SceneSetupHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); 124 SceneHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms);
125 sceneA.RegisterRegionWithGrid(); 125 sceneA.RegisterRegionWithGrid();
126 126
127 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041"); 127 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041");
128 TestClient client = SceneSetupHelpers.AddRootAgent(sceneA, agentId); 128 TestClient client = (TestClient)SceneHelpers.AddScenePresence(sceneA, agentId).ControllingClient;
129 129
130 ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface<ICapabilitiesModule>(); 130 ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface<ICapabilitiesModule>();
131 131
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 13d93f9..8b8aea5 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -58,9 +58,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
58 [Test] 58 [Test]
59 public void TestUpdateScene() 59 public void TestUpdateScene()
60 { 60 {
61 TestHelper.InMethod(); 61 TestHelpers.InMethod();
62 62
63 Scene scene = SceneSetupHelpers.SetupScene(); 63 Scene scene = SceneHelpers.SetupScene();
64 scene.Update(); 64 scene.Update();
65 65
66 Assert.That(scene.Frame, Is.EqualTo(1)); 66 Assert.That(scene.Frame, Is.EqualTo(1));
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
index f4e14d4..1abef8d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
@@ -55,12 +55,12 @@ namespace OpenSim.Region.Framework.Tests
55 [Test] 55 [Test]
56 public void TestRezObjectFromInventoryItem() 56 public void TestRezObjectFromInventoryItem()
57 { 57 {
58 TestHelper.InMethod(); 58 TestHelpers.InMethod();
59// log4net.Config.XmlConfigurator.Configure(); 59// log4net.Config.XmlConfigurator.Configure();
60 60
61 Scene scene = SceneSetupHelpers.SetupScene(); 61 Scene scene = SceneHelpers.SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
63 SceneObjectGroup sog1 = SceneSetupHelpers.CreateSceneObject(1, user1.PrincipalID); 63 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
64 SceneObjectPart sop1 = sog1.RootPart; 64 SceneObjectPart sop1 = sog1.RootPart;
65 65
66 // Create an object embedded inside the first 66 // Create an object embedded inside the first
@@ -98,12 +98,12 @@ namespace OpenSim.Region.Framework.Tests
98 [Test] 98 [Test]
99 public void TestMoveTaskInventoryItem() 99 public void TestMoveTaskInventoryItem()
100 { 100 {
101 TestHelper.InMethod(); 101 TestHelpers.InMethod();
102// log4net.Config.XmlConfigurator.Configure(); 102// log4net.Config.XmlConfigurator.Configure();
103 103
104 Scene scene = SceneSetupHelpers.SetupScene(); 104 Scene scene = SceneHelpers.SetupScene();
105 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 105 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
106 SceneObjectGroup sog1 = SceneSetupHelpers.CreateSceneObject(1, user1.PrincipalID); 106 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
107 SceneObjectPart sop1 = sog1.RootPart; 107 SceneObjectPart sop1 = sog1.RootPart;
108 TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1); 108 TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1);
109 109
@@ -125,12 +125,12 @@ namespace OpenSim.Region.Framework.Tests
125 [Test] 125 [Test]
126 public void TestMoveTaskInventoryItemNoParent() 126 public void TestMoveTaskInventoryItemNoParent()
127 { 127 {
128 TestHelper.InMethod(); 128 TestHelpers.InMethod();
129// log4net.Config.XmlConfigurator.Configure(); 129// log4net.Config.XmlConfigurator.Configure();
130 130
131 Scene scene = SceneSetupHelpers.SetupScene(); 131 Scene scene = SceneHelpers.SetupScene();
132 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 132 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
133 SceneObjectGroup sog1 = SceneSetupHelpers.CreateSceneObject(1, user1.PrincipalID); 133 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
134 SceneObjectPart sop1 = sog1.RootPart; 134 SceneObjectPart sop1 = sog1.RootPart;
135 TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1); 135 TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1);
136 136
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index abca792..55fc1e7 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -55,12 +55,12 @@ namespace OpenSim.Region.Framework.Tests
55 [Test] 55 [Test]
56 public void TestGiveInventoryItem() 56 public void TestGiveInventoryItem()
57 { 57 {
58 TestHelper.InMethod(); 58 TestHelpers.InMethod();
59// log4net.Config.XmlConfigurator.Configure(); 59// log4net.Config.XmlConfigurator.Configure();
60 60
61 Scene scene = SceneSetupHelpers.SetupScene(); 61 Scene scene = SceneHelpers.SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); 62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); 63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002));
64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); 64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID);
65 65
66 scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID); 66 scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID);
@@ -82,12 +82,12 @@ namespace OpenSim.Region.Framework.Tests
82 [Test] 82 [Test]
83 public void TestGiveInventoryFolder() 83 public void TestGiveInventoryFolder()
84 { 84 {
85 TestHelper.InMethod(); 85 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure(); 86// log4net.Config.XmlConfigurator.Configure();
87 87
88 Scene scene = SceneSetupHelpers.SetupScene(); 88 Scene scene = SceneHelpers.SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); 89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); 90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002));
91 InventoryFolderBase folder1 91 InventoryFolderBase folder1
92 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1"); 92 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1");
93 93
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
index 4da8df1..24de56e 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
47 public void Init() 47 public void Init()
48 { 48 {
49 // FIXME: We don't need a full scene here - it would be enough to set up the asset service. 49 // FIXME: We don't need a full scene here - it would be enough to set up the asset service.
50 Scene scene = SceneSetupHelpers.SetupScene(); 50 Scene scene = SceneHelpers.SetupScene();
51 m_assetService = scene.AssetService; 51 m_assetService = scene.AssetService;
52 m_uuidGatherer = new UuidGatherer(m_assetService); 52 m_uuidGatherer = new UuidGatherer(m_assetService);
53 } 53 }
@@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
55 [Test] 55 [Test]
56 public void TestCorruptAsset() 56 public void TestCorruptAsset()
57 { 57 {
58 TestHelper.InMethod(); 58 TestHelpers.InMethod();
59 59
60 UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); 60 UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
61 AssetBase corruptAsset 61 AssetBase corruptAsset
@@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
75 [Test] 75 [Test]
76 public void TestMissingAsset() 76 public void TestMissingAsset()
77 { 77 {
78 TestHelper.InMethod(); 78 TestHelpers.InMethod();
79 79
80 UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); 80 UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
81 IDictionary<UUID, AssetType> foundAssetUuids = new Dictionary<UUID, AssetType>(); 81 IDictionary<UUID, AssetType> foundAssetUuids = new Dictionary<UUID, AssetType>();
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index f71b507..0a30f4b 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -25,6 +25,9 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
29using System.Reflection;
30using log4net;
28using OpenMetaverse; 31using OpenMetaverse;
29using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
30using System; 33using System;
@@ -47,180 +50,199 @@ namespace OpenSim.Region.Framework.Scenes
47 50
48 public class UndoState 51 public class UndoState
49 { 52 {
53 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
50 public Vector3 Position = Vector3.Zero; 55 public Vector3 Position = Vector3.Zero;
51 public Vector3 Scale = Vector3.Zero; 56 public Vector3 Scale = Vector3.Zero;
52 public Quaternion Rotation = Quaternion.Identity; 57 public Quaternion Rotation = Quaternion.Identity;
53 public Vector3 GroupPosition = Vector3.Zero;
54 public Quaternion GroupRotation = Quaternion.Identity;
55 public Vector3 GroupScale = Vector3.Zero;
56 public DateTime LastUpdated = DateTime.Now;
57 public UndoType Type;
58 58
59 public UndoState(SceneObjectPart part, UndoType type) 59 /// <summary>
60 { 60 /// Is this undo state for an entire group?
61 Type = type; 61 /// </summary>
62 if (part != null) 62 public bool ForGroup;
63 { 63
64 if (part.ParentID == 0) 64 /// <summary>
65 { 65 /// Constructor.
66 GroupScale = part.ParentGroup.RootPart.Shape.Scale; 66 /// </summary>
67 67 /// <param name="part"></param>
68 //FUBAR WARNING: Do NOT get the group's absoluteposition here 68 /// <param name="forGroup">True if the undo is for an entire group</param>
69 //or you'll experience a loop and/or a stack issue 69 public UndoState(SceneObjectPart part, bool forGroup)
70 GroupPosition = part.ParentGroup.RootPart.AbsolutePosition;
71 GroupRotation = part.ParentGroup.GroupRotation;
72 Position = part.ParentGroup.RootPart.AbsolutePosition;
73 Rotation = part.RotationOffset;
74 Scale = part.Shape.Scale;
75 LastUpdated = DateTime.Now;
76 }
77 else
78 {
79 GroupScale = part.Shape.Scale;
80
81 //FUBAR WARNING: Do NOT get the group's absoluteposition here
82 //or you'll experience a loop and/or a stack issue
83 GroupPosition = part.ParentGroup.RootPart.AbsolutePosition;
84 GroupRotation = part.ParentGroup.Rotation;
85 Position = part.OffsetPosition;
86 Rotation = part.RotationOffset;
87 Scale = part.Shape.Scale;
88 LastUpdated = DateTime.Now;
89 }
90 }
91 }
92 public void Merge(UndoState last)
93 {
94 if ((Type & UndoType.STATE_GROUP_POSITION) == 0 || ((last.Type & UndoType.STATE_GROUP_POSITION) >= (Type & UndoType.STATE_GROUP_POSITION)))
95 {
96 GroupPosition = last.GroupPosition;
97 Position = last.Position;
98 }
99 if ((Type & UndoType.STATE_GROUP_SCALE) == 0 || ((last.Type & UndoType.STATE_GROUP_SCALE) >= (Type & UndoType.STATE_GROUP_SCALE)))
100 {
101 GroupScale = last.GroupScale;
102 Scale = last.Scale;
103 }
104 if ((Type & UndoType.STATE_GROUP_ROTATION) == 0 || ((last.Type & UndoType.STATE_GROUP_ROTATION) >= (Type & UndoType.STATE_GROUP_ROTATION)))
105 {
106 GroupRotation = last.GroupRotation;
107 Rotation = last.Rotation;
108 }
109 if ((Type & UndoType.STATE_PRIM_POSITION) == 0 || ((last.Type & UndoType.STATE_PRIM_POSITION) >= (Type & UndoType.STATE_PRIM_POSITION)))
110 {
111 Position = last.Position;
112 }
113 if ((Type & UndoType.STATE_PRIM_SCALE) == 0 || ((last.Type & UndoType.STATE_PRIM_SCALE) >= (Type & UndoType.STATE_PRIM_SCALE)))
114 {
115 Scale = last.Scale;
116 }
117 if ((Type & UndoType.STATE_PRIM_ROTATION) == 0 || ((last.Type & UndoType.STATE_PRIM_ROTATION) >= (Type & UndoType.STATE_PRIM_ROTATION)))
118 {
119 Rotation = last.Rotation;
120 }
121 Type = Type | last.Type;
122 }
123 public bool Compare(UndoState undo)
124 { 70 {
125 if (undo == null || Position == null) return false; 71 if (part.ParentID == 0)
126 if (undo.Position == Position && undo.Rotation == Rotation && undo.Scale == Scale && undo.GroupPosition == GroupPosition && undo.GroupScale == GroupScale && undo.GroupRotation == GroupRotation)
127 { 72 {
128 return true; 73 ForGroup = forGroup;
74
75 // if (ForGroup)
76 Position = part.ParentGroup.AbsolutePosition;
77 // else
78 // Position = part.OffsetPosition;
79
80 // m_log.DebugFormat(
81 // "[UNDO STATE]: Storing undo position {0} for root part", Position);
82
83 Rotation = part.RotationOffset;
84
85 // m_log.DebugFormat(
86 // "[UNDO STATE]: Storing undo rotation {0} for root part", Rotation);
87
88 Scale = part.Shape.Scale;
89
90 // m_log.DebugFormat(
91 // "[UNDO STATE]: Storing undo scale {0} for root part", Scale);
129 } 92 }
130 else 93 else
131 { 94 {
132 return false; 95 Position = part.OffsetPosition;
96 // m_log.DebugFormat(
97 // "[UNDO STATE]: Storing undo position {0} for child part", Position);
98
99 Rotation = part.RotationOffset;
100 // m_log.DebugFormat(
101 // "[UNDO STATE]: Storing undo rotation {0} for child part", Rotation);
102
103 Scale = part.Shape.Scale;
104 // m_log.DebugFormat(
105 // "[UNDO STATE]: Storing undo scale {0} for child part", Scale);
133 } 106 }
134 } 107 }
108
109 /// <summary>
110 /// Compare the relevant state in the given part to this state.
111 /// </summary>
112 /// <param name="part"></param>
113 /// <returns>true if both the part's position, rotation and scale match those in this undo state. False otherwise.</returns>
135 public bool Compare(SceneObjectPart part) 114 public bool Compare(SceneObjectPart part)
136 { 115 {
137 if (part != null) 116 if (part != null)
138 { 117 {
139 if (part.ParentID == 0) 118 if (part.ParentID == 0)
119 return
120 Position == part.ParentGroup.AbsolutePosition
121 && Rotation == part.RotationOffset
122 && Scale == part.Shape.Scale;
123 else
124 return
125 Position == part.OffsetPosition
126 && Rotation == part.RotationOffset
127 && Scale == part.Shape.Scale;
128 }
129
130 return false;
131 }
132
133 public void PlaybackState(SceneObjectPart part)
134 {
135 part.Undoing = true;
136
137 if (part.ParentID == 0)
138 {
139 // m_log.DebugFormat(
140 // "[UNDO STATE]: Undoing position to {0} for root part {1} {2}",
141 // Position, part.Name, part.LocalId);
142
143 if (Position != Vector3.Zero)
140 { 144 {
141 if (Position == part.ParentGroup.RootPart.AbsolutePosition && Rotation == part.ParentGroup.Rotation && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale) 145 if (ForGroup)
142 return true; 146 part.ParentGroup.AbsolutePosition = Position;
143 else 147 else
144 return false; 148 part.ParentGroup.UpdateRootPosition(Position);
145 } 149 }
150
151 // m_log.DebugFormat(
152 // "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}",
153 // part.RotationOffset, Rotation, part.Name, part.LocalId);
154
155 if (ForGroup)
156 part.UpdateRotation(Rotation);
146 else 157 else
158 part.ParentGroup.UpdateRootRotation(Rotation);
159
160 if (Scale != Vector3.Zero)
147 { 161 {
148 if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale) 162 // m_log.DebugFormat(
149 return true; 163 // "[UNDO STATE]: Undoing scale {0} to {1} for root part {2} {3}",
164 // part.Shape.Scale, Scale, part.Name, part.LocalId);
165
166 if (ForGroup)
167 part.ParentGroup.GroupResize(Scale);
150 else 168 else
151 return false; 169 part.Resize(Scale);
170 }
171
172 part.ParentGroup.ScheduleGroupForTerseUpdate();
173 }
174 else
175 {
176 if (Position != Vector3.Zero)
177 {
178 // m_log.DebugFormat(
179 // "[UNDO STATE]: Undoing position {0} to {1} for child part {2} {3}",
180 // part.OffsetPosition, Position, part.Name, part.LocalId);
152 181
182 part.OffsetPosition = Position;
153 } 183 }
184
185 // m_log.DebugFormat(
186 // "[UNDO STATE]: Undoing rotation {0} to {1} for child part {2} {3}",
187 // part.RotationOffset, Rotation, part.Name, part.LocalId);
188
189 part.UpdateRotation(Rotation);
190
191 if (Scale != Vector3.Zero)
192 {
193 // m_log.DebugFormat(
194 // "[UNDO STATE]: Undoing scale {0} to {1} for child part {2} {3}",
195 // part.Shape.Scale, Scale, part.Name, part.LocalId);
196
197 part.Resize(Scale);
198 }
199
200 part.ScheduleTerseUpdate();
154 } 201 }
155 return false; 202
203 part.Undoing = false;
156 } 204 }
157 205
158 private void RestoreState(SceneObjectPart part) 206 public void PlayfwdState(SceneObjectPart part)
159 { 207 {
160 bool GroupChange = false; 208 part.Undoing = true;
161 if ((Type & UndoType.STATE_GROUP_POSITION) != 0
162 || (Type & UndoType.STATE_GROUP_ROTATION) != 0
163 || (Type & UndoType.STATE_GROUP_SCALE) != 0)
164 {
165 GroupChange = true;
166 }
167 209
168 if (part != null) 210 if (part.ParentID == 0)
169 { 211 {
170 part.Undoing = true; 212 if (Position != Vector3.Zero)
213 part.ParentGroup.AbsolutePosition = Position;
171 214
172 if (part.ParentID == 0 && GroupChange == false) 215 if (Rotation != Quaternion.Identity)
173 { 216 part.UpdateRotation(Rotation);
174 if (Position != Vector3.Zero)
175 217
176 part.ParentGroup.UpdateSinglePosition(Position, part.LocalId); 218 if (Scale != Vector3.Zero)
177 part.ParentGroup.UpdateSingleRotation(Rotation, part.LocalId);
178 if (Scale != Vector3.Zero)
179 part.Resize(Scale);
180 part.ParentGroup.ScheduleGroupForTerseUpdate();
181 }
182 else
183 { 219 {
184 if (GroupChange) 220 if (ForGroup)
185 { 221 part.ParentGroup.GroupResize(Scale);
186 part.ParentGroup.RootPart.Undoing = true;
187 if (GroupPosition != Vector3.Zero)
188 {
189 //Calculate the scale...
190 Vector3 gs = part.Shape.Scale;
191 float scale = GroupScale.Z / gs.Z;
192
193 //Scale first since it can affect our position
194 part.ParentGroup.GroupResize(gs * scale, part.LocalId);
195 part.ParentGroup.AbsolutePosition = GroupPosition;
196 part.ParentGroup.UpdateGroupRotationR(GroupRotation);
197
198 }
199 part.ParentGroup.RootPart.Undoing = false;
200 }
201 else 222 else
202 { 223 part.Resize(Scale);
203 if (Position != Vector3.Zero) //We can use this for all the updates since all are set
204 {
205 part.OffsetPosition = Position;
206 part.UpdateRotation(Rotation);
207 part.Resize(Scale); part.ScheduleTerseUpdate();
208 }
209 }
210 } 224 }
211 part.Undoing = false;
212 225
226 part.ParentGroup.ScheduleGroupForTerseUpdate();
213 } 227 }
214 } 228 else
215 public void PlaybackState(SceneObjectPart part) 229 {
216 { 230 if (Position != Vector3.Zero)
217 RestoreState(part); 231 part.OffsetPosition = Position;
218 } 232
219 public void PlayfwdState(SceneObjectPart part) 233 if (Rotation != Quaternion.Identity)
220 { 234 part.UpdateRotation(Rotation);
221 RestoreState(part); 235
236 if (Scale != Vector3.Zero)
237 part.Resize(Scale);
238
239 part.ScheduleTerseUpdate();
240 }
241
242 part.Undoing = false;
222 } 243 }
223 } 244 }
245
224 public class LandUndoState 246 public class LandUndoState
225 { 247 {
226 public ITerrainModule m_terrainModule; 248 public ITerrainModule m_terrainModule;
@@ -234,10 +256,7 @@ namespace OpenSim.Region.Framework.Scenes
234 256
235 public bool Compare(ITerrainChannel terrainChannel) 257 public bool Compare(ITerrainChannel terrainChannel)
236 { 258 {
237 if (m_terrainChannel != terrainChannel) 259 return m_terrainChannel == terrainChannel;
238 return false;
239 else
240 return false;
241 } 260 }
242 261
243 public void PlaybackState() 262 public void PlaybackState()
@@ -246,4 +265,3 @@ namespace OpenSim.Region.Framework.Scenes
246 } 265 }
247 } 266 }
248} 267}
249
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index fdfbc78..8d41f00 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -43,11 +43,12 @@ namespace OpenSim.Region.Framework.Scenes
43 /// <summary> 43 /// <summary>
44 /// Gather uuids for a given entity. 44 /// Gather uuids for a given entity.
45 /// </summary> 45 /// </summary>
46 /// 46 /// <remarks>
47 /// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts 47 /// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts
48 /// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets 48 /// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets
49 /// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be 49 /// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be
50 /// retrieved to work out which assets it references). 50 /// retrieved to work out which assets it references).
51 /// </remarks>
51 public class UuidGatherer 52 public class UuidGatherer
52 { 53 {
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -76,11 +77,11 @@ namespace OpenSim.Region.Framework.Scenes
76 /// <summary> 77 /// <summary>
77 /// Gather all the asset uuids associated with the asset referenced by a given uuid 78 /// Gather all the asset uuids associated with the asset referenced by a given uuid
78 /// </summary> 79 /// </summary>
79 /// 80 /// <remarks>
80 /// This includes both those directly associated with 81 /// This includes both those directly associated with
81 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained 82 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
82 /// within this object). 83 /// within this object).
83 /// 84 /// </remarks>
84 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> 85 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
85 /// <param name="assetType">The type of the asset for the uuid given</param> 86 /// <param name="assetType">The type of the asset for the uuid given</param>
86 /// <param name="assetUuids">The assets gathered</param> 87 /// <param name="assetUuids">The assets gathered</param>
@@ -119,11 +120,11 @@ namespace OpenSim.Region.Framework.Scenes
119 /// <summary> 120 /// <summary>
120 /// Gather all the asset uuids associated with a given object. 121 /// Gather all the asset uuids associated with a given object.
121 /// </summary> 122 /// </summary>
122 /// 123 /// <remarks>
123 /// This includes both those directly associated with 124 /// This includes both those directly associated with
124 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained 125 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
125 /// within this object). 126 /// within this object).
126 /// 127 /// </remarks>
127 /// <param name="sceneObject">The scene object for which to gather assets</param> 128 /// <param name="sceneObject">The scene object for which to gather assets</param>
128 /// <param name="assetUuids">The assets gathered</param> 129 /// <param name="assetUuids">The assets gathered</param>
129 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids) 130 public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, AssetType> assetUuids)