Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork

avinationmerge
UbitUmarov 2012-03-26 23:04:07 +01:00
commit caeaa03a69
29 changed files with 795 additions and 296 deletions

View File

@ -188,19 +188,21 @@ namespace OpenSim.Framework.Console
{ {
lock (m_modulesCommands) lock (m_modulesCommands)
{ {
if (m_modulesCommands.ContainsKey(moduleName)) foreach (string key in m_modulesCommands.Keys)
{ {
List<CommandInfo> commands = m_modulesCommands[moduleName]; // Allow topic help requests to succeed whether they are upper or lowercase.
var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help)); if (moduleName.ToLower() == key.ToLower())
ourHelpText.Sort(); {
helpText.AddRange(ourHelpText); List<CommandInfo> commands = m_modulesCommands[key];
var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help));
ourHelpText.Sort();
helpText.AddRange(ourHelpText);
return true; return true;
} }
else
{
return false;
} }
return false;
} }
} }

View File

@ -423,12 +423,18 @@ namespace OpenSim.Framework
set { m_internalEndPoint = value; } set { m_internalEndPoint = value; }
} }
/// <summary>
/// The x co-ordinate of this region in map tiles (e.g. 1000).
/// </summary>
public uint RegionLocX public uint RegionLocX
{ {
get { return m_regionLocX.Value; } get { return m_regionLocX.Value; }
set { m_regionLocX = value; } set { m_regionLocX = value; }
} }
/// <summary>
/// The y co-ordinate of this region in map tiles (e.g. 1000).
/// </summary>
public uint RegionLocY public uint RegionLocY
{ {
get { return m_regionLocY.Value; } get { return m_regionLocY.Value; }

View File

@ -263,15 +263,16 @@ namespace OpenSim
{ {
string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1); string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
// away at some point.
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
"help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'",
HandleCommanderHelp);
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic, m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
"help " + capitalizedTopic, "help " + capitalizedTopic,
"Get help on plugin command '" + topic + "'", "Get help on plugin command '" + topic + "'",
HandleCommanderHelp); HandleCommanderHelp);
//
// m_console.Commands.AddCommand("General", false, topic,
// topic,
// "Execute subcommand for plugin '" + topic + "'",
// null);
ICommander commander = null; ICommander commander = null;
@ -508,8 +509,7 @@ namespace OpenSim
scene.SnmpService.LinkUp(scene); scene.SnmpService.LinkUp(scene);
} }
scene.StartTimer(); scene.Start();
scene.StartTimerWatchdog();
scene.StartScripts(); scene.StartScripts();

View File

@ -132,13 +132,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
{ {
// We need to do this because: // We need to do this because:
// "Saving the image to the same file it was constructed from is not allowed and throws an exception." // "Saving the image to the same file it was constructed from is not allowed and throws an exception."
string tempName = offsetX + "_ " + offsetY + "_" + filename; string tempName = Path.GetTempFileName();
Bitmap entireBitmap = null; Bitmap entireBitmap = null;
Bitmap thisBitmap = null; Bitmap thisBitmap = null;
if (File.Exists(filename)) if (File.Exists(filename))
{ {
File.Copy(filename, tempName); File.Copy(filename, tempName, true);
entireBitmap = new Bitmap(tempName); entireBitmap = new Bitmap(tempName);
if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY) if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY)
{ {
@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
} }
thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); thisBitmap = CreateGrayscaleBitmapFromMap(m_channel);
Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); // Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
for (int x = 0; x < regionSizeX; x++) for (int x = 0; x < regionSizeX; x++)
for (int y = 0; y < regionSizeY; y++) for (int y = 0; y < regionSizeY; y++)
entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y));

View File

@ -38,6 +38,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain
ITerrainChannel LoadStream(Stream stream); ITerrainChannel LoadStream(Stream stream);
void SaveFile(string filename, ITerrainChannel map); void SaveFile(string filename, ITerrainChannel map);
void SaveStream(Stream stream, ITerrainChannel map); void SaveStream(Stream stream, ITerrainChannel map);
/// <summary>
/// Save a number of map tiles to a single big image file.
/// </summary>
/// <remarks>
/// If the image file already exists then the tiles saved will replace those already in the file - other tiles
/// will be untouched.
/// </remarks>
/// <param name="filename">The terrain file to save</param>
/// <param name="offsetX">The map x co-ordinate at which to begin the save.</param>
/// <param name="offsetY">The may y co-ordinate at which to begin the save.</param>
/// <param name="fileWidth">The number of tiles to save along the X axis.</param>
/// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
/// <param name="regionSizeX">The width of a map tile.</param>
/// <param name="regionSizeY">The height of a map tile.</param>
void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY); void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY);
} }
} }

View File

@ -561,49 +561,56 @@ namespace OpenSim.Region.CoreModules.World.Terrain
} }
/// <summary> /// <summary>
/// Saves the terrain to a larger terrain file. /// Save a number of map tiles to a single big image file.
/// </summary> /// </summary>
/// <remarks>
/// If the image file already exists then the tiles saved will replace those already in the file - other tiles
/// will be untouched.
/// </remarks>
/// <param name="filename">The terrain file to save</param> /// <param name="filename">The terrain file to save</param>
/// <param name="fileWidth">The width of the file in units</param> /// <param name="fileWidth">The number of tiles to save along the X axis.</param>
/// <param name="fileHeight">The height of the file in units</param> /// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
/// <param name="fileStartX">Where to begin our slice</param> /// <param name="fileStartX">The map x co-ordinate at which to begin the save.</param>
/// <param name="fileStartY">Where to begin our slice</param> /// <param name="fileStartY">The may y co-ordinate at which to begin the save.</param>
public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
{ {
int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX; int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX;
int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY; int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY;
if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) if (offsetX < 0 || offsetX >= fileWidth || offsetY < 0 || offsetY >= fileHeight)
{ {
// this region is included in the tile request MainConsole.Instance.OutputFormat(
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) "ERROR: file width + minimum X tile and file height + minimum Y tile must incorporate the current region at ({0},{1}). File width {2} from {3} and file height {4} from {5} does not.",
m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, fileWidth, fileStartX, fileHeight, fileStartY);
return;
}
// this region is included in the tile request
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
{
if (filename.EndsWith(loader.Key))
{ {
if (filename.EndsWith(loader.Key)) lock (m_scene)
{ {
lock (m_scene) loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
{ fileWidth, fileHeight,
loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, (int)Constants.RegionSize,
fileWidth, fileHeight, (int)Constants.RegionSize);
(int)Constants.RegionSize,
(int)Constants.RegionSize);
m_log.InfoFormat("[TERRAIN]: Saved terrain from {0} to {1}", m_scene.RegionInfo.RegionName, filename); MainConsole.Instance.OutputFormat(
} "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}",
fileStartX, fileStartY, fileStartX + fileWidth - 1, fileStartY + fileHeight - 1,
return; m_scene.RegionInfo.RegionName, filename);
} }
}
m_log.ErrorFormat( return;
"[TERRAIN]: Could not save terrain from {0} to {1}. Valid file extensions are {2}", }
m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions);
}
else
{
m_log.ErrorFormat(
"[TERRAIN]: Could not save terrain from {0} to {1}. {2} {3} {4} {5} {6} {7}",
m_scene.RegionInfo.RegionName, filename, fileWidth, fileHeight, fileStartX, fileStartY, offsetX, offsetY);
} }
MainConsole.Instance.OutputFormat(
"ERROR: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions);
} }
/// <summary> /// <summary>
@ -1194,6 +1201,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
"Integer"); "Integer");
saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file",
"Integer"); "Integer");
saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first tile on the file\n"
+ "= Example =\n"
+ "To save a PNG file for a set of map tiles 2 regions wide and 3 regions high from map co-ordinate (9910,10234)\n"
+ " # terrain save-tile ST06.png 2 3 9910 10234\n",
"Integer");
// Terrain adjustments // Terrain adjustments
Command fillRegionCommand = Command fillRegionCommand =
new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value."); new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value.");

View File

@ -26,12 +26,12 @@
*/ */
using System; using System;
using System.Reflection;
using OpenMetaverse; using OpenMetaverse;
namespace OpenSim.Region.Framework.Interfaces namespace OpenSim.Region.Framework.Interfaces
{ {
public delegate void ScriptCommand(UUID script, string id, string module, string command, string k); public delegate void ScriptCommand(UUID script, string id, string module, string command, string k);
public delegate object ScriptInvocation(UUID script, object[] parms);
/// <summary> /// <summary>
/// Interface for communication between OpenSim modules and in-world scripts /// Interface for communication between OpenSim modules and in-world scripts
@ -46,14 +46,17 @@ namespace OpenSim.Region.Framework.Interfaces
/// </summary> /// </summary>
event ScriptCommand OnScriptCommand; event ScriptCommand OnScriptCommand;
void RegisterScriptInvocation(string name, ScriptInvocation fn, Type[] csig, Type rsig); void RegisterScriptInvocation(object target, string method);
void RegisterScriptInvocation(object target, MethodInfo method);
void RegisterScriptInvocation(object target, string[] methods);
Delegate[] GetScriptInvocationList();
ScriptInvocation LookupScriptInvocation(string fname); Delegate LookupScriptInvocation(string fname);
string LookupModInvocation(string fname); string LookupModInvocation(string fname);
Type[] LookupTypeSignature(string fname); Type[] LookupTypeSignature(string fname);
Type LookupReturnType(string fname); Type LookupReturnType(string fname);
object InvokeOperation(UUID scriptId, string fname, params object[] parms); object InvokeOperation(UUID hostId, UUID scriptId, string fname, params object[] parms);
/// <summary> /// <summary>
/// Send a link_message event to an in-world script /// Send a link_message event to an in-world script

View File

@ -125,7 +125,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
// XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
// are referenced with lower case names! // are referenced with lower case names!
UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name); UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
if (animID == UUID.Zero) if (animID == UUID.Zero)
return; return;

View File

@ -104,6 +104,11 @@ namespace OpenSim.Region.Framework.Scenes
public bool m_allowScriptCrossings; public bool m_allowScriptCrossings;
public bool m_useFlySlow; public bool m_useFlySlow;
/// <summary>
/// Temporarily setting to trigger appearance resends at 60 second intervals.
/// </summary>
public bool SendPeriodicAppearanceUpdates { get; set; }
protected float m_defaultDrawDistance = 255.0f; protected float m_defaultDrawDistance = 255.0f;
public float DefaultDrawDistance public float DefaultDrawDistance
{ {
@ -171,6 +176,11 @@ namespace OpenSim.Region.Framework.Scenes
protected set; protected set;
} }
/// <summary>
/// Current maintenance run number
/// </summary>
public uint MaintenanceRun { get; private set; }
/// <summary> /// <summary>
/// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we
/// will sleep for the remaining period. /// will sleep for the remaining period.
@ -181,6 +191,11 @@ namespace OpenSim.Region.Framework.Scenes
/// </remarks> /// </remarks>
public float MinFrameTime { get; private set; } public float MinFrameTime { get; private set; }
/// <summary>
/// The minimum length of time in seconds that will be taken for a maintenance run.
/// </summary>
public float MinMaintenanceTime { get; private set; }
private int m_update_physics = 1; private int m_update_physics = 1;
private int m_update_entitymovement = 1; private int m_update_entitymovement = 1;
private int m_update_objects = 1; private int m_update_objects = 1;
@ -209,20 +224,23 @@ namespace OpenSim.Region.Framework.Scenes
private int m_lastFrameTick; private int m_lastFrameTick;
public bool CombineRegions = false; public bool CombineRegions = false;
/// <summary>
/// Tick at which the last maintenance run occurred.
/// </summary>
private int m_lastMaintenanceTick;
/// <summary> /// <summary>
/// Signals whether temporary objects are currently being cleaned up. Needed because this is launched /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
/// asynchronously from the update loop. /// asynchronously from the update loop.
/// </summary> /// </summary>
private bool m_cleaningTemps = false; private bool m_cleaningTemps = false;
private Object m_heartbeatLock = new Object(); // private Object m_heartbeatLock = new Object();
// TODO: Possibly stop other classes being able to manipulate this directly. // TODO: Possibly stop other classes being able to manipulate this directly.
private SceneGraph m_sceneGraph; private SceneGraph m_sceneGraph;
private volatile int m_bordersLocked; private volatile int m_bordersLocked;
// private int m_RestartTimerCounter;
private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
// private int m_incrementsof15seconds;
private volatile bool m_backingup; private volatile bool m_backingup;
private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
@ -230,16 +248,34 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_physics_enabled = true; private bool m_physics_enabled = true;
private bool m_scripts_enabled = true; private bool m_scripts_enabled = true;
private string m_defaultScriptEngine; private string m_defaultScriptEngine;
private int m_LastLogin;
private Thread HeartbeatThread = null;
private volatile bool shuttingdown;
private int m_lastUpdate; /// <summary>
/// Tick at which the last login occurred.
/// </summary>
private int m_LastLogin;
private int m_lastIncoming; private int m_lastIncoming;
private int m_lastOutgoing; private int m_lastOutgoing;
private bool m_firstHeartbeat = true;
private int m_hbRestarts = 0; private int m_hbRestarts = 0;
/// <summary>
/// Thread that runs the scene loop.
/// </summary>
private Thread m_heartbeatThread;
/// <summary>
/// True if these scene is in the process of shutting down or is shutdown.
/// </summary>
public bool ShuttingDown
{
get { return m_shuttingDown; }
}
private volatile bool m_shuttingDown;
// private int m_lastUpdate;
private bool m_firstHeartbeat = true;
private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
private bool m_reprioritizationEnabled = true; private bool m_reprioritizationEnabled = true;
private double m_reprioritizationInterval = 5000.0; private double m_reprioritizationInterval = 5000.0;
@ -566,6 +602,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_config = config; m_config = config;
MinFrameTime = 0.089f; MinFrameTime = 0.089f;
MinMaintenanceTime = 1;
Random random = new Random(); Random random = new Random();
@ -577,7 +614,6 @@ namespace OpenSim.Region.Framework.Scenes
m_EstateDataService = estateDataService; m_EstateDataService = estateDataService;
m_regionHandle = m_regInfo.RegionHandle; m_regionHandle = m_regInfo.RegionHandle;
m_regionName = m_regInfo.RegionName; m_regionName = m_regInfo.RegionName;
m_lastUpdate = Util.EnvironmentTickCount();
m_lastIncoming = 0; m_lastIncoming = 0;
m_lastOutgoing = 0; m_lastOutgoing = 0;
@ -759,6 +795,7 @@ namespace OpenSim.Region.Framework.Scenes
m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences); m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences);
m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
SendPeriodicAppearanceUpdates = startupConfig.GetBoolean("SendPeriodicAppearanceUpdates", SendPeriodicAppearanceUpdates);
} }
} }
catch (Exception e) catch (Exception e)
@ -834,18 +871,13 @@ namespace OpenSim.Region.Framework.Scenes
m_permissions = new ScenePermissions(this); m_permissions = new ScenePermissions(this);
m_lastUpdate = Util.EnvironmentTickCount(); // m_lastUpdate = Util.EnvironmentTickCount();
} }
#endregion #endregion
#region Startup / Close Methods #region Startup / Close Methods
public bool ShuttingDown
{
get { return shuttingdown; }
}
/// <value> /// <value>
/// The scene graph for this scene /// The scene graph for this scene
/// </value> /// </value>
@ -1107,6 +1139,12 @@ namespace OpenSim.Region.Framework.Scenes
m_physics_enabled = enablePhysics; m_physics_enabled = enablePhysics;
} }
// if (options.ContainsKey("collisions"))
// {
// // TODO: Implement. If false, should stop objects colliding, though possibly should still allow
// // the avatar themselves to collide with the ground.
// }
if (options.ContainsKey("teleport")) if (options.ContainsKey("teleport"))
{ {
bool enableTeleportDebugging; bool enableTeleportDebugging;
@ -1158,8 +1196,7 @@ namespace OpenSim.Region.Framework.Scenes
ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
// Stop updating the scene objects and agents. // Stop updating the scene objects and agents.
//m_heartbeatTimer.Close(); m_shuttingDown = true;
shuttingdown = true;
m_log.Debug("[SCENE]: Persisting changed objects"); m_log.Debug("[SCENE]: Persisting changed objects");
EventManager.TriggerSceneShuttingDown(this); EventManager.TriggerSceneShuttingDown(this);
@ -1183,16 +1220,16 @@ namespace OpenSim.Region.Framework.Scenes
} }
/// <summary> /// <summary>
/// Start the timer which triggers regular scene updates /// Start the scene
/// </summary> /// </summary>
public void StartTimer() public void Start()
{ {
// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
//m_heartbeatTimer.Enabled = true; //m_heartbeatTimer.Enabled = true;
//m_heartbeatTimer.Interval = (int)(m_timespan * 1000); //m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
//m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
if (HeartbeatThread != null) if (m_heartbeatThread != null)
{ {
m_hbRestarts++; m_hbRestarts++;
if(m_hbRestarts > 10) if(m_hbRestarts > 10)
@ -1208,13 +1245,13 @@ namespace OpenSim.Region.Framework.Scenes
//proc.WaitForExit(); //proc.WaitForExit();
//Thread.Sleep(1000); //Thread.Sleep(1000);
//Environment.Exit(1); //Environment.Exit(1);
HeartbeatThread.Abort(); m_heartbeatThread.Abort();
Watchdog.AbortThread(HeartbeatThread.ManagedThreadId); Watchdog.AbortThread(m_heartbeatThread.ManagedThreadId);
HeartbeatThread = null; m_heartbeatThread = null;
} }
m_lastUpdate = Util.EnvironmentTickCount(); // m_lastUpdate = Util.EnvironmentTickCount();
HeartbeatThread m_heartbeatThread
= Watchdog.StartThread( = Watchdog.StartThread(
Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false); Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false);
} }
@ -1245,34 +1282,107 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
private void Heartbeat() private void Heartbeat()
{ {
if (!Monitor.TryEnter(m_heartbeatLock)) // if (!Monitor.TryEnter(m_heartbeatLock))
{ // {
Watchdog.RemoveThread(); // Watchdog.RemoveThread();
return; // return;
} // }
try // try
{ // {
m_eventManager.TriggerOnRegionStarted(this);
// The first frame can take a very long time due to physics actors being added on startup. Therefore, m_eventManager.TriggerOnRegionStarted(this);
// don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
// alarms for scenes with many objects.
Update(1);
Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
while (!shuttingdown) // The first frame can take a very long time due to physics actors being added on startup. Therefore,
Update(-1); // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
} // alarms for scenes with many objects.
finally Update(1);
{
Monitor.Pulse(m_heartbeatLock); Watchdog.StartThread(
Monitor.Exit(m_heartbeatLock); Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
}
Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
Update(-1);
// m_lastUpdate = Util.EnvironmentTickCount();
// m_firstHeartbeat = false;
// }
// finally
// {
// Monitor.Pulse(m_heartbeatLock);
// Monitor.Exit(m_heartbeatLock);
// }
Watchdog.RemoveThread(); Watchdog.RemoveThread();
} }
private void Maintenance()
{
DoMaintenance(-1);
Watchdog.RemoveThread();
}
public void DoMaintenance(int runs)
{
long? endRun = null;
int runtc;
int previousMaintenanceTick;
if (runs >= 0)
endRun = MaintenanceRun + runs;
List<Vector3> coarseLocations;
List<UUID> avatarUUIDs;
while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun))
{
runtc = Util.EnvironmentTickCount();
++MaintenanceRun;
// Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
if (MaintenanceRun % (m_update_coarse_locations / 10) == 0)
{
SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
// Send coarse locations to clients
ForEachScenePresence(delegate(ScenePresence presence)
{
presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
});
}
if (SendPeriodicAppearanceUpdates && MaintenanceRun % 60 == 0)
{
// m_log.DebugFormat("[SCENE]: Sending periodic appearance updates");
if (AvatarFactory != null)
{
ForEachRootScenePresence(sp => AvatarFactory.SendAppearance(sp.UUID));
}
}
Watchdog.UpdateThread();
previousMaintenanceTick = m_lastMaintenanceTick;
m_lastMaintenanceTick = Util.EnvironmentTickCount();
runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc);
runtc = (int)(MinMaintenanceTime * 1000) - runtc;
if (runtc > 0)
Thread.Sleep(runtc);
// Optionally warn if a frame takes double the amount of time that it should.
if (DebugUpdates
&& Util.EnvironmentTickCountSubtract(
m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2))
m_log.WarnFormat(
"[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}",
Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick),
MinMaintenanceTime * 1000,
RegionInfo.RegionName);
}
}
public override void Update(int frames) public override void Update(int frames)
{ {
long? endFrame = null; long? endFrame = null;
@ -1284,10 +1394,8 @@ namespace OpenSim.Region.Framework.Scenes
int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS; int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS;
int previousFrameTick; int previousFrameTick;
int maintc; int maintc;
List<Vector3> coarseLocations;
List<UUID> avatarUUIDs;
while (!shuttingdown && (endFrame == null || Frame < endFrame)) while (!m_shuttingDown && (endFrame == null || Frame < endFrame))
{ {
maintc = Util.EnvironmentTickCount(); maintc = Util.EnvironmentTickCount();
++Frame; ++Frame;
@ -1337,17 +1445,6 @@ namespace OpenSim.Region.Framework.Scenes
if (Frame % m_update_presences == 0) if (Frame % m_update_presences == 0)
m_sceneGraph.UpdatePresences(); m_sceneGraph.UpdatePresences();
// Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
if (Frame % m_update_coarse_locations == 0)
{
SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
// Send coarse locations to clients
ForEachScenePresence(delegate(ScenePresence presence)
{
presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
});
}
agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS);
// Delete temp-on-rez stuff // Delete temp-on-rez stuff
@ -1455,7 +1552,6 @@ namespace OpenSim.Region.Framework.Scenes
EventManager.TriggerRegionHeartbeatEnd(this); EventManager.TriggerRegionHeartbeatEnd(this);
// Tell the watchdog that this thread is still alive
Watchdog.UpdateThread(); Watchdog.UpdateThread();
previousFrameTick = m_lastFrameTick; previousFrameTick = m_lastFrameTick;
@ -1463,15 +1559,11 @@ namespace OpenSim.Region.Framework.Scenes
maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc); maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc);
maintc = (int)(MinFrameTime * 1000) - maintc; maintc = (int)(MinFrameTime * 1000) - maintc;
m_lastUpdate = Util.EnvironmentTickCount();
m_firstHeartbeat = false; m_firstHeartbeat = false;
if (maintc > 0) if (maintc > 0)
Thread.Sleep(maintc); Thread.Sleep(maintc);
m_lastUpdate = Util.EnvironmentTickCount();
m_firstHeartbeat = false;
// Optionally warn if a frame takes double the amount of time that it should. // Optionally warn if a frame takes double the amount of time that it should.
if (DebugUpdates if (DebugUpdates
&& Util.EnvironmentTickCountSubtract( && Util.EnvironmentTickCountSubtract(
@ -2662,7 +2754,6 @@ namespace OpenSim.Region.Framework.Scenes
|| (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
CheckHeartbeat(); CheckHeartbeat();
ScenePresence presence;
ScenePresence sp = GetScenePresence(client.AgentId); ScenePresence sp = GetScenePresence(client.AgentId);
@ -3253,7 +3344,7 @@ namespace OpenSim.Region.Framework.Scenes
public override void RemoveClient(UUID agentID, bool closeChildAgents) public override void RemoveClient(UUID agentID, bool closeChildAgents)
{ {
CheckHeartbeat(); // CheckHeartbeat();
bool isChildAgent = false; bool isChildAgent = false;
ScenePresence avatar = GetScenePresence(agentID); ScenePresence avatar = GetScenePresence(agentID);
if (avatar != null) if (avatar != null)
@ -4700,7 +4791,7 @@ namespace OpenSim.Region.Framework.Scenes
int health=1; // Start at 1, means we're up int health=1; // Start at 1, means we're up
if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000) if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000)
{ {
health+=1; health+=1;
flags |= 1; flags |= 1;
@ -4737,6 +4828,8 @@ Environment.Exit(1);
// //
if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000) if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
health++; health++;
else
return health;
return health; return health;
} }
@ -4929,8 +5022,8 @@ Environment.Exit(1);
if (m_firstHeartbeat) if (m_firstHeartbeat)
return; return;
if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000) if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) > 5000)
StartTimer(); Start();
} }
public override ISceneObject DeserializeObject(string representation) public override ISceneObject DeserializeObject(string representation)

View File

@ -233,6 +233,8 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_collisionEventFlag = false; private bool m_collisionEventFlag = false;
private object m_collisionEventLock = new Object(); private object m_collisionEventLock = new Object();
private int m_movementAnimationUpdateCounter = 0;
private Vector3 m_prevSitOffset; private Vector3 m_prevSitOffset;
protected AvatarAppearance m_appearance; protected AvatarAppearance m_appearance;
@ -741,6 +743,26 @@ namespace OpenSim.Region.Framework.Scenes
Appearance = appearance; Appearance = appearance;
} }
private void RegionHeartbeatEnd(Scene scene)
{
if (IsChildAgent)
return;
m_movementAnimationUpdateCounter ++;
if (m_movementAnimationUpdateCounter >= 2)
{
m_movementAnimationUpdateCounter = 0;
if (Animator != null)
{
Animator.UpdateMovementAnimations();
}
else
{
m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
}
}
}
public void RegisterToEvents() public void RegisterToEvents()
{ {
ControllingClient.OnCompleteMovementToRegion += CompleteMovement; ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
@ -952,6 +974,8 @@ namespace OpenSim.Region.Framework.Scenes
MovementFlag = 0; MovementFlag = 0;
m_scene.EventManager.TriggerOnMakeRootAgent(this); m_scene.EventManager.TriggerOnMakeRootAgent(this);
m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
} }
public int GetStateSource() public int GetStateSource()
@ -979,6 +1003,8 @@ namespace OpenSim.Region.Framework.Scenes
/// </remarks> /// </remarks>
public void MakeChildAgent() public void MakeChildAgent()
{ {
m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName);
// Reset these so that teleporting in and walking out isn't seen // Reset these so that teleporting in and walking out isn't seen
@ -2377,14 +2403,15 @@ namespace OpenSim.Region.Framework.Scenes
direc.Z *= 2.6f; direc.Z *= 2.6f;
// TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
Animator.TrySetMovementAnimation("PREJUMP"); // Animator.TrySetMovementAnimation("PREJUMP");
Animator.TrySetMovementAnimation("JUMP"); // Animator.TrySetMovementAnimation("JUMP");
} }
} }
} }
// TODO: Add the force instead of only setting it to support multiple forces per frame? // TODO: Add the force instead of only setting it to support multiple forces per frame?
m_forceToApply = direc; m_forceToApply = direc;
Animator.UpdateMovementAnimations();
} }
#endregion #endregion
@ -3334,18 +3361,6 @@ 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 (Animator != null)
{
// 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;

View File

@ -264,14 +264,14 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters
private void WriteOut(string msg, params object[] args) private void WriteOut(string msg, params object[] args)
{ {
m_log.InfoFormat(msg, args); // m_log.InfoFormat(msg, args);
// MainConsole.Instance.OutputFormat(msg, args); MainConsole.Instance.OutputFormat(msg, args);
} }
private void WriteError(string msg, params object[] args) private void WriteError(string msg, params object[] args)
{ {
m_log.ErrorFormat(msg, args); // m_log.ErrorFormat(msg, args);
// MainConsole.Instance.OutputFormat(msg, args); MainConsole.Instance.OutputFormat(msg, args);
} }
} }
} }

View File

@ -70,8 +70,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
//m_log.Info("[RegionReady] Initialising");
m_config = config.Configs["RegionReady"]; m_config = config.Configs["RegionReady"];
if (m_config != null) if (m_config != null)
{ {
@ -84,9 +82,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
m_uri = m_config.GetString("alert_uri",string.Empty); m_uri = m_config.GetString("alert_uri",string.Empty);
} }
} }
// if (!m_enabled)
// m_log.Info("[RegionReady] disabled.");
} }
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
@ -113,7 +108,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
{ {
scene.LoginLock = true; scene.LoginLock = true;
scene.LoginsDisabled = true; scene.LoginsDisabled = true;
m_log.InfoFormat("[RegionReady]: Logins disabled for {0}",m_scene.RegionInfo.RegionName); m_log.InfoFormat("[RegionReady]: Region {0} - logins disabled during initialization.",m_scene.RegionInfo.RegionName);
if(m_uri != string.Empty) if(m_uri != string.Empty)
{ {
@ -167,7 +162,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
void OnEmptyScriptCompileQueue(int numScriptsFailed, string message) void OnEmptyScriptCompileQueue(int numScriptsFailed, string message)
{ {
m_log.InfoFormat("[RegionReady]: Script compile queue empty!"); m_log.DebugFormat("[RegionReady]: Script compile queue empty!");
if (m_firstEmptyCompileQueue || m_oarFileLoading) if (m_firstEmptyCompileQueue || m_oarFileLoading)
{ {
@ -194,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
c.SenderUUID = UUID.Zero; c.SenderUUID = UUID.Zero;
c.Scene = m_scene; c.Scene = m_scene;
m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", m_log.DebugFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}",
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);
@ -210,7 +205,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
{ {
m_lastOarLoadedOk = true; m_lastOarLoadedOk = true;
} else { } else {
m_log.InfoFormat("[RegionReady]: Oar file load errors: {0}", message); m_log.WarnFormat("[RegionReady]: Oar file load errors: {0}", message);
m_lastOarLoadedOk = false; m_lastOarLoadedOk = false;
} }
} }
@ -233,7 +228,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
// 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("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName); m_log.InfoFormat("[RegionReady]: Initialization complete - logins enabled for {0}", m_scene.RegionInfo.RegionName);
if ( m_uri != string.Empty ) if ( m_uri != string.Empty )
{ {

View File

@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using Mono.Addins; using Mono.Addins;
using OpenMetaverse; using OpenMetaverse;
using System.Linq;
using System.Linq.Expressions;
namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
{ {
@ -47,15 +49,15 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
#region ScriptInvocation #region ScriptInvocation
protected class ScriptInvocationData protected class ScriptInvocationData
{ {
public ScriptInvocation ScriptInvocationFn { get; private set; } public Delegate ScriptInvocationDelegate { get; private set; }
public string FunctionName { get; private set; } public string FunctionName { get; private set; }
public Type[] TypeSignature { get; private set; } public Type[] TypeSignature { get; private set; }
public Type ReturnType { get; private set; } public Type ReturnType { get; private set; }
public ScriptInvocationData(string fname, ScriptInvocation fn, Type[] callsig, Type returnsig) public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig)
{ {
FunctionName = fname; FunctionName = fname;
ScriptInvocationFn = fn; ScriptInvocationDelegate = fn;
TypeSignature = callsig; TypeSignature = callsig;
ReturnType = returnsig; ReturnType = returnsig;
} }
@ -126,14 +128,72 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
m_scriptModule.PostScriptEvent(script, "link_message", args); m_scriptModule.PostScriptEvent(script, "link_message", args);
} }
public void RegisterScriptInvocation(string fname, ScriptInvocation fcall, Type[] csig, Type rsig) public void RegisterScriptInvocation(object target, string meth)
{ {
MethodInfo mi = target.GetType().GetMethod(meth,
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if (mi == null)
{
m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth);
return;
}
RegisterScriptInvocation(target, mi);
}
public void RegisterScriptInvocation(object target, string[] meth)
{
foreach (string m in meth)
RegisterScriptInvocation(target, m);
}
public void RegisterScriptInvocation(object target, MethodInfo mi)
{
m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, target.GetType().Name);
Type delegateType;
var typeArgs = mi.GetParameters()
.Select(p => p.ParameterType)
.ToList();
if (mi.ReturnType == typeof(void))
{
delegateType = Expression.GetActionType(typeArgs.ToArray());
}
else
{
typeArgs.Add(mi.ReturnType);
delegateType = Expression.GetFuncType(typeArgs.ToArray());
}
Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi);
lock (m_scriptInvocation) lock (m_scriptInvocation)
{ {
m_scriptInvocation[fname] = new ScriptInvocationData(fname,fcall,csig,rsig); ParameterInfo[] parameters = fcall.Method.GetParameters ();
if (parameters.Length < 2) // Must have two UUID params
return;
// Hide the first two parameters
Type[] parmTypes = new Type[parameters.Length - 2];
for (int i = 2 ; i < parameters.Length ; i++)
parmTypes[i - 2] = parameters[i].ParameterType;
m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType);
} }
} }
public Delegate[] GetScriptInvocationList()
{
List<Delegate> ret = new List<Delegate>();
lock (m_scriptInvocation)
{
foreach (ScriptInvocationData d in m_scriptInvocation.Values)
ret.Add(d.ScriptInvocationDelegate);
}
return ret.ToArray();
}
public string LookupModInvocation(string fname) public string LookupModInvocation(string fname)
{ {
lock (m_scriptInvocation) lock (m_scriptInvocation)
@ -147,19 +207,29 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
return "modInvokeI"; return "modInvokeI";
else if (sid.ReturnType == typeof(float)) else if (sid.ReturnType == typeof(float))
return "modInvokeF"; return "modInvokeF";
else if (sid.ReturnType == typeof(UUID))
return "modInvokeK";
else if (sid.ReturnType == typeof(OpenMetaverse.Vector3))
return "modInvokeV";
else if (sid.ReturnType == typeof(OpenMetaverse.Quaternion))
return "modInvokeR";
else if (sid.ReturnType == typeof(object[]))
return "modInvokeL";
m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
} }
} }
return null; return null;
} }
public ScriptInvocation LookupScriptInvocation(string fname) public Delegate LookupScriptInvocation(string fname)
{ {
lock (m_scriptInvocation) lock (m_scriptInvocation)
{ {
ScriptInvocationData sid; ScriptInvocationData sid;
if (m_scriptInvocation.TryGetValue(fname,out sid)) if (m_scriptInvocation.TryGetValue(fname,out sid))
return sid.ScriptInvocationFn; return sid.ScriptInvocationDelegate;
} }
return null; return null;
@ -189,10 +259,15 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
return null; return null;
} }
public object InvokeOperation(UUID scriptid, string fname, params object[] parms) public object InvokeOperation(UUID hostid, UUID scriptid, string fname, params object[] parms)
{ {
ScriptInvocation fn = LookupScriptInvocation(fname); List<object> olist = new List<object>();
return fn(scriptid,parms); olist.Add(hostid);
olist.Add(scriptid);
foreach (object o in parms)
olist.Add(o);
Delegate fn = LookupScriptInvocation(fname);
return fn.DynamicInvoke(olist.ToArray());
} }
#endregion #endregion

View File

@ -94,7 +94,7 @@ public class BSCharacter : PhysicsActor
_flying = isFlying; _flying = isFlying;
_orientation = Quaternion.Identity; _orientation = Quaternion.Identity;
_velocity = Vector3.Zero; _velocity = Vector3.Zero;
_buoyancy = isFlying ? 1f : 0f; _buoyancy = ComputeBuoyancyFromFlying(isFlying);
_scale = new Vector3(1f, 1f, 1f); _scale = new Vector3(1f, 1f, 1f);
_density = _scene.Params.avatarDensity; _density = _scene.Params.avatarDensity;
ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
@ -110,7 +110,7 @@ public class BSCharacter : PhysicsActor
shapeData.Buoyancy = _buoyancy; shapeData.Buoyancy = _buoyancy;
shapeData.Static = ShapeData.numericFalse; shapeData.Static = ShapeData.numericFalse;
shapeData.Friction = _scene.Params.avatarFriction; shapeData.Friction = _scene.Params.avatarFriction;
shapeData.Restitution = _scene.Params.defaultRestitution; shapeData.Restitution = _scene.Params.avatarRestitution;
// do actual create at taint time // do actual create at taint time
_scene.TaintedObject(delegate() _scene.TaintedObject(delegate()
@ -260,13 +260,13 @@ public class BSCharacter : PhysicsActor
get { return _flying; } get { return _flying; }
set { set {
_flying = value; _flying = value;
_scene.TaintedObject(delegate() // simulate flying by changing the effect of gravity
{ this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
// simulate flying by changing the effect of gravity
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _flying ? 1f : 0f);
});
} }
} }
private float ComputeBuoyancyFromFlying(bool ifFlying) {
return ifFlying ? 1f : 0f;
}
public override bool public override bool
SetAlwaysRun { SetAlwaysRun {
get { return _setAlwaysRun; } get { return _setAlwaysRun; }
@ -299,6 +299,7 @@ public class BSCharacter : PhysicsActor
get { return _kinematic; } get { return _kinematic; }
set { _kinematic = value; } set { _kinematic = value; }
} }
// neg=fall quickly, 0=1g, 1=0g, pos=float up
public override float Buoyancy { public override float Buoyancy {
get { return _buoyancy; } get { return _buoyancy; }
set { _buoyancy = value; set { _buoyancy = value;
@ -355,7 +356,7 @@ public class BSCharacter : PhysicsActor
} }
else else
{ {
m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); m_log.ErrorFormat("{0}: Got a NaN force applied to a Character", LogHeader);
} }
//m_lastUpdateSent = false; //m_lastUpdateSent = false;
} }

View File

@ -821,7 +821,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
*/ */
// Get what the body is doing, this includes 'external' influences // Get what the body is doing, this includes 'external' influences
Vector3 angularVelocity = m_prim.AngularVelocity; Vector3 angularVelocity = m_prim.RotationalVelocity;
// Vector3 angularVelocity = Vector3.Zero; // Vector3 angularVelocity = Vector3.Zero;
if (m_angularMotorApply > 0) if (m_angularMotorApply > 0)
@ -910,7 +910,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
// Apply to the body // Apply to the body
m_prim.AngularVelocity = m_lastAngularVelocity; m_prim.RotationalVelocity = m_lastAngularVelocity;
} //end MoveAngular } //end MoveAngular
internal void LimitRotation(float timestep) internal void LimitRotation(float timestep)

View File

@ -85,7 +85,6 @@ public sealed class BSPrim : PhysicsActor
private OMV.Vector3 _rotationalVelocity; private OMV.Vector3 _rotationalVelocity;
private bool _kinematic; private bool _kinematic;
private float _buoyancy; private float _buoyancy;
private OMV.Vector3 _angularVelocity;
private List<BSPrim> _childrenPrims; private List<BSPrim> _childrenPrims;
private BSPrim _parentPrim; private BSPrim _parentPrim;
@ -119,7 +118,6 @@ public sealed class BSPrim : PhysicsActor
_buoyancy = 1f; _buoyancy = 1f;
_velocity = OMV.Vector3.Zero; _velocity = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero;
_angularVelocity = OMV.Vector3.Zero;
_hullKey = 0; _hullKey = 0;
_meshKey = 0; _meshKey = 0;
_pbs = pbs; _pbs = pbs;
@ -146,7 +144,7 @@ public sealed class BSPrim : PhysicsActor
// called when this prim is being destroyed and we should free all the resources // called when this prim is being destroyed and we should free all the resources
public void Destroy() public void Destroy()
{ {
// m_log.DebugFormat("{0}: Destroy", LogHeader); // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, 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
@ -203,7 +201,7 @@ 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 = (BSPrim)obj; BSPrim parent = obj as BSPrim;
// m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); // m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
// TODO: decide if this parent checking needs to happen at taint time // TODO: decide if this parent checking needs to happen at taint time
if (_parentPrim == null) if (_parentPrim == null)
@ -527,10 +525,6 @@ public sealed class BSPrim : PhysicsActor
}); });
} }
} }
public OMV.Vector3 AngularVelocity {
get { return _angularVelocity; }
set { _angularVelocity = value; }
}
public override bool Kinematic { public override bool Kinematic {
get { return _kinematic; } get { return _kinematic; }
set { _kinematic = value; set { _kinematic = value;
@ -993,7 +987,7 @@ public sealed class BSPrim : PhysicsActor
} }
// m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
// LogHeader, _localID, _meshKey, indices.Length, vertices.Count); // LogHeader, _localID, _meshKey, indices.Length, vertices.Count);
BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices, BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices,
vertices.Count, verticesAsFloats); vertices.Count, verticesAsFloats);
@ -1127,7 +1121,7 @@ public sealed class BSPrim : PhysicsActor
return; return;
} }
// Create an object in Bullet // 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() private void CreateObject()
{ {
@ -1324,7 +1318,8 @@ 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}", LogHeader, LocalID, changed, _position, _orientation); // 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);
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
} }
} }

View File

@ -37,14 +37,18 @@ using OpenMetaverse;
using OpenSim.Region.Framework; using OpenSim.Region.Framework;
// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
// Debug linkset
// Test with multiple regions in one simulator
// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) // Adjust character capsule size when height is adjusted (ScenePresence.SetHeight)
// Test sculpties // Test sculpties
// Compute physics FPS reasonably // Compute physics FPS reasonably
// Based on material, set density and friction // Based on material, set density and friction
// More efficient memory usage in passing hull information from BSPrim to BulletSim // More efficient memory usage when passing hull information from BSPrim to BulletSim
// Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly? // Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly?
// In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground) // In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground)
// At the moment, physical and phantom causes object to drop through the terrain // At the moment, physical and phantom causes object to drop through the terrain
// Physical phantom objects and related typing (collision options )
// Check out llVolumeDetect. Must do something for that.
// Should prim.link() and prim.delink() membership checking happen at taint time? // Should prim.link() and prim.delink() membership checking happen at taint time?
// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once // Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect // Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
@ -52,6 +56,16 @@ using OpenSim.Region.Framework;
// Implement LockAngularMotion // Implement LockAngularMotion
// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) // Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
// Does NeedsMeshing() really need to exclude all the different shapes? // Does NeedsMeshing() really need to exclude all the different shapes?
// Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet.
// Add PID movement operations. What does ScenePresence.MoveToTarget do?
// Check terrain size. 128 or 127?
// Multiple contact points on collision?
// See code in ode::near... calls to collision_accounting_events()
// (This might not be a problem. ODE collects all the collisions with one object in one tick.)
// Use collision masks for collision with terrain and phantom objects
// Figure out how to not allocate a new Dictionary and List for every collision
// in BSPrim.Collide() and BSCharacter.Collide(). Can the same ones be reused?
// Raycast
// //
namespace OpenSim.Region.Physics.BulletSPlugin namespace OpenSim.Region.Physics.BulletSPlugin
{ {
@ -164,6 +178,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
if (m_log.IsDebugEnabled) if (m_log.IsDebugEnabled)
{ {
m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
// the handle is saved to it doesn't get freed after this call
m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
} }
@ -172,7 +187,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
mesher = meshmerizer; mesher = meshmerizer;
// The bounding box for the simulated world // The bounding box for the simulated world
Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f); Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f);
// m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
@ -220,10 +235,20 @@ public class BSScene : PhysicsScene, IPhysicsParameters
parms.terrainFriction = 0.5f; parms.terrainFriction = 0.5f;
parms.terrainHitFraction = 0.8f; parms.terrainHitFraction = 0.8f;
parms.terrainRestitution = 0f; parms.terrainRestitution = 0f;
parms.avatarFriction = 0.0f; parms.avatarFriction = 0.5f;
parms.avatarRestitution = 0.0f;
parms.avatarDensity = 60f; parms.avatarDensity = 60f;
parms.avatarCapsuleRadius = 0.37f; parms.avatarCapsuleRadius = 0.37f;
parms.avatarCapsuleHeight = 1.5f; // 2.140599f parms.avatarCapsuleHeight = 1.5f; // 2.140599f
parms.avatarContactProcessingThreshold = 0.1f;
parms.maxPersistantManifoldPoolSize = 0f;
parms.shouldDisableContactPoolDynamicAllocation = ConfigurationParameters.numericTrue;
parms.shouldForceUpdateAllAabbs = ConfigurationParameters.numericFalse;
parms.shouldRandomizeSolverOrder = ConfigurationParameters.numericFalse;
parms.shouldSplitSimulationIslands = ConfigurationParameters.numericFalse;
parms.shouldEnableFrictionCaching = ConfigurationParameters.numericFalse;
parms.numberOfSolverIterations = 0f; // means use default
if (config != null) if (config != null)
{ {
@ -265,14 +290,40 @@ public class BSScene : PhysicsScene, IPhysicsParameters
parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction); parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction);
parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution); parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution);
parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction); parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction);
parms.avatarRestitution = pConfig.GetFloat("AvatarRestitution", parms.avatarRestitution);
parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity); parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity);
parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius); parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius);
parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight); parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight);
parms.avatarContactProcessingThreshold = pConfig.GetFloat("AvatarContactProcessingThreshold", parms.avatarContactProcessingThreshold);
parms.maxPersistantManifoldPoolSize = pConfig.GetFloat("MaxPersistantManifoldPoolSize", parms.maxPersistantManifoldPoolSize);
parms.shouldDisableContactPoolDynamicAllocation = ParamBoolean(pConfig, "ShouldDisableContactPoolDynamicAllocation", parms.shouldDisableContactPoolDynamicAllocation);
parms.shouldForceUpdateAllAabbs = ParamBoolean(pConfig, "ShouldForceUpdateAllAabbs", parms.shouldForceUpdateAllAabbs);
parms.shouldRandomizeSolverOrder = ParamBoolean(pConfig, "ShouldRandomizeSolverOrder", parms.shouldRandomizeSolverOrder);
parms.shouldSplitSimulationIslands = ParamBoolean(pConfig, "ShouldSplitSimulationIslands", parms.shouldSplitSimulationIslands);
parms.shouldEnableFrictionCaching = ParamBoolean(pConfig, "ShouldEnableFrictionCaching", parms.shouldEnableFrictionCaching);
parms.numberOfSolverIterations = pConfig.GetFloat("NumberOfSolverIterations", parms.numberOfSolverIterations);
} }
} }
m_params[0] = parms; m_params[0] = parms;
} }
// A helper function that handles a true/false parameter and returns the proper float number encoding
float ParamBoolean(IConfig config, string parmName, float deflt)
{
float ret = deflt;
if (config.Contains(parmName))
{
ret = ConfigurationParameters.numericFalse;
if (config.GetBoolean(parmName, false))
{
ret = ConfigurationParameters.numericTrue;
}
}
return ret;
}
// Called directly from unmanaged code so don't do much // Called directly from unmanaged code so don't do much
private void BulletLogger(string msg) private void BulletLogger(string msg)
{ {
@ -391,16 +442,16 @@ public class BSScene : PhysicsScene, IPhysicsParameters
{ {
EntityProperties entprop = m_updateArray[ii]; EntityProperties entprop = m_updateArray[ii];
// m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position); // m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position);
BSCharacter actor;
if (m_avatars.TryGetValue(entprop.ID, out actor))
{
actor.UpdateProperties(entprop);
continue;
}
BSPrim prim; BSPrim prim;
if (m_prims.TryGetValue(entprop.ID, out prim)) if (m_prims.TryGetValue(entprop.ID, out prim))
{ {
prim.UpdateProperties(entprop); prim.UpdateProperties(entprop);
continue;
}
BSCharacter actor;
if (m_avatars.TryGetValue(entprop.ID, out actor))
{
actor.UpdateProperties(entprop);
} }
} }
} }
@ -470,12 +521,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public override void DeleteTerrain() public override void DeleteTerrain()
{ {
m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
} }
public override void Dispose() public override void Dispose()
{ {
m_log.DebugFormat("{0}: Dispose()", LogHeader); // m_log.DebugFormat("{0}: Dispose()", LogHeader);
} }
public override Dictionary<uint, float> GetTopColliders() public override Dictionary<uint, float> GetTopColliders()
@ -699,9 +750,23 @@ public class BSScene : PhysicsScene, IPhysicsParameters
new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ), new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ),
new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ), new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ),
new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ), new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ),
// new PhysParameterEntry("CcdMotionThreshold", "" ), new PhysParameterEntry("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ),
// new PhysParameterEntry("CcdSweptSphereRadius", "" ), new PhysParameterEntry("CcdSweptSphereRadius", "Continuious collision detection test radius" ),
new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ), new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ),
// Can only change the following at initialization time. Change the INI file and reboot.
new PhysParameterEntry("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)"),
new PhysParameterEntry("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count"),
new PhysParameterEntry("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step"),
new PhysParameterEntry("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction"),
new PhysParameterEntry("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands"),
new PhysParameterEntry("ShouldEnableFrictionCaching", "Enable friction computation caching"),
new PhysParameterEntry("NumberOfSolverIterations", "Number of internal iterations (0 means default)"),
new PhysParameterEntry("Friction", "Set friction parameter for a specific object" ),
new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ),
new PhysParameterEntry("Friction", "Set friction parameter for a specific object" ),
new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ),
new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ), new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ),
new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ), new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ),
@ -710,7 +775,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ), new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ),
new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ), new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ),
new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ), new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ),
new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" ) new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" ),
new PhysParameterEntry("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions")
}; };
#region IPhysicsParameters #region IPhysicsParameters
@ -733,6 +800,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
switch (lparm) switch (lparm)
{ {
case "detailedstats": m_detailedStatsStep = (int)val; break; case "detailedstats": m_detailedStatsStep = (int)val; break;
case "meshlod": m_meshLOD = (int)val; break; case "meshlod": m_meshLOD = (int)val; break;
case "sculptlod": m_sculptLOD = (int)val; break; case "sculptlod": m_sculptLOD = (int)val; break;
case "maxsubstep": m_maxSubSteps = (int)val; break; case "maxsubstep": m_maxSubSteps = (int)val; break;
@ -743,7 +811,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
case "defaultdensity": m_params[0].defaultDensity = val; break; case "defaultdensity": m_params[0].defaultDensity = val; break;
case "defaultrestitution": m_params[0].defaultRestitution = val; break; case "defaultrestitution": m_params[0].defaultRestitution = val; break;
case "collisionmargin": m_params[0].collisionMargin = val; break; case "collisionmargin": m_params[0].collisionMargin = val; break;
case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break; case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, localID, val); break;
case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break; case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break;
case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
@ -753,6 +821,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters
case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break; case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break;
case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break; case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break;
case "contactprocessingthreshold": UpdateParameterPrims(ref m_params[0].contactProcessingThreshold, lparm, localID, val); break; case "contactprocessingthreshold": UpdateParameterPrims(ref m_params[0].contactProcessingThreshold, lparm, localID, val); break;
// the following are used only at initialization time so setting them makes no sense
// case "maxPersistantmanifoldpoolSize": m_params[0].maxPersistantManifoldPoolSize = val; break;
// case "shoulddisablecontactpooldynamicallocation": m_params[0].shouldDisableContactPoolDynamicAllocation = val; break;
// case "shouldforceupdateallaabbs": m_params[0].shouldForceUpdateAllAabbs = val; break;
// case "shouldrandomizesolverorder": m_params[0].shouldRandomizeSolverOrder = val; break;
// case "shouldsplitsimulationislands": m_params[0].shouldSplitSimulationIslands = val; break;
// case "shouldenablefrictioncaching": m_params[0].shouldEnableFrictionCaching = val; break;
// case "numberofsolveriterations": m_params[0].numberOfSolverIterations = val; break;
case "friction": TaintedUpdateParameter(lparm, localID, val); break;
case "restitution": TaintedUpdateParameter(lparm, localID, val); break;
// set a terrain physical feature and cause terrain to be recalculated // set a terrain physical feature and cause terrain to be recalculated
case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break; case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break;
@ -764,6 +843,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break; case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break;
case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break; case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break;
case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break; case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break;
case "avatarcontactprocessingthreshold": UpdateParameterAvatars(ref m_params[0].avatarContactProcessingThreshold, "avatar", localID, val); break;
default: ret = false; break; default: ret = false; break;
} }
@ -856,6 +936,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break; case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break;
case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break; case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break;
case "contactprocessingthreshold": val = m_params[0].contactProcessingThreshold; break; case "contactprocessingthreshold": val = m_params[0].contactProcessingThreshold; break;
case "maxPersistantmanifoldpoolSize": val = m_params[0].maxPersistantManifoldPoolSize; break;
case "shoulddisablecontactpooldynamicallocation": val = m_params[0].shouldDisableContactPoolDynamicAllocation; break;
case "shouldforceupdateallaabbs": val = m_params[0].shouldForceUpdateAllAabbs; break;
case "shouldrandomizesolverorder": val = m_params[0].shouldRandomizeSolverOrder; break;
case "shouldsplitsimulationislands": val = m_params[0].shouldSplitSimulationIslands; break;
case "shouldenablefrictioncaching": val = m_params[0].shouldEnableFrictionCaching; break;
case "numberofsolveriterations": val = m_params[0].numberOfSolverIterations; break;
case "terrainfriction": val = m_params[0].terrainFriction; break; case "terrainfriction": val = m_params[0].terrainFriction; break;
case "terrainhitfraction": val = m_params[0].terrainHitFraction; break; case "terrainhitfraction": val = m_params[0].terrainHitFraction; break;
@ -866,6 +953,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
case "avatarrestitution": val = m_params[0].avatarRestitution; break; case "avatarrestitution": val = m_params[0].avatarRestitution; break;
case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break; case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break;
case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break; case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break;
case "avatarcontactprocessingthreshold": val = m_params[0].avatarContactProcessingThreshold; break;
default: ret = false; break; default: ret = false; break;
} }

View File

@ -132,6 +132,15 @@ public struct ConfigurationParameters
public float avatarRestitution; public float avatarRestitution;
public float avatarCapsuleRadius; public float avatarCapsuleRadius;
public float avatarCapsuleHeight; public float avatarCapsuleHeight;
public float avatarContactProcessingThreshold;
public float maxPersistantManifoldPoolSize;
public float shouldDisableContactPoolDynamicAllocation;
public float shouldForceUpdateAllAabbs;
public float shouldRandomizeSolverOrder;
public float shouldSplitSimulationIslands;
public float shouldEnableFrictionCaching;
public float numberOfSolverIterations;
public const float numericTrue = 1f; public const float numericTrue = 1f;
public const float numericFalse = 0f; public const float numericFalse = 0f;
@ -148,17 +157,17 @@ public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
int maxCollisions, IntPtr collisionArray, int maxCollisions, IntPtr collisionArray,
int maxUpdates, IntPtr updateArray); int maxUpdates, IntPtr updateArray);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool UpdateParameter(uint worldID, uint localID,
[MarshalAs(UnmanagedType.LPStr)]string paramCode, float value);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void Shutdown(uint worldID); public static extern void Shutdown(uint worldID);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool UpdateParameter(uint worldID, uint localID,
[MarshalAs(UnmanagedType.LPStr)]string paramCode, float value);
// ===============================================================================
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep, public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep,
out int updatedEntityCount, out int updatedEntityCount,
@ -240,6 +249,7 @@ public static extern bool HasObject(uint worldID, uint id);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool DestroyObject(uint worldID, uint id); public static extern bool DestroyObject(uint worldID, uint id);
// ===============================================================================
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern SweepHit ConvexSweepTest(uint worldID, uint id, Vector3 to, float extraMargin); public static extern SweepHit ConvexSweepTest(uint worldID, uint id, Vector3 to, float extraMargin);
@ -249,6 +259,7 @@ public static extern RaycastHit RayTest(uint worldID, uint id, Vector3 from, Vec
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern Vector3 RecoverFromPenetration(uint worldID, uint id); public static extern Vector3 RecoverFromPenetration(uint worldID, uint id);
// ===============================================================================
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void DumpBulletStatistics(); public static extern void DumpBulletStatistics();

View File

@ -120,33 +120,110 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
/// ///
/// </summary> /// </summary>
/// <param name="fname">The name of the function to invoke</param> /// <param name="fname">The name of the function to invoke</param>
/// <param name="fname">List of parameters</param> /// <param name="parms">List of parameters</param>
/// <returns>string result of the invocation</returns> /// <returns>string result of the invocation</returns>
public string modInvokeS(string fname, params object[] parms) public void modInvokeN(string fname, params object[] parms)
{ {
Type returntype = m_comms.LookupReturnType(fname); Type returntype = m_comms.LookupReturnType(fname);
if (returntype != typeof(string)) if (returntype != typeof(string))
MODError(String.Format("return type mismatch for {0}",fname)); MODError(String.Format("return type mismatch for {0}",fname));
return (string)modInvoke(fname,parms); modInvoke(fname,parms);
} }
public int modInvokeI(string fname, params object[] parms) public LSL_String modInvokeS(string fname, params object[] parms)
{
Type returntype = m_comms.LookupReturnType(fname);
if (returntype != typeof(string))
MODError(String.Format("return type mismatch for {0}",fname));
string result = (string)modInvoke(fname,parms);
return new LSL_String(result);
}
public LSL_Integer modInvokeI(string fname, params object[] parms)
{ {
Type returntype = m_comms.LookupReturnType(fname); Type returntype = m_comms.LookupReturnType(fname);
if (returntype != typeof(int)) if (returntype != typeof(int))
MODError(String.Format("return type mismatch for {0}",fname)); MODError(String.Format("return type mismatch for {0}",fname));
return (int)modInvoke(fname,parms); int result = (int)modInvoke(fname,parms);
return new LSL_Integer(result);
} }
public float modInvokeF(string fname, params object[] parms) public LSL_Float modInvokeF(string fname, params object[] parms)
{ {
Type returntype = m_comms.LookupReturnType(fname); Type returntype = m_comms.LookupReturnType(fname);
if (returntype != typeof(float)) if (returntype != typeof(float))
MODError(String.Format("return type mismatch for {0}",fname)); MODError(String.Format("return type mismatch for {0}",fname));
return (float)modInvoke(fname,parms); float result = (float)modInvoke(fname,parms);
return new LSL_Float(result);
}
public LSL_Key modInvokeK(string fname, params object[] parms)
{
Type returntype = m_comms.LookupReturnType(fname);
if (returntype != typeof(UUID))
MODError(String.Format("return type mismatch for {0}",fname));
UUID result = (UUID)modInvoke(fname,parms);
return new LSL_Key(result.ToString());
}
public LSL_Vector modInvokeV(string fname, params object[] parms)
{
Type returntype = m_comms.LookupReturnType(fname);
if (returntype != typeof(OpenMetaverse.Vector3))
MODError(String.Format("return type mismatch for {0}",fname));
OpenMetaverse.Vector3 result = (OpenMetaverse.Vector3)modInvoke(fname,parms);
return new LSL_Vector(result.X,result.Y,result.Z);
}
public LSL_Rotation modInvokeR(string fname, params object[] parms)
{
Type returntype = m_comms.LookupReturnType(fname);
if (returntype != typeof(OpenMetaverse.Quaternion))
MODError(String.Format("return type mismatch for {0}",fname));
OpenMetaverse.Quaternion result = (OpenMetaverse.Quaternion)modInvoke(fname,parms);
return new LSL_Rotation(result.X,result.Y,result.Z,result.W);
}
public LSL_List modInvokeL(string fname, params object[] parms)
{
Type returntype = m_comms.LookupReturnType(fname);
if (returntype != typeof(object[]))
MODError(String.Format("return type mismatch for {0}",fname));
object[] result = (object[])modInvoke(fname,parms);
object[] llist = new object[result.Length];
for (int i = 0; i < result.Length; i++)
{
if (result[i] is string)
llist[i] = new LSL_String((string)result[i]);
else if (result[i] is int)
llist[i] = new LSL_Integer((int)result[i]);
else if (result[i] is float)
llist[i] = new LSL_Float((float)result[i]);
else if (result[i] is OpenMetaverse.Vector3)
{
OpenMetaverse.Vector3 vresult = (OpenMetaverse.Vector3)result[i];
llist[i] = new LSL_Vector(vresult.X,vresult.Y,vresult.Z);
}
else if (result[i] is OpenMetaverse.Quaternion)
{
OpenMetaverse.Quaternion qresult = (OpenMetaverse.Quaternion)result[i];
llist[i] = new LSL_Rotation(qresult.X,qresult.Y,qresult.Z,qresult.W);
}
else
{
MODError(String.Format("unknown list element returned by {0}",fname));
}
}
return new LSL_List(llist);
} }
/// <summary> /// <summary>
@ -168,63 +245,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
MODError(String.Format("wrong number of parameters to function {0}",fname)); MODError(String.Format("wrong number of parameters to function {0}",fname));
object[] convertedParms = new object[parms.Length]; object[] convertedParms = new object[parms.Length];
for (int i = 0; i < parms.Length; i++) for (int i = 0; i < parms.Length; i++)
convertedParms[i] = ConvertFromLSL(parms[i],signature[i]);
// now call the function, the contract with the function is that it will always return
// non-null but don't trust it completely
try
{ {
if (parms[i] is LSL_String) object result = m_comms.InvokeOperation(m_host.UUID, m_itemID, fname, convertedParms);
{ if (result != null)
if (signature[i] != typeof(string)) return result;
MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
convertedParms[i] = (string)(LSL_String)parms[i]; MODError(String.Format("Invocation of {0} failed; null return value",fname));
} }
else if (parms[i] is LSL_Integer) catch (Exception e)
{ {
if (signature[i] != typeof(int)) MODError(String.Format("Invocation of {0} failed; {1}",fname,e.Message));
MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
convertedParms[i] = (int)(LSL_Integer)parms[i];
}
else if (parms[i] is LSL_Float)
{
if (signature[i] != typeof(float))
MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
convertedParms[i] = (float)(LSL_Float)parms[i];
}
else if (parms[i] is LSL_Key)
{
if (signature[i] != typeof(string))
MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
convertedParms[i] = (string)(LSL_Key)parms[i];
}
else if (parms[i] is LSL_Rotation)
{
if (signature[i] != typeof(string))
MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
convertedParms[i] = (string)(LSL_Rotation)parms[i];
}
else if (parms[i] is LSL_Vector)
{
if (signature[i] != typeof(string))
MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
convertedParms[i] = (string)(LSL_Vector)parms[i];
}
else
{
if (signature[i] != parms[i].GetType())
MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name));
convertedParms[i] = parms[i];
}
} }
return m_comms.InvokeOperation(m_itemID,fname,convertedParms); return null;
} }
/// <summary>
/// Send a command to functions registered on an event
/// </summary>
public string modSendCommand(string module, string command, string k) public string modSendCommand(string module, string command, string k)
{ {
if (!m_MODFunctionsEnabled) if (!m_MODFunctionsEnabled)
@ -239,5 +283,101 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return req.ToString(); return req.ToString();
} }
/// <summary>
/// </summary>
protected object ConvertFromLSL(object lslparm, Type type)
{
// ---------- String ----------
if (lslparm is LSL_String)
{
if (type == typeof(string))
return (string)(LSL_String)lslparm;
// Need to check for UUID since keys are often treated as strings
if (type == typeof(UUID))
return new UUID((string)(LSL_String)lslparm);
}
// ---------- Integer ----------
else if (lslparm is LSL_Integer)
{
if (type == typeof(int))
return (int)(LSL_Integer)lslparm;
}
// ---------- Float ----------
else if (lslparm is LSL_Float)
{
if (type == typeof(float))
return (float)(LSL_Float)lslparm;
}
// ---------- Key ----------
else if (lslparm is LSL_Key)
{
if (type == typeof(UUID))
return new UUID((LSL_Key)lslparm);
}
// ---------- Rotation ----------
else if (lslparm is LSL_Rotation)
{
if (type == typeof(OpenMetaverse.Quaternion))
{
LSL_Rotation rot = (LSL_Rotation)lslparm;
return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
}
}
// ---------- Vector ----------
else if (lslparm is LSL_Vector)
{
if (type == typeof(OpenMetaverse.Vector3))
{
LSL_Vector vect = (LSL_Vector)lslparm;
return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
}
}
// ---------- List ----------
else if (lslparm is LSL_List)
{
if (type == typeof(object[]))
{
object[] plist = (lslparm as LSL_List).Data;
object[] result = new object[plist.Length];
for (int i = 0; i < plist.Length; i++)
{
if (plist[i] is LSL_String)
result[i] = (string)(LSL_String)plist[i];
else if (plist[i] is LSL_Integer)
result[i] = (int)(LSL_Integer)plist[i];
else if (plist[i] is LSL_Float)
result[i] = (float)(LSL_Float)plist[i];
else if (plist[i] is LSL_Key)
result[i] = new UUID((LSL_Key)plist[i]);
else if (plist[i] is LSL_Rotation)
{
LSL_Rotation rot = (LSL_Rotation)plist[i];
result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
}
else if (plist[i] is LSL_Vector)
{
LSL_Vector vect = (LSL_Vector)plist[i];
result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
}
else
MODError("unknown LSL list element type");
}
return result;
}
}
MODError(String.Format("parameter type mismatch; expecting {0}",type.Name));
return null;
}
} }
} }

View File

@ -28,26 +28,27 @@
using System.Collections; using System.Collections;
using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Interfaces;
using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
{ {
public interface IMOD_Api public interface IMOD_Api
{ {
// Invocation functions // Invocation functions
string modInvokeS(string fname, params object[] parms); void modInvokeN(string fname, params object[] parms);
int modInvokeI(string fname, params object[] parms); LSL_String modInvokeS(string fname, params object[] parms);
float modInvokeF(string fname, params object[] parms); LSL_Integer modInvokeI(string fname, params object[] parms);
// vector modInvokeV(string fname, params object[] parms); LSL_Float modInvokeF(string fname, params object[] parms);
// rotation modInvokeV(string fname, params object[] parms); LSL_Key modInvokeK(string fname, params object[] parms);
// key modInvokeK(string fname, params object[] parms); LSL_Vector modInvokeV(string fname, params object[] parms);
// list modInvokeL(string fname, params object[] parms); LSL_Rotation modInvokeR(string fname, params object[] parms);
LSL_List modInvokeL(string fname, params object[] parms);
//Module functions //Module functions
string modSendCommand(string modules, string command, string k); string modSendCommand(string modules, string command, string k);

View File

@ -39,10 +39,14 @@ using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{ {
@ -58,21 +62,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_MOD_Functions = (IMOD_Api)api; m_MOD_Functions = (IMOD_Api)api;
} }
public string modInvokeS(string fname, params object[] parms) public void modInvokeN(string fname, params object[] parms)
{
m_MOD_Functions.modInvokeN(fname, parms);
}
public LSL_String modInvokeS(string fname, params object[] parms)
{ {
return m_MOD_Functions.modInvokeS(fname, parms); return m_MOD_Functions.modInvokeS(fname, parms);
} }
public int modInvokeI(string fname, params object[] parms) public LSL_Integer modInvokeI(string fname, params object[] parms)
{ {
return m_MOD_Functions.modInvokeI(fname, parms); return m_MOD_Functions.modInvokeI(fname, parms);
} }
public float modInvokeF(string fname, params object[] parms) public LSL_Float modInvokeF(string fname, params object[] parms)
{ {
return m_MOD_Functions.modInvokeF(fname, parms); return m_MOD_Functions.modInvokeF(fname, parms);
} }
public LSL_Key modInvokeK(string fname, params object[] parms)
{
return m_MOD_Functions.modInvokeK(fname, parms);
}
public LSL_Vector modInvokeV(string fname, params object[] parms)
{
return m_MOD_Functions.modInvokeV(fname, parms);
}
public LSL_Rotation modInvokeR(string fname, params object[] parms)
{
return m_MOD_Functions.modInvokeR(fname, parms);
}
public LSL_List modInvokeL(string fname, params object[] parms)
{
return m_MOD_Functions.modInvokeL(fname, parms);
}
public string modSendCommand(string module, string command, string k) public string modSendCommand(string module, string command, string k)
{ {
return m_MOD_Functions.modSendCommand(module, command, k); return m_MOD_Functions.modSendCommand(module, command, k);

View File

@ -226,7 +226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
break; break;
} }
} }
int z = 0;
try try
{ {
if (gotMatch) if (gotMatch)
@ -235,8 +235,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
finally finally
{ {
// Manually finalize all the iterators. // Manually finalize all the iterators.
for (int i = 0; i < nIterators; ++i) for (z = 0; z < nIterators; ++z)
iterators[i].Dispose(); iterators[z].Dispose();
} }
} }
} }

View File

@ -576,7 +576,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
break; break;
} }
} }
int z = 0;
try try
{ {
if (gotMatch) if (gotMatch)
@ -585,8 +585,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
finally finally
{ {
// Manually finalize all the iterators. // Manually finalize all the iterators.
for (int i = 0; i < nIterators; ++i) for (z = 0; z < nIterators; ++z)
iterators[i].Dispose(); iterators[z].Dispose();
} }
} }

View File

@ -73,17 +73,19 @@ namespace OpenSim.Server.Handlers.Login
if (requestData != null) if (requestData != null)
{ {
foreach (string key in requestData.Keys) // Debug code to show exactly what login parameters the viewer is sending us.
{ // TODO: Extract into a method that can be generally applied if one doesn't already exist.
object value = requestData[key]; // foreach (string key in requestData.Keys)
Console.WriteLine("{0}:{1}", key, value); // {
if (value is ArrayList) // object value = requestData[key];
{ // Console.WriteLine("{0}:{1}", key, value);
ICollection col = value as ICollection; // if (value is ArrayList)
foreach (object item in col) // {
Console.WriteLine(" {0}", item); // ICollection col = value as ICollection;
} // foreach (object item in col)
} // Console.WriteLine(" {0}", item);
// }
// }
if (requestData.ContainsKey("first") && requestData["first"] != null && if (requestData.ContainsKey("first") && requestData["first"] != null &&
requestData.ContainsKey("last") && requestData["last"] != null && ( requestData.ContainsKey("last") && requestData["last"] != null && (

View File

@ -177,6 +177,11 @@
; Objects will always be considered for persistance in the next sweep if the first change occurred this number of seconds ago ; Objects will always be considered for persistance in the next sweep if the first change occurred this number of seconds ago
MaximumTimeBeforePersistenceConsidered = 600 MaximumTimeBeforePersistenceConsidered = 600
; Experimental setting to resend appearance updates every 60 seconds.
; These packets are small and this can help with grey avatar syndrome.
; Default is false
SendPeriodicAppearanceUpdates = false
; ## ; ##
; ## PHYSICS ; ## PHYSICS
; ## ; ##
@ -841,10 +846,12 @@
TerrainFriction = 0.50 TerrainFriction = 0.50
TerrainHitFriction = 0.8 TerrainHitFriction = 0.8
TerrainRestitution = 0 TerrainRestitution = 0
AvatarFriction = 0 AvatarFriction = 0.2
AvatarRestitution = 0.0
AvatarDensity = 60.0 AvatarDensity = 60.0
AvatarCapsuleRadius = 0.37 AvatarCapsuleRadius = 0.37
AvatarCapsuleHeight = 1.5 AvatarCapsuleHeight = 1.5
AvatarContactProcessingThreshold = 0.1;
MaxObjectMass = 10000.01 MaxObjectMass = 10000.01
@ -857,6 +864,14 @@
CcdMotionThreshold = 0.0 CcdMotionThreshold = 0.0
CcdSweptSphereRadius = 0.0 CcdSweptSphereRadius = 0.0
ContactProcessingThreshold = 0.1 ContactProcessingThreshold = 0.1
MaxPersistantManifoldPoolSize = 0;
ShouldDisableContactPoolDynamicAllocation = True;
ShouldForceUpdateAllAabbs = False;
ShouldRandomizeSolverOrder = False;
ShouldSplitSimulationIslands = False;
ShouldEnableFrictionCaching = False;
NumberOfSolverIterations = 0;
; Whether to mesh sculpties ; Whether to mesh sculpties
MeshSculptedPrim = true MeshSculptedPrim = true

Binary file not shown.

BIN
bin/lib32/libBulletSim.so Executable file

Binary file not shown.

Binary file not shown.

BIN
bin/lib64/libBulletSim.so Executable file

Binary file not shown.