diff --git a/.gitignore b/.gitignore
index c8990d2f67..e04c219d90 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,6 +44,8 @@ bin/Physics*
bin/Terrain*
bin/Regions/*
bin/UserAssets
+bin/assetcache
+bin/maptiles
bin/estate_settings.xml
bin/config-include/CenomeCache.ini
bin/config-include/FlotsamCache.ini
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 98%
rename from OpenSim/Framework/Statistics/BaseStatsCollector.cs
rename to OpenSim/Framework/Monitoring/BaseStatsCollector.cs
index 3f918f3bd9..9ee087694b 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
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..a23cf1fea8
--- /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 449d014590..e4db964dba 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/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index 1b2f6818c1..4bde7be2e1 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -482,9 +482,16 @@ namespace OpenSim.Framework
MainConsole.Instance.Output("=====================================\n");
if (name == String.Empty)
- name = MainConsole.Instance.CmdPrompt("New region name", name);
- if (name == String.Empty)
- throw new Exception("Cannot interactively create region with no name");
+ {
+ while (name.Trim() == string.Empty)
+ {
+ name = MainConsole.Instance.CmdPrompt("New region name", name);
+ if (name.Trim() == string.Empty)
+ {
+ MainConsole.Instance.Output("Cannot interactively create region with no name");
+ }
+ }
+ }
source.AddConfig(name);
@@ -515,15 +522,20 @@ namespace OpenSim.Framework
//
allKeys.Remove("RegionUUID");
string regionUUID = config.GetString("RegionUUID", string.Empty);
- if (regionUUID == String.Empty)
+ if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
{
UUID newID = UUID.Random();
-
- regionUUID = MainConsole.Instance.CmdPrompt("RegionUUID", newID.ToString());
+ while (RegionID == UUID.Zero)
+ {
+ regionUUID = MainConsole.Instance.CmdPrompt("RegionUUID", newID.ToString());
+ if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
+ {
+ MainConsole.Instance.Output("RegionUUID must be a valid UUID");
+ }
+ }
config.Set("RegionUUID", regionUUID);
}
- RegionID = new UUID(regionUUID);
originRegionID = RegionID; // What IS this?! (Needed for RegionCombinerModule?)
// Location
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 9a2cd0e56c..cf19002baf 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -40,9 +40,9 @@ 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 Timer=System.Timers.Timer;
using OpenMetaverse;
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 24f986a756..e45cb895f7 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 a3bd330fb8..a385110b53 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;
/*
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
index 1e3fbf0db5..1c529b6e93 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
@@ -36,6 +36,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 8a0b4ab033..ba8aa9f98c 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[0], 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 76ac246caa..f3781534b7 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;
@@ -300,7 +300,7 @@ namespace OpenSim
private void HandleCommanderCommand(string module, string[] cmd)
{
- m_sceneManager.SendCommandToPluginModules(cmd);
+ SceneManager.SendCommandToPluginModules(cmd);
}
private void HandleCommanderHelp(string module, string[] cmd)
@@ -318,7 +318,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;
}
///
@@ -480,7 +483,7 @@ namespace OpenSim
scene.SnmpService.BootInfo("ScriptEngine started", scene);
}
- m_sceneManager.Add(scene);
+ SceneManager.Add(scene);
if (m_autoCreateClientStack)
{
@@ -510,7 +513,6 @@ namespace OpenSim
}
scene.Start();
-
scene.StartScripts();
return clientServer;
@@ -644,14 +646,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)
@@ -693,7 +695,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);
}
@@ -706,13 +708,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);
}
@@ -724,7 +726,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);
}
@@ -980,7 +982,7 @@ namespace OpenSim
try
{
- m_sceneManager.Close();
+ SceneManager.Close();
}
catch (Exception e)
{
@@ -1005,7 +1007,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;
}
///
@@ -1014,7 +1016,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 098e4eb2af..f7bb817644 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/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 86d8f62a46..7042c9a228 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/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/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index d30c2e2d4c..9a56f42567 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -204,8 +204,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
m_Scene.AssetService.Store(asset);
-
- m_Scene.CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
+ m_Scene.CreateNewInventoryItem(
+ remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
+ name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
}
else
{
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 7ed13206f0..e4c6c1ad76 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -131,11 +131,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
m_enabled = true;
}
- ///
- ///
- ///
-
-
///
///
///
@@ -149,7 +144,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 309856f542..26b406e35a 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/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
index 3f68ee02ec..0fe681fb63 100644
--- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
@@ -40,8 +40,6 @@ 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.
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 418904f65d..7cb3811483 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -517,8 +517,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;
@@ -2533,13 +2532,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
{
@@ -2547,7 +2546,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.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 98b8fccb4a..672d95a724 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -811,16 +811,20 @@ namespace OpenSim.Region.Framework.Scenes
&& oldAgentID == LibraryService.LibraryRootFolder.Owner))
{
CreateNewInventoryItem(
- remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
- item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
+ remoteClient, item.CreatorId, item.CreatorData, newFolderID,
+ newName, item.Description, item.Flags, callbackID, asset, (sbyte)item.InvType,
+ item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions,
+ item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
}
else
{
// If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
- if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0) && (m_permissions.BypassPermissions() || m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID)))
+ if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0)
+ && (m_permissions.BypassPermissions()
+ || m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID)))
{
CreateNewInventoryItem(
- remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID,
+ remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Description, item.Flags, callbackID,
asset, (sbyte) item.InvType,
item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions,
item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
@@ -885,32 +889,50 @@ namespace OpenSim.Region.Framework.Scenes
///
/// Create a new inventory item.
///
- ///
- ///
- ///
- ///
- ///
- ///
- public void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID,
- AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
+ /// Client creating this inventory item.
+ ///
+ ///
+ /// UUID of folder in which this item should be placed.
+ /// Item name.
+ /// Item description.
+ /// Item flags
+ /// Generated by the client.
+ /// Asset to which this item refers.
+ /// Type of inventory item.
+ /// Next owner pemrissions mask.
+ /// Unix timestamp at which this item was created.
+ public void CreateNewInventoryItem(
+ IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
+ string name, string description, uint flags, uint callbackID,
+ AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
{
CreateNewInventoryItem(
- remoteClient, creatorID, creatorData, folderID, name, flags, callbackID, asset, invType,
+ remoteClient, creatorID, creatorData, folderID, name, description, flags, callbackID, asset, invType,
(uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate);
}
///
/// Create a new Inventory Item
///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
+ /// Client creating this inventory item.
+ ///
+ ///
+ /// UUID of folder in which this item should be placed.
+ /// Item name.
+ /// Item description.
+ /// Item flags
+ /// Generated by the client.
+ /// Asset to which this item refers.
+ /// Type of inventory item.
+ /// Base permissions mask.
+ /// Current permissions mask.
+ /// Everyone permissions mask.
+ /// Next owner pemrissions mask.
+ /// Group permissions mask.
+ /// Unix timestamp at which this item was created.
private void CreateNewInventoryItem(
- IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType,
+ IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
+ string name, string description, uint flags, uint callbackID, AssetBase asset, sbyte invType,
uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate)
{
InventoryItemBase item = new InventoryItemBase();
@@ -919,8 +941,8 @@ namespace OpenSim.Region.Framework.Scenes
item.CreatorData = creatorData;
item.ID = UUID.Random();
item.AssetID = asset.FullID;
- item.Description = asset.Description;
item.Name = name;
+ item.Description = description;
item.Flags = flags;
item.AssetType = asset.Type;
item.InvType = invType;
@@ -1002,7 +1024,8 @@ namespace OpenSim.Region.Framework.Scenes
asset.Description = description;
CreateNewInventoryItem(
- remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType,
+ remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
+ name, description, 0, callbackID, asset, invType,
(uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All,
(uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch());
}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0bf2259b82..f7d74dbcb7 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;
@@ -1232,15 +1233,17 @@ namespace OpenSim.Region.Framework.Scenes
avatar.ControllingClient.SendShutdownConnectionNotice();
});
+ // Stop updating the scene objects and agents.
+ m_shuttingDown = true;
+
// Wait here, or the kick messages won't actually get to the agents before the scene terminates.
+ // We also need to wait to avoid a race condition with the scene update loop which might not yet
+ // have checked ShuttingDown.
Thread.Sleep(500);
// Stop all client threads.
ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
- // Stop updating the scene objects and agents.
- m_shuttingDown = true;
-
m_log.Debug("[SCENE]: Persisting changed objects");
EventManager.TriggerSceneShuttingDown(this);
@@ -1255,6 +1258,15 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGraph.Close();
+ if (PhysicsScene != null)
+ {
+ PhysicsScene phys = PhysicsScene;
+ // remove the physics engine from both Scene and SceneGraph
+ PhysicsScene = null;
+ phys.Dispose();
+ phys = null;
+ }
+
if (!GridService.DeregisterRegion(RegionInfo.RegionID))
m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
@@ -1553,8 +1565,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
{
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index d55b08240d..7c8bd8840c 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 e3fed493c4..a412414275 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
{
@@ -128,9 +170,11 @@ namespace OpenSim.Region.Framework.Scenes
public void Add(Scene scene)
{
- scene.OnRestart += HandleRestart;
+ lock (m_localScenes)
+ m_localScenes.Add(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, scene);
- m_localScenes.Add(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, scene);
+ scene.OnRestart += HandleRestart;
+ scene.EventManager.OnRegionReadyStatusChange += HandleRegionReadyStatusChange;
}
public void HandleRestart(RegionInfo rdata)
@@ -138,12 +182,19 @@ namespace OpenSim.Region.Framework.Scenes
m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main");
int RegionSceneElement = -1;
- m_localScenes.Remove(rdata.RegionID);
+ lock (m_localScenes)
+ m_localScenes.Remove(rdata.RegionID);
// Send signal to main that we're restarting this sim.
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;
@@ -483,7 +534,8 @@ namespace OpenSim.Region.Framework.Scenes
public void CloseScene(Scene scene)
{
- m_localScenes.Remove(scene.RegionInfo.RegionID);
+ lock (m_localScenes)
+ m_localScenes.Remove(scene.RegionInfo.RegionID);
scene.Close();
}
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index d6ff5a2890..20919a1982 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 86f33eb463..3b83e58933 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 ca9bd4ad07..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;
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/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
new file mode 100755
index 0000000000..3bc210084e
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -0,0 +1,308 @@
+/*
+ * 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 OMV = OpenMetaverse;
+
+namespace OpenSim.Region.Physics.BulletSPlugin
+{
+public class BSLinkset
+{
+ private static string LogHeader = "[BULLETSIM LINKSET]";
+
+ private BSPrim m_linksetRoot;
+ public BSPrim Root { get { return m_linksetRoot; } }
+
+ private BSScene m_scene;
+
+ private List m_children;
+
+ // We lock the diddling of linkset classes to prevent any badness.
+ // This locks the modification of the instances of this class. Changes
+ // to the physical representation is done via the tainting mechenism.
+ private object m_linksetActivityLock = new Object();
+
+ // We keep the prim's mass in the linkset structure since it could be dependent on other prims
+ private float m_mass;
+ public float LinksetMass
+ {
+ get
+ {
+ m_mass = ComputeLinksetMass();
+ return m_mass;
+ }
+ }
+
+ public OMV.Vector3 CenterOfMass
+ {
+ get { return ComputeLinksetCenterOfMass(); }
+ }
+
+ public OMV.Vector3 GeometricCenter
+ {
+ get { return ComputeLinksetGeometricCenter(); }
+ }
+
+ public BSLinkset(BSScene scene, BSPrim parent)
+ {
+ // A simple linkset of one (no children)
+ m_scene = scene;
+ m_linksetRoot = parent;
+ m_children = new List();
+ m_mass = parent.MassRaw;
+ }
+
+ // Link to a linkset where the child knows the parent.
+ // Parent changing should not happen so do some sanity checking.
+ // We return the parent's linkset so the child can track it's membership.
+ public BSLinkset AddMeToLinkset(BSPrim child, BSPrim parent)
+ {
+ lock (m_linksetActivityLock)
+ {
+ parent.Linkset.AddChildToLinkset(child);
+ }
+ return parent.Linkset;
+ }
+
+ public BSLinkset RemoveMeFromLinkset(BSPrim child)
+ {
+ lock (m_linksetActivityLock)
+ {
+ if (IsRoot(child))
+ {
+ // if root of linkset, take the linkset apart
+ while (m_children.Count > 0)
+ {
+ // Note that we don't do a foreach because the remove routine
+ // takes it out of the list.
+ RemoveChildFromLinkset(m_children[0]);
+ }
+ m_children.Clear(); // just to make sure
+ }
+ else
+ {
+ // Just removing a child from an existing linkset
+ RemoveChildFromLinkset(child);
+ }
+ }
+
+ // The child is down to a linkset of just itself
+ return new BSLinkset(m_scene, child);
+ }
+
+ // An existing linkset had one of its members rebuilt or something.
+ // Undo all the physical linking and rebuild the physical linkset.
+ public bool RefreshLinkset(BSPrim requestor)
+ {
+ return true;
+ }
+
+
+ // Return 'true' if the passed object is the root object of this linkset
+ public bool IsRoot(BSPrim requestor)
+ {
+ return (requestor.LocalID == m_linksetRoot.LocalID);
+ }
+
+ // Return 'true' if this linkset has any children (more than the root member)
+ public bool HasAnyChildren { get { return (m_children.Count > 0); } }
+
+ // Return 'true' if this child is in this linkset
+ public bool HasChild(BSPrim child)
+ {
+ bool ret = false;
+ foreach (BSPrim bp in m_children)
+ {
+ if (child.LocalID == bp.LocalID)
+ {
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ private float ComputeLinksetMass()
+ {
+ float mass = m_linksetRoot.MassRaw;
+ foreach (BSPrim bp in m_children)
+ {
+ mass += bp.MassRaw;
+ }
+ return mass;
+ }
+
+ private OMV.Vector3 ComputeLinksetCenterOfMass()
+ {
+ OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw;
+ float totalMass = m_linksetRoot.MassRaw;
+
+ foreach (BSPrim bp in m_children)
+ {
+ com += bp.Position * bp.MassRaw;
+ totalMass += bp.MassRaw;
+ }
+ com /= totalMass;
+
+ return com;
+ }
+
+ private OMV.Vector3 ComputeLinksetGeometricCenter()
+ {
+ OMV.Vector3 com = m_linksetRoot.Position;
+
+ foreach (BSPrim bp in m_children)
+ {
+ com += bp.Position * bp.MassRaw;
+ }
+ com /= m_children.Count + 1;
+
+ return com;
+ }
+
+ // I am the root of a linkset and a new child is being added
+ public void AddChildToLinkset(BSPrim pchild)
+ {
+ BSPrim child = pchild;
+ if (!HasChild(child))
+ {
+ m_children.Add(child);
+
+ m_scene.TaintedObject(delegate()
+ {
+ DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID);
+ DetailLog("{0},AddChildToLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
+ PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child
+ });
+ }
+ return;
+ }
+
+ // I am the root of a linkset and one of my children is being removed.
+ // Safe to call even if the child is not really in my linkset.
+ public void RemoveChildFromLinkset(BSPrim pchild)
+ {
+ BSPrim child = pchild;
+
+ if (m_children.Remove(child))
+ {
+ m_scene.TaintedObject(delegate()
+ {
+ DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
+ DetailLog("{0},RemoveChildFromLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
+
+ if (m_children.Count == 0)
+ {
+ // if the linkset is empty, make sure all linkages have been removed
+ PhysicallyUnlinkAllChildrenFromRoot();
+ }
+ else
+ {
+ PhysicallyUnlinkAChildFromRoot(pchild);
+ }
+ });
+ }
+ else
+ {
+ // This will happen if we remove the root of the linkset first. Non-fatal occurance.
+ // m_scene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
+ }
+ return;
+ }
+
+ // Create a constraint between me (root of linkset) and the passed prim (the child).
+ // Called at taint time!
+ private void PhysicallyLinkAChildToRoot(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(m_linksetRoot.Orientation);
+ OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.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}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
+ BSConstraint constrain = m_scene.Constraints.CreateConstraint(
+ m_scene.World, m_linksetRoot.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(m_scene.BoolNumeric(m_scene.Params.linkConstraintUseFrameOffset));
+ constrain.TranslationalLimitMotor(m_scene.BoolNumeric(m_scene.Params.linkConstraintEnableTransMotor),
+ m_scene.Params.linkConstraintTransMotorMaxVel,
+ m_scene.Params.linkConstraintTransMotorMaxForce);
+
+ }
+
+ // Remove linkage between myself and a particular child
+ // Called at taint time!
+ private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim)
+ {
+ DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
+ LogHeader, m_linksetRoot.LocalID, childPrim.LocalID);
+ DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
+ // BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
+ m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body);
+ }
+
+ // Remove linkage between myself and any possible children I might have
+ // Called at taint time!
+ private void PhysicallyUnlinkAllChildrenFromRoot()
+ {
+ // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
+ DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID);
+ m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body);
+ // BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
+ }
+
+ // Invoke the detailed logger and output something if it's enabled.
+ private void DebugLog(string msg, params Object[] args)
+ {
+ m_scene.Logger.DebugFormat(msg, args);
+ }
+
+ // Invoke the detailed logger and output something if it's enabled.
+ private void DetailLog(string msg, params Object[] args)
+ {
+ m_scene.PhysicsLogging.Write(msg, args);
+ }
+
+}
+}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index a19d6d7f17..7590d936a4 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -66,7 +66,7 @@ public sealed class BSPrim : PhysicsActor
private bool _isSelected;
private bool _isVolumeDetect;
private OMV.Vector3 _position;
- private float _mass;
+ private float _mass; // the mass of this object
private float _density;
private OMV.Vector3 _force;
private OMV.Vector3 _velocity;
@@ -89,14 +89,22 @@ public sealed class BSPrim : PhysicsActor
private bool _kinematic;
private float _buoyancy;
- private BSPrim _parentPrim;
- private List _childrenPrims;
+ // Membership in a linkset is controlled by this class.
+ private BSLinkset _linkset;
+ public BSLinkset Linkset
+ {
+ get { return _linkset; }
+ set { _linkset = value; }
+ }
private int _subscribedEventsMs = 0;
private int _nextCollisionOkTime = 0;
long _collidingStep;
long _collidingGroundStep;
+ private BulletBody m_body;
+ public BulletBody Body { get { return m_body; } }
+
private BSDynamics _vehicle;
private OMV.Vector3 _PIDTarget;
@@ -130,14 +138,18 @@ public sealed class BSPrim : PhysicsActor
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material
_density = _scene.Params.defaultDensity; // TODO: compute based on object material
_restitution = _scene.Params.defaultRestitution;
- _parentPrim = null; // not a child or a parent
+ _linkset = new BSLinkset(_scene, this); // a linkset of one
_vehicle = new BSDynamics(this); // add vehicleness
- _childrenPrims = new List();
_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));
});
}
@@ -153,16 +165,8 @@ public sealed class BSPrim : PhysicsActor
_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 possible children depending on me
- UnlinkAllChildren();
+ // Undo any links between me and any other object
+ _linkset = _linkset.RemoveMeFromLinkset(this);
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
@@ -179,7 +183,7 @@ public sealed class BSPrim : PhysicsActor
_scene.TaintedObject(delegate()
{
_mass = CalculateMass(); // changing size changes the mass
- BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, Mass, IsPhysical);
+ BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
RecreateGeomAndObject();
});
}
@@ -218,32 +222,8 @@ public sealed class BSPrim : PhysicsActor
BSPrim parent = obj as BSPrim;
DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
DetailLog("{0},link,parent={1}", LocalID, obj.LocalID);
- // TODO: decide if this parent checking needs to happen at taint time
- if (_parentPrim == null)
- {
- if (parent != null)
- {
- // I don't have a parent so I am joining a linkset
- parent.AddChildToLinkset(this);
- }
- }
- else
- {
- // I already have a parent, is parenting changing?
- if (parent != _parentPrim)
- {
- if (parent == null)
- {
- // we are being removed from a linkset
- _parentPrim.RemoveChildFromLinkset(this);
- }
- else
- {
- // asking to reparent a prim should not happen
- m_log.ErrorFormat("{0}: link(): Reparenting a prim. ", LogHeader);
- }
- }
- }
+
+ _linkset = _linkset.AddMeToLinkset(this, parent);
return;
}
@@ -252,92 +232,28 @@ public sealed class BSPrim : PhysicsActor
// TODO: decide if this parent checking needs to happen at taint time
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen
DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
- (_parentPrim==null ? "NULL" : _parentPrim._avName+"/"+_parentPrim.LocalID.ToString()));
- DetailLog("{0},delink,parent={1}", LocalID, (_parentPrim==null ? "NULL" : _parentPrim.LocalID.ToString()));
- if (_parentPrim != null)
- {
- _parentPrim.RemoveChildFromLinkset(this);
- }
+ _linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString());
+ DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString());
+
+ _linkset.RemoveMeFromLinkset(this);
return;
}
- // I am the root of a linkset and a new child is being added
- public void AddChildToLinkset(BSPrim pchild)
- {
- BSPrim child = pchild;
- _scene.TaintedObject(delegate()
- {
- if (!_childrenPrims.Contains(child))
- {
- DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, this.LocalID);
- 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
- LinkAChildToMe(pchild); // build the physical binding between me and the child
-
- _mass = CalculateMass();
- }
- });
- return;
- }
-
- // I am the root of a linkset and one of my children is being removed.
- // Safe to call even if the child is not really in my linkset.
- public void RemoveChildFromLinkset(BSPrim pchild)
- {
- BSPrim child = pchild;
- _scene.TaintedObject(delegate()
- {
- if (_childrenPrims.Contains(child))
- {
- DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
- DetailLog("{0},RemoveChildFromLinkset,child={1}", LocalID, pchild.LocalID);
- _childrenPrims.Remove(child);
- child._parentPrim = null; // the child has lost its parent
- 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
- {
- m_log.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset");
- }
- });
- return;
- }
-
- // return true if we are the root of a linkset (there are children to manage)
- public bool IsRootOfLinkset
- {
- get { return (_parentPrim == null && _childrenPrims.Count != 0); }
- }
-
// 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()
+ public void ZeroMotion()
{
_velocity = OMV.Vector3.Zero;
_acceleration = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero;
// Zero some other properties directly into the physics engine
- IntPtr obj = BulletSimAPI.GetBodyHandleWorldID2(_scene.WorldID, LocalID);
- BulletSimAPI.SetVelocity2(obj, OMV.Vector3.Zero);
- BulletSimAPI.SetAngularVelocity2(obj, OMV.Vector3.Zero);
- BulletSimAPI.SetInterpolation2(obj, OMV.Vector3.Zero, OMV.Vector3.Zero);
- BulletSimAPI.ClearForces2(obj);
+ 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)
@@ -348,9 +264,10 @@ public sealed class BSPrim : PhysicsActor
public override OMV.Vector3 Position {
get {
- // child prims move around based on their parent. Need to get the latest location
- if (_parentPrim != null)
+ if (!_linkset.IsRoot(this))
+ // child prims move around based on their parent. Need to get the latest location
_position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
+
// don't do the GetObjectPosition for root elements because this function is called a zillion times
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
return _position;
@@ -366,16 +283,31 @@ public sealed class BSPrim : PhysicsActor
}
}
- // Return the effective mass of the object. Non-physical objects do not have mass.
- public override float Mass {
- get {
- if (IsPhysical)
- return _mass;
- else
- return 0f;
+ // Return the effective mass of the object.
+ // If there are multiple items in the linkset, add them together for the root
+ public override float Mass
+ {
+ get
+ {
+ return _linkset.LinksetMass;
}
}
+ // used when we only want this prim's mass and not the linkset thing
+ public float MassRaw { get { return _mass; } }
+
+ // Is this used?
+ public override OMV.Vector3 CenterOfMass
+ {
+ get { return _linkset.CenterOfMass; }
+ }
+
+ // Is this used?
+ public override OMV.Vector3 GeometricCenter
+ {
+ get { return _linkset.GeometricCenter; }
+ }
+
public override OMV.Vector3 Force {
get { return _force; }
set {
@@ -383,7 +315,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);
});
}
}
@@ -407,8 +340,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
@@ -420,7 +352,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);
@@ -428,7 +359,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);
@@ -436,7 +366,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);
@@ -444,7 +373,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);
@@ -470,8 +398,6 @@ public sealed class BSPrim : PhysicsActor
return;
}
- public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } }
- public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } }
public override OMV.Vector3 Velocity {
get { return _velocity; }
set {
@@ -500,9 +426,9 @@ public sealed class BSPrim : PhysicsActor
}
public override OMV.Quaternion Orientation {
get {
- if (_parentPrim != null)
+ if (!_linkset.IsRoot(this))
{
- // children move around because tied to parent. Get a fresh value.
+ // Children move around because tied to parent. Get a fresh value.
_orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID);
}
return _orientation;
@@ -552,14 +478,16 @@ public sealed class BSPrim : PhysicsActor
private void SetObjectDynamic()
{
// 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 = CalculateMass();
- RecreateGeomAndObject();
- }
- DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, Mass);
- BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), Mass);
+
+ RecreateGeomAndObject();
+
+ float mass = _mass;
+ // Bullet wants static objects have a mass of zero
+ if (IsStatic)
+ mass = 0f;
+
+ 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
@@ -1001,6 +929,9 @@ public sealed class BSPrim : PhysicsActor
returnMass = _density * volume;
+ /*
+ * This change means each object keeps its own mass and the Mass property
+ * will return the sum if we're part of a linkset.
if (IsRootOfLinkset)
{
foreach (BSPrim prim in _childrenPrims)
@@ -1008,6 +939,7 @@ public sealed class BSPrim : PhysicsActor
returnMass += prim.CalculateMass();
}
}
+ */
if (returnMass <= 0)
returnMass = 0.0001f;
@@ -1023,9 +955,11 @@ public sealed class BSPrim : PhysicsActor
// The objects needs a hull if it's physical otherwise a mesh is enough
// No locking here because this is done when we know physics is not simulating
// if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used
- private void CreateGeom(bool forceRebuild)
+ // Returns 'true' if the geometry was rebuilt
+ private bool CreateGeom(bool forceRebuild)
{
// the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
+ bool ret = false;
if (!_scene.NeedsMeshing(_pbs))
{
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
@@ -1033,18 +967,26 @@ public sealed class BSPrim : PhysicsActor
if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
{
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
- _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
- DetailLog("{0},CreateGeom,sphere", LocalID);
- // Bullet native objects are scaled by the Bullet engine so pass the size in
- _scale = _size;
+ if (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)
+ {
+ DetailLog("{0},CreateGeom,sphere", LocalID);
+ _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
+ ret = true;
+ // Bullet native objects are scaled by the Bullet engine so pass the size in
+ _scale = _size;
+ }
}
}
else
{
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size);
- DetailLog("{0},CreateGeom,box", LocalID);
- _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
- _scale = _size;
+ if (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)
+ {
+ DetailLog("{0},CreateGeom,box", LocalID);
+ _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
+ ret = true;
+ _scale = _size;
+ }
}
}
else
@@ -1056,6 +998,7 @@ public sealed class BSPrim : PhysicsActor
// physical objects require a hull for interaction.
// This will create the mesh if it doesn't already exist
CreateGeomHull();
+ ret = true;
}
}
else
@@ -1064,9 +1007,11 @@ public sealed class BSPrim : PhysicsActor
{
// Static (non-physical) objects only need a mesh for bumping into
CreateGeomMesh();
+ ret = true;
}
}
}
+ return ret;
}
// No locking here because this is done when we know physics is not simulating
@@ -1251,20 +1196,18 @@ public sealed class BSPrim : PhysicsActor
// No locking here because this is done when the physics engine is not simulating
private void CreateObject()
{
- if (IsRootOfLinkset)
- {
- // Create a linkset around this object
- CreateLinkset();
- }
- else
- {
- // simple object
- // the mesh or hull must have already been created in Bullet
- ShapeData shape;
- FillShapeInfo(out shape);
- // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
- BulletSimAPI.CreateObject(_scene.WorldID, shape);
- }
+ // this routine is called when objects are rebuilt.
+
+ // the mesh or hull must have already been created in Bullet
+ ShapeData shape;
+ FillShapeInfo(out shape);
+ // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
+ BulletSimAPI.CreateObject(_scene.WorldID, shape);
+ // the CreateObject() may have recreated the rigid body. Make sure we have the latest.
+ m_body.Ptr = BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID);
+
+ // The root object could have been recreated. Make sure everything linksety is up to date.
+ _linkset.RefreshLinkset(this);
}
// Copy prim's info into the BulletSim shape description structure
@@ -1276,7 +1219,7 @@ public sealed class BSPrim : PhysicsActor
shape.Rotation = _orientation;
shape.Velocity = _velocity;
shape.Scale = _scale;
- shape.Mass = Mass;
+ shape.Mass = _isPhysical ? _mass : 0f;
shape.Buoyancy = _buoyancy;
shape.HullKey = _hullKey;
shape.MeshKey = _meshKey;
@@ -1286,72 +1229,6 @@ 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.
- void CreateLinkset()
- {
- DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
-
- // remove any constraints that might be in place
- DebugLog("{0}: CreateLinkset: RemoveConstraints between me and any children", LogHeader, LocalID);
- BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
-
- // create constraints between the root prim and each of the children
- foreach (BSPrim prim in _childrenPrims)
- {
- 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);
- BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, childPrim.LocalID,
- childRelativePosition,
- childRelativeRotation,
- OMV.Vector3.Zero,
- OMV.Quaternion.Identity,
- OMV.Vector3.Zero, OMV.Vector3.Zero,
- OMV.Vector3.Zero, OMV.Vector3.Zero);
- }
-
- // 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);
- }
-
- // 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);
- 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.
@@ -1429,7 +1306,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 (_parentPrim == null)
+ if (_linkset.IsRoot(this))
{
// 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 7cc3fe3ca5..c6d622b621 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -73,7 +73,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS SCENE]";
- private void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); }
+ public void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); }
public string BulletSimVersion = "?";
@@ -87,6 +87,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
private uint m_worldID;
public uint WorldID { get { return m_worldID; } }
+ // let my minuions use my logger
+ public ILog Logger { get { return m_log; } }
+
private bool m_initialized = false;
private int m_detailedStatsStep = 0;
@@ -103,6 +106,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 +243,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 +256,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 +277,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
@@ -634,6 +553,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// 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();
@@ -776,10 +701,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;
@@ -853,61 +780,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.numericFalse,
+ (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;
}
@@ -919,63 +1156,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);
@@ -983,7 +1175,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);
@@ -994,7 +1186,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)
{
@@ -1021,7 +1213,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();
@@ -1036,50 +1228,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 54a8cfde27..65e3145698 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]
@@ -211,6 +239,7 @@ public static extern bool DestroyMesh(uint worldID, System.UInt64 meshKey);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool CreateObject(uint worldID, ShapeData shapeData);
+/* Remove old functionality
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas);
@@ -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);
@@ -350,8 +380,22 @@ 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,
- Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular);
+ 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);
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 32e81e2ea1..929b019ecf 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -290,7 +290,6 @@ namespace OpenSim.Region.Physics.OdePlugin
private readonly IntPtr contactgroup;
- internal IntPtr LandGeom;
internal IntPtr WaterGeom;
private float nmTerrainContactFriction = 255.0f;
@@ -489,6 +488,8 @@ namespace OpenSim.Region.Physics.OdePlugin
///
internal Object OdeLock = new Object();
+ private bool _worldInitialized = false;
+
public IMesher mesher;
private IConfigSource m_config;
@@ -875,6 +876,8 @@ namespace OpenSim.Region.Physics.OdePlugin
staticPrimspace[i, j] = IntPtr.Zero;
}
}
+
+ _worldInitialized = true;
}
// internal void waitForSpaceUnlock(IntPtr space)
@@ -1508,8 +1511,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f)
&& (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f)
- && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f))
- && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom)
+ && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)))
{
if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f)
{
@@ -1538,7 +1540,7 @@ namespace OpenSim.Region.Physics.OdePlugin
//d.GeomGetAABB(contactGeom.g2, out aabb2);
//d.GeomGetAABB(contactGeom.g1, out aabb1);
//aabb1.
- if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom)
+ if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)))
{
if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z)
{
@@ -2896,6 +2898,8 @@ namespace OpenSim.Region.Physics.OdePlugin
/// The number of frames simulated over that period.
public override float Simulate(float timeStep)
{
+ if (!_worldInitialized) return 11f;
+
int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0;
int tempTick = 0, tempTick2 = 0;
@@ -4017,6 +4021,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void Dispose()
{
+ _worldInitialized = false;
+
m_rayCastManager.Dispose();
m_rayCastManager = null;
@@ -4037,6 +4043,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.WorldDestroy(world);
//d.CloseODE();
}
+
}
public override Dictionary GetTopColliders()
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
index 204c4ff5fb..3144d76432 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
@@ -99,6 +99,8 @@ namespace OpenSim.Region.RegionCombinerModule
public void RemoveRegion(Scene scene)
{
+ lock (m_startingScenes)
+ m_startingScenes.Remove(scene.RegionInfo.originRegionID);
}
public void RegionLoaded(Scene scene)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 693992afe4..94fd940dc1 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/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index bf77dc5c1a..1181c105a1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -3290,8 +3290,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
((LSL_Api)m_LSL_Api).llSay(0, string.Format("Unable to attach, item '{0}' is not an object.", itemName));
throw new Exception(String.Format("The inventory item '{0}' is not an object", itemName));
-
- return;
}
ScenePresence sp = World.GetScenePresence(avatarId);
@@ -3336,5 +3334,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
UUID test;
return UUID.TryParse(thing, out test) ? 1 : 0;
}
+
+ ///
+ /// Wraps to Math.Min()
+ ///
+ ///
+ ///
+ ///
+ public LSL_Float osMin(double a, double b)
+ {
+ CheckThreatLevel(ThreatLevel.None, "osMin");
+ m_host.AddScriptLPS(1);
+
+ return Math.Min(a, b);
+ }
+
+ ///
+ /// Wraps to Math.max()
+ ///
+ ///
+ ///
+ ///
+ public LSL_Float osMax(double a, double b)
+ {
+ CheckThreatLevel(ThreatLevel.None, "osMax");
+ m_host.AddScriptLPS(1);
+
+ return Math.Max(a, b);
+ }
}
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 24bdf0cfc8..aba66d32b2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -283,5 +283,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
///
/// 1 if thing is a valid UUID, 0 otherwise
LSL_Integer osIsUUID(string thing);
+
+ ///
+ /// Wraps to Math.Min()
+ ///
+ ///
+ ///
+ ///
+ LSL_Float osMin(double a, double b);
+
+ ///
+ /// Wraps to Math.max()
+ ///
+ ///
+ ///
+ ///
+ LSL_Float osMax(double a, double b);
}
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 99995a7171..53daa13d49 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -935,5 +935,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{
return m_OSSL_Functions.osIsUUID(thing);
}
+
+ public LSL_Float osMin(double a, double b)
+ {
+ return m_OSSL_Functions.osMin(a, b);
+ }
+
+ public LSL_Float osMax(double a, double b)
+ {
+ return m_OSSL_Functions.osMax(a, b);
+ }
}
}
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 79a6e0951e..f6cb7dfa95 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -719,7 +719,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/bin/Ionic.Zip.dll b/bin/Ionic.Zip.dll
old mode 100644
new mode 100755
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 6d699fd505..80d17d9da1 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -914,6 +914,12 @@
ShouldEnableFrictionCaching = False;
NumberOfSolverIterations = 0;
+ ; Linkset constraint parameters
+ LinkConstraintUseFrameOffset = False;
+ LinkConstraintEnableTransMotor = True;
+ LinkConstraintTransMotorMaxVel = 5.0;
+ LinkConstraintTransMotorMaxForce = 0.1;
+
; Whether to mesh sculpties
MeshSculptedPrim = true
@@ -931,7 +937,7 @@
FixedTimeStep = .01667
MaxCollisionsPerFrame = 2048
- MaxUpdatesPerFrame = 2048
+ MaxUpdatesPerFrame = 8192
[RemoteAdmin]
enabled = false
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll
index 322322a701..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 493c8cbc84..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 2bd13b8644..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 af3a078bfe..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 52a91c3111..469ca99b95 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -112,7 +112,37 @@
+<<<<<<< HEAD:prebuild.xml
+=======
+
+
+
+ ../../../bin/
+
+
+
+
+ ../../../bin/
+
+
+
+ ../../../bin/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>>>>>>> master:prebuild.xml
../../../../bin/
@@ -130,6 +160,7 @@
+
@@ -235,6 +266,7 @@
+<<<<<<< HEAD:prebuild.xml
@@ -260,6 +292,9 @@
+=======
+
+>>>>>>> master:prebuild.xml
../../bin/
@@ -436,7 +471,7 @@
-
+
@@ -720,9 +755,9 @@
+
-
@@ -754,13 +789,13 @@
+
-
+
+
-
-
@@ -806,10 +841,10 @@
+
-
@@ -1525,10 +1560,10 @@
+
-
@@ -1616,11 +1651,11 @@
+
+
-
-
@@ -1653,15 +1688,15 @@
-
-
+
+
-
+
@@ -1744,9 +1779,9 @@
+
-
@@ -1882,15 +1917,15 @@
+
-
+
-
-
+
@@ -2403,10 +2438,11 @@
+
+
-
@@ -2529,8 +2565,12 @@
+<<<<<<< HEAD:prebuild.xml
+=======
+
+>>>>>>> master:prebuild.xml
../../../bin/
@@ -2558,9 +2598,9 @@
+
-
@@ -3044,9 +3084,9 @@
+
-
@@ -3116,9 +3156,9 @@
+
-
@@ -3175,8 +3215,8 @@
+
-
@@ -3232,9 +3272,9 @@
+
-
@@ -3269,7 +3309,7 @@
-
+
diff --git a/runprebuild.sh b/runprebuild.sh
index b3b5c9d1d3..d276edbee4 100755
--- a/runprebuild.sh
+++ b/runprebuild.sh
@@ -1,4 +1,42 @@
#!/bin/sh
-mono bin/Prebuild.exe /target nant
-mono bin/Prebuild.exe /target vs2008
+case "$1" in
+
+ 'clean')
+
+ mono bin/Prebuild.exe /clean
+
+ ;;
+
+
+ 'autoclean')
+
+ echo y|mono bin/Prebuild.exe /clean
+
+ ;;
+
+
+ 'vs2010')
+
+ mono bin/Prebuild.exe /target vs2010
+
+ ;;
+
+
+ 'vs2008')
+
+ mono bin/Prebuild.exe /target vs2008
+
+ ;;
+
+
+ *)
+
+ mono bin/Prebuild.exe /target nant
+ mono bin/Prebuild.exe /target vs2008
+
+ ;;
+
+
+esac
+