aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Scenes/Prioritizer.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs199
5 files changed, 119 insertions, 133 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
index ef78f0f..0f35894 100644
--- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs
+++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
@@ -167,18 +167,20 @@ namespace OpenSim.Region.Framework.Scenes
167 { 167 {
168 if (!presence.IsChildAgent) 168 if (!presence.IsChildAgent)
169 { 169 {
170 // All avatars other than our own go into pqueue 1
171 if (entity is ScenePresence)
172 return 1;
173
170 if (entity is SceneObjectPart) 174 if (entity is SceneObjectPart)
171 { 175 {
176 // Attachments are high priority,
177 if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment)
178 return 1;
179
172 // Non physical prims are lower priority than physical prims 180 // Non physical prims are lower priority than physical prims
173 PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; 181 PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
174 if (physActor == null || !physActor.IsPhysical) 182 if (physActor == null || !physActor.IsPhysical)
175 pqueue++; 183 pqueue++;
176
177 // Attachments are high priority,
178 // MIC: shouldn't these already be in the highest priority queue already
179 // since their root position is same as the avatars?
180 if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment)
181 pqueue = 1;
182 } 184 }
183 } 185 }
184 } 186 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index f41c6b9..5b7a297 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1449,6 +1449,10 @@ namespace OpenSim.Region.Framework.Scenes
1449 } 1449 }
1450 else // Updating existing item with new perms etc 1450 else // Updating existing item with new perms etc
1451 { 1451 {
1452// m_log.DebugFormat(
1453// "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()",
1454// currentItem.Name, part.Name);
1455
1452 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); 1456 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
1453 if (agentTransactions != null) 1457 if (agentTransactions != null)
1454 { 1458 {
@@ -2089,6 +2093,12 @@ namespace OpenSim.Region.Framework.Scenes
2089 if (rot != null) 2093 if (rot != null)
2090 group.UpdateGroupRotationR((Quaternion)rot); 2094 group.UpdateGroupRotationR((Quaternion)rot);
2091 2095
2096 // TODO: This needs to be refactored with the similar code in
2097 // SceneGraph.AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel)
2098 // possibly by allowing this method to take a null rotation.
2099 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero)
2100 group.RootPart.ApplyImpulse((vel * group.GetMass()), false);
2101
2092 // We can only call this after adding the scene object, since the scene object references the scene 2102 // We can only call this after adding the scene object, since the scene object references the scene
2093 // to find out if scripts should be activated at all. 2103 // to find out if scripts should be activated at all.
2094 group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); 2104 group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 4d619c3..1d06889 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1255,7 +1255,6 @@ namespace OpenSim.Region.Framework.Scenes
1255 1255
1256 // Increment the frame counter 1256 // Increment the frame counter
1257 ++Frame; 1257 ++Frame;
1258
1259 try 1258 try
1260 { 1259 {
1261 // Check if any objects have reached their targets 1260 // Check if any objects have reached their targets
@@ -2383,7 +2382,9 @@ namespace OpenSim.Region.Framework.Scenes
2383 /// <returns></returns> 2382 /// <returns></returns>
2384 public bool IncomingCreateObject(ISceneObject sog) 2383 public bool IncomingCreateObject(ISceneObject sog)
2385 { 2384 {
2386 //m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); 2385 //m_log.DebugFormat(" >>> IncomingCreateObject(sog) <<< {0} deleted? {1} isAttach? {2}", ((SceneObjectGroup)sog).AbsolutePosition,
2386 // ((SceneObjectGroup)sog).IsDeleted, ((SceneObjectGroup)sog).RootPart.IsAttachment);
2387
2387 SceneObjectGroup newObject; 2388 SceneObjectGroup newObject;
2388 try 2389 try
2389 { 2390 {
@@ -2401,9 +2402,13 @@ namespace OpenSim.Region.Framework.Scenes
2401 return false; 2402 return false;
2402 } 2403 }
2403 2404
2404 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); 2405 // For attachments, we need to wait until the agent is root
2405 2406 // before we restart the scripts, or else some functions won't work.
2406 newObject.ResumeScripts(); 2407 if (!newObject.IsAttachment)
2408 {
2409 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
2410 newObject.ResumeScripts();
2411 }
2407 2412
2408 // Do this as late as possible so that listeners have full access to the incoming object 2413 // Do this as late as possible so that listeners have full access to the incoming object
2409 EventManager.TriggerOnIncomingSceneObject(newObject); 2414 EventManager.TriggerOnIncomingSceneObject(newObject);
@@ -2540,17 +2545,8 @@ namespace OpenSim.Region.Framework.Scenes
2540 ScenePresence sp = GetScenePresence(sog.OwnerID); 2545 ScenePresence sp = GetScenePresence(sog.OwnerID);
2541 2546
2542 if (sp != null) 2547 if (sp != null)
2543 { 2548 return sp.GetStateSource();
2544 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(sp.UUID);
2545
2546 if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default))
2547 {
2548 // This will get your attention
2549 //m_log.Error("[XXX] Triggering CHANGED_TELEPORT");
2550 2549
2551 return 5; // StateSource.Teleporting
2552 }
2553 }
2554 return 2; // StateSource.PrimCrossing 2550 return 2; // StateSource.PrimCrossing
2555 } 2551 }
2556 2552
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 1992956..d135f16 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -881,6 +881,8 @@ namespace OpenSim.Region.Framework.Scenes
881 881
882 if (m_items.ContainsKey(item.ItemID)) 882 if (m_items.ContainsKey(item.ItemID))
883 { 883 {
884// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name);
885
884 item.ParentID = m_part.UUID; 886 item.ParentID = m_part.UUID;
885 item.ParentPartID = m_part.UUID; 887 item.ParentPartID = m_part.UUID;
886 888
@@ -896,6 +898,7 @@ namespace OpenSim.Region.Framework.Scenes
896 m_inventorySerial++; 898 m_inventorySerial++;
897 if (fireScriptEvents) 899 if (fireScriptEvents)
898 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 900 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
901
899 if (considerChanged) 902 if (considerChanged)
900 { 903 {
901 HasInventoryChanged = true; 904 HasInventoryChanged = true;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index e551a2e..cdf8366 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -924,6 +924,9 @@ namespace OpenSim.Region.Framework.Scenes
924 924
925 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 925 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
926 926
927 bool wasChild = m_isChildAgent;
928 m_isChildAgent = false;
929
927 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); 930 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
928 if (gm != null) 931 if (gm != null)
929 m_grouptitle = gm.GetGroupTitle(m_uuid); 932 m_grouptitle = gm.GetGroupTitle(m_uuid);
@@ -1069,14 +1072,21 @@ namespace OpenSim.Region.Framework.Scenes
1069 // Animator.SendAnimPack(); 1072 // Animator.SendAnimPack();
1070 1073
1071 m_scene.SwapRootAgentCount(false); 1074 m_scene.SwapRootAgentCount(false);
1072 1075
1073 //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); 1076 // The initial login scene presence is already root when it gets here
1074 //if (userInfo != null) 1077 // and it has already rezzed the attachments and started their scripts.
1075 // userInfo.FetchInventory(); 1078 // We do the following only for non-login agents, because their scripts
1076 //else 1079 // haven't started yet.
1077 // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); 1080 if (wasChild)
1078 1081 {
1079 m_isChildAgent = false; 1082 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
1083 // Resume scripts
1084 Attachments.ForEach(delegate(SceneObjectGroup sog)
1085 {
1086 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1087 sog.ResumeScripts();
1088 });
1089 }
1080 1090
1081 // send the animations of the other presences to me 1091 // send the animations of the other presences to me
1082 m_scene.ForEachScenePresence(delegate(ScenePresence presence) 1092 m_scene.ForEachScenePresence(delegate(ScenePresence presence)
@@ -1088,6 +1098,20 @@ namespace OpenSim.Region.Framework.Scenes
1088 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1098 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1089 } 1099 }
1090 1100
1101 public int GetStateSource()
1102 {
1103 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID);
1104
1105 if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default))
1106 {
1107 // This will get your attention
1108 //m_log.Error("[XXX] Triggering CHANGED_TELEPORT");
1109
1110 return 5; // StateSource.Teleporting
1111 }
1112 return 2; // StateSource.PrimCrossing
1113 }
1114
1091 /// <summary> 1115 /// <summary>
1092 /// This turns a root agent into a child agent 1116 /// This turns a root agent into a child agent
1093 /// when an agent departs this region for a neighbor, this gets called. 1117 /// when an agent departs this region for a neighbor, this gets called.
@@ -1288,7 +1312,6 @@ namespace OpenSim.Region.Framework.Scenes
1288 AbsolutePosition = pos; 1312 AbsolutePosition = pos;
1289 } 1313 }
1290 1314
1291 m_isChildAgent = false;
1292 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1315 bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1293 MakeRootAgent(AbsolutePosition, m_flying); 1316 MakeRootAgent(AbsolutePosition, m_flying);
1294 1317
@@ -2757,12 +2780,14 @@ namespace OpenSim.Region.Framework.Scenes
2757 2780
2758 #region Update Client(s) 2781 #region Update Client(s)
2759 2782
2783
2760 /// <summary> 2784 /// <summary>
2761 /// Sends a location update to the client connected to this scenePresence 2785 /// Sends a location update to the client connected to this scenePresence
2762 /// </summary> 2786 /// </summary>
2763 /// <param name="remoteClient"></param> 2787 /// <param name="remoteClient"></param>
2764 public void SendTerseUpdateToClient(IClientAPI remoteClient) 2788 public void SendTerseUpdateToClient(IClientAPI remoteClient)
2765 { 2789 {
2790
2766 // If the client is inactive, it's getting its updates from another 2791 // If the client is inactive, it's getting its updates from another
2767 // server. 2792 // server.
2768 if (remoteClient.IsActive) 2793 if (remoteClient.IsActive)
@@ -2775,8 +2800,8 @@ namespace OpenSim.Region.Framework.Scenes
2775 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); 2800 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity);
2776 2801
2777 remoteClient.SendPrimUpdate( 2802 remoteClient.SendPrimUpdate(
2778 this, 2803 this,
2779 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity 2804 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
2780 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); 2805 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
2781 2806
2782 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2807 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
@@ -2784,16 +2809,31 @@ namespace OpenSim.Region.Framework.Scenes
2784 } 2809 }
2785 } 2810 }
2786 2811
2812
2813 // vars to support reduced update frequency when velocity is unchanged
2814 private Vector3 lastVelocitySentToAllClients = Vector3.Zero;
2815 private int lastTerseUpdateToAllClientsTick = Util.EnvironmentTickCount();
2816
2787 /// <summary> 2817 /// <summary>
2788 /// Send a location/velocity/accelleration update to all agents in scene 2818 /// Send a location/velocity/accelleration update to all agents in scene
2789 /// </summary> 2819 /// </summary>
2790 public void SendTerseUpdateToAllClients() 2820 public void SendTerseUpdateToAllClients()
2791 { 2821 {
2792 m_perfMonMS = Util.EnvironmentTickCount(); 2822 int currentTick = Util.EnvironmentTickCount();
2793
2794 m_scene.ForEachClient(SendTerseUpdateToClient);
2795 2823
2796 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2824 // decrease update frequency when avatar is moving but velocity is not changing
2825 if (m_velocity.Length() < 0.01f
2826 || Vector3.Distance(lastVelocitySentToAllClients, m_velocity) > 0.01f
2827 || currentTick - lastTerseUpdateToAllClientsTick > 1500)
2828 {
2829 m_perfMonMS = currentTick;
2830 lastVelocitySentToAllClients = m_velocity;
2831 lastTerseUpdateToAllClientsTick = currentTick;
2832
2833 m_scene.ForEachClient(SendTerseUpdateToClient);
2834
2835 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2836 }
2797 } 2837 }
2798 2838
2799 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2839 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
@@ -3478,54 +3518,6 @@ namespace OpenSim.Region.Framework.Scenes
3478 3518
3479 cAgent.Appearance = new AvatarAppearance(m_appearance); 3519 cAgent.Appearance = new AvatarAppearance(m_appearance);
3480 3520
3481/*
3482 try
3483 {
3484 // We might not pass the Wearables in all cases...
3485 // They're only needed so that persistent changes to the appearance
3486 // are preserved in the new region where the user is moving to.
3487 // But in Hypergrid we might not let this happen.
3488 int i = 0;
3489 UUID[] wears = new UUID[m_appearance.Wearables.Length * 2];
3490 foreach (AvatarWearable aw in m_appearance.Wearables)
3491 {
3492 if (aw != null)
3493 {
3494 wears[i++] = aw.ItemID;
3495 wears[i++] = aw.AssetID;
3496 }
3497 else
3498 {
3499 wears[i++] = UUID.Zero;
3500 wears[i++] = UUID.Zero;
3501 }
3502 }
3503 cAgent.Wearables = wears;
3504
3505 cAgent.VisualParams = m_appearance.VisualParams;
3506
3507 if (m_appearance.Texture != null)
3508 cAgent.AgentTextures = m_appearance.Texture.GetBytes();
3509 }
3510 catch (Exception e)
3511 {
3512 m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message);
3513 }
3514
3515 //Attachments
3516 List<int> attPoints = m_appearance.GetAttachedPoints();
3517 if (attPoints != null)
3518 {
3519 //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count);
3520 int i = 0;
3521 AvatarAttachment[] attachs = new AvatarAttachment[attPoints.Count];
3522 foreach (int point in attPoints)
3523 {
3524 attachs[i++] = new AvatarAttachment(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point));
3525 }
3526 cAgent.Attachments = attachs;
3527 }
3528*/
3529 lock (scriptedcontrols) 3521 lock (scriptedcontrols)
3530 { 3522 {
3531 ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; 3523 ControllerData[] controls = new ControllerData[scriptedcontrols.Count];
@@ -3545,9 +3537,26 @@ namespace OpenSim.Region.Framework.Scenes
3545 } 3537 }
3546 catch { } 3538 catch { }
3547 3539
3548 // cAgent.GroupID = ?? 3540 // Attachment objects
3549 // Groups??? 3541 if (m_attachments != null && m_attachments.Count > 0)
3550 3542 {
3543 cAgent.AttachmentObjects = new List<ISceneObject>();
3544 cAgent.AttachmentObjectStates = new List<string>();
3545 IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
3546 foreach (SceneObjectGroup sog in m_attachments)
3547 {
3548 // We need to make a copy and pass that copy
3549 // because of transfers withn the same sim
3550 ISceneObject clone = sog.CloneForNewScene();
3551 // Attachment module assumes that GroupPosition holds the offsets...!
3552 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
3553 ((SceneObjectGroup)clone).RootPart.IsAttachment = false;
3554 cAgent.AttachmentObjects.Add(clone);
3555 cAgent.AttachmentObjectStates.Add(sog.GetStateSnapshot());
3556 // Let's remove the scripts of the original object here
3557 sog.RemoveScriptInstances(true);
3558 }
3559 }
3551 } 3560 }
3552 3561
3553 public void CopyFrom(AgentData cAgent) 3562 public void CopyFrom(AgentData cAgent)
@@ -3589,50 +3598,6 @@ namespace OpenSim.Region.Framework.Scenes
3589 AddToPhysicalScene(isFlying); 3598 AddToPhysicalScene(isFlying);
3590 } 3599 }
3591 3600
3592/*
3593 uint i = 0;
3594 try
3595 {
3596 if (cAgent.Wearables == null)
3597 cAgent.Wearables = new UUID[0];
3598 AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2];
3599 for (uint n = 0; n < cAgent.Wearables.Length; n += 2)
3600 {
3601 UUID itemId = cAgent.Wearables[n];
3602 UUID assetId = cAgent.Wearables[n + 1];
3603 wears[i++] = new AvatarWearable(itemId, assetId);
3604 }
3605 // m_appearance.Wearables = wears;
3606 Primitive.TextureEntry textures = null;
3607 if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1)
3608 textures = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length);
3609
3610 byte[] visuals = null;
3611
3612 if ((cAgent.VisualParams != null) && (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT))
3613 visuals = (byte[])cAgent.VisualParams.Clone();
3614
3615 m_appearance = new AvatarAppearance(cAgent.AgentID,wears,textures,visuals);
3616 }
3617 catch (Exception e)
3618 {
3619 m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message);
3620 }
3621
3622 // Attachments
3623 try
3624 {
3625 if (cAgent.Attachments != null)
3626 {
3627 m_appearance.ClearAttachments();
3628 foreach (AvatarAttachment att in cAgent.Attachments)
3629 {
3630 m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID);
3631 }
3632 }
3633 }
3634 catch { }
3635*/
3636 try 3601 try
3637 { 3602 {
3638 lock (scriptedcontrols) 3603 lock (scriptedcontrols)
@@ -3662,8 +3627,18 @@ namespace OpenSim.Region.Framework.Scenes
3662 } 3627 }
3663 catch { } 3628 catch { }
3664 3629
3665 //cAgent.GroupID = ?? 3630 if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0)
3666 //Groups??? 3631 {
3632 m_attachments = new List<SceneObjectGroup>();
3633 int i = 0;
3634 foreach (ISceneObject so in cAgent.AttachmentObjects)
3635 {
3636 ((SceneObjectGroup)so).LocalId = 0;
3637 ((SceneObjectGroup)so).RootPart.UpdateFlag = 0;
3638 so.SetState(cAgent.AttachmentObjectStates[i++], m_scene);
3639 m_scene.IncomingCreateObject(so);
3640 }
3641 }
3667 } 3642 }
3668 3643
3669 public bool CopyAgent(out IAgentData agent) 3644 public bool CopyAgent(out IAgentData agent)