aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs22
-rw-r--r--OpenSim/Region/Framework/Scenes/CollisionSounds.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/KeyframeMotion.cs83
-rw-r--r--OpenSim/Region/Framework/Scenes/SOPVehicle.cs16
-rwxr-xr-xOpenSim/Region/Framework/Scenes/Scene.cs120
-rwxr-xr-xOpenSim/Region/Framework/Scenes/SceneGraph.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs161
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs300
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs49
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs95
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs170
14 files changed, 680 insertions, 378 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
index 441076d..093ea9c 100644
--- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
+++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
@@ -44,14 +44,13 @@ namespace OpenSim.Region.Framework.Interfaces
44 /// <param name='isReuseable'></param> 44 /// <param name='isReuseable'></param>
45 void ReturnData(UUID id, IDynamicTexture texture); 45 void ReturnData(UUID id, IDynamicTexture texture);
46 46
47 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams);
47 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, 48 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
48 int updateTimer); 49 bool SetBlending, byte AlphaValue);
49 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, 50 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
50 int updateTimer, bool SetBlending, byte AlphaValue); 51 bool SetBlending, int disp, byte AlphaValue, int face);
51 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, 52
52 int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face); 53 UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams);
53 UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
54 int updateTimer);
55 54
56 /// Apply a dynamically generated texture to all sides of the given prim. The texture is not persisted to the 55 /// Apply a dynamically generated texture to all sides of the given prim. The texture is not persisted to the
57 /// asset service. 56 /// asset service.
@@ -62,8 +61,6 @@ namespace OpenSim.Region.Framework.Interfaces
62 /// based texture or "image" to create a texture from an image at a particular URL</param> 61 /// based texture or "image" to create a texture from an image at a particular URL</param>
63 /// <param name="data">The data for the generator</param> 62 /// <param name="data">The data for the generator</param>
64 /// <param name="extraParams">Parameters for the generator that don't form part of the main data.</param> 63 /// <param name="extraParams">Parameters for the generator that don't form part of the main data.</param>
65 /// <param name="updateTimer">If zero, the image is never updated after the first generation. If positive
66 /// the image is updated at the given interval. Not implemented for </param>
67 /// <param name="SetBlending"> 64 /// <param name="SetBlending">
68 /// If true, the newly generated texture is blended with the appropriate existing ones on the prim 65 /// If true, the newly generated texture is blended with the appropriate existing ones on the prim
69 /// </param> 66 /// </param>
@@ -76,7 +73,7 @@ namespace OpenSim.Region.Framework.Interfaces
76 /// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID 73 /// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID
77 /// </returns> 74 /// </returns>
78 UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, 75 UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
79 int updateTimer, bool SetBlending, byte AlphaValue); 76 bool SetBlending, byte AlphaValue);
80 77
81 /// <summary> 78 /// <summary>
82 /// Apply a dynamically generated texture to the given prim. 79 /// Apply a dynamically generated texture to the given prim.
@@ -87,8 +84,6 @@ namespace OpenSim.Region.Framework.Interfaces
87 /// based texture or "image" to create a texture from an image at a particular URL</param> 84 /// based texture or "image" to create a texture from an image at a particular URL</param>
88 /// <param name="data">The data for the generator</param> 85 /// <param name="data">The data for the generator</param>
89 /// <param name="extraParams">Parameters for the generator that don't form part of the main data.</param> 86 /// <param name="extraParams">Parameters for the generator that don't form part of the main data.</param>
90 /// <param name="updateTimer">If zero, the image is never updated after the first generation. If positive
91 /// the image is updated at the given interval. Not implemented for </param>
92 /// <param name="SetBlending"> 87 /// <param name="SetBlending">
93 /// If true, the newly generated texture is blended with the appropriate existing ones on the prim 88 /// If true, the newly generated texture is blended with the appropriate existing ones on the prim
94 /// </param> 89 /// </param>
@@ -109,9 +104,8 @@ namespace OpenSim.Region.Framework.Interfaces
109 /// to obtain it directly from the SceneObjectPart. For instance, if ALL_SIDES is set then this texture 104 /// to obtain it directly from the SceneObjectPart. For instance, if ALL_SIDES is set then this texture
110 /// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID 105 /// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID
111 /// </returns> 106 /// </returns>
112 UUID AddDynamicTextureData( 107 UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
113 UUID simID, UUID primID, string contentType, string data, string extraParams, 108 bool SetBlending, int disp, byte AlphaValue, int face);
114 int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face);
115 109
116 void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, 110 void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
117 out double xSize, out double ySize); 111 out double xSize, out double ySize);
diff --git a/OpenSim/Region/Framework/Scenes/CollisionSounds.cs b/OpenSim/Region/Framework/Scenes/CollisionSounds.cs
index e76fef4..63aafcd 100644
--- a/OpenSim/Region/Framework/Scenes/CollisionSounds.cs
+++ b/OpenSim/Region/Framework/Scenes/CollisionSounds.cs
@@ -116,16 +116,20 @@ namespace OpenSim.Region.Framework.Scenes
116 116
117 public static void PartCollisionSound(SceneObjectPart part, List<CollisionForSoundInfo> collidersinfolist) 117 public static void PartCollisionSound(SceneObjectPart part, List<CollisionForSoundInfo> collidersinfolist)
118 { 118 {
119 if (part.CollisionSoundType < 0)
120 return;
121
119 if (collidersinfolist.Count == 0 || part == null) 122 if (collidersinfolist.Count == 0 || part == null)
120 return; 123 return;
121 124
122 if (part.VolumeDetectActive || (part.Flags & PrimFlags.Physics) == 0) 125 if (part.VolumeDetectActive || (part.Flags & PrimFlags.Physics) == 0)
123 return; 126 return;
124 127
125 if (part.ParentGroup == null) 128 SceneObjectGroup sog = part.ParentGroup;
129 if (sog == null || sog.IsDeleted || sog.inTransit)
126 return; 130 return;
127 131
128 if (part.CollisionSoundType < 0) 132 if(sog.CollisionSoundThrottled(part.CollisionSoundType))
129 return; 133 return;
130 134
131 float volume = part.CollisionSoundVolume; 135 float volume = part.CollisionSoundVolume;
@@ -189,15 +193,23 @@ namespace OpenSim.Region.Framework.Scenes
189 continue; 193 continue;
190 } 194 }
191 195
192 SceneObjectPart otherPart = part.ParentGroup.Scene.GetSceneObjectPart(id); 196 SceneObjectPart otherPart = sog.Scene.GetSceneObjectPart(id);
193 if (otherPart != null) 197 if (otherPart != null)
194 { 198 {
195 if (otherPart.CollisionSoundType < 0 || otherPart.VolumeDetectActive) 199 SceneObjectGroup othersog = otherPart.ParentGroup;
200 if(othersog == null || othersog.IsDeleted || othersog.inTransit)
201 continue;
202
203 int otherType = otherPart.CollisionSoundType;
204 if (otherType < 0 || otherPart.VolumeDetectActive)
196 continue; 205 continue;
197 206
198 if (!HaveSound) 207 if (!HaveSound)
199 { 208 {
200 if (otherPart.CollisionSoundType == 1) 209 if(othersog.CollisionSoundThrottled(otherType))
210 continue;
211
212 if (otherType == 1)
201 { 213 {
202 soundID = otherPart.CollisionSound; 214 soundID = otherPart.CollisionSound;
203 volume = otherPart.CollisionSoundVolume; 215 volume = otherPart.CollisionSoundVolume;
@@ -206,7 +218,7 @@ namespace OpenSim.Region.Framework.Scenes
206 } 218 }
207 else 219 else
208 { 220 {
209 if (otherPart.CollisionSoundType == 2) 221 if (otherType == 2)
210 { 222 {
211 volume = otherPart.CollisionSoundVolume; 223 volume = otherPart.CollisionSoundVolume;
212 if (volume == 0.0f) 224 if (volume == 0.0f)
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 827f91e..f76f882 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -855,7 +855,7 @@ namespace OpenSim.Region.Framework.Scenes
855 /// <see cref="Scene.DeleteSceneObject"/>, 855 /// <see cref="Scene.DeleteSceneObject"/>,
856 /// <see cref="Scene.SelectPrim"/>, 856 /// <see cref="Scene.SelectPrim"/>,
857 /// <see cref="Scene.DeselectPrim"/>, 857 /// <see cref="Scene.DeselectPrim"/>,
858 /// <see cref="SceneObjectGroup.UpdatePrimFlags"/>, 858 /// <see cref="SceneObjectGroup.UpdateFlags"/>,
859 /// <see cref="SceneObjectGroup.AbsolutePosition"/> 859 /// <see cref="SceneObjectGroup.AbsolutePosition"/>
860 /// </remarks> 860 /// </remarks>
861 public event ParcelPrimCountTainted OnParcelPrimCountTainted; 861 public event ParcelPrimCountTainted OnParcelPrimCountTainted;
diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
index d81d8a2..80ee510 100644
--- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
+++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
@@ -295,6 +295,7 @@ namespace OpenSim.Region.Framework.Scenes
295 lock (m_frames) 295 lock (m_frames)
296 { 296 {
297 KeyframeTimer.Add(this); 297 KeyframeTimer.Add(this);
298 m_lasttickMS = Util.GetTimeStampMS();
298 m_timerStopped = false; 299 m_timerStopped = false;
299 } 300 }
300 } 301 }
@@ -326,8 +327,8 @@ namespace OpenSim.Region.Framework.Scenes
326 newMotion.m_selected = true; 327 newMotion.m_selected = true;
327 } 328 }
328 329
329 newMotion.m_timerStopped = false; 330// newMotion.m_timerStopped = false;
330 newMotion.m_running = true; 331// newMotion.m_running = true;
331 newMotion.m_isCrossing = false; 332 newMotion.m_isCrossing = false;
332 newMotion.m_waitingCrossing = false; 333 newMotion.m_waitingCrossing = false;
333 } 334 }
@@ -483,9 +484,10 @@ namespace OpenSim.Region.Framework.Scenes
483 484
484 m_group.RootPart.Velocity = Vector3.Zero; 485 m_group.RootPart.Velocity = Vector3.Zero;
485 m_group.RootPart.AngularVelocity = Vector3.Zero; 486 m_group.RootPart.AngularVelocity = Vector3.Zero;
486 m_group.SendGroupRootTerseUpdate(); 487// m_group.SendGroupRootTerseUpdate();
487// m_group.RootPart.ScheduleTerseUpdate(); 488 m_group.RootPart.ScheduleTerseUpdate();
488 m_frames.Clear(); 489 m_frames.Clear();
490 m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId);
489 } 491 }
490 492
491 public void Pause() 493 public void Pause()
@@ -496,8 +498,9 @@ namespace OpenSim.Region.Framework.Scenes
496 m_group.RootPart.Velocity = Vector3.Zero; 498 m_group.RootPart.Velocity = Vector3.Zero;
497 m_group.RootPart.AngularVelocity = Vector3.Zero; 499 m_group.RootPart.AngularVelocity = Vector3.Zero;
498 m_skippedUpdates = 1000; 500 m_skippedUpdates = 1000;
499 m_group.SendGroupRootTerseUpdate(); 501// m_group.SendGroupRootTerseUpdate();
500// m_group.RootPart.ScheduleTerseUpdate(); 502 m_group.RootPart.ScheduleTerseUpdate();
503 m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId);
501 } 504 }
502 505
503 public void Suspend() 506 public void Suspend()
@@ -644,15 +647,16 @@ namespace OpenSim.Region.Framework.Scenes
644 647
645 m_group.RootPart.Velocity = Vector3.Zero; 648 m_group.RootPart.Velocity = Vector3.Zero;
646 m_group.RootPart.AngularVelocity = Vector3.Zero; 649 m_group.RootPart.AngularVelocity = Vector3.Zero;
647 m_group.SendGroupRootTerseUpdate(); 650// m_group.SendGroupRootTerseUpdate();
648 651 m_group.RootPart.ScheduleTerseUpdate();
649 m_frames.Clear(); 652 m_frames.Clear();
650 } 653 }
651 654
652 Vector3 m_lastPosUpdate; 655 [NonSerialized()] Vector3 m_lastPosUpdate;
653 Quaternion m_lastRotationUpdate; 656 [NonSerialized()] Quaternion m_lastRotationUpdate;
654 Vector3 m_currentVel; 657 [NonSerialized()] Vector3 m_currentVel;
655 int m_skippedUpdates; 658 [NonSerialized()] int m_skippedUpdates;
659 [NonSerialized()] double m_lasttickMS;
656 660
657 private void DoOnTimer(double tickDuration) 661 private void DoOnTimer(double tickDuration)
658 { 662 {
@@ -673,7 +677,8 @@ namespace OpenSim.Region.Framework.Scenes
673 { 677 {
674 m_group.RootPart.Velocity = Vector3.Zero; 678 m_group.RootPart.Velocity = Vector3.Zero;
675 m_skippedUpdates = 1000; 679 m_skippedUpdates = 1000;
676 m_group.SendGroupRootTerseUpdate(); 680// m_group.SendGroupRootTerseUpdate();
681 m_group.RootPart.ScheduleTerseUpdate();
677 } 682 }
678 return; 683 return;
679 } 684 }
@@ -696,6 +701,8 @@ namespace OpenSim.Region.Framework.Scenes
696 return; 701 return;
697 } 702 }
698 703
704 double nowMS = Util.GetTimeStampMS();
705
699 if (m_frames.Count == 0) 706 if (m_frames.Count == 0)
700 { 707 {
701 lock (m_frames) 708 lock (m_frames)
@@ -716,10 +723,16 @@ namespace OpenSim.Region.Framework.Scenes
716 m_currentVel /= (m_currentFrame.TimeMS * 0.001f); 723 m_currentVel /= (m_currentFrame.TimeMS * 0.001f);
717 724
718 m_currentFrame.TimeMS += (int)tickDuration; 725 m_currentFrame.TimeMS += (int)tickDuration;
726 m_lasttickMS = nowMS - 50f;
719 update = true; 727 update = true;
720 } 728 }
721 729
722 m_currentFrame.TimeMS -= (int)tickDuration; 730 int elapsed = (int)(nowMS - m_lasttickMS);
731 if( elapsed > 3 * tickDuration)
732 elapsed = (int)tickDuration;
733
734 m_currentFrame.TimeMS -= elapsed;
735 m_lasttickMS = nowMS;
723 736
724 // Do the frame processing 737 // Do the frame processing
725 double remainingSteps = (double)m_currentFrame.TimeMS / tickDuration; 738 double remainingSteps = (double)m_currentFrame.TimeMS / tickDuration;
@@ -752,7 +765,8 @@ namespace OpenSim.Region.Framework.Scenes
752 } 765 }
753 else 766 else
754 { 767 {
755 bool lastSteps = remainingSteps < 4; 768// bool lastSteps = remainingSteps < 4;
769
756 Vector3 currentPosition = m_group.AbsolutePosition; 770 Vector3 currentPosition = m_group.AbsolutePosition;
757 Vector3 motionThisFrame = (Vector3)m_currentFrame.Position - currentPosition; 771 Vector3 motionThisFrame = (Vector3)m_currentFrame.Position - currentPosition;
758 motionThisFrame /= (float)remainingSteps; 772 motionThisFrame /= (float)remainingSteps;
@@ -766,20 +780,22 @@ namespace OpenSim.Region.Framework.Scenes
766 Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed); 780 Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed);
767 step.Normalize(); 781 step.Normalize();
768 m_group.RootPart.RotationOffset = step; 782 m_group.RootPart.RotationOffset = step;
783/*
769 if (Math.Abs(step.X - m_lastRotationUpdate.X) > 0.001f 784 if (Math.Abs(step.X - m_lastRotationUpdate.X) > 0.001f
770 || Math.Abs(step.Y - m_lastRotationUpdate.Y) > 0.001f 785 || Math.Abs(step.Y - m_lastRotationUpdate.Y) > 0.001f
771 || Math.Abs(step.Z - m_lastRotationUpdate.Z) > 0.001f) 786 || Math.Abs(step.Z - m_lastRotationUpdate.Z) > 0.001f)
772 update = true; 787 update = true;
788*/
773 } 789 }
774 790
775 m_group.AbsolutePosition = m_nextPosition; 791 m_group.AbsolutePosition = m_nextPosition;
776 if(lastSteps) 792// if(lastSteps)
777 m_group.RootPart.Velocity = Vector3.Zero; 793// m_group.RootPart.Velocity = Vector3.Zero;
778 else 794// else
779 m_group.RootPart.Velocity = m_currentVel; 795 m_group.RootPart.Velocity = m_currentVel;
780 796/*
781 if(!update && ( 797 if(!update && (
782 lastSteps || 798// lastSteps ||
783 m_skippedUpdates * tickDuration > 0.5 || 799 m_skippedUpdates * tickDuration > 0.5 ||
784 Math.Abs(m_nextPosition.X - currentPosition.X) > 5f || 800 Math.Abs(m_nextPosition.X - currentPosition.X) > 5f ||
785 Math.Abs(m_nextPosition.Y - currentPosition.Y) > 5f || 801 Math.Abs(m_nextPosition.Y - currentPosition.Y) > 5f ||
@@ -790,15 +806,16 @@ namespace OpenSim.Region.Framework.Scenes
790 } 806 }
791 else 807 else
792 m_skippedUpdates++; 808 m_skippedUpdates++;
793 809*/
794 } 810 }
795 if(update) 811// if(update)
796 { 812// {
797 m_lastPosUpdate = m_nextPosition; 813// m_lastPosUpdate = m_nextPosition;
798 m_lastRotationUpdate = m_group.GroupRotation; 814// m_lastRotationUpdate = m_group.GroupRotation;
799 m_skippedUpdates = 0; 815// m_skippedUpdates = 0;
800 m_group.SendGroupRootTerseUpdate(); 816// m_group.SendGroupRootTerseUpdate();
801 } 817 m_group.RootPart.ScheduleTerseUpdate();
818// }
802 } 819 }
803 820
804 public Byte[] Serialize() 821 public Byte[] Serialize()
@@ -842,8 +859,8 @@ namespace OpenSim.Region.Framework.Scenes
842 { 859 {
843 m_group.RootPart.Velocity = Vector3.Zero; 860 m_group.RootPart.Velocity = Vector3.Zero;
844 m_skippedUpdates = 1000; 861 m_skippedUpdates = 1000;
845 m_group.SendGroupRootTerseUpdate(); 862// m_group.SendGroupRootTerseUpdate();
846// m_group.RootPart.ScheduleTerseUpdate(); 863 m_group.RootPart.ScheduleTerseUpdate();
847 } 864 }
848 } 865 }
849 866
@@ -855,8 +872,8 @@ namespace OpenSim.Region.Framework.Scenes
855 { 872 {
856 m_group.RootPart.Velocity = Vector3.Zero; 873 m_group.RootPart.Velocity = Vector3.Zero;
857 m_skippedUpdates = 1000; 874 m_skippedUpdates = 1000;
858 m_group.SendGroupRootTerseUpdate(); 875// m_group.SendGroupRootTerseUpdate();
859// m_group.RootPart.ScheduleTerseUpdate(); 876 m_group.RootPart.ScheduleTerseUpdate();
860 877
861 if (m_running) 878 if (m_running)
862 { 879 {
diff --git a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs
index 8d11331..351eda3 100644
--- a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs
+++ b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs
@@ -425,25 +425,25 @@ namespace OpenSim.Region.Framework.Scenes
425 425
426 private void XWfloat(string name, float f) 426 private void XWfloat(string name, float f)
427 { 427 {
428 writer.WriteElementString(name, f.ToString(Utils.EnUsCulture)); 428 writer.WriteElementString(name, f.ToString(Culture.FormatProvider));
429 } 429 }
430 430
431 private void XWVector(string name, Vector3 vec) 431 private void XWVector(string name, Vector3 vec)
432 { 432 {
433 writer.WriteStartElement(name); 433 writer.WriteStartElement(name);
434 writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture)); 434 writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider));
435 writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture)); 435 writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider));
436 writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture)); 436 writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider));
437 writer.WriteEndElement(); 437 writer.WriteEndElement();
438 } 438 }
439 439
440 private void XWQuat(string name, Quaternion quat) 440 private void XWQuat(string name, Quaternion quat)
441 { 441 {
442 writer.WriteStartElement(name); 442 writer.WriteStartElement(name);
443 writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture)); 443 writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider));
444 writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture)); 444 writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider));
445 writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture)); 445 writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider));
446 writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture)); 446 writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider));
447 writer.WriteEndElement(); 447 writer.WriteEndElement();
448 } 448 }
449 449
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index ebef158..c06b3dd 100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1651,10 +1651,11 @@ namespace OpenSim.Region.Framework.Scenes
1651 physicsMS2 = (float)(tmpMS2 - tmpMS); 1651 physicsMS2 = (float)(tmpMS2 - tmpMS);
1652 tmpMS = tmpMS2; 1652 tmpMS = tmpMS2;
1653 1653
1654/*
1654 // Apply any pending avatar force input to the avatar's velocity 1655 // Apply any pending avatar force input to the avatar's velocity
1655 if (Frame % m_update_entitymovement == 0) 1656 if (Frame % m_update_entitymovement == 0)
1656 m_sceneGraph.UpdateScenePresenceMovement(); 1657 m_sceneGraph.UpdateScenePresenceMovement();
1657 1658*/
1658 if (Frame % (m_update_coarse_locations) == 0 && !m_sendingCoarseLocations) 1659 if (Frame % (m_update_coarse_locations) == 0 && !m_sendingCoarseLocations)
1659 { 1660 {
1660 m_sendingCoarseLocations = true; 1661 m_sendingCoarseLocations = true;
@@ -1942,7 +1943,6 @@ namespace OpenSim.Region.Framework.Scenes
1942 { 1943 {
1943 if (!m_backingup) 1944 if (!m_backingup)
1944 { 1945 {
1945 m_backingup = true;
1946 WorkManager.RunInThreadPool(o => Backup(false), null, string.Format("BackupWorker ({0})", Name)); 1946 WorkManager.RunInThreadPool(o => Backup(false), null, string.Format("BackupWorker ({0})", Name));
1947 } 1947 }
1948 } 1948 }
@@ -1971,38 +1971,58 @@ namespace OpenSim.Region.Framework.Scenes
1971 { 1971 {
1972 lock (m_returns) 1972 lock (m_returns)
1973 { 1973 {
1974 EventManager.TriggerOnBackup(SimulationDataService, forced); 1974 if(m_backingup)
1975 {
1976 m_log.WarnFormat("[Scene] Backup of {0} already running. New call skipped", RegionInfo.RegionName);
1977 return;
1978 }
1975 1979
1976 foreach (KeyValuePair<UUID, ReturnInfo> ret in m_returns) 1980 m_backingup = true;
1981 try
1977 { 1982 {
1978 UUID transaction = UUID.Random(); 1983 EventManager.TriggerOnBackup(SimulationDataService, forced);
1979 1984
1980 GridInstantMessage msg = new GridInstantMessage(); 1985 if(m_returns.Count == 0)
1981 msg.fromAgentID = new Guid(UUID.Zero.ToString()); // From server 1986 return;
1982 msg.toAgentID = new Guid(ret.Key.ToString());
1983 msg.imSessionID = new Guid(transaction.ToString());
1984 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
1985 msg.fromAgentName = "Server";
1986 msg.dialog = (byte)19; // Object msg
1987 msg.fromGroup = false;
1988 msg.offline = (byte)1;
1989 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
1990 msg.Position = Vector3.Zero;
1991 msg.RegionID = RegionInfo.RegionID.Guid;
1992
1993 // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
1994 msg.binaryBucket = Util.StringToBytes256("\0");
1995 if (ret.Value.count > 1)
1996 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);
1997 else
1998 msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
1999 1987
2000 IMessageTransferModule tr = RequestModuleInterface<IMessageTransferModule>(); 1988 IMessageTransferModule tr = RequestModuleInterface<IMessageTransferModule>();
2001 if (tr != null) 1989 if (tr == null)
1990 return;
1991
1992 uint unixtime = (uint)Util.UnixTimeSinceEpoch();
1993 uint estateid = RegionInfo.EstateSettings.ParentEstateID;
1994 Guid regionguid = RegionInfo.RegionID.Guid;
1995
1996 foreach (KeyValuePair<UUID, ReturnInfo> ret in m_returns)
1997 {
1998 GridInstantMessage msg = new GridInstantMessage();
1999 msg.fromAgentID = Guid.Empty; // From server
2000 msg.toAgentID = ret.Key.Guid;
2001 msg.imSessionID = Guid.NewGuid();
2002 msg.timestamp = unixtime;
2003 msg.fromAgentName = "Server";
2004 msg.dialog = 19; // Object msg
2005 msg.fromGroup = false;
2006 msg.offline = 1;
2007 msg.ParentEstateID = estateid;
2008 msg.Position = Vector3.Zero;
2009 msg.RegionID = regionguid;
2010
2011 // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
2012 msg.binaryBucket = new Byte[1] {0};
2013 if (ret.Value.count > 1)
2014 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);
2015 else
2016 msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
2017
2002 tr.SendInstantMessage(msg, delegate(bool success) { }); 2018 tr.SendInstantMessage(msg, delegate(bool success) { });
2019 }
2020 m_returns.Clear();
2021 }
2022 finally
2023 {
2024 m_backingup = false;
2003 } 2025 }
2004 m_returns.Clear();
2005 m_backingup = false;
2006 } 2026 }
2007 } 2027 }
2008 2028
@@ -4805,16 +4825,34 @@ Label_GroupsDone:
4805 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, 4825 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
4806 Vector3 lookat, uint teleportFlags) 4826 Vector3 lookat, uint teleportFlags)
4807 { 4827 {
4808 GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName); 4828 if (EntityTransferModule == null)
4829 {
4830 m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
4831 return;
4832 }
4833
4834 ScenePresence sp = GetScenePresence(remoteClient.AgentId);
4835 if (sp == null || sp.IsDeleted || sp.IsInTransit)
4836 return;
4809 4837
4810 if (region == null) 4838 ulong regionHandle = 0;
4839 if(regionName == RegionInfo.RegionName)
4840 regionHandle = RegionInfo.RegionHandle;
4841 else
4842 {
4843 GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
4844 if (region != null)
4845 regionHandle = region.RegionHandle;
4846 }
4847
4848 if(regionHandle == 0)
4811 { 4849 {
4812 // can't find the region: Tell viewer and abort 4850 // can't find the region: Tell viewer and abort
4813 remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found."); 4851 remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
4814 return; 4852 return;
4815 } 4853 }
4816 4854
4817 RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags); 4855 EntityTransferModule.Teleport(sp, regionHandle, position, lookat, teleportFlags);
4818 } 4856 }
4819 4857
4820 /// <summary> 4858 /// <summary>
@@ -4828,19 +4866,17 @@ Label_GroupsDone:
4828 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, 4866 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
4829 Vector3 lookAt, uint teleportFlags) 4867 Vector3 lookAt, uint teleportFlags)
4830 { 4868 {
4831 ScenePresence sp = GetScenePresence(remoteClient.AgentId); 4869 if (EntityTransferModule == null)
4832 if (sp != null)
4833 { 4870 {
4834 if (EntityTransferModule != null) 4871 m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
4835 { 4872 return;
4836 EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
4837 }
4838 else
4839 {
4840 m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
4841 sp.ControllingClient.SendTeleportFailed("Unable to perform teleports on this simulator.");
4842 }
4843 } 4873 }
4874
4875 ScenePresence sp = GetScenePresence(remoteClient.AgentId);
4876 if (sp == null || sp.IsDeleted || sp.IsInTransit)
4877 return;
4878
4879 EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
4844 } 4880 }
4845 4881
4846 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) 4882 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index ae827f4..61a243d 100755
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -1649,7 +1649,7 @@ namespace OpenSim.Region.Framework.Scenes
1649 else // else turn it off 1649 else // else turn it off
1650 vdtc = false; 1650 vdtc = false;
1651 1651
1652 group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, vdtc); 1652 group.UpdateFlags(UsePhysics, SetTemporary, SetPhantom, vdtc);
1653 } 1653 }
1654 else 1654 else
1655 { 1655 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index fdfe8ae..6f46a92 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1259,6 +1259,8 @@ namespace OpenSim.Region.Framework.Scenes
1259 set { m_LoopSoundSlavePrims = value; } 1259 set { m_LoopSoundSlavePrims = value; }
1260 } 1260 }
1261 1261
1262 private double m_lastCollisionSoundMS;
1263
1262 /// <summary> 1264 /// <summary>
1263 /// The UUID for the region this object is in. 1265 /// The UUID for the region this object is in.
1264 /// </summary> 1266 /// </summary>
@@ -1336,7 +1338,7 @@ namespace OpenSim.Region.Framework.Scenes
1336 /// </summary> 1338 /// </summary>
1337 public SceneObjectGroup() 1339 public SceneObjectGroup()
1338 { 1340 {
1339 1341 m_lastCollisionSoundMS = Util.GetTimeStampMS() + 1000.0;
1340 } 1342 }
1341 1343
1342 /// <summary> 1344 /// <summary>
@@ -2716,35 +2718,22 @@ namespace OpenSim.Region.Framework.Scenes
2716 RootPart.KeyframeMotion.Stop(); 2718 RootPart.KeyframeMotion.Stop();
2717 RootPart.KeyframeMotion = null; 2719 RootPart.KeyframeMotion = null;
2718 } 2720 }
2719 UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2721 UpdateFlags(usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2720 } 2722 }
2721 2723
2722 public void ScriptSetTemporaryStatus(bool makeTemporary) 2724 public void ScriptSetTemporaryStatus(bool makeTemporary)
2723 { 2725 {
2724 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect); 2726 UpdateFlags(UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect);
2725 } 2727 }
2726 2728
2727 public void ScriptSetPhantomStatus(bool makePhantom) 2729 public void ScriptSetPhantomStatus(bool makePhantom)
2728 { 2730 {
2729 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect); 2731 UpdateFlags(UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect);
2730 } 2732 }
2731 2733
2732 public void ScriptSetVolumeDetect(bool makeVolumeDetect) 2734 public void ScriptSetVolumeDetect(bool makeVolumeDetect)
2733 { 2735 {
2734 UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect); 2736 UpdateFlags(UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect);
2735
2736 /*
2737 ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore
2738
2739 if (PhysActor != null) // Should always be the case now
2740 {
2741 PhysActor.SetVolumeDetect(param);
2742 }
2743 if (param != 0)
2744 AddFlag(PrimFlags.Phantom);
2745
2746 ScheduleFullUpdate();
2747 */
2748 } 2737 }
2749 2738
2750 public void applyImpulse(Vector3 impulse) 2739 public void applyImpulse(Vector3 impulse)
@@ -4029,84 +4018,80 @@ namespace OpenSim.Region.Framework.Scenes
4029 /// <param name="SetTemporary"></param> 4018 /// <param name="SetTemporary"></param>
4030 /// <param name="SetPhantom"></param> 4019 /// <param name="SetPhantom"></param>
4031 /// <param name="SetVolumeDetect"></param> 4020 /// <param name="SetVolumeDetect"></param>
4032 public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect) 4021 public void UpdateFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
4033 { 4022 {
4034 HasGroupChanged = true; 4023 if (m_scene == null || IsDeleted)
4024 return;
4035 4025
4036 SceneObjectPart selectionPart = GetPart(localID); 4026 HasGroupChanged = true;
4037 4027
4038 if (Scene != null) 4028 if (SetTemporary)
4039 { 4029 {
4040 if (SetTemporary) 4030 DetachFromBackup();
4041 { 4031 // Remove from database and parcel prim count
4042 DetachFromBackup(); 4032 //
4043 // Remove from database and parcel prim count 4033 m_scene.DeleteFromStorage(UUID);
4044 //
4045 m_scene.DeleteFromStorage(UUID);
4046 }
4047 else if (!Backup)
4048 {
4049 // Previously been temporary now switching back so make it
4050 // available for persisting again
4051 AttachToBackup();
4052 }
4053
4054 m_scene.EventManager.TriggerParcelPrimCountTainted();
4055 } 4034 }
4056 4035 else if (!Backup)
4057 if (selectionPart != null)
4058 { 4036 {
4059 SceneObjectPart[] parts = m_parts.GetArray(); 4037 // Previously been temporary now switching back so make it
4038 // available for persisting again
4039 AttachToBackup();
4040 }
4060 4041
4061 if (Scene != null && UsePhysics)
4062 {
4063 int maxprims = m_scene.m_linksetPhysCapacity;
4064 bool checkShape = (maxprims > 0 &&
4065 parts.Length > maxprims);
4066 4042
4067 for (int i = 0; i < parts.Length; i++) 4043 SceneObjectPart[] parts = m_parts.GetArray();
4068 { 4044
4069 SceneObjectPart part = parts[i]; 4045 if (UsePhysics)
4046 {
4047 int maxprims = m_scene.m_linksetPhysCapacity;
4048 bool checkShape = (maxprims > 0 &&
4049 parts.Length > maxprims);
4070 4050
4071 if(part.PhysicsShapeType == (byte)PhysicsShapeType.None) 4051 for (int i = 0; i < parts.Length; i++)
4072 continue; // assuming root type was checked elsewhere 4052 {
4053 SceneObjectPart part = parts[i];
4073 4054
4074 if (checkShape) 4055 if(part.PhysicsShapeType == (byte)PhysicsShapeType.None)
4075 { 4056 continue; // assuming root type was checked elsewhere
4076 if (--maxprims < 0)
4077 {
4078 UsePhysics = false;
4079 break;
4080 }
4081 }
4082 4057
4083 if (part.Scale.X > m_scene.m_maxPhys || 4058 if (checkShape)
4084 part.Scale.Y > m_scene.m_maxPhys || 4059 {
4085 part.Scale.Z > m_scene.m_maxPhys ) 4060 if (--maxprims < 0)
4086 { 4061 {
4087 UsePhysics = false; // Reset physics 4062 UsePhysics = false;
4088 break; 4063 break;
4089 } 4064 }
4090 } 4065 }
4091 }
4092
4093 if (parts.Length > 1)
4094 {
4095 m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
4096 4066
4097 for (int i = 0; i < parts.Length; i++) 4067 if (part.Scale.X > m_scene.m_maxPhys ||
4068 part.Scale.Y > m_scene.m_maxPhys ||
4069 part.Scale.Z > m_scene.m_maxPhys )
4098 { 4070 {
4099 4071 UsePhysics = false; // Reset physics
4100 if (parts[i].UUID != m_rootPart.UUID) 4072 break;
4101 parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
4102 } 4073 }
4074 }
4075 }
4076
4077 if (parts.Length > 1)
4078 {
4079 m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
4103 4080
4104 if (m_rootPart.PhysActor != null) 4081 for (int i = 0; i < parts.Length; i++)
4105 m_rootPart.PhysActor.Building = false; 4082 {
4083
4084 if (parts[i].UUID != m_rootPart.UUID)
4085 parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
4106 } 4086 }
4107 else 4087
4108 m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false); 4088 if (m_rootPart.PhysActor != null)
4089 m_rootPart.PhysActor.Building = false;
4109 } 4090 }
4091 else
4092 m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false);
4093
4094 m_scene.EventManager.TriggerParcelPrimCountTainted();
4110 } 4095 }
4111 4096
4112 public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data) 4097 public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data)
@@ -5528,7 +5513,33 @@ namespace OpenSim.Region.Framework.Scenes
5528 } 5513 }
5529 } 5514 }
5530 5515
5516 public bool CollisionSoundThrottled(int collisionSoundType)
5517 {
5518 double time = m_lastCollisionSoundMS;
5519// m_lastCollisionSoundMS = Util.GetTimeStampMS();
5520// time = m_lastCollisionSoundMS - time;
5521 double now = Util.GetTimeStampMS();
5522 time = now - time;
5523 switch (collisionSoundType)
5524 {
5525 case 0: // default sounds
5526 case 2: // default sounds with volume set by script
5527 if(time < 300.0)
5528 return true;
5529 break;
5530 case 1: // selected sound
5531 if(time < 200.0)
5532 return true;
5533 break;
5534 default:
5535 break;
5536 }
5537 m_lastCollisionSoundMS = now;
5538 return false;
5539 }
5540
5531 #endregion 5541 #endregion
5532 } 5542 }
5533 5543
5544
5534} 5545}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index c2eac24..f0a3fab 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -329,7 +329,8 @@ namespace OpenSim.Region.Framework.Scenes
329 private byte[] m_TextureAnimation; 329 private byte[] m_TextureAnimation;
330 private byte m_clickAction; 330 private byte m_clickAction;
331 private Color m_color = Color.Black; 331 private Color m_color = Color.Black;
332 private readonly List<uint> m_lastColliders = new List<uint>(); 332 private List<uint> m_lastColliders = new List<uint>();
333 private bool m_lastLandCollide;
333 private int m_linkNum; 334 private int m_linkNum;
334 335
335 private int m_scriptAccessPin; 336 private int m_scriptAccessPin;
@@ -369,9 +370,9 @@ namespace OpenSim.Region.Framework.Scenes
369 protected Vector3 m_lastPosition; 370 protected Vector3 m_lastPosition;
370 protected Quaternion m_lastRotation; 371 protected Quaternion m_lastRotation;
371 protected Vector3 m_lastVelocity; 372 protected Vector3 m_lastVelocity;
372 protected Vector3 m_lastAcceleration; 373 protected Vector3 m_lastAcceleration; // acceleration is a derived var with high noise
373 protected Vector3 m_lastAngularVelocity; 374 protected Vector3 m_lastAngularVelocity;
374 protected int m_lastUpdateSentTime; 375 protected double m_lastUpdateSentTime;
375 protected float m_buoyancy = 0.0f; 376 protected float m_buoyancy = 0.0f;
376 protected Vector3 m_force; 377 protected Vector3 m_force;
377 protected Vector3 m_torque; 378 protected Vector3 m_torque;
@@ -809,7 +810,7 @@ namespace OpenSim.Region.Framework.Scenes
809 { 810 {
810 // If this is a linkset, we don't want the physics engine mucking up our group position here. 811 // If this is a linkset, we don't want the physics engine mucking up our group position here.
811 PhysicsActor actor = PhysActor; 812 PhysicsActor actor = PhysActor;
812 if (ParentID == 0) 813 if (_parentID == 0)
813 { 814 {
814 if (actor != null) 815 if (actor != null)
815 m_groupPosition = actor.Position; 816 m_groupPosition = actor.Position;
@@ -838,7 +839,7 @@ namespace OpenSim.Region.Framework.Scenes
838 try 839 try
839 { 840 {
840 // Root prim actually goes at Position 841 // Root prim actually goes at Position
841 if (ParentID == 0) 842 if (_parentID == 0)
842 { 843 {
843 actor.Position = value; 844 actor.Position = value;
844 } 845 }
@@ -880,7 +881,7 @@ namespace OpenSim.Region.Framework.Scenes
880 ParentGroup.InvalidBoundsRadius(); 881 ParentGroup.InvalidBoundsRadius();
881 882
882 PhysicsActor actor = PhysActor; 883 PhysicsActor actor = PhysActor;
883 if (ParentID != 0 && actor != null) 884 if (_parentID != 0 && actor != null)
884 { 885 {
885 actor.Position = GetWorldPosition(); 886 actor.Position = GetWorldPosition();
886 actor.Orientation = GetWorldRotation(); 887 actor.Orientation = GetWorldRotation();
@@ -940,7 +941,7 @@ namespace OpenSim.Region.Framework.Scenes
940 PhysicsActor actor = PhysActor; 941 PhysicsActor actor = PhysActor;
941 // If this is a root of a linkset, the real rotation is what the physics engine thinks. 942 // If this is a root of a linkset, the real rotation is what the physics engine thinks.
942 // If not a root prim, the offset rotation is computed by SOG and is relative to the root. 943 // If not a root prim, the offset rotation is computed by SOG and is relative to the root.
943 if (ParentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null) 944 if (_parentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null)
944 m_rotationOffset = actor.Orientation; 945 m_rotationOffset = actor.Orientation;
945 946
946 return m_rotationOffset; 947 return m_rotationOffset;
@@ -957,7 +958,7 @@ namespace OpenSim.Region.Framework.Scenes
957 try 958 try
958 { 959 {
959 // Root prim gets value directly 960 // Root prim gets value directly
960 if (ParentID == 0) 961 if (_parentID == 0)
961 { 962 {
962 actor.Orientation = value; 963 actor.Orientation = value;
963 //m_log.Info("[PART]: RO1:" + actor.Orientation.ToString()); 964 //m_log.Info("[PART]: RO1:" + actor.Orientation.ToString());
@@ -1103,8 +1104,8 @@ namespace OpenSim.Region.Framework.Scenes
1103 { 1104 {
1104 get 1105 get
1105 { 1106 {
1106 if (m_text.Length > 255) 1107 if (m_text.Length > 256) // yes > 254
1107 return m_text.Substring(0, 254); 1108 return m_text.Substring(0, 256);
1108 return m_text; 1109 return m_text;
1109 } 1110 }
1110 set { m_text = value; } 1111 set { m_text = value; }
@@ -1258,6 +1259,9 @@ namespace OpenSim.Region.Framework.Scenes
1258 { 1259 {
1259 get 1260 get
1260 { 1261 {
1262 if (_parentID == 0)
1263 return GroupPosition;
1264
1261 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset); 1265 return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset);
1262 } 1266 }
1263 } 1267 }
@@ -1379,7 +1383,8 @@ namespace OpenSim.Region.Framework.Scenes
1379 public UUID LastOwnerID 1383 public UUID LastOwnerID
1380 { 1384 {
1381 get { return _lastOwnerID; } 1385 get { return _lastOwnerID; }
1382 set { _lastOwnerID = value; } 1386 set {
1387 _lastOwnerID = value; }
1383 } 1388 }
1384 1389
1385 public UUID RezzerID 1390 public UUID RezzerID
@@ -2422,7 +2427,7 @@ namespace OpenSim.Region.Framework.Scenes
2422 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2427 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
2423 PhysActor.OnOutOfBounds += PhysicsOutOfBounds; 2428 PhysActor.OnOutOfBounds += PhysicsOutOfBounds;
2424 2429
2425 if (ParentID != 0 && ParentID != LocalId) 2430 if (_parentID != 0 && _parentID != LocalId)
2426 { 2431 {
2427 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 2432 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
2428 2433
@@ -2788,12 +2793,13 @@ namespace OpenSim.Region.Framework.Scenes
2788 { 2793 {
2789 ColliderArgs colliderArgs = new ColliderArgs(); 2794 ColliderArgs colliderArgs = new ColliderArgs();
2790 List<DetectedObject> colliding = new List<DetectedObject>(); 2795 List<DetectedObject> colliding = new List<DetectedObject>();
2796 Scene parentScene = ParentGroup.Scene;
2791 foreach (uint localId in colliders) 2797 foreach (uint localId in colliders)
2792 { 2798 {
2793 if (localId == 0) 2799 if (localId == 0)
2794 continue; 2800 continue;
2795 2801
2796 SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); 2802 SceneObjectPart obj = parentScene.GetSceneObjectPart(localId);
2797 if (obj != null) 2803 if (obj != null)
2798 { 2804 {
2799 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name)) 2805 if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
@@ -2801,7 +2807,7 @@ namespace OpenSim.Region.Framework.Scenes
2801 } 2807 }
2802 else 2808 else
2803 { 2809 {
2804 ScenePresence av = ParentGroup.Scene.GetScenePresence(localId); 2810 ScenePresence av = parentScene.GetScenePresence(localId);
2805 if (av != null && (!av.IsChildAgent)) 2811 if (av != null && (!av.IsChildAgent))
2806 { 2812 {
2807 if (!dest.CollisionFilteredOut(av.UUID, av.Name)) 2813 if (!dest.CollisionFilteredOut(av.UUID, av.Name))
@@ -2874,10 +2880,13 @@ namespace OpenSim.Region.Framework.Scenes
2874 2880
2875 public void PhysicsCollision(EventArgs e) 2881 public void PhysicsCollision(EventArgs e)
2876 { 2882 {
2877 if (ParentGroup.Scene == null || ParentGroup.IsDeleted) 2883 if (ParentGroup.Scene == null || ParentGroup.IsDeleted || ParentGroup.inTransit)
2878 return; 2884 return;
2879 2885
2880 // this a thread from physics ( heartbeat ) 2886 // this a thread from physics ( heartbeat )
2887 bool thisHitLand = false;
2888 bool startLand = false;
2889 bool endedLand = false;
2881 2890
2882 CollisionEventUpdate a = (CollisionEventUpdate)e; 2891 CollisionEventUpdate a = (CollisionEventUpdate)e;
2883 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList; 2892 Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
@@ -2887,13 +2896,17 @@ namespace OpenSim.Region.Framework.Scenes
2887 2896
2888 if (collissionswith.Count == 0) 2897 if (collissionswith.Count == 0)
2889 { 2898 {
2890 if (m_lastColliders.Count == 0) 2899 if (m_lastColliders.Count == 0 && !m_lastLandCollide)
2891 return; // nothing to do 2900 return; // nothing to do
2892 2901
2902 endedLand = m_lastLandCollide;
2903 m_lastLandCollide = false;
2904
2893 foreach (uint localID in m_lastColliders) 2905 foreach (uint localID in m_lastColliders)
2894 { 2906 {
2895 endedColliders.Add(localID); 2907 endedColliders.Add(localID);
2896 } 2908 }
2909
2897 m_lastColliders.Clear(); 2910 m_lastColliders.Clear();
2898 } 2911 }
2899 else 2912 else
@@ -2909,19 +2922,39 @@ namespace OpenSim.Region.Framework.Scenes
2909 2922
2910 foreach (uint id in collissionswith.Keys) 2923 foreach (uint id in collissionswith.Keys)
2911 { 2924 {
2912 thisHitColliders.Add(id); 2925 if(id == 0)
2913 if (!m_lastColliders.Contains(id))
2914 { 2926 {
2915 startedColliders.Add(id); 2927 thisHitLand = true;
2916 2928 if (!m_lastLandCollide)
2917 curcontact = collissionswith[id]; 2929 {
2918 if (Math.Abs(curcontact.RelativeSpeed) > 0.2) 2930 startLand = true;
2931 curcontact = collissionswith[id];
2932 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2933 {
2934 soundinfo = new CollisionForSoundInfo();
2935 soundinfo.colliderID = id;
2936 soundinfo.position = curcontact.Position;
2937 soundinfo.relativeVel = curcontact.RelativeSpeed;
2938 soundinfolist.Add(soundinfo);
2939 }
2940 }
2941 }
2942 else
2943 {
2944 thisHitColliders.Add(id);
2945 if (!m_lastColliders.Contains(id))
2919 { 2946 {
2920 soundinfo = new CollisionForSoundInfo(); 2947 startedColliders.Add(id);
2921 soundinfo.colliderID = id; 2948
2922 soundinfo.position = curcontact.Position; 2949 curcontact = collissionswith[id];
2923 soundinfo.relativeVel = curcontact.RelativeSpeed; 2950 if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
2924 soundinfolist.Add(soundinfo); 2951 {
2952 soundinfo = new CollisionForSoundInfo();
2953 soundinfo.colliderID = id;
2954 soundinfo.position = curcontact.Position;
2955 soundinfo.relativeVel = curcontact.RelativeSpeed;
2956 soundinfolist.Add(soundinfo);
2957 }
2925 } 2958 }
2926 } 2959 }
2927 } 2960 }
@@ -2930,9 +2963,18 @@ namespace OpenSim.Region.Framework.Scenes
2930 { 2963 {
2931 foreach (uint id in collissionswith.Keys) 2964 foreach (uint id in collissionswith.Keys)
2932 { 2965 {
2933 thisHitColliders.Add(id); 2966 if(id == 0)
2934 if (!m_lastColliders.Contains(id)) 2967 {
2935 startedColliders.Add(id); 2968 thisHitLand = true;
2969 if (!m_lastLandCollide)
2970 startLand = true;
2971 }
2972 else
2973 {
2974 thisHitColliders.Add(id);
2975 if (!m_lastColliders.Contains(id))
2976 startedColliders.Add(id);
2977 }
2936 } 2978 }
2937 } 2979 }
2938 2980
@@ -2951,22 +2993,32 @@ namespace OpenSim.Region.Framework.Scenes
2951 foreach (uint localID in endedColliders) 2993 foreach (uint localID in endedColliders)
2952 m_lastColliders.Remove(localID); 2994 m_lastColliders.Remove(localID);
2953 2995
2996 if(m_lastLandCollide && !thisHitLand)
2997 endedLand = true;
2998
2999 m_lastLandCollide = thisHitLand;
3000
2954 // play sounds. 3001 // play sounds.
2955 if (soundinfolist.Count > 0) 3002 if (soundinfolist.Count > 0)
2956 CollisionSounds.PartCollisionSound(this, soundinfolist); 3003 CollisionSounds.PartCollisionSound(this, soundinfolist);
2957 } 3004 }
3005
3006 EventManager eventmanager = ParentGroup.Scene.EventManager;
2958 3007
2959 SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); 3008 SendCollisionEvent(scriptEvents.collision_start, startedColliders, eventmanager.TriggerScriptCollidingStart);
2960 if (!VolumeDetectActive) 3009 if (!VolumeDetectActive)
2961 SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); 3010 SendCollisionEvent(scriptEvents.collision , m_lastColliders , eventmanager.TriggerScriptColliding);
2962 SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); 3011 SendCollisionEvent(scriptEvents.collision_end , endedColliders , eventmanager.TriggerScriptCollidingEnd);
2963 3012
2964 if (startedColliders.Contains(0)) 3013 if (!VolumeDetectActive)
2965 SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart); 3014 {
2966 if (m_lastColliders.Contains(0)) 3015 if (startLand)
2967 SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); 3016 SendLandCollisionEvent(scriptEvents.land_collision_start, eventmanager.TriggerScriptLandCollidingStart);
2968 if (endedColliders.Contains(0)) 3017 if (m_lastLandCollide)
2969 SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); 3018 SendLandCollisionEvent(scriptEvents.land_collision, eventmanager.TriggerScriptLandColliding);
3019 if (endedLand)
3020 SendLandCollisionEvent(scriptEvents.land_collision_end, eventmanager.TriggerScriptLandCollidingEnd);
3021 }
2970 } 3022 }
2971 3023
2972 // The Collision sounds code calls this 3024 // The Collision sounds code calls this
@@ -2985,7 +3037,7 @@ namespace OpenSim.Region.Framework.Scenes
2985 volume = 0; 3037 volume = 0;
2986 3038
2987 int now = Util.EnvironmentTickCount(); 3039 int now = Util.EnvironmentTickCount();
2988 if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200) 3040 if(Util.EnvironmentTickCountSubtract(now, LastColSoundSentTime) < 200)
2989 return; 3041 return;
2990 3042
2991 LastColSoundSentTime = now; 3043 LastColSoundSentTime = now;
@@ -3026,7 +3078,7 @@ namespace OpenSim.Region.Framework.Scenes
3026 //ParentGroup.RootPart.m_groupPosition = newpos; 3078 //ParentGroup.RootPart.m_groupPosition = newpos;
3027 } 3079 }
3028/* 3080/*
3029 if (pa != null && ParentID != 0 && ParentGroup != null) 3081 if (pa != null && _parentID != 0 && ParentGroup != null)
3030 { 3082 {
3031 // Special case where a child object is requesting property updates. 3083 // Special case where a child object is requesting property updates.
3032 // This happens when linksets are modified to use flexible links rather than 3084 // This happens when linksets are modified to use flexible links rather than
@@ -3236,7 +3288,7 @@ namespace OpenSim.Region.Framework.Scenes
3236 3288
3237 /// <summary> 3289 /// <summary>
3238 /// Schedule a terse update for this prim. Terse updates only send position, 3290 /// Schedule a terse update for this prim. Terse updates only send position,
3239 /// rotation, velocity and rotational velocity information. 3291 /// rotation, velocity and rotational velocity information. WRONG!!!!
3240 /// </summary> 3292 /// </summary>
3241 public void ScheduleTerseUpdate() 3293 public void ScheduleTerseUpdate()
3242 { 3294 {
@@ -3295,21 +3347,6 @@ namespace OpenSim.Region.Framework.Scenes
3295 sp.SendAttachmentUpdate(this, UpdateRequired.FULL); 3347 sp.SendAttachmentUpdate(this, UpdateRequired.FULL);
3296 } 3348 }
3297 } 3349 }
3298
3299/* this does nothing
3300SendFullUpdateToClient(remoteClient, Position) ignores position parameter
3301 if (IsRoot)
3302 {
3303 if (ParentGroup.IsAttachment)
3304 {
3305 SendFullUpdateToClient(remoteClient, AttachedPos);
3306 }
3307 else
3308 {
3309 SendFullUpdateToClient(remoteClient, AbsolutePosition);
3310 }
3311 }
3312*/
3313 else 3350 else
3314 { 3351 {
3315 SendFullUpdateToClient(remoteClient); 3352 SendFullUpdateToClient(remoteClient);
@@ -3325,12 +3362,12 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
3325 return; 3362 return;
3326 3363
3327 // Update the "last" values 3364 // Update the "last" values
3328 m_lastPosition = OffsetPosition; 3365 m_lastPosition = AbsolutePosition;
3329 m_lastRotation = RotationOffset; 3366 m_lastRotation = RotationOffset;
3330 m_lastVelocity = Velocity; 3367 m_lastVelocity = Velocity;
3331 m_lastAcceleration = Acceleration; 3368 m_lastAcceleration = Acceleration;
3332 m_lastAngularVelocity = AngularVelocity; 3369 m_lastAngularVelocity = AngularVelocity;
3333 m_lastUpdateSentTime = Environment.TickCount; 3370 m_lastUpdateSentTime = Util.GetTimeStampMS();
3334 3371
3335 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3372 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3336 { 3373 {
@@ -3344,12 +3381,12 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
3344 return; 3381 return;
3345 3382
3346 // Update the "last" values 3383 // Update the "last" values
3347 m_lastPosition = OffsetPosition; 3384 m_lastPosition = AbsolutePosition;
3348 m_lastRotation = RotationOffset; 3385 m_lastRotation = RotationOffset;
3349 m_lastVelocity = Velocity; 3386 m_lastVelocity = Velocity;
3350 m_lastAcceleration = Acceleration; 3387 m_lastAcceleration = Acceleration;
3351 m_lastAngularVelocity = AngularVelocity; 3388 m_lastAngularVelocity = AngularVelocity;
3352 m_lastUpdateSentTime = Environment.TickCount; 3389 m_lastUpdateSentTime = Util.GetTimeStampMS();
3353 3390
3354 if (ParentGroup.IsAttachment) 3391 if (ParentGroup.IsAttachment)
3355 { 3392 {
@@ -3395,40 +3432,129 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
3395 ParentGroup.Scene.StatsReporter.AddObjectUpdates(1); 3432 ParentGroup.Scene.StatsReporter.AddObjectUpdates(1);
3396 } 3433 }
3397 3434
3435
3436 private const float ROTATION_TOLERANCE = 0.01f;
3437 private const float VELOCITY_TOLERANCE = 0.1f; // terse update vel has low resolution
3438 private const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
3439 private const double TIME_MS_TOLERANCE = 200f; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
3440
3398 /// <summary> 3441 /// <summary>
3399 /// Tell all the prims which have had updates scheduled 3442 /// Tell all the prims which have had updates scheduled
3400 /// </summary> 3443 /// </summary>
3401 public void SendScheduledUpdates() 3444 public void SendScheduledUpdates()
3402 { 3445 {
3403 const float ROTATION_TOLERANCE = 0.01f;
3404 const float VELOCITY_TOLERANCE = 0.001f;
3405 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
3406 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
3407
3408 switch (UpdateFlag) 3446 switch (UpdateFlag)
3409 { 3447 {
3448 case UpdateRequired.NONE:
3449 ClearUpdateSchedule();
3450 break;
3451
3410 case UpdateRequired.TERSE: 3452 case UpdateRequired.TERSE:
3411 { 3453
3412 ClearUpdateSchedule(); 3454 ClearUpdateSchedule();
3413 // Throw away duplicate or insignificant updates 3455 bool needupdate = true;
3414 if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || 3456 double now = Util.GetTimeStampMS();
3415 !Acceleration.Equals(m_lastAcceleration) || 3457 Vector3 curvel = Velocity;
3416 !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || 3458 Vector3 curacc = Acceleration;
3417 Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || 3459 Vector3 angvel = AngularVelocity;
3418 !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || 3460
3419 !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || 3461 while(true) // just to avoid ugly goto
3420 Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE) 3462 {
3463 double elapsed = now - m_lastUpdateSentTime;
3464 if (elapsed > TIME_MS_TOLERANCE)
3465 break;
3466
3467 if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE ||
3468 Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE ||
3469 Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE)
3470 break;
3471
3472 // velocity change is also direction not only norm)
3473 if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
3474 Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
3475 Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE)
3476 break;
3477
3478 float vx = Math.Abs(curvel.X);
3479 if(vx > 128.0)
3480 break;
3481 float vy = Math.Abs(curvel.Y);
3482 if(vy > 128.0)
3483 break;
3484 float vz = Math.Abs(curvel.Z);
3485 if(vz > 128.0)
3486 break;
3487
3488 if (
3489 vx < VELOCITY_TOLERANCE &&
3490 vy < VELOCITY_TOLERANCE &&
3491 vz < VELOCITY_TOLERANCE
3492 )
3493 {
3494 if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
3495 break;
3496
3497 if (vx < 1e-4 &&
3498 vy < 1e-4 &&
3499 vz < 1e-4 &&
3500 (
3501 Math.Abs(m_lastVelocity.X) > 1e-4 ||
3502 Math.Abs(m_lastVelocity.Y) > 1e-4 ||
3503 Math.Abs(m_lastVelocity.Z) > 1e-4
3504 ))
3505 break;
3506 }
3507
3508 if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > VELOCITY_TOLERANCE ||
3509 Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > VELOCITY_TOLERANCE ||
3510 Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > VELOCITY_TOLERANCE)
3511 break;
3512
3513 // viewer interpolators have a limit of 128m/s
3514 float ax = Math.Abs(angvel.X);
3515 if(ax > 64.0)
3516 break;
3517 float ay = Math.Abs(angvel.Y);
3518 if(ay > 64.0)
3519 break;
3520 float az = Math.Abs(angvel.Z);
3521 if(az > 64.0)
3522 break;
3523
3524 if (
3525 ax < VELOCITY_TOLERANCE &&
3526 ay < VELOCITY_TOLERANCE &&
3527 az < VELOCITY_TOLERANCE &&
3528 !RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
3529 )
3530 break;
3531
3532 needupdate = false;
3533 break;
3534 }
3535
3536 if(needupdate)
3421 { 3537 {
3422 SendTerseUpdateToAllClientsInternal(); 3538
3539 // Update the "last" values
3540 m_lastPosition = AbsolutePosition;
3541 m_lastRotation = RotationOffset;
3542 m_lastVelocity = curvel;
3543 m_lastAcceleration = curacc;
3544 m_lastAngularVelocity = angvel;
3545 m_lastUpdateSentTime = now;
3546
3547 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
3548 {
3549 SendTerseUpdateToClient(client);
3550 });
3423 } 3551 }
3424 break; 3552 break;
3425 } 3553
3426 case UpdateRequired.FULL: 3554 case UpdateRequired.FULL:
3427 {
3428 ClearUpdateSchedule(); 3555 ClearUpdateSchedule();
3429 SendFullUpdateToAllClientsInternal(); 3556 SendFullUpdateToAllClientsInternal();
3430 break; 3557 break;
3431 }
3432 } 3558 }
3433 } 3559 }
3434 3560
@@ -3441,13 +3567,15 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
3441 if (ParentGroup == null || ParentGroup.Scene == null) 3567 if (ParentGroup == null || ParentGroup.Scene == null)
3442 return; 3568 return;
3443 3569
3570 ClearUpdateSchedule();
3571
3444 // Update the "last" values 3572 // Update the "last" values
3445 m_lastPosition = OffsetPosition; 3573 m_lastPosition = AbsolutePosition;
3446 m_lastRotation = RotationOffset; 3574 m_lastRotation = RotationOffset;
3447 m_lastVelocity = Velocity; 3575 m_lastVelocity = Velocity;
3448 m_lastAcceleration = Acceleration; 3576 m_lastAcceleration = Acceleration;
3449 m_lastAngularVelocity = AngularVelocity; 3577 m_lastAngularVelocity = AngularVelocity;
3450 m_lastUpdateSentTime = Environment.TickCount; 3578 m_lastUpdateSentTime = Util.GetTimeStampMS();
3451 3579
3452 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3580 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
3453 { 3581 {
@@ -3460,13 +3588,15 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
3460 if (ParentGroup == null || ParentGroup.Scene == null) 3588 if (ParentGroup == null || ParentGroup.Scene == null)
3461 return; 3589 return;
3462 3590
3591 ClearUpdateSchedule();
3592
3463 // Update the "last" values 3593 // Update the "last" values
3464 m_lastPosition = OffsetPosition; 3594 m_lastPosition = AbsolutePosition;
3465 m_lastRotation = RotationOffset; 3595 m_lastRotation = RotationOffset;
3466 m_lastVelocity = Velocity; 3596 m_lastVelocity = Velocity;
3467 m_lastAcceleration = Acceleration; 3597 m_lastAcceleration = Acceleration;
3468 m_lastAngularVelocity = AngularVelocity; 3598 m_lastAngularVelocity = AngularVelocity;
3469 m_lastUpdateSentTime = Environment.TickCount; 3599 m_lastUpdateSentTime = Util.GetTimeStampMS();
3470 3600
3471 if (ParentGroup.IsAttachment) 3601 if (ParentGroup.IsAttachment)
3472 { 3602 {
@@ -4783,7 +4913,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter
4783 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 4913 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
4784 pa.OnOutOfBounds += PhysicsOutOfBounds; 4914 pa.OnOutOfBounds += PhysicsOutOfBounds;
4785 4915
4786 if (ParentID != 0 && ParentID != LocalId) 4916 if (_parentID != 0 && _parentID != LocalId)
4787 { 4917 {
4788 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; 4918 PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
4789 4919
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 7e3adb9..ba3aaae 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -279,8 +279,11 @@ namespace OpenSim.Region.Framework.Scenes
279 private bool MouseDown = false; 279 private bool MouseDown = false;
280 public Vector3 lastKnownAllowedPosition; 280 public Vector3 lastKnownAllowedPosition;
281 public bool sentMessageAboutRestrictedParcelFlyingDown; 281 public bool sentMessageAboutRestrictedParcelFlyingDown;
282
282 public Vector4 CollisionPlane = Vector4.UnitW; 283 public Vector4 CollisionPlane = Vector4.UnitW;
283 284
285 public Vector4 m_lastCollisionPlane = Vector4.UnitW;
286 private byte m_lastState;
284 private Vector3 m_lastPosition; 287 private Vector3 m_lastPosition;
285 private Quaternion m_lastRotation; 288 private Quaternion m_lastRotation;
286 private Vector3 m_lastVelocity; 289 private Vector3 m_lastVelocity;
@@ -2818,16 +2821,13 @@ namespace OpenSim.Region.Framework.Scenes
2818 CameraAtAxis = agentData.CameraAtAxis; 2821 CameraAtAxis = agentData.CameraAtAxis;
2819 CameraLeftAxis = agentData.CameraLeftAxis; 2822 CameraLeftAxis = agentData.CameraLeftAxis;
2820 CameraUpAxis = agentData.CameraUpAxis; 2823 CameraUpAxis = agentData.CameraUpAxis;
2821 Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis);
2822 CameraRotation = camRot;
2823
2824 // The Agent's Draw distance setting
2825 // When we get to the point of re-computing neighbors everytime this
2826 // changes, then start using the agent's drawdistance rather than the
2827 // region's draw distance.
2828
2829 DrawDistance = agentData.Far; 2824 DrawDistance = agentData.Far;
2830 2825
2826 CameraAtAxis.Normalize();
2827 CameraLeftAxis.Normalize();
2828 CameraUpAxis.Normalize();
2829 Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis);
2830 CameraRotation = camRot;
2831 2831
2832 // Check if Client has camera in 'follow cam' or 'build' mode. 2832 // Check if Client has camera in 'follow cam' or 'build' mode.
2833// Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation); 2833// Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
@@ -3789,29 +3789,21 @@ namespace OpenSim.Region.Framework.Scenes
3789 3789
3790 // Send terse position update if not sitting and position, velocity, or rotation 3790 // Send terse position update if not sitting and position, velocity, or rotation
3791 // has changed significantly from last sent update 3791 // has changed significantly from last sent update
3792 if (!IsSatOnObject && (
3793 !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
3794 || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
3795 || !m_pos.ApproxEquals(m_lastPosition, POSITION_LARGETOLERANCE)
3796 // if velocity is zero and it wasn't zero last time, send the update
3797 || (Velocity == Vector3.Zero && m_lastVelocity != Vector3.Zero)
3798 // if position has moved just a little and velocity is very low, send the update
3799 || (!m_pos.ApproxEquals(m_lastPosition, POSITION_SMALLTOLERANCE) && Velocity.LengthSquared() < LOWVELOCITYSQ )
3800 ) )
3801 {
3802/*
3803 if (!IsSatOnObject) 3792 if (!IsSatOnObject)
3804 { 3793 {
3805 // this does need to be more complex later 3794 // this does need to be more complex later
3806 Vector3 vel = Velocity; 3795 Vector3 vel = Velocity;
3807 Vector3 dpos = m_pos - m_lastPosition; 3796 Vector3 dpos = m_pos - m_lastPosition;
3808 if( Math.Abs(vel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE || 3797 if( State != m_lastState ||
3798 Math.Abs(vel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
3809 Math.Abs(vel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE || 3799 Math.Abs(vel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
3810 Math.Abs(vel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE || 3800 Math.Abs(vel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE ||
3811 3801
3812 Math.Abs(m_bodyRot.X - m_lastRotation.X) > ROTATION_TOLERANCE || 3802 Math.Abs(m_bodyRot.X - m_lastRotation.X) > ROTATION_TOLERANCE ||
3813 Math.Abs(m_bodyRot.Y - m_lastRotation.Y) > ROTATION_TOLERANCE || 3803 Math.Abs(m_bodyRot.Y - m_lastRotation.Y) > ROTATION_TOLERANCE ||
3814 Math.Abs(m_bodyRot.Z - m_lastRotation.Z) > ROTATION_TOLERANCE || 3804 Math.Abs(m_bodyRot.Z - m_lastRotation.Z) > ROTATION_TOLERANCE ||
3805
3806 (vel == Vector3.Zero && m_lastVelocity != Vector3.Zero) ||
3815 3807
3816 Math.Abs(dpos.X) > POSITION_LARGETOLERANCE || 3808 Math.Abs(dpos.X) > POSITION_LARGETOLERANCE ||
3817 Math.Abs(dpos.Y) > POSITION_LARGETOLERANCE || 3809 Math.Abs(dpos.Y) > POSITION_LARGETOLERANCE ||
@@ -3821,11 +3813,15 @@ namespace OpenSim.Region.Framework.Scenes
3821 Math.Abs(dpos.Y) > POSITION_SMALLTOLERANCE || 3813 Math.Abs(dpos.Y) > POSITION_SMALLTOLERANCE ||
3822 Math.Abs(dpos.Z) > POSITION_SMALLTOLERANCE) 3814 Math.Abs(dpos.Z) > POSITION_SMALLTOLERANCE)
3823 && vel.LengthSquared() < LOWVELOCITYSQ 3815 && vel.LengthSquared() < LOWVELOCITYSQ
3824 )) 3816 ) ||
3817
3818 Math.Abs(CollisionPlane.X - m_lastCollisionPlane.X) > POSITION_SMALLTOLERANCE ||
3819 Math.Abs(CollisionPlane.Y - m_lastCollisionPlane.Y) > POSITION_SMALLTOLERANCE ||
3820 Math.Abs(CollisionPlane.W - m_lastCollisionPlane.W) > POSITION_SMALLTOLERANCE
3821 )
3825 { 3822 {
3826*/
3827 SendTerseUpdateToAllClients(); 3823 SendTerseUpdateToAllClients();
3828// } 3824 }
3829 } 3825 }
3830 CheckForSignificantMovement(); 3826 CheckForSignificantMovement();
3831 } 3827 }
@@ -3921,11 +3917,14 @@ namespace OpenSim.Region.Framework.Scenes
3921 /// </summary> 3917 /// </summary>
3922 public void SendTerseUpdateToAllClients() 3918 public void SendTerseUpdateToAllClients()
3923 { 3919 {
3924 m_scene.ForEachScenePresence(SendTerseUpdateToAgent); 3920 m_lastState = State;
3925 // Update the "last" values
3926 m_lastPosition = m_pos; 3921 m_lastPosition = m_pos;
3927 m_lastRotation = m_bodyRot; 3922 m_lastRotation = m_bodyRot;
3928 m_lastVelocity = Velocity; 3923 m_lastVelocity = Velocity;
3924 m_lastCollisionPlane = CollisionPlane;
3925
3926 m_scene.ForEachScenePresence(SendTerseUpdateToAgent);
3927 // Update the "last" values
3929 TriggerScenePresenceUpdated(); 3928 TriggerScenePresenceUpdated();
3930 } 3929 }
3931 3930
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
index 7f7977e..41f3ef4 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
@@ -86,9 +86,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
86 86
87 writer.WriteStartElement("CoalescedObject"); 87 writer.WriteStartElement("CoalescedObject");
88 88
89 writer.WriteAttributeString("x", size.X.ToString()); 89 writer.WriteAttributeString("x", size.X.ToString(Culture.FormatProvider));
90 writer.WriteAttributeString("y", size.Y.ToString()); 90 writer.WriteAttributeString("y", size.Y.ToString(Culture.FormatProvider));
91 writer.WriteAttributeString("z", size.Z.ToString()); 91 writer.WriteAttributeString("z", size.Z.ToString(Culture.FormatProvider));
92 92
93 // Embed the offsets into the group XML 93 // Embed the offsets into the group XML
94 for (int i = 0; i < coaObjects.Count; i++) 94 for (int i = 0; i < coaObjects.Count; i++)
@@ -100,9 +100,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
100// i, obj.Name); 100// i, obj.Name);
101 101
102 writer.WriteStartElement("SceneObjectGroup"); 102 writer.WriteStartElement("SceneObjectGroup");
103 writer.WriteAttributeString("offsetx", offsets[i].X.ToString()); 103 writer.WriteAttributeString("offsetx", offsets[i].X.ToString(Culture.FormatProvider));
104 writer.WriteAttributeString("offsety", offsets[i].Y.ToString()); 104 writer.WriteAttributeString("offsety", offsets[i].Y.ToString(Culture.FormatProvider));
105 writer.WriteAttributeString("offsetz", offsets[i].Z.ToString()); 105 writer.WriteAttributeString("offsetz", offsets[i].Z.ToString(Culture.FormatProvider));
106 106
107 SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates); 107 SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates);
108 108
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index b012a08..82bbe6f 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -65,7 +65,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
65 { 65 {
66 using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) 66 using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
67 { 67 {
68 try { 68 try
69 {
69 return FromOriginalXmlFormat(reader); 70 return FromOriginalXmlFormat(reader);
70 } 71 }
71 catch (Exception e) 72 catch (Exception e)
@@ -109,11 +110,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
109 } 110 }
110 } 111 }
111 while (reader.ReadToNextSibling("Part")); 112 while (reader.ReadToNextSibling("Part"));
113 reader.ReadEndElement();
114 }
115
116 if (reader.Name == "KeyframeMotion" && reader.NodeType == XmlNodeType.Element)
117 {
118
119 string innerkeytxt = reader.ReadElementContentAsString();
120 sceneObject.RootPart.KeyframeMotion =
121 KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(innerkeytxt));
112 } 122 }
123 else
124 sceneObject.RootPart.KeyframeMotion = null;
113 125
114 // Script state may, or may not, exist. Not having any, is NOT 126 // Script state may, or may not, exist. Not having any, is NOT
115 // ever a problem. 127 // ever a problem.
116 sceneObject.LoadScriptState(reader); 128 sceneObject.LoadScriptState(reader);
129
117 sceneObject.InvalidateDeepEffectivePerms(); 130 sceneObject.InvalidateDeepEffectivePerms();
118 return sceneObject; 131 return sceneObject;
119 } 132 }
@@ -210,9 +223,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
210 223
211 writer.WriteEndElement(); // OtherParts 224 writer.WriteEndElement(); // OtherParts
212 225
226 if (sceneObject.RootPart.KeyframeMotion != null)
227 {
228 Byte[] data = sceneObject.RootPart.KeyframeMotion.Serialize();
229
230 writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty);
231 writer.WriteBase64(data, 0, data.Length);
232 writer.WriteEndElement();
233 }
234
213 if (doScriptStates) 235 if (doScriptStates)
214 sceneObject.SaveScriptedState(writer); 236 sceneObject.SaveScriptedState(writer);
215 237
238
216 if (!noRootElement) 239 if (!noRootElement)
217 writer.WriteEndElement(); // SceneObjectGroup 240 writer.WriteEndElement(); // SceneObjectGroup
218 241
@@ -1459,10 +1482,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1459 writer.WriteElementString("Description", sop.Description); 1482 writer.WriteElementString("Description", sop.Description);
1460 1483
1461 writer.WriteStartElement("Color"); 1484 writer.WriteStartElement("Color");
1462 writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture)); 1485 writer.WriteElementString("R", sop.Color.R.ToString(Culture.FormatProvider));
1463 writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture)); 1486 writer.WriteElementString("G", sop.Color.G.ToString(Culture.FormatProvider));
1464 writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture)); 1487 writer.WriteElementString("B", sop.Color.B.ToString(Culture.FormatProvider));
1465 writer.WriteElementString("A", sop.Color.A.ToString(Utils.EnUsCulture)); 1488 writer.WriteElementString("A", sop.Color.A.ToString(Culture.FormatProvider));
1466 writer.WriteEndElement(); 1489 writer.WriteEndElement();
1467 1490
1468 writer.WriteElementString("Text", sop.Text); 1491 writer.WriteElementString("Text", sop.Text);
@@ -1505,7 +1528,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1505 writer.WriteElementString("NextOwnerMask", sop.NextOwnerMask.ToString()); 1528 writer.WriteElementString("NextOwnerMask", sop.NextOwnerMask.ToString());
1506 WriteFlags(writer, "Flags", sop.Flags.ToString(), options); 1529 WriteFlags(writer, "Flags", sop.Flags.ToString(), options);
1507 WriteUUID(writer, "CollisionSound", sop.CollisionSound, options); 1530 WriteUUID(writer, "CollisionSound", sop.CollisionSound, options);
1508 writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString()); 1531 writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString(Culture.FormatProvider));
1509 if (sop.MediaUrl != null) 1532 if (sop.MediaUrl != null)
1510 writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString()); 1533 writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString());
1511 WriteVector(writer, "AttachedPos", sop.AttachedPos); 1534 WriteVector(writer, "AttachedPos", sop.AttachedPos);
@@ -1525,7 +1548,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1525 writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString()); 1548 writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString());
1526 writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString()); 1549 writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString());
1527 1550
1528 writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString()); 1551 writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString(Culture.FormatProvider));
1529 1552
1530 WriteVector(writer, "Force", sop.Force); 1553 WriteVector(writer, "Force", sop.Force);
1531 WriteVector(writer, "Torque", sop.Torque); 1554 WriteVector(writer, "Torque", sop.Torque);
@@ -1542,22 +1565,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1542 writer.WriteElementString("RotationAxisLocks", sop.RotationAxisLocks.ToString().ToLower()); 1565 writer.WriteElementString("RotationAxisLocks", sop.RotationAxisLocks.ToString().ToLower());
1543 writer.WriteElementString("PhysicsShapeType", sop.PhysicsShapeType.ToString().ToLower()); 1566 writer.WriteElementString("PhysicsShapeType", sop.PhysicsShapeType.ToString().ToLower());
1544 if (sop.Density != 1000.0f) 1567 if (sop.Density != 1000.0f)
1545 writer.WriteElementString("Density", sop.Density.ToString().ToLower()); 1568 writer.WriteElementString("Density", sop.Density.ToString(Culture.FormatProvider));
1546 if (sop.Friction != 0.6f) 1569 if (sop.Friction != 0.6f)
1547 writer.WriteElementString("Friction", sop.Friction.ToString().ToLower()); 1570 writer.WriteElementString("Friction", sop.Friction.ToString(Culture.FormatProvider));
1548 if (sop.Restitution != 0.5f) 1571 if (sop.Restitution != 0.5f)
1549 writer.WriteElementString("Bounce", sop.Restitution.ToString().ToLower()); 1572 writer.WriteElementString("Bounce", sop.Restitution.ToString(Culture.FormatProvider));
1550 if (sop.GravityModifier != 1.0f) 1573 if (sop.GravityModifier != 1.0f)
1551 writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower()); 1574 writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString(Culture.FormatProvider));
1552 WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset()); 1575 WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset());
1553 WriteVector(writer, "CameraAtOffset", sop.GetCameraAtOffset()); 1576 WriteVector(writer, "CameraAtOffset", sop.GetCameraAtOffset());
1554 1577
1555 // if (sop.Sound != UUID.Zero) force it till sop crossing does clear it on child prim 1578 // if (sop.Sound != UUID.Zero) force it till sop crossing does clear it on child prim
1556 { 1579 {
1557 WriteUUID(writer, "SoundID", sop.Sound, options); 1580 WriteUUID(writer, "SoundID", sop.Sound, options);
1558 writer.WriteElementString("SoundGain", sop.SoundGain.ToString().ToLower()); 1581 writer.WriteElementString("SoundGain", sop.SoundGain.ToString(Culture.FormatProvider));
1559 writer.WriteElementString("SoundFlags", sop.SoundFlags.ToString().ToLower()); 1582 writer.WriteElementString("SoundFlags", sop.SoundFlags.ToString().ToLower());
1560 writer.WriteElementString("SoundRadius", sop.SoundRadius.ToString().ToLower()); 1583 writer.WriteElementString("SoundRadius", sop.SoundRadius.ToString(Culture.FormatProvider));
1561 } 1584 }
1562 writer.WriteElementString("SoundQueueing", sop.SoundQueueing.ToString().ToLower()); 1585 writer.WriteElementString("SoundQueueing", sop.SoundQueueing.ToString().ToLower());
1563 1586
@@ -1577,19 +1600,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1577 static void WriteVector(XmlTextWriter writer, string name, Vector3 vec) 1600 static void WriteVector(XmlTextWriter writer, string name, Vector3 vec)
1578 { 1601 {
1579 writer.WriteStartElement(name); 1602 writer.WriteStartElement(name);
1580 writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture)); 1603 writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider));
1581 writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture)); 1604 writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider));
1582 writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture)); 1605 writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider));
1583 writer.WriteEndElement(); 1606 writer.WriteEndElement();
1584 } 1607 }
1585 1608
1586 static void WriteQuaternion(XmlTextWriter writer, string name, Quaternion quat) 1609 static void WriteQuaternion(XmlTextWriter writer, string name, Quaternion quat)
1587 { 1610 {
1588 writer.WriteStartElement(name); 1611 writer.WriteStartElement(name);
1589 writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture)); 1612 writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider));
1590 writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture)); 1613 writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider));
1591 writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture)); 1614 writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider));
1592 writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture)); 1615 writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider));
1593 writer.WriteEndElement(); 1616 writer.WriteEndElement();
1594 } 1617 }
1595 1618
@@ -1731,22 +1754,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1731 // Don't serialize SculptData. It's just a copy of the asset, which can be loaded separately using 'SculptTexture'. 1754 // Don't serialize SculptData. It's just a copy of the asset, which can be loaded separately using 'SculptTexture'.
1732 1755
1733 writer.WriteElementString("FlexiSoftness", shp.FlexiSoftness.ToString()); 1756 writer.WriteElementString("FlexiSoftness", shp.FlexiSoftness.ToString());
1734 writer.WriteElementString("FlexiTension", shp.FlexiTension.ToString()); 1757 writer.WriteElementString("FlexiTension", shp.FlexiTension.ToString(Culture.FormatProvider));
1735 writer.WriteElementString("FlexiDrag", shp.FlexiDrag.ToString()); 1758 writer.WriteElementString("FlexiDrag", shp.FlexiDrag.ToString(Culture.FormatProvider));
1736 writer.WriteElementString("FlexiGravity", shp.FlexiGravity.ToString()); 1759 writer.WriteElementString("FlexiGravity", shp.FlexiGravity.ToString(Culture.FormatProvider));
1737 writer.WriteElementString("FlexiWind", shp.FlexiWind.ToString()); 1760 writer.WriteElementString("FlexiWind", shp.FlexiWind.ToString(Culture.FormatProvider));
1738 writer.WriteElementString("FlexiForceX", shp.FlexiForceX.ToString()); 1761 writer.WriteElementString("FlexiForceX", shp.FlexiForceX.ToString(Culture.FormatProvider));
1739 writer.WriteElementString("FlexiForceY", shp.FlexiForceY.ToString()); 1762 writer.WriteElementString("FlexiForceY", shp.FlexiForceY.ToString(Culture.FormatProvider));
1740 writer.WriteElementString("FlexiForceZ", shp.FlexiForceZ.ToString()); 1763 writer.WriteElementString("FlexiForceZ", shp.FlexiForceZ.ToString(Culture.FormatProvider));
1741 1764
1742 writer.WriteElementString("LightColorR", shp.LightColorR.ToString()); 1765 writer.WriteElementString("LightColorR", shp.LightColorR.ToString(Culture.FormatProvider));
1743 writer.WriteElementString("LightColorG", shp.LightColorG.ToString()); 1766 writer.WriteElementString("LightColorG", shp.LightColorG.ToString(Culture.FormatProvider));
1744 writer.WriteElementString("LightColorB", shp.LightColorB.ToString()); 1767 writer.WriteElementString("LightColorB", shp.LightColorB.ToString(Culture.FormatProvider));
1745 writer.WriteElementString("LightColorA", shp.LightColorA.ToString()); 1768 writer.WriteElementString("LightColorA", shp.LightColorA.ToString(Culture.FormatProvider));
1746 writer.WriteElementString("LightRadius", shp.LightRadius.ToString()); 1769 writer.WriteElementString("LightRadius", shp.LightRadius.ToString(Culture.FormatProvider));
1747 writer.WriteElementString("LightCutoff", shp.LightCutoff.ToString()); 1770 writer.WriteElementString("LightCutoff", shp.LightCutoff.ToString(Culture.FormatProvider));
1748 writer.WriteElementString("LightFalloff", shp.LightFalloff.ToString()); 1771 writer.WriteElementString("LightFalloff", shp.LightFalloff.ToString(Culture.FormatProvider));
1749 writer.WriteElementString("LightIntensity", shp.LightIntensity.ToString()); 1772 writer.WriteElementString("LightIntensity", shp.LightIntensity.ToString(Culture.FormatProvider));
1750 1773
1751 writer.WriteElementString("FlexiEntry", shp.FlexiEntry.ToString().ToLower()); 1774 writer.WriteElementString("FlexiEntry", shp.FlexiEntry.ToString().ToLower());
1752 writer.WriteElementString("LightEntry", shp.LightEntry.ToString().ToLower()); 1775 writer.WriteElementString("LightEntry", shp.LightEntry.ToString().ToLower());
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs
index 045fd3c..4ce6a95 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs
@@ -54,8 +54,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
54 54
55 UUID ownerId = TestHelpers.ParseTail(0x1); 55 UUID ownerId = TestHelpers.ParseTail(0x1);
56 SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(3, ownerId, "so1", 0x10); 56 SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(3, ownerId, "so1", 0x10);
57 so1.ScriptSetPhysicsStatus(true);
58 m_scene.AddSceneObject(so1); 57 m_scene.AddSceneObject(so1);
58 so1.ScriptSetPhysicsStatus(true);
59 59
60 Assert.That(m_scene.SceneGraph.GetTotalObjectsCount(), Is.EqualTo(3)); 60 Assert.That(m_scene.SceneGraph.GetTotalObjectsCount(), Is.EqualTo(3));
61 Assert.That(m_scene.SceneGraph.GetActiveObjectsCount(), Is.EqualTo(3)); 61 Assert.That(m_scene.SceneGraph.GetActiveObjectsCount(), Is.EqualTo(3));
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index 5a9a5a0..80d3f62 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -65,7 +65,10 @@ namespace OpenSim.Region.Framework.Scenes
65 /// </summary> 65 /// </summary>
66 /// <value>The gathered uuids.</value> 66 /// <value>The gathered uuids.</value>
67 public IDictionary<UUID, sbyte> GatheredUuids { get; private set; } 67 public IDictionary<UUID, sbyte> GatheredUuids { get; private set; }
68 68 public HashSet<UUID> FailedUUIDs { get; private set; }
69 public HashSet<UUID> UncertainAssetsUUIDs { get; private set; }
70 public int possibleNotAssetCount { get; set; }
71 public int ErrorCount { get; private set; }
69 /// <summary> 72 /// <summary>
70 /// Gets the next UUID to inspect. 73 /// Gets the next UUID to inspect.
71 /// </summary> 74 /// </summary>
@@ -92,7 +95,10 @@ namespace OpenSim.Region.Framework.Scenes
92 /// <param name="assetService"> 95 /// <param name="assetService">
93 /// Asset service. 96 /// Asset service.
94 /// </param> 97 /// </param>
95 public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary<UUID, sbyte>()) {} 98 public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary<UUID, sbyte>(),
99 new HashSet <UUID>(),new HashSet <UUID>()) {}
100 public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector) : this(assetService, collector,
101 new HashSet <UUID>(), new HashSet <UUID>()) {}
96 102
97 /// <summary> 103 /// <summary>
98 /// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class. 104 /// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class.
@@ -101,16 +107,20 @@ namespace OpenSim.Region.Framework.Scenes
101 /// Asset service. 107 /// Asset service.
102 /// </param> 108 /// </param>
103 /// <param name="collector"> 109 /// <param name="collector">
104 /// Gathered UUIDs will be collected in this dictinaory. 110 /// Gathered UUIDs will be collected in this dictionary.
105 /// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected. 111 /// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected.
106 /// </param> 112 /// </param>
107 public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector) 113 public UuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector, HashSet <UUID> failedIDs, HashSet <UUID> uncertainAssetsUUIDs)
108 { 114 {
109 m_assetService = assetService; 115 m_assetService = assetService;
110 GatheredUuids = collector; 116 GatheredUuids = collector;
111 117
112 // FIXME: Not efficient for searching, can improve. 118 // FIXME: Not efficient for searching, can improve.
113 m_assetUuidsToInspect = new Queue<UUID>(); 119 m_assetUuidsToInspect = new Queue<UUID>();
120 FailedUUIDs = failedIDs;
121 UncertainAssetsUUIDs = uncertainAssetsUUIDs;
122 ErrorCount = 0;
123 possibleNotAssetCount = 0;
114 } 124 }
115 125
116 /// <summary> 126 /// <summary>
@@ -120,6 +130,19 @@ namespace OpenSim.Region.Framework.Scenes
120 /// <param name="uuid">UUID.</param> 130 /// <param name="uuid">UUID.</param>
121 public bool AddForInspection(UUID uuid) 131 public bool AddForInspection(UUID uuid)
122 { 132 {
133 if(uuid == UUID.Zero)
134 return false;
135
136 if(FailedUUIDs.Contains(uuid))
137 {
138 if(UncertainAssetsUUIDs.Contains(uuid))
139 possibleNotAssetCount++;
140 else
141 ErrorCount++;
142 return false;
143 }
144 if(GatheredUuids.ContainsKey(uuid))
145 return false;
123 if (m_assetUuidsToInspect.Contains(uuid)) 146 if (m_assetUuidsToInspect.Contains(uuid))
124 return false; 147 return false;
125 148
@@ -141,7 +164,9 @@ namespace OpenSim.Region.Framework.Scenes
141 public void AddForInspection(SceneObjectGroup sceneObject) 164 public void AddForInspection(SceneObjectGroup sceneObject)
142 { 165 {
143 // m_log.DebugFormat( 166 // m_log.DebugFormat(
144 // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); 167 // "[UUID GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
168 if(sceneObject.IsDeleted)
169 return;
145 170
146 SceneObjectPart[] parts = sceneObject.Parts; 171 SceneObjectPart[] parts = sceneObject.Parts;
147 for (int i = 0; i < parts.Length; i++) 172 for (int i = 0; i < parts.Length; i++)
@@ -149,7 +174,7 @@ namespace OpenSim.Region.Framework.Scenes
149 SceneObjectPart part = parts[i]; 174 SceneObjectPart part = parts[i];
150 175
151 // m_log.DebugFormat( 176 // m_log.DebugFormat(
152 // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); 177 // "[UUID GATHERER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
153 178
154 try 179 try
155 { 180 {
@@ -207,9 +232,7 @@ namespace OpenSim.Region.Framework.Scenes
207 // m_log.DebugFormat( 232 // m_log.DebugFormat(
208 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", 233 // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
209 // tii.Name, tii.Type, part.Name, part.UUID); 234 // tii.Name, tii.Type, part.Name, part.UUID);
210 235 AddForInspection(tii.AssetID, (sbyte)tii.Type);
211 if (!GatheredUuids.ContainsKey(tii.AssetID))
212 AddForInspection(tii.AssetID, (sbyte)tii.Type);
213 } 236 }
214 237
215 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed 238 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
@@ -225,9 +248,6 @@ namespace OpenSim.Region.Framework.Scenes
225 catch (Exception e) 248 catch (Exception e)
226 { 249 {
227 m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e); 250 m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e);
228 m_log.DebugFormat(
229 "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)",
230 part.Shape.TextureEntry.Length);
231 } 251 }
232 } 252 }
233 } 253 }
@@ -278,55 +298,112 @@ namespace OpenSim.Region.Framework.Scenes
278 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> 298 /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param>
279 private void GetAssetUuids(UUID assetUuid) 299 private void GetAssetUuids(UUID assetUuid)
280 { 300 {
301 if(assetUuid == UUID.Zero)
302 return;
303
304 if(FailedUUIDs.Contains(assetUuid))
305 {
306 if(UncertainAssetsUUIDs.Contains(assetUuid))
307 possibleNotAssetCount++;
308 else
309 ErrorCount++;
310 return;
311 }
312
281 // avoid infinite loops 313 // avoid infinite loops
282 if (GatheredUuids.ContainsKey(assetUuid)) 314 if (GatheredUuids.ContainsKey(assetUuid))
283 return; 315 return;
284 316
317 AssetBase assetBase;
285 try 318 try
286 { 319 {
287 AssetBase assetBase = GetAsset(assetUuid); 320 assetBase = GetAsset(assetUuid);
321 }
322 catch (Exception e)
323 {
324 m_log.ErrorFormat("[UUID GATHERER]: Failed to get asset {0} : {1}", assetUuid, e.Message);
325 ErrorCount++;
326 FailedUUIDs.Add(assetUuid);
327 return;
328 }
288 329
289 if (null != assetBase) 330 if(assetBase == null)
290 { 331 {
291 sbyte assetType = assetBase.Type; 332// m_log.ErrorFormat("[UUID GATHERER]: asset {0} not found", assetUuid);
292 GatheredUuids[assetUuid] = assetType; 333 FailedUUIDs.Add(assetUuid);
334 if(UncertainAssetsUUIDs.Contains(assetUuid))
335 possibleNotAssetCount++;
336 else
337 ErrorCount++;
338 return;
339 }
293 340
294 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) 341 if(UncertainAssetsUUIDs.Contains(assetUuid))
295 { 342 UncertainAssetsUUIDs.Remove(assetUuid);
296 RecordWearableAssetUuids(assetBase); 343
297 } 344 sbyte assetType = assetBase.Type;
298 else if ((sbyte)AssetType.Gesture == assetType) 345
299 { 346 if(assetBase.Data == null || assetBase.Data.Length == 0)
300 RecordGestureAssetUuids(assetBase); 347 {
301 } 348// m_log.ErrorFormat("[UUID GATHERER]: asset {0}, type {1} has no data", assetUuid, assetType);
302 else if ((sbyte)AssetType.Notecard == assetType) 349 ErrorCount++;
303 { 350 FailedUUIDs.Add(assetUuid);
304 RecordTextEmbeddedAssetUuids(assetBase); 351 return;
305 } 352 }
306 else if ((sbyte)AssetType.LSLText == assetType) 353
307 { 354 GatheredUuids[assetUuid] = assetType;
308 RecordTextEmbeddedAssetUuids(assetBase); 355 try
309 } 356 {
310 else if ((sbyte)OpenSimAssetType.Material == assetType) 357 if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
311 { 358 {
312 RecordMaterialAssetUuids(assetBase); 359 RecordWearableAssetUuids(assetBase);
313 } 360 }
314 else if ((sbyte)AssetType.Object == assetType) 361 else if ((sbyte)AssetType.Gesture == assetType)
315 { 362 {
316 RecordSceneObjectAssetUuids(assetBase); 363 RecordGestureAssetUuids(assetBase);
317 } 364 }
365 else if ((sbyte)AssetType.Notecard == assetType)
366 {
367 RecordTextEmbeddedAssetUuids(assetBase);
368 }
369 else if ((sbyte)AssetType.LSLText == assetType)
370 {
371 RecordTextEmbeddedAssetUuids(assetBase);
372 }
373 else if ((sbyte)OpenSimAssetType.Material == assetType)
374 {
375 RecordMaterialAssetUuids(assetBase);
376 }
377 else if ((sbyte)AssetType.Object == assetType)
378 {
379 RecordSceneObjectAssetUuids(assetBase);
318 } 380 }
319 } 381 }
320 catch (Exception) 382 catch (Exception e)
321 { 383 {
322 m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid); 384 m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset with id {0} type {1}: {2}", assetUuid, assetType, e.Message);
323 throw; 385 GatheredUuids.Remove(assetUuid);
386 ErrorCount++;
387 FailedUUIDs.Add(assetUuid);
324 } 388 }
325 } 389 }
326 390
327 private void AddForInspection(UUID assetUuid, sbyte assetType) 391 private void AddForInspection(UUID assetUuid, sbyte assetType)
328 { 392 {
393 if(assetUuid == UUID.Zero)
394 return;
395
329 // Here, we want to collect uuids which require further asset fetches but mark the others as gathered 396 // Here, we want to collect uuids which require further asset fetches but mark the others as gathered
397 if(FailedUUIDs.Contains(assetUuid))
398 {
399 if(UncertainAssetsUUIDs.Contains(assetUuid))
400 possibleNotAssetCount++;
401 else
402 ErrorCount++;
403 return;
404 }
405 if(GatheredUuids.ContainsKey(assetUuid))
406 return;
330 try 407 try
331 { 408 {
332 if ((sbyte)AssetType.Bodypart == assetType 409 if ((sbyte)AssetType.Bodypart == assetType
@@ -458,8 +535,11 @@ namespace OpenSim.Region.Framework.Scenes
458 foreach (Match uuidMatch in uuidMatches) 535 foreach (Match uuidMatch in uuidMatches)
459 { 536 {
460 UUID uuid = new UUID(uuidMatch.Value); 537 UUID uuid = new UUID(uuidMatch.Value);
538 if(uuid == UUID.Zero)
539 continue;
461// m_log.DebugFormat("[UUID GATHERER]: Recording {0} in text", uuid); 540// m_log.DebugFormat("[UUID GATHERER]: Recording {0} in text", uuid);
462 541 if(!UncertainAssetsUUIDs.Contains(uuid))
542 UncertainAssetsUUIDs.Add(uuid);
463 AddForInspection(uuid); 543 AddForInspection(uuid);
464 } 544 }
465 } 545 }