aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Monitoring/Watchdog.cs15
-rw-r--r--OpenSim/Framework/RegionInfo.cs42
-rw-r--r--OpenSim/Framework/Util.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs31
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs60
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs66
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs15
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs21
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs228
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs29
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs110
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs78
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs58
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs16
-rw-r--r--bin/OpenSim.ini.example12
-rw-r--r--bin/OpenSimDefaults.ini3
-rwxr-xr-xbin/lib32/BulletSim.dllbin550400 -> 553472 bytes
-rwxr-xr-xbin/lib32/libBulletSim.sobin2387345 -> 2387051 bytes
-rwxr-xr-xbin/lib64/BulletSim.dllbin706048 -> 709632 bytes
-rwxr-xr-xbin/lib64/libBulletSim.sobin2599320 -> 2599546 bytes
23 files changed, 469 insertions, 346 deletions
diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs
index 02f11fa..7964f28 100644
--- a/OpenSim/Framework/Monitoring/Watchdog.cs
+++ b/OpenSim/Framework/Monitoring/Watchdog.cs
@@ -89,6 +89,17 @@ namespace OpenSim.Framework.Monitoring
89 FirstTick = Environment.TickCount & Int32.MaxValue; 89 FirstTick = Environment.TickCount & Int32.MaxValue;
90 LastTick = FirstTick; 90 LastTick = FirstTick;
91 } 91 }
92
93 public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi)
94 {
95 Thread = previousTwi.Thread;
96 FirstTick = previousTwi.FirstTick;
97 LastTick = previousTwi.LastTick;
98 Timeout = previousTwi.Timeout;
99 IsTimedOut = previousTwi.IsTimedOut;
100 AlarmIfTimeout = previousTwi.AlarmIfTimeout;
101 AlarmMethod = previousTwi.AlarmMethod;
102 }
92 } 103 }
93 104
94 /// <summary> 105 /// <summary>
@@ -335,7 +346,9 @@ namespace OpenSim.Framework.Monitoring
335 if (callbackInfos == null) 346 if (callbackInfos == null)
336 callbackInfos = new List<ThreadWatchdogInfo>(); 347 callbackInfos = new List<ThreadWatchdogInfo>();
337 348
338 callbackInfos.Add(threadInfo); 349 // Send a copy of the watchdog info to prevent race conditions where the watchdog
350 // thread updates the monitoring info after an alarm has been sent out.
351 callbackInfos.Add(new ThreadWatchdogInfo(threadInfo));
339 } 352 }
340 } 353 }
341 } 354 }
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index 2080a16..8131089 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -120,7 +120,9 @@ namespace OpenSim.Framework
120 public UUID lastMapUUID = UUID.Zero; 120 public UUID lastMapUUID = UUID.Zero;
121 public string lastMapRefresh = "0"; 121 public string lastMapRefresh = "0";
122 122
123 private float m_nonphysPrimMin = 0;
123 private int m_nonphysPrimMax = 0; 124 private int m_nonphysPrimMax = 0;
125 private float m_physPrimMin = 0;
124 private int m_physPrimMax = 0; 126 private int m_physPrimMax = 0;
125 private bool m_clampPrimSize = false; 127 private bool m_clampPrimSize = false;
126 private int m_objectCapacity = 0; 128 private int m_objectCapacity = 0;
@@ -285,11 +287,21 @@ namespace OpenSim.Framework
285 set { m_windlight = value; } 287 set { m_windlight = value; }
286 } 288 }
287 289
290 public float NonphysPrimMin
291 {
292 get { return m_nonphysPrimMin; }
293 }
294
288 public int NonphysPrimMax 295 public int NonphysPrimMax
289 { 296 {
290 get { return m_nonphysPrimMax; } 297 get { return m_nonphysPrimMax; }
291 } 298 }
292 299
300 public float PhysPrimMin
301 {
302 get { return m_physPrimMin; }
303 }
304
293 public int PhysPrimMax 305 public int PhysPrimMax
294 { 306 {
295 get { return m_physPrimMax; } 307 get { return m_physPrimMax; }
@@ -623,16 +635,28 @@ namespace OpenSim.Framework
623 m_regionType = config.GetString("RegionType", String.Empty); 635 m_regionType = config.GetString("RegionType", String.Empty);
624 allKeys.Remove("RegionType"); 636 allKeys.Remove("RegionType");
625 637
626 // Prim stuff 638 #region Prim stuff
627 // 639
640 m_nonphysPrimMin = config.GetFloat("NonphysicalPrimMin", 0);
641 allKeys.Remove("NonphysicalPrimMin");
642
628 m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0); 643 m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0);
629 allKeys.Remove("NonphysicalPrimMax"); 644 allKeys.Remove("NonphysicalPrimMax");
645
646 m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0);
647 allKeys.Remove("PhysicalPrimMin");
648
630 m_physPrimMax = config.GetInt("PhysicalPrimMax", 0); 649 m_physPrimMax = config.GetInt("PhysicalPrimMax", 0);
631 allKeys.Remove("PhysicalPrimMax"); 650 allKeys.Remove("PhysicalPrimMax");
651
632 m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); 652 m_clampPrimSize = config.GetBoolean("ClampPrimSize", false);
633 allKeys.Remove("ClampPrimSize"); 653 allKeys.Remove("ClampPrimSize");
654
634 m_objectCapacity = config.GetInt("MaxPrims", 15000); 655 m_objectCapacity = config.GetInt("MaxPrims", 15000);
635 allKeys.Remove("MaxPrims"); 656 allKeys.Remove("MaxPrims");
657
658 #endregion
659
636 m_agentCapacity = config.GetInt("MaxAgents", 100); 660 m_agentCapacity = config.GetInt("MaxAgents", 100);
637 allKeys.Remove("MaxAgents"); 661 allKeys.Remove("MaxAgents");
638 662
@@ -668,10 +692,18 @@ namespace OpenSim.Framework
668 692
669 config.Set("ExternalHostName", m_externalHostName); 693 config.Set("ExternalHostName", m_externalHostName);
670 694
695 if (m_nonphysPrimMin != 0)
696 config.Set("NonphysicalPrimMax", m_nonphysPrimMin);
697
671 if (m_nonphysPrimMax != 0) 698 if (m_nonphysPrimMax != 0)
672 config.Set("NonphysicalPrimMax", m_nonphysPrimMax); 699 config.Set("NonphysicalPrimMax", m_nonphysPrimMax);
700
701 if (m_physPrimMin != 0)
702 config.Set("PhysicalPrimMax", m_physPrimMin);
703
673 if (m_physPrimMax != 0) 704 if (m_physPrimMax != 0)
674 config.Set("PhysicalPrimMax", m_physPrimMax); 705 config.Set("PhysicalPrimMax", m_physPrimMax);
706
675 config.Set("ClampPrimSize", m_clampPrimSize.ToString()); 707 config.Set("ClampPrimSize", m_clampPrimSize.ToString());
676 708
677 if (m_objectCapacity != 0) 709 if (m_objectCapacity != 0)
@@ -754,9 +786,15 @@ namespace OpenSim.Framework
754 configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, 786 configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
755 "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true); 787 "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
756 788
789 configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
790 "Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
791
757 configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, 792 configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
758 "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true); 793 "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
759 794
795 configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
796 "Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
797
760 configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, 798 configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
761 "Maximum size for physical prims", m_physPrimMax.ToString(), true); 799 "Maximum size for physical prims", m_physPrimMax.ToString(), true);
762 800
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 8cc29ee..38cb3a6 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -850,6 +850,12 @@ namespace OpenSim.Framework
850 return Math.Min(Math.Max(x, min), max); 850 return Math.Min(Math.Max(x, min), max);
851 } 851 }
852 852
853 public static Vector3 Clip(Vector3 vec, float min, float max)
854 {
855 return new Vector3(Clip(vec.X, min, max), Clip(vec.Y, min, max),
856 Clip(vec.Z, min, max));
857 }
858
853 /// <summary> 859 /// <summary>
854 /// Convert an UUID to a raw uuid string. Right now this is a string without hyphens. 860 /// Convert an UUID to a raw uuid string. Right now this is a string without hyphens.
855 /// </summary> 861 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0e5ddfd..d2d6aba 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -103,8 +103,26 @@ namespace OpenSim.Region.Framework.Scenes
103 /// </summary> 103 /// </summary>
104 public bool CollidablePrims { get; private set; } 104 public bool CollidablePrims { get; private set; }
105 105
106 /// <summary>
107 /// Minimum value of the size of a non-physical prim in each axis
108 /// </summary>
109 public float m_minNonphys = 0.01f;
110
111 /// <summary>
112 /// Maximum value of the size of a non-physical prim in each axis
113 /// </summary>
106 public float m_maxNonphys = 256; 114 public float m_maxNonphys = 256;
115
116 /// <summary>
117 /// Minimum value of the size of a physical prim in each axis
118 /// </summary>
119 public float m_minPhys = 0.01f;
120
121 /// <summary>
122 /// Maximum value of the size of a physical prim in each axis
123 /// </summary>
107 public float m_maxPhys = 10; 124 public float m_maxPhys = 10;
125
108 public bool m_clampPrimSize; 126 public bool m_clampPrimSize;
109 public bool m_trustBinaries; 127 public bool m_trustBinaries;
110 public bool m_allowScriptCrossings; 128 public bool m_allowScriptCrossings;
@@ -721,14 +739,25 @@ namespace OpenSim.Region.Framework.Scenes
721 PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims); 739 PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims);
722 CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims); 740 CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims);
723 741
742 m_minNonphys = startupConfig.GetFloat("NonphysicalPrimMin", m_minNonphys);
743 if (RegionInfo.NonphysPrimMin > 0)
744 {
745 m_minNonphys = RegionInfo.NonphysPrimMin;
746 }
747
724 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); 748 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys);
725 if (RegionInfo.NonphysPrimMax > 0) 749 if (RegionInfo.NonphysPrimMax > 0)
726 { 750 {
727 m_maxNonphys = RegionInfo.NonphysPrimMax; 751 m_maxNonphys = RegionInfo.NonphysPrimMax;
728 } 752 }
729 753
730 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); 754 m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
755 if (RegionInfo.PhysPrimMin > 0)
756 {
757 m_minPhys = RegionInfo.PhysPrimMin;
758 }
731 759
760 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
732 if (RegionInfo.PhysPrimMax > 0) 761 if (RegionInfo.PhysPrimMax > 0)
733 { 762 {
734 m_maxPhys = RegionInfo.PhysPrimMax; 763 m_maxPhys = RegionInfo.PhysPrimMax;
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 13842ad..b6339fb 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -375,12 +375,9 @@ namespace OpenSim.Region.Framework.Scenes
375 { 375 {
376 Vector3 scale = part.Shape.Scale; 376 Vector3 scale = part.Shape.Scale;
377 377
378 if (scale.X > m_parentScene.m_maxNonphys) 378 scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X));
379 scale.X = m_parentScene.m_maxNonphys; 379 scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y));
380 if (scale.Y > m_parentScene.m_maxNonphys) 380 scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z));
381 scale.Y = m_parentScene.m_maxNonphys;
382 if (scale.Z > m_parentScene.m_maxNonphys)
383 scale.Z = m_parentScene.m_maxNonphys;
384 381
385 part.Shape.Scale = scale; 382 part.Shape.Scale = scale;
386 } 383 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 5f90035..f6c725b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2674,17 +2674,17 @@ namespace OpenSim.Region.Framework.Scenes
2674 2674
2675 RootPart.StoreUndoState(true); 2675 RootPart.StoreUndoState(true);
2676 2676
2677 scale.X = Math.Min(scale.X, Scene.m_maxNonphys); 2677 scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X));
2678 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); 2678 scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y));
2679 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); 2679 scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z));
2680 2680
2681 PhysicsActor pa = m_rootPart.PhysActor; 2681 PhysicsActor pa = m_rootPart.PhysActor;
2682 2682
2683 if (pa != null && pa.IsPhysical) 2683 if (pa != null && pa.IsPhysical)
2684 { 2684 {
2685 scale.X = Math.Min(scale.X, Scene.m_maxPhys); 2685 scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X));
2686 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); 2686 scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y));
2687 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); 2687 scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z));
2688 } 2688 }
2689 2689
2690 float x = (scale.X / RootPart.Scale.X); 2690 float x = (scale.X / RootPart.Scale.X);
@@ -2716,6 +2716,14 @@ namespace OpenSim.Region.Framework.Scenes
2716 y *= a; 2716 y *= a;
2717 z *= a; 2717 z *= a;
2718 } 2718 }
2719 else if (oldSize.X * x < m_scene.m_minPhys)
2720 {
2721 f = m_scene.m_minPhys / oldSize.X;
2722 a = f / x;
2723 x *= a;
2724 y *= a;
2725 z *= a;
2726 }
2719 2727
2720 if (oldSize.Y * y > m_scene.m_maxPhys) 2728 if (oldSize.Y * y > m_scene.m_maxPhys)
2721 { 2729 {
@@ -2725,6 +2733,14 @@ namespace OpenSim.Region.Framework.Scenes
2725 y *= a; 2733 y *= a;
2726 z *= a; 2734 z *= a;
2727 } 2735 }
2736 else if (oldSize.Y * y < m_scene.m_minPhys)
2737 {
2738 f = m_scene.m_minPhys / oldSize.Y;
2739 a = f / y;
2740 x *= a;
2741 y *= a;
2742 z *= a;
2743 }
2728 2744
2729 if (oldSize.Z * z > m_scene.m_maxPhys) 2745 if (oldSize.Z * z > m_scene.m_maxPhys)
2730 { 2746 {
@@ -2734,6 +2750,14 @@ namespace OpenSim.Region.Framework.Scenes
2734 y *= a; 2750 y *= a;
2735 z *= a; 2751 z *= a;
2736 } 2752 }
2753 else if (oldSize.Z * z < m_scene.m_minPhys)
2754 {
2755 f = m_scene.m_minPhys / oldSize.Z;
2756 a = f / z;
2757 x *= a;
2758 y *= a;
2759 z *= a;
2760 }
2737 } 2761 }
2738 else 2762 else
2739 { 2763 {
@@ -2745,6 +2769,14 @@ namespace OpenSim.Region.Framework.Scenes
2745 y *= a; 2769 y *= a;
2746 z *= a; 2770 z *= a;
2747 } 2771 }
2772 else if (oldSize.X * x < m_scene.m_minNonphys)
2773 {
2774 f = m_scene.m_minNonphys / oldSize.X;
2775 a = f / x;
2776 x *= a;
2777 y *= a;
2778 z *= a;
2779 }
2748 2780
2749 if (oldSize.Y * y > m_scene.m_maxNonphys) 2781 if (oldSize.Y * y > m_scene.m_maxNonphys)
2750 { 2782 {
@@ -2754,6 +2786,14 @@ namespace OpenSim.Region.Framework.Scenes
2754 y *= a; 2786 y *= a;
2755 z *= a; 2787 z *= a;
2756 } 2788 }
2789 else if (oldSize.Y * y < m_scene.m_minNonphys)
2790 {
2791 f = m_scene.m_minNonphys / oldSize.Y;
2792 a = f / y;
2793 x *= a;
2794 y *= a;
2795 z *= a;
2796 }
2757 2797
2758 if (oldSize.Z * z > m_scene.m_maxNonphys) 2798 if (oldSize.Z * z > m_scene.m_maxNonphys)
2759 { 2799 {
@@ -2763,6 +2803,14 @@ namespace OpenSim.Region.Framework.Scenes
2763 y *= a; 2803 y *= a;
2764 z *= a; 2804 z *= a;
2765 } 2805 }
2806 else if (oldSize.Z * z < m_scene.m_minNonphys)
2807 {
2808 f = m_scene.m_minNonphys / oldSize.Z;
2809 a = f / z;
2810 x *= a;
2811 y *= a;
2812 z *= a;
2813 }
2766 } 2814 }
2767 2815
2768// obPart.IgnoreUndoUpdate = false; 2816// obPart.IgnoreUndoUpdate = false;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 4c87639..53b4f7e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -733,7 +733,7 @@ namespace OpenSim.Region.Framework.Scenes
733 } 733 }
734 catch (Exception e) 734 catch (Exception e)
735 { 735 {
736 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 736 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
737 } 737 }
738 } 738 }
739 739
@@ -2368,17 +2368,16 @@ namespace OpenSim.Region.Framework.Scenes
2368 /// <param name="scale"></param> 2368 /// <param name="scale"></param>
2369 public void Resize(Vector3 scale) 2369 public void Resize(Vector3 scale)
2370 { 2370 {
2371 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys); 2371 scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X));
2372 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys); 2372 scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y));
2373 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys); 2373 scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z));
2374 2374
2375 PhysicsActor pa = PhysActor; 2375 PhysicsActor pa = PhysActor;
2376
2377 if (pa != null && pa.IsPhysical) 2376 if (pa != null && pa.IsPhysical)
2378 { 2377 {
2379 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); 2378 scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X));
2380 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); 2379 scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y));
2381 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); 2380 scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z));
2382 } 2381 }
2383 2382
2384// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); 2383// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
@@ -4237,6 +4236,57 @@ namespace OpenSim.Region.Framework.Scenes
4237 ScheduleFullUpdate(); 4236 ScheduleFullUpdate();
4238 } 4237 }
4239 4238
4239 public void UpdateSlice(float begin, float end)
4240 {
4241 if (end < begin)
4242 {
4243 float temp = begin;
4244 begin = end;
4245 end = temp;
4246 }
4247 end = Math.Min(1f, Math.Max(0f, end));
4248 begin = Math.Min(Math.Min(1f, Math.Max(0f, begin)), end - 0.02f);
4249 if (begin < 0.02f && end < 0.02f)
4250 {
4251 begin = 0f;
4252 end = 0.02f;
4253 }
4254
4255 ushort uBegin = (ushort)(50000.0 * begin);
4256 ushort uEnd = (ushort)(50000.0 * (1f - end));
4257 bool updatePossiblyNeeded = false;
4258 PrimType primType = GetPrimType();
4259 if (primType == PrimType.SPHERE || primType == PrimType.TORUS || primType == PrimType.TUBE || primType == PrimType.RING)
4260 {
4261 if (m_shape.ProfileBegin != uBegin || m_shape.ProfileEnd != uEnd)
4262 {
4263 m_shape.ProfileBegin = uBegin;
4264 m_shape.ProfileEnd = uEnd;
4265 updatePossiblyNeeded = true;
4266 }
4267 }
4268 else if (m_shape.PathBegin != uBegin || m_shape.PathEnd != uEnd)
4269 {
4270 m_shape.PathBegin = uBegin;
4271 m_shape.PathEnd = uEnd;
4272 updatePossiblyNeeded = true;
4273 }
4274
4275 if (updatePossiblyNeeded && ParentGroup != null)
4276 {
4277 ParentGroup.HasGroupChanged = true;
4278 }
4279 if (updatePossiblyNeeded && PhysActor != null)
4280 {
4281 PhysActor.Shape = m_shape;
4282 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
4283 }
4284 if (updatePossiblyNeeded)
4285 {
4286 ScheduleFullUpdate();
4287 }
4288 }
4289
4240 /// <summary> 4290 /// <summary>
4241 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics 4291 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
4242 /// engine can use it. 4292 /// engine can use it.
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 548dfd3..65d526f 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1385,17 +1385,22 @@ namespace OpenSim.Region.Framework.Scenes
1385 bool DCFlagKeyPressed = false; 1385 bool DCFlagKeyPressed = false;
1386 Vector3 agent_control_v3 = Vector3.Zero; 1386 Vector3 agent_control_v3 = Vector3.Zero;
1387 1387
1388 bool oldflying = Flying; 1388 bool newFlying = actor.Flying;
1389 1389
1390 if (ForceFly) 1390 if (ForceFly)
1391 actor.Flying = true; 1391 newFlying = true;
1392 else if (FlyDisabled) 1392 else if (FlyDisabled)
1393 actor.Flying = false; 1393 newFlying = false;
1394 else 1394 else
1395 actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1395 newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1396 1396
1397 if (actor.Flying != oldflying) 1397 if (actor.Flying != newFlying)
1398 {
1399 // Note: ScenePresence.Flying is actually fetched from the physical actor
1400 // so setting PhysActor.Flying here also sets the ScenePresence's value.
1401 actor.Flying = newFlying;
1398 update_movementflag = true; 1402 update_movementflag = true;
1403 }
1399 1404
1400 if (ParentID == 0) 1405 if (ParentID == 0)
1401 { 1406 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index e2f7af9..1b23a36 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -124,10 +124,14 @@ public class BSCharacter : PhysicsActor
124 // do actual create at taint time 124 // do actual create at taint time
125 _scene.TaintedObject("BSCharacter.create", delegate() 125 _scene.TaintedObject("BSCharacter.create", delegate()
126 { 126 {
127 DetailLog("{0},BSCharacter.create", _localID);
127 BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); 128 BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData);
128 129
130 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#
131 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
132
129 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 133 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
130 // avatars get all collisions no matter what 134 // avatars get all collisions no matter what (makes walking on ground and such work)
131 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 135 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
132 }); 136 });
133 137
@@ -137,7 +141,7 @@ public class BSCharacter : PhysicsActor
137 // called when this character is being destroyed and the resources should be released 141 // called when this character is being destroyed and the resources should be released
138 public void Destroy() 142 public void Destroy()
139 { 143 {
140 // DetailLog("{0},BSCharacter.Destroy", LocalID); 144 DetailLog("{0},BSCharacter.Destroy", LocalID);
141 _scene.TaintedObject("BSCharacter.destroy", delegate() 145 _scene.TaintedObject("BSCharacter.destroy", delegate()
142 { 146 {
143 BulletSimAPI.DestroyObject(_scene.WorldID, _localID); 147 BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
@@ -319,14 +323,13 @@ public class BSCharacter : PhysicsActor
319 public override bool Flying { 323 public override bool Flying {
320 get { return _flying; } 324 get { return _flying; }
321 set { 325 set {
322 if (_flying != value) 326 _flying = value;
323 { 327 // simulate flying by changing the effect of gravity
324 _flying = value; 328 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
325 // simulate flying by changing the effect of gravity
326 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
327 }
328 } 329 }
329 } 330 }
331 // Flying is implimented by changing the avatar's buoyancy.
332 // Would this be done better with a vehicle type?
330 private float ComputeBuoyancyFromFlying(bool ifFlying) { 333 private float ComputeBuoyancyFromFlying(bool ifFlying) {
331 return ifFlying ? 1f : 0f; 334 return ifFlying ? 1f : 0f;
332 } 335 }
@@ -488,11 +491,9 @@ public class BSCharacter : PhysicsActor
488 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. 491 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
489 // base.RequestPhysicsterseUpdate(); 492 // base.RequestPhysicsterseUpdate();
490 493
491 /*
492 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", 494 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
493 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, 495 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
494 entprop.Acceleration, entprop.RotationalVelocity); 496 entprop.Acceleration, entprop.RotationalVelocity);
495 */
496 } 497 }
497 498
498 // Called by the scene when a collision with this object is reported 499 // Called by the scene when a collision with this object is reported
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 5a9f135..d7213fc 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -57,6 +57,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
57 private int frcount = 0; // Used to limit dynamics debug output to 57 private int frcount = 0; // Used to limit dynamics debug output to
58 // every 100th frame 58 // every 100th frame
59 59
60 private BSScene m_physicsScene;
60 private BSPrim m_prim; // the prim this dynamic controller belongs to 61 private BSPrim m_prim; // the prim this dynamic controller belongs to
61 62
62 // Vehicle properties 63 // Vehicle properties
@@ -74,7 +75,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
74 // HOVER_UP_ONLY 75 // HOVER_UP_ONLY
75 // LIMIT_MOTOR_UP 76 // LIMIT_MOTOR_UP
76 // LIMIT_ROLL_ONLY 77 // LIMIT_ROLL_ONLY
77 private VehicleFlag m_Hoverflags = (VehicleFlag)0;
78 private Vector3 m_BlockingEndPoint = Vector3.Zero; 78 private Vector3 m_BlockingEndPoint = Vector3.Zero;
79 private Quaternion m_RollreferenceFrame = Quaternion.Identity; 79 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
80 // Linear properties 80 // Linear properties
@@ -124,15 +124,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
124 private float m_verticalAttractionEfficiency = 1.0f; // damped 124 private float m_verticalAttractionEfficiency = 1.0f; // damped
125 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. 125 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
126 126
127 public BSDynamics(BSPrim myPrim) 127 public BSDynamics(BSScene myScene, BSPrim myPrim)
128 { 128 {
129 m_physicsScene = myScene;
129 m_prim = myPrim; 130 m_prim = myPrim;
130 m_type = Vehicle.TYPE_NONE; 131 m_type = Vehicle.TYPE_NONE;
131 } 132 }
132 133
133 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep) 134 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep)
134 { 135 {
135 DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 136 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
136 switch (pParam) 137 switch (pParam)
137 { 138 {
138 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 139 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@@ -231,7 +232,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
231 232
232 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep) 233 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep)
233 { 234 {
234 DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 235 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
235 switch (pParam) 236 switch (pParam)
236 { 237 {
237 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 238 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
@@ -266,7 +267,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
266 267
267 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) 268 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
268 { 269 {
269 DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 270 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
270 switch (pParam) 271 switch (pParam)
271 { 272 {
272 case Vehicle.REFERENCE_FRAME: 273 case Vehicle.REFERENCE_FRAME:
@@ -280,164 +281,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin
280 281
281 internal void ProcessVehicleFlags(int pParam, bool remove) 282 internal void ProcessVehicleFlags(int pParam, bool remove)
282 { 283 {
283 DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove); 284 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
285 VehicleFlag parm = (VehicleFlag)pParam;
284 if (remove) 286 if (remove)
285 { 287 {
286 if (pParam == -1) 288 if (pParam == -1)
287 { 289 {
288 m_flags = (VehicleFlag)0; 290 m_flags = (VehicleFlag)0;
289 m_Hoverflags = (VehicleFlag)0;
290 return;
291 } 291 }
292 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) 292 else
293 {
294 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0)
295 m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
296 }
297 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
298 {
299 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
300 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
301 }
302 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
303 {
304 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
305 m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
306 }
307 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
308 {
309 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
310 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
311 }
312 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
313 {
314 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
315 m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
316 }
317 if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
318 {
319 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
320 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
321 }
322 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
323 {
324 if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
325 m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
326 }
327 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
328 {
329 if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
330 m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
331 }
332 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
333 {
334 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
335 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
336 }
337 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
338 {
339 if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
340 m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
341 }
342 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
343 {
344 if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
345 m_flags &= ~(VehicleFlag.NO_X);
346 }
347 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
348 {
349 if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
350 m_flags &= ~(VehicleFlag.NO_Y);
351 }
352 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
353 {
354 if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
355 m_flags &= ~(VehicleFlag.NO_Z);
356 }
357 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
358 {
359 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
360 m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
361 }
362 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
363 {
364 if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
365 m_flags &= ~(VehicleFlag.NO_DEFLECTION);
366 }
367 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
368 { 293 {
369 if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0) 294 m_flags &= ~parm;
370 m_flags &= ~(VehicleFlag.LOCK_ROTATION);
371 } 295 }
372 } 296 }
373 else 297 else {
374 { 298 m_flags |= parm;
375 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
376 {
377 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
378 }
379 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
380 {
381 m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
382 }
383 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
384 {
385 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
386 }
387 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
388 {
389 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
390 }
391 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
392 {
393 m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
394 }
395 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
396 {
397 m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
398 }
399 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
400 {
401 m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
402 }
403 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
404 {
405 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
406 }
407 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
408 {
409 m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
410 }
411 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
412 {
413 m_flags |= (VehicleFlag.NO_X);
414 }
415 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
416 {
417 m_flags |= (VehicleFlag.NO_Y);
418 }
419 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
420 {
421 m_flags |= (VehicleFlag.NO_Z);
422 }
423 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
424 {
425 m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
426 }
427 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
428 {
429 m_flags |= (VehicleFlag.NO_DEFLECTION);
430 }
431 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
432 {
433 m_flags |= (VehicleFlag.LOCK_ROTATION);
434 }
435 } 299 }
436 }//end ProcessVehicleFlags 300 }//end ProcessVehicleFlags
437 301
438 internal void ProcessTypeChange(Vehicle pType) 302 internal void ProcessTypeChange(Vehicle pType, float stepSize)
439 { 303 {
440 DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); 304 VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
441 // Set Defaults For Type 305 // Set Defaults For Type
442 m_type = pType; 306 m_type = pType;
443 switch (pType) 307 switch (pType)
@@ -478,10 +342,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
478 // m_bankingMix = 1; 342 // m_bankingMix = 1;
479 // m_bankingTimescale = 10; 343 // m_bankingTimescale = 10;
480 // m_referenceFrame = Quaternion.Identity; 344 // m_referenceFrame = Quaternion.Identity;
481 m_Hoverflags &= 345 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
346 m_flags &=
482 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 347 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
483 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 348 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
484 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
485 break; 349 break;
486 case Vehicle.TYPE_CAR: 350 case Vehicle.TYPE_CAR:
487 m_linearFrictionTimescale = new Vector3(100, 2, 1000); 351 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
@@ -506,10 +370,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
506 // m_bankingMix = 1; 370 // m_bankingMix = 1;
507 // m_bankingTimescale = 1; 371 // m_bankingTimescale = 1;
508 // m_referenceFrame = Quaternion.Identity; 372 // m_referenceFrame = Quaternion.Identity;
509 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
510 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | 373 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
511 VehicleFlag.LIMIT_MOTOR_UP); 374 VehicleFlag.LIMIT_MOTOR_UP);
512 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY); 375 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
376 m_flags |= (VehicleFlag.HOVER_UP_ONLY);
513 break; 377 break;
514 case Vehicle.TYPE_BOAT: 378 case Vehicle.TYPE_BOAT:
515 m_linearFrictionTimescale = new Vector3(10, 3, 2); 379 m_linearFrictionTimescale = new Vector3(10, 3, 2);
@@ -534,12 +398,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
534 // m_bankingMix = 0.8f; 398 // m_bankingMix = 0.8f;
535 // m_bankingTimescale = 1; 399 // m_bankingTimescale = 1;
536 // m_referenceFrame = Quaternion.Identity; 400 // m_referenceFrame = Quaternion.Identity;
537 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | 401 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
538 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 402 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
539 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); 403 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
540 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | 404 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
541 VehicleFlag.LIMIT_MOTOR_UP); 405 VehicleFlag.LIMIT_MOTOR_UP);
542 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY); 406 m_flags |= (VehicleFlag.HOVER_WATER_ONLY);
543 break; 407 break;
544 case Vehicle.TYPE_AIRPLANE: 408 case Vehicle.TYPE_AIRPLANE:
545 m_linearFrictionTimescale = new Vector3(200, 10, 5); 409 m_linearFrictionTimescale = new Vector3(200, 10, 5);
@@ -564,7 +428,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
564 // m_bankingMix = 0.7f; 428 // m_bankingMix = 0.7f;
565 // m_bankingTimescale = 2; 429 // m_bankingTimescale = 2;
566 // m_referenceFrame = Quaternion.Identity; 430 // m_referenceFrame = Quaternion.Identity;
567 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 431 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
568 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 432 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
569 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); 433 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
570 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 434 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
@@ -592,11 +456,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
592 // m_bankingMix = 0.7f; 456 // m_bankingMix = 0.7f;
593 // m_bankingTimescale = 5; 457 // m_bankingTimescale = 5;
594 // m_referenceFrame = Quaternion.Identity; 458 // m_referenceFrame = Quaternion.Identity;
595 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 459 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
596 VehicleFlag.HOVER_UP_ONLY); 460 VehicleFlag.HOVER_UP_ONLY);
597 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); 461 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
598 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 462 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
599 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); 463 m_flags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
600 break; 464 break;
601 } 465 }
602 }//end SetDefaultsForType 466 }//end SetDefaultsForType
@@ -613,7 +477,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
613 MoveAngular(pTimestep); 477 MoveAngular(pTimestep);
614 LimitRotation(pTimestep); 478 LimitRotation(pTimestep);
615 479
616 DetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 480 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
617 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); 481 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
618 }// end Step 482 }// end Step
619 483
@@ -657,7 +521,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
657 521
658 */ 522 */
659 523
660 DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", 524 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
661 m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); 525 m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
662 } 526 }
663 else 527 else
@@ -669,7 +533,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
669 m_lastLinearVelocityVector = Vector3.Zero; 533 m_lastLinearVelocityVector = Vector3.Zero;
670 } 534 }
671 535
672 // convert requested object velocity to world-referenced vector 536 // convert requested object velocity to object relative vector
673 Quaternion rotq = m_prim.Orientation; 537 Quaternion rotq = m_prim.Orientation;
674 m_dir = m_lastLinearVelocityVector * rotq; 538 m_dir = m_lastLinearVelocityVector * rotq;
675 539
@@ -722,7 +586,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
722 if (changed) 586 if (changed)
723 { 587 {
724 m_prim.Position = pos; 588 m_prim.Position = pos;
725 DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", 589 VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
726 m_prim.LocalID, m_BlockingEndPoint, posChange, pos); 590 m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
727 } 591 }
728 } 592 }
@@ -732,32 +596,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin
732 { 596 {
733 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; 597 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2;
734 m_prim.Position = pos; 598 m_prim.Position = pos;
735 DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); 599 VDetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
736 } 600 }
737 601
738 // Check if hovering 602 // Check if hovering
739 if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 603 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
740 { 604 {
741 // We should hover, get the target height 605 // We should hover, get the target height
742 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) 606 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
743 { 607 {
744 m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight; 608 m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight;
745 } 609 }
746 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) 610 if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
747 { 611 {
748 m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; 612 m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
749 } 613 }
750 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) 614 if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
751 { 615 {
752 m_VhoverTargetHeight = m_VhoverHeight; 616 m_VhoverTargetHeight = m_VhoverHeight;
753 } 617 }
754 618
755 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0) 619 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
756 { 620 {
757 // If body is aready heigher, use its height as target height 621 // If body is aready heigher, use its height as target height
758 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; 622 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
759 } 623 }
760 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) 624 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
761 { 625 {
762 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) 626 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
763 { 627 {
@@ -779,7 +643,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
779 } 643 }
780 } 644 }
781 645
782 DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight); 646 VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
783 647
784// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped 648// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
785// m_VhoverTimescale = 0f; // time to acheive height 649// m_VhoverTimescale = 0f; // time to acheive height
@@ -815,7 +679,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
815 { 679 {
816 grav.Z = (float)(grav.Z * 1.037125); 680 grav.Z = (float)(grav.Z * 1.037125);
817 } 681 }
818 DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav); 682 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
819 //End Experimental Values 683 //End Experimental Values
820 } 684 }
821 if ((m_flags & (VehicleFlag.NO_X)) != 0) 685 if ((m_flags & (VehicleFlag.NO_X)) != 0)
@@ -844,7 +708,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
844 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); 708 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
845 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; 709 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
846 710
847 DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}", 711 VDetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
848 m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount); 712 m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount);
849 713
850 } // end MoveLinear() 714 } // end MoveLinear()
@@ -870,13 +734,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
870 // There are m_angularMotorApply steps. 734 // There are m_angularMotorApply steps.
871 Vector3 origAngularVelocity = m_angularMotorVelocity; 735 Vector3 origAngularVelocity = m_angularMotorVelocity;
872 // ramp up to new value 736 // ramp up to new value
873 // current velocity += error / (time to get there / step interval) 737 // current velocity += error / (time to get there / step interval)
874 // requested speed - last motor speed 738 // requested speed - last motor speed
875 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); 739 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
876 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); 740 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
877 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); 741 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
878 742
879 DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}", 743 VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
880 m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); 744 m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
881 745
882 m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected 746 m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
@@ -887,6 +751,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
887 // No motor recently applied, keep the body velocity 751 // No motor recently applied, keep the body velocity
888 // and decay the velocity 752 // and decay the velocity
889 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); 753 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
754 if (m_angularMotorVelocity.LengthSquared() < 0.00001)
755 m_angularMotorVelocity = Vector3.Zero;
890 } // end motor section 756 } // end motor section
891 757
892 // Vertical attractor section 758 // Vertical attractor section
@@ -924,7 +790,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
924 vertattr.X += bounce * angularVelocity.X; 790 vertattr.X += bounce * angularVelocity.X;
925 vertattr.Y += bounce * angularVelocity.Y; 791 vertattr.Y += bounce * angularVelocity.Y;
926 792
927 DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}", 793 VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
928 m_prim.LocalID, verterr, bounce, vertattr); 794 m_prim.LocalID, verterr, bounce, vertattr);
929 795
930 } // else vertical attractor is off 796 } // else vertical attractor is off
@@ -942,13 +808,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
942 { 808 {
943 m_lastAngularVelocity.X = 0; 809 m_lastAngularVelocity.X = 0;
944 m_lastAngularVelocity.Y = 0; 810 m_lastAngularVelocity.Y = 0;
945 DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 811 VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
946 } 812 }
947 813
948 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 814 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
949 { 815 {
950 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. 816 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
951 DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 817 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
952 } 818 }
953 819
954 // apply friction 820 // apply friction
@@ -958,7 +824,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
958 // Apply to the body 824 // Apply to the body
959 m_prim.RotationalVelocity = m_lastAngularVelocity; 825 m_prim.RotationalVelocity = m_lastAngularVelocity;
960 826
961 DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity); 827 VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
962 } //end MoveAngular 828 } //end MoveAngular
963 829
964 internal void LimitRotation(float timestep) 830 internal void LimitRotation(float timestep)
@@ -1005,11 +871,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1005 if (changed) 871 if (changed)
1006 m_prim.Orientation = m_rot; 872 m_prim.Orientation = m_rot;
1007 873
1008 DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot); 874 VDetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
1009 } 875 }
1010 876
1011 // Invoke the detailed logger and output something if it's enabled. 877 // Invoke the detailed logger and output something if it's enabled.
1012 private void DetailLog(string msg, params Object[] args) 878 private void VDetailLog(string msg, params Object[] args)
1013 { 879 {
1014 if (m_prim.Scene.VehicleLoggingEnabled) 880 if (m_prim.Scene.VehicleLoggingEnabled)
1015 m_prim.Scene.PhysicsLogging.Write(msg, args); 881 m_prim.Scene.PhysicsLogging.Write(msg, args);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 087b9bb..9e3f0db 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -42,6 +42,9 @@ public class BSLinkset
42 private BSScene m_physicsScene; 42 private BSScene m_physicsScene;
43 public BSScene PhysicsScene { get { return m_physicsScene; } } 43 public BSScene PhysicsScene { get { return m_physicsScene; } }
44 44
45 static int m_nextLinksetID = 1;
46 public int LinksetID { get; private set; }
47
45 // The children under the root in this linkset 48 // The children under the root in this linkset
46 private List<BSPrim> m_children; 49 private List<BSPrim> m_children;
47 50
@@ -74,6 +77,10 @@ public class BSLinkset
74 public BSLinkset(BSScene scene, BSPrim parent) 77 public BSLinkset(BSScene scene, BSPrim parent)
75 { 78 {
76 // A simple linkset of one (no children) 79 // A simple linkset of one (no children)
80 LinksetID = m_nextLinksetID++;
81 // We create LOTS of linksets.
82 if (m_nextLinksetID < 0)
83 m_nextLinksetID = 1;
77 m_physicsScene = scene; 84 m_physicsScene = scene;
78 m_linksetRoot = parent; 85 m_linksetRoot = parent;
79 m_children = new List<BSPrim>(); 86 m_children = new List<BSPrim>();
@@ -258,8 +265,7 @@ public class BSLinkset
258 BSPrim childx = child; 265 BSPrim childx = child;
259 m_physicsScene.TaintedObject("AddChildToLinkset", delegate() 266 m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
260 { 267 {
261 // DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); 268 DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
262 // DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
263 PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child 269 PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
264 }); 270 });
265 } 271 }
@@ -287,8 +293,7 @@ public class BSLinkset
287 BSPrim childx = child; 293 BSPrim childx = child;
288 m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 294 m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
289 { 295 {
290 // DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); 296 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
291 // DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
292 297
293 PhysicallyUnlinkAChildFromRoot(rootx, childx); 298 PhysicallyUnlinkAChildFromRoot(rootx, childx);
294 }); 299 });
@@ -319,7 +324,6 @@ public class BSLinkset
319 324
320 // create a constraint that allows no freedom of movement between the two objects 325 // create a constraint that allows no freedom of movement between the two objects
321 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 326 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
322 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
323 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}", 327 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
324 rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint); 328 rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
325 BS6DofConstraint constrain = new BS6DofConstraint( 329 BS6DofConstraint constrain = new BS6DofConstraint(
@@ -328,10 +332,10 @@ public class BSLinkset
328 true, 332 true,
329 true 333 true
330 ); 334 );
331 /* NOTE: attempt to build constraint with full frame computation, etc. 335 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
332 * Using the midpoint is easier since it lets the Bullet code use the transforms 336 * Using the midpoint is easier since it lets the Bullet code use the transforms
333 * of the objects. 337 * of the objects.
334 * Code left here as an example. 338 * Code left as a warning to future programmers.
335 // ================================================================================== 339 // ==================================================================================
336 // relative position normalized to the root prim 340 // relative position normalized to the root prim
337 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); 341 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
@@ -343,7 +347,6 @@ public class BSLinkset
343 347
344 // create a constraint that allows no freedom of movement between the two objects 348 // create a constraint that allows no freedom of movement between the two objects
345 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 349 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
346 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
347 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 350 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
348 BS6DofConstraint constrain = new BS6DofConstraint( 351 BS6DofConstraint constrain = new BS6DofConstraint(
349 PhysicsScene.World, rootPrim.Body, childPrim.Body, 352 PhysicsScene.World, rootPrim.Body, childPrim.Body,
@@ -382,8 +385,6 @@ public class BSLinkset
382 // Called at taint time! 385 // Called at taint time!
383 private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) 386 private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim)
384 { 387 {
385 // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
386 // LogHeader, rootPrim.LocalID, childPrim.LocalID);
387 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 388 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
388 389
389 // Find the constraint for this link and get rid of it from the overall collection and from my list 390 // Find the constraint for this link and get rid of it from the overall collection and from my list
@@ -397,20 +398,12 @@ public class BSLinkset
397 // Called at taint time! 398 // Called at taint time!
398 private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) 399 private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim)
399 { 400 {
400 // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
401 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); 401 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
402 402
403 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); 403 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body);
404 } 404 }
405 405
406 // Invoke the detailed logger and output something if it's enabled. 406 // Invoke the detailed logger and output something if it's enabled.
407 private void DebugLog(string msg, params Object[] args)
408 {
409 if (m_physicsScene.ShouldDebugLog)
410 m_physicsScene.Logger.DebugFormat(msg, args);
411 }
412
413 // Invoke the detailed logger and output something if it's enabled.
414 private void DetailLog(string msg, params Object[] args) 407 private void DetailLog(string msg, params Object[] args)
415 { 408 {
416 m_physicsScene.PhysicsLogging.Write(msg, args); 409 m_physicsScene.PhysicsLogging.Write(msg, args);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 9c20004..d3f1e9c 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -42,8 +42,6 @@ public sealed class BSPrim : PhysicsActor
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 private static readonly string LogHeader = "[BULLETS PRIM]"; 43 private static readonly string LogHeader = "[BULLETS PRIM]";
44 44
45 private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); }
46
47 private IMesh _mesh; 45 private IMesh _mesh;
48 private PrimitiveBaseShape _pbs; 46 private PrimitiveBaseShape _pbs;
49 private ShapeData.PhysicsShapeType _shapeType; 47 private ShapeData.PhysicsShapeType _shapeType;
@@ -141,8 +139,8 @@ public sealed class BSPrim : PhysicsActor
141 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material 139 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
142 _density = _scene.Params.defaultDensity; // TODO: compute based on object material 140 _density = _scene.Params.defaultDensity; // TODO: compute based on object material
143 _restitution = _scene.Params.defaultRestitution; 141 _restitution = _scene.Params.defaultRestitution;
144 _linkset = new BSLinkset(_scene, this); // a linkset of one 142 _linkset = new BSLinkset(Scene, this); // a linkset of one
145 _vehicle = new BSDynamics(this); // add vehicleness 143 _vehicle = new BSDynamics(Scene, this); // add vehicleness
146 _mass = CalculateMass(); 144 _mass = CalculateMass();
147 // do the actual object creation at taint time 145 // do the actual object creation at taint time
148 DetailLog("{0},BSPrim.constructor,call", LocalID); 146 DetailLog("{0},BSPrim.constructor,call", LocalID);
@@ -193,7 +191,7 @@ public sealed class BSPrim : PhysicsActor
193 { 191 {
194 _mass = CalculateMass(); // changing size changes the mass 192 _mass = CalculateMass(); // changing size changes the mass
195 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); 193 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
196 // DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); 194 DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
197 RecreateGeomAndObject(); 195 RecreateGeomAndObject();
198 }); 196 });
199 } 197 }
@@ -232,7 +230,6 @@ public sealed class BSPrim : PhysicsActor
232 BSPrim parent = obj as BSPrim; 230 BSPrim parent = obj as BSPrim;
233 if (parent != null) 231 if (parent != null)
234 { 232 {
235 DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID);
236 BSPrim parentBefore = _linkset.LinksetRoot; 233 BSPrim parentBefore = _linkset.LinksetRoot;
237 int childrenBefore = _linkset.NumberOfChildren; 234 int childrenBefore = _linkset.NumberOfChildren;
238 235
@@ -248,8 +245,6 @@ public sealed class BSPrim : PhysicsActor
248 public override void delink() { 245 public override void delink() {
249 // TODO: decide if this parent checking needs to happen at taint time 246 // TODO: decide if this parent checking needs to happen at taint time
250 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen 247 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
251 DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
252 _linkset.LinksetRoot._avName+"/"+_linkset.LinksetRoot.LocalID.ToString());
253 248
254 BSPrim parentBefore = _linkset.LinksetRoot; 249 BSPrim parentBefore = _linkset.LinksetRoot;
255 int childrenBefore = _linkset.NumberOfChildren; 250 int childrenBefore = _linkset.NumberOfChildren;
@@ -280,7 +275,7 @@ public sealed class BSPrim : PhysicsActor
280 275
281 public override void LockAngularMotion(OMV.Vector3 axis) 276 public override void LockAngularMotion(OMV.Vector3 axis)
282 { 277 {
283 // DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 278 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
284 return; 279 return;
285 } 280 }
286 281
@@ -299,7 +294,7 @@ public sealed class BSPrim : PhysicsActor
299 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? 294 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
300 _scene.TaintedObject("BSPrim.setPosition", delegate() 295 _scene.TaintedObject("BSPrim.setPosition", delegate()
301 { 296 {
302 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 297 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
303 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 298 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
304 }); 299 });
305 } 300 }
@@ -336,7 +331,7 @@ public sealed class BSPrim : PhysicsActor
336 _force = value; 331 _force = value;
337 _scene.TaintedObject("BSPrim.setForce", delegate() 332 _scene.TaintedObject("BSPrim.setForce", delegate()
338 { 333 {
339 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); 334 DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
340 // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); 335 // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
341 BulletSimAPI.SetObjectForce2(Body.Ptr, _force); 336 BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
342 }); 337 });
@@ -354,7 +349,7 @@ public sealed class BSPrim : PhysicsActor
354 { 349 {
355 // Done at taint time so we're sure the physics engine is not using the variables 350 // Done at taint time so we're sure the physics engine is not using the variables
356 // Vehicle code changes the parameters for this vehicle type. 351 // Vehicle code changes the parameters for this vehicle type.
357 _vehicle.ProcessTypeChange(type); 352 _vehicle.ProcessTypeChange(type, Scene.LastSimulatedTimestep);
358 // Tell the scene about the vehicle so it will get processing each frame. 353 // Tell the scene about the vehicle so it will get processing each frame.
359 _scene.VehicleInSceneTypeChanged(this, type); 354 _scene.VehicleInSceneTypeChanged(this, type);
360 }); 355 });
@@ -414,7 +409,7 @@ public sealed class BSPrim : PhysicsActor
414 _velocity = value; 409 _velocity = value;
415 _scene.TaintedObject("BSPrim.setVelocity", delegate() 410 _scene.TaintedObject("BSPrim.setVelocity", delegate()
416 { 411 {
417 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 412 DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
418 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); 413 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
419 }); 414 });
420 } 415 }
@@ -422,7 +417,7 @@ public sealed class BSPrim : PhysicsActor
422 public override OMV.Vector3 Torque { 417 public override OMV.Vector3 Torque {
423 get { return _torque; } 418 get { return _torque; }
424 set { _torque = value; 419 set { _torque = value;
425 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); 420 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
426 } 421 }
427 } 422 }
428 public override float CollisionScore { 423 public override float CollisionScore {
@@ -449,7 +444,7 @@ public sealed class BSPrim : PhysicsActor
449 _scene.TaintedObject("BSPrim.setOrientation", delegate() 444 _scene.TaintedObject("BSPrim.setOrientation", delegate()
450 { 445 {
451 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 446 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
452 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); 447 DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
453 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 448 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
454 }); 449 });
455 } 450 }
@@ -486,11 +481,8 @@ public sealed class BSPrim : PhysicsActor
486 // No locking here because only called when it is safe 481 // No locking here because only called when it is safe
487 private void SetObjectDynamic() 482 private void SetObjectDynamic()
488 { 483 {
489 // RA: remove this for the moment. 484 // If it's becoming dynamic, it will need hullness
490 // The problem is that dynamic objects are hulls so if we are becoming physical 485 VerifyCorrectPhysicalShape();
491 // the shape has to be checked and possibly built.
492 // Maybe a VerifyCorrectPhysicalShape() routine?
493 // RecreateGeomAndObject();
494 486
495 // Bullet wants static objects to have a mass of zero 487 // Bullet wants static objects to have a mass of zero
496 float mass = IsStatic ? 0f : _mass; 488 float mass = IsStatic ? 0f : _mass;
@@ -501,13 +493,15 @@ public sealed class BSPrim : PhysicsActor
501 _linkset.Refresh(this); 493 _linkset.Refresh(this);
502 494
503 CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); 495 CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr);
504 // DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); 496 DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf);
505 } 497 }
506 498
507 // prims don't fly 499 // prims don't fly
508 public override bool Flying { 500 public override bool Flying {
509 get { return _flying; } 501 get { return _flying; }
510 set { _flying = value; } 502 set {
503 _flying = value;
504 }
511 } 505 }
512 public override bool SetAlwaysRun { 506 public override bool SetAlwaysRun {
513 get { return _setAlwaysRun; } 507 get { return _setAlwaysRun; }
@@ -558,7 +552,7 @@ public sealed class BSPrim : PhysicsActor
558 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); 552 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
559 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 553 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
560 { 554 {
561 // DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); 555 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
562 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); 556 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
563 }); 557 });
564 } 558 }
@@ -575,7 +569,7 @@ public sealed class BSPrim : PhysicsActor
575 _buoyancy = value; 569 _buoyancy = value;
576 _scene.TaintedObject("BSPrim.setBuoyancy", delegate() 570 _scene.TaintedObject("BSPrim.setBuoyancy", delegate()
577 { 571 {
578 // DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 572 DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
579 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); 573 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
580 }); 574 });
581 } 575 }
@@ -638,17 +632,17 @@ public sealed class BSPrim : PhysicsActor
638 } 632 }
639 m_accumulatedForces.Clear(); 633 m_accumulatedForces.Clear();
640 } 634 }
641 // DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); 635 DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
642 BulletSimAPI.AddObjectForce2(Body.Ptr, fSum); 636 BulletSimAPI.AddObjectForce2(Body.Ptr, fSum);
643 }); 637 });
644 } 638 }
645 639
646 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { 640 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
647 // DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); 641 DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
648 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); 642 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
649 } 643 }
650 public override void SetMomentum(OMV.Vector3 momentum) { 644 public override void SetMomentum(OMV.Vector3 momentum) {
651 // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); 645 DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
652 } 646 }
653 public override void SubscribeEvents(int ms) { 647 public override void SubscribeEvents(int ms) {
654 _subscribedEventsMs = ms; 648 _subscribedEventsMs = ms;
@@ -992,7 +986,7 @@ public sealed class BSPrim : PhysicsActor
992 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); 986 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
993 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) 987 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
994 { 988 {
995 // DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); 989 DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
996 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; 990 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
997 // Bullet native objects are scaled by the Bullet engine so pass the size in 991 // Bullet native objects are scaled by the Bullet engine so pass the size in
998 _scale = _size; 992 _scale = _size;
@@ -1006,7 +1000,7 @@ public sealed class BSPrim : PhysicsActor
1006 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); 1000 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
1007 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) 1001 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
1008 { 1002 {
1009 // DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); 1003 DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
1010 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; 1004 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
1011 _scale = _size; 1005 _scale = _size;
1012 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? 1006 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
@@ -1042,19 +1036,26 @@ public sealed class BSPrim : PhysicsActor
1042 // No locking here because this is done when we know physics is not simulating 1036 // No locking here because this is done when we know physics is not simulating
1043 private void CreateGeomMesh() 1037 private void CreateGeomMesh()
1044 { 1038 {
1045 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; 1039 // level of detail based on size and type of the object
1040 float lod = _scene.MeshLOD;
1041 if (_pbs.SculptEntry)
1042 lod = _scene.SculptLOD;
1043 float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
1044 if (maxAxis > _scene.MeshMegaPrimThreshold)
1045 lod = _scene.MeshMegaPrimLOD;
1046
1046 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod); 1047 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
1047 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); 1048 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
1048 1049
1049 // if this new shape is the same as last time, don't recreate the mesh 1050 // if this new shape is the same as last time, don't recreate the mesh
1050 if (_meshKey == newMeshKey) return; 1051 if (_meshKey == newMeshKey) return;
1051 1052
1052 // DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); 1053 DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
1053 // Since we're recreating new, get rid of any previously generated shape 1054 // Since we're recreating new, get rid of any previously generated shape
1054 if (_meshKey != 0) 1055 if (_meshKey != 0)
1055 { 1056 {
1056 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); 1057 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
1057 // DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); 1058 DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
1058 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); 1059 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
1059 _mesh = null; 1060 _mesh = null;
1060 _meshKey = 0; 1061 _meshKey = 0;
@@ -1084,7 +1085,7 @@ public sealed class BSPrim : PhysicsActor
1084 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; 1085 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
1085 // meshes are already scaled by the meshmerizer 1086 // meshes are already scaled by the meshmerizer
1086 _scale = new OMV.Vector3(1f, 1f, 1f); 1087 _scale = new OMV.Vector3(1f, 1f, 1f);
1087 // DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); 1088 DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
1088 return; 1089 return;
1089 } 1090 }
1090 1091
@@ -1098,13 +1099,13 @@ public sealed class BSPrim : PhysicsActor
1098 // if the hull hasn't changed, don't rebuild it 1099 // if the hull hasn't changed, don't rebuild it
1099 if (newHullKey == _hullKey) return; 1100 if (newHullKey == _hullKey) return;
1100 1101
1101 // DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey); 1102 DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
1102 1103
1103 // Since we're recreating new, get rid of any previously generated shape 1104 // Since we're recreating new, get rid of any previously generated shape
1104 if (_hullKey != 0) 1105 if (_hullKey != 0)
1105 { 1106 {
1106 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); 1107 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
1107 // DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey); 1108 DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
1108 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); 1109 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
1109 _hullKey = 0; 1110 _hullKey = 0;
1110 } 1111 }
@@ -1198,7 +1199,7 @@ public sealed class BSPrim : PhysicsActor
1198 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; 1199 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
1199 // meshes are already scaled by the meshmerizer 1200 // meshes are already scaled by the meshmerizer
1200 _scale = new OMV.Vector3(1f, 1f, 1f); 1201 _scale = new OMV.Vector3(1f, 1f, 1f);
1201 // DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); 1202 DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
1202 return; 1203 return;
1203 } 1204 }
1204 1205
@@ -1210,6 +1211,27 @@ public sealed class BSPrim : PhysicsActor
1210 return; 1211 return;
1211 } 1212 }
1212 1213
1214 private void VerifyCorrectPhysicalShape()
1215 {
1216 if (IsStatic)
1217 {
1218 // if static, we don't need a hull so, if there is one, rebuild without it
1219 if (_hullKey != 0)
1220 {
1221 RecreateGeomAndObject();
1222 }
1223 }
1224 else
1225 {
1226 // if not static, it will need a hull to efficiently collide with things
1227 if (_hullKey == 0)
1228 {
1229 RecreateGeomAndObject();
1230 }
1231
1232 }
1233 }
1234
1213 // Create an object in Bullet if it has not already been created 1235 // Create an object in Bullet if it has not already been created
1214 // No locking here because this is done when the physics engine is not simulating 1236 // No locking here because this is done when the physics engine is not simulating
1215 // Returns 'true' if an object was actually created. 1237 // Returns 'true' if an object was actually created.
@@ -1334,10 +1356,8 @@ public sealed class BSPrim : PhysicsActor
1334 _acceleration = entprop.Acceleration; 1356 _acceleration = entprop.Acceleration;
1335 _rotationalVelocity = entprop.RotationalVelocity; 1357 _rotationalVelocity = entprop.RotationalVelocity;
1336 1358
1337 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", 1359 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1338 // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); 1360 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1339 // DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1340 // LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1341 1361
1342 base.RequestPhysicsterseUpdate(); 1362 base.RequestPhysicsterseUpdate();
1343 } 1363 }
@@ -1353,6 +1373,7 @@ public sealed class BSPrim : PhysicsActor
1353 } 1373 }
1354 1374
1355 // I've collided with something 1375 // I've collided with something
1376 // Called at taint time from within the Step() function
1356 CollisionEventUpdate collisionCollection; 1377 CollisionEventUpdate collisionCollection;
1357 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 1378 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
1358 { 1379 {
@@ -1366,6 +1387,15 @@ public sealed class BSPrim : PhysicsActor
1366 } 1387 }
1367 1388
1368 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); 1389 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
1390 BSPrim collidingWithPrim;
1391 if (_scene.Prims.TryGetValue(collidingWith, out collidingWithPrim))
1392 {
1393 // prims in the same linkset cannot collide with each other
1394 if (this.Linkset.LinksetID == collidingWithPrim.Linkset.LinksetID)
1395 {
1396 return;
1397 }
1398 }
1369 1399
1370 // if someone is subscribed to collision events.... 1400 // if someone is subscribed to collision events....
1371 if (_subscribedEventsMs != 0) { 1401 if (_subscribedEventsMs != 0) {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index a31c578..56924aa 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -73,15 +73,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters
73 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 73 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
74 private static readonly string LogHeader = "[BULLETS SCENE]"; 74 private static readonly string LogHeader = "[BULLETS SCENE]";
75 75
76 public void DebugLog(string mm, params Object[] xx) { if (ShouldDebugLog) m_log.DebugFormat(mm, xx); } 76 // The name of the region we're working for.
77 public string RegionName { get; private set; }
77 78
78 public string BulletSimVersion = "?"; 79 public string BulletSimVersion = "?";
79 80
80 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); 81 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
82 public Dictionary<uint, BSCharacter> Characters { get { return m_avatars; } }
83
81 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>(); 84 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
85 public Dictionary<uint, BSPrim> Prims { get { return m_prims; } }
86
82 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>(); 87 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
83 private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>(); 88 private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>();
89
84 private List<BSPrim> m_vehicles = new List<BSPrim>(); 90 private List<BSPrim> m_vehicles = new List<BSPrim>();
91
85 private float[] m_heightMap; 92 private float[] m_heightMap;
86 private float m_waterLevel; 93 private float m_waterLevel;
87 private uint m_worldID; 94 private uint m_worldID;
@@ -95,16 +102,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
95 private int m_detailedStatsStep = 0; 102 private int m_detailedStatsStep = 0;
96 103
97 public IMesher mesher; 104 public IMesher mesher;
98 private float m_meshLOD; 105 // Level of Detail values kept as float because that's what the Meshmerizer wants
99 public float MeshLOD 106 public float MeshLOD { get; private set; }
100 { 107 public float MeshMegaPrimLOD { get; private set; }
101 get { return m_meshLOD; } 108 public float MeshMegaPrimThreshold { get; private set; }
102 } 109 public float SculptLOD { get; private set; }
103 private float m_sculptLOD;
104 public float SculptLOD
105 {
106 get { return m_sculptLOD; }
107 }
108 110
109 private BulletSim m_worldSim; 111 private BulletSim m_worldSim;
110 public BulletSim World 112 public BulletSim World
@@ -179,8 +181,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
179 ConfigurationParameters[] m_params; 181 ConfigurationParameters[] m_params;
180 GCHandle m_paramsHandle; 182 GCHandle m_paramsHandle;
181 183
182 public bool ShouldDebugLog { get; private set; } 184 // Handle to the callback used by the unmanaged code to call into the managed code.
183 185 // Used for debug logging.
186 // Need to store the handle in a persistant variable so it won't be freed.
184 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; 187 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
185 188
186 // Sometimes you just have to log everything. 189 // Sometimes you just have to log everything.
@@ -196,6 +199,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
196 public BSScene(string identifier) 199 public BSScene(string identifier)
197 { 200 {
198 m_initialized = false; 201 m_initialized = false;
202 // we are passed the name of the region we're working for.
203 RegionName = identifier;
199 } 204 }
200 205
201 public override void Initialise(IMesher meshmerizer, IConfigSource config) 206 public override void Initialise(IMesher meshmerizer, IConfigSource config)
@@ -281,10 +286,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
281 // Very detailed logging for physics debugging 286 // Very detailed logging for physics debugging
282 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); 287 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
283 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); 288 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
284 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-"); 289 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
285 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); 290 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
286 // Very detailed logging for vehicle debugging 291 // Very detailed logging for vehicle debugging
287 m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); 292 m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
293
294 // Do any replacements in the parameters
295 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
288 } 296 }
289 } 297 }
290 } 298 }
@@ -362,7 +370,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
362 BSPrim bsprim = prim as BSPrim; 370 BSPrim bsprim = prim as BSPrim;
363 if (bsprim != null) 371 if (bsprim != null)
364 { 372 {
365 // DetailLog("{0},RemovePrim,call", bsprim.LocalID); 373 DetailLog("{0},RemovePrim,call", bsprim.LocalID);
366 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); 374 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
367 try 375 try
368 { 376 {
@@ -388,7 +396,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
388 396
389 if (!m_initialized) return null; 397 if (!m_initialized) return null;
390 398
391 // DetailLog("{0},AddPrimShape,call", localID); 399 DetailLog("{0},AddPrimShape,call", localID);
392 400
393 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); 401 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
394 lock (m_prims) m_prims.Add(localID, prim); 402 lock (m_prims) m_prims.Add(localID, prim);
@@ -429,13 +437,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
429 { 437 {
430 numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, 438 numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
431 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); 439 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
432 // DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); 440 DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
433 } 441 }
434 catch (Exception e) 442 catch (Exception e)
435 { 443 {
436 m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e); 444 m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e);
437 // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); 445 // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
438 // updatedEntityCount = 0; 446 updatedEntityCount = 0;
439 collidersCount = 0; 447 collidersCount = 0;
440 } 448 }
441 449
@@ -534,6 +542,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
534 else if (m_avatars.ContainsKey(collidingWith)) 542 else if (m_avatars.ContainsKey(collidingWith))
535 type = ActorTypes.Agent; 543 type = ActorTypes.Agent;
536 544
545 // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
546
537 BSPrim prim; 547 BSPrim prim;
538 if (m_prims.TryGetValue(localID, out prim)) { 548 if (m_prims.TryGetValue(localID, out prim)) {
539 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration); 549 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
@@ -897,16 +907,26 @@ public class BSScene : PhysicsScene, IPhysicsParameters
897 (s) => { return s.NumericBool(s._forceSimplePrimMeshing); }, 907 (s) => { return s.NumericBool(s._forceSimplePrimMeshing); },
898 (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ), 908 (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ),
899 909
900 new ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", 910 new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
901 8f, 911 8f,
902 (s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); }, 912 (s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); },
903 (s) => { return (float)s.m_meshLOD; }, 913 (s) => { return s.MeshLOD; },
904 (s,p,l,v) => { s.m_meshLOD = (int)v; } ), 914 (s,p,l,v) => { s.MeshLOD = v; } ),
905 new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", 915 new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
916 16f,
917 (s,cf,p,v) => { s.MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
918 (s) => { return s.MeshMegaPrimLOD; },
919 (s,p,l,v) => { s.MeshMegaPrimLOD = v; } ),
920 new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
921 10f,
922 (s,cf,p,v) => { s.MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
923 (s) => { return s.MeshMegaPrimThreshold; },
924 (s,p,l,v) => { s.MeshMegaPrimThreshold = v; } ),
925 new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
906 32f, 926 32f,
907 (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); }, 927 (s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); },
908 (s) => { return (float)s.m_sculptLOD; }, 928 (s) => { return s.SculptLOD; },
909 (s,p,l,v) => { s.m_sculptLOD = (int)v; } ), 929 (s,p,l,v) => { s.SculptLOD = v; } ),
910 930
911 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", 931 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
912 10f, 932 10f,
@@ -1137,12 +1157,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1137 (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); }, 1157 (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); },
1138 (s) => { return (float)s.m_detailedStatsStep; }, 1158 (s) => { return (float)s.m_detailedStatsStep; },
1139 (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), 1159 (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
1140 new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
1141 ConfigurationParameters.numericFalse,
1142 (s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
1143 (s) => { return s.NumericBool(s.ShouldDebugLog); },
1144 (s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ),
1145
1146 }; 1160 };
1147 1161
1148 // Convert a boolean to our numeric true and false values 1162 // Convert a boolean to our numeric true and false values
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 7e48659..fceae02 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -1343,31 +1343,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1343 if (part == null || part.ParentGroup.IsDeleted) 1343 if (part == null || part.ParentGroup.IsDeleted)
1344 return; 1344 return;
1345 1345
1346 if (scale.x < 0.01) 1346 // First we need to check whether or not we need to clamp the size of a physics-enabled prim
1347 scale.x = 0.01;
1348 if (scale.y < 0.01)
1349 scale.y = 0.01;
1350 if (scale.z < 0.01)
1351 scale.z = 0.01;
1352
1353 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor; 1347 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor;
1354
1355 if (pa != null && pa.IsPhysical) 1348 if (pa != null && pa.IsPhysical)
1356 { 1349 {
1357 if (scale.x > World.m_maxPhys) 1350 scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x));
1358 scale.x = World.m_maxPhys; 1351 scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y));
1359 if (scale.y > World.m_maxPhys) 1352 scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z));
1360 scale.y = World.m_maxPhys;
1361 if (scale.z > World.m_maxPhys)
1362 scale.z = World.m_maxPhys;
1363 } 1353 }
1364 1354
1365 if (scale.x > World.m_maxNonphys) 1355 // Next we clamp the scale to the non-physical min/max
1366 scale.x = World.m_maxNonphys; 1356 scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x));
1367 if (scale.y > World.m_maxNonphys) 1357 scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y));
1368 scale.y = World.m_maxNonphys; 1358 scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z));
1369 if (scale.z > World.m_maxNonphys)
1370 scale.z = World.m_maxNonphys;
1371 1359
1372 Vector3 tmp = part.Scale; 1360 Vector3 tmp = part.Scale;
1373 tmp.X = (float)scale.x; 1361 tmp.X = (float)scale.x;
@@ -4031,9 +4019,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4031 public void llSetText(string text, LSL_Vector color, double alpha) 4019 public void llSetText(string text, LSL_Vector color, double alpha)
4032 { 4020 {
4033 m_host.AddScriptLPS(1); 4021 m_host.AddScriptLPS(1);
4034 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), 4022 Vector3 av3 = Util.Clip(new Vector3((float)color.x, (float)color.y,
4035 Util.Clip((float)color.y, 0.0f, 1.0f), 4023 (float)color.z), 0.0f, 1.0f);
4036 Util.Clip((float)color.z, 0.0f, 1.0f));
4037 m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); 4024 m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
4038 //m_host.ParentGroup.HasGroupChanged = true; 4025 //m_host.ParentGroup.HasGroupChanged = true;
4039 //m_host.ParentGroup.ScheduleGroupForFullUpdate(); 4026 //m_host.ParentGroup.ScheduleGroupForFullUpdate();
@@ -7647,9 +7634,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7647 string primText = rules.GetLSLStringItem(idx++); 7634 string primText = rules.GetLSLStringItem(idx++);
7648 LSL_Vector primTextColor = rules.GetVector3Item(idx++); 7635 LSL_Vector primTextColor = rules.GetVector3Item(idx++);
7649 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); 7636 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
7650 Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), 7637 Vector3 av3 = Util.Clip(new Vector3((float)primTextColor.x,
7651 Util.Clip((float)primTextColor.y, 0.0f, 1.0f), 7638 (float)primTextColor.y,
7652 Util.Clip((float)primTextColor.z, 0.0f, 1.0f)); 7639 (float)primTextColor.z), 0.0f, 1.0f);
7653 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); 7640 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
7654 7641
7655 break; 7642 break;
@@ -7679,6 +7666,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7679 LSL_Float gain = rules.GetLSLFloatItem(idx++); 7666 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7680 TargetOmega(part, axis, (double)spinrate, (double)gain); 7667 TargetOmega(part, axis, (double)spinrate, (double)gain);
7681 break; 7668 break;
7669 case (int)ScriptBaseClass.PRIM_SLICE:
7670 if (remain < 1)
7671 return null;
7672 LSL_Vector slice = rules.GetVector3Item(idx++);
7673 part.UpdateSlice((float)slice.x, (float)slice.y);
7674 break;
7682 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 7675 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7683 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 7676 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7684 return null; 7677 return null;
@@ -7687,6 +7680,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7687 } 7680 }
7688 } 7681 }
7689 } 7682 }
7683 catch (InvalidCastException e)
7684 {
7685 ShoutError(e.Message);
7686 }
7690 finally 7687 finally
7691 { 7688 {
7692 if (positionChanged) 7689 if (positionChanged)
@@ -8349,6 +8346,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8349 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 8346 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8350 res.Add(new LSL_Vector(GetPartLocalPos(part))); 8347 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8351 break; 8348 break;
8349 case (int)ScriptBaseClass.PRIM_SLICE:
8350 PrimType prim_type = part.GetPrimType();
8351 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
8352 res.Add(new LSL_Vector(
8353 (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0,
8354 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0,
8355 0
8356 ));
8357 break;
8352 } 8358 }
8353 } 8359 }
8354 return res; 8360 return res;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index e1c054d..cad8518 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -328,6 +328,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
328 public const int PRIM_OMEGA = 32; 328 public const int PRIM_OMEGA = 32;
329 public const int PRIM_POS_LOCAL = 33; 329 public const int PRIM_POS_LOCAL = 33;
330 public const int PRIM_LINK_TARGET = 34; 330 public const int PRIM_LINK_TARGET = 34;
331 public const int PRIM_SLICE = 35;
331 public const int PRIM_TEXGEN_DEFAULT = 0; 332 public const int PRIM_TEXGEN_DEFAULT = 0;
332 public const int PRIM_TEXGEN_PLANAR = 1; 333 public const int PRIM_TEXGEN_PLANAR = 1;
333 334
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..562433d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -560,12 +560,23 @@ namespace OpenSim.Region.ScriptEngine.Shared
560 else if (m_data[itemIndex] is LSL_Types.LSLString) 560 else if (m_data[itemIndex] is LSL_Types.LSLString)
561 return new LSLInteger(m_data[itemIndex].ToString()); 561 return new LSLInteger(m_data[itemIndex].ToString());
562 else 562 else
563 throw new InvalidCastException(); 563 throw new InvalidCastException(string.Format(
564 "{0} expected but {1} given",
565 typeof(LSL_Types.LSLInteger).Name,
566 m_data[itemIndex] != null ?
567 m_data[itemIndex].GetType().Name : "null"));
564 } 568 }
565 569
566 public LSL_Types.Vector3 GetVector3Item(int itemIndex) 570 public LSL_Types.Vector3 GetVector3Item(int itemIndex)
567 { 571 {
568 return (LSL_Types.Vector3)m_data[itemIndex]; 572 if(m_data[itemIndex] is LSL_Types.Vector3)
573 return (LSL_Types.Vector3)m_data[itemIndex];
574 else
575 throw new InvalidCastException(string.Format(
576 "{0} expected but {1} given",
577 typeof(LSL_Types.Vector3).Name,
578 m_data[itemIndex] != null ?
579 m_data[itemIndex].GetType().Name : "null"));
569 } 580 }
570 581
571 public LSL_Types.Quaternion GetQuaternionItem(int itemIndex) 582 public LSL_Types.Quaternion GetQuaternionItem(int itemIndex)
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 2dba029..1571fb4 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -982,10 +982,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
982 return false; 982 return false;
983 } 983 }
984 984
985 UUID assetID = item.AssetID; 985 m_log.DebugFormat(
986 "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
987 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
988 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
986 989
987 //m_log.DebugFormat("[XEngine] Compiling script {0} ({1} on object {2})", 990 UUID assetID = item.AssetID;
988 // item.Name, itemID.ToString(), part.ParentGroup.RootPart.Name);
989 991
990 ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID); 992 ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID);
991 993
@@ -1164,10 +1166,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1164 stateSource, m_MaxScriptQueue); 1166 stateSource, m_MaxScriptQueue);
1165 1167
1166// if (DebugLevel >= 1) 1168// if (DebugLevel >= 1)
1167 m_log.DebugFormat( 1169// m_log.DebugFormat(
1168 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", 1170// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1169 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, 1171// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1170 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1172// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1171 1173
1172 if (presence != null) 1174 if (presence != null)
1173 { 1175 {
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 9c68b65..eac30b8 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -87,10 +87,18 @@
87 ;; from the selected region_info_source. 87 ;; from the selected region_info_source.
88 ; allow_regionless = false 88 ; allow_regionless = false
89 89
90 ;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.01
91 ;; Minimum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMin!).
92 ; NonphysicalPrimMin = 0.01
93
90 ;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256 94 ;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256
91 ;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!). 95 ;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!).
92 ; NonphysicalPrimMax = 256 96 ; NonphysicalPrimMax = 256
93 97
98 ;# {PhysicalPrimMin} {} {Minimum size of physical prims?} {} 10
99 ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
100 ; PhysicalPrimMin = 0.01
101
94 ;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10 102 ;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10
95 ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file. 103 ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
96 ; PhysicalPrimMax = 10 104 ; PhysicalPrimMax = 10
@@ -675,7 +683,9 @@
675 ;; Maximum number of events to queue for a script (excluding timers) 683 ;; Maximum number of events to queue for a script (excluding timers)
676 ; MaxScriptEventQueue = 300 684 ; MaxScriptEventQueue = 300
677 685
678 ;; Stack size per thread created 686 ;; Stack size per script engine thread in bytes.
687 ;; If you are experiencing StackOverflowExceptions you may want to increase this (e.g. double it).
688 ;; The trade-off may be increased memory usage by the script engine.
679 ; ThreadStackSize = 262144 689 ; ThreadStackSize = 262144
680 690
681 ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true 691 ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 96f1386..b2fca0c 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -931,6 +931,9 @@
931 931
932 ; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail 932 ; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail
933 MeshLevelOfDetail = 8 933 MeshLevelOfDetail = 8
934 ; if mesh size is > threshold meters, we need to add more detail because people will notice
935 MeshLevelOfDetailMegaPrimThreshold = 10
936 MeshLevelOfDetailMegaPrim = 16
934 ; number^2 non-physical level of detail of the sculpt texture. 32x32 - 1024 verticies 937 ; number^2 non-physical level of detail of the sculpt texture. 32x32 - 1024 verticies
935 SculptLevelOfDetail = 32 938 SculptLevelOfDetail = 32
936 939
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll
index 0f2d522..cc55f00 100755
--- a/bin/lib32/BulletSim.dll
+++ b/bin/lib32/BulletSim.dll
Binary files differ
diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so
index 783c9a2..26ad52b 100755
--- a/bin/lib32/libBulletSim.so
+++ b/bin/lib32/libBulletSim.so
Binary files differ
diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll
index c2a2bda..94dae95 100755
--- a/bin/lib64/BulletSim.dll
+++ b/bin/lib64/BulletSim.dll
Binary files differ
diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so
index 74d4f98..52e9960 100755
--- a/bin/lib64/libBulletSim.so
+++ b/bin/lib64/libBulletSim.so
Binary files differ