merge crap gerge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork

Conflicts:
	bin/Regions/Regions.ini.example
	bin/lib32/BulletSim.dll
	bin/lib32/libBulletSim.so
	bin/lib64/BulletSim.dll
	bin/lib64/libBulletSim.so
avinationmerge
ubit 2012-08-02 18:21:08 +02:00
commit 254d3e1ad3
101 changed files with 3570 additions and 1367 deletions

2
.gitignore vendored
View File

@ -44,6 +44,8 @@ bin/Physics*
bin/Terrain* bin/Terrain*
bin/Regions/* bin/Regions/*
bin/UserAssets bin/UserAssets
bin/assetcache
bin/maptiles
bin/estate_settings.xml bin/estate_settings.xml
bin/config-include/CenomeCache.ini bin/config-include/CenomeCache.ini
bin/config-include/FlotsamCache.ini bin/config-include/FlotsamCache.ini

View File

@ -66,6 +66,19 @@ namespace OpenSim.Framework
IConfigSource Config { get; } IConfigSource Config { get; }
/// <summary>
/// Are logins enabled on this simulator?
/// </summary>
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

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

@ -482,9 +482,16 @@ namespace OpenSim.Framework
MainConsole.Instance.Output("=====================================\n"); MainConsole.Instance.Output("=====================================\n");
if (name == String.Empty) if (name == String.Empty)
{
while (name.Trim() == string.Empty)
{
name = MainConsole.Instance.CmdPrompt("New region name", name); name = MainConsole.Instance.CmdPrompt("New region name", name);
if (name == String.Empty) if (name.Trim() == string.Empty)
throw new Exception("Cannot interactively create region with no name"); {
MainConsole.Instance.Output("Cannot interactively create region with no name");
}
}
}
source.AddConfig(name); source.AddConfig(name);
@ -515,15 +522,20 @@ namespace OpenSim.Framework
// //
allKeys.Remove("RegionUUID"); allKeys.Remove("RegionUUID");
string regionUUID = config.GetString("RegionUUID", string.Empty); string regionUUID = config.GetString("RegionUUID", string.Empty);
if (regionUUID == String.Empty) if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
{ {
UUID newID = UUID.Random(); UUID newID = UUID.Random();
while (RegionID == UUID.Zero)
{
regionUUID = MainConsole.Instance.CmdPrompt("RegionUUID", newID.ToString()); regionUUID = MainConsole.Instance.CmdPrompt("RegionUUID", newID.ToString());
if (!UUID.TryParse(regionUUID.Trim(), out RegionID))
{
MainConsole.Instance.Output("RegionUUID must be a valid UUID");
}
}
config.Set("RegionUUID", regionUUID); config.Set("RegionUUID", regionUUID);
} }
RegionID = new UUID(regionUUID);
originRegionID = RegionID; // What IS this?! (Needed for RegionCombinerModule?) originRegionID = RegionID; // What IS this?! (Needed for RegionCombinerModule?)
// Location // Location

View File

@ -40,9 +40,9 @@ 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 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;
/* /*

View File

@ -36,6 +36,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,13 +1140,13 @@ 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,
c.Name, c.Name,
c.RemoteEndPoint.ToString(),
c.CircuitCode.ToString(), c.CircuitCode.ToString(),
c.RemoteEndPoint.ToString(),
c.IsActive.ToString()))); c.IsActive.ToString())));
MainConsole.Instance.Output(cdt.ToString()); MainConsole.Instance.Output(cdt.ToString());
@ -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[0], 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;
@ -300,7 +300,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)
@ -318,7 +318,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>
@ -480,7 +483,7 @@ namespace OpenSim
scene.SnmpService.BootInfo("ScriptEngine started", scene); scene.SnmpService.BootInfo("ScriptEngine started", scene);
} }
m_sceneManager.Add(scene); SceneManager.Add(scene);
if (m_autoCreateClientStack) if (m_autoCreateClientStack)
{ {
@ -510,7 +513,6 @@ namespace OpenSim
} }
scene.Start(); scene.Start();
scene.StartScripts(); scene.StartScripts();
return clientServer; return clientServer;
@ -644,14 +646,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)
@ -693,7 +695,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);
} }
@ -706,13 +708,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);
} }
@ -724,7 +726,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);
} }
@ -781,6 +783,7 @@ namespace OpenSim
scene.LoadWorldMap(); scene.LoadWorldMap();
scene.PhysicsScene = GetPhysicsScene(scene.RegionInfo.RegionName); scene.PhysicsScene = GetPhysicsScene(scene.RegionInfo.RegionName);
scene.PhysicsScene.RequestAssetMethod = scene.PhysicsRequestAsset;
scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
scene.PhysicsScene.SetWaterLevel((float) regionInfo.RegionSettings.WaterHeight); scene.PhysicsScene.SetWaterLevel((float) regionInfo.RegionSettings.WaterHeight);
@ -980,7 +983,7 @@ namespace OpenSim
try try
{ {
m_sceneManager.Close(); SceneManager.Close();
} }
catch (Exception e) catch (Exception e)
{ {
@ -1005,7 +1008,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>
@ -1014,7 +1017,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;
@ -355,8 +355,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_animationSequenceNumber = 1; private int m_animationSequenceNumber = 1;
private bool m_SendLogoutPacketWhenClosing = true; private bool m_SendLogoutPacketWhenClosing = true;
private AgentUpdateArgs lastarg; private AgentUpdateArgs lastarg;
private bool m_IsActive = true;
private bool m_IsLoggingOut = false;
protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@ -428,16 +426,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public uint CircuitCode { get { return m_circuitCode; } } public uint CircuitCode { get { return m_circuitCode; } }
public int MoneyBalance { get { return m_moneyBalance; } } public int MoneyBalance { get { return m_moneyBalance; } }
public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } }
public bool IsActive
{ /// <summary>
get { return m_IsActive; } /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to
set { m_IsActive = value; } /// prevent race conditions by different threads calling Close().
} /// </summary>
public bool IsLoggingOut public bool IsActive { get; set; }
{
get { return m_IsLoggingOut; } /// <summary>
set { m_IsLoggingOut = value; } /// Used to synchronise threads when client is being closed.
} /// </summary>
public Object CloseSyncLock { get; private set; }
public bool IsLoggingOut { get; set; }
public bool DisableFacelights public bool DisableFacelights
{ {
@ -462,6 +463,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
// DebugPacketLevel = 1; // DebugPacketLevel = 1;
CloseSyncLock = new Object();
RegisterInterface<IClientIM>(this); RegisterInterface<IClientIM>(this);
RegisterInterface<IClientInventory>(this); RegisterInterface<IClientInventory>(this);
RegisterInterface<IClientChat>(this); RegisterInterface<IClientChat>(this);
@ -494,13 +497,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_prioritizer = new Prioritizer(m_scene); m_prioritizer = new Prioritizer(m_scene);
RegisterLocalPacketHandlers(); RegisterLocalPacketHandlers();
IsActive = true;
} }
#region Client Methods #region Client Methods
/// <summary> /// <summary>
/// Shut down the client view /// Close down the client view
/// </summary> /// </summary>
public void Close() public void Close()
{ {
@ -513,7 +518,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void Close(bool sendStop) public void Close(bool sendStop)
{ {
IsActive = false; IsActive = false;
// We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
// a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
lock (CloseSyncLock)
{
if (!IsActive)
return;
IsActive = false;
CloseWithoutChecks(sendStop);
}
}
/// <summary>
/// Closes down the client view without first checking whether it is active.
/// </summary>
/// <remarks>
/// This exists because LLUDPServer has to set IsActive = false in earlier synchronous code before calling
/// CloseWithoutIsActiveCheck asynchronously.
///
/// Callers must lock ClosingSyncLock before calling.
/// </remarks>
public void CloseWithoutChecks(bool sendStop)
{
m_log.DebugFormat( m_log.DebugFormat(
"[CLIENT]: Close has been called for {0} attached to scene {1}", "[CLIENT]: Close has been called for {0} attached to scene {1}",
Name, m_scene.RegionInfo.RegionName); Name, m_scene.RegionInfo.RegionName);
@ -3634,7 +3661,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
{ {
if (!IsActive) return; // We don't need to update inactive clients. // We don't need to update inactive clients.
if (!IsActive)
return;
CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate); CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate);
loc.Header.Reliable = false; loc.Header.Reliable = false;
@ -5267,7 +5296,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate); AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate);
AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply);
AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage, false); AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage);
AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship); AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship);
AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship); AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship);

View File

@ -279,7 +279,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;
@ -1181,12 +1181,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// regular client pings. /// regular client pings.
/// </remarks> /// </remarks>
/// <param name='client'></param> /// <param name='client'></param>
private void DeactivateClientDueToTimeout(IClientAPI client) private void DeactivateClientDueToTimeout(LLClientView client)
{
lock (client.CloseSyncLock)
{ {
// We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
// though it's set later on by LLClientView.Close()
client.IsActive = false;
m_log.WarnFormat( m_log.WarnFormat(
"[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}",
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName);
@ -1196,7 +1194,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!client.SceneAgent.IsChildAgent) if (!client.SceneAgent.IsChildAgent)
client.Kick("Simulator logged you out due to connection timeout"); client.Kick("Simulator logged you out due to connection timeout");
Util.FireAndForget(o => client.Close()); client.CloseWithoutChecks(true);
}
} }
private void IncomingPacketHandler() private void IncomingPacketHandler()

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

@ -626,10 +626,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.InventoryService.UpdateItem(item); m_scene.InventoryService.UpdateItem(item);
// this gets called when the agent logs off! // If the name of the object has been changed whilst attached then we want to update the inventory
// item in the viewer.
if (sp.ControllingClient != null) if (sp.ControllingClient != null)
sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0); sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
} }
grp.HasGroupChanged = false; // Prevent it being saved over and over grp.HasGroupChanged = false; // Prevent it being saved over and over
} }
// else // else

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
= (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); = (SceneObjectGroup)(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 = (SceneObjectGroup)(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

@ -96,7 +96,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnClientClosed += OnClientClosed; scene.EventManager.OnClientClosed += OnClientClosed;
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; // scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
} }
public void PostInitialise() public void PostInitialise()
@ -133,7 +133,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
private void OnNewClient(IClientAPI client) private void OnNewClient(IClientAPI client)
{ {
// Subscribe to instant messages // Subscribe to instant messages
client.OnInstantMessage += OnInstantMessage; // client.OnInstantMessage += OnInstantMessage;
client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
lock (m_ClientMap) lock (m_ClientMap)
@ -171,15 +171,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
ActiveGroupTitle); ActiveGroupTitle);
} }
private void OnInstantMessage(IClientAPI client, GridInstantMessage im) // private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
{ // {
} // }
private void OnGridInstantMessage(GridInstantMessage msg) // private void OnGridInstantMessage(GridInstantMessage msg)
{ // {
// Trigger the above event handler // // Trigger the above event handler
OnInstantMessage(null, msg); // OnInstantMessage(null, msg);
} // }
private void HandleUUIDGroupNameRequest(UUID id,IClientAPI remote_client) private void HandleUUIDGroupNameRequest(UUID id,IClientAPI remote_client)
{ {

View File

@ -143,11 +143,13 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
// m_log.DebugFormat( // m_log.DebugFormat(
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}", // "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
// toAgentID.ToString(), scene.RegionInfo.RegionName); // toAgentID.ToString(), scene.RegionInfo.RegionName);
ScenePresence sp = scene.GetScenePresence(toAgentID); ScenePresence sp = scene.GetScenePresence(toAgentID);
if (sp != null && !sp.IsChildAgent) if (sp != null && !sp.IsChildAgent)
{ {
// Local message // Local message
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID); m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID);
sp.ControllingClient.SendInstantMessage(im); sp.ControllingClient.SendInstantMessage(im);
// Message sent // Message sent
@ -159,13 +161,15 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
// try child avatar second // try child avatar second
foreach (Scene scene in m_Scenes) foreach (Scene scene in m_Scenes)
{ {
// m_log.DebugFormat( m_log.DebugFormat(
// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
ScenePresence sp = scene.GetScenePresence(toAgentID); ScenePresence sp = scene.GetScenePresence(toAgentID);
if (sp != null) if (sp != null)
{ {
// Local message // Local message
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID); m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID);
sp.ControllingClient.SendInstantMessage(im); sp.ControllingClient.SendInstantMessage(im);
// Message sent // Message sent
@ -174,10 +178,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
} }
} }
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
SendGridInstantMessageViaXMLRPC(im, result);
return; SendGridInstantMessageViaXMLRPC(im, result);
} }
private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result) private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)

View File

@ -313,8 +313,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
} }
} }
else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined || else if (
im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined) im.dialog == (byte)InstantMessageDialog.InventoryDeclined
|| im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined)
{ {
// Here, the recipient is local and we can assume that the // Here, the recipient is local and we can assume that the
// inventory is loaded. Courtesy of the above bulk update, // inventory is loaded. Courtesy of the above bulk update,

View File

@ -204,8 +204,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
m_Scene.AssetService.Store(asset); m_Scene.AssetService.Store(asset);
m_Scene.CreateNewInventoryItem(
m_Scene.CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate); remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
} }
else else
{ {

View File

@ -39,7 +39,7 @@ using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.Avatar.Attachments namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BinaryLoggingModule")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BinaryLoggingModule")]
public class BinaryLoggingModule : INonSharedRegionModule public class BinaryLoggingModule : INonSharedRegionModule

View File

@ -0,0 +1,161 @@
/*
* 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.IO;
using System.Text;
using log4net;
namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
{
/// <summary>
/// Class for writing a high performance, high volume log file.
/// Sometimes, to debug, one has a high volume logging to do and the regular
/// log file output is not appropriate.
/// Create a new instance with the parameters needed and
/// call Write() to output a line. Call Close() when finished.
/// If created with no parameters, it will not log anything.
/// </summary>
public class LogWriter : IDisposable
{
public bool Enabled { get; private set; }
private string m_logDirectory = ".";
private int m_logMaxFileTimeMin = 5; // 5 minutes
public String LogFileHeader { get; set; }
private StreamWriter m_logFile = null;
private TimeSpan m_logFileLife;
private DateTime m_logFileEndTime;
private Object m_logFileWriteLock = new Object();
// set externally when debugging. If let 'null', this does not write any error messages.
public ILog ErrorLogger = null;
private string LogHeader = "[LOG WRITER]";
/// <summary>
/// Create a log writer that will not write anything. Good for when not enabled
/// but the write statements are still in the code.
/// </summary>
public LogWriter()
{
Enabled = false;
m_logFile = null;
}
/// <summary>
/// Create a log writer instance.
/// </summary>
/// <param name="dir">The directory to create the log file in. May be 'null' for default.</param>
/// <param name="headr">The characters that begin the log file name. May be 'null' for default.</param>
/// <param name="maxFileTime">Maximum age of a log file in minutes. If zero, will set default.</param>
public LogWriter(string dir, string headr, int maxFileTime)
{
m_logDirectory = dir == null ? "." : dir;
LogFileHeader = headr == null ? "log-" : headr;
m_logMaxFileTimeMin = maxFileTime;
if (m_logMaxFileTimeMin < 1)
m_logMaxFileTimeMin = 5;
m_logFileLife = new TimeSpan(0, m_logMaxFileTimeMin, 0);
m_logFileEndTime = DateTime.Now + m_logFileLife;
Enabled = true;
}
public void Dispose()
{
this.Close();
}
public void Close()
{
Enabled = false;
if (m_logFile != null)
{
m_logFile.Close();
m_logFile.Dispose();
m_logFile = null;
}
}
public void Write(string line, params object[] args)
{
if (!Enabled) return;
Write(String.Format(line, args));
}
public void Write(string line)
{
if (!Enabled) return;
try
{
lock (m_logFileWriteLock)
{
DateTime now = DateTime.Now;
if (m_logFile == null || now > m_logFileEndTime)
{
if (m_logFile != null)
{
m_logFile.Close();
m_logFile.Dispose();
m_logFile = null;
}
// First log file or time has expired, start writing to a new log file
m_logFileEndTime = now + m_logFileLife;
string path = (m_logDirectory.Length > 0 ? m_logDirectory
+ System.IO.Path.DirectorySeparatorChar.ToString() : "")
+ String.Format("{0}{1}.log", LogFileHeader, now.ToString("yyyyMMddHHmmss"));
m_logFile = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write));
}
if (m_logFile != null)
{
StringBuilder buff = new StringBuilder(line.Length + 25);
buff.Append(now.ToString("yyyyMMddHHmmssfff"));
// buff.Append(now.ToString("yyyyMMddHHmmss"));
buff.Append(",");
buff.Append(line);
buff.Append("\r\n");
m_logFile.Write(buff.ToString());
}
}
}
catch (Exception e)
{
if (ErrorLogger != null)
{
ErrorLogger.ErrorFormat("{0}: FAILURE WRITING TO LOGFILE: {1}", LogHeader, e);
}
Enabled = false;
}
return;
}
}
}

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

@ -131,11 +131,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
m_enabled = true; m_enabled = true;
} }
///<summary>
///
///</summary>
///<summary> ///<summary>
/// ///
///</summary> ///</summary>
@ -149,10 +144,9 @@ 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.OnLoginsEnabled += OnLoginsEnabled; scene.EventManager.OnRegionReadyStatusChange += s => { if (s.Ready) UploadMapTile(s); };
} }
///<summary> ///<summary>
/// ///
///</summary> ///</summary>
@ -167,20 +161,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
#endregion ISharedRegionModule #endregion ISharedRegionModule
void OnLoginsEnabled(string regionName)
{
Scene scene = null;
foreach (Scene s in m_scenes.Values)
if (s.RegionInfo.RegionName == regionName)
{
scene = s;
break;
}
if (scene != null)
UploadMapTile(scene);
}
///<summary> ///<summary>
/// ///
///</summary> ///</summary>

View File

@ -129,18 +129,18 @@ namespace OpenSim.Region.CoreModules.World
switch (cmd[1]) switch (cmd[1])
{ {
case "enable": case "enable":
scene.LoginsDisabled = false; scene.LoginsEnabled = true;
MainConsole.Instance.Output(String.Format("Logins are enabled for region {0}", scene.RegionInfo.RegionName)); MainConsole.Instance.Output(String.Format("Logins are enabled for region {0}", scene.RegionInfo.RegionName));
break; break;
case "disable": case "disable":
scene.LoginsDisabled = true; scene.LoginsEnabled = false;
MainConsole.Instance.Output(String.Format("Logins are disabled for region {0}", scene.RegionInfo.RegionName)); MainConsole.Instance.Output(String.Format("Logins are disabled for region {0}", scene.RegionInfo.RegionName));
break; break;
case "status": case "status":
if (scene.LoginsDisabled) if (scene.LoginsEnabled)
MainConsole.Instance.Output(String.Format("Login in {0} are disabled", scene.RegionInfo.RegionName));
else
MainConsole.Instance.Output(String.Format("Login in {0} are enabled", scene.RegionInfo.RegionName)); MainConsole.Instance.Output(String.Format("Login in {0} are enabled", scene.RegionInfo.RegionName));
else
MainConsole.Instance.Output(String.Format("Login in {0} are disabled", scene.RegionInfo.RegionName));
break; break;
default: default:
MainConsole.Instance.Output("Syntax: login enable|disable|status"); MainConsole.Instance.Output("Syntax: login enable|disable|status");

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

@ -119,17 +119,20 @@ namespace OpenSim.Region.CoreModules.World.Sound
m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
{ {
double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); double dis = Util.GetDistanceTo(sp.AbsolutePosition, position);
if (dis > 100.0) // Max audio distance if (dis > 100.0) // Max audio distance
return; return;
float thisSpGain;
// Scale by distance // Scale by distance
if (radius == 0) if (radius == 0)
gain = (float)((double)gain * ((100.0 - dis) / 100.0)); thisSpGain = (float)((double)gain * ((100.0 - dis) / 100.0));
else else
gain = (float)((double)gain * ((radius - dis) / radius)); thisSpGain = (float)((double)gain * ((radius - dis) / radius));
sp.ControllingClient.SendTriggeredSound( sp.ControllingClient.SendTriggeredSound(
soundId, ownerID, objectID, parentID, handle, position, (float)gain); soundId, ownerID, objectID, parentID, handle, position, thisSpGain);
}); });
} }
} }

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

@ -25,14 +25,23 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using OpenSim.Framework;
namespace OpenSim.Region.Framework.Interfaces namespace OpenSim.Region.Framework.Interfaces
{ {
public interface IRegionReadyModule public interface IRegionReadyModule
{ {
void OarLoadingAlert(string msg); void OarLoadingAlert(string msg);
/// <summary>
/// Trigger region ready status manually.
/// </summary>
/// <remarks>
/// This should be called by the scene if the IRegionReadyModule has set Scene.LoginLock == true
/// </remarks>
/// <param name='scene'></param>
void TriggerRegionReady(IScene scene);
} }
} }

View File

@ -40,8 +40,6 @@ 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.

View File

@ -67,6 +67,10 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="key"></param> /// <param name="key"></param>
void DispatchReply(UUID scriptId, int code, string text, string key); void DispatchReply(UUID scriptId, int code, string text, string key);
/// For constants
void RegisterConstant(string cname, object value);
object LookupModConstant(string cname);
// For use ONLY by the script API // For use ONLY by the script API
void RaiseEvent(UUID script, string id, string module, string command, string key); void RaiseEvent(UUID script, string id, string module, string command, string key);
} }

View File

@ -551,11 +551,5 @@ namespace OpenSim.Region.Framework.Scenes.Animation
SendAnimPack(animIDs, sequenceNums, objectIDs); SendAnimPack(animIDs, sequenceNums, objectIDs);
} }
public void Close()
{
m_animations = null;
m_scenePresence = null;
}
} }
} }

View File

@ -500,15 +500,24 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void RegionHeartbeatEnd(Scene scene); public delegate void RegionHeartbeatEnd(Scene scene);
public event RegionHeartbeatEnd OnRegionHeartbeatEnd; public event RegionHeartbeatEnd OnRegionHeartbeatEnd;
public delegate void LoginsEnabled(string regionName);
/// <summary> /// <summary>
/// This should only fire in all circumstances if the RegionReady module is active. /// Fired when logins to a region are enabled or disabled.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// TODO: Fire this even when the RegionReady module is not active. ///
/// </remarks> /// </remarks>
public event LoginsEnabled OnLoginsEnabled; /// Fired
public event RegionLoginsStatusChange OnRegionLoginsStatusChange;
public delegate void RegionLoginsStatusChange(IScene scene);
/// <summary>
/// Fired when a region is considered ready for use.
/// </summary>
/// <remarks>
/// A region is considered ready when startup operations such as loading of scripts already on the region
/// have been completed.
/// </remarks>
public event Action<IScene> OnRegionReadyStatusChange;
public delegate void PrimsLoaded(Scene s); public delegate void PrimsLoaded(Scene s);
public event PrimsLoaded OnPrimsLoaded; public event PrimsLoaded OnPrimsLoaded;
@ -2502,21 +2511,42 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void TriggerLoginsEnabled (string regionName) public void TriggerRegionLoginsStatusChange(IScene scene)
{ {
LoginsEnabled handler = OnLoginsEnabled; RegionLoginsStatusChange handler = OnRegionLoginsStatusChange;
if ( handler != null) if (handler != null)
{ {
foreach (LoginsEnabled d in handler.GetInvocationList()) foreach (RegionLoginsStatusChange d in handler.GetInvocationList())
{ {
try try
{ {
d(regionName); d(scene);
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("[EVENT MANAGER]: Delegate for LoginsEnabled failed - continuing {0} - {1}", m_log.ErrorFormat("[EVENT MANAGER]: Delegate for OnRegionLoginsStatusChange failed - continuing {0} - {1}",
e.Message, e.StackTrace);
}
}
}
}
public void TriggerRegionReadyStatusChange(IScene scene)
{
Action<IScene> handler = OnRegionReadyStatusChange;
if (handler != null)
{
foreach (Action<IScene> d in handler.GetInvocationList())
{
try
{
d(scene);
}
catch (Exception e)
{
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

@ -811,16 +811,20 @@ namespace OpenSim.Region.Framework.Scenes
&& oldAgentID == LibraryService.LibraryRootFolder.Owner)) && oldAgentID == LibraryService.LibraryRootFolder.Owner))
{ {
CreateNewInventoryItem( CreateNewInventoryItem(
remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, remoteClient, item.CreatorId, item.CreatorData, newFolderID,
item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch()); newName, item.Description, item.Flags, callbackID, asset, (sbyte)item.InvType,
item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions,
item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
} }
else else
{ {
// If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item. // If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0) && (m_permissions.BypassPermissions() || m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID))) if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0)
&& (m_permissions.BypassPermissions()
|| m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID)))
{ {
CreateNewInventoryItem( CreateNewInventoryItem(
remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Description, item.Flags, callbackID,
asset, (sbyte) item.InvType, asset, (sbyte) item.InvType,
item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions, item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions,
item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch()); item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
@ -885,32 +889,50 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary> /// <summary>
/// Create a new inventory item. /// Create a new inventory item.
/// </summary> /// </summary>
/// <param name="remoteClient"></param> /// <param name="remoteClient">Client creating this inventory item.</param>
/// <param name="folderID"></param> /// <param name="creatorID"></param>
/// <param name="callbackID"></param> /// <param name="creatorData"></param>
/// <param name="asset"></param> /// <param name="folderID">UUID of folder in which this item should be placed.</param>
/// <param name="invType"></param> /// <param name="name">Item name.</para>
/// <param name="nextOwnerMask"></param> /// <param name="description">Item description.</param>
public void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, /// <param name="flags">Item flags</param>
/// <param name="callbackID">Generated by the client.</para>
/// <param name="asset">Asset to which this item refers.</param>
/// <param name="invType">Type of inventory item.</param>
/// <param name="nextOwnerMask">Next owner pemrissions mask.</param>
/// <param name="creationDate">Unix timestamp at which this item was created.</param>
public void CreateNewInventoryItem(
IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
string name, string description, uint flags, uint callbackID,
AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate) AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
{ {
CreateNewInventoryItem( CreateNewInventoryItem(
remoteClient, creatorID, creatorData, folderID, name, flags, callbackID, asset, invType, remoteClient, creatorID, creatorData, folderID, name, description, flags, callbackID, asset, invType,
(uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate); (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate);
} }
/// <summary> /// <summary>
/// Create a new Inventory Item /// Create a new Inventory Item
/// </summary> /// </summary>
/// <param name="remoteClient"></param> /// <param name="remoteClient">Client creating this inventory item.</param>
/// <param name="folderID"></param> /// <param name="creatorID"></param>
/// <param name="callbackID"></param> /// <param name="creatorData"></param>
/// <param name="asset"></param> /// <param name="folderID">UUID of folder in which this item should be placed.</param>
/// <param name="invType"></param> /// <param name="name">Item name.</para>
/// <param name="nextOwnerMask"></param> /// <param name="description">Item description.</param>
/// <param name="creationDate"></param> /// <param name="flags">Item flags</param>
/// <param name="callbackID">Generated by the client.</para>
/// <param name="asset">Asset to which this item refers.</param>
/// <param name="invType">Type of inventory item.</param>
/// <param name="baseMask">Base permissions mask.</param>
/// <param name="currentMask">Current permissions mask.</param>
/// <param name="everyoneMask">Everyone permissions mask.</param>
/// <param name="nextOwnerMask">Next owner pemrissions mask.</param>
/// <param name="groupMask">Group permissions mask.</param>
/// <param name="creationDate">Unix timestamp at which this item was created.</param>
private void CreateNewInventoryItem( private void CreateNewInventoryItem(
IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType, IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID,
string name, string description, uint flags, uint callbackID, AssetBase asset, sbyte invType,
uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate) uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate)
{ {
InventoryItemBase item = new InventoryItemBase(); InventoryItemBase item = new InventoryItemBase();
@ -919,8 +941,8 @@ namespace OpenSim.Region.Framework.Scenes
item.CreatorData = creatorData; item.CreatorData = creatorData;
item.ID = UUID.Random(); item.ID = UUID.Random();
item.AssetID = asset.FullID; item.AssetID = asset.FullID;
item.Description = asset.Description;
item.Name = name; item.Name = name;
item.Description = description;
item.Flags = flags; item.Flags = flags;
item.AssetType = asset.Type; item.AssetType = asset.Type;
item.InvType = invType; item.InvType = invType;
@ -1002,7 +1024,8 @@ namespace OpenSim.Region.Framework.Scenes
asset.Description = description; asset.Description = description;
CreateNewInventoryItem( CreateNewInventoryItem(
remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType, remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
name, description, 0, callbackID, asset, invType,
(uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All,
(uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch()); (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch());
} }

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;
@ -129,9 +130,10 @@ namespace OpenSim.Region.Framework.Scenes
public bool m_strictAccessControl = true; public bool m_strictAccessControl = true;
public bool m_seeIntoBannedRegion = false; public bool m_seeIntoBannedRegion = false;
public int MaxUndoCount = 5; public int MaxUndoCount = 5;
// Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
public bool LoginLock = false; public bool LoginLock = false;
public bool LoginsDisabled = true;
public bool StartDisabled = false; public bool StartDisabled = false;
public bool LoadingPrims; public bool LoadingPrims;
public IXfer XferManager; public IXfer XferManager;
@ -727,6 +729,8 @@ namespace OpenSim.Region.Framework.Scenes
{ {
IConfig startupConfig = m_config.Configs["Startup"]; IConfig startupConfig = m_config.Configs["Startup"];
StartDisabled = startupConfig.GetBoolean("StartDisabled", false);
m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance); m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance);
m_useBackup = startupConfig.GetBoolean("UseSceneBackup", m_useBackup); m_useBackup = startupConfig.GetBoolean("UseSceneBackup", m_useBackup);
if (!m_useBackup) if (!m_useBackup)
@ -1229,15 +1233,17 @@ namespace OpenSim.Region.Framework.Scenes
avatar.ControllingClient.SendShutdownConnectionNotice(); avatar.ControllingClient.SendShutdownConnectionNotice();
}); });
// Stop updating the scene objects and agents.
m_shuttingDown = true;
// Wait here, or the kick messages won't actually get to the agents before the scene terminates. // Wait here, or the kick messages won't actually get to the agents before the scene terminates.
// We also need to wait to avoid a race condition with the scene update loop which might not yet
// have checked ShuttingDown.
Thread.Sleep(500); Thread.Sleep(500);
// Stop all client threads. // Stop all client threads.
ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
// Stop updating the scene objects and agents.
m_shuttingDown = true;
m_log.Debug("[SCENE]: Persisting changed objects"); m_log.Debug("[SCENE]: Persisting changed objects");
EventManager.TriggerSceneShuttingDown(this); EventManager.TriggerSceneShuttingDown(this);
@ -1252,6 +1258,15 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGraph.Close(); m_sceneGraph.Close();
if (PhysicsScene != null)
{
PhysicsScene phys = PhysicsScene;
// remove the physics engine from both Scene and SceneGraph
PhysicsScene = null;
phys.Dispose();
phys = null;
}
if (!GridService.DeregisterRegion(RegionInfo.RegionID)) if (!GridService.DeregisterRegion(RegionInfo.RegionID))
m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name); m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
@ -1530,7 +1545,7 @@ namespace OpenSim.Region.Framework.Scenes
// landMS = Util.EnvironmentTickCountSubtract(ldMS); // landMS = Util.EnvironmentTickCountSubtract(ldMS);
//} //}
if (LoginsDisabled && Frame == 20) if (!LoginsEnabled && Frame == 20)
{ {
// m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
@ -1539,30 +1554,33 @@ namespace OpenSim.Region.Framework.Scenes
// allocations, and there is no more work to be done until someone logs in // allocations, and there is no more work to be done until someone logs in
GC.Collect(); GC.Collect();
IConfig startupConfig = m_config.Configs["Startup"]; if (!LoginLock)
if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) {
if (!StartDisabled)
{
m_log.InfoFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
LoginsEnabled = true;
}
m_sceneGridService.InformNeighborsThatRegionisUp(
RequestModuleInterface<INeighbourService>(), RegionInfo);
// Region ready should always be set
Ready = true;
}
else
{ {
// This handles a case of a region having no scripts for the RegionReady module // This handles a case of a region having no scripts for the RegionReady module
if (m_sceneGraph.GetActiveScriptsCount() == 0) if (m_sceneGraph.GetActiveScriptsCount() == 0)
{ {
// need to be able to tell these have changed in RegionReady // In this case, we leave it to the IRegionReadyModule to enable logins
LoginLock = false;
EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
}
// For RegionReady lockouts // LoginLock can currently only be set by a region module implementation.
if (!LoginLock) // If somehow this hasn't been done then the quickest way to bugfix is to see the
{ // NullReferenceException
m_log.InfoFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); IRegionReadyModule rrm = RequestModuleInterface<IRegionReadyModule>();
LoginsDisabled = false; rrm.TriggerRegionReady(this);
} }
m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
}
else
{
StartDisabled = true;
LoginsDisabled = true;
} }
} }
} }
@ -3477,25 +3495,31 @@ namespace OpenSim.Region.Framework.Scenes
if (AgentTransactionsModule != null) if (AgentTransactionsModule != null)
AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
avatar.Close();
m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
m_log.Debug("[Scene] The avatar has left the building"); m_log.Debug("[Scene] The avatar has left the building");
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error( m_log.Error(
string.Format("[SCENE]: Exception removing {0} from {1}, ", avatar.Name, RegionInfo.RegionName), e); string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e);
} }
finally finally
{
try
{ {
// Always clean these structures up so that any failure above doesn't cause them to remain in the // Always clean these structures up so that any failure above doesn't cause them to remain in the
// scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
// the same cleanup exception continually. // the same cleanup exception continually.
// TODO: This should probably extend to the whole method, but we don't want to also catch the NRE
// since this would hide the underlying failure and other associated problems.
m_sceneGraph.RemoveScenePresence(agentID); m_sceneGraph.RemoveScenePresence(agentID);
m_clientManager.Remove(agentID); m_clientManager.Remove(agentID);
avatar.Close();
}
catch (Exception e)
{
m_log.Error(
string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e);
}
} }
//m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
@ -3609,7 +3633,7 @@ namespace OpenSim.Region.Framework.Scenes
agent.startpos agent.startpos
); );
if (LoginsDisabled) if (!LoginsEnabled)
{ {
reason = "Logins Disabled"; reason = "Logins Disabled";
return false; return false;
@ -3666,8 +3690,8 @@ namespace OpenSim.Region.Framework.Scenes
// We have a zombie from a crashed session. // We have a zombie from a crashed session.
// Or the same user is trying to be root twice here, won't work. // Or the same user is trying to be root twice here, won't work.
// Kill it. // Kill it.
m_log.DebugFormat( m_log.WarnFormat(
"[SCENE]: Zombie scene presence detected for {0} {1} in {2}", "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
sp.Name, sp.UUID, RegionInfo.RegionName); sp.Name, sp.UUID, RegionInfo.RegionName);
sp.ControllingClient.Close(); sp.ControllingClient.Close();
@ -4657,6 +4681,23 @@ namespace OpenSim.Region.Framework.Scenes
return m_sceneGraph.GetScenePresence(localID); return m_sceneGraph.GetScenePresence(localID);
} }
/// <summary>
/// Gets all the scene presences in this scene.
/// </summary>
/// <remarks>
/// This method will return both root and child scene presences.
///
/// Consider using ForEachScenePresence() or ForEachRootScenePresence() if possible since these will not
/// involving creating a new List object.
/// </remarks>
/// <returns>
/// A list of the scene presences. Adding or removing from the list will not affect the presences in the scene.
/// </returns>
public List<ScenePresence> GetScenePresences()
{
return new List<ScenePresence>(m_sceneGraph.GetScenePresences());
}
/// <summary> /// <summary>
/// Performs action on all avatars in the scene (root scene presences) /// Performs action on all avatars in the scene (root scene presences)
/// Avatars may be an NPC or a 'real' client. /// Avatars may be an NPC or a 'real' client.
@ -5775,5 +5816,21 @@ Environment.Exit(1);
{ {
GC.Collect(); GC.Collect();
} }
// Wrappers to get physics modules retrieve assets. Has to be done this way
// because we can't assign the asset service to physics directly - at the
// time physics are instantiated it's not registered but it will be by
// the time the first prim exists.
public void PhysicsRequestAsset(UUID assetID, AssetReceivedDelegate callback)
{
AssetService.Get(assetID.ToString(), callback, PhysicsAssetReceived);
}
private void PhysicsAssetReceived(string id, Object sender, AssetBase asset)
{
AssetReceivedDelegate callback = (AssetReceivedDelegate)sender;
callback(asset);
}
} }
} }

View File

@ -106,6 +106,42 @@ namespace OpenSim.Region.Framework.Scenes
protected readonly ClientManager m_clientManager = new ClientManager(); protected readonly ClientManager m_clientManager = new ClientManager();
public bool LoginsEnabled
{
get
{
return m_loginsEnabled;
}
set
{
if (m_loginsEnabled != value)
{
m_loginsEnabled = value;
EventManager.TriggerRegionLoginsStatusChange(this);
}
}
}
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

@ -848,7 +848,7 @@ namespace OpenSim.Region.Framework.Scenes
/// pass a delegate to ForEachScenePresence. /// pass a delegate to ForEachScenePresence.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private List<ScenePresence> GetScenePresences() protected internal List<ScenePresence> GetScenePresences()
{ {
return m_scenePresenceArray; return m_scenePresenceArray;
} }

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
{ {
@ -128,9 +170,11 @@ namespace OpenSim.Region.Framework.Scenes
public void Add(Scene scene) public void Add(Scene scene)
{ {
scene.OnRestart += HandleRestart; lock (m_localScenes)
m_localScenes.Add(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, scene); m_localScenes.Add(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, scene);
scene.OnRestart += HandleRestart;
scene.EventManager.OnRegionReadyStatusChange += HandleRegionReadyStatusChange;
} }
public void HandleRestart(RegionInfo rdata) public void HandleRestart(RegionInfo rdata)
@ -138,12 +182,19 @@ namespace OpenSim.Region.Framework.Scenes
m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main");
int RegionSceneElement = -1; int RegionSceneElement = -1;
lock (m_localScenes)
m_localScenes.Remove(rdata.RegionID); m_localScenes.Remove(rdata.RegionID);
// Send signal to main that we're restarting this sim. // Send signal to main that we're restarting this sim.
OnRestartSim(rdata); OnRestartSim(rdata);
} }
private void HandleRegionReadyStatusChange(IScene scene)
{
lock (m_localScenes)
AllRegionsReady = m_localScenes.FindAll(s => !s.Ready).Count == 0;
}
public void SendSimOnlineNotification(ulong regionHandle) public void SendSimOnlineNotification(ulong regionHandle)
{ {
RegionInfo Result = null; RegionInfo Result = null;
@ -483,6 +534,7 @@ namespace OpenSim.Region.Framework.Scenes
public void CloseScene(Scene scene) public void CloseScene(Scene scene)
{ {
lock (m_localScenes)
m_localScenes.Remove(scene.RegionInfo.RegionID); m_localScenes.Remove(scene.RegionInfo.RegionID);
scene.Close(); scene.Close();

View File

@ -1991,7 +1991,7 @@ namespace OpenSim.Region.Framework.Scenes
try try
{ {
if (!m_scene.ShuttingDown || // if shutting down then there will be nothing to handle the return so leave till next restart if (!m_scene.ShuttingDown || // if shutting down then there will be nothing to handle the return so leave till next restart
m_scene.LoginsDisabled || // We're starting up or doing maintenance, don't mess with things !m_scene.LoginsEnabled || // We're starting up or doing maintenance, don't mess with things
m_scene.LoadingPrims) // Land may not be valid yet m_scene.LoadingPrims) // Land may not be valid yet
{ {

View File

@ -110,15 +110,10 @@ namespace OpenSim.Region.Framework.Scenes
public UUID currentParcelUUID = UUID.Zero; public UUID currentParcelUUID = UUID.Zero;
protected ScenePresenceAnimator m_animator;
/// <value> /// <value>
/// The animator for this avatar /// The animator for this avatar
/// </value> /// </value>
public ScenePresenceAnimator Animator public ScenePresenceAnimator Animator { get; private set; }
{
get { return m_animator; }
private set { m_animator = value; }
}
/// <summary> /// <summary>
/// Attachments recorded on this avatar. /// Attachments recorded on this avatar.
@ -2763,7 +2758,6 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID);
avatar.ControllingClient.SendAvatarDataImmediate(this); avatar.ControllingClient.SendAvatarDataImmediate(this);
if (Animator != null)
Animator.SendAnimPackToClient(avatar.ControllingClient); Animator.SendAnimPackToClient(avatar.ControllingClient);
} }
@ -3440,6 +3434,16 @@ namespace OpenSim.Region.Framework.Scenes
if (IsChildAgent) if (IsChildAgent)
return; return;
//if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
// The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
// as of this comment the interval is set in AddToPhysicalScene
// if (m_updateCount > 0)
// {
Animator.UpdateMovementAnimations();
// m_updateCount--;
// }
CollisionEventUpdate collisionData = (CollisionEventUpdate)e; CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
@ -3453,7 +3457,7 @@ namespace OpenSim.Region.Framework.Scenes
// m_lastColCount = coldata.Count; // m_lastColCount = coldata.Count;
// } // }
if (coldata.Count != 0 && Animator != null) if (coldata.Count != 0)
{ {
switch (Animator.CurrentMovementAnimation) switch (Animator.CurrentMovementAnimation)
{ {
@ -3565,7 +3569,7 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.SendHealth(Health); ControllingClient.SendHealth(Health);
} }
public void Close() protected internal void Close()
{ {
// Clear known regions // Clear known regions
KnownRegions = new Dictionary<ulong, string>(); KnownRegions = new Dictionary<ulong, string>();
@ -3581,9 +3585,6 @@ namespace OpenSim.Region.Framework.Scenes
// m_reprioritizationTimer.Dispose(); // m_reprioritizationTimer.Dispose();
RemoveFromPhysicalScene(); RemoveFromPhysicalScene();
if(Animator != null)
Animator.Close();
Animator = null;
} }
public void AddAttachment(SceneObjectGroup gobj) public void AddAttachment(SceneObjectGroup gobj)

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

@ -53,48 +53,83 @@ namespace OpenSim.Region.Framework.Scenes.Tests
/// Scene presence tests /// Scene presence tests
/// </summary> /// </summary>
[TestFixture] [TestFixture]
public class ScenePresenceAgentTests public class ScenePresenceAgentTests : OpenSimTestCase
{ {
public Scene scene, scene2, scene3; // public Scene scene, scene2, scene3;
public UUID agent1, agent2, agent3; // public UUID agent1, agent2, agent3;
public static Random random; // public static Random random;
public ulong region1,region2,region3; // public ulong region1, region2, region3;
public AgentCircuitData acd1; // public AgentCircuitData acd1;
public SceneObjectGroup sog1, sog2, sog3; // public TestClient testclient;
public TestClient testclient;
[TestFixtureSetUp] // [TestFixtureSetUp]
public void Init() // public void Init()
// {
//// TestHelpers.InMethod();
////
//// SceneHelpers sh = new SceneHelpers();
////
//// scene = sh.SetupScene("Neighbour x", UUID.Random(), 1000, 1000);
//// scene2 = sh.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000);
//// scene3 = sh.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000);
////
//// ISharedRegionModule interregionComms = new LocalSimulationConnectorModule();
//// interregionComms.Initialise(new IniConfigSource());
//// interregionComms.PostInitialise();
//// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms);
//// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms);
//// SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms);
//
//// agent1 = UUID.Random();
//// agent2 = UUID.Random();
//// agent3 = UUID.Random();
//
//// region1 = scene.RegionInfo.RegionHandle;
//// region2 = scene2.RegionInfo.RegionHandle;
//// region3 = scene3.RegionInfo.RegionHandle;
// }
[Test]
public void TestCreateRootScenePresence()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
// TestHelpers.EnableLogging();
SceneHelpers sh = new SceneHelpers(); UUID spUuid = TestHelpers.ParseTail(0x1);
scene = sh.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); TestScene scene = new SceneHelpers().SetupScene();
scene2 = sh.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); SceneHelpers.AddScenePresence(scene, spUuid);
scene3 = sh.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000);
ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(spUuid), Is.Not.Null);
interregionComms.Initialise(new IniConfigSource()); Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1));
interregionComms.PostInitialise();
SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms);
SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms);
SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms);
agent1 = UUID.Random(); ScenePresence sp = scene.GetScenePresence(spUuid);
agent2 = UUID.Random(); Assert.That(sp, Is.Not.Null);
agent3 = UUID.Random(); Assert.That(sp.IsChildAgent, Is.False);
random = new Random(); Assert.That(sp.UUID, Is.EqualTo(spUuid));
sog1 = SceneHelpers.CreateSceneObject(1, agent1);
scene.AddSceneObject(sog1);
sog2 = SceneHelpers.CreateSceneObject(1, agent1);
scene.AddSceneObject(sog2);
sog3 = SceneHelpers.CreateSceneObject(1, agent1);
scene.AddSceneObject(sog3);
region1 = scene.RegionInfo.RegionHandle; Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1));
region2 = scene2.RegionInfo.RegionHandle; }
region3 = scene3.RegionInfo.RegionHandle;
[Test]
public void TestCreateDuplicateRootScenePresence()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
UUID spUuid = TestHelpers.ParseTail(0x1);
TestScene scene = new SceneHelpers().SetupScene();
SceneHelpers.AddScenePresence(scene, spUuid);
SceneHelpers.AddScenePresence(scene, spUuid);
Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(spUuid), Is.Not.Null);
Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1));
ScenePresence sp = scene.GetScenePresence(spUuid);
Assert.That(sp, Is.Not.Null);
Assert.That(sp.IsChildAgent, Is.False);
Assert.That(sp.UUID, Is.EqualTo(spUuid));
} }
[Test] [Test]
@ -106,9 +141,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
TestScene scene = new SceneHelpers().SetupScene(); TestScene scene = new SceneHelpers().SetupScene();
ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null);
Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1));
scene.IncomingCloseAgent(sp.UUID); scene.IncomingCloseAgent(sp.UUID);
Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
@ -266,99 +298,99 @@ namespace OpenSim.Region.Framework.Scenes.Tests
// but things are synchronous among them. So there should be // but things are synchronous among them. So there should be
// 3 threads in here. // 3 threads in here.
//[Test] //[Test]
public void T021_TestCrossToNewRegion() // public void T021_TestCrossToNewRegion()
{ // {
TestHelpers.InMethod(); // TestHelpers.InMethod();
//
scene.RegisterRegionWithGrid(); // scene.RegisterRegionWithGrid();
scene2.RegisterRegionWithGrid(); // scene2.RegisterRegionWithGrid();
//
// Adding child agent to region 1001 // // Adding child agent to region 1001
string reason; // string reason;
scene2.NewUserConnection(acd1,0, out reason); // scene2.NewUserConnection(acd1,0, out reason);
scene2.AddNewClient(testclient, PresenceType.User); // scene2.AddNewClient(testclient, PresenceType.User);
//
ScenePresence presence = scene.GetScenePresence(agent1); // ScenePresence presence = scene.GetScenePresence(agent1);
presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); // presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true);
//
ScenePresence presence2 = scene2.GetScenePresence(agent1); // ScenePresence presence2 = scene2.GetScenePresence(agent1);
//
// Adding neighbour region caps info to presence2 // // Adding neighbour region caps info to presence2
//
string cap = presence.ControllingClient.RequestClientInfo().CapsPath; // string cap = presence.ControllingClient.RequestClientInfo().CapsPath;
presence2.AddNeighbourRegion(region1, cap); // presence2.AddNeighbourRegion(region1, cap);
//
Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region."); // Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region.");
Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region."); // Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region.");
//
// Cross to x+1 // // Cross to x+1
presence.AbsolutePosition = new Vector3(Constants.RegionSize+1,3,100); // presence.AbsolutePosition = new Vector3(Constants.RegionSize+1,3,100);
presence.Update(); // presence.Update();
//
EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing"); // EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing");
//
// Mimicking communication between client and server, by waiting OK from client // // Mimicking communication between client and server, by waiting OK from client
// sent by TestClient.CrossRegion call. Originally, this is network comm. // // sent by TestClient.CrossRegion call. Originally, this is network comm.
if (!wh.WaitOne(5000,false)) // if (!wh.WaitOne(5000,false))
{ // {
presence.Update(); // presence.Update();
if (!wh.WaitOne(8000,false)) // if (!wh.WaitOne(8000,false))
throw new ArgumentException("1 - Timeout waiting for signal/variable."); // throw new ArgumentException("1 - Timeout waiting for signal/variable.");
} // }
//
// This is a TestClient specific method that fires OnCompleteMovementToRegion event, which // // This is a TestClient specific method that fires OnCompleteMovementToRegion event, which
// would normally be fired after receiving the reply packet from comm. done on the last line. // // would normally be fired after receiving the reply packet from comm. done on the last line.
testclient.CompleteMovement(); // testclient.CompleteMovement();
//
// Crossings are asynchronous // // Crossings are asynchronous
int timer = 10; // int timer = 10;
//
// Make sure cross hasn't already finished // // Make sure cross hasn't already finished
if (!presence.IsInTransit && !presence.IsChildAgent) // if (!presence.IsInTransit && !presence.IsChildAgent)
{ // {
// If not and not in transit yet, give it some more time // // If not and not in transit yet, give it some more time
Thread.Sleep(5000); // Thread.Sleep(5000);
} // }
//
// Enough time, should at least be in transit by now. // // Enough time, should at least be in transit by now.
while (presence.IsInTransit && timer > 0) // while (presence.IsInTransit && timer > 0)
{ // {
Thread.Sleep(1000); // Thread.Sleep(1000);
timer-=1; // timer-=1;
} // }
//
Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 2->1."); // Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 2->1.");
Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected."); // Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected.");
Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent."); // Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent.");
//
// Cross Back // // Cross Back
presence2.AbsolutePosition = new Vector3(-10, 3, 100); // presence2.AbsolutePosition = new Vector3(-10, 3, 100);
presence2.Update(); // presence2.Update();
//
if (!wh.WaitOne(5000,false)) // if (!wh.WaitOne(5000,false))
{ // {
presence2.Update(); // presence2.Update();
if (!wh.WaitOne(8000,false)) // if (!wh.WaitOne(8000,false))
throw new ArgumentException("2 - Timeout waiting for signal/variable."); // throw new ArgumentException("2 - Timeout waiting for signal/variable.");
} // }
testclient.CompleteMovement(); // testclient.CompleteMovement();
//
if (!presence2.IsInTransit && !presence2.IsChildAgent) // if (!presence2.IsInTransit && !presence2.IsChildAgent)
{ // {
// If not and not in transit yet, give it some more time // // If not and not in transit yet, give it some more time
Thread.Sleep(5000); // Thread.Sleep(5000);
} // }
//
// Enough time, should at least be in transit by now. // // Enough time, should at least be in transit by now.
while (presence2.IsInTransit && timer > 0) // while (presence2.IsInTransit && timer > 0)
{ // {
Thread.Sleep(1000); // Thread.Sleep(1000);
timer-=1; // timer-=1;
} // }
//
Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 1->2."); // Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 1->2.");
Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected."); // Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected.");
Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again."); // Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again.");
} // }
} }
} }

View File

@ -301,7 +301,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
sp.AbsolutePosition = preTeleportPosition; sp.AbsolutePosition = preTeleportPosition;
// Make sceneB refuse CreateAgent // Make sceneB refuse CreateAgent
sceneB.LoginsDisabled = true; sceneB.LoginsEnabled = false;
sceneA.RequestTeleportLocation( sceneA.RequestTeleportLocation(
sp.ControllingClient, sp.ControllingClient,

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(
@ -115,6 +110,12 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
"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",
"show throttles [full]", "show throttles [full]",
@ -373,14 +374,19 @@ 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",
@ -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",
@ -416,8 +423,6 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
{ {
scene.ForEachClient( scene.ForEachClient(
delegate(IClientAPI client) delegate(IClientAPI client)
{
if (client is IStatsCollector)
{ {
bool isChild = client.SceneAgent.IsChildAgent; bool isChild = client.SceneAgent.IsChildAgent;
if (isChild && !showChildren) if (isChild && !showChildren)
@ -433,6 +438,8 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding)); report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
if (client is IStatsCollector)
{
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

@ -47,7 +47,7 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PhysicsParameters")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PhysicsParameters")]
public class PhysicsParameters : ISharedRegionModule public class PhysicsParameters : ISharedRegionModule
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static string LogHeader = "[PHYSICS PARAMETERS]"; // private static string LogHeader = "[PHYSICS PARAMETERS]";
private List<Scene> m_scenes = new List<Scene>(); private List<Scene> m_scenes = new List<Scene>();

View File

@ -31,16 +31,14 @@ using System.Reflection;
using System.Net; using System.Net;
using System.IO; using System.IO;
using System.Text; using System.Text;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
using OpenSim.Services.Interfaces;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
namespace OpenSim.Region.OptionalModules.Scripting.RegionReady namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
{ {
@ -50,16 +48,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IConfig m_config = null; private IConfig m_config = null;
private bool m_ScriptRez;
private bool m_firstEmptyCompileQueue; private bool m_firstEmptyCompileQueue;
private bool m_oarFileLoading; private bool m_oarFileLoading;
private bool m_lastOarLoadedOk; private bool m_lastOarLoadedOk;
private int m_channelNotify = -1000; private int m_channelNotify = -1000;
private bool m_enabled = false; private bool m_enabled = false;
private bool m_disable_logins = false; private bool m_disable_logins;
private string m_uri = string.Empty; private string m_uri = string.Empty;
Scene m_scene = null; Scene m_scene;
#region INonSharedRegionModule interface #region INonSharedRegionModule interface
@ -93,53 +90,40 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
m_scene.RegisterModuleInterface<IRegionReadyModule>(this); m_scene.RegisterModuleInterface<IRegionReadyModule>(this);
m_ScriptRez = false;
m_firstEmptyCompileQueue = true; m_firstEmptyCompileQueue = true;
m_oarFileLoading = false; m_oarFileLoading = false;
m_lastOarLoadedOk = true; m_lastOarLoadedOk = true;
m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded; m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded;
m_scene.EventManager.OnRezScript += OnRezScript;
m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled;
m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName); m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName);
if (m_disable_logins == true) if (m_disable_logins)
{ {
scene.LoginLock = true; m_scene.LoginLock = true;
scene.LoginsDisabled = true; m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
m_log.InfoFormat("[RegionReady]: Region {0} - logins disabled during initialization.",m_scene.RegionInfo.RegionName);
if(m_uri != string.Empty) m_log.InfoFormat("[RegionReady]: Region {0} - LOGINS DISABLED DURING INITIALIZATION.", m_scene.Name);
if (m_uri != string.Empty)
{ {
RRAlert("disabled"); RRAlert("disabled");
} }
} }
} }
void OnRezScript (uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource)
{
if (!m_ScriptRez)
{
m_ScriptRez = true;
m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
m_scene.EventManager.OnRezScript -= OnRezScript;
}
}
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
if (!m_enabled) if (!m_enabled)
return; return;
m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue;
m_scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded; m_scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded;
m_scene.EventManager.OnLoginsEnabled -= OnLoginsEnabled;
if(m_uri != string.Empty) if (m_disable_logins)
{ m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue;
if (m_uri != string.Empty)
RRAlert("shutdown"); RRAlert("shutdown");
}
m_scene = null; m_scene = null;
} }
@ -159,7 +143,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
#endregion #endregion
void OnEmptyScriptCompileQueue(int numScriptsFailed, string message) void OnEmptyScriptCompileQueue(int numScriptsFailed, string message)
{ {
m_log.DebugFormat("[RegionReady]: Script compile queue empty!"); m_log.DebugFormat("[RegionReady]: Script compile queue empty!");
@ -193,75 +176,80 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); m_scene.RegionInfo.RegionName, c.Message, m_channelNotify);
m_scene.EventManager.TriggerOnChatBroadcast(this, c); m_scene.EventManager.TriggerOnChatBroadcast(this, c);
m_scene.EventManager.TriggerLoginsEnabled(m_scene.RegionInfo.RegionName);
m_scene.SceneGridService.InformNeighborsThatRegionisUp(m_scene.RequestModuleInterface<INeighbourService>(), m_scene.RegionInfo); TriggerRegionReady(m_scene);
} }
} }
void OnOarFileLoaded(Guid requestId, string message) void OnOarFileLoaded(Guid requestId, string message)
{ {
m_oarFileLoading = true; m_oarFileLoading = true;
if (message==String.Empty) if (message==String.Empty)
{ {
m_lastOarLoadedOk = true; m_lastOarLoadedOk = true;
} else { }
else
{
m_log.WarnFormat("[RegionReady]: Oar file load errors: {0}", message); m_log.WarnFormat("[RegionReady]: Oar file load errors: {0}", message);
m_lastOarLoadedOk = false; m_lastOarLoadedOk = false;
} }
} }
// This will be triggerd by Scene if we have no scripts /// <summary>
// m_ScriptsRezzing will be false if there were none /// This will be triggered by Scene directly if it contains no scripts on startup. Otherwise it is triggered
// else it will be true and we should wait on the /// when the script compile queue is empty after initial region startup.
// empty compile queue /// </summary>
void OnLoginsEnabled(string regionName) /// <param name='scene'></param>
public void TriggerRegionReady(IScene scene)
{ {
if (m_disable_logins == true) m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue;
{
if (m_scene.StartDisabled == false)
{
m_scene.LoginsDisabled = false;
m_scene.LoginLock = false; m_scene.LoginLock = false;
m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; if (!m_scene.StartDisabled)
{
m_scene.LoginsEnabled = true;
// m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
// m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
m_log.InfoFormat( m_log.InfoFormat(
"[RegionReady]: INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name); "[RegionReady]: INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name);
}
m_scene.SceneGridService.InformNeighborsThatRegionisUp(
m_scene.RequestModuleInterface<INeighbourService>(), m_scene.RegionInfo);
if (m_uri != string.Empty) if (m_uri != string.Empty)
{ {
RRAlert("enabled"); RRAlert("enabled");
} }
}
} m_scene.Ready = true;
} }
public void OarLoadingAlert(string msg) public void OarLoadingAlert(string msg)
{ {
// Let's bypass this for now until some better feedback can be established // Let's bypass this for now until some better feedback can be established
// //
return;
if (msg == "load") // if (msg == "load")
{ // {
m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue; // m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded; // m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded;
m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled; // m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled;
m_scene.EventManager.OnRezScript += OnRezScript; // m_scene.EventManager.OnRezScript += OnRezScript;
m_oarFileLoading = true; // m_oarFileLoading = true;
m_firstEmptyCompileQueue = true; // m_firstEmptyCompileQueue = true;
//
m_scene.LoginsDisabled = true; // m_scene.LoginsDisabled = true;
m_scene.LoginLock = true; // m_scene.LoginLock = true;
if ( m_uri != string.Empty ) // if ( m_uri != string.Empty )
{ // {
RRAlert("loading oar"); // RRAlert("loading oar");
RRAlert("disabled"); // RRAlert("disabled");
} // }
} // }
} }
public void RRAlert(string status) public void RRAlert(string status)

View File

@ -46,6 +46,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
private static readonly ILog m_log = private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Dictionary<string,object> m_constants = new Dictionary<string,object>();
#region ScriptInvocation #region ScriptInvocation
protected class ScriptInvocationData protected class ScriptInvocationData
{ {
@ -269,6 +271,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
Delegate fn = LookupScriptInvocation(fname); Delegate fn = LookupScriptInvocation(fname);
return fn.DynamicInvoke(olist.ToArray()); return fn.DynamicInvoke(olist.ToArray());
} }
/// <summary>
/// Operation to for a region module to register a constant to be used
/// by the script engine
/// </summary>
public void RegisterConstant(string cname, object value)
{
m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString());
lock (m_constants)
{
m_constants.Add(cname,value);
}
}
/// <summary>
/// Operation to check for a registered constant
/// </summary>
public object LookupModConstant(string cname)
{
// m_log.DebugFormat("[MODULE COMMANDS] lookup constant <{0}>",cname);
lock (m_constants)
{
object value = null;
if (m_constants.TryGetValue(cname,out value))
return value;
}
return null;
}
#endregion #endregion
} }

View File

@ -41,7 +41,7 @@ public class BSCharacter : PhysicsActor
private BSScene _scene; private BSScene _scene;
private String _avName; private String _avName;
private bool _stopped; // private bool _stopped;
private Vector3 _size; private Vector3 _size;
private Vector3 _scale; private Vector3 _scale;
private PrimitiveBaseShape _pbs; private PrimitiveBaseShape _pbs;
@ -134,9 +134,9 @@ public class BSCharacter : PhysicsActor
{ {
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
} }
// No one calls this method so I don't know what it could possibly mean
public override bool Stopped { public override bool Stopped {
get { return _stopped; } get { return false; }
} }
public override Vector3 Size { public override Vector3 Size {
get { return _size; } get { return _size; }
@ -391,16 +391,12 @@ public class BSCharacter : PhysicsActor
_mass = _density * _avatarVolume; _mass = _density * _avatarVolume;
} }
// Set to 'true' if the individual changed items should be checked
// (someday RequestPhysicsTerseUpdate() will take a bitmap of changed properties)
const bool SHOULD_CHECK_FOR_INDIVIDUAL_CHANGES = false;
// The physics engine says that properties have updated. Update same and inform // The physics engine says that properties have updated. Update same and inform
// the world that things have changed. // the world that things have changed.
public void UpdateProperties(EntityProperties entprop) public void UpdateProperties(EntityProperties entprop)
{ {
/*
bool changed = false; bool changed = false;
if (SHOULD_CHECK_FOR_INDIVIDUAL_CHANGES) {
// we assign to the local variables so the normal set action does not happen // we assign to the local variables so the normal set action does not happen
if (_position != entprop.Position) { if (_position != entprop.Position) {
_position = entprop.Position; _position = entprop.Position;
@ -428,16 +424,15 @@ public class BSCharacter : PhysicsActor
// loop that updates avatars. // loop that updates avatars.
// base.RequestPhysicsterseUpdate(); // base.RequestPhysicsterseUpdate();
} }
} */
else {
_position = entprop.Position; _position = entprop.Position;
_orientation = entprop.Rotation; _orientation = entprop.Rotation;
_velocity = entprop.Velocity; _velocity = entprop.Velocity;
_acceleration = entprop.Acceleration; _acceleration = entprop.Acceleration;
_rotationalVelocity = entprop.RotationalVelocity; _rotationalVelocity = entprop.RotationalVelocity;
// Avatars don't report theirr changes the usual way. Changes are checked for in the heartbeat loop.
// base.RequestPhysicsterseUpdate(); // base.RequestPhysicsterseUpdate();
} }
}
// Called by the scene when a collision with this object is reported // Called by the scene when a collision with this object is reported
// The collision, if it should be reported to the character, is placed in a collection // The collision, if it should be reported to the character, is placed in a collection

View File

@ -0,0 +1,125 @@
/*
* 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,
true /*useLinearReferenceFrameA*/, true /*disableCollisionsBetweenLinkedBodies*/));
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 SetCFMAndERP(float cfm, float erp)
{
bool ret = true;
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL);
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
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,184 @@
/*
* 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.
// Return 'true' if a constraint was found.
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;
}
// Remove any constraint between the passed bodies.
// Presumed there is only one such constraint possible.
// Return 'true' if a constraint was found and destroyed.
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;
}
// Remove all constraints that reference the passed body.
// Return 'true' if any constraints were destroyed.
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

@ -57,7 +57,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
private int frcount = 0; // Used to limit dynamics debug output to private int frcount = 0; // Used to limit dynamics debug output to
// every 100th frame // every 100th frame
// private BSScene m_parentScene = null;
private BSPrim m_prim; // the prim this dynamic controller belongs to private BSPrim m_prim; // the prim this dynamic controller belongs to
// Vehicle properties // Vehicle properties
@ -131,8 +130,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
m_type = Vehicle.TYPE_NONE; m_type = Vehicle.TYPE_NONE;
} }
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep)
{ {
DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
switch (pParam) switch (pParam)
{ {
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@ -229,8 +229,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
} }
}//end ProcessFloatVehicleParam }//end ProcessFloatVehicleParam
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep)
{ {
DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
switch (pParam) switch (pParam)
{ {
case Vehicle.ANGULAR_FRICTION_TIMESCALE: case Vehicle.ANGULAR_FRICTION_TIMESCALE:
@ -265,6 +266,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
{ {
DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
switch (pParam) switch (pParam)
{ {
case Vehicle.REFERENCE_FRAME: case Vehicle.REFERENCE_FRAME:
@ -278,6 +280,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
internal void ProcessVehicleFlags(int pParam, bool remove) internal void ProcessVehicleFlags(int pParam, bool remove)
{ {
DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
if (remove) if (remove)
{ {
if (pParam == -1) if (pParam == -1)
@ -434,6 +437,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
internal void ProcessTypeChange(Vehicle pType) internal void ProcessTypeChange(Vehicle pType)
{ {
DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
// Set Defaults For Type // Set Defaults For Type
m_type = pType; m_type = pType;
switch (pType) switch (pType)
@ -594,11 +598,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
break; break;
} }
}//end SetDefaultsForType }//end SetDefaultsForType
internal void Step(float pTimestep, BSScene pParentScene) internal void Step(float pTimestep)
{ {
if (m_type == Vehicle.TYPE_NONE) return; if (m_type == Vehicle.TYPE_NONE) return;
@ -606,21 +609,34 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (frcount > 100) if (frcount > 100)
frcount = 0; frcount = 0;
MoveLinear(pTimestep, pParentScene); MoveLinear(pTimestep);
MoveAngular(pTimestep); MoveAngular(pTimestep);
LimitRotation(pTimestep); LimitRotation(pTimestep);
DetailLog("{0},Dynamics,done,pos={1},force={2},velocity={3},angvel={4}",
m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
}// end Step }// end Step
private void MoveLinear(float pTimestep, BSScene _pParentScene) private void MoveLinear(float pTimestep)
{ {
if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant // requested m_linearMotorDirection is significant
// if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
if (m_linearMotorDirection.LengthSquared() > 0.0001f)
{ {
Vector3 origDir = m_linearMotorDirection;
Vector3 origVel = m_lastLinearVelocityVector;
// add drive to body // add drive to body
Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); // Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector? Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale);
// lastLinearVelocityVector is the current body velocity vector?
// RA: Not sure what the *10 is for. A correction for pTimestep?
// m_lastLinearVelocityVector += (addAmount*10);
m_lastLinearVelocityVector += addAmount;
// This will work temporarily, but we really need to compare speed on an axis // This will work temporarily, but we really need to compare speed on an axis
// KF: Limit body velocity to applied velocity? // KF: Limit body velocity to applied velocity?
// Limit the velocity vector to less than the last set linear motor direction
if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
@ -630,76 +646,93 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// decay applied velocity // decay applied velocity
Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
//Console.WriteLine("decay: " + decayfraction);
m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
//Console.WriteLine("actual: " + m_linearMotorDirection);
/*
Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/m_linearMotorTimescale;
m_lastLinearVelocityVector += addAmount;
float decayfraction = (1.0f - 1.0f / m_linearMotorDecayTimescale);
m_linearMotorDirection *= decayfraction;
*/
DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
} }
else else
{ // requested is not significant {
// if what remains of applied is small, zero it. // if what remains of applied is small, zero it.
if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) // if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
// m_lastLinearVelocityVector = Vector3.Zero;
m_linearMotorDirection = Vector3.Zero;
m_lastLinearVelocityVector = Vector3.Zero; m_lastLinearVelocityVector = Vector3.Zero;
} }
// convert requested object velocity to world-referenced vector // convert requested object velocity to world-referenced vector
m_dir = m_lastLinearVelocityVector; Quaternion rotq = m_prim.Orientation;
Quaternion rot = m_prim.Orientation; m_dir = m_lastLinearVelocityVector * rotq;
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
m_dir *= rotq; // apply obj rotation to velocity vector
// add Gravity andBuoyancy // Add the various forces into m_dir which will be our new direction vector (velocity)
// add Gravity and Buoyancy
// KF: So far I have found no good method to combine a script-requested // KF: So far I have found no good method to combine a script-requested
// .Z velocity and gravity. Therefore only 0g will used script-requested // .Z velocity and gravity. Therefore only 0g will used script-requested
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
Vector3 grav = Vector3.Zero; Vector3 grav = Vector3.Zero;
// There is some gravity, make a gravity force vector // There is some gravity, make a gravity force vector that is applied after object velocity.
// that is applied after object velocity.
float objMass = m_prim.Mass;
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
grav.Z = _pParentScene.DefaultGravity.Z * objMass * (1f - m_VehicleBuoyancy); grav.Z = m_prim.Scene.DefaultGravity.Z * m_prim.Mass * (1f - m_VehicleBuoyancy);
// Preserve the current Z velocity // Preserve the current Z velocity
Vector3 vel_now = m_prim.Velocity; Vector3 vel_now = m_prim.Velocity;
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
Vector3 pos = m_prim.Position; Vector3 pos = m_prim.Position;
Vector3 posChange = pos;
// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); // Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
Vector3 posChange = new Vector3();
posChange.X = pos.X - m_lastPositionVector.X;
posChange.Y = pos.Y - m_lastPositionVector.Y;
posChange.Z = pos.Z - m_lastPositionVector.Z;
double Zchange = Math.Abs(posChange.Z); double Zchange = Math.Abs(posChange.Z);
if (m_BlockingEndPoint != Vector3.Zero) if (m_BlockingEndPoint != Vector3.Zero)
{ {
bool changed = false;
if (pos.X >= (m_BlockingEndPoint.X - (float)1)) if (pos.X >= (m_BlockingEndPoint.X - (float)1))
{ {
pos.X -= posChange.X + 1; pos.X -= posChange.X + 1;
m_prim.Position = pos; changed = true;
} }
if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
{ {
pos.Y -= posChange.Y + 1; pos.Y -= posChange.Y + 1;
m_prim.Position = pos; changed = true;
} }
if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
{ {
pos.Z -= posChange.Z + 1; pos.Z -= posChange.Z + 1;
m_prim.Position = pos; changed = true;
} }
if (pos.X <= 0) if (pos.X <= 0)
{ {
pos.X += posChange.X + 1; pos.X += posChange.X + 1;
m_prim.Position = pos; changed = true;
} }
if (pos.Y <= 0) if (pos.Y <= 0)
{ {
pos.Y += posChange.Y + 1; pos.Y += posChange.Y + 1;
m_prim.Position = pos; changed = true;
} }
} if (changed)
if (pos.Z < _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y))
{ {
pos.Z = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2;
m_prim.Position = pos; m_prim.Position = pos;
DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
}
}
// If below the terrain, move us above the ground a little.
if (pos.Z < m_prim.Scene.GetTerrainHeightAtXYZ(pos))
{
pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2;
m_prim.Position = pos;
DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
} }
// Check if hovering // Check if hovering
@ -708,11 +741,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// We should hover, get the target height // We should hover, get the target height
if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0)
{ {
m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight; m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight;
} }
if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
{ {
m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
} }
if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
{ {
@ -746,6 +779,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
} }
} }
DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped // m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
// m_VhoverTimescale = 0f; // time to acheive height // m_VhoverTimescale = 0f; // time to acheive height
// pTimestep is time since last frame,in secs // pTimestep is time since last frame,in secs
@ -774,12 +809,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
grav.Z = (float)(grav.Z * 1.125); grav.Z = (float)(grav.Z * 1.125);
} }
float terraintemp = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y); float terraintemp = m_prim.Scene.GetTerrainHeightAtXYZ(pos);
float postemp = (pos.Z - terraintemp); float postemp = (pos.Z - terraintemp);
if (postemp > 2.5f) if (postemp > 2.5f)
{ {
grav.Z = (float)(grav.Z * 1.037125); grav.Z = (float)(grav.Z * 1.037125);
} }
DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
//End Experimental Values //End Experimental Values
} }
if ((m_flags & (VehicleFlag.NO_X)) != 0) if ((m_flags & (VehicleFlag.NO_X)) != 0)
@ -800,32 +836,39 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Apply velocity // Apply velocity
m_prim.Velocity = m_dir; m_prim.Velocity = m_dir;
// apply gravity force // apply gravity force
m_prim.Force = grav; // Why is this set here? The physics engine already does gravity.
// m_prim.AddForce(grav, false);
// m_prim.Force = grav;
// Apply friction
// apply friction
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount);
} // end MoveLinear() } // end MoveLinear()
private void MoveAngular(float pTimestep) private void MoveAngular(float pTimestep)
{ {
/* // m_angularMotorDirection // angular velocity requested by LSL motor
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor // m_angularMotorApply // application frame counter
private int m_angularMotorApply = 0; // application frame counter // m_angularMotorVelocity // current angular motor velocity (ramps up and down)
private float m_angularMotorVelocity = 0; // current angular motor velocity (ramps up and down) // m_angularMotorTimescale // motor angular velocity ramp up rate
private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate // m_angularMotorDecayTimescale // motor angular velocity decay rate
private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate // m_angularFrictionTimescale // body angular velocity decay rate
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate // m_lastAngularVelocity // what was last applied to body
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
*/
// Get what the body is doing, this includes 'external' influences // Get what the body is doing, this includes 'external' influences
Vector3 angularVelocity = m_prim.RotationalVelocity; Vector3 angularVelocity = m_prim.RotationalVelocity;
// Vector3 angularVelocity = Vector3.Zero;
if (m_angularMotorApply > 0) if (m_angularMotorApply > 0)
{ {
// Rather than snapping the angular motor velocity from the old value to
// a newly set velocity, this routine steps the value from the previous
// value (m_angularMotorVelocity) to the requested value (m_angularMotorDirection).
// There are m_angularMotorApply steps.
Vector3 origAngularVelocity = m_angularMotorVelocity;
// ramp up to new value // ramp up to new value
// current velocity += error / (time to get there / step interval) // current velocity += error / (time to get there / step interval)
// requested speed - last motor speed // requested speed - last motor speed
@ -833,23 +876,21 @@ namespace OpenSim.Region.Physics.BulletSPlugin
m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
// velocity may still be acheived. // velocity may still be acheived.
} }
else else
{ {
// no motor recently applied, keep the body velocity // No motor recently applied, keep the body velocity
/* m_angularMotorVelocity.X = angularVelocity.X;
m_angularMotorVelocity.Y = angularVelocity.Y;
m_angularMotorVelocity.Z = angularVelocity.Z; */
// and decay the velocity // and decay the velocity
m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
} // end motor section } // end motor section
// Vertical attractor section // Vertical attractor section
Vector3 vertattr = Vector3.Zero; Vector3 vertattr = Vector3.Zero;
if (m_verticalAttractionTimescale < 300) if (m_verticalAttractionTimescale < 300)
{ {
float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep);
@ -871,7 +912,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Error is 0 (no error) to +/- 2 (max error) // Error is 0 (no error) to +/- 2 (max error)
// scale it by VAservo // scale it by VAservo
verterr = verterr * VAservo; verterr = verterr * VAservo;
//if (frcount == 0) Console.WriteLine("VAerr=" + verterr);
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed. // Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
@ -884,11 +924,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
vertattr.X += bounce * angularVelocity.X; vertattr.X += bounce * angularVelocity.X;
vertattr.Y += bounce * angularVelocity.Y; vertattr.Y += bounce * angularVelocity.Y;
DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
m_prim.LocalID, verterr, bounce, vertattr);
} // else vertical attractor is off } // else vertical attractor is off
// m_lastVertAttractor = vertattr; // m_lastVertAttractor = vertattr;
// Bank section tba // Bank section tba
// Deflection section tba // Deflection section tba
// Sum velocities // Sum velocities
@ -898,11 +942,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
m_lastAngularVelocity.X = 0; m_lastAngularVelocity.X = 0;
m_lastAngularVelocity.Y = 0; m_lastAngularVelocity.Y = 0;
DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
} }
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
{ {
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
} }
// apply friction // apply friction
@ -912,10 +958,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Apply to the body // Apply to the body
m_prim.RotationalVelocity = m_lastAngularVelocity; m_prim.RotationalVelocity = m_lastAngularVelocity;
DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
} //end MoveAngular } //end MoveAngular
internal void LimitRotation(float timestep) internal void LimitRotation(float timestep)
{ {
Quaternion rotq = m_prim.Orientation; // rotq = rotation of object Quaternion rotq = m_prim.Orientation;
Quaternion m_rot = rotq; Quaternion m_rot = rotq;
bool changed = false; bool changed = false;
if (m_RollreferenceFrame != Quaternion.Identity) if (m_RollreferenceFrame != Quaternion.Identity)
@ -923,18 +971,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (rotq.X >= m_RollreferenceFrame.X) if (rotq.X >= m_RollreferenceFrame.X)
{ {
m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2); m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2);
changed = true;
} }
if (rotq.Y >= m_RollreferenceFrame.Y) if (rotq.Y >= m_RollreferenceFrame.Y)
{ {
m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2); m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2);
changed = true;
} }
if (rotq.X <= -m_RollreferenceFrame.X) if (rotq.X <= -m_RollreferenceFrame.X)
{ {
m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2); m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2);
changed = true;
} }
if (rotq.Y <= -m_RollreferenceFrame.Y) if (rotq.Y <= -m_RollreferenceFrame.Y)
{ {
m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2); m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2);
changed = true;
} }
changed = true; changed = true;
} }
@ -944,8 +996,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
m_rot.Y = 0; m_rot.Y = 0;
changed = true; changed = true;
} }
if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
{
m_rot.X = 0;
m_rot.Y = 0;
changed = true;
}
if (changed) if (changed)
m_prim.Orientation = m_rot; m_prim.Orientation = m_rot;
DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
}
// Invoke the detailed logger and output something if it's enabled.
private void DetailLog(string msg, params Object[] args)
{
if (m_prim.Scene.VehicleLoggingEnabled)
m_prim.Scene.PhysicsLogging.Write(msg, args);
} }
} }
} }

View File

@ -0,0 +1,352 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyrightD
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using OMV = OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
{
public class BSLinkset
{
private static string LogHeader = "[BULLETSIM LINKSET]";
private BSPrim m_linksetRoot;
public BSPrim Root { get { return m_linksetRoot; } }
private BSScene m_scene;
private List<BSPrim> m_children;
// We lock the diddling of linkset classes to prevent any badness.
// This locks the modification of the instances of this class. Changes
// to the physical representation is done via the tainting mechenism.
private object m_linksetActivityLock = new Object();
// We keep the prim's mass in the linkset structure since it could be dependent on other prims
private float m_mass;
public float LinksetMass
{
get
{
m_mass = ComputeLinksetMass();
return m_mass;
}
}
public OMV.Vector3 CenterOfMass
{
get { return ComputeLinksetCenterOfMass(); }
}
public OMV.Vector3 GeometricCenter
{
get { return ComputeLinksetGeometricCenter(); }
}
public BSLinkset(BSScene scene, BSPrim parent)
{
// A simple linkset of one (no children)
m_scene = scene;
m_linksetRoot = parent;
m_children = new List<BSPrim>();
m_mass = parent.MassRaw;
}
// Link to a linkset where the child knows the parent.
// Parent changing should not happen so do some sanity checking.
// We return the parent's linkset so the child can track it's membership.
public BSLinkset AddMeToLinkset(BSPrim child, BSPrim parent)
{
lock (m_linksetActivityLock)
{
parent.Linkset.AddChildToLinkset(child);
}
return parent.Linkset;
}
public BSLinkset RemoveMeFromLinkset(BSPrim child)
{
lock (m_linksetActivityLock)
{
if (IsRoot(child))
{
// if root of linkset, take the linkset apart
while (m_children.Count > 0)
{
// Note that we don't do a foreach because the remove routine
// takes it out of the list.
RemoveChildFromLinkset(m_children[0]);
}
m_children.Clear(); // just to make sure
}
else
{
// Just removing a child from an existing linkset
RemoveChildFromLinkset(child);
}
}
// The child is down to a linkset of just itself
return new BSLinkset(m_scene, child);
}
// An existing linkset had one of its members rebuilt or something.
// Go through the linkset and rebuild the pointers to the bodies of the linkset members.
public BSLinkset RefreshLinkset(BSPrim requestor)
{
BSLinkset ret = requestor.Linkset;
lock (m_linksetActivityLock)
{
System.IntPtr aPtr = BulletSimAPI.GetBodyHandle2(m_scene.World.Ptr, m_linksetRoot.LocalID);
if (aPtr == System.IntPtr.Zero)
{
// That's odd. We can't find the root of the linkset.
// The linkset is somehow dead. The requestor is now a member of a linkset of one.
DetailLog("{0},RefreshLinkset.RemoveRoot,child={1}", m_linksetRoot.LocalID, m_linksetRoot.LocalID);
ret = RemoveMeFromLinkset(m_linksetRoot);
}
else
{
// Reconstruct the pointer to the body of the linkset root.
DetailLog("{0},RefreshLinkset.RebuildRoot,rootID={1},ptr={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, aPtr);
m_linksetRoot.Body = new BulletBody(m_linksetRoot.LocalID, aPtr);
List<BSPrim> toRemove = new List<BSPrim>();
foreach (BSPrim bsp in m_children)
{
aPtr = BulletSimAPI.GetBodyHandle2(m_scene.World.Ptr, bsp.LocalID);
if (aPtr == System.IntPtr.Zero)
{
toRemove.Add(bsp);
}
else
{
// Reconstruct the pointer to the body of the linkset root.
DetailLog("{0},RefreshLinkset.RebuildChild,rootID={1},ptr={2}", bsp.LocalID, m_linksetRoot.LocalID, aPtr);
bsp.Body = new BulletBody(bsp.LocalID, aPtr);
}
}
foreach (BSPrim bsp in toRemove)
{
RemoveChildFromLinkset(bsp);
}
}
}
return ret;
}
// Return 'true' if the passed object is the root object of this linkset
public bool IsRoot(BSPrim requestor)
{
return (requestor.LocalID == m_linksetRoot.LocalID);
}
// Return 'true' if this linkset has any children (more than the root member)
public bool HasAnyChildren { get { return (m_children.Count > 0); } }
// Return 'true' if this child is in this linkset
public bool HasChild(BSPrim child)
{
bool ret = false;
foreach (BSPrim bp in m_children)
{
if (child.LocalID == bp.LocalID)
{
ret = true;
break;
}
}
return ret;
}
private float ComputeLinksetMass()
{
float mass = m_linksetRoot.MassRaw;
foreach (BSPrim bp in m_children)
{
mass += bp.MassRaw;
}
return mass;
}
private OMV.Vector3 ComputeLinksetCenterOfMass()
{
OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw;
float totalMass = m_linksetRoot.MassRaw;
foreach (BSPrim bp in m_children)
{
com += bp.Position * bp.MassRaw;
totalMass += bp.MassRaw;
}
com /= totalMass;
return com;
}
private OMV.Vector3 ComputeLinksetGeometricCenter()
{
OMV.Vector3 com = m_linksetRoot.Position;
foreach (BSPrim bp in m_children)
{
com += bp.Position * bp.MassRaw;
}
com /= m_children.Count + 1;
return com;
}
// I am the root of a linkset and a new child is being added
public void AddChildToLinkset(BSPrim pchild)
{
BSPrim child = pchild;
if (!HasChild(child))
{
m_children.Add(child);
m_scene.TaintedObject(delegate()
{
DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID);
DetailLog("{0},AddChildToLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child
});
}
return;
}
// I am the root of a linkset and one of my children is being removed.
// Safe to call even if the child is not really in my linkset.
public void RemoveChildFromLinkset(BSPrim pchild)
{
BSPrim child = pchild;
if (m_children.Remove(child))
{
m_scene.TaintedObject(delegate()
{
DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
DetailLog("{0},RemoveChildFromLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
if (m_children.Count == 0)
{
// if the linkset is empty, make sure all linkages have been removed
PhysicallyUnlinkAllChildrenFromRoot();
}
else
{
PhysicallyUnlinkAChildFromRoot(pchild);
}
});
}
else
{
// This will happen if we remove the root of the linkset first. Non-fatal occurance.
// m_scene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
}
return;
}
// Create a constraint between me (root of linkset) and the passed prim (the child).
// Called at taint time!
private void PhysicallyLinkAChildToRoot(BSPrim childPrim)
{
// Zero motion for children so they don't interpolate
childPrim.ZeroMotion();
// relative position normalized to the root prim
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(m_linksetRoot.Orientation);
OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.Position) * invThisOrientation;
// relative rotation of the child to the parent
OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
// create a constraint that allows no freedom of movement between the two objects
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
BSConstraint constrain = m_scene.Constraints.CreateConstraint(
m_scene.World, m_linksetRoot.Body, childPrim.Body,
// childRelativePosition,
// childRelativeRotation,
OMV.Vector3.Zero,
OMV.Quaternion.Identity,
OMV.Vector3.Zero,
OMV.Quaternion.Identity
);
constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
// tweek the constraint to increase stability
constrain.UseFrameOffset(m_scene.BoolNumeric(m_scene.Params.linkConstraintUseFrameOffset));
constrain.TranslationalLimitMotor(m_scene.BoolNumeric(m_scene.Params.linkConstraintEnableTransMotor),
m_scene.Params.linkConstraintTransMotorMaxVel,
m_scene.Params.linkConstraintTransMotorMaxForce);
constrain.SetCFMAndERP(m_scene.Params.linkConstraintCFM, m_scene.Params.linkConstraintERP);
}
// Remove linkage between myself and a particular child
// Called at taint time!
private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim)
{
DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
LogHeader, m_linksetRoot.LocalID, childPrim.LocalID);
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
// BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body);
}
// Remove linkage between myself and any possible children I might have
// Called at taint time!
private void PhysicallyUnlinkAllChildrenFromRoot()
{
// DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID);
m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body);
// BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
}
// Invoke the detailed logger and output something if it's enabled.
private void DebugLog(string msg, params Object[] args)
{
m_scene.Logger.DebugFormat(msg, args);
}
// Invoke the detailed logger and output something if it's enabled.
private void DetailLog(string msg, params Object[] args)
{
m_scene.PhysicsLogging.Write(msg, args);
}
}
}

View File

@ -42,6 +42,8 @@ public sealed class BSPrim : PhysicsActor
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS PRIM]"; private static readonly string LogHeader = "[BULLETS PRIM]";
private void DebugLog(string mm, params Object[] xx) { if (_scene.shouldDebugLog) m_log.DebugFormat(mm, xx); }
private IMesh _mesh; private IMesh _mesh;
private PrimitiveBaseShape _pbs; private PrimitiveBaseShape _pbs;
private ShapeData.PhysicsShapeType _shapeType; private ShapeData.PhysicsShapeType _shapeType;
@ -50,6 +52,7 @@ public sealed class BSPrim : PhysicsActor
private List<ConvexResult> _hulls; private List<ConvexResult> _hulls;
private BSScene _scene; private BSScene _scene;
public BSScene Scene { get { return _scene; } }
private String _avName; private String _avName;
private uint _localID = 0; private uint _localID = 0;
@ -63,7 +66,7 @@ public sealed class BSPrim : PhysicsActor
private bool _isSelected; private bool _isSelected;
private bool _isVolumeDetect; private bool _isVolumeDetect;
private OMV.Vector3 _position; private OMV.Vector3 _position;
private float _mass; private float _mass; // the mass of this object
private float _density; private float _density;
private OMV.Vector3 _force; private OMV.Vector3 _force;
private OMV.Vector3 _velocity; private OMV.Vector3 _velocity;
@ -86,14 +89,25 @@ public sealed class BSPrim : PhysicsActor
private bool _kinematic; private bool _kinematic;
private float _buoyancy; private float _buoyancy;
private List<BSPrim> _childrenPrims; // Membership in a linkset is controlled by this class.
private BSPrim _parentPrim; private BSLinkset _linkset;
public BSLinkset Linkset
{
get { return _linkset; }
set { _linkset = value; }
}
private int _subscribedEventsMs = 0; private int _subscribedEventsMs = 0;
private int _nextCollisionOkTime = 0; private int _nextCollisionOkTime = 0;
long _collidingStep; long _collidingStep;
long _collidingGroundStep; long _collidingGroundStep;
private BulletBody m_body;
public BulletBody Body {
get { return m_body; }
set { m_body = value; }
}
private BSDynamics _vehicle; private BSDynamics _vehicle;
private OMV.Vector3 _PIDTarget; private OMV.Vector3 _PIDTarget;
@ -127,17 +141,18 @@ public sealed class BSPrim : PhysicsActor
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
_density = _scene.Params.defaultDensity; // TODO: compute based on object material _density = _scene.Params.defaultDensity; // TODO: compute based on object material
_restitution = _scene.Params.defaultRestitution; _restitution = _scene.Params.defaultRestitution;
_parentPrim = null; // not a child or a parent _linkset = new BSLinkset(_scene, this); // a linkset of one
_vehicle = new BSDynamics(this); // add vehicleness _vehicle = new BSDynamics(this); // add vehicleness
_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));
}); });
} }
@ -145,13 +160,19 @@ public sealed class BSPrim : PhysicsActor
public void Destroy() public void Destroy()
{ {
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, 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
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
// Undo any links between me and any other object
_linkset = _linkset.RemoveMeFromLinkset(this);
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff. // 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);
}); });
} }
@ -164,8 +185,9 @@ 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, (IsPhysical ? _mass : 0f), IsPhysical);
DetailLog("{0}: setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
RecreateGeomAndObject(); RecreateGeomAndObject();
}); });
} }
@ -175,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();
}); });
} }
@ -202,33 +224,10 @@ public sealed class BSPrim : PhysicsActor
// link me to the specified parent // link me to the specified parent
public override void link(PhysicsActor obj) { public override void link(PhysicsActor obj) {
BSPrim parent = obj as BSPrim; BSPrim parent = obj as BSPrim;
// m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
// TODO: decide if this parent checking needs to happen at taint time DetailLog("{0},link,parent={1}", LocalID, obj.LocalID);
if (_parentPrim == null)
{ _linkset = _linkset.AddMeToLinkset(this, parent);
if (parent != null)
{
// I don't have a parent so I am joining a linkset
parent.AddChildToLinkset(this);
}
}
else
{
// I already have a parent, is parenting changing?
if (parent != _parentPrim)
{
if (parent == null)
{
// we are being removed from a linkset
_parentPrim.RemoveChildFromLinkset(this);
}
else
{
// asking to reparent a prim should not happen
m_log.ErrorFormat("{0}: Reparenting a prim. ", LogHeader);
}
}
}
return; return;
} }
@ -236,101 +235,92 @@ public sealed class BSPrim : PhysicsActor
public override void delink() { public override void delink() {
// TODO: decide if this parent checking needs to happen at taint time // TODO: decide if this parent checking needs to happen at taint time
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
// m_log.DebugFormat("{0}: delink {1}/{2}", LogHeader, _avName, _localID); DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
if (_parentPrim != null) _linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString());
{ DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString());
_parentPrim.RemoveChildFromLinkset(this);
} _linkset.RemoveMeFromLinkset(this);
return; return;
} }
// I am the root of a linkset and a new child is being added
public void AddChildToLinkset(BSPrim pchild)
{
BSPrim child = pchild;
_scene.TaintedObject(delegate()
{
if (!_childrenPrims.Contains(child))
{
_childrenPrims.Add(child);
child.ParentPrim = this; // the child has gained a parent
RecreateGeomAndObject(); // rebuild my shape with the new child added
}
});
return;
}
// I am the root of a linkset and one of my children is being removed.
// Safe to call even if the child is not really in my linkset.
public void RemoveChildFromLinkset(BSPrim pchild)
{
BSPrim child = pchild;
_scene.TaintedObject(delegate()
{
if (_childrenPrims.Contains(child))
{
BulletSimAPI.RemoveConstraint(_scene.WorldID, child.LocalID, this.LocalID);
_childrenPrims.Remove(child);
child.ParentPrim = null; // the child has lost its parent
RecreateGeomAndObject(); // rebuild my shape with the child removed
}
else
{
m_log.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset");
}
});
return;
}
public BSPrim ParentPrim
{
set { _parentPrim = value; }
}
// return true if we are the root of a linkset (there are children to manage)
public bool IsRootOfLinkset
{
get { return (_parentPrim == null && _childrenPrims.Count != 0); }
}
// Set motion values to zero. // 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.
private void ZeroMotion() // Called at taint time!
public 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) { return; } public override void LockAngularMotion(OMV.Vector3 axis)
{
DetailLog("{0},LockAngularMotion,call,axis={1}", LocalID, axis);
return;
}
public override OMV.Vector3 Position { public override OMV.Vector3 Position {
get { get {
// don't do the following GetObjectPosition because this function is called a zillion times if (!_linkset.IsRoot(this))
// child prims move around based on their parent. Need to get the latest location
_position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
// don't do the GetObjectPosition for root elements because this function is called a zillion times
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
return _position; return _position;
} }
set { set {
_position = value; _position = value;
// TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
// m_log.DebugFormat("{0}: setPosition: id={1}, position={2}", LogHeader, _localID, _position);
}); });
} }
} }
public override float Mass {
get { return _mass; } // Return the effective mass of the object.
// If there are multiple items in the linkset, add them together for the root
public override float Mass
{
get
{
return _linkset.LinksetMass;
} }
}
// used when we only want this prim's mass and not the linkset thing
public float MassRaw { get { return _mass; } }
// Is this used?
public override OMV.Vector3 CenterOfMass
{
get { return _linkset.CenterOfMass; }
}
// Is this used?
public override OMV.Vector3 GeometricCenter
{
get { return _linkset.GeometricCenter; }
}
public override OMV.Vector3 Force { public override OMV.Vector3 Force {
get { return _force; } get { return _force; }
set { set {
_force = value; _force = value;
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); DetailLog("{0},SetForce,taint,force={1}", LocalID, _force);
// BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
}); });
} }
} }
@ -341,15 +331,22 @@ public sealed class BSPrim : PhysicsActor
} }
set { set {
Vehicle type = (Vehicle)value; Vehicle type = (Vehicle)value;
_vehicle.ProcessTypeChange(type);
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
DetailLog("{0},SetVehicleType,taint,type={1}", LocalID, type);
_vehicle.ProcessTypeChange(type);
if (type == Vehicle.TYPE_NONE) if (type == Vehicle.TYPE_NONE)
{ {
_scene.RemoveVehiclePrim(this); _scene.RemoveVehiclePrim(this);
} }
else else
{ {
_scene.TaintedObject(delegate()
{
// Tell the physics engine to clear state
BulletSimAPI.ClearForces2(this.Body.Ptr);
});
// 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
_scene.AddVehiclePrim(this); _scene.AddVehiclePrim(this);
} }
@ -359,47 +356,59 @@ public sealed class BSPrim : PhysicsActor
} }
public override void VehicleFloatParam(int param, float value) public override void VehicleFloatParam(int param, float value)
{ {
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value); _scene.TaintedObject(delegate()
{
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
});
} }
public override void VehicleVectorParam(int param, OMV.Vector3 value) public override void VehicleVectorParam(int param, OMV.Vector3 value)
{ {
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value); _scene.TaintedObject(delegate()
{
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
});
} }
public override void VehicleRotationParam(int param, OMV.Quaternion rotation) public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
{
_scene.TaintedObject(delegate()
{ {
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation); _vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
});
} }
public override void VehicleFlags(int param, bool remove) public override void VehicleFlags(int param, bool remove)
{
_scene.TaintedObject(delegate()
{ {
_vehicle.ProcessVehicleFlags(param, remove); _vehicle.ProcessVehicleFlags(param, remove);
});
} }
// Called each simulation step to advance vehicle characteristics
// Called each simulation step to advance vehicle characteristics.
// 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, _scene); 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
public override void SetVolumeDetect(int param) { public override void SetVolumeDetect(int param) {
bool newValue = (param != 0); bool newValue = (param != 0);
if (_isVolumeDetect != newValue)
{
_isVolumeDetect = newValue; _isVolumeDetect = newValue;
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
SetObjectDynamic(); SetObjectDynamic();
}); });
}
return; return;
} }
public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } }
public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } }
public override OMV.Vector3 Velocity { public override OMV.Vector3 Velocity {
get { return _velocity; } get { return _velocity; }
set { _velocity = value; set {
_velocity = value;
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
DetailLog("{0},SetVelocity,taint,vel={1}", LocalID, _velocity);
BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
}); });
} }
@ -407,6 +416,7 @@ public sealed class BSPrim : PhysicsActor
public override OMV.Vector3 Torque { public override OMV.Vector3 Torque {
get { return _torque; } get { return _torque; }
set { _torque = value; set { _torque = value;
DetailLog("{0},SetTorque,call,torque={1}", LocalID, _torque);
} }
} }
public override float CollisionScore { public override float CollisionScore {
@ -419,13 +429,21 @@ public sealed class BSPrim : PhysicsActor
set { _acceleration = value; } set { _acceleration = value; }
} }
public override OMV.Quaternion Orientation { public override OMV.Quaternion Orientation {
get { return _orientation; } get {
if (!_linkset.IsRoot(this))
{
// Children move around because tied to parent. Get a fresh value.
_orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID);
}
return _orientation;
}
set { set {
_orientation = value; _orientation = value;
// m_log.DebugFormat("{0}: set orientation: id={1}, ori={2}", LogHeader, LocalID, _orientation); // TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint?
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
DetailLog("{0},SetOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
}); });
} }
@ -458,25 +476,24 @@ public sealed class BSPrim : PhysicsActor
get { return !IsPhantom && !_isVolumeDetect; } get { return !IsPhantom && !_isVolumeDetect; }
} }
// make gravity work if the object is physical and not selected // Make gravity work if the object is physical and not selected
// no locking here because only called when it is safe // No locking here because only called when it is safe
// Only called at taint time so it is save to call into Bullet.
private void SetObjectDynamic() private void SetObjectDynamic()
{ {
// m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid); // RA: remove this for the moment.
// non-physical things work best with a mass of zero // The problem is that dynamic objects are hulls so if we are becoming physical
if (IsStatic) // the shape has to be checked and possibly built.
{ // Maybe a VerifyCorrectPhysicalShape() routine?
_mass = 0f; // RecreateGeomAndObject();
}
else
{
_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();
} float mass = _mass;
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), _mass); // Bullet wants static objects have a mass of zero
if (IsStatic)
mass = 0f;
DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass);
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
} }
// prims don't fly // prims don't fly
@ -516,11 +533,24 @@ public sealed class BSPrim : PhysicsActor
set { _floatOnWater = value; } set { _floatOnWater = value; }
} }
public override OMV.Vector3 RotationalVelocity { public override OMV.Vector3 RotationalVelocity {
get { return _rotationalVelocity; } get {
set { _rotationalVelocity = value; /*
OMV.Vector3 pv = OMV.Vector3.Zero;
// if close to zero, report zero
// This is copied from ODE but I'm not sure why it returns zero but doesn't
// zero the property in the physics engine.
if (_rotationalVelocity.ApproxEquals(pv, 0.2f))
return pv;
*/
return _rotationalVelocity;
}
set {
_rotationalVelocity = value;
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
DetailLog("{0},SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
}); });
} }
@ -533,9 +563,11 @@ public sealed class BSPrim : PhysicsActor
} }
public override float Buoyancy { public override float Buoyancy {
get { return _buoyancy; } get { return _buoyancy; }
set { _buoyancy = value; set {
_buoyancy = value;
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
DetailLog("{0},SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
}); });
} }
@ -573,27 +605,45 @@ public sealed class BSPrim : PhysicsActor
public override float APIDStrength { set { return; } } public override float APIDStrength { set { return; } }
public override float APIDDamping { set { return; } } public override float APIDDamping { set { return; } }
private List<OMV.Vector3> m_accumulatedForces = new List<OMV.Vector3>();
public override void AddForce(OMV.Vector3 force, bool pushforce) { public override void AddForce(OMV.Vector3 force, bool pushforce) {
if (force.IsFinite()) if (force.IsFinite())
{ {
_force.X += force.X; // _force += force;
_force.Y += force.Y; lock (m_accumulatedForces)
_force.Z += force.Z; m_accumulatedForces.Add(new OMV.Vector3(force));
} }
else else
{ {
m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader);
return;
} }
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
{ {
BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); lock (m_accumulatedForces)
{
if (m_accumulatedForces.Count > 0)
{
OMV.Vector3 fSum = OMV.Vector3.Zero;
foreach (OMV.Vector3 v in m_accumulatedForces)
{
fSum += v;
}
m_accumulatedForces.Clear();
DetailLog("{0},SetObjectForce,taint,force={1}", LocalID, fSum);
BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, fSum);
}
}
}); });
} }
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
DetailLog("{0},AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
// m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
} }
public override void SetMomentum(OMV.Vector3 momentum) { public override void SetMomentum(OMV.Vector3 momentum) {
DetailLog("{0},SetMomentum,call,mom={1}", LocalID, momentum);
} }
public override void SubscribeEvents(int ms) { public override void SubscribeEvents(int ms) {
_subscribedEventsMs = ms; _subscribedEventsMs = ms;
@ -885,6 +935,9 @@ public sealed class BSPrim : PhysicsActor
returnMass = _density * volume; returnMass = _density * volume;
/*
* This change means each object keeps its own mass and the Mass property
* will return the sum if we're part of a linkset.
if (IsRootOfLinkset) if (IsRootOfLinkset)
{ {
foreach (BSPrim prim in _childrenPrims) foreach (BSPrim prim in _childrenPrims)
@ -892,6 +945,7 @@ public sealed class BSPrim : PhysicsActor
returnMass += prim.CalculateMass(); returnMass += prim.CalculateMass();
} }
} }
*/
if (returnMass <= 0) if (returnMass <= 0)
returnMass = 0.0001f; returnMass = 0.0001f;
@ -907,9 +961,11 @@ public sealed class BSPrim : PhysicsActor
// The objects needs a hull if it's physical otherwise a mesh is enough // The objects needs a hull if it's physical otherwise a mesh is enough
// No locking here because this is done when we know physics is not simulating // No locking here because this is done when we know physics is not simulating
// if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used
private void CreateGeom(bool forceRebuild) // Returns 'true' if the geometry was rebuilt
private bool CreateGeom(bool forceRebuild)
{ {
// the mesher thought this was too simple to mesh. Use a native Bullet collision shape. // the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
bool ret = false;
if (!_scene.NeedsMeshing(_pbs)) if (!_scene.NeedsMeshing(_pbs))
{ {
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
@ -917,16 +973,28 @@ public sealed class BSPrim : PhysicsActor
if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
{ {
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
{
DetailLog("{0},CreateGeom,sphere", LocalID);
_shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
// Bullet native objects are scaled by the Bullet engine so pass the size in // Bullet native objects are scaled by the Bullet engine so pass the size in
_scale = _size; _scale = _size;
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
ret = true;
}
} }
} }
else else
{ {
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size); // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
{
DetailLog("{0},CreateGeom,box", LocalID);
_shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
_scale = _size; _scale = _size;
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
ret = true;
}
} }
} }
else else
@ -938,6 +1006,7 @@ public sealed class BSPrim : PhysicsActor
// physical objects require a hull for interaction. // physical objects require a hull for interaction.
// This will create the mesh if it doesn't already exist // This will create the mesh if it doesn't already exist
CreateGeomHull(); CreateGeomHull();
ret = true;
} }
} }
else else
@ -946,9 +1015,11 @@ public sealed class BSPrim : PhysicsActor
{ {
// Static (non-physical) objects only need a mesh for bumping into // Static (non-physical) objects only need a mesh for bumping into
CreateGeomMesh(); CreateGeomMesh();
ret = true;
} }
} }
} }
return ret;
} }
// No locking here because this is done when we know physics is not simulating // No locking here because this is done when we know physics is not simulating
@ -961,10 +1032,12 @@ public sealed class BSPrim : PhysicsActor
// if this new shape is the same as last time, don't recreate the mesh // if this new shape is the same as last time, don't recreate the mesh
if (_meshKey == newMeshKey) return; if (_meshKey == newMeshKey) return;
DetailLog("{0},CreateGeomMesh,create,key={1}", LocalID, _meshKey);
// Since we're recreating new, get rid of any previously generated shape // Since we're recreating new, get rid of any previously generated shape
if (_meshKey != 0) if (_meshKey != 0)
{ {
// m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
DetailLog("{0},CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
_mesh = null; _mesh = null;
_meshKey = 0; _meshKey = 0;
@ -981,7 +1054,6 @@ public sealed class BSPrim : PhysicsActor
int vi = 0; int vi = 0;
foreach (OMV.Vector3 vv in vertices) foreach (OMV.Vector3 vv in vertices)
{ {
// m_log.DebugFormat("{0}: {1}: <{2:0.00}, {3:0.00}, {4:0.00}>", LogHeader, vi / 3, vv.X, vv.Y, vv.Z);
verticesAsFloats[vi++] = vv.X; verticesAsFloats[vi++] = vv.X;
verticesAsFloats[vi++] = vv.Y; verticesAsFloats[vi++] = vv.Y;
verticesAsFloats[vi++] = vv.Z; verticesAsFloats[vi++] = vv.Z;
@ -995,6 +1067,7 @@ public sealed class BSPrim : PhysicsActor
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
// meshes are already scaled by the meshmerizer // meshes are already scaled by the meshmerizer
_scale = new OMV.Vector3(1f, 1f, 1f); _scale = new OMV.Vector3(1f, 1f, 1f);
DetailLog("{0},CreateGeomMesh,done", LocalID);
return; return;
} }
@ -1008,13 +1081,17 @@ public sealed class BSPrim : PhysicsActor
// if the hull hasn't changed, don't rebuild it // if the hull hasn't changed, don't rebuild it
if (newHullKey == _hullKey) return; if (newHullKey == _hullKey) return;
DetailLog("{0},CreateGeomHull,create,key={1}", LocalID, _meshKey);
// Since we're recreating new, get rid of any previously generated shape // Since we're recreating new, get rid of any previously generated shape
if (_hullKey != 0) if (_hullKey != 0)
{ {
// m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
DetailLog("{0},CreateGeomHull,deleteOldHull,key={1}", LocalID, _meshKey);
BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
_hullKey = 0; _hullKey = 0;
_hulls.Clear(); _hulls.Clear();
DetailLog("{0},CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey);
BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
_mesh = null; // the mesh cannot match either _mesh = null; // the mesh cannot match either
_meshKey = 0; _meshKey = 0;
@ -1111,6 +1188,7 @@ public sealed class BSPrim : PhysicsActor
_shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
// meshes are already scaled by the meshmerizer // meshes are already scaled by the meshmerizer
_scale = new OMV.Vector3(1f, 1f, 1f); _scale = new OMV.Vector3(1f, 1f, 1f);
DetailLog("{0},CreateGeomHull,done", LocalID);
return; return;
} }
@ -1124,47 +1202,21 @@ public sealed class BSPrim : PhysicsActor
// Create an object in Bullet if it has not already been created // Create an object in Bullet if it has not already been created
// 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
private void CreateObject() // Returns 'true' if an object was actually created.
private bool CreateObject()
{ {
if (IsRootOfLinkset) // this routine is called when objects are rebuilt.
{
// Create a linkset around this object
// CreateLinksetWithCompoundHull();
CreateLinksetWithConstraints();
}
else
{
// simple object
// the mesh or hull must have already been created in Bullet // the mesh or hull must have already been created in Bullet
ShapeData shape; ShapeData shape;
FillShapeInfo(out shape); FillShapeInfo(out shape);
// m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type); // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
BulletSimAPI.CreateObject(_scene.WorldID, shape); bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
}
}
// Create a linkset by creating a compound hull at the root prim that consists of all // the CreateObject() may have recreated the rigid body. Make sure we have the latest.
// the children. m_body.Ptr = BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID);
// NOTE: This does not allow proper collisions with the children prims so it is not a workable solution
void CreateLinksetWithCompoundHull() return ret;
{
// 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
@ -1186,44 +1238,6 @@ public sealed class BSPrim : PhysicsActor
shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
} }
// Create the linkset by putting constraints between the objects of the set so they cannot move
// relative to each other.
// TODO: make this more effeicient: a large linkset gets rebuilt over and over and prims are added
void CreateLinksetWithConstraints()
{
// m_log.DebugFormat("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
// remove any constraints that might be in place
foreach (BSPrim prim in _childrenPrims)
{
// m_log.DebugFormat("{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
foreach (BSPrim prim in _childrenPrims)
{
// m_log.DebugFormat("{0}: CreateLinkset: AddConstraint between root prim {1} and child prim {2}", LogHeader, LocalID, prim.LocalID);
// Zero motion for children so they don't interpolate
prim.ZeroMotion();
// relative position normalized to the root prim
OMV.Vector3 childRelativePosition = (prim._position - this._position) * OMV.Quaternion.Inverse(this._orientation);
// relative rotation of the child to the parent
OMV.Quaternion relativeRotation = OMV.Quaternion.Inverse(prim._orientation) * this._orientation;
// this is a constraint that allows no freedom of movement between the two objects
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
BulletSimAPI.AddConstraint(_scene.WorldID, LocalID, prim.LocalID,
childRelativePosition,
relativeRotation,
OMV.Vector3.Zero,
OMV.Quaternion.Identity,
OMV.Vector3.Zero, OMV.Vector3.Zero,
OMV.Vector3.Zero, OMV.Vector3.Zero);
}
}
// 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.
@ -1231,7 +1245,7 @@ public sealed class BSPrim : PhysicsActor
private void RecreateGeomAndObject() private void RecreateGeomAndObject()
{ {
// m_log.DebugFormat("{0}: RecreateGeomAndObject. lID={1}", LogHeader, _localID); // m_log.DebugFormat("{0}: RecreateGeomAndObject. lID={1}", LogHeader, _localID);
CreateGeom(true); if (CreateGeom(true))
CreateObject(); CreateObject();
return; return;
} }
@ -1252,66 +1266,56 @@ public sealed class BSPrim : PhysicsActor
const float POSITION_TOLERANCE = 0.05f; const float POSITION_TOLERANCE = 0.05f;
const float ACCELERATION_TOLERANCE = 0.01f; const float ACCELERATION_TOLERANCE = 0.01f;
const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
const bool SHOULD_DAMP_UPDATES = false;
public void UpdateProperties(EntityProperties entprop) public void UpdateProperties(EntityProperties entprop)
{ {
/*
UpdatedProperties changed = 0; UpdatedProperties changed = 0;
if (SHOULD_DAMP_UPDATES)
{
// 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
// if (_position != entprop.Position) // if (_position != entprop.Position)
if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE)) if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE))
{ {
_position = entprop.Position; _position = entprop.Position;
// m_log.DebugFormat("{0}: UpdateProperties: id={1}, pos = {2}", LogHeader, LocalID, _position);
changed |= UpdatedProperties.Position; changed |= UpdatedProperties.Position;
} }
// if (_orientation != entprop.Rotation) // if (_orientation != entprop.Rotation)
if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE)) if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE))
{ {
_orientation = entprop.Rotation; _orientation = entprop.Rotation;
// m_log.DebugFormat("{0}: UpdateProperties: id={1}, rot = {2}", LogHeader, LocalID, _orientation);
changed |= UpdatedProperties.Rotation; changed |= UpdatedProperties.Rotation;
} }
// if (_velocity != entprop.Velocity) // if (_velocity != entprop.Velocity)
if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE)) if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE))
{ {
_velocity = entprop.Velocity; _velocity = entprop.Velocity;
// m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity);
changed |= UpdatedProperties.Velocity; changed |= UpdatedProperties.Velocity;
} }
// if (_acceleration != entprop.Acceleration) // if (_acceleration != entprop.Acceleration)
if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE)) if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE))
{ {
_acceleration = entprop.Acceleration; _acceleration = entprop.Acceleration;
// m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration);
changed |= UpdatedProperties.Acceleration; changed |= UpdatedProperties.Acceleration;
} }
// if (_rotationalVelocity != entprop.RotationalVelocity) // if (_rotationalVelocity != entprop.RotationalVelocity)
if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE)) if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE))
{ {
_rotationalVelocity = entprop.RotationalVelocity; _rotationalVelocity = entprop.RotationalVelocity;
// m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity);
changed |= UpdatedProperties.RotationalVel; changed |= UpdatedProperties.RotationalVel;
} }
if (changed != 0) if (changed != 0)
{ {
// m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
// Only update the position of single objects and linkset roots // Only update the position of single objects and linkset roots
if (this._parentPrim == null) if (this._parentPrim == null)
{ {
// m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
} }
} }
} */
else
{
// 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.
// Only 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 (_linkset.IsRoot(this))
{ {
// 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;
@ -1319,10 +1323,20 @@ public sealed class BSPrim : PhysicsActor
_velocity = entprop.Velocity; _velocity = entprop.Velocity;
_acceleration = entprop.Acceleration; _acceleration = entprop.Acceleration;
_rotationalVelocity = entprop.RotationalVelocity; _rotationalVelocity = entprop.RotationalVelocity;
// m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}",
// LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
DetailLog("{0},UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
} }
else
{
// For debugging, we can also report the movement of children
DetailLog("{0},UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
entprop.Acceleration, entprop.RotationalVelocity);
} }
} }
@ -1362,5 +1376,11 @@ public sealed class BSPrim : PhysicsActor
collisionCollection.Clear(); collisionCollection.Clear();
} }
} }
// Invoke the detailed logger and output something if it's enabled.
private void DetailLog(string msg, params Object[] args)
{
Scene.PhysicsLogging.Write(msg, args);
}
} }
} }

File diff suppressed because it is too large Load Diff

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
{ {
@ -44,13 +66,14 @@ public struct ShapeData
{ {
public enum PhysicsShapeType public enum PhysicsShapeType
{ {
SHAPE_AVATAR = 0, SHAPE_UNKNOWN = 0,
SHAPE_BOX = 1, SHAPE_AVATAR = 1,
SHAPE_CONE = 2, SHAPE_BOX = 2,
SHAPE_CYLINDER = 3, SHAPE_CONE = 3,
SHAPE_SPHERE = 4, SHAPE_CYLINDER = 4,
SHAPE_MESH = 5, SHAPE_SPHERE = 5,
SHAPE_HULL = 6 SHAPE_MESH = 6,
SHAPE_HULL = 7
}; };
public uint ID; public uint ID;
public PhysicsShapeType Type; public PhysicsShapeType Type;
@ -64,12 +87,12 @@ public struct ShapeData
public System.UInt64 MeshKey; public System.UInt64 MeshKey;
public float Friction; public float Friction;
public float Restitution; public float Restitution;
public int Collidable; public float Collidable; // true of things bump into this
public int Static; // true if a static object. Otherwise gravity, etc. public float Static; // true if a static object. Otherwise gravity, etc.
// note that bools are passed as ints since bool size changes by language and architecture // note that bools are passed as floats since bool size changes by language and architecture
public const int numericTrue = 1; public const float numericTrue = 1f;
public const int numericFalse = 0; public const float numericFalse = 0f;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct SweepHit public struct SweepHit
@ -142,10 +165,56 @@ 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 float linkConstraintERP;
public float linkConstraintCFM;
public const float numericTrue = 1f; public const float numericTrue = 1f;
public const float numericFalse = 0f; public const float numericFalse = 0f;
} }
// Values used by Bullet and BulletSim to control collisions
public enum CollisionFlags : uint
{
STATIC_OBJECT = 1 << 0,
KINEMATIC_OBJECT = 1 << 1,
NO_CONTACT_RESPONSE = 1 << 2,
CUSTOM_MATERIAL_CALLBACK = 1 << 3,
CHARACTER_OBJECT = 1 << 4,
DISABLE_VISUALIZE_OBJECT = 1 << 5,
DISABLE_SPU_COLLISION_PROCESS = 1 << 6,
// Following used by BulletSim to control collisions
VOLUME_DETECT_OBJECT = 1 << 10,
PHANTOM_OBJECT = 1 << 11,
PHYSICAL_OBJECT = 1 << 12,
};
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2.
public enum ConstraintParams : int
{
BT_CONSTRAINT_ERP = 1, // this one is not used in Bullet as of 20120730
BT_CONSTRAINT_STOP_ERP,
BT_CONSTRAINT_CFM,
BT_CONSTRAINT_STOP_CFM,
};
public enum ConstraintParamAxis : int
{
AXIS_LINEAR_X = 0,
AXIS_LINEAR_Y,
AXIS_LINEAR_Z,
AXIS_ANGULAR_X,
AXIS_ANGULAR_Y,
AXIS_ANGULAR_Z,
AXIS_LINEAR_ALL = 20, // these last three added by BulletSim so we don't have to do zillions of calls
AXIS_ANGULAR_ALL,
AXIS_ALL
};
// ===============================================================================
static class BulletSimAPI { static class BulletSimAPI {
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
@ -195,6 +264,7 @@ public static extern bool DestroyMesh(uint worldID, System.UInt64 meshKey);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool CreateObject(uint worldID, ShapeData shapeData); public static extern bool CreateObject(uint worldID, ShapeData shapeData);
/* Remove old functionality
[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);
@ -209,10 +279,14 @@ 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);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern Quaternion GetObjectOrientation(uint WorldID, uint id);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetObjectTranslation(uint worldID, uint id, Vector3 position, Quaternion rotation); public static extern bool SetObjectTranslation(uint worldID, uint id, Vector3 position, Quaternion rotation);
@ -268,5 +342,179 @@ public static extern void DumpBulletStatistics();
public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void SetDebugLogCallback(DebugLogCallback callback); public static extern void SetDebugLogCallback(DebugLogCallback callback);
// ===============================================================================
// ===============================================================================
// ===============================================================================
// A new version of the API that enables moving all the logic out of the C++ code and into
// the C# code. This will make modifications easier for the next person.
// This interface passes the actual pointers to the objects in the unmanaged
// address space. All the management (calls for creation/destruction/lookup)
// is done in the C# code.
// The names have a "2" tacked on. This will be removed as the C# code gets rebuilt
// and the old code is removed.
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GetSimHandle2(uint worldID);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr GetBodyHandle2(IntPtr sim, uint id);
// ===============================================================================
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr 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,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
[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 SetConstraintParam2(IntPtr constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool DestroyConstraint2(IntPtr sim, IntPtr constrain);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern Vector3 GetPosition2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern Quaternion GetOrientation2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetVelocity2(IntPtr obj, Vector3 velocity);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetObjectForce2(IntPtr obj, Vector3 force);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetCcdMotionThreshold2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetCcdSweepSphereRadius2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetDamping2(IntPtr obj, float lin_damping, float ang_damping);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetDeactivationTime2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetContactProcessingThreshold2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetFriction2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetRestitution2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetLinearVelocity2(IntPtr obj, Vector3 val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetInterpolation2(IntPtr obj, Vector3 lin, Vector3 ang);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr SetCollisionFlags2(IntPtr obj, uint flags);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr AddToCollisionFlags2(IntPtr obj, uint flags);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr RemoveFromCollisionFlags2(IntPtr obj, uint flags);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetMassProps2(IntPtr obj, float mass, Vector3 inertia);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool UpdateInertiaTensor2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetGravity2(IntPtr obj, Vector3 val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr ClearForces2(IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetMargin2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool UpdateSingleAabb2(IntPtr world, IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool DestroyObject2(IntPtr world, uint id);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void DumpPhysicsStatistics2(IntPtr sim);
} }
} }

View File

@ -71,6 +71,9 @@ namespace OpenSim.Region.Physics.Manager
All = 0x3f All = 0x3f
} }
public delegate void RequestAssetDelegate(UUID assetID, AssetReceivedDelegate callback);
public delegate void AssetReceivedDelegate(AssetBase asset);
/// <summary> /// <summary>
/// Contact result from a raycast. /// Contact result from a raycast.
/// </summary> /// </summary>
@ -103,6 +106,8 @@ namespace OpenSim.Region.Physics.Manager
get { return new NullPhysicsScene(); } get { return new NullPhysicsScene(); }
} }
public RequestAssetDelegate RequestAssetMethod { private get; set; }
public virtual void TriggerPhysicsBasedRestart() public virtual void TriggerPhysicsBasedRestart()
{ {
physicsCrash handler = OnPhysicsCrash; physicsCrash handler = OnPhysicsCrash;

View File

@ -290,7 +290,6 @@ namespace OpenSim.Region.Physics.OdePlugin
private readonly IntPtr contactgroup; private readonly IntPtr contactgroup;
internal IntPtr LandGeom;
internal IntPtr WaterGeom; internal IntPtr WaterGeom;
private float nmTerrainContactFriction = 255.0f; private float nmTerrainContactFriction = 255.0f;
@ -489,6 +488,8 @@ namespace OpenSim.Region.Physics.OdePlugin
/// </summary> /// </summary>
internal Object OdeLock = new Object(); internal Object OdeLock = new Object();
private bool _worldInitialized = false;
public IMesher mesher; public IMesher mesher;
private IConfigSource m_config; private IConfigSource m_config;
@ -875,6 +876,8 @@ namespace OpenSim.Region.Physics.OdePlugin
staticPrimspace[i, j] = IntPtr.Zero; staticPrimspace[i, j] = IntPtr.Zero;
} }
} }
_worldInitialized = true;
} }
// internal void waitForSpaceUnlock(IntPtr space) // internal void waitForSpaceUnlock(IntPtr space)
@ -1508,8 +1511,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f)
&& (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f)
&& (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)))
&& contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom)
{ {
if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f) if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f)
{ {
@ -1538,7 +1540,7 @@ namespace OpenSim.Region.Physics.OdePlugin
//d.GeomGetAABB(contactGeom.g2, out aabb2); //d.GeomGetAABB(contactGeom.g2, out aabb2);
//d.GeomGetAABB(contactGeom.g1, out aabb1); //d.GeomGetAABB(contactGeom.g1, out aabb1);
//aabb1. //aabb1.
if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom) if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)))
{ {
if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z) if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z)
{ {
@ -2896,6 +2898,8 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <returns>The number of frames simulated over that period.</returns> /// <returns>The number of frames simulated over that period.</returns>
public override float Simulate(float timeStep) public override float Simulate(float timeStep)
{ {
if (!_worldInitialized) return 11f;
int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0; int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0;
int tempTick = 0, tempTick2 = 0; int tempTick = 0, tempTick2 = 0;
@ -4017,6 +4021,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void Dispose() public override void Dispose()
{ {
_worldInitialized = false;
m_rayCastManager.Dispose(); m_rayCastManager.Dispose();
m_rayCastManager = null; m_rayCastManager = null;
@ -4037,6 +4043,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.WorldDestroy(world); d.WorldDestroy(world);
//d.CloseODE(); //d.CloseODE();
} }
} }
public override Dictionary<uint, float> GetTopColliders() public override Dictionary<uint, float> GetTopColliders()

View File

@ -99,6 +99,8 @@ namespace OpenSim.Region.RegionCombinerModule
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
lock (m_startingScenes)
m_startingScenes.Remove(scene.RegionInfo.originRegionID);
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)

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

@ -6885,23 +6885,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (folderID == UUID.Zero) if (folderID == UUID.Zero)
return; return;
byte[] bucket = new byte[1]; if (m_TransferModule != null)
bucket[0] = (byte)AssetType.Folder; {
//byte[] objBytes = folderID.GetBytes(); byte[] bucket = new byte[] { (byte)AssetType.Folder };
//Array.Copy(objBytes, 0, bucket, 1, 16);
GridInstantMessage msg = new GridInstantMessage(World, GridInstantMessage msg = new GridInstantMessage(World,
m_host.OwnerID, m_host.Name, destID, m_host.UUID, m_host.Name + ", an object owned by " +
resolveName(m_host.OwnerID) + ",", destID,
(byte)InstantMessageDialog.TaskInventoryOffered, (byte)InstantMessageDialog.TaskInventoryOffered,
false, category+". "+m_host.Name+" is located at "+ false, category + "\n" + m_host.Name + " is located at " +
World.RegionInfo.RegionName+" "+ World.RegionInfo.RegionName + " " +
m_host.AbsolutePosition.ToString(), m_host.AbsolutePosition.ToString(),
folderID, true, m_host.AbsolutePosition, folderID, true, m_host.AbsolutePosition,
bucket); bucket);
if (m_TransferModule != null)
m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
} }
}
public void llSetVehicleType(int type) public void llSetVehicleType(int type)
{ {

View File

@ -200,24 +200,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
for (int i = 0; i < result.Length; i++) for (int i = 0; i < result.Length; i++)
{ {
if (result[i] is string) if (result[i] is string)
{
llist[i] = new LSL_String((string)result[i]); llist[i] = new LSL_String((string)result[i]);
}
else if (result[i] is int) else if (result[i] is int)
{
llist[i] = new LSL_Integer((int)result[i]); llist[i] = new LSL_Integer((int)result[i]);
}
else if (result[i] is float) else if (result[i] is float)
{
llist[i] = new LSL_Float((float)result[i]); llist[i] = new LSL_Float((float)result[i]);
}
else if (result[i] is UUID)
{
llist[i] = new LSL_Key(result[i].ToString());
}
else if (result[i] is OpenMetaverse.Vector3) else if (result[i] is OpenMetaverse.Vector3)
{ {
OpenMetaverse.Vector3 vresult = (OpenMetaverse.Vector3)result[i]; OpenMetaverse.Vector3 vresult = (OpenMetaverse.Vector3)result[i];
llist[i] = new LSL_Vector(vresult.X,vresult.Y,vresult.Z); llist[i] = new LSL_Vector(vresult.X, vresult.Y, vresult.Z);
} }
else if (result[i] is OpenMetaverse.Quaternion) else if (result[i] is OpenMetaverse.Quaternion)
{ {
OpenMetaverse.Quaternion qresult = (OpenMetaverse.Quaternion)result[i]; OpenMetaverse.Quaternion qresult = (OpenMetaverse.Quaternion)result[i];
llist[i] = new LSL_Rotation(qresult.X,qresult.Y,qresult.Z,qresult.W); llist[i] = new LSL_Rotation(qresult.X, qresult.Y, qresult.Z, qresult.W);
} }
else else
{ {
MODError(String.Format("unknown list element returned by {0}",fname)); MODError(String.Format("unknown list element {1} returned by {0}", fname, result[i].GetType().Name));
} }
} }

View File

@ -3290,8 +3290,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
((LSL_Api)m_LSL_Api).llSay(0, string.Format("Unable to attach, item '{0}' is not an object.", itemName)); ((LSL_Api)m_LSL_Api).llSay(0, string.Format("Unable to attach, item '{0}' is not an object.", itemName));
throw new Exception(String.Format("The inventory item '{0}' is not an object", itemName)); throw new Exception(String.Format("The inventory item '{0}' is not an object", itemName));
return;
} }
ScenePresence sp = World.GetScenePresence(avatarId); ScenePresence sp = World.GetScenePresence(avatarId);
@ -3322,5 +3320,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
InitLSL(); InitLSL();
((LSL_Api)m_LSL_Api).DetachFromAvatar(); ((LSL_Api)m_LSL_Api).DetachFromAvatar();
} }
/// <summary>
/// Checks if thing is a UUID.
/// </summary>
/// <param name="thing"></param>
/// <returns>1 if thing is a valid UUID, 0 otherwise</returns>
public LSL_Integer osIsUUID(string thing)
{
CheckThreatLevel(ThreatLevel.None, "osIsUUID");
m_host.AddScriptLPS(1);
UUID test;
return UUID.TryParse(thing, out test) ? 1 : 0;
}
/// <summary>
/// Wraps to Math.Min()
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public LSL_Float osMin(double a, double b)
{
CheckThreatLevel(ThreatLevel.None, "osMin");
m_host.AddScriptLPS(1);
return Math.Min(a, b);
}
/// <summary>
/// Wraps to Math.max()
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public LSL_Float osMax(double a, double b)
{
CheckThreatLevel(ThreatLevel.None, "osMax");
m_host.AddScriptLPS(1);
return Math.Max(a, b);
}
} }
} }

View File

@ -51,7 +51,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{ {
get get
{ {
lock (SenseRepeatListLock)
return SenseRepeaters.Count; return SenseRepeaters.Count;
} }
} }
@ -61,8 +60,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
m_CmdManager = CmdManager; m_CmdManager = CmdManager;
maximumRange = CmdManager.m_ScriptEngine.Config.GetDouble("SensorMaxRange", 96.0d); maximumRange = CmdManager.m_ScriptEngine.Config.GetDouble("SensorMaxRange", 96.0d);
maximumToReturn = CmdManager.m_ScriptEngine.Config.GetInt("SensorMaxResults", 16); maximumToReturn = CmdManager.m_ScriptEngine.Config.GetInt("SensorMaxResults", 16);
m_npcModule = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<INPCModule>();
} }
private INPCModule m_npcModule;
private Object SenseLock = new Object(); private Object SenseLock = new Object();
private const int AGENT = 1; private const int AGENT = 1;
@ -115,6 +117,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
public double distance; public double distance;
} }
/// <summary>
/// Sensors to process.
/// </summary>
/// <remarks>
/// Do not add or remove sensors from this list directly. Instead, copy the list and substitute the updated
/// copy. This is to avoid locking the list for the duration of the sensor sweep, which increases the danger
/// of deadlocks with future code updates.
///
/// Always lock SenseRepeatListLock when updating this list.
/// </remarks>
private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>(); private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>();
private object SenseRepeatListLock = new object(); private object SenseRepeatListLock = new object();
@ -124,6 +136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{ {
// Always remove first, in case this is a re-set // Always remove first, in case this is a re-set
UnSetSenseRepeaterEvents(m_localID, m_itemID); UnSetSenseRepeaterEvents(m_localID, m_itemID);
if (sec == 0) // Disabling timer if (sec == 0) // Disabling timer
return; return;
@ -143,9 +156,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
ts.host = host; ts.host = host;
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
AddSenseRepeater(ts);
}
private void AddSenseRepeater(SenseRepeatClass senseRepeater)
{
lock (SenseRepeatListLock) lock (SenseRepeatListLock)
{ {
SenseRepeaters.Add(ts); List<SenseRepeatClass> newSenseRepeaters = new List<SenseRepeatClass>(SenseRepeaters);
newSenseRepeaters.Add(senseRepeater);
SenseRepeaters = newSenseRepeaters;
} }
} }
@ -154,27 +175,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
// Remove from timer // Remove from timer
lock (SenseRepeatListLock) lock (SenseRepeatListLock)
{ {
List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>(); List<SenseRepeatClass> newSenseRepeaters = new List<SenseRepeatClass>();
foreach (SenseRepeatClass ts in SenseRepeaters) foreach (SenseRepeatClass ts in SenseRepeaters)
{ {
if (ts.localID != m_localID || ts.itemID != m_itemID) if (ts.localID != m_localID || ts.itemID != m_itemID)
{ {
NewSensors.Add(ts); newSenseRepeaters.Add(ts);
} }
} }
SenseRepeaters.Clear();
SenseRepeaters = NewSensors; SenseRepeaters = newSenseRepeaters;
} }
} }
public void CheckSenseRepeaterEvents() public void CheckSenseRepeaterEvents()
{ {
lock (SenseRepeatListLock)
{
// Nothing to do here?
if (SenseRepeaters.Count == 0)
return;
// Go through all timers // Go through all timers
foreach (SenseRepeatClass ts in SenseRepeaters) foreach (SenseRepeatClass ts in SenseRepeaters)
{ {
@ -186,7 +201,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
} }
} }
} // lock
} }
public void SenseOnce(uint m_localID, UUID m_itemID, public void SenseOnce(uint m_localID, UUID m_itemID,
@ -440,8 +454,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
private List<SensedEntity> doAgentSensor(SenseRepeatClass ts) private List<SensedEntity> doAgentSensor(SenseRepeatClass ts)
{ {
INPCModule npcModule = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<INPCModule>();
List<SensedEntity> sensedEntities = new List<SensedEntity>(); List<SensedEntity> sensedEntities = new List<SensedEntity>();
// If nobody about quit fast // If nobody about quit fast
@ -486,7 +498,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc) if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
{ {
INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
if (npcData == null || !npcData.SenseAsAgent) if (npcData == null || !npcData.SenseAsAgent)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
@ -504,7 +516,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
} }
else else
{ {
INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
if (npcData != null && npcData.SenseAsAgent) if (npcData != null && npcData.SenseAsAgent)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
@ -619,8 +631,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{ {
List<Object> data = new List<Object>(); List<Object> data = new List<Object>();
lock (SenseRepeatListLock)
{
foreach (SenseRepeatClass ts in SenseRepeaters) foreach (SenseRepeatClass ts in SenseRepeaters)
{ {
if (ts.itemID == itemID) if (ts.itemID == itemID)
@ -633,7 +643,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
data.Add(ts.arc); data.Add(ts.arc);
} }
} }
}
return data.ToArray(); return data.ToArray();
} }
@ -667,8 +677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
ts.next = ts.next =
DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
lock (SenseRepeatListLock) AddSenseRepeater(ts);
SenseRepeaters.Add(ts);
idx += 6; idx += 6;
} }

View File

@ -276,5 +276,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void osSetTerrainTexture(int level, LSL_Key texture); void osSetTerrainTexture(int level, LSL_Key texture);
void osSetTerrainTextureHeight(int corner, double low, double high); void osSetTerrainTextureHeight(int corner, double low, double high);
/// <summary>
/// Checks if thing is a UUID.
/// </summary>
/// <param name="thing"></param>
/// <returns>1 if thing is a valid UUID, 0 otherwise</returns>
LSL_Integer osIsUUID(string thing);
/// <summary>
/// Wraps to Math.Min()
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
LSL_Float osMin(double a, double b);
/// <summary>
/// Wraps to Math.max()
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
LSL_Float osMax(double a, double b);
} }
} }

View File

@ -930,5 +930,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{ {
m_OSSL_Functions.osSetTerrainTextureHeight(corner, low, high); m_OSSL_Functions.osSetTerrainTextureHeight(corner, low, high);
} }
public LSL_Integer osIsUUID(string thing)
{
return m_OSSL_Functions.osIsUUID(thing);
}
public LSL_Float osMin(double a, double b)
{
return m_OSSL_Functions.osMin(a, b);
}
public LSL_Float osMax(double a, double b)
{
return m_OSSL_Functions.osMax(a, b);
}
} }
} }

View File

@ -255,7 +255,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
else if (s is IdentDotExpression) else if (s is IdentDotExpression)
retstr += Generate(CheckName(((IdentDotExpression) s).Name) + "." + ((IdentDotExpression) s).Member, s); retstr += Generate(CheckName(((IdentDotExpression) s).Name) + "." + ((IdentDotExpression) s).Member, s);
else if (s is IdentExpression) else if (s is IdentExpression)
retstr += Generate(CheckName(((IdentExpression) s).Name), s); retstr += GenerateIdentifier(((IdentExpression) s).Name, s);
else if (s is IDENT) else if (s is IDENT)
retstr += Generate(CheckName(((TOKEN) s).yytext), s); retstr += Generate(CheckName(((TOKEN) s).yytext), s);
else else
@ -867,6 +867,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
return retstr; return retstr;
} }
/// <summary>
/// Generates the code for an identifier
/// </summary>
/// <param name="id">The symbol name</param>
/// <param name="s">The Symbol node.</param>
/// <returns>String containing C# code for identifier reference.</returns>
private string GenerateIdentifier(string id, SYMBOL s)
{
if (m_comms != null)
{
object value = m_comms.LookupModConstant(id);
if (value != null)
{
string retval = null;
if (value is int)
retval = ((int)value).ToString();
else if (value is float)
retval = String.Format("new LSL_Types.LSLFloat({0})",((float)value).ToString());
else if (value is string)
retval = String.Format("new LSL_Types.LSLString(\"{0}\")",((string)value));
else if (value is OpenMetaverse.UUID)
retval = String.Format("new LSL_Types.key(\"{0}\")",((OpenMetaverse.UUID)value).ToString());
else if (value is OpenMetaverse.Vector3)
retval = String.Format("new LSL_Types.Vector3(\"{0}\")",((OpenMetaverse.Vector3)value).ToString());
else if (value is OpenMetaverse.Quaternion)
retval = String.Format("new LSL_Types.Quaternion(\"{0}\")",((OpenMetaverse.Quaternion)value).ToString());
else retval = id;
return Generate(retval, s);
}
}
return Generate(CheckName(id), s);
}
/// <summary> /// <summary>
/// Generates the code for a FunctionCall node. /// Generates the code for a FunctionCall node.
/// </summary> /// </summary>

View File

@ -36,6 +36,7 @@ using OpenSim.Framework;
using OpenSim.Region.CoreModules; using OpenSim.Region.CoreModules;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Region.Framework.Interfaces;
namespace OpenSim.Region.ScriptEngine.Shared namespace OpenSim.Region.ScriptEngine.Shared
{ {
@ -83,6 +84,12 @@ namespace OpenSim.Region.ScriptEngine.Shared
public class DetectParams public class DetectParams
{ {
public const int AGENT = 1;
public const int ACTIVE = 2;
public const int PASSIVE = 4;
public const int SCRIPTED = 8;
public const int OS_NPC = 0x01000000;
public DetectParams() public DetectParams()
{ {
Key = UUID.Zero; Key = UUID.Zero;
@ -199,8 +206,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
Type = 0x01; // Avatar Type = 0x01; // Avatar
if (presence.PresenceType == PresenceType.Npc) if (presence.PresenceType == PresenceType.Npc)
Type = 0x20; Type = 0x20;
// Cope Impl. We don't use OS_NPC.
//if (presence.PresenceType != PresenceType.Npc)
//{
// Type = AGENT;
//}
//else
//{
// Type = OS_NPC;
// INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
// INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
// if (npcData.SenseAsAgent)
// {
// Type |= AGENT;
// }
//}
if (presence.Velocity != Vector3.Zero) if (presence.Velocity != Vector3.Zero)
Type |= 0x02; // Active Type |= ACTIVE;
Group = presence.ControllingClient.ActiveGroupId; Group = presence.ControllingClient.ActiveGroupId;
@ -215,15 +241,15 @@ namespace OpenSim.Region.ScriptEngine.Shared
Name = part.Name; Name = part.Name;
Owner = part.OwnerID; Owner = part.OwnerID;
if (part.Velocity == Vector3.Zero) if (part.Velocity == Vector3.Zero)
Type = 0x04; // Passive Type = PASSIVE;
else else
Type = 0x02; // Passive Type = ACTIVE;
foreach (SceneObjectPart p in part.ParentGroup.Parts) foreach (SceneObjectPart p in part.ParentGroup.Parts)
{ {
if (p.Inventory.ContainsScripts()) if (p.Inventory.ContainsScripts())
{ {
Type |= 0x08; // Scripted Type |= SCRIPTED; // Scripted
break; break;
} }
} }

View File

@ -312,11 +312,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
part.SetScriptEvents(ItemID, part.SetScriptEvents(ItemID,
(int)m_Script.GetStateEventFlags(State)); (int)m_Script.GetStateEventFlags(State));
Running = false; if (!Running)
if (ShuttingDown)
m_startOnInit = false; m_startOnInit = false;
Running = false;
// we get new rez events on sim restart, too // we get new rez events on sim restart, too
// but if there is state, then we fire the change // but if there is state, then we fire the change
// event // event
@ -352,11 +352,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public void Init() public void Init()
{ {
if (!m_startOnInit) if (ShuttingDown)
return; return;
if (m_startedFromSavedState) if (m_startedFromSavedState)
{ {
if (m_startOnInit)
Start(); Start();
if (m_postOnRez) if (m_postOnRez)
{ {
@ -389,6 +390,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
} }
else else
{ {
if (m_startOnInit)
Start(); Start();
PostEvent(new EventParams("state_entry", PostEvent(new EventParams("state_entry",
new Object[0], new DetectParams[0])); new Object[0], new DetectParams[0]));

View File

@ -109,6 +109,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
private bool m_KillTimedOutScripts; private bool m_KillTimedOutScripts;
private string m_ScriptEnginesPath = null; private string m_ScriptEnginesPath = null;
private ExpiringCache<UUID, bool> m_runFlags = new ExpiringCache<UUID, bool>();
/// <summary> /// <summary>
/// Is the entire simulator in the process of shutting down? /// Is the entire simulator in the process of shutting down?
/// </summary> /// </summary>
@ -715,6 +717,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
m_Scene.EventManager.OnGetScriptRunning += OnGetScriptRunning; m_Scene.EventManager.OnGetScriptRunning += OnGetScriptRunning;
m_Scene.EventManager.OnShutdown += OnShutdown; m_Scene.EventManager.OnShutdown += OnShutdown;
// If region ready has been triggered, then the region had no scripts to compile and completed its other
// work.
m_Scene.EventManager.OnRegionReadyStatusChange += s => { if (s.Ready) m_InitialStartup = false; };
if (m_SleepTime > 0) if (m_SleepTime > 0)
{ {
m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoMaintenance), m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoMaintenance),
@ -1270,6 +1276,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
if (instance!=null) if (instance!=null)
instance.Init(); instance.Init();
bool runIt;
if (m_runFlags.TryGetValue(itemID, out runIt))
{
if (!runIt)
StopScript(itemID);
m_runFlags.Remove(itemID);
}
return true; return true;
} }
@ -1660,6 +1674,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
IScriptInstance instance = GetInstance(itemID); IScriptInstance instance = GetInstance(itemID);
if (instance != null) if (instance != null)
instance.Start(); instance.Start();
else
m_runFlags.AddOrUpdate(itemID, true, 240);
} }
public void StopScript(UUID itemID) public void StopScript(UUID itemID)
@ -1671,6 +1687,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
// cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort. // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort.
instance.Stop(1000); instance.Stop(1000);
} }
else
{
m_runFlags.AddOrUpdate(itemID, false, 240);
}
} }
public DetectParams GetDetectParams(UUID itemID, int idx) public DetectParams GetDetectParams(UUID itemID, int idx)

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

@ -122,7 +122,7 @@ namespace OpenSim.Services.Connectors
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception unwrapping folder list: {0}", e.Message); m_log.Error("[XINVENTORY SERVICES CONNECTOR]: Exception unwrapping folder list: ", e);
} }
return fldrs; return fldrs;
@ -191,7 +191,7 @@ namespace OpenSim.Services.Connectors
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetFolderContent: {0}", e.Message); m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Exception in GetFolderContent: {0}", e.Message);
} }
return inventory; return inventory;
@ -432,7 +432,7 @@ namespace OpenSim.Services.Connectors
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetItem: {0}", e.Message); m_log.Error("[XINVENTORY SERVICES CONNECTOR]: Exception in GetItem: ", e);
} }
return null; return null;
@ -456,7 +456,7 @@ namespace OpenSim.Services.Connectors
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetFolder: {0}", e.Message); m_log.Error("[XINVENTORY SERVICES CONNECTOR]: Exception in GetFolder: ", e);
} }
return null; return null;
@ -474,7 +474,7 @@ namespace OpenSim.Services.Connectors
List<InventoryItemBase> items = new List<InventoryItemBase>(); List<InventoryItemBase> items = new List<InventoryItemBase>();
foreach (Object o in ret.Values) // getting the values directly, we don't care about the keys item_i foreach (Object o in ((Dictionary<string,object>)ret["ITEMS"]).Values)
items.Add(BuildItem((Dictionary<string, object>)o)); items.Add(BuildItem((Dictionary<string, object>)o));
return items; return items;
@ -525,7 +525,7 @@ namespace OpenSim.Services.Connectors
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetUserInventory: {0}", e.Message); m_log.Error("[XINVENTORY SERVICES CONNECTOR]: Exception in GetUserInventory: ", e);
} }
return inventory; return inventory;
@ -574,7 +574,7 @@ namespace OpenSim.Services.Connectors
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception building folder: {0}", e.Message); m_log.Error("[XINVENTORY SERVICES CONNECTOR]: Exception building folder: ", e);
} }
return folder; return folder;
@ -613,11 +613,10 @@ namespace OpenSim.Services.Connectors
} }
catch (Exception e) catch (Exception e)
{ {
m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception building item: {0}", e.Message); m_log.Error("[XINVENTORY CONNECTOR]: Exception building item: ", e);
} }
return item; return item;
} }
} }
} }

View File

@ -190,7 +190,7 @@ namespace OpenSim.Tests.Common
= physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test"); = physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test");
testScene.RegionInfo.EstateSettings = new EstateSettings(); testScene.RegionInfo.EstateSettings = new EstateSettings();
testScene.LoginsDisabled = false; testScene.LoginsEnabled = true;
testScene.RegisterRegionWithGrid(); testScene.RegisterRegionWithGrid();
SceneManager.Add(testScene); SceneManager.Add(testScene);

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

@ -47,6 +47,9 @@ namespace pCampBot
{ {
Dictionary<UUID, Primitive> objects = Bot.Objects; Dictionary<UUID, Primitive> objects = Bot.Objects;
if (objects.Count <= 0)
return;
Primitive prim = objects.ElementAt(Bot.Random.Next(0, objects.Count - 1)).Value; Primitive prim = objects.ElementAt(Bot.Random.Next(0, objects.Count - 1)).Value;
// This appears to be a typical message sent when a viewer user clicks a clickable object // This appears to be a typical message sent when a viewer user clicks a clickable object

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="v4_0" 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="v4_0" name="OpenSim.Framework.Servers.HttpServer" path="OpenSim/Framework/Servers/HttpServer" type="Library"> <Project frameworkVersion="v4_0" 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="v4_0" 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="v4_0" name="OpenSim.Data" path="OpenSim/Data" type="Library"> <Project frameworkVersion="v4_0" 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/"/>
@ -640,39 +643,6 @@
</Files> </Files>
</Project> </Project>
<Project frameworkVersion="v4_0" name="OpenSim.Region.Physics.BulletSPlugin" path="OpenSim/Region/Physics/BulletSPlugin" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../bin/Physics/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../bin/Physics/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Core"/>
<Reference name="System.Xml"/>
<Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
<Reference name="Nini.dll" path="../../../../bin/"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/>
<Reference name="log4net.dll" path="../../../../bin/"/>
<Files>
<Match pattern="*.cs" recurse="true">
<Exclude name="Tests" pattern="Tests"/>
</Match>
</Files>
</Project>
<Project frameworkVersion="v4_0" name="OpenSim.Region.Physics.Meshing" path="OpenSim/Region/Physics/Meshing" type="Library"> <Project frameworkVersion="v4_0" name="OpenSim.Region.Physics.Meshing" path="OpenSim/Region/Physics/Meshing" type="Library">
<Configuration name="Debug"> <Configuration name="Debug">
<Options> <Options>
@ -753,9 +723,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/"/>
@ -787,13 +757,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/"/>
@ -839,10 +809,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 -->
@ -1558,10 +1528,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"/>
@ -1649,11 +1619,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/"/>
@ -1686,15 +1656,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/"/>
@ -1777,9 +1747,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"/>
@ -1834,6 +1804,64 @@
</Files> </Files>
</Project> </Project>
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ConvexDecompositionDotNet" path="OpenSim/Region/Physics/ConvexDecompositionDotNet" 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="System.Data"/>
<Reference name="System.Xml"/>
<Files>
<Match pattern="*.cs" recurse="true">
<Exclude name="Tests" pattern="Tests"/>
</Match>
</Files>
</Project>
<Project frameworkVersion="v4_0" name="OpenSim.Region.Physics.BulletSPlugin" path="OpenSim/Region/Physics/BulletSPlugin" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../bin/Physics/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../bin/Physics/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Core"/>
<Reference name="System.Xml"/>
<Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
<Reference name="Nini.dll" path="../../../../bin/"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/>
<Reference name="log4net.dll" path="../../../../bin/"/>
<Files>
<Match pattern="*.cs" recurse="true">
<Exclude name="Tests" pattern="Tests"/>
</Match>
</Files>
</Project>
<!-- OpenSim app --> <!-- OpenSim app -->
<Project frameworkVersion="v4_0" name="OpenSim" path="OpenSim/Region/Application" type="Exe"> <Project frameworkVersion="v4_0" name="OpenSim" path="OpenSim/Region/Application" type="Exe">
<Configuration name="Debug"> <Configuration name="Debug">
@ -1857,15 +1885,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"/>
@ -2378,10 +2406,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"/>
@ -2504,7 +2533,6 @@
</Files> </Files>
</Project> </Project>
<Project frameworkVersion="v4_0" name="OpenSim.Region.UserStatistics" path="OpenSim/Region/UserStatistics" type="Library"> <Project frameworkVersion="v4_0" name="OpenSim.Region.UserStatistics" path="OpenSim/Region/UserStatistics" type="Library">
<Configuration name="Debug"> <Configuration name="Debug">
<Options> <Options>
@ -2533,9 +2561,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"/>
@ -3019,9 +3047,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"/>
@ -3091,9 +3119,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"/>
@ -3150,8 +3178,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"/>
@ -3207,9 +3235,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"/>
@ -3244,7 +3272,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"/>

Some files were not shown because too many files have changed in this diff Show More