Merge branch 'master' of /home/opensim/var/repo/opensim

integration
BlueWall 2012-07-26 11:45:55 -04:00
commit 552ea11383
64 changed files with 1591 additions and 592 deletions

View File

@ -71,6 +71,14 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
bool LoginsEnabled { get; set; } bool LoginsEnabled { get; set; }
/// <summary>
/// Is this region ready for use?
/// </summary>
/// <remarks>
/// This does not mean that logins are enabled, merely that they can be.
/// </remarks>
bool Ready { get; set; }
float TimeDilation { get; } float TimeDilation { get; }
bool AllowScriptCrossings { get; } bool AllowScriptCrossings { get; }

View File

@ -28,7 +28,7 @@
using System; using System;
using System.Timers; using System.Timers;
namespace OpenSim.Framework.Statistics namespace OpenSim.Framework.Monitoring
{ {
/// <summary> /// <summary>
/// Asset service statistics collection /// Asset service statistics collection

View File

@ -31,8 +31,7 @@ using System.Text;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
namespace OpenSim.Framework.Monitoring
namespace OpenSim.Framework.Statistics
{ {
/// <summary> /// <summary>
/// Statistics which all collectors are interested in reporting /// Statistics which all collectors are interested in reporting
@ -44,14 +43,18 @@ namespace OpenSim.Framework.Statistics
StringBuilder sb = new StringBuilder(Environment.NewLine); StringBuilder sb = new StringBuilder(Environment.NewLine);
sb.Append("MEMORY STATISTICS"); sb.Append("MEMORY STATISTICS");
sb.Append(Environment.NewLine); sb.Append(Environment.NewLine);
sb.Append(
string.Format( sb.AppendFormat(
"Allocated to OpenSim objects: {0} MB\n", "Allocated to OpenSim objects: {0} MB\n",
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0))); Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
sb.Append(
string.Format( sb.AppendFormat(
"Process memory : {0} MB\n", "OpenSim object memory churn : {0} MB/s\n",
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0))); Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
sb.AppendFormat(
"Process memory : {0} MB\n",
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0));
return sb.ToString(); return sb.ToString();
} }

View File

@ -25,7 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
namespace OpenSim.Framework.Statistics.Interfaces namespace OpenSim.Framework.Monitoring.Interfaces
{ {
/// <summary> /// <summary>
/// Implemented by objects which allow statistical information to be pulled from them. /// Implemented by objects which allow statistical information to be pulled from them.

View File

@ -25,7 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
namespace OpenSim.Framework.Statistics namespace OpenSim.Framework.Monitoring
{ {
/// <summary> /// <summary>
/// Implemented by classes which collect up non-viewer statistical information /// Implemented by classes which collect up non-viewer statistical information

View File

@ -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
{
/// <summary>
/// Experimental watchdog for memory usage.
/// </summary>
public static class MemoryWatchdog
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Is this watchdog active?
/// </summary>
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;
/// <summary>
/// Average memory churn in bytes per millisecond.
/// </summary>
public static double AverageMemoryChurn
{
get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; }
}
/// <summary>
/// Maximum number of statistical samples.
/// </summary>
/// <remarks>
/// At the moment this corresponds to 1 minute since the sampling rate is every 2.5 seconds as triggered from
/// the main Watchdog.
/// </remarks>
private static int m_maxSamples = 24;
/// <summary>
/// Time when the watchdog was last updated.
/// </summary>
private static int m_lastUpdateTick;
/// <summary>
/// Memory used at time of last watchdog update.
/// </summary>
private static long m_lastUpdateMemory;
/// <summary>
/// Memory churn rate per millisecond.
/// </summary>
private static double m_churnRatePerMillisecond;
/// <summary>
/// Historical samples for calculating moving average.
/// </summary>
private static Queue<double> m_samples = new Queue<double>(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;
}
}
}

View File

@ -28,12 +28,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework.Statistics.Interfaces;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework.Monitoring.Interfaces;
namespace OpenSim.Framework.Statistics namespace OpenSim.Framework.Monitoring
{ {
/// <summary> /// <summary>
/// Collects sim statistics which aren't already being collected for the linden viewer's statistics pane /// Collects sim statistics which aren't already being collected for the linden viewer's statistics pane

View File

@ -25,7 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
namespace OpenSim.Framework.Statistics namespace OpenSim.Framework.Monitoring
{ {
/// <summary> /// <summary>
/// Singleton used to provide access to statistics reporters /// Singleton used to provide access to statistics reporters

View File

@ -27,7 +27,7 @@
using System.Timers; using System.Timers;
namespace OpenSim.Framework.Statistics namespace OpenSim.Framework.Monitoring
{ {
/// <summary> /// <summary>
/// Collects user service statistics /// Collects user service statistics

View File

@ -31,7 +31,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using log4net; using log4net;
namespace OpenSim.Framework namespace OpenSim.Framework.Monitoring
{ {
/// <summary> /// <summary>
/// Manages launching threads and keeping watch over them for timeouts /// Manages launching threads and keeping watch over them for timeouts
@ -325,6 +325,9 @@ namespace OpenSim.Framework
callback(callbackInfo); callback(callbackInfo);
} }
if (MemoryWatchdog.Enabled)
MemoryWatchdog.Update();
m_watchdogTimer.Start(); m_watchdogTimer.Start();
} }
} }

View File

@ -40,9 +40,10 @@ using log4net.Core;
using log4net.Repository; using log4net.Repository;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using Timer=System.Timers.Timer; using Timer=System.Timers.Timer;
using OpenMetaverse; using OpenMetaverse;

View File

@ -45,6 +45,7 @@ using OpenMetaverse.StructuredData;
using CoolHTTPListener = HttpServer.HttpListener; using CoolHTTPListener = HttpServer.HttpListener;
using HttpListener=System.Net.HttpListener; using HttpListener=System.Net.HttpListener;
using LogPrio=HttpServer.LogPrio; using LogPrio=HttpServer.LogPrio;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer namespace OpenSim.Framework.Servers.HttpServer
{ {

View File

@ -32,6 +32,7 @@ using System.Reflection;
using log4net; using log4net;
using HttpServer; using HttpServer;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer namespace OpenSim.Framework.Servers.HttpServer
{ {

View File

@ -34,6 +34,7 @@ using HttpServer;
using OpenMetaverse; using OpenMetaverse;
using System.Reflection; using System.Reflection;
using log4net; using log4net;
using OpenSim.Framework.Monitoring;
namespace OpenSim.Framework.Servers.HttpServer namespace OpenSim.Framework.Servers.HttpServer
{ {

View File

@ -40,7 +40,7 @@ using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
@ -200,9 +200,9 @@ namespace OpenSim
PrintFileToConsole("startuplogo.txt"); PrintFileToConsole("startuplogo.txt");
// For now, start at the 'root' level by default // 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", ChangeSelectedRegion("region",
new string[] {"change", "region", m_sceneManager.Scenes[0].RegionInfo.RegionName}); new string[] {"change", "region", SceneManager.Scenes[0].RegionInfo.RegionName});
else else
ChangeSelectedRegion("region", new string[] {"change", "region", "root"}); ChangeSelectedRegion("region", new string[] {"change", "region", "root"});
@ -461,7 +461,7 @@ namespace OpenSim
if (cmdparams.Length > 4) if (cmdparams.Length > 4)
alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, 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) foreach (ScenePresence presence in agents)
{ {
@ -542,7 +542,7 @@ namespace OpenSim
private void HandleForceUpdate(string module, string[] args) private void HandleForceUpdate(string module, string[] args)
{ {
MainConsole.Instance.Output("Updating all clients"); MainConsole.Instance.Output("Updating all clients");
m_sceneManager.ForceCurrentSceneClientUpdate(); SceneManager.ForceCurrentSceneClientUpdate();
} }
/// <summary> /// <summary>
@ -554,7 +554,7 @@ namespace OpenSim
{ {
if (args.Length == 6) if (args.Length == 6)
{ {
m_sceneManager.HandleEditCommandOnCurrentScene(args); SceneManager.HandleEditCommandOnCurrentScene(args);
} }
else else
{ {
@ -765,7 +765,7 @@ namespace OpenSim
case "load": case "load":
if (cmdparams.Length > 1) 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])); MainConsole.Instance.Output(String.Format("Loading module: {0}", cmdparams[1]));
m_moduleLoader.LoadRegionModules(cmdparams[1], s); m_moduleLoader.LoadRegionModules(cmdparams[1], s);
@ -803,14 +803,14 @@ namespace OpenSim
case "backup": case "backup":
MainConsole.Instance.Output("Triggering save of pending object updates to persistent store"); MainConsole.Instance.Output("Triggering save of pending object updates to persistent store");
m_sceneManager.BackupCurrentScene(); SceneManager.BackupCurrentScene();
break; break;
case "remove-region": case "remove-region":
string regRemoveName = CombineParams(cmdparams, 0); string regRemoveName = CombineParams(cmdparams, 0);
Scene removeScene; Scene removeScene;
if (m_sceneManager.TryGetScene(regRemoveName, out removeScene)) if (SceneManager.TryGetScene(regRemoveName, out removeScene))
RemoveRegion(removeScene, false); RemoveRegion(removeScene, false);
else else
MainConsole.Instance.Output("No region with that name"); MainConsole.Instance.Output("No region with that name");
@ -820,14 +820,14 @@ namespace OpenSim
string regDeleteName = CombineParams(cmdparams, 0); string regDeleteName = CombineParams(cmdparams, 0);
Scene killScene; Scene killScene;
if (m_sceneManager.TryGetScene(regDeleteName, out killScene)) if (SceneManager.TryGetScene(regDeleteName, out killScene))
RemoveRegion(killScene, true); RemoveRegion(killScene, true);
else else
MainConsole.Instance.Output("no region with that name"); MainConsole.Instance.Output("no region with that name");
break; break;
case "restart": case "restart":
m_sceneManager.RestartCurrentScene(); SceneManager.RestartCurrentScene();
break; break;
} }
} }
@ -842,7 +842,7 @@ namespace OpenSim
{ {
string newRegionName = CombineParams(cmdparams, 2); 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)); MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName));
} }
else else
@ -850,7 +850,7 @@ namespace OpenSim
MainConsole.Instance.Output("Usage: change region <region name>"); MainConsole.Instance.Output("Usage: change region <region name>");
} }
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)); MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName));
// m_log.DebugFormat("Original prompt is {0}", m_consolePrompt); // m_log.DebugFormat("Original prompt is {0}", m_consolePrompt);
@ -868,7 +868,7 @@ namespace OpenSim
}); });
m_console.DefaultPrompt = prompt; m_console.DefaultPrompt = prompt;
m_console.ConsoleScene = m_sceneManager.CurrentScene; m_console.ConsoleScene = SceneManager.CurrentScene;
} }
/// <summary> /// <summary>
@ -892,7 +892,7 @@ namespace OpenSim
int newDebug; int newDebug;
if (int.TryParse(args[2], out 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. // We provide user information elsewhere if any clients had their debug level set.
// MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug); // MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug);
} }
@ -907,7 +907,7 @@ namespace OpenSim
case "scene": case "scene":
if (args.Length == 4) if (args.Length == 4)
{ {
if (m_sceneManager.CurrentScene == null) if (SceneManager.CurrentScene == null)
{ {
MainConsole.Instance.Output("Please use 'change region <regioname>' first"); MainConsole.Instance.Output("Please use 'change region <regioname>' first");
} }
@ -915,7 +915,7 @@ namespace OpenSim
{ {
string key = args[2]; string key = args[2];
string value = args[3]; string value = args[3];
m_sceneManager.CurrentScene.SetSceneCoreDebug( SceneManager.CurrentScene.SetSceneCoreDebug(
new Dictionary<string, string>() { { key, value } }); new Dictionary<string, string>() { { key, value } });
MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value); MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value);
@ -954,10 +954,10 @@ namespace OpenSim
IList agents; IList agents;
if (showParams.Length > 1 && showParams[1] == "full") if (showParams.Length > 1 && showParams[1] == "full")
{ {
agents = m_sceneManager.GetCurrentScenePresences(); agents = SceneManager.GetCurrentScenePresences();
} else } else
{ {
agents = m_sceneManager.GetCurrentSceneAvatars(); agents = SceneManager.GetCurrentSceneAvatars();
} }
MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count)); MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count));
@ -1037,7 +1037,7 @@ namespace OpenSim
MainConsole.Instance.Output("Shared Module: " + module.Name); MainConsole.Instance.Output("Shared Module: " + module.Name);
} }
m_sceneManager.ForEachScene( SceneManager.ForEachScene(
delegate(Scene scene) { delegate(Scene scene) {
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:"); m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
foreach (IRegionModule module in scene.Modules.Values) foreach (IRegionModule module in scene.Modules.Values)
@ -1050,7 +1050,7 @@ namespace OpenSim
} }
); );
m_sceneManager.ForEachScene( SceneManager.ForEachScene(
delegate(Scene scene) { delegate(Scene scene) {
MainConsole.Instance.Output("Loaded new region modules in" + scene.RegionInfo.RegionName + " are:"); MainConsole.Instance.Output("Loaded new region modules in" + scene.RegionInfo.RegionName + " are:");
foreach (IRegionModuleBase module in scene.RegionModules.Values) foreach (IRegionModuleBase module in scene.RegionModules.Values)
@ -1066,7 +1066,7 @@ namespace OpenSim
break; break;
case "regions": case "regions":
m_sceneManager.ForEachScene( SceneManager.ForEachScene(
delegate(Scene scene) delegate(Scene scene)
{ {
MainConsole.Instance.Output(String.Format( MainConsole.Instance.Output(String.Format(
@ -1080,7 +1080,7 @@ namespace OpenSim
break; break;
case "ratings": case "ratings":
m_sceneManager.ForEachScene( SceneManager.ForEachScene(
delegate(Scene scene) delegate(Scene scene)
{ {
string rating = ""; string rating = "";
@ -1115,7 +1115,7 @@ namespace OpenSim
cdt.AddColumn("IP", 16); cdt.AddColumn("IP", 16);
cdt.AddColumn("Viewer Name", 24); cdt.AddColumn("Viewer Name", 24);
m_sceneManager.ForEachScene( SceneManager.ForEachScene(
s => s =>
{ {
foreach (AgentCircuitData aCircuit in s.AuthenticateHandler.GetAgentCircuits().Values) foreach (AgentCircuitData aCircuit in s.AuthenticateHandler.GetAgentCircuits().Values)
@ -1140,7 +1140,7 @@ namespace OpenSim
cdt.AddColumn("Endpoint", 23); cdt.AddColumn("Endpoint", 23);
cdt.AddColumn("Active?", 7); cdt.AddColumn("Active?", 7);
m_sceneManager.ForEachScene( SceneManager.ForEachScene(
s => s.ForEachClient( s => s.ForEachClient(
c => cdt.AddRow( c => cdt.AddRow(
s.Name, s.Name,
@ -1161,11 +1161,11 @@ namespace OpenSim
{ {
if (cmdparams.Length > 5) if (cmdparams.Length > 5)
{ {
m_sceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]); SceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]);
} }
else 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) if (cmdparams.Length > 0)
{ {
m_sceneManager.SaveCurrentSceneToXml(cmdparams[2]); SceneManager.SaveCurrentSceneToXml(cmdparams[2]);
} }
else 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 <X,Y,Z> = <{0},{1},{2}>",loadOffset.X,loadOffset.Y,loadOffset.Z)); MainConsole.Instance.Output(String.Format("loadOffsets <X,Y,Z> = <{0},{1},{2}>",loadOffset.X,loadOffset.Y,loadOffset.Z));
} }
} }
m_sceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset); SceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset);
} }
else else
{ {
try try
{ {
m_sceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset); SceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset);
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
@ -1244,11 +1244,11 @@ namespace OpenSim
{ {
if (cmdparams.Length > 2) if (cmdparams.Length > 2)
{ {
m_sceneManager.SaveCurrentSceneToXml2(cmdparams[2]); SceneManager.SaveCurrentSceneToXml2(cmdparams[2]);
} }
else else
{ {
m_sceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME); SceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME);
} }
} }
@ -1263,7 +1263,7 @@ namespace OpenSim
{ {
try try
{ {
m_sceneManager.LoadCurrentSceneFromXml2(cmdparams[2]); SceneManager.LoadCurrentSceneFromXml2(cmdparams[2]);
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
@ -1274,7 +1274,7 @@ namespace OpenSim
{ {
try try
{ {
m_sceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME); SceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME);
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
@ -1291,7 +1291,7 @@ namespace OpenSim
{ {
try try
{ {
m_sceneManager.LoadArchiveToCurrentScene(cmdparams); SceneManager.LoadArchiveToCurrentScene(cmdparams);
} }
catch (Exception e) catch (Exception e)
{ {
@ -1305,7 +1305,7 @@ namespace OpenSim
/// <param name="cmdparams"></param> /// <param name="cmdparams"></param>
protected void SaveOar(string module, string[] cmdparams) protected void SaveOar(string module, string[] cmdparams)
{ {
m_sceneManager.SaveCurrentSceneToArchive(cmdparams); SceneManager.SaveCurrentSceneToArchive(cmdparams);
} }
private static string CombineParams(string[] commandParams, int pos) private static string CombineParams(string[] commandParams, int pos)

View File

@ -40,7 +40,7 @@ using OpenSim.Framework.Communications;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack; using OpenSim.Region.ClientStack;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts; using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts;
using OpenSim.Region.Framework; using OpenSim.Region.Framework;
@ -285,7 +285,7 @@ namespace OpenSim
private void HandleCommanderCommand(string module, string[] cmd) private void HandleCommanderCommand(string module, string[] cmd)
{ {
m_sceneManager.SendCommandToPluginModules(cmd); SceneManager.SendCommandToPluginModules(cmd);
} }
private void HandleCommanderHelp(string module, string[] cmd) private void HandleCommanderHelp(string module, string[] cmd)
@ -303,7 +303,10 @@ namespace OpenSim
// Called from base.StartUp() // Called from base.StartUp()
m_httpServerPort = m_networkServersInfo.HttpListenerPort; 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;
} }
/// <summary> /// <summary>
@ -412,7 +415,7 @@ namespace OpenSim
// scripting engines. // scripting engines.
scene.CreateScriptInstances(); scene.CreateScriptInstances();
m_sceneManager.Add(scene); SceneManager.Add(scene);
if (m_autoCreateClientStack) if (m_autoCreateClientStack)
{ {
@ -432,7 +435,6 @@ namespace OpenSim
mscene = scene; mscene = scene;
scene.Start(); scene.Start();
scene.StartScripts(); scene.StartScripts();
return clientServer; return clientServer;
@ -561,14 +563,14 @@ namespace OpenSim
{ {
// only need to check this if we are not at the // only need to check this if we are not at the
// root level // root level
if ((m_sceneManager.CurrentScene != null) && if ((SceneManager.CurrentScene != null) &&
(m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID)) (SceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
{ {
m_sceneManager.TrySetCurrentScene(".."); SceneManager.TrySetCurrentScene("..");
} }
scene.DeleteAllSceneObjects(); scene.DeleteAllSceneObjects();
m_sceneManager.CloseScene(scene); SceneManager.CloseScene(scene);
ShutdownClientServer(scene.RegionInfo); ShutdownClientServer(scene.RegionInfo);
if (!cleanup) if (!cleanup)
@ -610,7 +612,7 @@ namespace OpenSim
public void RemoveRegion(string name, bool cleanUp) public void RemoveRegion(string name, bool cleanUp)
{ {
Scene target; Scene target;
if (m_sceneManager.TryGetScene(name, out target)) if (SceneManager.TryGetScene(name, out target))
RemoveRegion(target, cleanUp); RemoveRegion(target, cleanUp);
} }
@ -623,13 +625,13 @@ namespace OpenSim
{ {
// only need to check this if we are not at the // only need to check this if we are not at the
// root level // root level
if ((m_sceneManager.CurrentScene != null) && if ((SceneManager.CurrentScene != null) &&
(m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID)) (SceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
{ {
m_sceneManager.TrySetCurrentScene(".."); SceneManager.TrySetCurrentScene("..");
} }
m_sceneManager.CloseScene(scene); SceneManager.CloseScene(scene);
ShutdownClientServer(scene.RegionInfo); ShutdownClientServer(scene.RegionInfo);
} }
@ -641,7 +643,7 @@ namespace OpenSim
public void CloseRegion(string name) public void CloseRegion(string name)
{ {
Scene target; Scene target;
if (m_sceneManager.TryGetScene(name, out target)) if (SceneManager.TryGetScene(name, out target))
CloseRegion(target); CloseRegion(target);
} }
@ -897,7 +899,7 @@ namespace OpenSim
try try
{ {
m_sceneManager.Close(); SceneManager.Close();
} }
catch (Exception e) catch (Exception e)
{ {
@ -922,7 +924,7 @@ namespace OpenSim
/// <param name="usernum">The first out parameter describing the number of all the avatars in the Region server</param> /// <param name="usernum">The first out parameter describing the number of all the avatars in the Region server</param>
public void GetAvatarNumber(out int usernum) public void GetAvatarNumber(out int usernum)
{ {
usernum = m_sceneManager.GetCurrentSceneAvatars().Count; usernum = SceneManager.GetCurrentSceneAvatars().Count;
} }
/// <summary> /// <summary>
@ -931,7 +933,7 @@ namespace OpenSim
/// <param name="regionnum">The first out parameter describing the number of regions</param> /// <param name="regionnum">The first out parameter describing the number of regions</param>
public void GetRegionNumber(out int regionnum) public void GetRegionNumber(out int regionnum)
{ {
regionnum = m_sceneManager.Scenes.Count; regionnum = SceneManager.Scenes.Count;
} }
/// <summary> /// <summary>

View File

@ -41,7 +41,7 @@ using OpenMetaverse.Messages.Linden;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Client; using OpenSim.Framework.Client;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;

View File

@ -278,7 +278,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public string GetStats() public string GetStats()
{ {
return string.Format( return string.Format(
"{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}", "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7} {12,7}",
Util.EnvironmentTickCountSubtract(TickLastPacketReceived),
PacketsReceived, PacketsReceived,
PacketsSent, PacketsSent,
PacketsResent, PacketsResent,

View File

@ -37,7 +37,7 @@ using log4net;
using Nini.Config; using Nini.Config;
using OpenMetaverse.Packets; using OpenMetaverse.Packets;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenMetaverse; using OpenMetaverse;

View File

@ -53,9 +53,8 @@ namespace OpenSim.Region.ClientStack
protected ISimulationDataService m_simulationDataService; protected ISimulationDataService m_simulationDataService;
protected IEstateDataService m_estateDataService; protected IEstateDataService m_estateDataService;
protected ClientStackManager m_clientStackManager; 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 NetworkServersInfo NetServersInfo { get { return m_networkServersInfo; } }
public ISimulationDataService SimulationDataService { get { return m_simulationDataService; } } public ISimulationDataService SimulationDataService { get { return m_simulationDataService; } }
public IEstateDataService EstateDataService { get { return m_estateDataService; } } public IEstateDataService EstateDataService { get { return m_estateDataService; } }
@ -77,6 +76,7 @@ namespace OpenSim.Region.ClientStack
protected override void StartupSpecific() protected override void StartupSpecific()
{ {
SceneManager = new SceneManager();
m_clientStackManager = CreateClientStackManager(); m_clientStackManager = CreateClientStackManager();
Initialize(); Initialize();

View File

@ -28,6 +28,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.IO;
using System.Xml;
using log4net; using log4net;
using Mono.Addins; using Mono.Addins;
using Nini.Config; using Nini.Config;
@ -202,7 +204,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
} }
} }
public void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted) public void DeRezAttachments(IScenePresence sp)
{ {
if (!Enabled) if (!Enabled)
return; return;
@ -213,18 +215,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{ {
foreach (SceneObjectGroup so in sp.GetAttachments()) foreach (SceneObjectGroup so in sp.GetAttachments())
{ {
// We can only remove the script instances from the script engine after we've retrieved their xml state UpdateDetachedObject(sp, so);
// when we update the attachment item.
m_scene.DeleteSceneObject(so, false, false);
if (saveChanged || saveAllScripted)
{
so.IsAttachment = false;
so.AbsolutePosition = so.RootPart.AttachedPos;
UpdateKnownItem(sp, so, saveAllScripted);
}
so.RemoveScriptInstances(true);
} }
sp.ClearAttachments(); sp.ClearAttachments();
@ -528,7 +519,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// <param name="sp"></param> /// <param name="sp"></param>
/// <param name="grp"></param> /// <param name="grp"></param>
/// <param name="saveAllScripted"></param> /// <param name="saveAllScripted"></param>
private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted) private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, string scriptedState)
{ {
// Saving attachments for NPCs messes them up for the real owner! // Saving attachments for NPCs messes them up for the real owner!
INPCModule module = m_scene.RequestModuleInterface<INPCModule>(); INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
@ -538,13 +529,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return; return;
} }
if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts())) if (grp.HasGroupChanged)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", // "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
// grp.UUID, grp.AttachmentPoint); // grp.UUID, grp.AttachmentPoint);
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState);
InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID); InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID);
item = m_scene.InventoryService.GetItem(item); item = m_scene.InventoryService.GetItem(item);
@ -683,6 +674,60 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return newItem; return newItem;
} }
private string GetObjectScriptStates(SceneObjectGroup grp)
{
using (StringWriter sw = new StringWriter())
{
using (XmlTextWriter writer = new XmlTextWriter(sw))
{
grp.SaveScriptedState(writer);
}
return sw.ToString();
}
}
private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so)
{
// Don't save attachments for HG visitors, it
// messes up their inventory. When a HG visitor logs
// out on a foreign grid, their attachments will be
// reloaded in the state they were in when they left
// the home grid. This is best anyway as the visited
// grid may use an incompatible script engine.
bool saveChanged
= sp.PresenceType != PresenceType.Npc
&& (m_scene.UserManagementModule == null
|| m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
// Scripts MUST be snapshotted before the object is
// removed from the scene because doing otherwise will
// clobber the run flag
string scriptedState = GetObjectScriptStates(so);
// Remove the object from the scene so no more updates
// are sent. Doing this before the below changes will ensure
// updates can't cause "HUD artefacts"
m_scene.DeleteSceneObject(so, false, false);
// Prepare sog for storage
so.AttachedAvatar = UUID.Zero;
so.RootPart.SetParentLocalId(0);
so.IsAttachment = false;
if (saveChanged)
{
// We cannot use AbsolutePosition here because that would
// attempt to cross the prim as it is detached
so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; });
UpdateKnownItem(sp, so, scriptedState);
}
// Now, remove the scripts
so.RemoveScriptInstances(true);
}
private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so)
{ {
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
@ -690,22 +735,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
sp.RemoveAttachment(so); sp.RemoveAttachment(so);
// Prepare sog for storage UpdateDetachedObject(sp, so);
so.AttachedAvatar = UUID.Zero;
so.RootPart.SetParentLocalId(0);
so.IsAttachment = false;
// We cannot use AbsolutePosition here because that would
// attempt to cross the prim as it is detached
so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; });
UpdateKnownItem(sp, so, true);
// This MUST happen AFTER serialization because it will
// either stop or remove the scripts. Both will cause scripts
// to be serialized in a stopped state with the true run
// state already lost.
m_scene.DeleteSceneObject(so, false, true);
} }
private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(

View File

@ -47,6 +47,7 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.XEngine; using OpenSim.Region.ScriptEngine.XEngine;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
@ -289,21 +290,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
Scene scene = CreateTestScene(); Scene scene = CreateScriptingEnabledTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10); SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
TaskInventoryHelpers.AddScript(scene, so.RootPart); TaskInventoryItem scriptItem
= TaskInventoryHelpers.AddScript(
scene,
so.RootPart,
"scriptItem",
"default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000); InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
// FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
// In the future, we need to be able to do this programatically more predicably.
scene.EventManager.OnChatFromWorld += OnChatFromWorld;
scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
m_chatEvent.WaitOne(60000);
// TODO: Need to have a test that checks the script is actually started but this involves a lot more // TODO: Need to have a test that checks the script is actually started but this involves a lot more
// plumbing of the script engine and either pausing for events or more infrastructure to turn off various // plumbing of the script engine and either pausing for events or more infrastructure to turn off various
// script engine delays/asychronicity that isn't helpful in an automated regression testing context. // script engine delays/asychronicity that isn't helpful in an automated regression testing context.
SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.Name); SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.Name);
Assert.That(attSo.ContainsScripts(), Is.True); Assert.That(attSo.ContainsScripts(), Is.True);
TaskInventoryItem reRezzedScriptItem = attSo.RootPart.Inventory.GetInventoryItem(scriptItem.Name);
IScriptModule xengine = scene.RequestModuleInterface<IScriptModule>();
Assert.That(xengine.GetScriptState(reRezzedScriptItem.ItemID), Is.True);
} }
[Test] [Test]
@ -379,29 +396,49 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10); SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
TaskInventoryHelpers.AddScript(scene, so.RootPart); TaskInventoryItem scriptTaskItem
= TaskInventoryHelpers.AddScript(
scene,
so.RootPart,
"scriptItem",
"default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000); InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
// FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running. // FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
// In the future, we need to be able to do this programatically more predicably. // In the future, we need to be able to do this programatically more predicably.
scene.EventManager.OnChatFromWorld += OnChatFromWorld; scene.EventManager.OnChatFromWorld += OnChatFromWorld;
SceneObjectGroup soRezzed SceneObjectGroup rezzedSo
= scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
// Wait for chat to signal rezzed script has been started. // Wait for chat to signal rezzed script has been started.
m_chatEvent.WaitOne(60000); m_chatEvent.WaitOne(60000);
scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, soRezzed); scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, rezzedSo);
InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem); InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem);
AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString()); AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString());
// TODO: It would probably be better here to check script state via the saving and retrieval of state
// information at a higher level, rather than having to inspect the serialization.
XmlDocument soXml = new XmlDocument(); XmlDocument soXml = new XmlDocument();
soXml.LoadXml(Encoding.UTF8.GetString(asset.Data)); soXml.LoadXml(Encoding.UTF8.GetString(asset.Data));
XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState"); XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState");
Assert.That(scriptStateNodes.Count, Is.EqualTo(1)); Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
// Re-rez the attachment to check script running state
SceneObjectGroup reRezzedSo = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
// Wait for chat to signal rezzed script has been started.
m_chatEvent.WaitOne(60000);
TaskInventoryItem reRezzedScriptItem = reRezzedSo.RootPart.Inventory.GetInventoryItem(scriptTaskItem.Name);
IScriptModule xengine = scene.RequestModuleInterface<IScriptModule>();
Assert.That(xengine.GetScriptState(reRezzedScriptItem.ItemID), Is.True);
// Console.WriteLine(soXml.OuterXml);
} }
/// <summary> /// <summary>

View File

@ -37,7 +37,7 @@ using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;

View File

@ -40,6 +40,7 @@ using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Capabilities; using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;

View File

@ -31,7 +31,7 @@ using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using Nini.Config; using Nini.Config;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Services.Connectors; using OpenSim.Services.Connectors;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;

View File

@ -128,11 +128,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
m_enabled = true; m_enabled = true;
} }
///<summary>
///
///</summary>
///<summary> ///<summary>
/// ///
///</summary> ///</summary>
@ -146,7 +141,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
lock (m_scenes) lock (m_scenes)
m_scenes[scene.RegionInfo.RegionID] = scene; m_scenes[scene.RegionInfo.RegionID] = scene;
scene.EventManager.OnRegionReady += s => UploadMapTile(s); scene.EventManager.OnRegionReadyStatusChange += s => { if (s.Ready) UploadMapTile(s); };
} }
///<summary> ///<summary>

View File

@ -37,7 +37,7 @@ using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;

View File

@ -37,7 +37,7 @@ using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;

View File

@ -42,6 +42,7 @@ using OpenMetaverse.Imaging;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Capabilities; using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Monitoring;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;

View File

@ -65,7 +65,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="sp">The presence closing</param> /// <param name="sp">The presence closing</param>
/// <param name="saveChanged">Save changed attachments.</param> /// <param name="saveChanged">Save changed attachments.</param>
/// <param name="saveAllScripted">Save attachments with scripts even if they haven't changed.</para> /// <param name="saveAllScripted">Save attachments with scripts even if they haven't changed.</para>
void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted); void DeRezAttachments(IScenePresence sp);
/// <summary> /// <summary>
/// Delete all the presence's attachments from the scene /// Delete all the presence's attachments from the scene

View File

@ -40,6 +40,8 @@ namespace OpenSim.Region.Framework.Interfaces
/// </remarks> /// </remarks>
public interface IScenePresence : ISceneAgent public interface IScenePresence : ISceneAgent
{ {
PresenceType PresenceType { get; }
/// <summary> /// <summary>
/// Copy of the script states while the agent is in transit. This state may /// Copy of the script states while the agent is in transit. This state may
/// need to be placed back in case of transfer fail. /// need to be placed back in case of transfer fail.
@ -83,4 +85,4 @@ namespace OpenSim.Region.Framework.Interfaces
void RemoveAttachment(SceneObjectGroup gobj); void RemoveAttachment(SceneObjectGroup gobj);
void ClearAttachments(); void ClearAttachments();
} }
} }

View File

@ -513,8 +513,7 @@ namespace OpenSim.Region.Framework.Scenes
/// A region is considered ready when startup operations such as loading of scripts already on the region /// A region is considered ready when startup operations such as loading of scripts already on the region
/// have been completed. /// have been completed.
/// </remarks> /// </remarks>
public event RegionReady OnRegionReady; public event Action<IScene> OnRegionReadyStatusChange;
public delegate void RegionReady(IScene scene);
public delegate void PrimsLoaded(Scene s); public delegate void PrimsLoaded(Scene s);
public event PrimsLoaded OnPrimsLoaded; public event PrimsLoaded OnPrimsLoaded;
@ -2508,13 +2507,13 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void TriggerRegionReady(IScene scene) public void TriggerRegionReadyStatusChange(IScene scene)
{ {
RegionReady handler = OnRegionReady; Action<IScene> handler = OnRegionReadyStatusChange;
if (handler != null) if (handler != null)
{ {
foreach (RegionReady d in handler.GetInvocationList()) foreach (Action<IScene> d in handler.GetInvocationList())
{ {
try try
{ {
@ -2522,7 +2521,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
catch (Exception e) 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); e.Message, e.StackTrace);
} }
} }

View File

@ -39,7 +39,7 @@ using OpenSim.Framework.Communications;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework; using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;

View File

@ -40,6 +40,7 @@ using OpenMetaverse;
using OpenMetaverse.Packets; using OpenMetaverse.Packets;
using OpenMetaverse.Imaging; using OpenMetaverse.Imaging;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Framework.Communications; using OpenSim.Framework.Communications;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
@ -1499,8 +1500,8 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGridService.InformNeighborsThatRegionisUp( m_sceneGridService.InformNeighborsThatRegionisUp(
RequestModuleInterface<INeighbourService>(), RegionInfo); RequestModuleInterface<INeighbourService>(), RegionInfo);
// Region ready should always be triggered whether logins are immediately enabled or not. // Region ready should always be set
EventManager.TriggerRegionReady(this); Ready = true;
} }
else else
{ {
@ -3297,17 +3298,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (AttachmentsModule != null) if (AttachmentsModule != null)
{ {
// Don't save attachments for HG visitors, it AttachmentsModule.DeRezAttachments(avatar);
// messes up their inventory. When a HG visitor logs
// out on a foreign grid, their attachments will be
// reloaded in the state they were in when they left
// the home grid. This is best anyway as the visited
// grid may use an incompatible script engine.
bool saveChanged
= avatar.PresenceType != PresenceType.Npc
&& (UserManagementModule == null || UserManagementModule.IsLocalGridUser(avatar.UUID));
AttachmentsModule.DeRezAttachments(avatar, saveChanged, false);
} }
ForEachClient( ForEachClient(

View File

@ -124,6 +124,24 @@ namespace OpenSim.Region.Framework.Scenes
} }
private bool m_loginsEnabled; 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 public float TimeDilation
{ {
get { return 1.0f; } get { return 1.0f; }

View File

@ -47,6 +47,48 @@ namespace OpenSim.Region.Framework.Scenes
public event RestartSim OnRestartSim; public event RestartSim OnRestartSim;
/// <summary>
/// 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.
/// </summary>
public event Action<SceneManager> OnRegionsReadyStatusChange;
/// <summary>
/// Are all regions ready for use?
/// </summary>
public bool AllRegionsReady
{
get
{
return m_allRegionsReady;
}
private set
{
if (m_allRegionsReady != value)
{
m_allRegionsReady = value;
Action<SceneManager> handler = OnRegionsReadyStatusChange;
if (handler != null)
{
foreach (Action<SceneManager> 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; private static SceneManager m_instance = null;
public static SceneManager Instance public static SceneManager Instance
{ {
@ -141,10 +183,11 @@ namespace OpenSim.Region.Framework.Scenes
public void Add(Scene scene) public void Add(Scene scene)
{ {
scene.OnRestart += HandleRestart;
lock (m_localScenes) lock (m_localScenes)
m_localScenes.Add(scene); m_localScenes.Add(scene);
scene.OnRestart += HandleRestart;
scene.EventManager.OnRegionReadyStatusChange += HandleRegionReadyStatusChange;
} }
public void HandleRestart(RegionInfo rdata) public void HandleRestart(RegionInfo rdata)
@ -175,6 +218,12 @@ namespace OpenSim.Region.Framework.Scenes
OnRestartSim(rdata); OnRestartSim(rdata);
} }
private void HandleRegionReadyStatusChange(IScene scene)
{
lock (m_localScenes)
AllRegionsReady = m_localScenes.TrueForAll(s => s.Ready);
}
public void SendSimOnlineNotification(ulong regionHandle) public void SendSimOnlineNotification(ulong regionHandle)
{ {
RegionInfo Result = null; RegionInfo Result = null;

View File

@ -151,6 +151,24 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
ToOriginalXmlFormat(sceneObject, writer, doScriptStates, false); ToOriginalXmlFormat(sceneObject, writer, doScriptStates, false);
} }
public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject, string scriptedState)
{
using (StringWriter sw = new StringWriter())
{
using (XmlTextWriter writer = new XmlTextWriter(sw))
{
writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
ToOriginalXmlFormat(sceneObject, writer, false, true);
writer.WriteRaw(scriptedState);
writer.WriteEndElement();
}
return sw.ToString();
}
}
/// <summary> /// <summary>
/// Serialize a scene object to the original xml format /// Serialize a scene object to the original xml format
/// </summary> /// </summary>

View File

@ -30,7 +30,7 @@ using System.Collections.Generic;
using System.Timers; using System.Timers;
using OpenMetaverse.Packets; using OpenMetaverse.Packets;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
namespace OpenSim.Region.Framework.Scenes namespace OpenSim.Region.Framework.Scenes

View File

@ -38,6 +38,7 @@ using OpenMetaverse;
using OpenMetaverse.Packets; using OpenMetaverse.Packets;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Client; using OpenSim.Framework.Client;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server

View File

@ -34,6 +34,7 @@ using System.Text;
using System.Threading; using System.Threading;
using log4net; using log4net;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server

View File

@ -35,7 +35,7 @@ using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
@ -81,18 +81,6 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
lock (m_scenes) lock (m_scenes)
m_scenes[scene.RegionInfo.RegionID] = scene; m_scenes[scene.RegionInfo.RegionID] = scene;
scene.AddCommand(
"Comms", this, "image queues clear",
"image queues clear <first-name> <last-name>",
"Clear the image queues (textures downloaded via UDP) for a particular client.",
(mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd)));
scene.AddCommand(
"Comms", this, "image queues show",
"image queues show <first-name> <last-name>",
"Show the image queues (textures downloaded via UDP) for a particular client.",
(mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
scene.AddCommand( scene.AddCommand(
"Comms", this, "show pqueues", "Comms", this, "show pqueues",
"show pqueues [full]", "show pqueues [full]",
@ -105,8 +93,15 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
"Comms", this, "show queues", "Comms", this, "show queues",
"show queues [full]", "show queues [full]",
"Show queue data for each client", "Show queue data for each client",
"Without the 'full' option, only root agents are shown." "Without the 'full' option, only root agents are shown.\n"
+ " With the 'full' option child agents are also shown.", + "With the 'full' option child agents are also shown.\n\n"
+ "Type - Rt is a root (avatar) client whilst cd is a child (neighbour interacting) client.\n"
+ "Since Last In - Time in milliseconds since last packet received.\n"
+ "Pkts In - Number of packets processed from the client.\n"
+ "Pkts Out - Number of packets sent to the client.\n"
+ "Pkts Resent - Number of packets resent to the client.\n"
+ "Bytes Unacked - Number of bytes transferred to the client that are awaiting acknowledgement.\n"
+ "Q Pkts * - Number of packets of various types (land, wind, etc.) to be sent to the client that are waiting for available bandwidth.\n",
(mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd))); (mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd)));
scene.AddCommand( scene.AddCommand(
@ -114,6 +109,12 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
"show image queues <first-name> <last-name>", "show image queues <first-name> <last-name>",
"Show the image queues (textures downloaded via UDP) for a particular client.", "Show the image queues (textures downloaded via UDP) for a particular client.",
(mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd))); (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
scene.AddCommand(
"Comms", this, "clear image queues",
"clear image queues <first-name> <last-name>",
"Clear the image queues (textures downloaded via UDP) for a particular client.",
(mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd)));
scene.AddCommand( scene.AddCommand(
"Comms", this, "show throttles", "Comms", this, "show throttles",
@ -373,17 +374,22 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
int maxNameLength = 18; int maxNameLength = 18;
int maxRegionNameLength = 14; int maxRegionNameLength = 14;
int maxTypeLength = 4; int maxTypeLength = 4;
int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
int totalInfoFieldsLength
= maxNameLength + columnPadding
+ maxRegionNameLength + columnPadding
+ maxTypeLength + columnPadding;
report.Append(GetColumnEntry("User", maxNameLength, columnPadding)); report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding)); report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
report.AppendFormat( report.AppendFormat(
"{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}\n", "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7} {12,7}\n",
"Since",
"Pkts",
"Pkts", "Pkts",
"Pkts", "Pkts",
"Pkts",
"Bytes", "Bytes",
"Q Pkts", "Q Pkts",
"Q Pkts", "Q Pkts",
@ -396,7 +402,8 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
report.AppendFormat( report.AppendFormat(
"{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}\n", "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7} {12,7}\n",
"Last In",
"In", "In",
"Out", "Out",
"Resent", "Resent",
@ -417,22 +424,22 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
scene.ForEachClient( scene.ForEachClient(
delegate(IClientAPI client) delegate(IClientAPI client)
{ {
bool isChild = client.SceneAgent.IsChildAgent;
if (isChild && !showChildren)
return;
string name = client.Name;
if (pname != "" && name != pname)
return;
string regionName = scene.RegionInfo.RegionName;
report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
if (client is IStatsCollector) if (client is IStatsCollector)
{ {
bool isChild = client.SceneAgent.IsChildAgent;
if (isChild && !showChildren)
return;
string name = client.Name;
if (pname != "" && name != pname)
return;
string regionName = scene.RegionInfo.RegionName;
report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
IStatsCollector stats = (IStatsCollector)client; IStatsCollector stats = (IStatsCollector)client;
report.AppendLine(stats.Report()); report.AppendLine(stats.Report());

View File

@ -36,7 +36,7 @@ using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;

View File

@ -36,7 +36,7 @@ using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;

View File

@ -37,6 +37,7 @@ using OpenMetaverse;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;

View File

@ -37,7 +37,7 @@ using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.CoreModules.Avatar.Friends; using OpenSim.Region.CoreModules.Avatar.Friends;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;

View File

@ -225,7 +225,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
RRAlert("enabled"); RRAlert("enabled");
} }
m_scene.EventManager.TriggerRegionReady(m_scene); m_scene.Ready = true;
} }
public void OarLoadingAlert(string msg) public void OarLoadingAlert(string msg)

View File

@ -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;
}
}
}

View File

@ -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<BSConstraint> m_constraints;
private BulletSim m_world;
public BSConstraintCollection(BulletSim world)
{
m_world = world;
m_constraints = new List<BSConstraint>();
}
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<BSConstraint> toRemove = new List<BSConstraint>();
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;
}
}
}
}
}

View File

@ -97,6 +97,9 @@ public sealed class BSPrim : PhysicsActor
long _collidingStep; long _collidingStep;
long _collidingGroundStep; long _collidingGroundStep;
private BulletBody m_body;
public BulletBody Body { get { return m_body; } }
private BSDynamics _vehicle; private BSDynamics _vehicle;
private OMV.Vector3 _PIDTarget; private OMV.Vector3 _PIDTarget;
@ -133,14 +136,16 @@ public sealed class BSPrim : PhysicsActor
_parentPrim = null; // not a child or a parent _parentPrim = null; // not a child or a parent
_vehicle = new BSDynamics(this); // add vehicleness _vehicle = new BSDynamics(this); // add vehicleness
_childrenPrims = new List<BSPrim>(); _childrenPrims = new List<BSPrim>();
if (_isPhysical) _mass = CalculateMass();
_mass = CalculateMass();
else
_mass = 0f;
// do the actual object creation at taint time // do the actual object creation at taint time
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
RecreateGeomAndObject(); RecreateGeomAndObject();
// Get the pointer to the physical body for this object.
// At the moment, we're still letting BulletSim manage the creation and destruction
// of the object. Someday we'll move that into the C# code.
m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
}); });
} }
@ -149,22 +154,26 @@ public sealed class BSPrim : PhysicsActor
{ {
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
// DetailLog("{0},Destroy", LocalID); // DetailLog("{0},Destroy", LocalID);
// Undo any vehicle properties // Undo any vehicle properties
_vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
_scene.RemoveVehiclePrim(this); // just to make sure _scene.RemoveVehiclePrim(this); // just to make sure
// undo any dependance with/on other objects
if (_parentPrim != null)
{
// If I'm someone's child, tell them to forget about me.
_parentPrim.RemoveChildFromLinkset(this);
_parentPrim = null;
}
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
// undo any dependance with/on other objects
if (_parentPrim != null)
{
// If I'm someone's child, tell them to forget about me.
_parentPrim.RemoveChildFromLinkset(this);
_parentPrim = null;
}
// make sure there are no other prims linked to me
UnlinkAllChildren();
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff. // everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
BulletSimAPI.DestroyObject(_scene.WorldID, _localID); BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
}); });
} }
@ -177,8 +186,8 @@ public sealed class BSPrim : PhysicsActor
_size = value; _size = value;
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
if (_isPhysical) _mass = CalculateMass(); // changing size changes the mass _mass = CalculateMass(); // changing size changes the mass
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, _mass, _isPhysical); BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, Mass, IsPhysical);
RecreateGeomAndObject(); RecreateGeomAndObject();
}); });
} }
@ -188,7 +197,7 @@ public sealed class BSPrim : PhysicsActor
_pbs = value; _pbs = value;
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
if (_isPhysical) _mass = CalculateMass(); // changing the shape changes the mass _mass = CalculateMass(); // changing the shape changes the mass
RecreateGeomAndObject(); RecreateGeomAndObject();
}); });
} }
@ -272,7 +281,10 @@ public sealed class BSPrim : PhysicsActor
DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID); DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID);
_childrenPrims.Add(child); _childrenPrims.Add(child);
child._parentPrim = this; // the child has gained a parent child._parentPrim = this; // the child has gained a parent
RecreateGeomAndObject(); // rebuild my shape with the new child added // RecreateGeomAndObject(); // rebuild my shape with the new child added
LinkAChildToMe(pchild); // build the physical binding between me and the child
_mass = CalculateMass();
} }
}); });
return; return;
@ -288,14 +300,21 @@ public sealed class BSPrim : PhysicsActor
if (_childrenPrims.Contains(child)) if (_childrenPrims.Contains(child))
{ {
DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
DetailLog("{0},RemoveChildToLinkset,child={1}", LocalID, pchild.LocalID); DetailLog("{0},RemoveChildFromLinkset,child={1}", LocalID, pchild.LocalID);
if (!BulletSimAPI.RemoveConstraintByID(_scene.WorldID, child.LocalID))
{
m_log.ErrorFormat("{0}: RemoveChildFromLinkset: Failed remove constraint for {1}", LogHeader, child.LocalID);
}
_childrenPrims.Remove(child); _childrenPrims.Remove(child);
child._parentPrim = null; // the child has lost its parent child._parentPrim = null; // the child has lost its parent
RecreateGeomAndObject(); // rebuild my shape with the child removed if (_childrenPrims.Count == 0)
{
// if the linkset is empty, make sure all linkages have been removed
UnlinkAllChildren();
}
else
{
// RecreateGeomAndObject(); // rebuild my shape with the child removed
UnlinkAChildFromMe(pchild);
}
_mass = CalculateMass();
} }
else else
{ {
@ -314,12 +333,18 @@ public sealed class BSPrim : PhysicsActor
// Set motion values to zero. // Set motion values to zero.
// Do it to the properties so the values get set in the physics engine. // Do it to the properties so the values get set in the physics engine.
// Push the setting of the values to the viewer. // Push the setting of the values to the viewer.
// Called at taint time!
private void ZeroMotion() private void ZeroMotion()
{ {
Velocity = OMV.Vector3.Zero; _velocity = OMV.Vector3.Zero;
_acceleration = OMV.Vector3.Zero; _acceleration = OMV.Vector3.Zero;
RotationalVelocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero;
base.RequestPhysicsterseUpdate();
// Zero some other properties directly into the physics engine
BulletSimAPI.SetVelocity2(Body.Ptr, OMV.Vector3.Zero);
BulletSimAPI.SetAngularVelocity2(Body.Ptr, OMV.Vector3.Zero);
BulletSimAPI.SetInterpolation2(Body.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero);
BulletSimAPI.ClearForces2(Body.Ptr);
} }
public override void LockAngularMotion(OMV.Vector3 axis) public override void LockAngularMotion(OMV.Vector3 axis)
@ -347,9 +372,17 @@ public sealed class BSPrim : PhysicsActor
}); });
} }
} }
// Return the effective mass of the object. Non-physical objects do not have mass.
public override float Mass { public override float Mass {
get { return _mass; } get {
if (IsPhysical)
return _mass;
else
return 0f;
}
} }
public override OMV.Vector3 Force { public override OMV.Vector3 Force {
get { return _force; } get { return _force; }
set { set {
@ -357,7 +390,8 @@ public sealed class BSPrim : PhysicsActor
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
DetailLog("{0},SetForce,taint,force={1}", LocalID, _force); DetailLog("{0},SetForce,taint,force={1}", LocalID, _force);
BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
}); });
} }
} }
@ -381,8 +415,7 @@ public sealed class BSPrim : PhysicsActor
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
// Tell the physics engine to clear state // Tell the physics engine to clear state
IntPtr obj = BulletSimAPI.GetBodyHandleWorldID2(_scene.WorldID, LocalID); BulletSimAPI.ClearForces2(this.Body.Ptr);
BulletSimAPI.ClearForces2(obj);
}); });
// make it so the scene will call us each tick to do vehicle things // make it so the scene will call us each tick to do vehicle things
@ -394,7 +427,6 @@ public sealed class BSPrim : PhysicsActor
} }
public override void VehicleFloatParam(int param, float value) public override void VehicleFloatParam(int param, float value)
{ {
m_log.DebugFormat("{0} VehicleFloatParam. {1} <= {2}", LogHeader, param, value);
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
@ -402,7 +434,6 @@ public sealed class BSPrim : PhysicsActor
} }
public override void VehicleVectorParam(int param, OMV.Vector3 value) public override void VehicleVectorParam(int param, OMV.Vector3 value)
{ {
m_log.DebugFormat("{0} VehicleVectorParam. {1} <= {2}", LogHeader, param, value);
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
@ -410,7 +441,6 @@ public sealed class BSPrim : PhysicsActor
} }
public override void VehicleRotationParam(int param, OMV.Quaternion rotation) public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
{ {
m_log.DebugFormat("{0} VehicleRotationParam. {1} <= {2}", LogHeader, param, rotation);
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
@ -418,7 +448,6 @@ public sealed class BSPrim : PhysicsActor
} }
public override void VehicleFlags(int param, bool remove) public override void VehicleFlags(int param, bool remove)
{ {
m_log.DebugFormat("{0} VehicleFlags. {1}. Remove={2}", LogHeader, param, remove);
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
_vehicle.ProcessVehicleFlags(param, remove); _vehicle.ProcessVehicleFlags(param, remove);
@ -429,7 +458,8 @@ public sealed class BSPrim : PhysicsActor
// Called from Scene when doing simulation step so we're in taint processing time. // Called from Scene when doing simulation step so we're in taint processing time.
public void StepVehicle(float timeStep) public void StepVehicle(float timeStep)
{ {
_vehicle.Step(timeStep); if (IsPhysical)
_vehicle.Step(timeStep);
} }
// Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
@ -526,20 +556,13 @@ public sealed class BSPrim : PhysicsActor
{ {
// m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid); // 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 // non-physical things work best with a mass of zero
if (IsStatic) if (!IsStatic)
{
_mass = 0f;
}
else
{ {
_mass = CalculateMass(); _mass = CalculateMass();
// If it's dynamic, make sure the hull has been created for it
// This shouldn't do much work if the object had previously been built
RecreateGeomAndObject(); RecreateGeomAndObject();
} }
DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, _mass); DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, Mass);
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass); BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), Mass);
} }
// prims don't fly // prims don't fly
@ -1234,7 +1257,7 @@ public sealed class BSPrim : PhysicsActor
if (IsRootOfLinkset) if (IsRootOfLinkset)
{ {
// Create a linkset around this object // Create a linkset around this object
CreateLinksetWithConstraints(); CreateLinkset();
} }
else else
{ {
@ -1247,30 +1270,6 @@ public sealed class BSPrim : PhysicsActor
} }
} }
// Create a linkset by creating a compound hull at the root prim that consists of all
// the children.
// NOTE: This does not allow proper collisions with the children prims so it is not a workable solution
void CreateLinksetWithCompoundHull()
{
// If I am the root prim of a linkset, replace my physical shape with all the
// pieces of the children.
// All of the children should have called CreateGeom so they have a hull
// in the physics engine already. Here we pull together all of those hulls
// into one shape.
int totalPrimsInLinkset = _childrenPrims.Count + 1;
// m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, totalPrimsInLinkset);
ShapeData[] shapes = new ShapeData[totalPrimsInLinkset];
FillShapeInfo(out shapes[0]);
int ii = 1;
foreach (BSPrim prim in _childrenPrims)
{
// m_log.DebugFormat("{0}: CreateLinkset: adding prim {1}", LogHeader, prim.LocalID);
prim.FillShapeInfo(out shapes[ii]);
ii++;
}
BulletSimAPI.CreateLinkset(_scene.WorldID, totalPrimsInLinkset, shapes);
}
// Copy prim's info into the BulletSim shape description structure // Copy prim's info into the BulletSim shape description structure
public void FillShapeInfo(out ShapeData shape) public void FillShapeInfo(out ShapeData shape)
{ {
@ -1280,7 +1279,7 @@ public sealed class BSPrim : PhysicsActor
shape.Rotation = _orientation; shape.Rotation = _orientation;
shape.Velocity = _velocity; shape.Velocity = _velocity;
shape.Scale = _scale; shape.Scale = _scale;
shape.Mass = _isPhysical ? _mass : 0f; shape.Mass = Mass;
shape.Buoyancy = _buoyancy; shape.Buoyancy = _buoyancy;
shape.HullKey = _hullKey; shape.HullKey = _hullKey;
shape.MeshKey = _meshKey; shape.MeshKey = _meshKey;
@ -1290,45 +1289,84 @@ public sealed class BSPrim : PhysicsActor
shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; 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 // Create the linkset by putting constraints between the objects of the set so they cannot move
// relative to each other. // relative to each other.
// TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added void CreateLinkset()
void CreateLinksetWithConstraints()
{ {
DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); // DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
// remove any constraints that might be in place // remove any constraints that might be in place
foreach (BSPrim prim in _childrenPrims) UnlinkAllChildren();
{
DebugLog("{0}: CreateLinkset: RemoveConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, prim.LocalID);
}
// create constraints between the root prim and each of the children // create constraints between the root prim and each of the children
foreach (BSPrim prim in _childrenPrims) foreach (BSPrim prim in _childrenPrims)
{ {
// Zero motion for children so they don't interpolate LinkAChildToMe(prim);
prim.ZeroMotion();
// relative position normalized to the root prim
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation);
OMV.Vector3 childRelativePosition = (prim._position - this._position) * invThisOrientation;
// relative rotation of the child to the parent
OMV.Quaternion childRelativeRotation = invThisOrientation * prim._orientation;
// this is a constraint that allows no freedom of movement between the two objects
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID,
childRelativePosition,
childRelativeRotation,
OMV.Vector3.Zero,
OMV.Quaternion.Identity,
OMV.Vector3.Zero, OMV.Vector3.Zero,
OMV.Vector3.Zero, OMV.Vector3.Zero);
} }
} }
// Create a constraint between me (root of linkset) and the passed prim (the child).
// Called at taint time!
private void LinkAChildToMe(BSPrim childPrim)
{
// Zero motion for children so they don't interpolate
childPrim.ZeroMotion();
// relative position normalized to the root prim
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation);
OMV.Vector3 childRelativePosition = (childPrim._position - this._position) * invThisOrientation;
// relative rotation of the child to the parent
OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim._orientation;
// create a constraint that allows no freedom of movement between the two objects
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID);
BSConstraint constrain = _scene.Constraints.CreateConstraint(
_scene.World, this.Body, childPrim.Body,
childRelativePosition,
childRelativeRotation,
OMV.Vector3.Zero,
OMV.Quaternion.Identity);
constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
// tweek the constraint to increase stability
constrain.UseFrameOffset(_scene.BoolNumeric(_scene.Params.linkConstraintUseFrameOffset));
if (_scene.BoolNumeric(_scene.Params.linkConstraintEnableTransMotor))
{
constrain.TranslationalLimitMotor(true,
_scene.Params.linkConstraintTransMotorMaxVel,
_scene.Params.linkConstraintTransMotorMaxForce);
}
}
// Remove linkage between myself and a particular child
// Called at taint time!
private void UnlinkAChildFromMe(BSPrim childPrim)
{
DebugLog("{0}: UnlinkAChildFromMe: RemoveConstraint between root prim {1} and child prim {2}",
LogHeader, LocalID, childPrim.LocalID);
DetailLog("{0},UnlinkAChildFromMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID);
// BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
_scene.Constraints.RemoveAndDestroyConstraint(this.Body, childPrim.Body);
}
// Remove linkage between myself and any possible children I might have
// Called at taint time!
private void UnlinkAllChildren()
{
DebugLog("{0}: UnlinkAllChildren:", LogHeader);
DetailLog("{0},UnlinkAllChildren,taint", LocalID);
_scene.Constraints.RemoveAndDestroyConstraint(this.Body);
// BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
}
#endregion // Linkset creation and destruction
// Rebuild the geometry and object. // Rebuild the geometry and object.
// This is called when the shape changes so we need to recreate the mesh/hull. // This is called when the shape changes so we need to recreate the mesh/hull.
// No locking here because this is done when the physics engine is not simulating // No locking here because this is done when the physics engine is not simulating
@ -1405,7 +1443,7 @@ public sealed class BSPrim : PhysicsActor
// Don't check for damping here -- it's done in BulletSim and SceneObjectPart. // 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. // Updates only for individual prims and for the root object of a linkset.
if (this._parentPrim == null) if (_parentPrim == null)
{ {
// Assign to the local variables so the normal set action does not happen // Assign to the local variables so the normal set action does not happen
_position = entprop.Position; _position = entprop.Position;

View File

@ -103,6 +103,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters
get { return m_sculptLOD; } 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 int m_maxSubSteps;
private float m_fixedTimeStep; private float m_fixedTimeStep;
private long m_simulationStep = 0; private long m_simulationStep = 0;
@ -229,6 +240,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.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; m_initialized = true;
} }
@ -237,116 +253,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters
private void GetInitialParameterValues(IConfigSource config) private void GetInitialParameterValues(IConfigSource config)
{ {
ConfigurationParameters parms = new ConfigurationParameters(); ConfigurationParameters parms = new ConfigurationParameters();
m_params[0] = parms;
_meshSculptedPrim = true; // mesh sculpted prims SetParameterDefaultValues();
_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
if (config != null) if (config != null)
{ {
// If there are specifications in the ini file, use those values // 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"]; IConfig pConfig = config.Configs["BulletSim"];
if (pConfig != null) if (pConfig != null)
{ {
_meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim); SetParameterConfigurationValues(pConfig);
_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);
// Very detailed logging for physics debugging // Very detailed logging for physics debugging
m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
@ -357,7 +274,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); 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 // A helper function that handles a true/false parameter and returns the proper float number encoding
@ -630,6 +546,33 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public override void Dispose() public override void Dispose()
{ {
// m_log.DebugFormat("{0}: Dispose()", LogHeader); // m_log.DebugFormat("{0}: Dispose()", LogHeader);
// make sure no stepping happens while we're deleting stuff
m_initialized = false;
if (m_constraintCollection != null)
{
m_constraintCollection.Dispose();
m_constraintCollection = null;
}
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
{
kvp.Value.Destroy();
}
m_avatars.Clear();
foreach (KeyValuePair<uint, BSPrim> kvp in m_prims)
{
kvp.Value.Destroy();
}
m_prims.Clear();
// Anything left in the unmanaged code should be cleaned out
BulletSimAPI.Shutdown(WorldID);
// Not logging any more
PhysicsLogging.Close();
} }
public override Dictionary<uint, float> GetTopColliders() public override Dictionary<uint, float> GetTopColliders()
@ -755,10 +698,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
} }
// The calls to the PhysicsActors can't directly call into the physics engine // 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. // We rely on C#'s closure to save and restore the context for the delegate.
public void TaintedObject(TaintCallback callback) public void TaintedObject(TaintCallback callback)
{ {
if (!m_initialized) return;
lock (_taintLock) lock (_taintLock)
_taintedObjects.Add(callback); _taintedObjects.Add(callback);
return; return;
@ -832,61 +777,371 @@ public class BSScene : PhysicsScene, IPhysicsParameters
} }
#endregion Vehicles #endregion Vehicles
#region Runtime settable parameters #region Parameters
public static PhysParameterEntry[] SettableParameters = new PhysParameterEntry[]
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)"), public string name;
new PhysParameterEntry("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)"), public string desc;
new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"), public float defaultValue;
new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"), public ParamUser userParam;
new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"), public ParamGet getter;
new PhysParameterEntry("DetailedStats", "Frames between outputting detailed phys stats. Zero is off"), 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"), // List of all of the externally visible parameters.
new PhysParameterEntry("DefaultDensity", "Density for new objects" ), // For each parameter, this table maps a text name to getter and setters.
new PhysParameterEntry("DefaultRestitution", "Bouncyness of an object" ), // A ParameterDefn() takes the following parameters:
// new PhysParameterEntry("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!!)" ), // -- the text name of the parameter. This is used for console input and ini file.
new PhysParameterEntry("Gravity", "Vertical force of gravity (negative means down)" ), // -- 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 ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
new PhysParameterEntry("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)" ), 8f,
new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ), (s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); },
new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ), (s) => { return (float)s.m_meshLOD; },
new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ), (s,p,l,v) => { s.m_meshLOD = (int)v; } ),
new PhysParameterEntry("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ), new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
new PhysParameterEntry("CcdSweptSphereRadius", "Continuious collision detection test radius" ), 32,
new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ), (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); },
// Can only change the following at initialization time. Change the INI file and reboot. (s) => { return (float)s.m_sculptLOD; },
new PhysParameterEntry("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)"), (s,p,l,v) => { s.m_sculptLOD = (int)v; } ),
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 PhysParameterEntry("Friction", "Set friction parameter for a specific object" ), new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ), 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 ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ), 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 ParameterDefn("DefaultFriction", "Friction factor used on new objects",
new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ), 0.5f,
new PhysParameterEntry("TerrainRestitution", "Bouncyness" ), (s,cf,p,v) => { s.m_params[0].defaultFriction = cf.GetFloat(p, v); },
new PhysParameterEntry("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation." ), (s) => { return s.m_params[0].defaultFriction; },
new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ), (s,p,l,v) => { s.m_params[0].defaultFriction = v; } ),
new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ), new ParameterDefn("DefaultDensity", "Density for new objects" ,
new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ), 10.000006836f, // Aluminum g/cm3
new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" ), (s,cf,p,v) => { s.m_params[0].defaultDensity = cf.GetFloat(p, v); },
new PhysParameterEntry("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions") (s) => { return s.m_params[0].defaultDensity; },
(s,p,l,v) => { s.m_params[0].defaultDensity = v; } ),
new ParameterDefn("DefaultRestitution", "Bouncyness of an object" ,
0f,
(s,cf,p,v) => { s.m_params[0].defaultRestitution = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].defaultRestitution; },
(s,p,l,v) => { s.m_params[0].defaultRestitution = v; } ),
new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)",
0f,
(s,cf,p,v) => { s.m_params[0].collisionMargin = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].collisionMargin; },
(s,p,l,v) => { s.m_params[0].collisionMargin = v; } ),
new ParameterDefn("Gravity", "Vertical force of gravity (negative means down)",
-9.80665f,
(s,cf,p,v) => { s.m_params[0].gravity = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].gravity; },
(s,p,l,v) => { s.m_params[0].gravity = v; s.TaintedUpdateParameter(p,l,v); } ),
new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)",
0f,
(s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].linearDamping; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearDamping, p, l, v); } ),
new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
0f,
(s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].angularDamping; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularDamping, p, l, v); } ),
new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
0.2f,
(s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].deactivationTime; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].deactivationTime, p, l, v); } ),
new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
0.8f,
(s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].linearSleepingThreshold; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ),
new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
1.0f,
(s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].angularSleepingThreshold; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ),
new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
0f, // set to zero to disable
(s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].ccdMotionThreshold; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ),
new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
0f,
(s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].ccdSweptSphereRadius; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ),
new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
0.1f,
(s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].contactProcessingThreshold; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ),
new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
0.5f,
(s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].terrainFriction; },
(s,p,l,v) => { s.m_params[0].terrainFriction = v; s.TaintedUpdateParameter(p,l,v); } ),
new ParameterDefn("TerrainHitFraction", "Distance to measure hit collisions" ,
0.8f,
(s,cf,p,v) => { s.m_params[0].terrainHitFraction = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].terrainHitFraction; },
(s,p,l,v) => { s.m_params[0].terrainHitFraction = v; s.TaintedUpdateParameter(p,l,v); } ),
new ParameterDefn("TerrainRestitution", "Bouncyness" ,
0f,
(s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].terrainRestitution; },
(s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ),
new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
0.5f,
(s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarFriction; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarFriction, p, l, v); } ),
new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
60f,
(s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarDensity; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarDensity, p, l, v); } ),
new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
0f,
(s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarRestitution; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarRestitution, p, l, v); } ),
new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar",
0.37f,
(s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarCapsuleRadius; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ),
new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
1.5f,
(s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarCapsuleHeight; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ),
new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
0.1f,
(s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarContactProcessingThreshold; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)",
0f, // zero to disable
(s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].maxPersistantManifoldPoolSize; },
(s,p,l,v) => { s.m_params[0].maxPersistantManifoldPoolSize = v; } ),
new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
ConfigurationParameters.numericTrue,
(s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
(s) => { return s.m_params[0].shouldDisableContactPoolDynamicAllocation; },
(s,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ),
new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
ConfigurationParameters.numericFalse,
(s,cf,p,v) => { s.m_params[0].shouldForceUpdateAllAabbs = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
(s) => { return s.m_params[0].shouldForceUpdateAllAabbs; },
(s,p,l,v) => { s.m_params[0].shouldForceUpdateAllAabbs = v; } ),
new ParameterDefn("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction",
ConfigurationParameters.numericFalse,
(s,cf,p,v) => { s.m_params[0].shouldRandomizeSolverOrder = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
(s) => { return s.m_params[0].shouldRandomizeSolverOrder; },
(s,p,l,v) => { s.m_params[0].shouldRandomizeSolverOrder = v; } ),
new ParameterDefn("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands",
ConfigurationParameters.numericFalse,
(s,cf,p,v) => { s.m_params[0].shouldSplitSimulationIslands = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
(s) => { return s.m_params[0].shouldSplitSimulationIslands; },
(s,p,l,v) => { s.m_params[0].shouldSplitSimulationIslands = v; } ),
new ParameterDefn("ShouldEnableFrictionCaching", "Enable friction computation caching",
ConfigurationParameters.numericFalse,
(s,cf,p,v) => { s.m_params[0].shouldEnableFrictionCaching = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
(s) => { return s.m_params[0].shouldEnableFrictionCaching; },
(s,p,l,v) => { s.m_params[0].shouldEnableFrictionCaching = v; } ),
new ParameterDefn("NumberOfSolverIterations", "Number of internal iterations (0 means default)",
0f, // zero says use Bullet default
(s,cf,p,v) => { s.m_params[0].numberOfSolverIterations = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].numberOfSolverIterations; },
(s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ),
new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
ConfigurationParameters.numericTrue,
(s,cf,p,v) => { s.m_params[0].linkConstraintUseFrameOffset = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
(s) => { return s.m_params[0].linkConstraintUseFrameOffset; },
(s,p,l,v) => { s.m_params[0].linkConstraintUseFrameOffset = v; } ),
new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints",
ConfigurationParameters.numericTrue,
(s,cf,p,v) => { s.m_params[0].linkConstraintEnableTransMotor = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
(s) => { return s.m_params[0].linkConstraintEnableTransMotor; },
(s,p,l,v) => { s.m_params[0].linkConstraintEnableTransMotor = v; } ),
new ParameterDefn("LinkConstraintTransMotorMaxVel", "Maximum velocity to be applied by translational motor in linkset constraints",
5.0f,
(s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxVel = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].linkConstraintTransMotorMaxVel; },
(s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxVel = v; } ),
new ParameterDefn("LinkConstraintTransMotorMaxForce", "Maximum force to be applied by translational motor in linkset constraints",
0.1f,
(s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; },
(s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ),
new ParameterDefn("DetailedStats", "Frames between outputting detailed phys stats. (0 is off)",
0f,
(s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); },
(s) => { return (float)s.m_detailedStatsStep; },
(s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
ConfigurationParameters.numericFalse,
(s,cf,p,v) => { s.shouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
(s) => { return s.NumericBool(s.shouldDebugLog); },
(s,p,l,v) => { s.shouldDebugLog = s.BoolNumeric(v); } ),
}; };
// Convert a boolean to our numeric true and false values
public float NumericBool(bool b)
{
return (b ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse);
}
// Convert numeric true and false values to a boolean
public bool BoolNumeric(float b)
{
return (b == ConfigurationParameters.numericTrue ? true : false);
}
// Search through the parameter definitions and return the matching
// ParameterDefn structure.
// Case does not matter as names are compared after converting to lower case.
// Returns 'false' if the parameter is not found.
private bool TryGetParameter(string paramName, out ParameterDefn defn)
{
bool ret = false;
ParameterDefn foundDefn = new ParameterDefn();
string pName = paramName.ToLower();
foreach (ParameterDefn parm in ParameterDefinitions)
{
if (pName == parm.name.ToLower())
{
foundDefn = parm;
ret = true;
break;
}
}
defn = foundDefn;
return ret;
}
// Pass through the settable parameters and set the default values
private void SetParameterDefaultValues()
{
foreach (ParameterDefn parm in ParameterDefinitions)
{
parm.setter(this, parm.name, PhysParameterEntry.APPLY_TO_NONE, parm.defaultValue);
}
}
// Get user set values out of the ini file.
private void SetParameterConfigurationValues(IConfig cfg)
{
foreach (ParameterDefn parm in ParameterDefinitions)
{
parm.userParam(this, cfg, parm.name, parm.defaultValue);
}
}
private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
private void BuildParameterTable()
{
if (SettableParameters.Length < ParameterDefinitions.Length)
{
List<PhysParameterEntry> entries = new List<PhysParameterEntry>();
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 #region IPhysicsParameters
// Get the list of parameters this physics engine supports // Get the list of parameters this physics engine supports
public PhysParameterEntry[] GetParameterList() public PhysParameterEntry[] GetParameterList()
{ {
BuildParameterTable();
return SettableParameters; return SettableParameters;
} }
@ -898,63 +1153,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// value activated ('terrainFriction' for instance). // value activated ('terrainFriction' for instance).
public bool SetPhysicsParameter(string parm, float val, uint localID) public bool SetPhysicsParameter(string parm, float val, uint localID)
{ {
bool ret = true; bool ret = false;
string lparm = parm.ToLower(); ParameterDefn theParam;
switch (lparm) if (TryGetParameter(parm, out theParam))
{ {
case "detailedstats": m_detailedStatsStep = (int)val; break; theParam.setter(this, parm, localID, val);
ret = true;
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;
} }
return ret; return ret;
} }
// check to see if we are updating a parameter for a particular or all of the prims // 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<uint> operateOn; List<uint> operateOn;
lock (m_prims) operateOn = new List<uint>(m_prims.Keys); lock (m_prims) operateOn = new List<uint>(m_prims.Keys);
@ -962,7 +1172,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
} }
// check to see if we are updating a parameter for a particular or all of the avatars // 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<uint> operateOn; List<uint> operateOn;
lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys); lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys);
@ -973,7 +1183,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// If the local ID is APPLY_TO_NONE, just change the default value // If the 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 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 // If the localID is a specific object, apply the parameter change to only that object
private void UpdateParameterSet(List<uint> lIDs, ref float defaultLoc, string parm, uint localID, float val) protected void UpdateParameterSet(List<uint> lIDs, ref float defaultLoc, string parm, uint localID, float val)
{ {
switch (localID) switch (localID)
{ {
@ -1000,7 +1210,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
} }
// schedule the actual updating of the paramter to when the phys engine is not busy // 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; uint xlocalID = localID;
string xparm = parm.ToLower(); string xparm = parm.ToLower();
@ -1015,50 +1225,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public bool GetPhysicsParameter(string parm, out float value) public bool GetPhysicsParameter(string parm, out float value)
{ {
float val = 0f; float val = 0f;
bool ret = true; bool ret = false;
switch (parm.ToLower()) ParameterDefn theParam;
if (TryGetParameter(parm, out theParam))
{ {
case "detailedstats": val = (int)m_detailedStatsStep; break; val = theParam.getter(this);
case "meshlod": val = (float)m_meshLOD; break; ret = true;
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;
} }
value = val; value = val;
return ret; return ret;

View File

@ -32,6 +32,28 @@ using OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin { 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)] [StructLayout(LayoutKind.Sequential)]
public struct ConvexHull public struct ConvexHull
{ {
@ -142,6 +164,11 @@ public struct ConfigurationParameters
public float shouldEnableFrictionCaching; public float shouldEnableFrictionCaching;
public float numberOfSolverIterations; public float numberOfSolverIterations;
public float linkConstraintUseFrameOffset;
public float linkConstraintEnableTransMotor;
public float linkConstraintTransMotorMaxVel;
public float linkConstraintTransMotorMaxForce;
public const float numericTrue = 1f; public const float numericTrue = 1f;
public const float numericFalse = 0f; public const float numericFalse = 0f;
} }
@ -162,6 +189,7 @@ public enum CollisionFlags : uint
PHYSICAL_OBJECT = 1 << 12, PHYSICAL_OBJECT = 1 << 12,
}; };
// ===============================================================================
static class BulletSimAPI { static class BulletSimAPI {
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
@ -214,6 +242,7 @@ public static extern bool CreateObject(uint worldID, ShapeData shapeData);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas); public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas);
/* Remove old functionality
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void AddConstraint(uint worldID, uint id1, uint id2, public static extern void AddConstraint(uint worldID, uint id1, uint id2,
Vector3 frame1, Quaternion frame1rot, Vector3 frame1, Quaternion frame1rot,
@ -225,6 +254,7 @@ public static extern bool RemoveConstraintByID(uint worldID, uint id1);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2); public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2);
*/
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern Vector3 GetObjectPosition(uint WorldID, uint id); public static extern Vector3 GetObjectPosition(uint WorldID, uint id);
@ -291,13 +321,14 @@ public static extern void SetDebugLogCallback(DebugLogCallback callback);
// =============================================================================== // ===============================================================================
// =============================================================================== // ===============================================================================
// =============================================================================== // ===============================================================================
// A new version of the API that moves all the logic out of the C++ code and into // A new version of the API that enables moving all the logic out of the C++ code and into
// the C# code. This will make modifications easier for the next person. // the C# code. This will make modifications easier for the next person.
// This interface passes the actual pointers to the objects in the unmanaged // This interface passes the actual pointers to the objects in the unmanaged
// address space. All the management (calls for creation/destruction/lookup) // address space. All the management (calls for creation/destruction/lookup)
// is done in the C# code. // is done in the C# code.
// The names have a 2 tacked on. This will be removed as the code gets rebuilt // The names have a "2" tacked on. This will be removed as the C# code gets rebuilt
// and the old code is removed from the C# code. // and the old code is removed.
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GetSimHandle2(uint worldID); public static extern IntPtr GetSimHandle2(uint worldID);
@ -307,8 +338,115 @@ public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GetBodyHandle2(IntPtr sim, uint id); public static extern IntPtr GetBodyHandle2(IntPtr sim, uint id);
// ===============================================================================
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr ClearForces2(IntPtr obj); public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
int maxCollisions, IntPtr collisionArray,
int maxUpdates, IntPtr updateArray);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool UpdateParameter2(IntPtr sim, uint localID, String parm, float value);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void SetHeightmap2(IntPtr sim, float[] heightmap);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void Shutdown2(IntPtr sim);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern int PhysicsStep2(IntPtr sim, float timeStep, int maxSubSteps, float fixedTimeStep,
out int updatedEntityCount,
out IntPtr updatedEntitiesPtr,
out int collidersCount,
out IntPtr collidersPtr);
/*
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateMesh2(IntPtr sim, int indicesCount, int* indices, int verticesCount, float* vertices );
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool BuildHull2(IntPtr sim, IntPtr mesh);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool ReleaseHull2(IntPtr sim, IntPtr mesh);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool DestroyMesh2(IntPtr sim, IntPtr mesh);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateObject2(IntPtr sim, ShapeData shapeData);
*/
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateConstraint2(IntPtr sim, IntPtr obj1, IntPtr obj2,
Vector3 frame1loc, Quaternion frame1rot,
Vector3 frame2loc, Quaternion frame2rot);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetAngularLimits2(IntPtr constrain, Vector3 low, Vector3 hi);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool UseFrameOffset2(IntPtr constrain, float enable);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool CalculateTransforms2(IntPtr constrain);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool DestroyConstraint2(IntPtr sim, IntPtr constrain);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern Vector3 GetPosition2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern Quaternion GetOrientation2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetVelocity2(IntPtr obj, Vector3 velocity);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetObjectForce2(IntPtr obj, Vector3 force);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetCcdMotionThreshold2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetCcdSweepSphereRadius2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetDamping2(IntPtr obj, float lin_damping, float ang_damping);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetDeactivationTime2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetContactProcessingThreshold2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetFriction2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetRestitution2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetLinearVelocity2(IntPtr obj, Vector3 val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetInterpolation2(IntPtr obj, Vector3 lin, Vector3 ang);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr SetCollisionFlags2(IntPtr obj, uint flags); public static extern IntPtr SetCollisionFlags2(IntPtr obj, uint flags);
@ -319,5 +457,35 @@ public static extern IntPtr AddToCollisionFlags2(IntPtr obj, uint flags);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr RemoveFromCollisionFlags2(IntPtr obj, uint flags); public static extern IntPtr RemoveFromCollisionFlags2(IntPtr obj, uint flags);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetMassProps2(IntPtr obj, float mass, Vector3 inertia);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool UpdateInertiaTensor2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetGravity2(IntPtr obj, Vector3 val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr ClearForces2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetMargin2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool UpdateSingleAabb2(IntPtr world, IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool DestroyObject2(IntPtr world, uint id);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void DumpPhysicsStatistics2(IntPtr sim);
} }
} }

View File

@ -31,6 +31,7 @@ using System.Collections.Generic;
using System.Threading; using System.Threading;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared;

View File

@ -646,7 +646,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
// If region ready has been triggered, then the region had no scripts to compile and completed its other // If region ready has been triggered, then the region had no scripts to compile and completed its other
// work. // work.
m_Scene.EventManager.OnRegionReady += s => m_InitialStartup = false; m_Scene.EventManager.OnRegionReadyStatusChange += s => { if (s.Ready) m_InitialStartup = false; };
if (m_SleepTime > 0) if (m_SleepTime > 0)
{ {

View File

@ -34,7 +34,7 @@ using Mono.Data.SqliteClient;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.UserStatistics namespace OpenSim.Region.UserStatistics
{ {

View File

@ -33,7 +33,7 @@ using System.Text;
using Mono.Data.SqliteClient; using Mono.Data.SqliteClient;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.UserStatistics namespace OpenSim.Region.UserStatistics

View File

@ -34,7 +34,7 @@ using System.Text.RegularExpressions;
using Mono.Data.SqliteClient; using Mono.Data.SqliteClient;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.UserStatistics namespace OpenSim.Region.UserStatistics
{ {

View File

@ -33,7 +33,7 @@ using System.Text;
using Mono.Data.SqliteClient; using Mono.Data.SqliteClient;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Framework.Statistics; using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.UserStatistics namespace OpenSim.Region.UserStatistics
{ {

View File

@ -79,9 +79,27 @@ namespace OpenSim.Tests.Common
/// <param name="part"></param> /// <param name="part"></param>
/// <returns>The item that was added</returns> /// <returns>The item that was added</returns>
public static TaskInventoryItem AddScript(Scene scene, SceneObjectPart part) public static TaskInventoryItem AddScript(Scene scene, SceneObjectPart part)
{
return AddScript(scene, part, "scriptItem", "default { state_entry() { llSay(0, \"Hello World\"); } }");
}
/// <summary>
/// Add a simple script to the given part.
/// </summary>
/// <remarks>
/// TODO: Accept input for item and asset IDs to avoid mysterious script failures that try to use any of these
/// functions more than once in a test.
/// </remarks>
/// <param name="scene"></param>
/// <param name="part"></param>
/// <param name="scriptName">Name of the script to add</param>
/// <param name="scriptSource">LSL script source</param>
/// <returns>The item that was added</returns>
public static TaskInventoryItem AddScript(
Scene scene, SceneObjectPart part, string scriptName, string scriptSource)
{ {
AssetScriptText ast = new AssetScriptText(); AssetScriptText ast = new AssetScriptText();
ast.Source = "default { state_entry() { llSay(0, \"Hello World\"); } }"; ast.Source = scriptSource;
ast.Encode(); ast.Encode();
UUID assetUuid = new UUID("00000000-0000-0000-1000-000000000000"); UUID assetUuid = new UUID("00000000-0000-0000-1000-000000000000");
@ -91,7 +109,7 @@ namespace OpenSim.Tests.Common
scene.AssetService.Store(asset); scene.AssetService.Store(asset);
TaskInventoryItem item TaskInventoryItem item
= new TaskInventoryItem = new TaskInventoryItem
{ Name = "scriptItem", AssetID = assetUuid, ItemID = itemUuid, { Name = scriptName, AssetID = assetUuid, ItemID = itemUuid,
Type = (int)AssetType.LSLText, InvType = (int)InventoryType.LSL }; Type = (int)AssetType.LSLText, InvType = (int)InventoryType.LSL };
part.Inventory.AddInventoryItem(item, true); part.Inventory.AddInventoryItem(item, true);

View File

@ -914,6 +914,12 @@
ShouldEnableFrictionCaching = False; ShouldEnableFrictionCaching = False;
NumberOfSolverIterations = 0; NumberOfSolverIterations = 0;
; Linkset constraint parameters
LinkConstraintUseFrameOffset = True;
LinkConstraintEnableTransMotor = True;
LinkConstraintTransMotorMaxVel = 5.0;
LinkConstraintTransMotorMaxForce = 0.1;
; Whether to mesh sculpties ; Whether to mesh sculpties
MeshSculptedPrim = true MeshSculptedPrim = true

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -112,6 +112,32 @@
</Files> </Files>
</Project> </Project>
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Monitoring" path="OpenSim/Framework/Monitoring" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Core"/>
<Reference name="log4net" path="../../../bin/"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
<Reference name="OpenSim.Framework"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Servers.HttpServer" path="OpenSim/Framework/Servers/HttpServer" type="Library"> <Project frameworkVersion="v3_5" name="OpenSim.Framework.Servers.HttpServer" path="OpenSim/Framework/Servers/HttpServer" type="Library">
<Configuration name="Debug"> <Configuration name="Debug">
<Options> <Options>
@ -130,6 +156,7 @@
<Reference name="System.Xml"/> <Reference name="System.Xml"/>
<Reference name="System.Web"/> <Reference name="System.Web"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../../bin/"/> <Reference name="OpenMetaverse.StructuredData" path="../../../../bin/"/>
<Reference name="OpenMetaverseTypes" path="../../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
<Reference name="XMLRPC" path="../../../../bin/"/> <Reference name="XMLRPC" path="../../../../bin/"/>
@ -235,30 +262,6 @@
</Files> </Files>
</Project> </Project>
<Project frameworkVersion="v3_5" name="OpenSim.Framework.Statistics" path="OpenSim/Framework/Statistics" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
<Reference name="OpenSim.Framework"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Data" path="OpenSim/Data" type="Library"> <Project frameworkVersion="v3_5" name="OpenSim.Data" path="OpenSim/Data" type="Library">
<Configuration name="Debug"> <Configuration name="Debug">
<Options> <Options>
@ -436,7 +439,7 @@
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Statistics"/> <Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="XMLRPC" path="../../../bin/"/> <Reference name="XMLRPC" path="../../../bin/"/>
@ -601,9 +604,9 @@
<Reference name="System.Xml"/> <Reference name="System.Xml"/>
<Reference name="System.Web"/> <Reference name="System.Web"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Services.Interfaces"/> <Reference name="OpenSim.Services.Interfaces"/>
<Reference name="OpenMetaverse" path="../../bin/"/> <Reference name="OpenMetaverse" path="../../bin/"/>
<Reference name="OpenMetaverseTypes" path="../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../bin/"/>
@ -635,13 +638,13 @@
<Reference name="System"/> <Reference name="System"/>
<Reference name="System.Xml"/> <Reference name="System.Xml"/>
<Reference name="System.Web"/> <Reference name="System.Web"/>
<Reference name="OpenSim.Data"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.AssetLoader.Filesystem"/> <Reference name="OpenSim.Framework.AssetLoader.Filesystem"/>
<Reference name="OpenSim.Data"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Services.Interfaces"/> <Reference name="OpenSim.Services.Interfaces"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
@ -687,10 +690,10 @@
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Data"/> <Reference name="OpenSim.Data"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Serialization"/> <Reference name="OpenSim.Framework.Serialization"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<!-- For scripting in funny languages by default --> <!-- For scripting in funny languages by default -->
@ -1444,10 +1447,10 @@
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Serialization"/> <Reference name="OpenSim.Framework.Serialization"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Server.Base"/> <Reference name="OpenSim.Server.Base"/>
@ -1535,11 +1538,11 @@
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Data"/> <Reference name="OpenSim.Data"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="XMLRPC" path="../../../bin/"/> <Reference name="XMLRPC" path="../../../bin/"/>
<Reference name="Nini" path="../../../bin/"/> <Reference name="Nini" path="../../../bin/"/>
@ -1572,15 +1575,15 @@
<Reference name="OpenMetaverseTypes" path="../../../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../../../bin/"/> <Reference name="OpenMetaverse.StructuredData" path="../../../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../../../bin/"/> <Reference name="OpenMetaverse" path="../../../../../bin/"/>
<Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Data"/> <Reference name="OpenSim.Data"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.ClientStack"/> <Reference name="OpenSim.Region.ClientStack"/>
<Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Services.Interfaces"/> <Reference name="OpenSim.Services.Interfaces"/>
<Reference name="Nini" path="../../../../../bin/"/> <Reference name="Nini" path="../../../../../bin/"/>
<Reference name="log4net" path="../../../../../bin/"/> <Reference name="log4net" path="../../../../../bin/"/>
@ -1663,9 +1666,9 @@
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Data"/> <Reference name="OpenSim.Data"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.CoreModules"/> <Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Region.ClientStack.LindenUDP"/> <Reference name="OpenSim.Region.ClientStack.LindenUDP"/>
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
@ -1801,15 +1804,15 @@
<Reference name="OpenMetaverse" path="../../../bin/"/> <Reference name="OpenMetaverse" path="../../../bin/"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Data"/> <Reference name="OpenSim.Data"/>
<Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.CoreModules"/> <Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Region.ClientStack"/> <Reference name="OpenSim.Region.ClientStack"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Server.Base"/> <Reference name="OpenSim.Server.Base"/>
<Reference name="OpenSim.Services.Base"/> <Reference name="OpenSim.Services.Base"/>
<Reference name="OpenSim.Services.Interfaces"/> <Reference name="OpenSim.Services.Interfaces"/>
@ -2321,10 +2324,11 @@
<Reference name="OpenSim"/> <Reference name="OpenSim"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.CoreModules"/> <Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Services.Interfaces"/> <Reference name="OpenSim.Services.Interfaces"/>
<Reference name="OpenSim.Region.ScriptEngine.Shared"/> <Reference name="OpenSim.Region.ScriptEngine.Shared"/>
<Reference name="OpenSim.Region.ScriptEngine.Shared.Api.Runtime"/> <Reference name="OpenSim.Region.ScriptEngine.Shared.Api.Runtime"/>
@ -2447,7 +2451,6 @@
</Files> </Files>
</Project> </Project>
<Project frameworkVersion="v3_5" name="OpenSim.Region.UserStatistics" path="OpenSim/Region/UserStatistics" type="Library"> <Project frameworkVersion="v3_5" name="OpenSim.Region.UserStatistics" path="OpenSim/Region/UserStatistics" type="Library">
<Configuration name="Debug"> <Configuration name="Debug">
<Options> <Options>
@ -2476,9 +2479,9 @@
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.CoreModules"/> <Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="Mono.Data.SqliteClient" path="../../../bin/"/> <Reference name="Mono.Data.SqliteClient" path="../../../bin/"/>
<Reference name="Mono.Addins"/> <Reference name="Mono.Addins"/>
@ -2962,9 +2965,9 @@
<Reference name="OpenSim.Framework.Serialization"/> <Reference name="OpenSim.Framework.Serialization"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.CoreModules"/> <Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
@ -3034,9 +3037,9 @@
<Reference name="OpenSim.Framework.Serialization"/> <Reference name="OpenSim.Framework.Serialization"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.CoreModules"/> <Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Region.OptionalModules"/> <Reference name="OpenSim.Region.OptionalModules"/>
@ -3093,8 +3096,8 @@
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Region.ClientStack.LindenCaps"/> <Reference name="OpenSim.Region.ClientStack.LindenCaps"/>
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
@ -3150,9 +3153,9 @@
<Reference name="OpenMetaverseTypes" path="../../../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../../../bin/"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Framework.Servers"/> <Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Framework.Statistics"/>
<Reference name="OpenSim.Region.ClientStack.LindenCaps"/> <Reference name="OpenSim.Region.ClientStack.LindenCaps"/>
<Reference name="OpenSim.Region.ClientStack.LindenUDP"/> <Reference name="OpenSim.Region.ClientStack.LindenUDP"/>
<Reference name="OpenSim.Region.CoreModules"/> <Reference name="OpenSim.Region.CoreModules"/>
@ -3187,7 +3190,7 @@
<Reference name="OpenMetaverseTypes" path="../../../../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../../../../bin/"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Statistics"/> <Reference name="OpenSim.Framework.Monitoring"/>
<Reference name="OpenSim.Region.ClientStack"/> <Reference name="OpenSim.Region.ClientStack"/>
<Reference name="OpenSim.Region.ClientStack.LindenUDP"/> <Reference name="OpenSim.Region.ClientStack.LindenUDP"/>
<Reference name="OpenSim.Region.CoreModules"/> <Reference name="OpenSim.Region.CoreModules"/>