diff options
Diffstat (limited to 'OpenSim/Region')
21 files changed, 747 insertions, 273 deletions
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index b304403..ddc7f10 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs | |||
@@ -263,15 +263,16 @@ namespace OpenSim | |||
263 | { | 263 | { |
264 | string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1); | 264 | string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1); |
265 | 265 | ||
266 | // This is a hack to allow the user to enter the help command in upper or lowercase. This will go | ||
267 | // away at some point. | ||
268 | m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic, | ||
269 | "help " + capitalizedTopic, | ||
270 | "Get help on plugin command '" + topic + "'", | ||
271 | HandleCommanderHelp); | ||
266 | m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic, | 272 | m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic, |
267 | "help " + capitalizedTopic, | 273 | "help " + capitalizedTopic, |
268 | "Get help on plugin command '" + topic + "'", | 274 | "Get help on plugin command '" + topic + "'", |
269 | HandleCommanderHelp); | 275 | HandleCommanderHelp); |
270 | // | ||
271 | // m_console.Commands.AddCommand("General", false, topic, | ||
272 | // topic, | ||
273 | // "Execute subcommand for plugin '" + topic + "'", | ||
274 | // null); | ||
275 | 276 | ||
276 | ICommander commander = null; | 277 | ICommander commander = null; |
277 | 278 | ||
@@ -508,8 +509,7 @@ namespace OpenSim | |||
508 | scene.SnmpService.LinkUp(scene); | 509 | scene.SnmpService.LinkUp(scene); |
509 | } | 510 | } |
510 | 511 | ||
511 | scene.StartTimer(); | 512 | scene.Start(); |
512 | scene.StartTimerWatchdog(); | ||
513 | 513 | ||
514 | scene.StartScripts(); | 514 | scene.StartScripts(); |
515 | 515 | ||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index 21a9999..58925fd 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs | |||
@@ -132,13 +132,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
132 | { | 132 | { |
133 | // We need to do this because: | 133 | // We need to do this because: |
134 | // "Saving the image to the same file it was constructed from is not allowed and throws an exception." | 134 | // "Saving the image to the same file it was constructed from is not allowed and throws an exception." |
135 | string tempName = offsetX + "_ " + offsetY + "_" + filename; | 135 | string tempName = Path.GetTempFileName(); |
136 | 136 | ||
137 | Bitmap entireBitmap = null; | 137 | Bitmap entireBitmap = null; |
138 | Bitmap thisBitmap = null; | 138 | Bitmap thisBitmap = null; |
139 | if (File.Exists(filename)) | 139 | if (File.Exists(filename)) |
140 | { | 140 | { |
141 | File.Copy(filename, tempName); | 141 | File.Copy(filename, tempName, true); |
142 | entireBitmap = new Bitmap(tempName); | 142 | entireBitmap = new Bitmap(tempName); |
143 | if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY) | 143 | if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY) |
144 | { | 144 | { |
@@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
152 | } | 152 | } |
153 | 153 | ||
154 | thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); | 154 | thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); |
155 | Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); | 155 | // Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); |
156 | for (int x = 0; x < regionSizeX; x++) | 156 | for (int x = 0; x < regionSizeX; x++) |
157 | for (int y = 0; y < regionSizeY; y++) | 157 | for (int y = 0; y < regionSizeY; y++) |
158 | entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); | 158 | entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs index 7237f90..d407617 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs | |||
@@ -38,6 +38,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
38 | ITerrainChannel LoadStream(Stream stream); | 38 | ITerrainChannel LoadStream(Stream stream); |
39 | void SaveFile(string filename, ITerrainChannel map); | 39 | void SaveFile(string filename, ITerrainChannel map); |
40 | void SaveStream(Stream stream, ITerrainChannel map); | 40 | void SaveStream(Stream stream, ITerrainChannel map); |
41 | |||
42 | /// <summary> | ||
43 | /// Save a number of map tiles to a single big image file. | ||
44 | /// </summary> | ||
45 | /// <remarks> | ||
46 | /// If the image file already exists then the tiles saved will replace those already in the file - other tiles | ||
47 | /// will be untouched. | ||
48 | /// </remarks> | ||
49 | /// <param name="filename">The terrain file to save</param> | ||
50 | /// <param name="offsetX">The map x co-ordinate at which to begin the save.</param> | ||
51 | /// <param name="offsetY">The may y co-ordinate at which to begin the save.</param> | ||
52 | /// <param name="fileWidth">The number of tiles to save along the X axis.</param> | ||
53 | /// <param name="fileHeight">The number of tiles to save along the Y axis.</param> | ||
54 | /// <param name="regionSizeX">The width of a map tile.</param> | ||
55 | /// <param name="regionSizeY">The height of a map tile.</param> | ||
41 | void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY); | 56 | void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY); |
42 | } | 57 | } |
43 | } \ No newline at end of file | 58 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index b5e79b8..9159f0c 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | |||
@@ -561,49 +561,56 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
561 | } | 561 | } |
562 | 562 | ||
563 | /// <summary> | 563 | /// <summary> |
564 | /// Saves the terrain to a larger terrain file. | 564 | /// Save a number of map tiles to a single big image file. |
565 | /// </summary> | 565 | /// </summary> |
566 | /// <remarks> | ||
567 | /// If the image file already exists then the tiles saved will replace those already in the file - other tiles | ||
568 | /// will be untouched. | ||
569 | /// </remarks> | ||
566 | /// <param name="filename">The terrain file to save</param> | 570 | /// <param name="filename">The terrain file to save</param> |
567 | /// <param name="fileWidth">The width of the file in units</param> | 571 | /// <param name="fileWidth">The number of tiles to save along the X axis.</param> |
568 | /// <param name="fileHeight">The height of the file in units</param> | 572 | /// <param name="fileHeight">The number of tiles to save along the Y axis.</param> |
569 | /// <param name="fileStartX">Where to begin our slice</param> | 573 | /// <param name="fileStartX">The map x co-ordinate at which to begin the save.</param> |
570 | /// <param name="fileStartY">Where to begin our slice</param> | 574 | /// <param name="fileStartY">The may y co-ordinate at which to begin the save.</param> |
571 | public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) | 575 | public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) |
572 | { | 576 | { |
573 | int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX; | 577 | int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX; |
574 | int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY; | 578 | int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY; |
575 | 579 | ||
576 | if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) | 580 | if (offsetX < 0 || offsetX >= fileWidth || offsetY < 0 || offsetY >= fileHeight) |
577 | { | 581 | { |
578 | // this region is included in the tile request | 582 | MainConsole.Instance.OutputFormat( |
579 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 583 | "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.", |
584 | m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, fileWidth, fileStartX, fileHeight, fileStartY); | ||
585 | |||
586 | return; | ||
587 | } | ||
588 | |||
589 | // this region is included in the tile request | ||
590 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | ||
591 | { | ||
592 | if (filename.EndsWith(loader.Key)) | ||
580 | { | 593 | { |
581 | if (filename.EndsWith(loader.Key)) | 594 | lock (m_scene) |
582 | { | 595 | { |
583 | lock (m_scene) | 596 | loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, |
584 | { | 597 | fileWidth, fileHeight, |
585 | loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, | 598 | (int)Constants.RegionSize, |
586 | fileWidth, fileHeight, | 599 | (int)Constants.RegionSize); |
587 | (int)Constants.RegionSize, | 600 | |
588 | (int)Constants.RegionSize); | 601 | MainConsole.Instance.OutputFormat( |
589 | 602 | "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}", | |
590 | m_log.InfoFormat("[TERRAIN]: Saved terrain from {0} to {1}", m_scene.RegionInfo.RegionName, filename); | 603 | fileStartX, fileStartY, fileStartX + fileWidth - 1, fileStartY + fileHeight - 1, |
591 | } | 604 | m_scene.RegionInfo.RegionName, filename); |
592 | |||
593 | return; | ||
594 | } | 605 | } |
606 | |||
607 | return; | ||
595 | } | 608 | } |
596 | |||
597 | m_log.ErrorFormat( | ||
598 | "[TERRAIN]: Could not save terrain from {0} to {1}. Valid file extensions are {2}", | ||
599 | m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions); | ||
600 | } | ||
601 | else | ||
602 | { | ||
603 | m_log.ErrorFormat( | ||
604 | "[TERRAIN]: Could not save terrain from {0} to {1}. {2} {3} {4} {5} {6} {7}", | ||
605 | m_scene.RegionInfo.RegionName, filename, fileWidth, fileHeight, fileStartX, fileStartY, offsetX, offsetY); | ||
606 | } | 609 | } |
610 | |||
611 | MainConsole.Instance.OutputFormat( | ||
612 | "ERROR: Could not save terrain from {0} to {1}. Valid file extensions are {2}", | ||
613 | m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions); | ||
607 | } | 614 | } |
608 | 615 | ||
609 | /// <summary> | 616 | /// <summary> |
@@ -1194,6 +1201,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1194 | "Integer"); | 1201 | "Integer"); |
1195 | saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", | 1202 | saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", |
1196 | "Integer"); | 1203 | "Integer"); |
1204 | saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first tile on the file\n" | ||
1205 | + "= Example =\n" | ||
1206 | + "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" | ||
1207 | + " # terrain save-tile ST06.png 2 3 9910 10234\n", | ||
1208 | "Integer"); | ||
1209 | |||
1197 | // Terrain adjustments | 1210 | // Terrain adjustments |
1198 | Command fillRegionCommand = | 1211 | Command fillRegionCommand = |
1199 | new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value."); | 1212 | new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value."); |
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs index bb4c788..bfe1e8d 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs | |||
@@ -26,12 +26,12 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | ||
29 | using OpenMetaverse; | 30 | using OpenMetaverse; |
30 | 31 | ||
31 | namespace OpenSim.Region.Framework.Interfaces | 32 | namespace OpenSim.Region.Framework.Interfaces |
32 | { | 33 | { |
33 | public delegate void ScriptCommand(UUID script, string id, string module, string command, string k); | 34 | public delegate void ScriptCommand(UUID script, string id, string module, string command, string k); |
34 | public delegate object ScriptInvocation(UUID script, object[] parms); | ||
35 | 35 | ||
36 | /// <summary> | 36 | /// <summary> |
37 | /// Interface for communication between OpenSim modules and in-world scripts | 37 | /// Interface for communication between OpenSim modules and in-world scripts |
@@ -46,14 +46,17 @@ namespace OpenSim.Region.Framework.Interfaces | |||
46 | /// </summary> | 46 | /// </summary> |
47 | event ScriptCommand OnScriptCommand; | 47 | event ScriptCommand OnScriptCommand; |
48 | 48 | ||
49 | void RegisterScriptInvocation(string name, ScriptInvocation fn, Type[] csig, Type rsig); | 49 | void RegisterScriptInvocation(object target, string method); |
50 | void RegisterScriptInvocation(object target, MethodInfo method); | ||
51 | void RegisterScriptInvocation(object target, string[] methods); | ||
52 | Delegate[] GetScriptInvocationList(); | ||
50 | 53 | ||
51 | ScriptInvocation LookupScriptInvocation(string fname); | 54 | Delegate LookupScriptInvocation(string fname); |
52 | string LookupModInvocation(string fname); | 55 | string LookupModInvocation(string fname); |
53 | Type[] LookupTypeSignature(string fname); | 56 | Type[] LookupTypeSignature(string fname); |
54 | Type LookupReturnType(string fname); | 57 | Type LookupReturnType(string fname); |
55 | 58 | ||
56 | object InvokeOperation(UUID scriptId, string fname, params object[] parms); | 59 | object InvokeOperation(UUID hostId, UUID scriptId, string fname, params object[] parms); |
57 | 60 | ||
58 | /// <summary> | 61 | /// <summary> |
59 | /// Send a link_message event to an in-world script | 62 | /// Send a link_message event to an in-world script |
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index cded9be..f5623bd 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs | |||
@@ -125,7 +125,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation | |||
125 | 125 | ||
126 | // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations | 126 | // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations |
127 | // are referenced with lower case names! | 127 | // are referenced with lower case names! |
128 | UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name); | 128 | UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper()); |
129 | if (animID == UUID.Zero) | 129 | if (animID == UUID.Zero) |
130 | return; | 130 | return; |
131 | 131 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 44a738e..6ac7846 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -104,6 +104,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
104 | public bool m_allowScriptCrossings; | 104 | public bool m_allowScriptCrossings; |
105 | public bool m_useFlySlow; | 105 | public bool m_useFlySlow; |
106 | 106 | ||
107 | /// <summary> | ||
108 | /// Temporarily setting to trigger appearance resends at 60 second intervals. | ||
109 | /// </summary> | ||
110 | public bool SendPeriodicAppearanceUpdates { get; set; } | ||
111 | |||
107 | protected float m_defaultDrawDistance = 255.0f; | 112 | protected float m_defaultDrawDistance = 255.0f; |
108 | public float DefaultDrawDistance | 113 | public float DefaultDrawDistance |
109 | { | 114 | { |
@@ -172,6 +177,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
172 | } | 177 | } |
173 | 178 | ||
174 | /// <summary> | 179 | /// <summary> |
180 | /// Current maintenance run number | ||
181 | /// </summary> | ||
182 | public uint MaintenanceRun { get; private set; } | ||
183 | |||
184 | /// <summary> | ||
175 | /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we | 185 | /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we |
176 | /// will sleep for the remaining period. | 186 | /// will sleep for the remaining period. |
177 | /// </summary> | 187 | /// </summary> |
@@ -181,6 +191,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
181 | /// </remarks> | 191 | /// </remarks> |
182 | public float MinFrameTime { get; private set; } | 192 | public float MinFrameTime { get; private set; } |
183 | 193 | ||
194 | /// <summary> | ||
195 | /// The minimum length of time in seconds that will be taken for a maintenance run. | ||
196 | /// </summary> | ||
197 | public float MinMaintenanceTime { get; private set; } | ||
198 | |||
184 | private int m_update_physics = 1; | 199 | private int m_update_physics = 1; |
185 | private int m_update_entitymovement = 1; | 200 | private int m_update_entitymovement = 1; |
186 | private int m_update_objects = 1; | 201 | private int m_update_objects = 1; |
@@ -210,19 +225,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
210 | 225 | ||
211 | public bool CombineRegions = false; | 226 | public bool CombineRegions = false; |
212 | /// <summary> | 227 | /// <summary> |
228 | /// Tick at which the last maintenance run occurred. | ||
229 | /// </summary> | ||
230 | private int m_lastMaintenanceTick; | ||
231 | |||
232 | /// <summary> | ||
213 | /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched | 233 | /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched |
214 | /// asynchronously from the update loop. | 234 | /// asynchronously from the update loop. |
215 | /// </summary> | 235 | /// </summary> |
216 | private bool m_cleaningTemps = false; | 236 | private bool m_cleaningTemps = false; |
217 | 237 | ||
218 | private Object m_heartbeatLock = new Object(); | 238 | // private Object m_heartbeatLock = new Object(); |
219 | 239 | ||
220 | // TODO: Possibly stop other classes being able to manipulate this directly. | 240 | // TODO: Possibly stop other classes being able to manipulate this directly. |
221 | private SceneGraph m_sceneGraph; | 241 | private SceneGraph m_sceneGraph; |
222 | private volatile int m_bordersLocked; | 242 | private volatile int m_bordersLocked; |
223 | // private int m_RestartTimerCounter; | ||
224 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing | 243 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing |
225 | // private int m_incrementsof15seconds; | ||
226 | private volatile bool m_backingup; | 244 | private volatile bool m_backingup; |
227 | private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); | 245 | private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); |
228 | private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); | 246 | private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); |
@@ -230,16 +248,34 @@ namespace OpenSim.Region.Framework.Scenes | |||
230 | private bool m_physics_enabled = true; | 248 | private bool m_physics_enabled = true; |
231 | private bool m_scripts_enabled = true; | 249 | private bool m_scripts_enabled = true; |
232 | private string m_defaultScriptEngine; | 250 | private string m_defaultScriptEngine; |
251 | |||
252 | /// <summary> | ||
253 | /// Tick at which the last login occurred. | ||
254 | /// </summary> | ||
233 | private int m_LastLogin; | 255 | private int m_LastLogin; |
234 | private Thread HeartbeatThread = null; | ||
235 | private volatile bool shuttingdown; | ||
236 | 256 | ||
237 | private int m_lastUpdate; | ||
238 | private int m_lastIncoming; | 257 | private int m_lastIncoming; |
239 | private int m_lastOutgoing; | 258 | private int m_lastOutgoing; |
240 | private bool m_firstHeartbeat = true; | ||
241 | private int m_hbRestarts = 0; | 259 | private int m_hbRestarts = 0; |
242 | 260 | ||
261 | |||
262 | /// <summary> | ||
263 | /// Thread that runs the scene loop. | ||
264 | /// </summary> | ||
265 | private Thread m_heartbeatThread; | ||
266 | |||
267 | /// <summary> | ||
268 | /// True if these scene is in the process of shutting down or is shutdown. | ||
269 | /// </summary> | ||
270 | public bool ShuttingDown | ||
271 | { | ||
272 | get { return m_shuttingDown; } | ||
273 | } | ||
274 | private volatile bool m_shuttingDown; | ||
275 | |||
276 | // private int m_lastUpdate; | ||
277 | private bool m_firstHeartbeat = true; | ||
278 | |||
243 | private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; | 279 | private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; |
244 | private bool m_reprioritizationEnabled = true; | 280 | private bool m_reprioritizationEnabled = true; |
245 | private double m_reprioritizationInterval = 5000.0; | 281 | private double m_reprioritizationInterval = 5000.0; |
@@ -566,6 +602,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
566 | { | 602 | { |
567 | m_config = config; | 603 | m_config = config; |
568 | MinFrameTime = 0.089f; | 604 | MinFrameTime = 0.089f; |
605 | MinMaintenanceTime = 1; | ||
569 | 606 | ||
570 | Random random = new Random(); | 607 | Random random = new Random(); |
571 | 608 | ||
@@ -577,7 +614,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
577 | m_EstateDataService = estateDataService; | 614 | m_EstateDataService = estateDataService; |
578 | m_regionHandle = m_regInfo.RegionHandle; | 615 | m_regionHandle = m_regInfo.RegionHandle; |
579 | m_regionName = m_regInfo.RegionName; | 616 | m_regionName = m_regInfo.RegionName; |
580 | m_lastUpdate = Util.EnvironmentTickCount(); | ||
581 | m_lastIncoming = 0; | 617 | m_lastIncoming = 0; |
582 | m_lastOutgoing = 0; | 618 | m_lastOutgoing = 0; |
583 | 619 | ||
@@ -759,6 +795,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
759 | m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences); | 795 | m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences); |
760 | m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); | 796 | m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); |
761 | m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); | 797 | m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); |
798 | SendPeriodicAppearanceUpdates = startupConfig.GetBoolean("SendPeriodicAppearanceUpdates", SendPeriodicAppearanceUpdates); | ||
762 | } | 799 | } |
763 | } | 800 | } |
764 | catch (Exception e) | 801 | catch (Exception e) |
@@ -834,18 +871,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
834 | 871 | ||
835 | m_permissions = new ScenePermissions(this); | 872 | m_permissions = new ScenePermissions(this); |
836 | 873 | ||
837 | m_lastUpdate = Util.EnvironmentTickCount(); | 874 | // m_lastUpdate = Util.EnvironmentTickCount(); |
838 | } | 875 | } |
839 | 876 | ||
840 | #endregion | 877 | #endregion |
841 | 878 | ||
842 | #region Startup / Close Methods | 879 | #region Startup / Close Methods |
843 | 880 | ||
844 | public bool ShuttingDown | ||
845 | { | ||
846 | get { return shuttingdown; } | ||
847 | } | ||
848 | |||
849 | /// <value> | 881 | /// <value> |
850 | /// The scene graph for this scene | 882 | /// The scene graph for this scene |
851 | /// </value> | 883 | /// </value> |
@@ -1107,6 +1139,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1107 | m_physics_enabled = enablePhysics; | 1139 | m_physics_enabled = enablePhysics; |
1108 | } | 1140 | } |
1109 | 1141 | ||
1142 | // if (options.ContainsKey("collisions")) | ||
1143 | // { | ||
1144 | // // TODO: Implement. If false, should stop objects colliding, though possibly should still allow | ||
1145 | // // the avatar themselves to collide with the ground. | ||
1146 | // } | ||
1147 | |||
1110 | if (options.ContainsKey("teleport")) | 1148 | if (options.ContainsKey("teleport")) |
1111 | { | 1149 | { |
1112 | bool enableTeleportDebugging; | 1150 | bool enableTeleportDebugging; |
@@ -1158,8 +1196,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1158 | ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); | 1196 | ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); |
1159 | 1197 | ||
1160 | // Stop updating the scene objects and agents. | 1198 | // Stop updating the scene objects and agents. |
1161 | //m_heartbeatTimer.Close(); | 1199 | m_shuttingDown = true; |
1162 | shuttingdown = true; | ||
1163 | 1200 | ||
1164 | m_log.Debug("[SCENE]: Persisting changed objects"); | 1201 | m_log.Debug("[SCENE]: Persisting changed objects"); |
1165 | EventManager.TriggerSceneShuttingDown(this); | 1202 | EventManager.TriggerSceneShuttingDown(this); |
@@ -1183,16 +1220,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1183 | } | 1220 | } |
1184 | 1221 | ||
1185 | /// <summary> | 1222 | /// <summary> |
1186 | /// Start the timer which triggers regular scene updates | 1223 | /// Start the scene |
1187 | /// </summary> | 1224 | /// </summary> |
1188 | public void StartTimer() | 1225 | public void Start() |
1189 | { | 1226 | { |
1190 | // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); | 1227 | // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); |
1191 | 1228 | ||
1192 | //m_heartbeatTimer.Enabled = true; | 1229 | //m_heartbeatTimer.Enabled = true; |
1193 | //m_heartbeatTimer.Interval = (int)(m_timespan * 1000); | 1230 | //m_heartbeatTimer.Interval = (int)(m_timespan * 1000); |
1194 | //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); | 1231 | //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); |
1195 | if (HeartbeatThread != null) | 1232 | if (m_heartbeatThread != null) |
1196 | { | 1233 | { |
1197 | m_hbRestarts++; | 1234 | m_hbRestarts++; |
1198 | if(m_hbRestarts > 10) | 1235 | if(m_hbRestarts > 10) |
@@ -1208,13 +1245,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1208 | //proc.WaitForExit(); | 1245 | //proc.WaitForExit(); |
1209 | //Thread.Sleep(1000); | 1246 | //Thread.Sleep(1000); |
1210 | //Environment.Exit(1); | 1247 | //Environment.Exit(1); |
1211 | HeartbeatThread.Abort(); | 1248 | m_heartbeatThread.Abort(); |
1212 | Watchdog.AbortThread(HeartbeatThread.ManagedThreadId); | 1249 | Watchdog.AbortThread(m_heartbeatThread.ManagedThreadId); |
1213 | HeartbeatThread = null; | 1250 | m_heartbeatThread = null; |
1214 | } | 1251 | } |
1215 | m_lastUpdate = Util.EnvironmentTickCount(); | 1252 | // m_lastUpdate = Util.EnvironmentTickCount(); |
1216 | 1253 | ||
1217 | HeartbeatThread | 1254 | m_heartbeatThread |
1218 | = Watchdog.StartThread( | 1255 | = Watchdog.StartThread( |
1219 | Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false); | 1256 | Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false); |
1220 | } | 1257 | } |
@@ -1245,34 +1282,107 @@ namespace OpenSim.Region.Framework.Scenes | |||
1245 | /// </summary> | 1282 | /// </summary> |
1246 | private void Heartbeat() | 1283 | private void Heartbeat() |
1247 | { | 1284 | { |
1248 | if (!Monitor.TryEnter(m_heartbeatLock)) | 1285 | // if (!Monitor.TryEnter(m_heartbeatLock)) |
1249 | { | 1286 | // { |
1250 | Watchdog.RemoveThread(); | 1287 | // Watchdog.RemoveThread(); |
1251 | return; | 1288 | // return; |
1252 | } | 1289 | // } |
1253 | 1290 | ||
1254 | try | 1291 | // try |
1255 | { | 1292 | // { |
1256 | m_eventManager.TriggerOnRegionStarted(this); | ||
1257 | 1293 | ||
1258 | // The first frame can take a very long time due to physics actors being added on startup. Therefore, | 1294 | m_eventManager.TriggerOnRegionStarted(this); |
1259 | // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false | ||
1260 | // alarms for scenes with many objects. | ||
1261 | Update(1); | ||
1262 | Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; | ||
1263 | 1295 | ||
1264 | while (!shuttingdown) | 1296 | // The first frame can take a very long time due to physics actors being added on startup. Therefore, |
1265 | Update(-1); | 1297 | // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false |
1266 | } | 1298 | // alarms for scenes with many objects. |
1267 | finally | 1299 | Update(1); |
1268 | { | 1300 | |
1269 | Monitor.Pulse(m_heartbeatLock); | 1301 | Watchdog.StartThread( |
1270 | Monitor.Exit(m_heartbeatLock); | 1302 | Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); |
1271 | } | 1303 | |
1304 | Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; | ||
1305 | Update(-1); | ||
1306 | |||
1307 | // m_lastUpdate = Util.EnvironmentTickCount(); | ||
1308 | // m_firstHeartbeat = false; | ||
1309 | // } | ||
1310 | // finally | ||
1311 | // { | ||
1312 | // Monitor.Pulse(m_heartbeatLock); | ||
1313 | // Monitor.Exit(m_heartbeatLock); | ||
1314 | // } | ||
1315 | |||
1316 | Watchdog.RemoveThread(); | ||
1317 | } | ||
1318 | |||
1319 | private void Maintenance() | ||
1320 | { | ||
1321 | DoMaintenance(-1); | ||
1272 | 1322 | ||
1273 | Watchdog.RemoveThread(); | 1323 | Watchdog.RemoveThread(); |
1274 | } | 1324 | } |
1275 | 1325 | ||
1326 | public void DoMaintenance(int runs) | ||
1327 | { | ||
1328 | long? endRun = null; | ||
1329 | int runtc; | ||
1330 | int previousMaintenanceTick; | ||
1331 | |||
1332 | if (runs >= 0) | ||
1333 | endRun = MaintenanceRun + runs; | ||
1334 | |||
1335 | List<Vector3> coarseLocations; | ||
1336 | List<UUID> avatarUUIDs; | ||
1337 | |||
1338 | while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun)) | ||
1339 | { | ||
1340 | runtc = Util.EnvironmentTickCount(); | ||
1341 | ++MaintenanceRun; | ||
1342 | |||
1343 | // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) | ||
1344 | if (MaintenanceRun % (m_update_coarse_locations / 10) == 0) | ||
1345 | { | ||
1346 | SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); | ||
1347 | // Send coarse locations to clients | ||
1348 | ForEachScenePresence(delegate(ScenePresence presence) | ||
1349 | { | ||
1350 | presence.SendCoarseLocations(coarseLocations, avatarUUIDs); | ||
1351 | }); | ||
1352 | } | ||
1353 | |||
1354 | if (SendPeriodicAppearanceUpdates && MaintenanceRun % 60 == 0) | ||
1355 | { | ||
1356 | // m_log.DebugFormat("[SCENE]: Sending periodic appearance updates"); | ||
1357 | |||
1358 | if (AvatarFactory != null) | ||
1359 | { | ||
1360 | ForEachRootScenePresence(sp => AvatarFactory.SendAppearance(sp.UUID)); | ||
1361 | } | ||
1362 | } | ||
1363 | |||
1364 | Watchdog.UpdateThread(); | ||
1365 | |||
1366 | previousMaintenanceTick = m_lastMaintenanceTick; | ||
1367 | m_lastMaintenanceTick = Util.EnvironmentTickCount(); | ||
1368 | runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); | ||
1369 | runtc = (int)(MinMaintenanceTime * 1000) - runtc; | ||
1370 | |||
1371 | if (runtc > 0) | ||
1372 | Thread.Sleep(runtc); | ||
1373 | |||
1374 | // Optionally warn if a frame takes double the amount of time that it should. | ||
1375 | if (DebugUpdates | ||
1376 | && Util.EnvironmentTickCountSubtract( | ||
1377 | m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2)) | ||
1378 | m_log.WarnFormat( | ||
1379 | "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", | ||
1380 | Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), | ||
1381 | MinMaintenanceTime * 1000, | ||
1382 | RegionInfo.RegionName); | ||
1383 | } | ||
1384 | } | ||
1385 | |||
1276 | public override void Update(int frames) | 1386 | public override void Update(int frames) |
1277 | { | 1387 | { |
1278 | long? endFrame = null; | 1388 | long? endFrame = null; |
@@ -1284,10 +1394,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1284 | int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS; | 1394 | int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS; |
1285 | int previousFrameTick; | 1395 | int previousFrameTick; |
1286 | int maintc; | 1396 | int maintc; |
1287 | List<Vector3> coarseLocations; | ||
1288 | List<UUID> avatarUUIDs; | ||
1289 | 1397 | ||
1290 | while (!shuttingdown && (endFrame == null || Frame < endFrame)) | 1398 | while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) |
1291 | { | 1399 | { |
1292 | maintc = Util.EnvironmentTickCount(); | 1400 | maintc = Util.EnvironmentTickCount(); |
1293 | ++Frame; | 1401 | ++Frame; |
@@ -1337,17 +1445,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1337 | if (Frame % m_update_presences == 0) | 1445 | if (Frame % m_update_presences == 0) |
1338 | m_sceneGraph.UpdatePresences(); | 1446 | m_sceneGraph.UpdatePresences(); |
1339 | 1447 | ||
1340 | // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) | ||
1341 | if (Frame % m_update_coarse_locations == 0) | ||
1342 | { | ||
1343 | SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); | ||
1344 | // Send coarse locations to clients | ||
1345 | ForEachScenePresence(delegate(ScenePresence presence) | ||
1346 | { | ||
1347 | presence.SendCoarseLocations(coarseLocations, avatarUUIDs); | ||
1348 | }); | ||
1349 | } | ||
1350 | |||
1351 | agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); | 1448 | agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); |
1352 | 1449 | ||
1353 | // Delete temp-on-rez stuff | 1450 | // Delete temp-on-rez stuff |
@@ -1455,7 +1552,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1455 | 1552 | ||
1456 | EventManager.TriggerRegionHeartbeatEnd(this); | 1553 | EventManager.TriggerRegionHeartbeatEnd(this); |
1457 | 1554 | ||
1458 | // Tell the watchdog that this thread is still alive | ||
1459 | Watchdog.UpdateThread(); | 1555 | Watchdog.UpdateThread(); |
1460 | 1556 | ||
1461 | previousFrameTick = m_lastFrameTick; | 1557 | previousFrameTick = m_lastFrameTick; |
@@ -1463,15 +1559,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1463 | maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc); | 1559 | maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc); |
1464 | maintc = (int)(MinFrameTime * 1000) - maintc; | 1560 | maintc = (int)(MinFrameTime * 1000) - maintc; |
1465 | 1561 | ||
1466 | m_lastUpdate = Util.EnvironmentTickCount(); | ||
1467 | m_firstHeartbeat = false; | 1562 | m_firstHeartbeat = false; |
1468 | 1563 | ||
1469 | if (maintc > 0) | 1564 | if (maintc > 0) |
1470 | Thread.Sleep(maintc); | 1565 | Thread.Sleep(maintc); |
1471 | 1566 | ||
1472 | m_lastUpdate = Util.EnvironmentTickCount(); | ||
1473 | m_firstHeartbeat = false; | ||
1474 | |||
1475 | // Optionally warn if a frame takes double the amount of time that it should. | 1567 | // Optionally warn if a frame takes double the amount of time that it should. |
1476 | if (DebugUpdates | 1568 | if (DebugUpdates |
1477 | && Util.EnvironmentTickCountSubtract( | 1569 | && Util.EnvironmentTickCountSubtract( |
@@ -2662,7 +2754,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2662 | || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; | 2754 | || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; |
2663 | 2755 | ||
2664 | CheckHeartbeat(); | 2756 | CheckHeartbeat(); |
2665 | ScenePresence presence; | ||
2666 | 2757 | ||
2667 | ScenePresence sp = GetScenePresence(client.AgentId); | 2758 | ScenePresence sp = GetScenePresence(client.AgentId); |
2668 | 2759 | ||
@@ -3253,7 +3344,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3253 | 3344 | ||
3254 | public override void RemoveClient(UUID agentID, bool closeChildAgents) | 3345 | public override void RemoveClient(UUID agentID, bool closeChildAgents) |
3255 | { | 3346 | { |
3256 | CheckHeartbeat(); | 3347 | // CheckHeartbeat(); |
3257 | bool isChildAgent = false; | 3348 | bool isChildAgent = false; |
3258 | ScenePresence avatar = GetScenePresence(agentID); | 3349 | ScenePresence avatar = GetScenePresence(agentID); |
3259 | if (avatar != null) | 3350 | if (avatar != null) |
@@ -4700,7 +4791,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4700 | 4791 | ||
4701 | int health=1; // Start at 1, means we're up | 4792 | int health=1; // Start at 1, means we're up |
4702 | 4793 | ||
4703 | if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000) | 4794 | if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000) |
4704 | { | 4795 | { |
4705 | health+=1; | 4796 | health+=1; |
4706 | flags |= 1; | 4797 | flags |= 1; |
@@ -4737,6 +4828,8 @@ Environment.Exit(1); | |||
4737 | // | 4828 | // |
4738 | if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000) | 4829 | if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000) |
4739 | health++; | 4830 | health++; |
4831 | else | ||
4832 | return health; | ||
4740 | 4833 | ||
4741 | return health; | 4834 | return health; |
4742 | } | 4835 | } |
@@ -4929,8 +5022,8 @@ Environment.Exit(1); | |||
4929 | if (m_firstHeartbeat) | 5022 | if (m_firstHeartbeat) |
4930 | return; | 5023 | return; |
4931 | 5024 | ||
4932 | if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000) | 5025 | if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) > 5000) |
4933 | StartTimer(); | 5026 | Start(); |
4934 | } | 5027 | } |
4935 | 5028 | ||
4936 | public override ISceneObject DeserializeObject(string representation) | 5029 | public override ISceneObject DeserializeObject(string representation) |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 2346c60..a23dc31 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -233,6 +233,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
233 | private bool m_collisionEventFlag = false; | 233 | private bool m_collisionEventFlag = false; |
234 | private object m_collisionEventLock = new Object(); | 234 | private object m_collisionEventLock = new Object(); |
235 | 235 | ||
236 | private int m_movementAnimationUpdateCounter = 0; | ||
237 | |||
236 | private Vector3 m_prevSitOffset; | 238 | private Vector3 m_prevSitOffset; |
237 | 239 | ||
238 | protected AvatarAppearance m_appearance; | 240 | protected AvatarAppearance m_appearance; |
@@ -741,6 +743,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
741 | Appearance = appearance; | 743 | Appearance = appearance; |
742 | } | 744 | } |
743 | 745 | ||
746 | private void RegionHeartbeatEnd(Scene scene) | ||
747 | { | ||
748 | if (IsChildAgent) | ||
749 | return; | ||
750 | |||
751 | m_movementAnimationUpdateCounter ++; | ||
752 | if (m_movementAnimationUpdateCounter >= 2) | ||
753 | { | ||
754 | m_movementAnimationUpdateCounter = 0; | ||
755 | if (Animator != null) | ||
756 | { | ||
757 | Animator.UpdateMovementAnimations(); | ||
758 | } | ||
759 | else | ||
760 | { | ||
761 | m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; | ||
762 | } | ||
763 | } | ||
764 | } | ||
765 | |||
744 | public void RegisterToEvents() | 766 | public void RegisterToEvents() |
745 | { | 767 | { |
746 | ControllingClient.OnCompleteMovementToRegion += CompleteMovement; | 768 | ControllingClient.OnCompleteMovementToRegion += CompleteMovement; |
@@ -952,6 +974,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
952 | MovementFlag = 0; | 974 | MovementFlag = 0; |
953 | 975 | ||
954 | m_scene.EventManager.TriggerOnMakeRootAgent(this); | 976 | m_scene.EventManager.TriggerOnMakeRootAgent(this); |
977 | |||
978 | m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd; | ||
955 | } | 979 | } |
956 | 980 | ||
957 | public int GetStateSource() | 981 | public int GetStateSource() |
@@ -979,6 +1003,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
979 | /// </remarks> | 1003 | /// </remarks> |
980 | public void MakeChildAgent() | 1004 | public void MakeChildAgent() |
981 | { | 1005 | { |
1006 | m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; | ||
1007 | |||
982 | m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); | 1008 | m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1}", Name, Scene.RegionInfo.RegionName); |
983 | 1009 | ||
984 | // Reset these so that teleporting in and walking out isn't seen | 1010 | // Reset these so that teleporting in and walking out isn't seen |
@@ -2377,14 +2403,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2377 | direc.Z *= 2.6f; | 2403 | direc.Z *= 2.6f; |
2378 | 2404 | ||
2379 | // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. | 2405 | // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. |
2380 | Animator.TrySetMovementAnimation("PREJUMP"); | 2406 | // Animator.TrySetMovementAnimation("PREJUMP"); |
2381 | Animator.TrySetMovementAnimation("JUMP"); | 2407 | // Animator.TrySetMovementAnimation("JUMP"); |
2382 | } | 2408 | } |
2383 | } | 2409 | } |
2384 | } | 2410 | } |
2385 | 2411 | ||
2386 | // TODO: Add the force instead of only setting it to support multiple forces per frame? | 2412 | // TODO: Add the force instead of only setting it to support multiple forces per frame? |
2387 | m_forceToApply = direc; | 2413 | m_forceToApply = direc; |
2414 | Animator.UpdateMovementAnimations(); | ||
2388 | } | 2415 | } |
2389 | 2416 | ||
2390 | #endregion | 2417 | #endregion |
@@ -3334,18 +3361,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3334 | if (IsChildAgent) | 3361 | if (IsChildAgent) |
3335 | return; | 3362 | return; |
3336 | 3363 | ||
3337 | //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) | ||
3338 | // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( | ||
3339 | // as of this comment the interval is set in AddToPhysicalScene | ||
3340 | if (Animator != null) | ||
3341 | { | ||
3342 | // if (m_updateCount > 0) | ||
3343 | // { | ||
3344 | Animator.UpdateMovementAnimations(); | ||
3345 | // m_updateCount--; | ||
3346 | // } | ||
3347 | } | ||
3348 | |||
3349 | CollisionEventUpdate collisionData = (CollisionEventUpdate)e; | 3364 | CollisionEventUpdate collisionData = (CollisionEventUpdate)e; |
3350 | Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; | 3365 | Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; |
3351 | 3366 | ||
diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs index a3f68e5..e452124 100755 --- a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs +++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs | |||
@@ -264,14 +264,14 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters | |||
264 | 264 | ||
265 | private void WriteOut(string msg, params object[] args) | 265 | private void WriteOut(string msg, params object[] args) |
266 | { | 266 | { |
267 | m_log.InfoFormat(msg, args); | 267 | // m_log.InfoFormat(msg, args); |
268 | // MainConsole.Instance.OutputFormat(msg, args); | 268 | MainConsole.Instance.OutputFormat(msg, args); |
269 | } | 269 | } |
270 | 270 | ||
271 | private void WriteError(string msg, params object[] args) | 271 | private void WriteError(string msg, params object[] args) |
272 | { | 272 | { |
273 | m_log.ErrorFormat(msg, args); | 273 | // m_log.ErrorFormat(msg, args); |
274 | // MainConsole.Instance.OutputFormat(msg, args); | 274 | MainConsole.Instance.OutputFormat(msg, args); |
275 | } | 275 | } |
276 | } | 276 | } |
277 | } \ No newline at end of file | 277 | } |
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index d0142a4..0b9f875 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs | |||
@@ -70,8 +70,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
70 | 70 | ||
71 | public void Initialise(IConfigSource config) | 71 | public void Initialise(IConfigSource config) |
72 | { | 72 | { |
73 | //m_log.Info("[RegionReady] Initialising"); | ||
74 | |||
75 | m_config = config.Configs["RegionReady"]; | 73 | m_config = config.Configs["RegionReady"]; |
76 | if (m_config != null) | 74 | if (m_config != null) |
77 | { | 75 | { |
@@ -84,9 +82,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
84 | m_uri = m_config.GetString("alert_uri",string.Empty); | 82 | m_uri = m_config.GetString("alert_uri",string.Empty); |
85 | } | 83 | } |
86 | } | 84 | } |
87 | |||
88 | // if (!m_enabled) | ||
89 | // m_log.Info("[RegionReady] disabled."); | ||
90 | } | 85 | } |
91 | 86 | ||
92 | public void AddRegion(Scene scene) | 87 | public void AddRegion(Scene scene) |
@@ -113,7 +108,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
113 | { | 108 | { |
114 | scene.LoginLock = true; | 109 | scene.LoginLock = true; |
115 | scene.LoginsDisabled = true; | 110 | scene.LoginsDisabled = true; |
116 | m_log.InfoFormat("[RegionReady]: Logins disabled for {0}",m_scene.RegionInfo.RegionName); | 111 | m_log.InfoFormat("[RegionReady]: Region {0} - logins disabled during initialization.",m_scene.RegionInfo.RegionName); |
117 | 112 | ||
118 | if(m_uri != string.Empty) | 113 | if(m_uri != string.Empty) |
119 | { | 114 | { |
@@ -167,7 +162,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
167 | 162 | ||
168 | void OnEmptyScriptCompileQueue(int numScriptsFailed, string message) | 163 | void OnEmptyScriptCompileQueue(int numScriptsFailed, string message) |
169 | { | 164 | { |
170 | m_log.InfoFormat("[RegionReady]: Script compile queue empty!"); | 165 | m_log.DebugFormat("[RegionReady]: Script compile queue empty!"); |
171 | 166 | ||
172 | if (m_firstEmptyCompileQueue || m_oarFileLoading) | 167 | if (m_firstEmptyCompileQueue || m_oarFileLoading) |
173 | { | 168 | { |
@@ -194,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
194 | c.SenderUUID = UUID.Zero; | 189 | c.SenderUUID = UUID.Zero; |
195 | c.Scene = m_scene; | 190 | c.Scene = m_scene; |
196 | 191 | ||
197 | m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", | 192 | m_log.DebugFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", |
198 | m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); | 193 | m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); |
199 | 194 | ||
200 | m_scene.EventManager.TriggerOnChatBroadcast(this, c); | 195 | m_scene.EventManager.TriggerOnChatBroadcast(this, c); |
@@ -210,7 +205,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
210 | { | 205 | { |
211 | m_lastOarLoadedOk = true; | 206 | m_lastOarLoadedOk = true; |
212 | } else { | 207 | } else { |
213 | m_log.InfoFormat("[RegionReady]: Oar file load errors: {0}", message); | 208 | m_log.WarnFormat("[RegionReady]: Oar file load errors: {0}", message); |
214 | m_lastOarLoadedOk = false; | 209 | m_lastOarLoadedOk = false; |
215 | } | 210 | } |
216 | } | 211 | } |
@@ -233,7 +228,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady | |||
233 | // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", | 228 | // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", |
234 | // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); | 229 | // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); |
235 | 230 | ||
236 | m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName); | 231 | m_log.InfoFormat("[RegionReady]: Initialization complete - logins enabled for {0}", m_scene.RegionInfo.RegionName); |
237 | 232 | ||
238 | if ( m_uri != string.Empty ) | 233 | if ( m_uri != string.Empty ) |
239 | { | 234 | { |
diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index a90362e..cab30de 100644 --- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs | |||
@@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Interfaces; | |||
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using Mono.Addins; | 36 | using Mono.Addins; |
37 | using OpenMetaverse; | 37 | using OpenMetaverse; |
38 | using System.Linq; | ||
39 | using System.Linq.Expressions; | ||
38 | 40 | ||
39 | namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | 41 | namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms |
40 | { | 42 | { |
@@ -47,15 +49,15 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
47 | #region ScriptInvocation | 49 | #region ScriptInvocation |
48 | protected class ScriptInvocationData | 50 | protected class ScriptInvocationData |
49 | { | 51 | { |
50 | public ScriptInvocation ScriptInvocationFn { get; private set; } | 52 | public Delegate ScriptInvocationDelegate { get; private set; } |
51 | public string FunctionName { get; private set; } | 53 | public string FunctionName { get; private set; } |
52 | public Type[] TypeSignature { get; private set; } | 54 | public Type[] TypeSignature { get; private set; } |
53 | public Type ReturnType { get; private set; } | 55 | public Type ReturnType { get; private set; } |
54 | 56 | ||
55 | public ScriptInvocationData(string fname, ScriptInvocation fn, Type[] callsig, Type returnsig) | 57 | public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig) |
56 | { | 58 | { |
57 | FunctionName = fname; | 59 | FunctionName = fname; |
58 | ScriptInvocationFn = fn; | 60 | ScriptInvocationDelegate = fn; |
59 | TypeSignature = callsig; | 61 | TypeSignature = callsig; |
60 | ReturnType = returnsig; | 62 | ReturnType = returnsig; |
61 | } | 63 | } |
@@ -126,14 +128,72 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
126 | m_scriptModule.PostScriptEvent(script, "link_message", args); | 128 | m_scriptModule.PostScriptEvent(script, "link_message", args); |
127 | } | 129 | } |
128 | 130 | ||
129 | public void RegisterScriptInvocation(string fname, ScriptInvocation fcall, Type[] csig, Type rsig) | 131 | public void RegisterScriptInvocation(object target, string meth) |
130 | { | 132 | { |
133 | MethodInfo mi = target.GetType().GetMethod(meth, | ||
134 | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); | ||
135 | if (mi == null) | ||
136 | { | ||
137 | m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth); | ||
138 | return; | ||
139 | } | ||
140 | |||
141 | RegisterScriptInvocation(target, mi); | ||
142 | } | ||
143 | |||
144 | public void RegisterScriptInvocation(object target, string[] meth) | ||
145 | { | ||
146 | foreach (string m in meth) | ||
147 | RegisterScriptInvocation(target, m); | ||
148 | } | ||
149 | |||
150 | public void RegisterScriptInvocation(object target, MethodInfo mi) | ||
151 | { | ||
152 | m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, target.GetType().Name); | ||
153 | |||
154 | Type delegateType; | ||
155 | var typeArgs = mi.GetParameters() | ||
156 | .Select(p => p.ParameterType) | ||
157 | .ToList(); | ||
158 | |||
159 | if (mi.ReturnType == typeof(void)) | ||
160 | { | ||
161 | delegateType = Expression.GetActionType(typeArgs.ToArray()); | ||
162 | } | ||
163 | else | ||
164 | { | ||
165 | typeArgs.Add(mi.ReturnType); | ||
166 | delegateType = Expression.GetFuncType(typeArgs.ToArray()); | ||
167 | } | ||
168 | |||
169 | Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi); | ||
170 | |||
131 | lock (m_scriptInvocation) | 171 | lock (m_scriptInvocation) |
132 | { | 172 | { |
133 | m_scriptInvocation[fname] = new ScriptInvocationData(fname,fcall,csig,rsig); | 173 | ParameterInfo[] parameters = fcall.Method.GetParameters (); |
174 | if (parameters.Length < 2) // Must have two UUID params | ||
175 | return; | ||
176 | |||
177 | // Hide the first two parameters | ||
178 | Type[] parmTypes = new Type[parameters.Length - 2]; | ||
179 | for (int i = 2 ; i < parameters.Length ; i++) | ||
180 | parmTypes[i - 2] = parameters[i].ParameterType; | ||
181 | m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType); | ||
134 | } | 182 | } |
135 | } | 183 | } |
136 | 184 | ||
185 | public Delegate[] GetScriptInvocationList() | ||
186 | { | ||
187 | List<Delegate> ret = new List<Delegate>(); | ||
188 | |||
189 | lock (m_scriptInvocation) | ||
190 | { | ||
191 | foreach (ScriptInvocationData d in m_scriptInvocation.Values) | ||
192 | ret.Add(d.ScriptInvocationDelegate); | ||
193 | } | ||
194 | return ret.ToArray(); | ||
195 | } | ||
196 | |||
137 | public string LookupModInvocation(string fname) | 197 | public string LookupModInvocation(string fname) |
138 | { | 198 | { |
139 | lock (m_scriptInvocation) | 199 | lock (m_scriptInvocation) |
@@ -147,19 +207,29 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
147 | return "modInvokeI"; | 207 | return "modInvokeI"; |
148 | else if (sid.ReturnType == typeof(float)) | 208 | else if (sid.ReturnType == typeof(float)) |
149 | return "modInvokeF"; | 209 | return "modInvokeF"; |
210 | else if (sid.ReturnType == typeof(UUID)) | ||
211 | return "modInvokeK"; | ||
212 | else if (sid.ReturnType == typeof(OpenMetaverse.Vector3)) | ||
213 | return "modInvokeV"; | ||
214 | else if (sid.ReturnType == typeof(OpenMetaverse.Quaternion)) | ||
215 | return "modInvokeR"; | ||
216 | else if (sid.ReturnType == typeof(object[])) | ||
217 | return "modInvokeL"; | ||
218 | |||
219 | m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name); | ||
150 | } | 220 | } |
151 | } | 221 | } |
152 | 222 | ||
153 | return null; | 223 | return null; |
154 | } | 224 | } |
155 | 225 | ||
156 | public ScriptInvocation LookupScriptInvocation(string fname) | 226 | public Delegate LookupScriptInvocation(string fname) |
157 | { | 227 | { |
158 | lock (m_scriptInvocation) | 228 | lock (m_scriptInvocation) |
159 | { | 229 | { |
160 | ScriptInvocationData sid; | 230 | ScriptInvocationData sid; |
161 | if (m_scriptInvocation.TryGetValue(fname,out sid)) | 231 | if (m_scriptInvocation.TryGetValue(fname,out sid)) |
162 | return sid.ScriptInvocationFn; | 232 | return sid.ScriptInvocationDelegate; |
163 | } | 233 | } |
164 | 234 | ||
165 | return null; | 235 | return null; |
@@ -189,10 +259,15 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
189 | return null; | 259 | return null; |
190 | } | 260 | } |
191 | 261 | ||
192 | public object InvokeOperation(UUID scriptid, string fname, params object[] parms) | 262 | public object InvokeOperation(UUID hostid, UUID scriptid, string fname, params object[] parms) |
193 | { | 263 | { |
194 | ScriptInvocation fn = LookupScriptInvocation(fname); | 264 | List<object> olist = new List<object>(); |
195 | return fn(scriptid,parms); | 265 | olist.Add(hostid); |
266 | olist.Add(scriptid); | ||
267 | foreach (object o in parms) | ||
268 | olist.Add(o); | ||
269 | Delegate fn = LookupScriptInvocation(fname); | ||
270 | return fn.DynamicInvoke(olist.ToArray()); | ||
196 | } | 271 | } |
197 | #endregion | 272 | #endregion |
198 | 273 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 0cab5d1..20708d9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -94,7 +94,7 @@ public class BSCharacter : PhysicsActor | |||
94 | _flying = isFlying; | 94 | _flying = isFlying; |
95 | _orientation = Quaternion.Identity; | 95 | _orientation = Quaternion.Identity; |
96 | _velocity = Vector3.Zero; | 96 | _velocity = Vector3.Zero; |
97 | _buoyancy = isFlying ? 1f : 0f; | 97 | _buoyancy = ComputeBuoyancyFromFlying(isFlying); |
98 | _scale = new Vector3(1f, 1f, 1f); | 98 | _scale = new Vector3(1f, 1f, 1f); |
99 | _density = _scene.Params.avatarDensity; | 99 | _density = _scene.Params.avatarDensity; |
100 | ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale | 100 | ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale |
@@ -110,7 +110,7 @@ public class BSCharacter : PhysicsActor | |||
110 | shapeData.Buoyancy = _buoyancy; | 110 | shapeData.Buoyancy = _buoyancy; |
111 | shapeData.Static = ShapeData.numericFalse; | 111 | shapeData.Static = ShapeData.numericFalse; |
112 | shapeData.Friction = _scene.Params.avatarFriction; | 112 | shapeData.Friction = _scene.Params.avatarFriction; |
113 | shapeData.Restitution = _scene.Params.defaultRestitution; | 113 | shapeData.Restitution = _scene.Params.avatarRestitution; |
114 | 114 | ||
115 | // do actual create at taint time | 115 | // do actual create at taint time |
116 | _scene.TaintedObject(delegate() | 116 | _scene.TaintedObject(delegate() |
@@ -260,13 +260,13 @@ public class BSCharacter : PhysicsActor | |||
260 | get { return _flying; } | 260 | get { return _flying; } |
261 | set { | 261 | set { |
262 | _flying = value; | 262 | _flying = value; |
263 | _scene.TaintedObject(delegate() | 263 | // simulate flying by changing the effect of gravity |
264 | { | 264 | this.Buoyancy = ComputeBuoyancyFromFlying(_flying); |
265 | // simulate flying by changing the effect of gravity | ||
266 | BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _flying ? 1f : 0f); | ||
267 | }); | ||
268 | } | 265 | } |
269 | } | 266 | } |
267 | private float ComputeBuoyancyFromFlying(bool ifFlying) { | ||
268 | return ifFlying ? 1f : 0f; | ||
269 | } | ||
270 | public override bool | 270 | public override bool |
271 | SetAlwaysRun { | 271 | SetAlwaysRun { |
272 | get { return _setAlwaysRun; } | 272 | get { return _setAlwaysRun; } |
@@ -299,6 +299,7 @@ public class BSCharacter : PhysicsActor | |||
299 | get { return _kinematic; } | 299 | get { return _kinematic; } |
300 | set { _kinematic = value; } | 300 | set { _kinematic = value; } |
301 | } | 301 | } |
302 | // neg=fall quickly, 0=1g, 1=0g, pos=float up | ||
302 | public override float Buoyancy { | 303 | public override float Buoyancy { |
303 | get { return _buoyancy; } | 304 | get { return _buoyancy; } |
304 | set { _buoyancy = value; | 305 | set { _buoyancy = value; |
@@ -355,7 +356,7 @@ public class BSCharacter : PhysicsActor | |||
355 | } | 356 | } |
356 | else | 357 | else |
357 | { | 358 | { |
358 | m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); | 359 | m_log.ErrorFormat("{0}: Got a NaN force applied to a Character", LogHeader); |
359 | } | 360 | } |
360 | //m_lastUpdateSent = false; | 361 | //m_lastUpdateSent = false; |
361 | } | 362 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 046726d..eb20eb3 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -821,7 +821,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
821 | */ | 821 | */ |
822 | 822 | ||
823 | // Get what the body is doing, this includes 'external' influences | 823 | // Get what the body is doing, this includes 'external' influences |
824 | Vector3 angularVelocity = m_prim.AngularVelocity; | 824 | Vector3 angularVelocity = m_prim.RotationalVelocity; |
825 | // Vector3 angularVelocity = Vector3.Zero; | 825 | // Vector3 angularVelocity = Vector3.Zero; |
826 | 826 | ||
827 | if (m_angularMotorApply > 0) | 827 | if (m_angularMotorApply > 0) |
@@ -910,7 +910,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
910 | m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; | 910 | m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; |
911 | 911 | ||
912 | // Apply to the body | 912 | // Apply to the body |
913 | m_prim.AngularVelocity = m_lastAngularVelocity; | 913 | m_prim.RotationalVelocity = m_lastAngularVelocity; |
914 | 914 | ||
915 | } //end MoveAngular | 915 | } //end MoveAngular |
916 | internal void LimitRotation(float timestep) | 916 | internal void LimitRotation(float timestep) |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 898436b..f122df9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -85,7 +85,6 @@ public sealed class BSPrim : PhysicsActor | |||
85 | private OMV.Vector3 _rotationalVelocity; | 85 | private OMV.Vector3 _rotationalVelocity; |
86 | private bool _kinematic; | 86 | private bool _kinematic; |
87 | private float _buoyancy; | 87 | private float _buoyancy; |
88 | private OMV.Vector3 _angularVelocity; | ||
89 | 88 | ||
90 | private List<BSPrim> _childrenPrims; | 89 | private List<BSPrim> _childrenPrims; |
91 | private BSPrim _parentPrim; | 90 | private BSPrim _parentPrim; |
@@ -119,7 +118,6 @@ public sealed class BSPrim : PhysicsActor | |||
119 | _buoyancy = 1f; | 118 | _buoyancy = 1f; |
120 | _velocity = OMV.Vector3.Zero; | 119 | _velocity = OMV.Vector3.Zero; |
121 | _rotationalVelocity = OMV.Vector3.Zero; | 120 | _rotationalVelocity = OMV.Vector3.Zero; |
122 | _angularVelocity = OMV.Vector3.Zero; | ||
123 | _hullKey = 0; | 121 | _hullKey = 0; |
124 | _meshKey = 0; | 122 | _meshKey = 0; |
125 | _pbs = pbs; | 123 | _pbs = pbs; |
@@ -146,7 +144,7 @@ public sealed class BSPrim : PhysicsActor | |||
146 | // called when this prim is being destroyed and we should free all the resources | 144 | // called when this prim is being destroyed and we should free all the resources |
147 | public void Destroy() | 145 | public void Destroy() |
148 | { | 146 | { |
149 | // m_log.DebugFormat("{0}: Destroy", LogHeader); | 147 | // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); |
150 | // Undo any vehicle properties | 148 | // Undo any vehicle properties |
151 | _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); | 149 | _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); |
152 | _scene.RemoveVehiclePrim(this); // just to make sure | 150 | _scene.RemoveVehiclePrim(this); // just to make sure |
@@ -203,7 +201,7 @@ public sealed class BSPrim : PhysicsActor | |||
203 | 201 | ||
204 | // link me to the specified parent | 202 | // link me to the specified parent |
205 | public override void link(PhysicsActor obj) { | 203 | public override void link(PhysicsActor obj) { |
206 | BSPrim parent = (BSPrim)obj; | 204 | BSPrim parent = obj as BSPrim; |
207 | // m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); | 205 | // m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); |
208 | // TODO: decide if this parent checking needs to happen at taint time | 206 | // TODO: decide if this parent checking needs to happen at taint time |
209 | if (_parentPrim == null) | 207 | if (_parentPrim == null) |
@@ -527,10 +525,6 @@ public sealed class BSPrim : PhysicsActor | |||
527 | }); | 525 | }); |
528 | } | 526 | } |
529 | } | 527 | } |
530 | public OMV.Vector3 AngularVelocity { | ||
531 | get { return _angularVelocity; } | ||
532 | set { _angularVelocity = value; } | ||
533 | } | ||
534 | public override bool Kinematic { | 528 | public override bool Kinematic { |
535 | get { return _kinematic; } | 529 | get { return _kinematic; } |
536 | set { _kinematic = value; | 530 | set { _kinematic = value; |
@@ -993,7 +987,7 @@ public sealed class BSPrim : PhysicsActor | |||
993 | } | 987 | } |
994 | 988 | ||
995 | // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", | 989 | // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", |
996 | // LogHeader, _localID, _meshKey, indices.Length, vertices.Count); | 990 | // LogHeader, _localID, _meshKey, indices.Length, vertices.Count); |
997 | BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices, | 991 | BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices, |
998 | vertices.Count, verticesAsFloats); | 992 | vertices.Count, verticesAsFloats); |
999 | 993 | ||
@@ -1127,7 +1121,7 @@ public sealed class BSPrim : PhysicsActor | |||
1127 | return; | 1121 | return; |
1128 | } | 1122 | } |
1129 | 1123 | ||
1130 | // Create an object in Bullet | 1124 | // Create an object in Bullet if it has not already been created |
1131 | // No locking here because this is done when the physics engine is not simulating | 1125 | // No locking here because this is done when the physics engine is not simulating |
1132 | private void CreateObject() | 1126 | private void CreateObject() |
1133 | { | 1127 | { |
@@ -1324,7 +1318,8 @@ public sealed class BSPrim : PhysicsActor | |||
1324 | _velocity = entprop.Velocity; | 1318 | _velocity = entprop.Velocity; |
1325 | _acceleration = entprop.Acceleration; | 1319 | _acceleration = entprop.Acceleration; |
1326 | _rotationalVelocity = entprop.RotationalVelocity; | 1320 | _rotationalVelocity = entprop.RotationalVelocity; |
1327 | // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); | 1321 | // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", |
1322 | // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); | ||
1328 | base.RequestPhysicsterseUpdate(); | 1323 | base.RequestPhysicsterseUpdate(); |
1329 | } | 1324 | } |
1330 | } | 1325 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index e9a849c..581d540 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -37,14 +37,18 @@ using OpenMetaverse; | |||
37 | using OpenSim.Region.Framework; | 37 | using OpenSim.Region.Framework; |
38 | 38 | ||
39 | // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) | 39 | // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) |
40 | // Debug linkset | ||
41 | // Test with multiple regions in one simulator | ||
40 | // Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) | 42 | // Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) |
41 | // Test sculpties | 43 | // Test sculpties |
42 | // Compute physics FPS reasonably | 44 | // Compute physics FPS reasonably |
43 | // Based on material, set density and friction | 45 | // Based on material, set density and friction |
44 | // More efficient memory usage in passing hull information from BSPrim to BulletSim | 46 | // More efficient memory usage when passing hull information from BSPrim to BulletSim |
45 | // Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly? | 47 | // Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly? |
46 | // In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground) | 48 | // In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground) |
47 | // At the moment, physical and phantom causes object to drop through the terrain | 49 | // At the moment, physical and phantom causes object to drop through the terrain |
50 | // Physical phantom objects and related typing (collision options ) | ||
51 | // Check out llVolumeDetect. Must do something for that. | ||
48 | // Should prim.link() and prim.delink() membership checking happen at taint time? | 52 | // Should prim.link() and prim.delink() membership checking happen at taint time? |
49 | // Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once | 53 | // Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once |
50 | // Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect | 54 | // Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect |
@@ -52,6 +56,16 @@ using OpenSim.Region.Framework; | |||
52 | // Implement LockAngularMotion | 56 | // Implement LockAngularMotion |
53 | // Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) | 57 | // Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) |
54 | // Does NeedsMeshing() really need to exclude all the different shapes? | 58 | // Does NeedsMeshing() really need to exclude all the different shapes? |
59 | // Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet. | ||
60 | // Add PID movement operations. What does ScenePresence.MoveToTarget do? | ||
61 | // Check terrain size. 128 or 127? | ||
62 | // Multiple contact points on collision? | ||
63 | // See code in ode::near... calls to collision_accounting_events() | ||
64 | // (This might not be a problem. ODE collects all the collisions with one object in one tick.) | ||
65 | // Use collision masks for collision with terrain and phantom objects | ||
66 | // Figure out how to not allocate a new Dictionary and List for every collision | ||
67 | // in BSPrim.Collide() and BSCharacter.Collide(). Can the same ones be reused? | ||
68 | // Raycast | ||
55 | // | 69 | // |
56 | namespace OpenSim.Region.Physics.BulletSPlugin | 70 | namespace OpenSim.Region.Physics.BulletSPlugin |
57 | { | 71 | { |
@@ -164,6 +178,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
164 | if (m_log.IsDebugEnabled) | 178 | if (m_log.IsDebugEnabled) |
165 | { | 179 | { |
166 | m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); | 180 | m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); |
181 | // the handle is saved to it doesn't get freed after this call | ||
167 | m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); | 182 | m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); |
168 | BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); | 183 | BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); |
169 | } | 184 | } |
@@ -172,7 +187,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
172 | 187 | ||
173 | mesher = meshmerizer; | 188 | mesher = meshmerizer; |
174 | // The bounding box for the simulated world | 189 | // The bounding box for the simulated world |
175 | Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f); | 190 | Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f); |
176 | 191 | ||
177 | // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); | 192 | // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); |
178 | m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), | 193 | m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), |
@@ -220,10 +235,20 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
220 | parms.terrainFriction = 0.5f; | 235 | parms.terrainFriction = 0.5f; |
221 | parms.terrainHitFraction = 0.8f; | 236 | parms.terrainHitFraction = 0.8f; |
222 | parms.terrainRestitution = 0f; | 237 | parms.terrainRestitution = 0f; |
223 | parms.avatarFriction = 0.0f; | 238 | parms.avatarFriction = 0.5f; |
239 | parms.avatarRestitution = 0.0f; | ||
224 | parms.avatarDensity = 60f; | 240 | parms.avatarDensity = 60f; |
225 | parms.avatarCapsuleRadius = 0.37f; | 241 | parms.avatarCapsuleRadius = 0.37f; |
226 | parms.avatarCapsuleHeight = 1.5f; // 2.140599f | 242 | parms.avatarCapsuleHeight = 1.5f; // 2.140599f |
243 | parms.avatarContactProcessingThreshold = 0.1f; | ||
244 | |||
245 | parms.maxPersistantManifoldPoolSize = 0f; | ||
246 | parms.shouldDisableContactPoolDynamicAllocation = ConfigurationParameters.numericTrue; | ||
247 | parms.shouldForceUpdateAllAabbs = ConfigurationParameters.numericFalse; | ||
248 | parms.shouldRandomizeSolverOrder = ConfigurationParameters.numericFalse; | ||
249 | parms.shouldSplitSimulationIslands = ConfigurationParameters.numericFalse; | ||
250 | parms.shouldEnableFrictionCaching = ConfigurationParameters.numericFalse; | ||
251 | parms.numberOfSolverIterations = 0f; // means use default | ||
227 | 252 | ||
228 | if (config != null) | 253 | if (config != null) |
229 | { | 254 | { |
@@ -265,14 +290,40 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
265 | parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction); | 290 | parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction); |
266 | parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution); | 291 | parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution); |
267 | parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction); | 292 | parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction); |
293 | parms.avatarRestitution = pConfig.GetFloat("AvatarRestitution", parms.avatarRestitution); | ||
268 | parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity); | 294 | parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity); |
269 | parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius); | 295 | parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius); |
270 | parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight); | 296 | parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight); |
297 | parms.avatarContactProcessingThreshold = pConfig.GetFloat("AvatarContactProcessingThreshold", parms.avatarContactProcessingThreshold); | ||
298 | |||
299 | parms.maxPersistantManifoldPoolSize = pConfig.GetFloat("MaxPersistantManifoldPoolSize", parms.maxPersistantManifoldPoolSize); | ||
300 | parms.shouldDisableContactPoolDynamicAllocation = ParamBoolean(pConfig, "ShouldDisableContactPoolDynamicAllocation", parms.shouldDisableContactPoolDynamicAllocation); | ||
301 | parms.shouldForceUpdateAllAabbs = ParamBoolean(pConfig, "ShouldForceUpdateAllAabbs", parms.shouldForceUpdateAllAabbs); | ||
302 | parms.shouldRandomizeSolverOrder = ParamBoolean(pConfig, "ShouldRandomizeSolverOrder", parms.shouldRandomizeSolverOrder); | ||
303 | parms.shouldSplitSimulationIslands = ParamBoolean(pConfig, "ShouldSplitSimulationIslands", parms.shouldSplitSimulationIslands); | ||
304 | parms.shouldEnableFrictionCaching = ParamBoolean(pConfig, "ShouldEnableFrictionCaching", parms.shouldEnableFrictionCaching); | ||
305 | parms.numberOfSolverIterations = pConfig.GetFloat("NumberOfSolverIterations", parms.numberOfSolverIterations); | ||
271 | } | 306 | } |
272 | } | 307 | } |
273 | m_params[0] = parms; | 308 | m_params[0] = parms; |
274 | } | 309 | } |
275 | 310 | ||
311 | // A helper function that handles a true/false parameter and returns the proper float number encoding | ||
312 | float ParamBoolean(IConfig config, string parmName, float deflt) | ||
313 | { | ||
314 | float ret = deflt; | ||
315 | if (config.Contains(parmName)) | ||
316 | { | ||
317 | ret = ConfigurationParameters.numericFalse; | ||
318 | if (config.GetBoolean(parmName, false)) | ||
319 | { | ||
320 | ret = ConfigurationParameters.numericTrue; | ||
321 | } | ||
322 | } | ||
323 | return ret; | ||
324 | } | ||
325 | |||
326 | |||
276 | // Called directly from unmanaged code so don't do much | 327 | // Called directly from unmanaged code so don't do much |
277 | private void BulletLogger(string msg) | 328 | private void BulletLogger(string msg) |
278 | { | 329 | { |
@@ -391,16 +442,16 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
391 | { | 442 | { |
392 | EntityProperties entprop = m_updateArray[ii]; | 443 | EntityProperties entprop = m_updateArray[ii]; |
393 | // m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position); | 444 | // m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position); |
394 | BSCharacter actor; | ||
395 | if (m_avatars.TryGetValue(entprop.ID, out actor)) | ||
396 | { | ||
397 | actor.UpdateProperties(entprop); | ||
398 | continue; | ||
399 | } | ||
400 | BSPrim prim; | 445 | BSPrim prim; |
401 | if (m_prims.TryGetValue(entprop.ID, out prim)) | 446 | if (m_prims.TryGetValue(entprop.ID, out prim)) |
402 | { | 447 | { |
403 | prim.UpdateProperties(entprop); | 448 | prim.UpdateProperties(entprop); |
449 | continue; | ||
450 | } | ||
451 | BSCharacter actor; | ||
452 | if (m_avatars.TryGetValue(entprop.ID, out actor)) | ||
453 | { | ||
454 | actor.UpdateProperties(entprop); | ||
404 | } | 455 | } |
405 | } | 456 | } |
406 | } | 457 | } |
@@ -470,12 +521,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
470 | 521 | ||
471 | public override void DeleteTerrain() | 522 | public override void DeleteTerrain() |
472 | { | 523 | { |
473 | m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); | 524 | // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); |
474 | } | 525 | } |
475 | 526 | ||
476 | public override void Dispose() | 527 | public override void Dispose() |
477 | { | 528 | { |
478 | m_log.DebugFormat("{0}: Dispose()", LogHeader); | 529 | // m_log.DebugFormat("{0}: Dispose()", LogHeader); |
479 | } | 530 | } |
480 | 531 | ||
481 | public override Dictionary<uint, float> GetTopColliders() | 532 | public override Dictionary<uint, float> GetTopColliders() |
@@ -699,9 +750,23 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
699 | new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ), | 750 | new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ), |
700 | new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ), | 751 | new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ), |
701 | new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ), | 752 | new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ), |
702 | // new PhysParameterEntry("CcdMotionThreshold", "" ), | 753 | new PhysParameterEntry("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ), |
703 | // new PhysParameterEntry("CcdSweptSphereRadius", "" ), | 754 | new PhysParameterEntry("CcdSweptSphereRadius", "Continuious collision detection test radius" ), |
704 | new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ), | 755 | new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ), |
756 | // Can only change the following at initialization time. Change the INI file and reboot. | ||
757 | new PhysParameterEntry("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)"), | ||
758 | new PhysParameterEntry("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count"), | ||
759 | new PhysParameterEntry("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step"), | ||
760 | new PhysParameterEntry("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction"), | ||
761 | new PhysParameterEntry("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands"), | ||
762 | new PhysParameterEntry("ShouldEnableFrictionCaching", "Enable friction computation caching"), | ||
763 | new PhysParameterEntry("NumberOfSolverIterations", "Number of internal iterations (0 means default)"), | ||
764 | |||
765 | new PhysParameterEntry("Friction", "Set friction parameter for a specific object" ), | ||
766 | new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ), | ||
767 | |||
768 | new PhysParameterEntry("Friction", "Set friction parameter for a specific object" ), | ||
769 | new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ), | ||
705 | 770 | ||
706 | new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ), | 771 | new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ), |
707 | new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ), | 772 | new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ), |
@@ -710,7 +775,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
710 | new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ), | 775 | new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ), |
711 | new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ), | 776 | new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ), |
712 | new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ), | 777 | new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ), |
713 | new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" ) | 778 | new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" ), |
779 | new PhysParameterEntry("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions") | ||
780 | |||
714 | }; | 781 | }; |
715 | 782 | ||
716 | #region IPhysicsParameters | 783 | #region IPhysicsParameters |
@@ -733,6 +800,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
733 | switch (lparm) | 800 | switch (lparm) |
734 | { | 801 | { |
735 | case "detailedstats": m_detailedStatsStep = (int)val; break; | 802 | case "detailedstats": m_detailedStatsStep = (int)val; break; |
803 | |||
736 | case "meshlod": m_meshLOD = (int)val; break; | 804 | case "meshlod": m_meshLOD = (int)val; break; |
737 | case "sculptlod": m_sculptLOD = (int)val; break; | 805 | case "sculptlod": m_sculptLOD = (int)val; break; |
738 | case "maxsubstep": m_maxSubSteps = (int)val; break; | 806 | case "maxsubstep": m_maxSubSteps = (int)val; break; |
@@ -743,7 +811,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
743 | case "defaultdensity": m_params[0].defaultDensity = val; break; | 811 | case "defaultdensity": m_params[0].defaultDensity = val; break; |
744 | case "defaultrestitution": m_params[0].defaultRestitution = val; break; | 812 | case "defaultrestitution": m_params[0].defaultRestitution = val; break; |
745 | case "collisionmargin": m_params[0].collisionMargin = val; break; | 813 | case "collisionmargin": m_params[0].collisionMargin = val; break; |
746 | case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break; | 814 | case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, localID, val); break; |
747 | 815 | ||
748 | case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break; | 816 | case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break; |
749 | case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; | 817 | case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; |
@@ -753,6 +821,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
753 | case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break; | 821 | case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break; |
754 | case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break; | 822 | case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break; |
755 | case "contactprocessingthreshold": UpdateParameterPrims(ref m_params[0].contactProcessingThreshold, lparm, localID, val); break; | 823 | case "contactprocessingthreshold": UpdateParameterPrims(ref m_params[0].contactProcessingThreshold, lparm, localID, val); break; |
824 | // the following are used only at initialization time so setting them makes no sense | ||
825 | // case "maxPersistantmanifoldpoolSize": m_params[0].maxPersistantManifoldPoolSize = val; break; | ||
826 | // case "shoulddisablecontactpooldynamicallocation": m_params[0].shouldDisableContactPoolDynamicAllocation = val; break; | ||
827 | // case "shouldforceupdateallaabbs": m_params[0].shouldForceUpdateAllAabbs = val; break; | ||
828 | // case "shouldrandomizesolverorder": m_params[0].shouldRandomizeSolverOrder = val; break; | ||
829 | // case "shouldsplitsimulationislands": m_params[0].shouldSplitSimulationIslands = val; break; | ||
830 | // case "shouldenablefrictioncaching": m_params[0].shouldEnableFrictionCaching = val; break; | ||
831 | // case "numberofsolveriterations": m_params[0].numberOfSolverIterations = val; break; | ||
832 | |||
833 | case "friction": TaintedUpdateParameter(lparm, localID, val); break; | ||
834 | case "restitution": TaintedUpdateParameter(lparm, localID, val); break; | ||
756 | 835 | ||
757 | // set a terrain physical feature and cause terrain to be recalculated | 836 | // set a terrain physical feature and cause terrain to be recalculated |
758 | case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break; | 837 | case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break; |
@@ -764,6 +843,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
764 | case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break; | 843 | case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break; |
765 | case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break; | 844 | case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break; |
766 | case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break; | 845 | case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break; |
846 | case "avatarcontactprocessingthreshold": UpdateParameterAvatars(ref m_params[0].avatarContactProcessingThreshold, "avatar", localID, val); break; | ||
767 | 847 | ||
768 | default: ret = false; break; | 848 | default: ret = false; break; |
769 | } | 849 | } |
@@ -856,6 +936,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
856 | case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break; | 936 | case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break; |
857 | case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break; | 937 | case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break; |
858 | case "contactprocessingthreshold": val = m_params[0].contactProcessingThreshold; break; | 938 | case "contactprocessingthreshold": val = m_params[0].contactProcessingThreshold; break; |
939 | case "maxPersistantmanifoldpoolSize": val = m_params[0].maxPersistantManifoldPoolSize; break; | ||
940 | case "shoulddisablecontactpooldynamicallocation": val = m_params[0].shouldDisableContactPoolDynamicAllocation; break; | ||
941 | case "shouldforceupdateallaabbs": val = m_params[0].shouldForceUpdateAllAabbs; break; | ||
942 | case "shouldrandomizesolverorder": val = m_params[0].shouldRandomizeSolverOrder; break; | ||
943 | case "shouldsplitsimulationislands": val = m_params[0].shouldSplitSimulationIslands; break; | ||
944 | case "shouldenablefrictioncaching": val = m_params[0].shouldEnableFrictionCaching; break; | ||
945 | case "numberofsolveriterations": val = m_params[0].numberOfSolverIterations; break; | ||
859 | 946 | ||
860 | case "terrainfriction": val = m_params[0].terrainFriction; break; | 947 | case "terrainfriction": val = m_params[0].terrainFriction; break; |
861 | case "terrainhitfraction": val = m_params[0].terrainHitFraction; break; | 948 | case "terrainhitfraction": val = m_params[0].terrainHitFraction; break; |
@@ -866,6 +953,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
866 | case "avatarrestitution": val = m_params[0].avatarRestitution; break; | 953 | case "avatarrestitution": val = m_params[0].avatarRestitution; break; |
867 | case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break; | 954 | case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break; |
868 | case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break; | 955 | case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break; |
956 | case "avatarcontactprocessingthreshold": val = m_params[0].avatarContactProcessingThreshold; break; | ||
869 | default: ret = false; break; | 957 | default: ret = false; break; |
870 | 958 | ||
871 | } | 959 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index d12bd7d..086f0dc 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | |||
@@ -132,6 +132,15 @@ public struct ConfigurationParameters | |||
132 | public float avatarRestitution; | 132 | public float avatarRestitution; |
133 | public float avatarCapsuleRadius; | 133 | public float avatarCapsuleRadius; |
134 | public float avatarCapsuleHeight; | 134 | public float avatarCapsuleHeight; |
135 | public float avatarContactProcessingThreshold; | ||
136 | |||
137 | public float maxPersistantManifoldPoolSize; | ||
138 | public float shouldDisableContactPoolDynamicAllocation; | ||
139 | public float shouldForceUpdateAllAabbs; | ||
140 | public float shouldRandomizeSolverOrder; | ||
141 | public float shouldSplitSimulationIslands; | ||
142 | public float shouldEnableFrictionCaching; | ||
143 | public float numberOfSolverIterations; | ||
135 | 144 | ||
136 | public const float numericTrue = 1f; | 145 | public const float numericTrue = 1f; |
137 | public const float numericFalse = 0f; | 146 | public const float numericFalse = 0f; |
@@ -149,16 +158,16 @@ public static extern uint Initialize(Vector3 maxPosition, IntPtr parms, | |||
149 | int maxUpdates, IntPtr updateArray); | 158 | int maxUpdates, IntPtr updateArray); |
150 | 159 | ||
151 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 160 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
152 | public static extern bool UpdateParameter(uint worldID, uint localID, | ||
153 | [MarshalAs(UnmanagedType.LPStr)]string paramCode, float value); | ||
154 | |||
155 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
156 | public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); | 161 | public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); |
157 | 162 | ||
158 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 163 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
159 | public static extern void Shutdown(uint worldID); | 164 | public static extern void Shutdown(uint worldID); |
160 | 165 | ||
166 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
167 | public static extern bool UpdateParameter(uint worldID, uint localID, | ||
168 | [MarshalAs(UnmanagedType.LPStr)]string paramCode, float value); | ||
161 | 169 | ||
170 | // =============================================================================== | ||
162 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 171 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
163 | public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep, | 172 | public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep, |
164 | out int updatedEntityCount, | 173 | out int updatedEntityCount, |
@@ -240,6 +249,7 @@ public static extern bool HasObject(uint worldID, uint id); | |||
240 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 249 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
241 | public static extern bool DestroyObject(uint worldID, uint id); | 250 | public static extern bool DestroyObject(uint worldID, uint id); |
242 | 251 | ||
252 | // =============================================================================== | ||
243 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 253 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
244 | public static extern SweepHit ConvexSweepTest(uint worldID, uint id, Vector3 to, float extraMargin); | 254 | public static extern SweepHit ConvexSweepTest(uint worldID, uint id, Vector3 to, float extraMargin); |
245 | 255 | ||
@@ -249,6 +259,7 @@ public static extern RaycastHit RayTest(uint worldID, uint id, Vector3 from, Vec | |||
249 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 259 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
250 | public static extern Vector3 RecoverFromPenetration(uint worldID, uint id); | 260 | public static extern Vector3 RecoverFromPenetration(uint worldID, uint id); |
251 | 261 | ||
262 | // =============================================================================== | ||
252 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 263 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
253 | public static extern void DumpBulletStatistics(); | 264 | public static extern void DumpBulletStatistics(); |
254 | 265 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 2942104..7c07e15 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs | |||
@@ -120,33 +120,110 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
120 | /// | 120 | /// |
121 | /// </summary> | 121 | /// </summary> |
122 | /// <param name="fname">The name of the function to invoke</param> | 122 | /// <param name="fname">The name of the function to invoke</param> |
123 | /// <param name="fname">List of parameters</param> | 123 | /// <param name="parms">List of parameters</param> |
124 | /// <returns>string result of the invocation</returns> | 124 | /// <returns>string result of the invocation</returns> |
125 | public string modInvokeS(string fname, params object[] parms) | 125 | public void modInvokeN(string fname, params object[] parms) |
126 | { | 126 | { |
127 | Type returntype = m_comms.LookupReturnType(fname); | 127 | Type returntype = m_comms.LookupReturnType(fname); |
128 | if (returntype != typeof(string)) | 128 | if (returntype != typeof(string)) |
129 | MODError(String.Format("return type mismatch for {0}",fname)); | 129 | MODError(String.Format("return type mismatch for {0}",fname)); |
130 | 130 | ||
131 | return (string)modInvoke(fname,parms); | 131 | modInvoke(fname,parms); |
132 | } | 132 | } |
133 | 133 | ||
134 | public int modInvokeI(string fname, params object[] parms) | 134 | public LSL_String modInvokeS(string fname, params object[] parms) |
135 | { | ||
136 | Type returntype = m_comms.LookupReturnType(fname); | ||
137 | if (returntype != typeof(string)) | ||
138 | MODError(String.Format("return type mismatch for {0}",fname)); | ||
139 | |||
140 | string result = (string)modInvoke(fname,parms); | ||
141 | return new LSL_String(result); | ||
142 | } | ||
143 | |||
144 | public LSL_Integer modInvokeI(string fname, params object[] parms) | ||
135 | { | 145 | { |
136 | Type returntype = m_comms.LookupReturnType(fname); | 146 | Type returntype = m_comms.LookupReturnType(fname); |
137 | if (returntype != typeof(int)) | 147 | if (returntype != typeof(int)) |
138 | MODError(String.Format("return type mismatch for {0}",fname)); | 148 | MODError(String.Format("return type mismatch for {0}",fname)); |
139 | 149 | ||
140 | return (int)modInvoke(fname,parms); | 150 | int result = (int)modInvoke(fname,parms); |
151 | return new LSL_Integer(result); | ||
141 | } | 152 | } |
142 | 153 | ||
143 | public float modInvokeF(string fname, params object[] parms) | 154 | public LSL_Float modInvokeF(string fname, params object[] parms) |
144 | { | 155 | { |
145 | Type returntype = m_comms.LookupReturnType(fname); | 156 | Type returntype = m_comms.LookupReturnType(fname); |
146 | if (returntype != typeof(float)) | 157 | if (returntype != typeof(float)) |
147 | MODError(String.Format("return type mismatch for {0}",fname)); | 158 | MODError(String.Format("return type mismatch for {0}",fname)); |
148 | 159 | ||
149 | return (float)modInvoke(fname,parms); | 160 | float result = (float)modInvoke(fname,parms); |
161 | return new LSL_Float(result); | ||
162 | } | ||
163 | |||
164 | public LSL_Key modInvokeK(string fname, params object[] parms) | ||
165 | { | ||
166 | Type returntype = m_comms.LookupReturnType(fname); | ||
167 | if (returntype != typeof(UUID)) | ||
168 | MODError(String.Format("return type mismatch for {0}",fname)); | ||
169 | |||
170 | UUID result = (UUID)modInvoke(fname,parms); | ||
171 | return new LSL_Key(result.ToString()); | ||
172 | } | ||
173 | |||
174 | public LSL_Vector modInvokeV(string fname, params object[] parms) | ||
175 | { | ||
176 | Type returntype = m_comms.LookupReturnType(fname); | ||
177 | if (returntype != typeof(OpenMetaverse.Vector3)) | ||
178 | MODError(String.Format("return type mismatch for {0}",fname)); | ||
179 | |||
180 | OpenMetaverse.Vector3 result = (OpenMetaverse.Vector3)modInvoke(fname,parms); | ||
181 | return new LSL_Vector(result.X,result.Y,result.Z); | ||
182 | } | ||
183 | |||
184 | public LSL_Rotation modInvokeR(string fname, params object[] parms) | ||
185 | { | ||
186 | Type returntype = m_comms.LookupReturnType(fname); | ||
187 | if (returntype != typeof(OpenMetaverse.Quaternion)) | ||
188 | MODError(String.Format("return type mismatch for {0}",fname)); | ||
189 | |||
190 | OpenMetaverse.Quaternion result = (OpenMetaverse.Quaternion)modInvoke(fname,parms); | ||
191 | return new LSL_Rotation(result.X,result.Y,result.Z,result.W); | ||
192 | } | ||
193 | |||
194 | public LSL_List modInvokeL(string fname, params object[] parms) | ||
195 | { | ||
196 | Type returntype = m_comms.LookupReturnType(fname); | ||
197 | if (returntype != typeof(object[])) | ||
198 | MODError(String.Format("return type mismatch for {0}",fname)); | ||
199 | |||
200 | object[] result = (object[])modInvoke(fname,parms); | ||
201 | object[] llist = new object[result.Length]; | ||
202 | for (int i = 0; i < result.Length; i++) | ||
203 | { | ||
204 | if (result[i] is string) | ||
205 | llist[i] = new LSL_String((string)result[i]); | ||
206 | else if (result[i] is int) | ||
207 | llist[i] = new LSL_Integer((int)result[i]); | ||
208 | else if (result[i] is float) | ||
209 | llist[i] = new LSL_Float((float)result[i]); | ||
210 | else if (result[i] is OpenMetaverse.Vector3) | ||
211 | { | ||
212 | OpenMetaverse.Vector3 vresult = (OpenMetaverse.Vector3)result[i]; | ||
213 | llist[i] = new LSL_Vector(vresult.X,vresult.Y,vresult.Z); | ||
214 | } | ||
215 | else if (result[i] is OpenMetaverse.Quaternion) | ||
216 | { | ||
217 | OpenMetaverse.Quaternion qresult = (OpenMetaverse.Quaternion)result[i]; | ||
218 | llist[i] = new LSL_Rotation(qresult.X,qresult.Y,qresult.Z,qresult.W); | ||
219 | } | ||
220 | else | ||
221 | { | ||
222 | MODError(String.Format("unknown list element returned by {0}",fname)); | ||
223 | } | ||
224 | } | ||
225 | |||
226 | return new LSL_List(llist); | ||
150 | } | 227 | } |
151 | 228 | ||
152 | /// <summary> | 229 | /// <summary> |
@@ -168,63 +245,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
168 | MODError(String.Format("wrong number of parameters to function {0}",fname)); | 245 | MODError(String.Format("wrong number of parameters to function {0}",fname)); |
169 | 246 | ||
170 | object[] convertedParms = new object[parms.Length]; | 247 | object[] convertedParms = new object[parms.Length]; |
171 | |||
172 | for (int i = 0; i < parms.Length; i++) | 248 | for (int i = 0; i < parms.Length; i++) |
173 | { | 249 | convertedParms[i] = ConvertFromLSL(parms[i],signature[i]); |
174 | if (parms[i] is LSL_String) | ||
175 | { | ||
176 | if (signature[i] != typeof(string)) | ||
177 | MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); | ||
178 | 250 | ||
179 | convertedParms[i] = (string)(LSL_String)parms[i]; | 251 | // now call the function, the contract with the function is that it will always return |
180 | } | 252 | // non-null but don't trust it completely |
181 | else if (parms[i] is LSL_Integer) | 253 | try |
182 | { | 254 | { |
183 | if (signature[i] != typeof(int)) | 255 | object result = m_comms.InvokeOperation(m_host.UUID, m_itemID, fname, convertedParms); |
184 | MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); | 256 | if (result != null) |
185 | 257 | return result; | |
186 | convertedParms[i] = (int)(LSL_Integer)parms[i]; | ||
187 | } | ||
188 | else if (parms[i] is LSL_Float) | ||
189 | { | ||
190 | if (signature[i] != typeof(float)) | ||
191 | MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); | ||
192 | |||
193 | convertedParms[i] = (float)(LSL_Float)parms[i]; | ||
194 | } | ||
195 | else if (parms[i] is LSL_Key) | ||
196 | { | ||
197 | if (signature[i] != typeof(string)) | ||
198 | MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); | ||
199 | |||
200 | convertedParms[i] = (string)(LSL_Key)parms[i]; | ||
201 | } | ||
202 | else if (parms[i] is LSL_Rotation) | ||
203 | { | ||
204 | if (signature[i] != typeof(string)) | ||
205 | MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); | ||
206 | |||
207 | convertedParms[i] = (string)(LSL_Rotation)parms[i]; | ||
208 | } | ||
209 | else if (parms[i] is LSL_Vector) | ||
210 | { | ||
211 | if (signature[i] != typeof(string)) | ||
212 | MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); | ||
213 | |||
214 | convertedParms[i] = (string)(LSL_Vector)parms[i]; | ||
215 | } | ||
216 | else | ||
217 | { | ||
218 | if (signature[i] != parms[i].GetType()) | ||
219 | MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); | ||
220 | 258 | ||
221 | convertedParms[i] = parms[i]; | 259 | MODError(String.Format("Invocation of {0} failed; null return value",fname)); |
222 | } | 260 | } |
261 | catch (Exception e) | ||
262 | { | ||
263 | MODError(String.Format("Invocation of {0} failed; {1}",fname,e.Message)); | ||
223 | } | 264 | } |
224 | 265 | ||
225 | return m_comms.InvokeOperation(m_itemID,fname,convertedParms); | 266 | return null; |
226 | } | 267 | } |
227 | 268 | ||
269 | /// <summary> | ||
270 | /// Send a command to functions registered on an event | ||
271 | /// </summary> | ||
228 | public string modSendCommand(string module, string command, string k) | 272 | public string modSendCommand(string module, string command, string k) |
229 | { | 273 | { |
230 | if (!m_MODFunctionsEnabled) | 274 | if (!m_MODFunctionsEnabled) |
@@ -239,5 +283,101 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
239 | 283 | ||
240 | return req.ToString(); | 284 | return req.ToString(); |
241 | } | 285 | } |
286 | |||
287 | /// <summary> | ||
288 | /// </summary> | ||
289 | protected object ConvertFromLSL(object lslparm, Type type) | ||
290 | { | ||
291 | // ---------- String ---------- | ||
292 | if (lslparm is LSL_String) | ||
293 | { | ||
294 | if (type == typeof(string)) | ||
295 | return (string)(LSL_String)lslparm; | ||
296 | |||
297 | // Need to check for UUID since keys are often treated as strings | ||
298 | if (type == typeof(UUID)) | ||
299 | return new UUID((string)(LSL_String)lslparm); | ||
300 | } | ||
301 | |||
302 | // ---------- Integer ---------- | ||
303 | else if (lslparm is LSL_Integer) | ||
304 | { | ||
305 | if (type == typeof(int)) | ||
306 | return (int)(LSL_Integer)lslparm; | ||
307 | } | ||
308 | |||
309 | // ---------- Float ---------- | ||
310 | else if (lslparm is LSL_Float) | ||
311 | { | ||
312 | if (type == typeof(float)) | ||
313 | return (float)(LSL_Float)lslparm; | ||
314 | } | ||
315 | |||
316 | // ---------- Key ---------- | ||
317 | else if (lslparm is LSL_Key) | ||
318 | { | ||
319 | if (type == typeof(UUID)) | ||
320 | return new UUID((LSL_Key)lslparm); | ||
321 | } | ||
322 | |||
323 | // ---------- Rotation ---------- | ||
324 | else if (lslparm is LSL_Rotation) | ||
325 | { | ||
326 | if (type == typeof(OpenMetaverse.Quaternion)) | ||
327 | { | ||
328 | LSL_Rotation rot = (LSL_Rotation)lslparm; | ||
329 | return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); | ||
330 | } | ||
331 | } | ||
332 | |||
333 | // ---------- Vector ---------- | ||
334 | else if (lslparm is LSL_Vector) | ||
335 | { | ||
336 | if (type == typeof(OpenMetaverse.Vector3)) | ||
337 | { | ||
338 | LSL_Vector vect = (LSL_Vector)lslparm; | ||
339 | return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); | ||
340 | } | ||
341 | } | ||
342 | |||
343 | // ---------- List ---------- | ||
344 | else if (lslparm is LSL_List) | ||
345 | { | ||
346 | if (type == typeof(object[])) | ||
347 | { | ||
348 | object[] plist = (lslparm as LSL_List).Data; | ||
349 | object[] result = new object[plist.Length]; | ||
350 | for (int i = 0; i < plist.Length; i++) | ||
351 | { | ||
352 | if (plist[i] is LSL_String) | ||
353 | result[i] = (string)(LSL_String)plist[i]; | ||
354 | else if (plist[i] is LSL_Integer) | ||
355 | result[i] = (int)(LSL_Integer)plist[i]; | ||
356 | else if (plist[i] is LSL_Float) | ||
357 | result[i] = (float)(LSL_Float)plist[i]; | ||
358 | else if (plist[i] is LSL_Key) | ||
359 | result[i] = new UUID((LSL_Key)plist[i]); | ||
360 | else if (plist[i] is LSL_Rotation) | ||
361 | { | ||
362 | LSL_Rotation rot = (LSL_Rotation)plist[i]; | ||
363 | result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); | ||
364 | } | ||
365 | else if (plist[i] is LSL_Vector) | ||
366 | { | ||
367 | LSL_Vector vect = (LSL_Vector)plist[i]; | ||
368 | result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); | ||
369 | } | ||
370 | else | ||
371 | MODError("unknown LSL list element type"); | ||
372 | } | ||
373 | |||
374 | return result; | ||
375 | } | ||
376 | } | ||
377 | |||
378 | MODError(String.Format("parameter type mismatch; expecting {0}",type.Name)); | ||
379 | return null; | ||
380 | } | ||
381 | |||
242 | } | 382 | } |
243 | } | 383 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs index 756a59f..aa78aaa 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs | |||
@@ -28,26 +28,27 @@ | |||
28 | using System.Collections; | 28 | using System.Collections; |
29 | using OpenSim.Region.ScriptEngine.Interfaces; | 29 | using OpenSim.Region.ScriptEngine.Interfaces; |
30 | 30 | ||
31 | using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | 31 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; |
32 | using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; | 32 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; |
33 | using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | 33 | using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; |
34 | using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; | 34 | using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; |
35 | using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; | ||
35 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | 36 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; |
36 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; | 37 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; |
37 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; | ||
38 | 38 | ||
39 | namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | 39 | namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces |
40 | { | 40 | { |
41 | public interface IMOD_Api | 41 | public interface IMOD_Api |
42 | { | 42 | { |
43 | // Invocation functions | 43 | // Invocation functions |
44 | string modInvokeS(string fname, params object[] parms); | 44 | void modInvokeN(string fname, params object[] parms); |
45 | int modInvokeI(string fname, params object[] parms); | 45 | LSL_String modInvokeS(string fname, params object[] parms); |
46 | float modInvokeF(string fname, params object[] parms); | 46 | LSL_Integer modInvokeI(string fname, params object[] parms); |
47 | // vector modInvokeV(string fname, params object[] parms); | 47 | LSL_Float modInvokeF(string fname, params object[] parms); |
48 | // rotation modInvokeV(string fname, params object[] parms); | 48 | LSL_Key modInvokeK(string fname, params object[] parms); |
49 | // key modInvokeK(string fname, params object[] parms); | 49 | LSL_Vector modInvokeV(string fname, params object[] parms); |
50 | // list modInvokeL(string fname, params object[] parms); | 50 | LSL_Rotation modInvokeR(string fname, params object[] parms); |
51 | LSL_List modInvokeL(string fname, params object[] parms); | ||
51 | 52 | ||
52 | //Module functions | 53 | //Module functions |
53 | string modSendCommand(string modules, string command, string k); | 54 | string modSendCommand(string modules, string command, string k); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs index 04b7f14..1c47138 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs | |||
@@ -39,10 +39,14 @@ using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; | |||
39 | using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | 39 | using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; |
40 | using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; | 40 | using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; |
41 | using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | 41 | using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; |
42 | using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; | 42 | |
43 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | ||
44 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; | 43 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; |
45 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; | 44 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; |
45 | using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | ||
46 | using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; | ||
47 | using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; | ||
48 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | ||
49 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | ||
46 | 50 | ||
47 | namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | 51 | namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase |
48 | { | 52 | { |
@@ -58,21 +62,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
58 | m_MOD_Functions = (IMOD_Api)api; | 62 | m_MOD_Functions = (IMOD_Api)api; |
59 | } | 63 | } |
60 | 64 | ||
61 | public string modInvokeS(string fname, params object[] parms) | 65 | public void modInvokeN(string fname, params object[] parms) |
66 | { | ||
67 | m_MOD_Functions.modInvokeN(fname, parms); | ||
68 | } | ||
69 | |||
70 | public LSL_String modInvokeS(string fname, params object[] parms) | ||
62 | { | 71 | { |
63 | return m_MOD_Functions.modInvokeS(fname, parms); | 72 | return m_MOD_Functions.modInvokeS(fname, parms); |
64 | } | 73 | } |
65 | 74 | ||
66 | public int modInvokeI(string fname, params object[] parms) | 75 | public LSL_Integer modInvokeI(string fname, params object[] parms) |
67 | { | 76 | { |
68 | return m_MOD_Functions.modInvokeI(fname, parms); | 77 | return m_MOD_Functions.modInvokeI(fname, parms); |
69 | } | 78 | } |
70 | 79 | ||
71 | public float modInvokeF(string fname, params object[] parms) | 80 | public LSL_Float modInvokeF(string fname, params object[] parms) |
72 | { | 81 | { |
73 | return m_MOD_Functions.modInvokeF(fname, parms); | 82 | return m_MOD_Functions.modInvokeF(fname, parms); |
74 | } | 83 | } |
75 | 84 | ||
85 | public LSL_Key modInvokeK(string fname, params object[] parms) | ||
86 | { | ||
87 | return m_MOD_Functions.modInvokeK(fname, parms); | ||
88 | } | ||
89 | |||
90 | public LSL_Vector modInvokeV(string fname, params object[] parms) | ||
91 | { | ||
92 | return m_MOD_Functions.modInvokeV(fname, parms); | ||
93 | } | ||
94 | |||
95 | public LSL_Rotation modInvokeR(string fname, params object[] parms) | ||
96 | { | ||
97 | return m_MOD_Functions.modInvokeR(fname, parms); | ||
98 | } | ||
99 | |||
100 | public LSL_List modInvokeL(string fname, params object[] parms) | ||
101 | { | ||
102 | return m_MOD_Functions.modInvokeL(fname, parms); | ||
103 | } | ||
104 | |||
76 | public string modSendCommand(string module, string command, string k) | 105 | public string modSendCommand(string module, string command, string k) |
77 | { | 106 | { |
78 | return m_MOD_Functions.modSendCommand(module, command, k); | 107 | return m_MOD_Functions.modSendCommand(module, command, k); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/IndexedAnswers.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/IndexedAnswers.cs index 04357a9..09a9a08 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/IndexedAnswers.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/IndexedAnswers.cs | |||
@@ -226,7 +226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog | |||
226 | break; | 226 | break; |
227 | } | 227 | } |
228 | } | 228 | } |
229 | 229 | int z = 0; | |
230 | try | 230 | try |
231 | { | 231 | { |
232 | if (gotMatch) | 232 | if (gotMatch) |
@@ -235,8 +235,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog | |||
235 | finally | 235 | finally |
236 | { | 236 | { |
237 | // Manually finalize all the iterators. | 237 | // Manually finalize all the iterators. |
238 | for (int i = 0; i < nIterators; ++i) | 238 | for (z = 0; z < nIterators; ++z) |
239 | iterators[i].Dispose(); | 239 | iterators[z].Dispose(); |
240 | } | 240 | } |
241 | } | 241 | } |
242 | } | 242 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YP.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YP.cs index d8f44c1..f2171dd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YP.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YP.cs | |||
@@ -576,7 +576,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog | |||
576 | break; | 576 | break; |
577 | } | 577 | } |
578 | } | 578 | } |
579 | 579 | int z = 0; | |
580 | try | 580 | try |
581 | { | 581 | { |
582 | if (gotMatch) | 582 | if (gotMatch) |
@@ -585,8 +585,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog | |||
585 | finally | 585 | finally |
586 | { | 586 | { |
587 | // Manually finalize all the iterators. | 587 | // Manually finalize all the iterators. |
588 | for (int i = 0; i < nIterators; ++i) | 588 | for (z = 0; z < nIterators; ++z) |
589 | iterators[i].Dispose(); | 589 | iterators[z].Dispose(); |
590 | } | 590 | } |
591 | } | 591 | } |
592 | 592 | ||