diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index 2c38e0f6a1..87ec99ef60 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -71,6 +71,14 @@ namespace OpenSim.Framework
///
bool LoginsEnabled { get; set; }
+ ///
+ /// Is this region ready for use?
+ ///
+ ///
+ /// This does not mean that logins are enabled, merely that they can be.
+ ///
+ bool Ready { get; set; }
+
float TimeDilation { get; }
bool AllowScriptCrossings { get; }
diff --git a/OpenSim/Framework/Statistics/AssetStatsCollector.cs b/OpenSim/Framework/Monitoring/AssetStatsCollector.cs
similarity index 99%
rename from OpenSim/Framework/Statistics/AssetStatsCollector.cs
rename to OpenSim/Framework/Monitoring/AssetStatsCollector.cs
index 7082ef3c3c..2a4d45bf0c 100644
--- a/OpenSim/Framework/Statistics/AssetStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/AssetStatsCollector.cs
@@ -28,7 +28,7 @@
using System;
using System.Timers;
-namespace OpenSim.Framework.Statistics
+namespace OpenSim.Framework.Monitoring
{
///
/// Asset service statistics collection
diff --git a/OpenSim/Framework/Statistics/BaseStatsCollector.cs b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
similarity index 80%
rename from OpenSim/Framework/Statistics/BaseStatsCollector.cs
rename to OpenSim/Framework/Monitoring/BaseStatsCollector.cs
index c9e57ce7b3..57a63ef4f2 100644
--- a/OpenSim/Framework/Statistics/BaseStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/BaseStatsCollector.cs
@@ -31,8 +31,7 @@ using System.Text;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
-
-namespace OpenSim.Framework.Statistics
+namespace OpenSim.Framework.Monitoring
{
///
/// Statistics which all collectors are interested in reporting
@@ -44,14 +43,18 @@ namespace OpenSim.Framework.Statistics
StringBuilder sb = new StringBuilder(Environment.NewLine);
sb.Append("MEMORY STATISTICS");
sb.Append(Environment.NewLine);
- sb.Append(
- string.Format(
- "Allocated to OpenSim objects: {0} MB\n",
- Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)));
- sb.Append(
- string.Format(
- "Process memory : {0} MB\n",
- Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0)));
+
+ sb.AppendFormat(
+ "Allocated to OpenSim objects: {0} MB\n",
+ Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
+
+ sb.AppendFormat(
+ "OpenSim object memory churn : {0} MB/s\n",
+ Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
+
+ sb.AppendFormat(
+ "Process memory : {0} MB\n",
+ Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0));
return sb.ToString();
}
diff --git a/OpenSim/Framework/Statistics/Interfaces/IPullStatsProvider.cs b/OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs
similarity index 97%
rename from OpenSim/Framework/Statistics/Interfaces/IPullStatsProvider.cs
rename to OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs
index 430e580e1a..86a66207f6 100644
--- a/OpenSim/Framework/Statistics/Interfaces/IPullStatsProvider.cs
+++ b/OpenSim/Framework/Monitoring/Interfaces/IPullStatsProvider.cs
@@ -25,7 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-namespace OpenSim.Framework.Statistics.Interfaces
+namespace OpenSim.Framework.Monitoring.Interfaces
{
///
/// Implemented by objects which allow statistical information to be pulled from them.
diff --git a/OpenSim/Framework/Statistics/Interfaces/IStatsCollector.cs b/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs
similarity index 98%
rename from OpenSim/Framework/Statistics/Interfaces/IStatsCollector.cs
rename to OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs
index 477bbb364e..99f75e34b1 100644
--- a/OpenSim/Framework/Statistics/Interfaces/IStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/Interfaces/IStatsCollector.cs
@@ -25,7 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-namespace OpenSim.Framework.Statistics
+namespace OpenSim.Framework.Monitoring
{
///
/// Implemented by classes which collect up non-viewer statistical information
diff --git a/OpenSim/Framework/Monitoring/MemoryWatchdog.cs b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
new file mode 100644
index 0000000000..65996136c5
--- /dev/null
+++ b/OpenSim/Framework/Monitoring/MemoryWatchdog.cs
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using log4net;
+
+namespace OpenSim.Framework.Monitoring
+{
+ ///
+ /// Experimental watchdog for memory usage.
+ ///
+ public static class MemoryWatchdog
+ {
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Is this watchdog active?
+ ///
+ public static bool Enabled
+ {
+ get { return m_enabled; }
+ set
+ {
+// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
+
+ if (value && !m_enabled)
+ UpdateLastRecord(GC.GetTotalMemory(false), Util.EnvironmentTickCount());
+
+ m_enabled = value;
+ }
+ }
+ private static bool m_enabled;
+
+ ///
+ /// Average memory churn in bytes per millisecond.
+ ///
+ public static double AverageMemoryChurn
+ {
+ get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; }
+ }
+
+ ///
+ /// Maximum number of statistical samples.
+ ///
+ ///
+ /// At the moment this corresponds to 1 minute since the sampling rate is every 2.5 seconds as triggered from
+ /// the main Watchdog.
+ ///
+ private static int m_maxSamples = 24;
+
+ ///
+ /// Time when the watchdog was last updated.
+ ///
+ private static int m_lastUpdateTick;
+
+ ///
+ /// Memory used at time of last watchdog update.
+ ///
+ private static long m_lastUpdateMemory;
+
+ ///
+ /// Memory churn rate per millisecond.
+ ///
+ private static double m_churnRatePerMillisecond;
+
+ ///
+ /// Historical samples for calculating moving average.
+ ///
+ private static Queue m_samples = new Queue(m_maxSamples);
+
+ public static void Update()
+ {
+ int now = Util.EnvironmentTickCount();
+ long memoryNow = GC.GetTotalMemory(false);
+ long memoryDiff = memoryNow - m_lastUpdateMemory;
+
+ if (memoryDiff >= 0)
+ {
+ if (m_samples.Count >= m_maxSamples)
+ m_samples.Dequeue();
+
+ double elapsed = Util.EnvironmentTickCountSubtract(now, m_lastUpdateTick);
+
+ // This should never happen since it's not useful for updates to occur with no time elapsed, but
+ // protect ourselves from a divide-by-zero just in case.
+ if (elapsed == 0)
+ return;
+
+ m_samples.Enqueue(memoryDiff / (double)elapsed);
+ }
+
+ UpdateLastRecord(memoryNow, now);
+ }
+
+ private static void UpdateLastRecord(long memoryNow, int timeNow)
+ {
+ m_lastUpdateMemory = memoryNow;
+ m_lastUpdateTick = timeNow;
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Framework/Statistics/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
similarity index 99%
rename from OpenSim/Framework/Statistics/SimExtraStatsCollector.cs
rename to OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
index a506e3ba4d..cdd7cc711e 100644
--- a/OpenSim/Framework/Statistics/SimExtraStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
@@ -28,12 +28,11 @@
using System;
using System.Collections.Generic;
using System.Text;
-
using OpenMetaverse;
-using OpenSim.Framework.Statistics.Interfaces;
using OpenMetaverse.StructuredData;
+using OpenSim.Framework.Monitoring.Interfaces;
-namespace OpenSim.Framework.Statistics
+namespace OpenSim.Framework.Monitoring
{
///
/// Collects sim statistics which aren't already being collected for the linden viewer's statistics pane
diff --git a/OpenSim/Framework/Statistics/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
similarity index 98%
rename from OpenSim/Framework/Statistics/StatsManager.cs
rename to OpenSim/Framework/Monitoring/StatsManager.cs
index 436ce2fa04..d78fa6a1f0 100644
--- a/OpenSim/Framework/Statistics/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -25,7 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-namespace OpenSim.Framework.Statistics
+namespace OpenSim.Framework.Monitoring
{
///
/// Singleton used to provide access to statistics reporters
diff --git a/OpenSim/Framework/Statistics/UserStatsCollector.cs b/OpenSim/Framework/Monitoring/UserStatsCollector.cs
similarity index 98%
rename from OpenSim/Framework/Statistics/UserStatsCollector.cs
rename to OpenSim/Framework/Monitoring/UserStatsCollector.cs
index fd2a9bf198..e89c8e6344 100644
--- a/OpenSim/Framework/Statistics/UserStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/UserStatsCollector.cs
@@ -27,7 +27,7 @@
using System.Timers;
-namespace OpenSim.Framework.Statistics
+namespace OpenSim.Framework.Monitoring
{
///
/// Collects user service statistics
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs
similarity index 99%
rename from OpenSim/Framework/Watchdog.cs
rename to OpenSim/Framework/Monitoring/Watchdog.cs
index 8a74f538f7..d4cf02fe41 100644
--- a/OpenSim/Framework/Watchdog.cs
+++ b/OpenSim/Framework/Monitoring/Watchdog.cs
@@ -31,7 +31,7 @@ using System.Linq;
using System.Threading;
using log4net;
-namespace OpenSim.Framework
+namespace OpenSim.Framework.Monitoring
{
///
/// Manages launching threads and keeping watch over them for timeouts
@@ -325,6 +325,9 @@ namespace OpenSim.Framework
callback(callbackInfo);
}
+ if (MemoryWatchdog.Enabled)
+ MemoryWatchdog.Update();
+
m_watchdogTimer.Start();
}
}
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 14d8b0caae..2a8ae38b69 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -40,9 +40,10 @@ using log4net.Core;
using log4net.Repository;
using OpenSim.Framework;
using OpenSim.Framework.Console;
+using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using Timer=System.Timers.Timer;
using OpenMetaverse;
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 3de7f9ca72..f57ea76b66 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -45,6 +45,7 @@ using OpenMetaverse.StructuredData;
using CoolHTTPListener = HttpServer.HttpListener;
using HttpListener=System.Net.HttpListener;
using LogPrio=HttpServer.LogPrio;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer
{
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 3252251702..8d5015110d 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -32,6 +32,7 @@ using System.Reflection;
using log4net;
using HttpServer;
using OpenSim.Framework;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer
{
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
index 35a8dee169..5adbcd1ef8 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
@@ -34,6 +34,7 @@ using HttpServer;
using OpenMetaverse;
using System.Reflection;
using log4net;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer
{
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index a4d85acefb..07a975619f 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -40,7 +40,7 @@ using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
@@ -200,9 +200,9 @@ namespace OpenSim
PrintFileToConsole("startuplogo.txt");
// For now, start at the 'root' level by default
- if (m_sceneManager.Scenes.Count == 1) // If there is only one region, select it
+ if (SceneManager.Scenes.Count == 1) // If there is only one region, select it
ChangeSelectedRegion("region",
- new string[] {"change", "region", m_sceneManager.Scenes[0].RegionInfo.RegionName});
+ new string[] {"change", "region", SceneManager.Scenes[0].RegionInfo.RegionName});
else
ChangeSelectedRegion("region", new string[] {"change", "region", "root"});
@@ -461,7 +461,7 @@ namespace OpenSim
if (cmdparams.Length > 4)
alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4));
- IList agents = m_sceneManager.GetCurrentSceneAvatars();
+ IList agents = SceneManager.GetCurrentSceneAvatars();
foreach (ScenePresence presence in agents)
{
@@ -542,7 +542,7 @@ namespace OpenSim
private void HandleForceUpdate(string module, string[] args)
{
MainConsole.Instance.Output("Updating all clients");
- m_sceneManager.ForceCurrentSceneClientUpdate();
+ SceneManager.ForceCurrentSceneClientUpdate();
}
///
@@ -554,7 +554,7 @@ namespace OpenSim
{
if (args.Length == 6)
{
- m_sceneManager.HandleEditCommandOnCurrentScene(args);
+ SceneManager.HandleEditCommandOnCurrentScene(args);
}
else
{
@@ -765,7 +765,7 @@ namespace OpenSim
case "load":
if (cmdparams.Length > 1)
{
- foreach (Scene s in new ArrayList(m_sceneManager.Scenes))
+ foreach (Scene s in new ArrayList(SceneManager.Scenes))
{
MainConsole.Instance.Output(String.Format("Loading module: {0}", cmdparams[1]));
m_moduleLoader.LoadRegionModules(cmdparams[1], s);
@@ -803,14 +803,14 @@ namespace OpenSim
case "backup":
MainConsole.Instance.Output("Triggering save of pending object updates to persistent store");
- m_sceneManager.BackupCurrentScene();
+ SceneManager.BackupCurrentScene();
break;
case "remove-region":
string regRemoveName = CombineParams(cmdparams, 0);
Scene removeScene;
- if (m_sceneManager.TryGetScene(regRemoveName, out removeScene))
+ if (SceneManager.TryGetScene(regRemoveName, out removeScene))
RemoveRegion(removeScene, false);
else
MainConsole.Instance.Output("No region with that name");
@@ -820,14 +820,14 @@ namespace OpenSim
string regDeleteName = CombineParams(cmdparams, 0);
Scene killScene;
- if (m_sceneManager.TryGetScene(regDeleteName, out killScene))
+ if (SceneManager.TryGetScene(regDeleteName, out killScene))
RemoveRegion(killScene, true);
else
MainConsole.Instance.Output("no region with that name");
break;
case "restart":
- m_sceneManager.RestartCurrentScene();
+ SceneManager.RestartCurrentScene();
break;
}
}
@@ -842,7 +842,7 @@ namespace OpenSim
{
string newRegionName = CombineParams(cmdparams, 2);
- if (!m_sceneManager.TrySetCurrentScene(newRegionName))
+ if (!SceneManager.TrySetCurrentScene(newRegionName))
MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName));
}
else
@@ -850,7 +850,7 @@ namespace OpenSim
MainConsole.Instance.Output("Usage: change region ");
}
- string regionName = (m_sceneManager.CurrentScene == null ? "root" : m_sceneManager.CurrentScene.RegionInfo.RegionName);
+ string regionName = (SceneManager.CurrentScene == null ? "root" : SceneManager.CurrentScene.RegionInfo.RegionName);
MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName));
// m_log.DebugFormat("Original prompt is {0}", m_consolePrompt);
@@ -868,7 +868,7 @@ namespace OpenSim
});
m_console.DefaultPrompt = prompt;
- m_console.ConsoleScene = m_sceneManager.CurrentScene;
+ m_console.ConsoleScene = SceneManager.CurrentScene;
}
///
@@ -892,7 +892,7 @@ namespace OpenSim
int newDebug;
if (int.TryParse(args[2], out newDebug))
{
- m_sceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
+ SceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
// We provide user information elsewhere if any clients had their debug level set.
// MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug);
}
@@ -907,7 +907,7 @@ namespace OpenSim
case "scene":
if (args.Length == 4)
{
- if (m_sceneManager.CurrentScene == null)
+ if (SceneManager.CurrentScene == null)
{
MainConsole.Instance.Output("Please use 'change region ' first");
}
@@ -915,7 +915,7 @@ namespace OpenSim
{
string key = args[2];
string value = args[3];
- m_sceneManager.CurrentScene.SetSceneCoreDebug(
+ SceneManager.CurrentScene.SetSceneCoreDebug(
new Dictionary() { { key, value } });
MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value);
@@ -954,10 +954,10 @@ namespace OpenSim
IList agents;
if (showParams.Length > 1 && showParams[1] == "full")
{
- agents = m_sceneManager.GetCurrentScenePresences();
+ agents = SceneManager.GetCurrentScenePresences();
} else
{
- agents = m_sceneManager.GetCurrentSceneAvatars();
+ agents = SceneManager.GetCurrentSceneAvatars();
}
MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count));
@@ -1037,7 +1037,7 @@ namespace OpenSim
MainConsole.Instance.Output("Shared Module: " + module.Name);
}
- m_sceneManager.ForEachScene(
+ SceneManager.ForEachScene(
delegate(Scene scene) {
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
foreach (IRegionModule module in scene.Modules.Values)
@@ -1050,7 +1050,7 @@ namespace OpenSim
}
);
- m_sceneManager.ForEachScene(
+ SceneManager.ForEachScene(
delegate(Scene scene) {
MainConsole.Instance.Output("Loaded new region modules in" + scene.RegionInfo.RegionName + " are:");
foreach (IRegionModuleBase module in scene.RegionModules.Values)
@@ -1066,7 +1066,7 @@ namespace OpenSim
break;
case "regions":
- m_sceneManager.ForEachScene(
+ SceneManager.ForEachScene(
delegate(Scene scene)
{
MainConsole.Instance.Output(String.Format(
@@ -1080,7 +1080,7 @@ namespace OpenSim
break;
case "ratings":
- m_sceneManager.ForEachScene(
+ SceneManager.ForEachScene(
delegate(Scene scene)
{
string rating = "";
@@ -1115,7 +1115,7 @@ namespace OpenSim
cdt.AddColumn("IP", 16);
cdt.AddColumn("Viewer Name", 24);
- m_sceneManager.ForEachScene(
+ SceneManager.ForEachScene(
s =>
{
foreach (AgentCircuitData aCircuit in s.AuthenticateHandler.GetAgentCircuits().Values)
@@ -1140,7 +1140,7 @@ namespace OpenSim
cdt.AddColumn("Endpoint", 23);
cdt.AddColumn("Active?", 7);
- m_sceneManager.ForEachScene(
+ SceneManager.ForEachScene(
s => s.ForEachClient(
c => cdt.AddRow(
s.Name,
@@ -1161,11 +1161,11 @@ namespace OpenSim
{
if (cmdparams.Length > 5)
{
- m_sceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]);
+ SceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]);
}
else
{
- m_sceneManager.SaveNamedPrimsToXml2("Primitive", DEFAULT_PRIM_BACKUP_FILENAME);
+ SceneManager.SaveNamedPrimsToXml2("Primitive", DEFAULT_PRIM_BACKUP_FILENAME);
}
}
@@ -1180,11 +1180,11 @@ namespace OpenSim
if (cmdparams.Length > 0)
{
- m_sceneManager.SaveCurrentSceneToXml(cmdparams[2]);
+ SceneManager.SaveCurrentSceneToXml(cmdparams[2]);
}
else
{
- m_sceneManager.SaveCurrentSceneToXml(DEFAULT_PRIM_BACKUP_FILENAME);
+ SceneManager.SaveCurrentSceneToXml(DEFAULT_PRIM_BACKUP_FILENAME);
}
}
@@ -1221,13 +1221,13 @@ namespace OpenSim
MainConsole.Instance.Output(String.Format("loadOffsets = <{0},{1},{2}>",loadOffset.X,loadOffset.Y,loadOffset.Z));
}
}
- m_sceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset);
+ SceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset);
}
else
{
try
{
- m_sceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset);
+ SceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset);
}
catch (FileNotFoundException)
{
@@ -1244,11 +1244,11 @@ namespace OpenSim
{
if (cmdparams.Length > 2)
{
- m_sceneManager.SaveCurrentSceneToXml2(cmdparams[2]);
+ SceneManager.SaveCurrentSceneToXml2(cmdparams[2]);
}
else
{
- m_sceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME);
+ SceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME);
}
}
@@ -1263,7 +1263,7 @@ namespace OpenSim
{
try
{
- m_sceneManager.LoadCurrentSceneFromXml2(cmdparams[2]);
+ SceneManager.LoadCurrentSceneFromXml2(cmdparams[2]);
}
catch (FileNotFoundException)
{
@@ -1274,7 +1274,7 @@ namespace OpenSim
{
try
{
- m_sceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME);
+ SceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME);
}
catch (FileNotFoundException)
{
@@ -1291,7 +1291,7 @@ namespace OpenSim
{
try
{
- m_sceneManager.LoadArchiveToCurrentScene(cmdparams);
+ SceneManager.LoadArchiveToCurrentScene(cmdparams);
}
catch (Exception e)
{
@@ -1305,7 +1305,7 @@ namespace OpenSim
///
protected void SaveOar(string module, string[] cmdparams)
{
- m_sceneManager.SaveCurrentSceneToArchive(cmdparams);
+ SceneManager.SaveCurrentSceneToArchive(cmdparams);
}
private static string CombineParams(string[] commandParams, int pos)
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 3271555730..408474178b 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -40,7 +40,7 @@ using OpenSim.Framework.Communications;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts;
using OpenSim.Region.Framework;
@@ -285,7 +285,7 @@ namespace OpenSim
private void HandleCommanderCommand(string module, string[] cmd)
{
- m_sceneManager.SendCommandToPluginModules(cmd);
+ SceneManager.SendCommandToPluginModules(cmd);
}
private void HandleCommanderHelp(string module, string[] cmd)
@@ -303,7 +303,10 @@ namespace OpenSim
// Called from base.StartUp()
m_httpServerPort = m_networkServersInfo.HttpListenerPort;
- m_sceneManager.OnRestartSim += handleRestartRegion;
+ SceneManager.OnRestartSim += handleRestartRegion;
+
+ // Only start the memory watchdog once all regions are ready
+ SceneManager.OnRegionsReadyStatusChange += sm => MemoryWatchdog.Enabled = sm.AllRegionsReady;
}
///
@@ -412,7 +415,7 @@ namespace OpenSim
// scripting engines.
scene.CreateScriptInstances();
- m_sceneManager.Add(scene);
+ SceneManager.Add(scene);
if (m_autoCreateClientStack)
{
@@ -432,7 +435,6 @@ namespace OpenSim
mscene = scene;
scene.Start();
-
scene.StartScripts();
return clientServer;
@@ -561,14 +563,14 @@ namespace OpenSim
{
// only need to check this if we are not at the
// root level
- if ((m_sceneManager.CurrentScene != null) &&
- (m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
+ if ((SceneManager.CurrentScene != null) &&
+ (SceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
{
- m_sceneManager.TrySetCurrentScene("..");
+ SceneManager.TrySetCurrentScene("..");
}
scene.DeleteAllSceneObjects();
- m_sceneManager.CloseScene(scene);
+ SceneManager.CloseScene(scene);
ShutdownClientServer(scene.RegionInfo);
if (!cleanup)
@@ -610,7 +612,7 @@ namespace OpenSim
public void RemoveRegion(string name, bool cleanUp)
{
Scene target;
- if (m_sceneManager.TryGetScene(name, out target))
+ if (SceneManager.TryGetScene(name, out target))
RemoveRegion(target, cleanUp);
}
@@ -623,13 +625,13 @@ namespace OpenSim
{
// only need to check this if we are not at the
// root level
- if ((m_sceneManager.CurrentScene != null) &&
- (m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
+ if ((SceneManager.CurrentScene != null) &&
+ (SceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
{
- m_sceneManager.TrySetCurrentScene("..");
+ SceneManager.TrySetCurrentScene("..");
}
- m_sceneManager.CloseScene(scene);
+ SceneManager.CloseScene(scene);
ShutdownClientServer(scene.RegionInfo);
}
@@ -641,7 +643,7 @@ namespace OpenSim
public void CloseRegion(string name)
{
Scene target;
- if (m_sceneManager.TryGetScene(name, out target))
+ if (SceneManager.TryGetScene(name, out target))
CloseRegion(target);
}
@@ -897,7 +899,7 @@ namespace OpenSim
try
{
- m_sceneManager.Close();
+ SceneManager.Close();
}
catch (Exception e)
{
@@ -922,7 +924,7 @@ namespace OpenSim
/// The first out parameter describing the number of all the avatars in the Region server
public void GetAvatarNumber(out int usernum)
{
- usernum = m_sceneManager.GetCurrentSceneAvatars().Count;
+ usernum = SceneManager.GetCurrentSceneAvatars().Count;
}
///
@@ -931,7 +933,7 @@ namespace OpenSim
/// The first out parameter describing the number of regions
public void GetRegionNumber(out int regionnum)
{
- regionnum = m_sceneManager.Scenes.Count;
+ regionnum = SceneManager.Scenes.Count;
}
///
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index f7864b8c52..01ceeeda98 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -41,7 +41,7 @@ using OpenMetaverse.Messages.Linden;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Client;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ffa3be420e..8963756dcc 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -278,7 +278,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public string GetStats()
{
return string.Format(
- "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}",
+ "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7} {12,7}",
+ Util.EnvironmentTickCountSubtract(TickLastPacketReceived),
PacketsReceived,
PacketsSent,
PacketsResent,
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 746eb90996..55780d641c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -37,7 +37,7 @@ using log4net;
using Nini.Config;
using OpenMetaverse.Packets;
using OpenSim.Framework;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
using OpenMetaverse;
diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
index c4324e8592..4672f8aa8a 100644
--- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs
+++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
@@ -53,9 +53,8 @@ namespace OpenSim.Region.ClientStack
protected ISimulationDataService m_simulationDataService;
protected IEstateDataService m_estateDataService;
protected ClientStackManager m_clientStackManager;
- protected SceneManager m_sceneManager = new SceneManager();
- public SceneManager SceneManager { get { return m_sceneManager; } }
+ public SceneManager SceneManager { get; protected set; }
public NetworkServersInfo NetServersInfo { get { return m_networkServersInfo; } }
public ISimulationDataService SimulationDataService { get { return m_simulationDataService; } }
public IEstateDataService EstateDataService { get { return m_estateDataService; } }
@@ -77,6 +76,7 @@ namespace OpenSim.Region.ClientStack
protected override void StartupSpecific()
{
+ SceneManager = new SceneManager();
m_clientStackManager = CreateClientStackManager();
Initialize();
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 0f3b1e813b..464dfd34e0 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -28,6 +28,8 @@
using System;
using System.Collections.Generic;
using System.Reflection;
+using System.IO;
+using System.Xml;
using log4net;
using Mono.Addins;
using Nini.Config;
@@ -202,7 +204,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
}
- public void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted)
+ public void DeRezAttachments(IScenePresence sp)
{
if (!Enabled)
return;
@@ -213,18 +215,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
foreach (SceneObjectGroup so in sp.GetAttachments())
{
- // We can only remove the script instances from the script engine after we've retrieved their xml state
- // when we update the attachment item.
- m_scene.DeleteSceneObject(so, false, false);
-
- if (saveChanged || saveAllScripted)
- {
- so.IsAttachment = false;
- so.AbsolutePosition = so.RootPart.AttachedPos;
- UpdateKnownItem(sp, so, saveAllScripted);
- }
-
- so.RemoveScriptInstances(true);
+ UpdateDetachedObject(sp, so);
}
sp.ClearAttachments();
@@ -528,7 +519,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
///
///
///
- private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted)
+ private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, string scriptedState)
{
// Saving attachments for NPCs messes them up for the real owner!
INPCModule module = m_scene.RequestModuleInterface();
@@ -538,13 +529,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return;
}
- if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts()))
+ if (grp.HasGroupChanged)
{
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
// grp.UUID, grp.AttachmentPoint);
- string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
+ string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState);
InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID);
item = m_scene.InventoryService.GetItem(item);
@@ -683,6 +674,60 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return newItem;
}
+ private string GetObjectScriptStates(SceneObjectGroup grp)
+ {
+ using (StringWriter sw = new StringWriter())
+ {
+ using (XmlTextWriter writer = new XmlTextWriter(sw))
+ {
+ grp.SaveScriptedState(writer);
+ }
+
+ return sw.ToString();
+ }
+ }
+
+ private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so)
+ {
+ // Don't save attachments for HG visitors, it
+ // messes up their inventory. When a HG visitor logs
+ // out on a foreign grid, their attachments will be
+ // reloaded in the state they were in when they left
+ // the home grid. This is best anyway as the visited
+ // grid may use an incompatible script engine.
+ bool saveChanged
+ = sp.PresenceType != PresenceType.Npc
+ && (m_scene.UserManagementModule == null
+ || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
+
+ // Scripts MUST be snapshotted before the object is
+ // removed from the scene because doing otherwise will
+ // clobber the run flag
+ string scriptedState = GetObjectScriptStates(so);
+
+ // Remove the object from the scene so no more updates
+ // are sent. Doing this before the below changes will ensure
+ // updates can't cause "HUD artefacts"
+ m_scene.DeleteSceneObject(so, false, false);
+
+ // Prepare sog for storage
+ so.AttachedAvatar = UUID.Zero;
+ so.RootPart.SetParentLocalId(0);
+ so.IsAttachment = false;
+
+ if (saveChanged)
+ {
+ // We cannot use AbsolutePosition here because that would
+ // attempt to cross the prim as it is detached
+ so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; });
+
+ UpdateKnownItem(sp, so, scriptedState);
+ }
+
+ // Now, remove the scripts
+ so.RemoveScriptInstances(true);
+ }
+
private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so)
{
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
@@ -690,22 +735,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
sp.RemoveAttachment(so);
- // Prepare sog for storage
- so.AttachedAvatar = UUID.Zero;
- so.RootPart.SetParentLocalId(0);
- so.IsAttachment = false;
-
- // We cannot use AbsolutePosition here because that would
- // attempt to cross the prim as it is detached
- so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; });
-
- UpdateKnownItem(sp, so, true);
-
- // This MUST happen AFTER serialization because it will
- // either stop or remove the scripts. Both will cause scripts
- // to be serialized in a stopped state with the true run
- // state already lost.
- m_scene.DeleteSceneObject(so, false, true);
+ UpdateDetachedObject(sp, so);
}
private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index b021a478c8..6e7a414df1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -47,6 +47,7 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.XEngine;
using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common;
@@ -289,21 +290,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
{
TestHelpers.InMethod();
- Scene scene = CreateTestScene();
+ Scene scene = CreateScriptingEnabledTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
- ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
+ ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
- TaskInventoryHelpers.AddScript(scene, so.RootPart);
+ TaskInventoryItem scriptItem
+ = TaskInventoryHelpers.AddScript(
+ scene,
+ so.RootPart,
+ "scriptItem",
+ "default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
+
InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
+ // FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
+ // In the future, we need to be able to do this programatically more predicably.
+ scene.EventManager.OnChatFromWorld += OnChatFromWorld;
+
scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
+ m_chatEvent.WaitOne(60000);
+
// TODO: Need to have a test that checks the script is actually started but this involves a lot more
// plumbing of the script engine and either pausing for events or more infrastructure to turn off various
// script engine delays/asychronicity that isn't helpful in an automated regression testing context.
SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.Name);
Assert.That(attSo.ContainsScripts(), Is.True);
+
+ TaskInventoryItem reRezzedScriptItem = attSo.RootPart.Inventory.GetInventoryItem(scriptItem.Name);
+ IScriptModule xengine = scene.RequestModuleInterface();
+ Assert.That(xengine.GetScriptState(reRezzedScriptItem.ItemID), Is.True);
}
[Test]
@@ -379,29 +396,49 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
- TaskInventoryHelpers.AddScript(scene, so.RootPart);
+ TaskInventoryItem scriptTaskItem
+ = TaskInventoryHelpers.AddScript(
+ scene,
+ so.RootPart,
+ "scriptItem",
+ "default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
+
InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
// FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
// In the future, we need to be able to do this programatically more predicably.
scene.EventManager.OnChatFromWorld += OnChatFromWorld;
- SceneObjectGroup soRezzed
+ SceneObjectGroup rezzedSo
= scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
// Wait for chat to signal rezzed script has been started.
m_chatEvent.WaitOne(60000);
- scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, soRezzed);
+ scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, rezzedSo);
InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem);
AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString());
+ // TODO: It would probably be better here to check script state via the saving and retrieval of state
+ // information at a higher level, rather than having to inspect the serialization.
XmlDocument soXml = new XmlDocument();
soXml.LoadXml(Encoding.UTF8.GetString(asset.Data));
XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState");
Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
+
+ // Re-rez the attachment to check script running state
+ SceneObjectGroup reRezzedSo = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
+
+ // Wait for chat to signal rezzed script has been started.
+ m_chatEvent.WaitOne(60000);
+
+ TaskInventoryItem reRezzedScriptItem = reRezzedSo.RootPart.Inventory.GetInventoryItem(scriptTaskItem.Name);
+ IScriptModule xengine = scene.RequestModuleInterface();
+ Assert.That(xengine.GetScriptState(reRezzedScriptItem.ItemID), Is.True);
+
+// Console.WriteLine(soXml.OuterXml);
}
///
diff --git a/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs b/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs
index 4bcd2ac499..764adf9401 100644
--- a/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs
@@ -37,7 +37,7 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
diff --git a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs
index a6e2548406..4a76b00467 100644
--- a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs
+++ b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs
@@ -40,6 +40,7 @@ using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
+using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
index 990dffb61a..11e0150083 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
@@ -31,7 +31,7 @@ using System.Collections.Generic;
using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Services.Connectors;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index 56418043e4..9d282b8741 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -128,11 +128,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
m_enabled = true;
}
- ///
- ///
- ///
-
-
///
///
///
@@ -146,7 +141,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
lock (m_scenes)
m_scenes[scene.RegionInfo.RegionID] = scene;
- scene.EventManager.OnRegionReady += s => UploadMapTile(s);
+ scene.EventManager.OnRegionReadyStatusChange += s => { if (s.Ready) UploadMapTile(s); };
}
///
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
index e5cd3e2133..09f6758ba4 100644
--- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
@@ -37,7 +37,7 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
diff --git a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs
index 2838e0c356..7d3547322f 100644
--- a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs
@@ -37,7 +37,7 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 724533b0cb..dfba3ffbd2 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -42,6 +42,7 @@ using OpenMetaverse.Imaging;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Capabilities;
+using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index 351e60341d..d5200b73ed 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -65,7 +65,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// The presence closing
/// Save changed attachments.
/// Save attachments with scripts even if they haven't changed.
- void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted);
+ void DeRezAttachments(IScenePresence sp);
///
/// Delete all the presence's attachments from the scene
diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
index e6b926ce8c..3f68ee02ec 100644
--- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
@@ -40,6 +40,8 @@ namespace OpenSim.Region.Framework.Interfaces
///
public interface IScenePresence : ISceneAgent
{
+ PresenceType PresenceType { get; }
+
///
/// Copy of the script states while the agent is in transit. This state may
/// need to be placed back in case of transfer fail.
@@ -83,4 +85,4 @@ namespace OpenSim.Region.Framework.Interfaces
void RemoveAttachment(SceneObjectGroup gobj);
void ClearAttachments();
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 620b605e02..6dea2f0cd1 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -513,8 +513,7 @@ namespace OpenSim.Region.Framework.Scenes
/// A region is considered ready when startup operations such as loading of scripts already on the region
/// have been completed.
///
- public event RegionReady OnRegionReady;
- public delegate void RegionReady(IScene scene);
+ public event Action OnRegionReadyStatusChange;
public delegate void PrimsLoaded(Scene s);
public event PrimsLoaded OnPrimsLoaded;
@@ -2508,13 +2507,13 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- public void TriggerRegionReady(IScene scene)
+ public void TriggerRegionReadyStatusChange(IScene scene)
{
- RegionReady handler = OnRegionReady;
+ Action handler = OnRegionReadyStatusChange;
if (handler != null)
{
- foreach (RegionReady d in handler.GetInvocationList())
+ foreach (Action d in handler.GetInvocationList())
{
try
{
@@ -2522,7 +2521,7 @@ namespace OpenSim.Region.Framework.Scenes
}
catch (Exception e)
{
- m_log.ErrorFormat("[EVENT MANAGER]: Delegate for OnRegionReady failed - continuing {0} - {1}",
+ m_log.ErrorFormat("[EVENT MANAGER]: Delegate for OnRegionReadyStatusChange failed - continuing {0} - {1}",
e.Message, e.StackTrace);
}
}
diff --git a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
index 1365831779..c11174dc4e 100644
--- a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
+++ b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
@@ -39,7 +39,7 @@ using OpenSim.Framework.Communications;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 51a6820c67..24f62e3b86 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -40,6 +40,7 @@ using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenMetaverse.Imaging;
using OpenSim.Framework;
+using OpenSim.Framework.Monitoring;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Communications;
using OpenSim.Framework.Console;
@@ -1499,8 +1500,8 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGridService.InformNeighborsThatRegionisUp(
RequestModuleInterface(), RegionInfo);
- // Region ready should always be triggered whether logins are immediately enabled or not.
- EventManager.TriggerRegionReady(this);
+ // Region ready should always be set
+ Ready = true;
}
else
{
@@ -3297,17 +3298,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (AttachmentsModule != null)
{
- // Don't save attachments for HG visitors, it
- // messes up their inventory. When a HG visitor logs
- // out on a foreign grid, their attachments will be
- // reloaded in the state they were in when they left
- // the home grid. This is best anyway as the visited
- // grid may use an incompatible script engine.
- bool saveChanged
- = avatar.PresenceType != PresenceType.Npc
- && (UserManagementModule == null || UserManagementModule.IsLocalGridUser(avatar.UUID));
-
- AttachmentsModule.DeRezAttachments(avatar, saveChanged, false);
+ AttachmentsModule.DeRezAttachments(avatar);
}
ForEachClient(
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 282fc5e927..b87a38a335 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -124,6 +124,24 @@ namespace OpenSim.Region.Framework.Scenes
}
private bool m_loginsEnabled;
+ public bool Ready
+ {
+ get
+ {
+ return m_ready;
+ }
+
+ set
+ {
+ if (m_ready != value)
+ {
+ m_ready = value;
+ EventManager.TriggerRegionReadyStatusChange(this);
+ }
+ }
+ }
+ private bool m_ready;
+
public float TimeDilation
{
get { return 1.0f; }
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index d73a959ab6..c81b55de16 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -47,6 +47,48 @@ namespace OpenSim.Region.Framework.Scenes
public event RestartSim OnRestartSim;
+ ///
+ /// Fired when either all regions are ready for use or at least one region has become unready for use where
+ /// previously all regions were ready.
+ ///
+ public event Action OnRegionsReadyStatusChange;
+
+ ///
+ /// Are all regions ready for use?
+ ///
+ public bool AllRegionsReady
+ {
+ get
+ {
+ return m_allRegionsReady;
+ }
+
+ private set
+ {
+ if (m_allRegionsReady != value)
+ {
+ m_allRegionsReady = value;
+ Action handler = OnRegionsReadyStatusChange;
+ if (handler != null)
+ {
+ foreach (Action d in handler.GetInvocationList())
+ {
+ try
+ {
+ d(this);
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("[SCENE MANAGER]: Delegate for OnRegionsReadyStatusChange failed - continuing {0} - {1}",
+ e.Message, e.StackTrace);
+ }
+ }
+ }
+ }
+ }
+ }
+ private bool m_allRegionsReady;
+
private static SceneManager m_instance = null;
public static SceneManager Instance
{
@@ -141,10 +183,11 @@ namespace OpenSim.Region.Framework.Scenes
public void Add(Scene scene)
{
- scene.OnRestart += HandleRestart;
-
lock (m_localScenes)
m_localScenes.Add(scene);
+
+ scene.OnRestart += HandleRestart;
+ scene.EventManager.OnRegionReadyStatusChange += HandleRegionReadyStatusChange;
}
public void HandleRestart(RegionInfo rdata)
@@ -175,6 +218,12 @@ namespace OpenSim.Region.Framework.Scenes
OnRestartSim(rdata);
}
+ private void HandleRegionReadyStatusChange(IScene scene)
+ {
+ lock (m_localScenes)
+ AllRegionsReady = m_localScenes.TrueForAll(s => s.Ready);
+ }
+
public void SendSimOnlineNotification(ulong regionHandle)
{
RegionInfo Result = null;
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 0b34156495..2d4c60ad75 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -151,6 +151,24 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
ToOriginalXmlFormat(sceneObject, writer, doScriptStates, false);
}
+ public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject, string scriptedState)
+ {
+ using (StringWriter sw = new StringWriter())
+ {
+ using (XmlTextWriter writer = new XmlTextWriter(sw))
+ {
+ writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
+
+ ToOriginalXmlFormat(sceneObject, writer, false, true);
+
+ writer.WriteRaw(scriptedState);
+
+ writer.WriteEndElement();
+ }
+ return sw.ToString();
+ }
+ }
+
///
/// Serialize a scene object to the original xml format
///
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 742d42a7e0..96317c3de3 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -30,7 +30,7 @@ using System.Collections.Generic;
using System.Timers;
using OpenMetaverse.Packets;
using OpenSim.Framework;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
namespace OpenSim.Region.Framework.Scenes
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 5043208277..bae25cdf7b 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -38,6 +38,7 @@ using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenSim.Framework;
using OpenSim.Framework.Client;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
index a7c5020eb6..9d27386a5a 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
@@ -34,6 +34,7 @@ using System.Text;
using System.Threading;
using log4net;
using OpenSim.Framework;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
index a7ebeccdc9..5fe594860d 100644
--- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
@@ -35,7 +35,7 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
@@ -81,18 +81,6 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
lock (m_scenes)
m_scenes[scene.RegionInfo.RegionID] = scene;
- scene.AddCommand(
- "Comms", this, "image queues clear",
- "image queues clear ",
- "Clear the image queues (textures downloaded via UDP) for a particular client.",
- (mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd)));
-
- scene.AddCommand(
- "Comms", this, "image queues show",
- "image queues show ",
- "Show the image queues (textures downloaded via UDP) for a particular client.",
- (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
-
scene.AddCommand(
"Comms", this, "show pqueues",
"show pqueues [full]",
@@ -105,8 +93,15 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
"Comms", this, "show queues",
"show queues [full]",
"Show queue data for each client",
- "Without the 'full' option, only root agents are shown."
- + " With the 'full' option child agents are also shown.",
+ "Without the 'full' option, only root agents are shown.\n"
+ + "With the 'full' option child agents are also shown.\n\n"
+ + "Type - Rt is a root (avatar) client whilst cd is a child (neighbour interacting) client.\n"
+ + "Since Last In - Time in milliseconds since last packet received.\n"
+ + "Pkts In - Number of packets processed from the client.\n"
+ + "Pkts Out - Number of packets sent to the client.\n"
+ + "Pkts Resent - Number of packets resent to the client.\n"
+ + "Bytes Unacked - Number of bytes transferred to the client that are awaiting acknowledgement.\n"
+ + "Q Pkts * - Number of packets of various types (land, wind, etc.) to be sent to the client that are waiting for available bandwidth.\n",
(mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd)));
scene.AddCommand(
@@ -114,6 +109,12 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
"show image queues ",
"Show the image queues (textures downloaded via UDP) for a particular client.",
(mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
+
+ scene.AddCommand(
+ "Comms", this, "clear image queues",
+ "clear image queues ",
+ "Clear the image queues (textures downloaded via UDP) for a particular client.",
+ (mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd)));
scene.AddCommand(
"Comms", this, "show throttles",
@@ -373,17 +374,22 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
int maxNameLength = 18;
int maxRegionNameLength = 14;
int maxTypeLength = 4;
- int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
+
+ int totalInfoFieldsLength
+ = maxNameLength + columnPadding
+ + maxRegionNameLength + columnPadding
+ + maxTypeLength + columnPadding;
report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
report.AppendFormat(
- "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}\n",
+ "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7} {12,7}\n",
+ "Since",
+ "Pkts",
"Pkts",
"Pkts",
- "Pkts",
"Bytes",
"Q Pkts",
"Q Pkts",
@@ -396,7 +402,8 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
report.AppendFormat(
- "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}\n",
+ "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7} {12,7}\n",
+ "Last In",
"In",
"Out",
"Resent",
@@ -417,22 +424,22 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
scene.ForEachClient(
delegate(IClientAPI client)
{
+ bool isChild = client.SceneAgent.IsChildAgent;
+ if (isChild && !showChildren)
+ return;
+
+ string name = client.Name;
+ if (pname != "" && name != pname)
+ return;
+
+ string regionName = scene.RegionInfo.RegionName;
+
+ report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
+ report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
+ report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
+
if (client is IStatsCollector)
{
- bool isChild = client.SceneAgent.IsChildAgent;
- if (isChild && !showChildren)
- return;
-
- string name = client.Name;
- if (pname != "" && name != pname)
- return;
-
- string regionName = scene.RegionInfo.RegionName;
-
- report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
- report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
- report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
-
IStatsCollector stats = (IStatsCollector)client;
report.AppendLine(stats.Report());
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
index 6bb6729c83..d718a2f052 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -36,7 +36,7 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
index 1b9e3ace5c..d68aabc5ca 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
@@ -36,7 +36,7 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
index cd401a6096..ca956fbe91 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
@@ -37,6 +37,7 @@ using OpenMetaverse;
using log4net;
using Nini.Config;
using OpenSim.Framework;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
index 2602050de4..4e84364dd3 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
@@ -37,7 +37,7 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.CoreModules.Avatar.Friends;
using OpenSim.Region.Framework.Interfaces;
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index f459b8c610..fff3a32010 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -225,7 +225,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
RRAlert("enabled");
}
- m_scene.EventManager.TriggerRegionReady(m_scene);
+ m_scene.Ready = true;
}
public void OarLoadingAlert(string msg)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
new file mode 100755
index 0000000000..fbb9e21958
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyrightD
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Physics.BulletSPlugin
+{
+
+public class BSConstraint : IDisposable
+{
+ private BulletSim m_world;
+ private BulletBody m_body1;
+ private BulletBody m_body2;
+ private BulletConstraint m_constraint;
+ private bool m_enabled = false;
+
+ public BSConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
+ Vector3 frame1, Quaternion frame1rot,
+ Vector3 frame2, Quaternion frame2rot
+ )
+ {
+ m_world = world;
+ m_body1 = obj1;
+ m_body2 = obj2;
+ m_constraint = new BulletConstraint(BulletSimAPI.CreateConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr,
+ frame1, frame1rot,
+ frame2, frame2rot));
+ m_enabled = true;
+ }
+
+ public void Dispose()
+ {
+ if (m_enabled)
+ {
+ // BulletSimAPI.RemoveConstraint(m_world.ID, m_body1.ID, m_body2.ID);
+ BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr);
+ m_enabled = false;
+ }
+ }
+
+ public BulletBody Body1 { get { return m_body1; } }
+ public BulletBody Body2 { get { return m_body2; } }
+
+ public bool SetLinearLimits(Vector3 low, Vector3 high)
+ {
+ bool ret = false;
+ if (m_enabled)
+ ret = BulletSimAPI.SetLinearLimits2(m_constraint.Ptr, low, high);
+ return ret;
+ }
+
+ public bool SetAngularLimits(Vector3 low, Vector3 high)
+ {
+ bool ret = false;
+ if (m_enabled)
+ ret = BulletSimAPI.SetAngularLimits2(m_constraint.Ptr, low, high);
+ return ret;
+ }
+
+ public bool UseFrameOffset(bool useOffset)
+ {
+ bool ret = false;
+ float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
+ if (m_enabled)
+ ret = BulletSimAPI.UseFrameOffset2(m_constraint.Ptr, onOff);
+ return ret;
+ }
+
+ public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce)
+ {
+ bool ret = false;
+ float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
+ if (m_enabled)
+ ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce);
+ return ret;
+ }
+
+ public bool CalculateTransforms()
+ {
+ bool ret = false;
+ if (m_enabled)
+ {
+ BulletSimAPI.CalculateTransforms2(m_constraint.Ptr);
+ ret = true;
+ }
+ return ret;
+ }
+}
+}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs
new file mode 100755
index 0000000000..a2650fbd36
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraintCollection.cs
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyrightD
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using log4net;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Physics.BulletSPlugin
+{
+
+public class BSConstraintCollection : IDisposable
+{
+ // private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ // private static readonly string LogHeader = "[CONSTRAINT COLLECTION]";
+
+ delegate bool ConstraintAction(BSConstraint constrain);
+
+ private List m_constraints;
+ private BulletSim m_world;
+
+ public BSConstraintCollection(BulletSim world)
+ {
+ m_world = world;
+ m_constraints = new List();
+ }
+
+ public void Dispose()
+ {
+ this.Clear();
+ }
+
+ public void Clear()
+ {
+ foreach (BSConstraint cons in m_constraints)
+ {
+ cons.Dispose();
+ }
+ m_constraints.Clear();
+ }
+
+ public BSConstraint CreateConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
+ Vector3 frame1, Quaternion frame1rot,
+ Vector3 frame2, Quaternion frame2rot)
+ {
+ BSConstraint constrain = new BSConstraint(world, obj1, obj2, frame1, frame1rot, frame2, frame2rot);
+
+ this.AddConstraint(constrain);
+ return constrain;
+ }
+
+ public bool AddConstraint(BSConstraint cons)
+ {
+ // There is only one constraint between any bodies. Remove any old just to make sure.
+ RemoveAndDestroyConstraint(cons.Body1, cons.Body2);
+
+ m_constraints.Add(cons);
+
+ return true;
+ }
+
+ // Get the constraint between two bodies. There can be only one the way we're using them.
+ public bool TryGetConstraint(BulletBody body1, BulletBody body2, out BSConstraint returnConstraint)
+ {
+ bool found = false;
+ BSConstraint foundConstraint = null;
+
+ uint lookingID1 = body1.ID;
+ uint lookingID2 = body2.ID;
+ ForEachConstraint(delegate(BSConstraint constrain)
+ {
+ if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2)
+ || (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1))
+ {
+ foundConstraint = constrain;
+ found = true;
+ }
+ return found;
+ });
+ returnConstraint = foundConstraint;
+ return found;
+ }
+
+ public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2)
+ {
+ // return BulletSimAPI.RemoveConstraint(m_world.ID, obj1.ID, obj2.ID);
+
+ bool ret = false;
+ BSConstraint constrain;
+
+ if (this.TryGetConstraint(body1, body2, out constrain))
+ {
+ // remove the constraint from our collection
+ m_constraints.Remove(constrain);
+ // tell the engine that all its structures need to be freed
+ constrain.Dispose();
+ // we destroyed something
+ ret = true;
+ }
+
+ return ret;
+ }
+
+ public bool RemoveAndDestroyConstraint(BulletBody body1)
+ {
+ // return BulletSimAPI.RemoveConstraintByID(m_world.ID, obj.ID);
+
+ List toRemove = new List();
+ uint lookingID = body1.ID;
+ ForEachConstraint(delegate(BSConstraint constrain)
+ {
+ if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID)
+ {
+ toRemove.Add(constrain);
+ }
+ return false;
+ });
+ lock (m_constraints)
+ {
+ foreach (BSConstraint constrain in toRemove)
+ {
+ m_constraints.Remove(constrain);
+ constrain.Dispose();
+ }
+ }
+ return (toRemove.Count > 0);
+ }
+
+ public bool RecalculateAllConstraints()
+ {
+ foreach (BSConstraint constrain in m_constraints)
+ {
+ constrain.CalculateTransforms();
+ }
+ return true;
+ }
+
+ // Lock the constraint list and loop through it.
+ // The constraint action returns 'true' if it wants the loop aborted.
+ private void ForEachConstraint(ConstraintAction action)
+ {
+ lock (m_constraints)
+ {
+ foreach (BSConstraint constrain in m_constraints)
+ {
+ if (action(constrain))
+ break;
+ }
+ }
+ }
+
+
+}
+}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 71a430391e..3be28e34ac 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -97,6 +97,9 @@ public sealed class BSPrim : PhysicsActor
long _collidingStep;
long _collidingGroundStep;
+ private BulletBody m_body;
+ public BulletBody Body { get { return m_body; } }
+
private BSDynamics _vehicle;
private OMV.Vector3 _PIDTarget;
@@ -133,14 +136,16 @@ public sealed class BSPrim : PhysicsActor
_parentPrim = null; // not a child or a parent
_vehicle = new BSDynamics(this); // add vehicleness
_childrenPrims = new List();
- if (_isPhysical)
- _mass = CalculateMass();
- else
- _mass = 0f;
+ _mass = CalculateMass();
// do the actual object creation at taint time
_scene.TaintedObject(delegate()
{
RecreateGeomAndObject();
+
+ // Get the pointer to the physical body for this object.
+ // At the moment, we're still letting BulletSim manage the creation and destruction
+ // of the object. Someday we'll move that into the C# code.
+ m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
});
}
@@ -149,22 +154,26 @@ public sealed class BSPrim : PhysicsActor
{
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
// DetailLog("{0},Destroy", LocalID);
+
// Undo any vehicle properties
_vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
_scene.RemoveVehiclePrim(this); // just to make sure
- // undo any dependance with/on other objects
- if (_parentPrim != null)
- {
- // If I'm someone's child, tell them to forget about me.
- _parentPrim.RemoveChildFromLinkset(this);
- _parentPrim = null;
- }
-
_scene.TaintedObject(delegate()
{
+ // undo any dependance with/on other objects
+ if (_parentPrim != null)
+ {
+ // If I'm someone's child, tell them to forget about me.
+ _parentPrim.RemoveChildFromLinkset(this);
+ _parentPrim = null;
+ }
+
+ // make sure there are no other prims linked to me
+ UnlinkAllChildren();
+
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
- BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
+ BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
});
}
@@ -177,8 +186,8 @@ public sealed class BSPrim : PhysicsActor
_size = value;
_scene.TaintedObject(delegate()
{
- if (_isPhysical) _mass = CalculateMass(); // changing size changes the mass
- BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, _mass, _isPhysical);
+ _mass = CalculateMass(); // changing size changes the mass
+ BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, Mass, IsPhysical);
RecreateGeomAndObject();
});
}
@@ -188,7 +197,7 @@ public sealed class BSPrim : PhysicsActor
_pbs = value;
_scene.TaintedObject(delegate()
{
- if (_isPhysical) _mass = CalculateMass(); // changing the shape changes the mass
+ _mass = CalculateMass(); // changing the shape changes the mass
RecreateGeomAndObject();
});
}
@@ -272,7 +281,10 @@ public sealed class BSPrim : PhysicsActor
DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID);
_childrenPrims.Add(child);
child._parentPrim = this; // the child has gained a parent
- RecreateGeomAndObject(); // rebuild my shape with the new child added
+ // RecreateGeomAndObject(); // rebuild my shape with the new child added
+ LinkAChildToMe(pchild); // build the physical binding between me and the child
+
+ _mass = CalculateMass();
}
});
return;
@@ -288,14 +300,21 @@ public sealed class BSPrim : PhysicsActor
if (_childrenPrims.Contains(child))
{
DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
- DetailLog("{0},RemoveChildToLinkset,child={1}", LocalID, pchild.LocalID);
- if (!BulletSimAPI.RemoveConstraintByID(_scene.WorldID, child.LocalID))
- {
- m_log.ErrorFormat("{0}: RemoveChildFromLinkset: Failed remove constraint for {1}", LogHeader, child.LocalID);
- }
+ DetailLog("{0},RemoveChildFromLinkset,child={1}", LocalID, pchild.LocalID);
_childrenPrims.Remove(child);
child._parentPrim = null; // the child has lost its parent
- RecreateGeomAndObject(); // rebuild my shape with the child removed
+ if (_childrenPrims.Count == 0)
+ {
+ // if the linkset is empty, make sure all linkages have been removed
+ UnlinkAllChildren();
+ }
+ else
+ {
+ // RecreateGeomAndObject(); // rebuild my shape with the child removed
+ UnlinkAChildFromMe(pchild);
+ }
+
+ _mass = CalculateMass();
}
else
{
@@ -314,12 +333,18 @@ public sealed class BSPrim : PhysicsActor
// Set motion values to zero.
// Do it to the properties so the values get set in the physics engine.
// Push the setting of the values to the viewer.
+ // Called at taint time!
private void ZeroMotion()
{
- Velocity = OMV.Vector3.Zero;
+ _velocity = OMV.Vector3.Zero;
_acceleration = OMV.Vector3.Zero;
- RotationalVelocity = OMV.Vector3.Zero;
- base.RequestPhysicsterseUpdate();
+ _rotationalVelocity = OMV.Vector3.Zero;
+
+ // Zero some other properties directly into the physics engine
+ BulletSimAPI.SetVelocity2(Body.Ptr, OMV.Vector3.Zero);
+ BulletSimAPI.SetAngularVelocity2(Body.Ptr, OMV.Vector3.Zero);
+ BulletSimAPI.SetInterpolation2(Body.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero);
+ BulletSimAPI.ClearForces2(Body.Ptr);
}
public override void LockAngularMotion(OMV.Vector3 axis)
@@ -347,9 +372,17 @@ public sealed class BSPrim : PhysicsActor
});
}
}
+
+ // Return the effective mass of the object. Non-physical objects do not have mass.
public override float Mass {
- get { return _mass; }
+ get {
+ if (IsPhysical)
+ return _mass;
+ else
+ return 0f;
+ }
}
+
public override OMV.Vector3 Force {
get { return _force; }
set {
@@ -357,7 +390,8 @@ public sealed class BSPrim : PhysicsActor
_scene.TaintedObject(delegate()
{
DetailLog("{0},SetForce,taint,force={1}", LocalID, _force);
- BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
+ // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
+ BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
});
}
}
@@ -381,8 +415,7 @@ public sealed class BSPrim : PhysicsActor
_scene.TaintedObject(delegate()
{
// Tell the physics engine to clear state
- IntPtr obj = BulletSimAPI.GetBodyHandleWorldID2(_scene.WorldID, LocalID);
- BulletSimAPI.ClearForces2(obj);
+ BulletSimAPI.ClearForces2(this.Body.Ptr);
});
// make it so the scene will call us each tick to do vehicle things
@@ -394,7 +427,6 @@ public sealed class BSPrim : PhysicsActor
}
public override void VehicleFloatParam(int param, float value)
{
- m_log.DebugFormat("{0} VehicleFloatParam. {1} <= {2}", LogHeader, param, value);
_scene.TaintedObject(delegate()
{
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
@@ -402,7 +434,6 @@ public sealed class BSPrim : PhysicsActor
}
public override void VehicleVectorParam(int param, OMV.Vector3 value)
{
- m_log.DebugFormat("{0} VehicleVectorParam. {1} <= {2}", LogHeader, param, value);
_scene.TaintedObject(delegate()
{
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
@@ -410,7 +441,6 @@ public sealed class BSPrim : PhysicsActor
}
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
{
- m_log.DebugFormat("{0} VehicleRotationParam. {1} <= {2}", LogHeader, param, rotation);
_scene.TaintedObject(delegate()
{
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
@@ -418,7 +448,6 @@ public sealed class BSPrim : PhysicsActor
}
public override void VehicleFlags(int param, bool remove)
{
- m_log.DebugFormat("{0} VehicleFlags. {1}. Remove={2}", LogHeader, param, remove);
_scene.TaintedObject(delegate()
{
_vehicle.ProcessVehicleFlags(param, remove);
@@ -429,7 +458,8 @@ public sealed class BSPrim : PhysicsActor
// Called from Scene when doing simulation step so we're in taint processing time.
public void StepVehicle(float timeStep)
{
- _vehicle.Step(timeStep);
+ if (IsPhysical)
+ _vehicle.Step(timeStep);
}
// Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
@@ -526,20 +556,13 @@ public sealed class BSPrim : PhysicsActor
{
// m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid);
// non-physical things work best with a mass of zero
- if (IsStatic)
- {
- _mass = 0f;
- }
- else
+ if (!IsStatic)
{
_mass = CalculateMass();
- // If it's dynamic, make sure the hull has been created for it
- // This shouldn't do much work if the object had previously been built
RecreateGeomAndObject();
-
}
- DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, _mass);
- BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass);
+ DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, Mass);
+ BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), Mass);
}
// prims don't fly
@@ -1234,7 +1257,7 @@ public sealed class BSPrim : PhysicsActor
if (IsRootOfLinkset)
{
// Create a linkset around this object
- CreateLinksetWithConstraints();
+ CreateLinkset();
}
else
{
@@ -1247,30 +1270,6 @@ public sealed class BSPrim : PhysicsActor
}
}
- // Create a linkset by creating a compound hull at the root prim that consists of all
- // the children.
- // NOTE: This does not allow proper collisions with the children prims so it is not a workable solution
- void CreateLinksetWithCompoundHull()
- {
- // If I am the root prim of a linkset, replace my physical shape with all the
- // pieces of the children.
- // All of the children should have called CreateGeom so they have a hull
- // in the physics engine already. Here we pull together all of those hulls
- // into one shape.
- int totalPrimsInLinkset = _childrenPrims.Count + 1;
- // m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, totalPrimsInLinkset);
- ShapeData[] shapes = new ShapeData[totalPrimsInLinkset];
- FillShapeInfo(out shapes[0]);
- int ii = 1;
- foreach (BSPrim prim in _childrenPrims)
- {
- // m_log.DebugFormat("{0}: CreateLinkset: adding prim {1}", LogHeader, prim.LocalID);
- prim.FillShapeInfo(out shapes[ii]);
- ii++;
- }
- BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes);
- }
-
// Copy prim's info into the BulletSim shape description structure
public void FillShapeInfo(out ShapeData shape)
{
@@ -1280,7 +1279,7 @@ public sealed class BSPrim : PhysicsActor
shape.Rotation = _orientation;
shape.Velocity = _velocity;
shape.Scale = _scale;
- shape.Mass = _isPhysical ? _mass : 0f;
+ shape.Mass = Mass;
shape.Buoyancy = _buoyancy;
shape.HullKey = _hullKey;
shape.MeshKey = _meshKey;
@@ -1290,45 +1289,84 @@ public sealed class BSPrim : PhysicsActor
shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
}
+ #region Linkset creation and destruction
+
// Create the linkset by putting constraints between the objects of the set so they cannot move
// relative to each other.
- // TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added
- void CreateLinksetWithConstraints()
+ void CreateLinkset()
{
- DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
+ // DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
// remove any constraints that might be in place
- foreach (BSPrim prim in _childrenPrims)
- {
- DebugLog("{0}: CreateLinkset: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
- BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID);
- }
+ UnlinkAllChildren();
+
// create constraints between the root prim and each of the children
foreach (BSPrim prim in _childrenPrims)
{
- // Zero motion for children so they don't interpolate
- prim.ZeroMotion();
-
- // relative position normalized to the root prim
- OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation);
- OMV.Vector3 childRelativePosition = (prim._position - this._position) * invThisOrientation;
-
- // relative rotation of the child to the parent
- OMV.Quaternion childRelativeRotation = invThisOrientation * prim._orientation;
-
- // this is a constraint that allows no freedom of movement between the two objects
- // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
- DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
- BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID,
- childRelativePosition,
- childRelativeRotation,
- OMV.Vector3.Zero,
- OMV.Quaternion.Identity,
- OMV.Vector3.Zero, OMV.Vector3.Zero,
- OMV.Vector3.Zero, OMV.Vector3.Zero);
+ LinkAChildToMe(prim);
}
}
+ // Create a constraint between me (root of linkset) and the passed prim (the child).
+ // Called at taint time!
+ private void LinkAChildToMe(BSPrim childPrim)
+ {
+ // Zero motion for children so they don't interpolate
+ childPrim.ZeroMotion();
+
+ // relative position normalized to the root prim
+ OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation);
+ OMV.Vector3 childRelativePosition = (childPrim._position - this._position) * invThisOrientation;
+
+ // relative rotation of the child to the parent
+ OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim._orientation;
+
+ // create a constraint that allows no freedom of movement between the two objects
+ // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
+ // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
+ DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID);
+ BSConstraint constrain = _scene.Constraints.CreateConstraint(
+ _scene.World, this.Body, childPrim.Body,
+ childRelativePosition,
+ childRelativeRotation,
+ OMV.Vector3.Zero,
+ OMV.Quaternion.Identity);
+ constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
+ constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
+
+ // tweek the constraint to increase stability
+ constrain.UseFrameOffset(_scene.BoolNumeric(_scene.Params.linkConstraintUseFrameOffset));
+ if (_scene.BoolNumeric(_scene.Params.linkConstraintEnableTransMotor))
+ {
+ constrain.TranslationalLimitMotor(true,
+ _scene.Params.linkConstraintTransMotorMaxVel,
+ _scene.Params.linkConstraintTransMotorMaxForce);
+ }
+ }
+
+ // Remove linkage between myself and a particular child
+ // Called at taint time!
+ private void UnlinkAChildFromMe(BSPrim childPrim)
+ {
+ DebugLog("{0}: UnlinkAChildFromMe: RemoveConstraint between root prim {1} and child prim {2}",
+ LogHeader, LocalID, childPrim.LocalID);
+ DetailLog("{0},UnlinkAChildFromMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID);
+ // BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
+ _scene.Constraints.RemoveAndDestroyConstraint(this.Body, childPrim.Body);
+ }
+
+ // Remove linkage between myself and any possible children I might have
+ // Called at taint time!
+ private void UnlinkAllChildren()
+ {
+ DebugLog("{0}: UnlinkAllChildren:", LogHeader);
+ DetailLog("{0},UnlinkAllChildren,taint", LocalID);
+ _scene.Constraints.RemoveAndDestroyConstraint(this.Body);
+ // BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
+ }
+
+ #endregion // Linkset creation and destruction
+
// Rebuild the geometry and object.
// This is called when the shape changes so we need to recreate the mesh/hull.
// No locking here because this is done when the physics engine is not simulating
@@ -1405,7 +1443,7 @@ public sealed class BSPrim : PhysicsActor
// Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
// Updates only for individual prims and for the root object of a linkset.
- if (this._parentPrim == null)
+ if (_parentPrim == null)
{
// Assign to the local variables so the normal set action does not happen
_position = entprop.Position;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 87734853df..a1587a8824 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -103,6 +103,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters
get { return m_sculptLOD; }
}
+ private BulletSim m_worldSim;
+ public BulletSim World
+ {
+ get { return m_worldSim; }
+ }
+ private BSConstraintCollection m_constraintCollection;
+ public BSConstraintCollection Constraints
+ {
+ get { return m_constraintCollection; }
+ }
+
private int m_maxSubSteps;
private float m_fixedTimeStep;
private long m_simulationStep = 0;
@@ -229,6 +240,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject());
+ // Initialization to support the transition to a new API which puts most of the logic
+ // into the C# code so it is easier to modify and add to.
+ m_worldSim = new BulletSim(m_worldID, BulletSimAPI.GetSimHandle2(m_worldID));
+ m_constraintCollection = new BSConstraintCollection(World);
+
m_initialized = true;
}
@@ -237,116 +253,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters
private void GetInitialParameterValues(IConfigSource config)
{
ConfigurationParameters parms = new ConfigurationParameters();
+ m_params[0] = parms;
- _meshSculptedPrim = true; // mesh sculpted prims
- _forceSimplePrimMeshing = false; // use complex meshing if called for
-
- m_meshLOD = 8f;
- m_sculptLOD = 32f;
-
- shouldDebugLog = false;
- m_detailedStatsStep = 0; // disabled
-
- m_maxSubSteps = 10;
- m_fixedTimeStep = 1f / 60f;
- m_maxCollisionsPerFrame = 2048;
- m_maxUpdatesPerFrame = 2048;
- m_maximumObjectMass = 10000.01f;
-
- PID_D = 2200f;
- PID_P = 900f;
-
- parms.defaultFriction = 0.5f;
- parms.defaultDensity = 10.000006836f; // Aluminum g/cm3
- parms.defaultRestitution = 0f;
- parms.collisionMargin = 0.0f;
- parms.gravity = -9.80665f;
-
- parms.linearDamping = 0.0f;
- parms.angularDamping = 0.0f;
- parms.deactivationTime = 0.2f;
- parms.linearSleepingThreshold = 0.8f;
- parms.angularSleepingThreshold = 1.0f;
- parms.ccdMotionThreshold = 0.0f; // set to zero to disable
- parms.ccdSweptSphereRadius = 0.0f;
- parms.contactProcessingThreshold = 0.1f;
-
- parms.terrainFriction = 0.5f;
- parms.terrainHitFraction = 0.8f;
- parms.terrainRestitution = 0f;
- parms.avatarFriction = 0.5f;
- parms.avatarRestitution = 0.0f;
- parms.avatarDensity = 60f;
- parms.avatarCapsuleRadius = 0.37f;
- parms.avatarCapsuleHeight = 1.5f; // 2.140599f
- parms.avatarContactProcessingThreshold = 0.1f;
-
- parms.maxPersistantManifoldPoolSize = 0f;
- parms.shouldDisableContactPoolDynamicAllocation = ConfigurationParameters.numericTrue;
- parms.shouldForceUpdateAllAabbs = ConfigurationParameters.numericFalse;
- parms.shouldRandomizeSolverOrder = ConfigurationParameters.numericFalse;
- parms.shouldSplitSimulationIslands = ConfigurationParameters.numericFalse;
- parms.shouldEnableFrictionCaching = ConfigurationParameters.numericFalse;
- parms.numberOfSolverIterations = 0f; // means use default
+ SetParameterDefaultValues();
if (config != null)
{
// If there are specifications in the ini file, use those values
- // WHEN ADDING OR UPDATING THIS SECTION, BE SURE TO UPDATE OpenSimDefaults.ini
- // ALSO REMEMBER TO UPDATE THE RUNTIME SETTING OF THE PARAMETERS.
IConfig pConfig = config.Configs["BulletSim"];
if (pConfig != null)
{
- _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim);
- _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing);
-
- shouldDebugLog = pConfig.GetBoolean("ShouldDebugLog", shouldDebugLog);
- m_detailedStatsStep = pConfig.GetInt("DetailedStatsStep", m_detailedStatsStep);
-
- m_meshLOD = pConfig.GetFloat("MeshLevelOfDetail", m_meshLOD);
- m_sculptLOD = pConfig.GetFloat("SculptLevelOfDetail", m_sculptLOD);
-
- m_maxSubSteps = pConfig.GetInt("MaxSubSteps", m_maxSubSteps);
- m_fixedTimeStep = pConfig.GetFloat("FixedTimeStep", m_fixedTimeStep);
- m_maxCollisionsPerFrame = pConfig.GetInt("MaxCollisionsPerFrame", m_maxCollisionsPerFrame);
- m_maxUpdatesPerFrame = pConfig.GetInt("MaxUpdatesPerFrame", m_maxUpdatesPerFrame);
- m_maximumObjectMass = pConfig.GetFloat("MaxObjectMass", m_maximumObjectMass);
-
- PID_D = pConfig.GetFloat("PIDDerivative", PID_D);
- PID_P = pConfig.GetFloat("PIDProportional", PID_P);
-
- parms.defaultFriction = pConfig.GetFloat("DefaultFriction", parms.defaultFriction);
- parms.defaultDensity = pConfig.GetFloat("DefaultDensity", parms.defaultDensity);
- parms.defaultRestitution = pConfig.GetFloat("DefaultRestitution", parms.defaultRestitution);
- parms.collisionMargin = pConfig.GetFloat("CollisionMargin", parms.collisionMargin);
- parms.gravity = pConfig.GetFloat("Gravity", parms.gravity);
-
- parms.linearDamping = pConfig.GetFloat("LinearDamping", parms.linearDamping);
- parms.angularDamping = pConfig.GetFloat("AngularDamping", parms.angularDamping);
- parms.deactivationTime = pConfig.GetFloat("DeactivationTime", parms.deactivationTime);
- parms.linearSleepingThreshold = pConfig.GetFloat("LinearSleepingThreshold", parms.linearSleepingThreshold);
- parms.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", parms.angularSleepingThreshold);
- parms.ccdMotionThreshold = pConfig.GetFloat("CcdMotionThreshold", parms.ccdMotionThreshold);
- parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius);
- parms.contactProcessingThreshold = pConfig.GetFloat("ContactProcessingThreshold", parms.contactProcessingThreshold);
-
- parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction);
- parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction);
- parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution);
- parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction);
- parms.avatarRestitution = pConfig.GetFloat("AvatarRestitution", parms.avatarRestitution);
- parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity);
- parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius);
- parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight);
- parms.avatarContactProcessingThreshold = pConfig.GetFloat("AvatarContactProcessingThreshold", parms.avatarContactProcessingThreshold);
-
- parms.maxPersistantManifoldPoolSize = pConfig.GetFloat("MaxPersistantManifoldPoolSize", parms.maxPersistantManifoldPoolSize);
- parms.shouldDisableContactPoolDynamicAllocation = ParamBoolean(pConfig, "ShouldDisableContactPoolDynamicAllocation", parms.shouldDisableContactPoolDynamicAllocation);
- parms.shouldForceUpdateAllAabbs = ParamBoolean(pConfig, "ShouldForceUpdateAllAabbs", parms.shouldForceUpdateAllAabbs);
- parms.shouldRandomizeSolverOrder = ParamBoolean(pConfig, "ShouldRandomizeSolverOrder", parms.shouldRandomizeSolverOrder);
- parms.shouldSplitSimulationIslands = ParamBoolean(pConfig, "ShouldSplitSimulationIslands", parms.shouldSplitSimulationIslands);
- parms.shouldEnableFrictionCaching = ParamBoolean(pConfig, "ShouldEnableFrictionCaching", parms.shouldEnableFrictionCaching);
- parms.numberOfSolverIterations = pConfig.GetFloat("NumberOfSolverIterations", parms.numberOfSolverIterations);
+ SetParameterConfigurationValues(pConfig);
// Very detailed logging for physics debugging
m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
@@ -357,7 +274,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
}
}
- m_params[0] = parms;
}
// A helper function that handles a true/false parameter and returns the proper float number encoding
@@ -630,6 +546,33 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public override void Dispose()
{
// m_log.DebugFormat("{0}: Dispose()", LogHeader);
+
+ // make sure no stepping happens while we're deleting stuff
+ m_initialized = false;
+
+ if (m_constraintCollection != null)
+ {
+ m_constraintCollection.Dispose();
+ m_constraintCollection = null;
+ }
+
+ foreach (KeyValuePair kvp in m_avatars)
+ {
+ kvp.Value.Destroy();
+ }
+ m_avatars.Clear();
+
+ foreach (KeyValuePair kvp in m_prims)
+ {
+ kvp.Value.Destroy();
+ }
+ m_prims.Clear();
+
+ // Anything left in the unmanaged code should be cleaned out
+ BulletSimAPI.Shutdown(WorldID);
+
+ // Not logging any more
+ PhysicsLogging.Close();
}
public override Dictionary GetTopColliders()
@@ -755,10 +698,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
}
// The calls to the PhysicsActors can't directly call into the physics engine
- // because it might be busy. We we delay changes to a known time.
+ // because it might be busy. We delay changes to a known time.
// We rely on C#'s closure to save and restore the context for the delegate.
public void TaintedObject(TaintCallback callback)
{
+ if (!m_initialized) return;
+
lock (_taintLock)
_taintedObjects.Add(callback);
return;
@@ -832,61 +777,371 @@ public class BSScene : PhysicsScene, IPhysicsParameters
}
#endregion Vehicles
- #region Runtime settable parameters
- public static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[]
+ #region Parameters
+
+ delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
+ delegate float ParamGet(BSScene scene);
+ delegate void ParamSet(BSScene scene, string paramName, uint localID, float val);
+
+ private struct ParameterDefn
{
- new PhysParameterEntry("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)"),
- new PhysParameterEntry("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)"),
- new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"),
- new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"),
- new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"),
- new PhysParameterEntry("DetailedStats", "Frames between outputting detailed phys stats. Zero is off"),
+ public string name;
+ public string desc;
+ public float defaultValue;
+ public ParamUser userParam;
+ public ParamGet getter;
+ public ParamSet setter;
+ public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
+ {
+ name = n;
+ desc = d;
+ defaultValue = v;
+ userParam = u;
+ getter = g;
+ setter = s;
+ }
+ }
- new PhysParameterEntry("DefaultFriction", "Friction factor used on new objects"),
- new PhysParameterEntry("DefaultDensity", "Density for new objects" ),
- new PhysParameterEntry("DefaultRestitution", "Bouncyness of an object" ),
- // new PhysParameterEntry("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!!)" ),
- new PhysParameterEntry("Gravity", "Vertical force of gravity (negative means down)" ),
+ // List of all of the externally visible parameters.
+ // For each parameter, this table maps a text name to getter and setters.
+ // A ParameterDefn() takes the following parameters:
+ // -- the text name of the parameter. This is used for console input and ini file.
+ // -- a short text description of the parameter. This shows up in the console listing.
+ // -- a delegate for fetching the parameter from the ini file.
+ // Should handle fetching the right type from the ini file and converting it.
+ // -- a delegate for getting the value as a float
+ // -- a delegate for setting the value from a float
+ //
+ // To add a new variable, it is best to find an existing definition and copy it.
+ private ParameterDefn[] ParameterDefinitions =
+ {
+ new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties",
+ ConfigurationParameters.numericTrue,
+ (s,cf,p,v) => { s._meshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); },
+ (s) => { return s.NumericBool(s._meshSculptedPrim); },
+ (s,p,l,v) => { s._meshSculptedPrim = s.BoolNumeric(v); } ),
+ new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects",
+ ConfigurationParameters.numericFalse,
+ (s,cf,p,v) => { s._forceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); },
+ (s) => { return s.NumericBool(s._forceSimplePrimMeshing); },
+ (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ),
- new PhysParameterEntry("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)" ),
- new PhysParameterEntry("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)" ),
- new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ),
- new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ),
- new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ),
- new PhysParameterEntry("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ),
- new PhysParameterEntry("CcdSweptSphereRadius", "Continuious collision detection test radius" ),
- new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ),
- // Can only change the following at initialization time. Change the INI file and reboot.
- new PhysParameterEntry("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)"),
- new PhysParameterEntry("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count"),
- new PhysParameterEntry("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step"),
- new PhysParameterEntry("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction"),
- new PhysParameterEntry("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands"),
- new PhysParameterEntry("ShouldEnableFrictionCaching", "Enable friction computation caching"),
- new PhysParameterEntry("NumberOfSolverIterations", "Number of internal iterations (0 means default)"),
+ new ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
+ 8f,
+ (s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); },
+ (s) => { return (float)s.m_meshLOD; },
+ (s,p,l,v) => { s.m_meshLOD = (int)v; } ),
+ new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
+ 32,
+ (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); },
+ (s) => { return (float)s.m_sculptLOD; },
+ (s,p,l,v) => { s.m_sculptLOD = (int)v; } ),
- new PhysParameterEntry("Friction", "Set friction parameter for a specific object" ),
- new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ),
+ new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
+ 10f,
+ (s,cf,p,v) => { s.m_maxSubSteps = cf.GetInt(p, (int)v); },
+ (s) => { return (float)s.m_maxSubSteps; },
+ (s,p,l,v) => { s.m_maxSubSteps = (int)v; } ),
+ new ParameterDefn("FixedTimeStep", "In simulation step, seconds of one substep (1/60)",
+ 1f / 60f,
+ (s,cf,p,v) => { s.m_fixedTimeStep = cf.GetFloat(p, v); },
+ (s) => { return (float)s.m_fixedTimeStep; },
+ (s,p,l,v) => { s.m_fixedTimeStep = v; } ),
+ new ParameterDefn("MaxCollisionsPerFrame", "Max collisions returned at end of each frame",
+ 2048f,
+ (s,cf,p,v) => { s.m_maxCollisionsPerFrame = cf.GetInt(p, (int)v); },
+ (s) => { return (float)s.m_maxCollisionsPerFrame; },
+ (s,p,l,v) => { s.m_maxCollisionsPerFrame = (int)v; } ),
+ new ParameterDefn("MaxUpdatesPerFrame", "Max updates returned at end of each frame",
+ 8000f,
+ (s,cf,p,v) => { s.m_maxUpdatesPerFrame = cf.GetInt(p, (int)v); },
+ (s) => { return (float)s.m_maxUpdatesPerFrame; },
+ (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
+ new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
+ 10000.01f,
+ (s,cf,p,v) => { s.m_maximumObjectMass = cf.GetFloat(p, v); },
+ (s) => { return (float)s.m_maximumObjectMass; },
+ (s,p,l,v) => { s.m_maximumObjectMass = v; } ),
- new PhysParameterEntry("Friction", "Set friction parameter for a specific object" ),
- new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ),
+ new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
+ 2200f,
+ (s,cf,p,v) => { s.PID_D = cf.GetFloat(p, v); },
+ (s) => { return (float)s.PID_D; },
+ (s,p,l,v) => { s.PID_D = v; } ),
+ new ParameterDefn("PID_P", "Parameteric factor for motion smoothing",
+ 900f,
+ (s,cf,p,v) => { s.PID_P = cf.GetFloat(p, v); },
+ (s) => { return (float)s.PID_P; },
+ (s,p,l,v) => { s.PID_P = v; } ),
- new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ),
- new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ),
- new PhysParameterEntry("TerrainRestitution", "Bouncyness" ),
- new PhysParameterEntry("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation." ),
- new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ),
- new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ),
- new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ),
- new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" ),
- new PhysParameterEntry("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions")
+ new ParameterDefn("DefaultFriction", "Friction factor used on new objects",
+ 0.5f,
+ (s,cf,p,v) => { s.m_params[0].defaultFriction = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].defaultFriction; },
+ (s,p,l,v) => { s.m_params[0].defaultFriction = v; } ),
+ new ParameterDefn("DefaultDensity", "Density for new objects" ,
+ 10.000006836f, // Aluminum g/cm3
+ (s,cf,p,v) => { s.m_params[0].defaultDensity = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].defaultDensity; },
+ (s,p,l,v) => { s.m_params[0].defaultDensity = v; } ),
+ new ParameterDefn("DefaultRestitution", "Bouncyness of an object" ,
+ 0f,
+ (s,cf,p,v) => { s.m_params[0].defaultRestitution = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].defaultRestitution; },
+ (s,p,l,v) => { s.m_params[0].defaultRestitution = v; } ),
+ new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)",
+ 0f,
+ (s,cf,p,v) => { s.m_params[0].collisionMargin = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].collisionMargin; },
+ (s,p,l,v) => { s.m_params[0].collisionMargin = v; } ),
+ new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)",
+ -9.80665f,
+ (s,cf,p,v) => { s.m_params[0].gravity = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].gravity; },
+ (s,p,l,v) => { s.m_params[0].gravity = v; s.TaintedUpdateParameter(p,l,v); } ),
+
+
+ new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)",
+ 0f,
+ (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].linearDamping; },
+ (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearDamping, p, l, v); } ),
+ new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
+ 0f,
+ (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].angularDamping; },
+ (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularDamping, p, l, v); } ),
+ new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
+ 0.2f,
+ (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].deactivationTime; },
+ (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].deactivationTime, p, l, v); } ),
+ new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
+ 0.8f,
+ (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].linearSleepingThreshold; },
+ (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ),
+ new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
+ 1.0f,
+ (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].angularSleepingThreshold; },
+ (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ),
+ new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
+ 0f, // set to zero to disable
+ (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].ccdMotionThreshold; },
+ (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ),
+ new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
+ 0f,
+ (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].ccdSweptSphereRadius; },
+ (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ),
+ new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
+ 0.1f,
+ (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].contactProcessingThreshold; },
+ (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ),
+
+ new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
+ 0.5f,
+ (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].terrainFriction; },
+ (s,p,l,v) => { s.m_params[0].terrainFriction = v; s.TaintedUpdateParameter(p,l,v); } ),
+ new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" ,
+ 0.8f,
+ (s,cf,p,v) => { s.m_params[0].terrainHitFraction = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].terrainHitFraction; },
+ (s,p,l,v) => { s.m_params[0].terrainHitFraction = v; s.TaintedUpdateParameter(p,l,v); } ),
+ new ParameterDefn("TerrainRestitution", "Bouncyness" ,
+ 0f,
+ (s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].terrainRestitution; },
+ (s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ),
+ new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
+ 0.5f,
+ (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].avatarFriction; },
+ (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarFriction, p, l, v); } ),
+ new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
+ 60f,
+ (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].avatarDensity; },
+ (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarDensity, p, l, v); } ),
+ new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
+ 0f,
+ (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].avatarRestitution; },
+ (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarRestitution, p, l, v); } ),
+ new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar",
+ 0.37f,
+ (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].avatarCapsuleRadius; },
+ (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ),
+ new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
+ 1.5f,
+ (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].avatarCapsuleHeight; },
+ (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ),
+ new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
+ 0.1f,
+ (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].avatarContactProcessingThreshold; },
+ (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
+
+
+ new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)",
+ 0f, // zero to disable
+ (s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].maxPersistantManifoldPoolSize; },
+ (s,p,l,v) => { s.m_params[0].maxPersistantManifoldPoolSize = v; } ),
+ new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
+ ConfigurationParameters.numericTrue,
+ (s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
+ (s) => { return s.m_params[0].shouldDisableContactPoolDynamicAllocation; },
+ (s,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ),
+ new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
+ ConfigurationParameters.numericFalse,
+ (s,cf,p,v) => { s.m_params[0].shouldForceUpdateAllAabbs = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
+ (s) => { return s.m_params[0].shouldForceUpdateAllAabbs; },
+ (s,p,l,v) => { s.m_params[0].shouldForceUpdateAllAabbs = v; } ),
+ new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction",
+ ConfigurationParameters.numericFalse,
+ (s,cf,p,v) => { s.m_params[0].shouldRandomizeSolverOrder = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
+ (s) => { return s.m_params[0].shouldRandomizeSolverOrder; },
+ (s,p,l,v) => { s.m_params[0].shouldRandomizeSolverOrder = v; } ),
+ new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands",
+ ConfigurationParameters.numericFalse,
+ (s,cf,p,v) => { s.m_params[0].shouldSplitSimulationIslands = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
+ (s) => { return s.m_params[0].shouldSplitSimulationIslands; },
+ (s,p,l,v) => { s.m_params[0].shouldSplitSimulationIslands = v; } ),
+ new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching",
+ ConfigurationParameters.numericFalse,
+ (s,cf,p,v) => { s.m_params[0].shouldEnableFrictionCaching = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
+ (s) => { return s.m_params[0].shouldEnableFrictionCaching; },
+ (s,p,l,v) => { s.m_params[0].shouldEnableFrictionCaching = v; } ),
+ new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)",
+ 0f, // zero says use Bullet default
+ (s,cf,p,v) => { s.m_params[0].numberOfSolverIterations = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].numberOfSolverIterations; },
+ (s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ),
+
+ new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
+ ConfigurationParameters.numericTrue,
+ (s,cf,p,v) => { s.m_params[0].linkConstraintUseFrameOffset = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
+ (s) => { return s.m_params[0].linkConstraintUseFrameOffset; },
+ (s,p,l,v) => { s.m_params[0].linkConstraintUseFrameOffset = v; } ),
+ new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
+ ConfigurationParameters.numericTrue,
+ (s,cf,p,v) => { s.m_params[0].linkConstraintEnableTransMotor = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
+ (s) => { return s.m_params[0].linkConstraintEnableTransMotor; },
+ (s,p,l,v) => { s.m_params[0].linkConstraintEnableTransMotor = v; } ),
+ new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints",
+ 5.0f,
+ (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxVel = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].linkConstraintTransMotorMaxVel; },
+ (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxVel = v; } ),
+ new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints",
+ 0.1f,
+ (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = cf.GetFloat(p, v); },
+ (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; },
+ (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ),
+
+ new ParameterDefn("DetailedStats", "Frames between outputting detailed phys stats. (0 is off)",
+ 0f,
+ (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); },
+ (s) => { return (float)s.m_detailedStatsStep; },
+ (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
+ new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
+ ConfigurationParameters.numericFalse,
+ (s,cf,p,v) => { s.shouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
+ (s) => { return s.NumericBool(s.shouldDebugLog); },
+ (s,p,l,v) => { s.shouldDebugLog = s.BoolNumeric(v); } ),
};
+ // Convert a boolean to our numeric true and false values
+ public float NumericBool(bool b)
+ {
+ return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse);
+ }
+
+ // Convert numeric true and false values to a boolean
+ public bool BoolNumeric(float b)
+ {
+ return (b == ConfigurationParameters.numericTrue ? true : false);
+ }
+
+ // Search through the parameter definitions and return the matching
+ // ParameterDefn structure.
+ // Case does not matter as names are compared after converting to lower case.
+ // Returns 'false' if the parameter is not found.
+ private bool TryGetParameter(string paramName, out ParameterDefn defn)
+ {
+ bool ret = false;
+ ParameterDefn foundDefn = new ParameterDefn();
+ string pName = paramName.ToLower();
+
+ foreach (ParameterDefn parm in ParameterDefinitions)
+ {
+ if (pName == parm.name.ToLower())
+ {
+ foundDefn = parm;
+ ret = true;
+ break;
+ }
+ }
+ defn = foundDefn;
+ return ret;
+ }
+
+ // Pass through the settable parameters and set the default values
+ private void SetParameterDefaultValues()
+ {
+ foreach (ParameterDefn parm in ParameterDefinitions)
+ {
+ parm.setter(this, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue);
+ }
+ }
+
+ // Get user set values out of the ini file.
+ private void SetParameterConfigurationValues(IConfig cfg)
+ {
+ foreach (ParameterDefn parm in ParameterDefinitions)
+ {
+ parm.userParam(this, cfg, parm.name, parm.defaultValue);
+ }
+ }
+
+ private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
+
+ private void BuildParameterTable()
+ {
+ if (SettableParameters.Length < ParameterDefinitions.Length)
+ {
+
+ List entries = new List();
+ for (int ii = 0; ii < ParameterDefinitions.Length; ii++)
+ {
+ ParameterDefn pd = ParameterDefinitions[ii];
+ entries.Add(new PhysParameterEntry(pd.name, pd.desc));
+ }
+
+ // make the list in alphabetical order for estetic reasons
+ entries.Sort(delegate(PhysParameterEntry ppe1, PhysParameterEntry ppe2)
+ {
+ return ppe1.name.CompareTo(ppe2.name);
+ });
+
+ SettableParameters = entries.ToArray();
+ }
+ }
+
+
#region IPhysicsParameters
// Get the list of parameters this physics engine supports
public PhysParameterEntry[] GetParameterList()
{
+ BuildParameterTable();
return SettableParameters;
}
@@ -898,63 +1153,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// value activated ('terrainFriction' for instance).
public bool SetPhysicsParameter(string parm, float val, uint localID)
{
- bool ret = true;
- string lparm = parm.ToLower();
- switch (lparm)
+ bool ret = false;
+ ParameterDefn theParam;
+ if (TryGetParameter(parm, out theParam))
{
- case "detailedstats": m_detailedStatsStep = (int)val; break;
-
- case "meshlod": m_meshLOD = (int)val; break;
- case "sculptlod": m_sculptLOD = (int)val; break;
- case "maxsubstep": m_maxSubSteps = (int)val; break;
- case "fixedtimestep": m_fixedTimeStep = val; break;
- case "maxobjectmass": m_maximumObjectMass = val; break;
-
- case "defaultfriction": m_params[0].defaultFriction = val; break;
- case "defaultdensity": m_params[0].defaultDensity = val; break;
- case "defaultrestitution": m_params[0].defaultRestitution = val; break;
- case "collisionmargin": m_params[0].collisionMargin = val; break;
- case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, localID, val); break;
-
- case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break;
- case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
- case "deactivationtime": UpdateParameterPrims(ref m_params[0].deactivationTime, lparm, localID, val); break;
- case "linearsleepingthreshold": UpdateParameterPrims(ref m_params[0].linearSleepingThreshold, lparm, localID, val); break;
- case "angularsleepingthreshold": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
- case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break;
- case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break;
- case "contactprocessingthreshold": UpdateParameterPrims(ref m_params[0].contactProcessingThreshold, lparm, localID, val); break;
- // the following are used only at initialization time so setting them makes no sense
- // case "maxPersistantmanifoldpoolSize": m_params[0].maxPersistantManifoldPoolSize = val; break;
- // case "shoulddisablecontactpooldynamicallocation": m_params[0].shouldDisableContactPoolDynamicAllocation = val; break;
- // case "shouldforceupdateallaabbs": m_params[0].shouldForceUpdateAllAabbs = val; break;
- // case "shouldrandomizesolverorder": m_params[0].shouldRandomizeSolverOrder = val; break;
- // case "shouldsplitsimulationislands": m_params[0].shouldSplitSimulationIslands = val; break;
- // case "shouldenablefrictioncaching": m_params[0].shouldEnableFrictionCaching = val; break;
- // case "numberofsolveriterations": m_params[0].numberOfSolverIterations = val; break;
-
- case "friction": TaintedUpdateParameter(lparm, localID, val); break;
- case "restitution": TaintedUpdateParameter(lparm, localID, val); break;
-
- // set a terrain physical feature and cause terrain to be recalculated
- case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break;
- case "terrainhitfraction": m_params[0].terrainHitFraction = val; TaintedUpdateParameter("terrain", 0, val); break;
- case "terrainrestitution": m_params[0].terrainRestitution = val; TaintedUpdateParameter("terrain", 0, val); break;
- // set an avatar physical feature and cause avatar(s) to be recalculated
- case "avatarfriction": UpdateParameterAvatars(ref m_params[0].avatarFriction, "avatar", localID, val); break;
- case "avatardensity": UpdateParameterAvatars(ref m_params[0].avatarDensity, "avatar", localID, val); break;
- case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break;
- case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break;
- case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break;
- case "avatarcontactprocessingthreshold": UpdateParameterAvatars(ref m_params[0].avatarContactProcessingThreshold, "avatar", localID, val); break;
-
- default: ret = false; break;
+ theParam.setter(this, parm, localID, val);
+ ret = true;
}
return ret;
}
// check to see if we are updating a parameter for a particular or all of the prims
- private void UpdateParameterPrims(ref float loc, string parm, uint localID, float val)
+ protected void UpdateParameterPrims(ref float loc, string parm, uint localID, float val)
{
List operateOn;
lock (m_prims) operateOn = new List(m_prims.Keys);
@@ -962,7 +1172,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
}
// check to see if we are updating a parameter for a particular or all of the avatars
- private void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val)
+ protected void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val)
{
List operateOn;
lock (m_avatars) operateOn = new List(m_avatars.Keys);
@@ -973,7 +1183,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// If the local ID is APPLY_TO_NONE, just change the default value
// If the localID is APPLY_TO_ALL change the default value and apply the new value to all the lIDs
// If the localID is a specific object, apply the parameter change to only that object
- private void UpdateParameterSet(List lIDs, ref float defaultLoc, string parm, uint localID, float val)
+ protected void UpdateParameterSet(List lIDs, ref float defaultLoc, string parm, uint localID, float val)
{
switch (localID)
{
@@ -1000,7 +1210,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
}
// schedule the actual updating of the paramter to when the phys engine is not busy
- private void TaintedUpdateParameter(string parm, uint localID, float val)
+ protected void TaintedUpdateParameter(string parm, uint localID, float val)
{
uint xlocalID = localID;
string xparm = parm.ToLower();
@@ -1015,50 +1225,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public bool GetPhysicsParameter(string parm, out float value)
{
float val = 0f;
- bool ret = true;
- switch (parm.ToLower())
+ bool ret = false;
+ ParameterDefn theParam;
+ if (TryGetParameter(parm, out theParam))
{
- case "detailedstats": val = (int)m_detailedStatsStep; break;
- case "meshlod": val = (float)m_meshLOD; break;
- case "sculptlod": val = (float)m_sculptLOD; break;
- case "maxsubstep": val = (float)m_maxSubSteps; break;
- case "fixedtimestep": val = m_fixedTimeStep; break;
- case "maxobjectmass": val = m_maximumObjectMass; break;
-
- case "defaultfriction": val = m_params[0].defaultFriction; break;
- case "defaultdensity": val = m_params[0].defaultDensity; break;
- case "defaultrestitution": val = m_params[0].defaultRestitution; break;
- case "collisionmargin": val = m_params[0].collisionMargin; break;
- case "gravity": val = m_params[0].gravity; break;
-
- case "lineardamping": val = m_params[0].linearDamping; break;
- case "angulardamping": val = m_params[0].angularDamping; break;
- case "deactivationtime": val = m_params[0].deactivationTime; break;
- case "linearsleepingthreshold": val = m_params[0].linearSleepingThreshold; break;
- case "angularsleepingthreshold": val = m_params[0].angularDamping; break;
- case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break;
- case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break;
- case "contactprocessingthreshold": val = m_params[0].contactProcessingThreshold; break;
- case "maxPersistantmanifoldpoolSize": val = m_params[0].maxPersistantManifoldPoolSize; break;
- case "shoulddisablecontactpooldynamicallocation": val = m_params[0].shouldDisableContactPoolDynamicAllocation; break;
- case "shouldforceupdateallaabbs": val = m_params[0].shouldForceUpdateAllAabbs; break;
- case "shouldrandomizesolverorder": val = m_params[0].shouldRandomizeSolverOrder; break;
- case "shouldsplitsimulationislands": val = m_params[0].shouldSplitSimulationIslands; break;
- case "shouldenablefrictioncaching": val = m_params[0].shouldEnableFrictionCaching; break;
- case "numberofsolveriterations": val = m_params[0].numberOfSolverIterations; break;
-
- case "terrainfriction": val = m_params[0].terrainFriction; break;
- case "terrainhitfraction": val = m_params[0].terrainHitFraction; break;
- case "terrainrestitution": val = m_params[0].terrainRestitution; break;
-
- case "avatarfriction": val = m_params[0].avatarFriction; break;
- case "avatardensity": val = m_params[0].avatarDensity; break;
- case "avatarrestitution": val = m_params[0].avatarRestitution; break;
- case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break;
- case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break;
- case "avatarcontactprocessingthreshold": val = m_params[0].avatarContactProcessingThreshold; break;
- default: ret = false; break;
-
+ val = theParam.getter(this);
+ ret = true;
}
value = val;
return ret;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index babb707b75..89fd9b71d6 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -32,6 +32,28 @@ using OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin {
+// Classes to allow some type checking for the API
+public struct BulletSim
+{
+ public BulletSim(uint id, IntPtr xx) { ID = id; Ptr = xx; }
+ public IntPtr Ptr;
+ public uint ID;
+}
+
+public struct BulletBody
+{
+ public BulletBody(uint id, IntPtr xx) { ID = id; Ptr = xx; }
+ public IntPtr Ptr;
+ public uint ID;
+}
+
+public struct BulletConstraint
+{
+ public BulletConstraint(IntPtr xx) { Ptr = xx; }
+ public IntPtr Ptr;
+}
+
+// ===============================================================================
[StructLayout(LayoutKind.Sequential)]
public struct ConvexHull
{
@@ -142,6 +164,11 @@ public struct ConfigurationParameters
public float shouldEnableFrictionCaching;
public float numberOfSolverIterations;
+ public float linkConstraintUseFrameOffset;
+ public float linkConstraintEnableTransMotor;
+ public float linkConstraintTransMotorMaxVel;
+ public float linkConstraintTransMotorMaxForce;
+
public const float numericTrue = 1f;
public const float numericFalse = 0f;
}
@@ -162,6 +189,7 @@ public enum CollisionFlags : uint
PHYSICAL_OBJECT = 1 << 12,
};
+// ===============================================================================
static class BulletSimAPI {
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
@@ -214,6 +242,7 @@ public static extern bool CreateObject(uint worldID, ShapeData shapeData);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas);
+/* Remove old functionality
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void AddConstraint(uint worldID, uint id1, uint id2,
Vector3 frame1, Quaternion frame1rot,
@@ -225,6 +254,7 @@ public static extern bool RemoveConstraintByID(uint worldID, uint id1);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2);
+ */
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern Vector3 GetObjectPosition(uint WorldID, uint id);
@@ -291,13 +321,14 @@ public static extern void SetDebugLogCallback(DebugLogCallback callback);
// ===============================================================================
// ===============================================================================
// ===============================================================================
-// A new version of the API that moves all the logic out of the C++ code and into
+// A new version of the API that enables moving all the logic out of the C++ code and into
// the C# code. This will make modifications easier for the next person.
// This interface passes the actual pointers to the objects in the unmanaged
// address space. All the management (calls for creation/destruction/lookup)
// is done in the C# code.
-// The names have a 2 tacked on. This will be removed as the code gets rebuilt
-// and the old code is removed from the C# code.
+// The names have a "2" tacked on. This will be removed as the C# code gets rebuilt
+// and the old code is removed.
+
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GetSimHandle2(uint worldID);
@@ -307,8 +338,115 @@ public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GetBodyHandle2(IntPtr sim, uint id);
+// ===============================================================================
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
-public static extern IntPtr ClearForces2(IntPtr obj);
+public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
+ int maxCollisions, IntPtr collisionArray,
+ int maxUpdates, IntPtr updateArray);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool UpdateParameter2(IntPtr sim, uint localID, String parm, float value);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern void SetHeightmap2(IntPtr sim, float[] heightmap);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern void Shutdown2(IntPtr sim);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern int PhysicsStep2(IntPtr sim, float timeStep, int maxSubSteps, float fixedTimeStep,
+ out int updatedEntityCount,
+ out IntPtr updatedEntitiesPtr,
+ out int collidersCount,
+ out IntPtr collidersPtr);
+
+/*
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern IntPtr CreateMesh2(IntPtr sim, int indicesCount, int* indices, int verticesCount, float* vertices );
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool BuildHull2(IntPtr sim, IntPtr mesh);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool ReleaseHull2(IntPtr sim, IntPtr mesh);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool DestroyMesh2(IntPtr sim, IntPtr mesh);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern IntPtr CreateObject2(IntPtr sim, ShapeData shapeData);
+*/
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern IntPtr CreateConstraint2(IntPtr sim, IntPtr obj1, IntPtr obj2,
+ Vector3 frame1loc, Quaternion frame1rot,
+ Vector3 frame2loc, Quaternion frame2rot);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetAngularLimits2(IntPtr constrain, Vector3 low, Vector3 hi);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool UseFrameOffset2(IntPtr constrain, float enable);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool CalculateTransforms2(IntPtr constrain);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool DestroyConstraint2(IntPtr sim, IntPtr constrain);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern Vector3 GetPosition2(IntPtr obj);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern Quaternion GetOrientation2(IntPtr obj);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetVelocity2(IntPtr obj, Vector3 velocity);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetObjectForce2(IntPtr obj, Vector3 force);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetCcdMotionThreshold2(IntPtr obj, float val);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetCcdSweepSphereRadius2(IntPtr obj, float val);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetDamping2(IntPtr obj, float lin_damping, float ang_damping);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetDeactivationTime2(IntPtr obj, float val);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetContactProcessingThreshold2(IntPtr obj, float val);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetFriction2(IntPtr obj, float val);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetRestitution2(IntPtr obj, float val);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetLinearVelocity2(IntPtr obj, Vector3 val);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetInterpolation2(IntPtr obj, Vector3 lin, Vector3 ang);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr SetCollisionFlags2(IntPtr obj, uint flags);
@@ -319,5 +457,35 @@ public static extern IntPtr AddToCollisionFlags2(IntPtr obj, uint flags);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr RemoveFromCollisionFlags2(IntPtr obj, uint flags);
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetMassProps2(IntPtr obj, float mass, Vector3 inertia);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool UpdateInertiaTensor2(IntPtr obj);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetGravity2(IntPtr obj, Vector3 val);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern IntPtr ClearForces2(IntPtr obj);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool SetMargin2(IntPtr obj, float val);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool UpdateSingleAabb2(IntPtr world, IntPtr obj);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern bool DestroyObject2(IntPtr world, uint id);
+
+[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
+public static extern void DumpPhysicsStatistics2(IntPtr sim);
+
}
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 5b22860f72..47a9cdc094 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -31,6 +31,7 @@ using System.Collections.Generic;
using System.Threading;
using OpenMetaverse;
using OpenSim.Framework;
+using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared;
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index da344d6116..2dba029307 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -646,7 +646,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
// If region ready has been triggered, then the region had no scripts to compile and completed its other
// work.
- m_Scene.EventManager.OnRegionReady += s => m_InitialStartup = false;
+ m_Scene.EventManager.OnRegionReadyStatusChange += s => { if (s.Ready) m_InitialStartup = false; };
if (m_SleepTime > 0)
{
diff --git a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs
index dcbd7173d9..3243a9a952 100644
--- a/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs
+++ b/OpenSim/Region/UserStatistics/ActiveConnectionsAJAX.cs
@@ -34,7 +34,7 @@ using Mono.Data.SqliteClient;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.UserStatistics
{
diff --git a/OpenSim/Region/UserStatistics/Default_Report.cs b/OpenSim/Region/UserStatistics/Default_Report.cs
index 0e1763046d..cdc615caff 100644
--- a/OpenSim/Region/UserStatistics/Default_Report.cs
+++ b/OpenSim/Region/UserStatistics/Default_Report.cs
@@ -33,7 +33,7 @@ using System.Text;
using Mono.Data.SqliteClient;
using OpenMetaverse;
using OpenSim.Region.Framework.Scenes;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.UserStatistics
diff --git a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs b/OpenSim/Region/UserStatistics/LogLinesAJAX.cs
index 811baba998..74de46b227 100644
--- a/OpenSim/Region/UserStatistics/LogLinesAJAX.cs
+++ b/OpenSim/Region/UserStatistics/LogLinesAJAX.cs
@@ -34,7 +34,7 @@ using System.Text.RegularExpressions;
using Mono.Data.SqliteClient;
using OpenMetaverse;
using OpenSim.Region.Framework.Scenes;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.UserStatistics
{
diff --git a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs
index 8c04e71a61..28051fb674 100644
--- a/OpenSim/Region/UserStatistics/SimStatsAJAX.cs
+++ b/OpenSim/Region/UserStatistics/SimStatsAJAX.cs
@@ -33,7 +33,7 @@ using System.Text;
using Mono.Data.SqliteClient;
using OpenMetaverse;
using OpenSim.Region.Framework.Scenes;
-using OpenSim.Framework.Statistics;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.UserStatistics
{
diff --git a/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs
index fba03abcf0..0a2b30a279 100644
--- a/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/TaskInventoryHelpers.cs
@@ -79,9 +79,27 @@ namespace OpenSim.Tests.Common
///
/// The item that was added
public static TaskInventoryItem AddScript(Scene scene, SceneObjectPart part)
+ {
+ return AddScript(scene, part, "scriptItem", "default { state_entry() { llSay(0, \"Hello World\"); } }");
+ }
+
+ ///
+ /// Add a simple script to the given part.
+ ///
+ ///
+ /// TODO: Accept input for item and asset IDs to avoid mysterious script failures that try to use any of these
+ /// functions more than once in a test.
+ ///
+ ///
+ ///
+ /// Name of the script to add
+ /// LSL script source
+ /// The item that was added
+ public static TaskInventoryItem AddScript(
+ Scene scene, SceneObjectPart part, string scriptName, string scriptSource)
{
AssetScriptText ast = new AssetScriptText();
- ast.Source = "default { state_entry() { llSay(0, \"Hello World\"); } }";
+ ast.Source = scriptSource;
ast.Encode();
UUID assetUuid = new UUID("00000000-0000-0000-1000-000000000000");
@@ -91,7 +109,7 @@ namespace OpenSim.Tests.Common
scene.AssetService.Store(asset);
TaskInventoryItem item
= new TaskInventoryItem
- { Name = "scriptItem", AssetID = assetUuid, ItemID = itemUuid,
+ { Name = scriptName, AssetID = assetUuid, ItemID = itemUuid,
Type = (int)AssetType.LSLText, InvType = (int)InventoryType.LSL };
part.Inventory.AddInventoryItem(item, true);
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index ededdc054e..5935ca1b54 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -914,6 +914,12 @@
ShouldEnableFrictionCaching = False;
NumberOfSolverIterations = 0;
+ ; Linkset constraint parameters
+ LinkConstraintUseFrameOffset = True;
+ LinkConstraintEnableTransMotor = True;
+ LinkConstraintTransMotorMaxVel = 5.0;
+ LinkConstraintTransMotorMaxForce = 0.1;
+
; Whether to mesh sculpties
MeshSculptedPrim = true
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll
index 8791ba57de..c6bb76af7f 100755
Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ
diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so
index da98509500..6ca98cc8fe 100755
Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ
diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll
index 9af5dab4c2..0924dd01da 100755
Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ
diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so
index 3d4b630756..70bcdb7983 100755
Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ
diff --git a/prebuild.xml b/prebuild.xml
index 5973ece167..ea4ec250a4 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -112,6 +112,32 @@
+
+
+
+ ../../../bin/
+
+
+
+
+ ../../../bin/
+
+
+
+ ../../../bin/
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -130,6 +156,7 @@
+
@@ -235,30 +262,6 @@
-
-
-
- ../../../bin/
-
-
-
-
- ../../../bin/
-
-
-
- ../../../bin/
-
-
-
-
-
-
-
-
-
-
-
@@ -436,7 +439,7 @@
-
+
@@ -601,9 +604,9 @@
+
-
@@ -635,13 +638,13 @@
+
-
+
+
-
-
@@ -687,10 +690,10 @@
+
-
@@ -1444,10 +1447,10 @@
+
-
@@ -1535,11 +1538,11 @@
+
+
-
-
@@ -1572,15 +1575,15 @@
-
-
+
+
-
+
@@ -1663,9 +1666,9 @@
+
-
@@ -1801,15 +1804,15 @@
+
-
+
-
-
+
@@ -2321,10 +2324,11 @@
+
+
-
@@ -2447,7 +2451,6 @@
-
@@ -2476,9 +2479,9 @@
+
-
@@ -2962,9 +2965,9 @@
+
-
@@ -3034,9 +3037,9 @@
+
-
@@ -3093,8 +3096,8 @@
+
-
@@ -3150,9 +3153,9 @@
+
-
@@ -3187,7 +3190,7 @@
-
+