From fef73a1a1011126d4df2da2279caae9cef7984d1 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 18 Aug 2011 14:32:09 -0700 Subject: BulletSim: add runtime setting of physics parameters. Update default values. --- .../PhysicsParameters/PhysicsParameters.cs | 277 +++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100755 OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs (limited to 'OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs') diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs new file mode 100755 index 0000000..2a44360 --- /dev/null +++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs @@ -0,0 +1,277 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Collections.Generic; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.CoreModules.Framework.InterfaceCommander; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.OptionalModules.PhysicsParameters +{ + /// + /// + /// + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PhysicsParameters")] + public class PhysicsParameters : ISharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static string LogHeader = "[PHYSICS PARAMETERS]"; + + private List m_scenes = new List(); + private static bool m_commandsLoaded = false; + + #region ISharedRegionModule + public string Name { get { return "Runtime Physics Parameter Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { + // m_log.DebugFormat("{0}: INITIALIZED MODULE", LogHeader); + } + + public void PostInitialise() + { + // m_log.DebugFormat("[{0}: POST INITIALIZED MODULE", LogHeader); + InstallInterfaces(); + } + + public void Close() + { + // m_log.DebugFormat("{0}: CLOSED MODULE", LogHeader); + } + + public void AddRegion(Scene scene) + { + // m_log.DebugFormat("{0}: REGION {1} ADDED", LogHeader, scene.RegionInfo.RegionName); + m_scenes.Add(scene); + } + + public void RemoveRegion(Scene scene) + { + // m_log.DebugFormat("{0}: REGION {1} REMOVED", LogHeader, scene.RegionInfo.RegionName); + if (m_scenes.Contains(scene)) + m_scenes.Remove(scene); + } + + public void RegionLoaded(Scene scene) + { + // m_log.DebugFormat("{0}: REGION {1} LOADED", LogHeader, scene.RegionInfo.RegionName); + } + #endregion INonSharedRegionModule + + private const string getInvocation = "physics get [|ALL]"; + private const string setInvocation = "physics set [|TRUE|FALSE] [localID|ALL]"; + private const string listInvocation = "physics list"; + private void InstallInterfaces() + { + if (!m_commandsLoaded) + { + MainConsole.Instance.Commands.AddCommand("Physics", false, "physics set", + "physics set", + "Set physics parameter from currently selected region" + Environment.NewLine + + "Invocation: " + setInvocation, + ProcessPhysicsSet); + + MainConsole.Instance.Commands.AddCommand("Physics", false, "physics get", + "physics get", + "Get physics parameter from currently selected region" + Environment.NewLine + + "Invocation: " + getInvocation, + ProcessPhysicsGet); + + MainConsole.Instance.Commands.AddCommand("Physics", false, "physics list", + "physics list", + "List settable physics parameters" + Environment.NewLine + + "Invocation: " + listInvocation, + ProcessPhysicsList); + + m_commandsLoaded = true; + } + } + + // TODO: extend get so you can get a value from an individual localID + private void ProcessPhysicsGet(string module, string[] cmdparms) + { + if (cmdparms.Length != 3) + { + WriteError("Parameter count error. Invocation: " + getInvocation); + return; + } + string parm = cmdparms[2]; + + if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null) + { + WriteError("Error: no region selected. Use 'change region' to select a region."); + return; + } + + Scene scene = SceneManager.Instance.CurrentScene; + IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters; + if (physScene != null) + { + if (parm.ToLower() == "all") + { + foreach (PhysParameterEntry ppe in physScene.GetParameterList()) + { + float val = 0.0f; + if (physScene.GetPhysicsParameter(ppe.name, out val)) + { + WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, val); + } + else + { + WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, ppe.name, "unknown"); + } + } + } + else + { + float val = 0.0f; + if (physScene.GetPhysicsParameter(parm, out val)) + { + WriteOut(" {0}/{1} = {2}", scene.RegionInfo.RegionName, parm, val); + } + else + { + WriteError("Failed fetch of parameter '{0}' from region '{1}'", parm, scene.RegionInfo.RegionName); + } + } + } + else + { + WriteError("Region '{0}' physics engine has no gettable physics parameters", scene.RegionInfo.RegionName); + } + return; + } + + private void ProcessPhysicsSet(string module, string[] cmdparms) + { + if (cmdparms.Length < 4 || cmdparms.Length > 5) + { + WriteError("Parameter count error. Invocation: " + getInvocation); + return; + } + string parm = "xxx"; + float val = 0f; + uint localID = (uint)PhysParameterEntry.APPLY_TO_NONE; // set default value + try + { + parm = cmdparms[2]; + string valparm = cmdparms[3].ToLower(); + if (valparm == "true") + val = PhysParameterEntry.NUMERIC_TRUE; + else + { + if (valparm == "false") + val = PhysParameterEntry.NUMERIC_FALSE; + else + val = float.Parse(valparm, Culture.NumberFormatInfo); + } + if (cmdparms.Length > 4) + { + if (cmdparms[4].ToLower() == "all") + localID = (uint)PhysParameterEntry.APPLY_TO_ALL; + else + localID = uint.Parse(cmdparms[2], Culture.NumberFormatInfo); + } + } + catch + { + WriteError(" Error parsing parameters. Invocation: " + setInvocation); + return; + } + + if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null) + { + WriteError("Error: no region selected. Use 'change region' to select a region."); + return; + } + + Scene scene = SceneManager.Instance.CurrentScene; + IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters; + if (physScene != null) + { + if (!physScene.SetPhysicsParameter(parm, val, localID)) + { + WriteError("Failed set of parameter '{0}' for region '{1}'", parm, scene.RegionInfo.RegionName); + } + } + else + { + WriteOut("Region '{0}'s physics engine has no settable physics parameters", scene.RegionInfo.RegionName); + } + return; + } + + private void ProcessPhysicsList(string module, string[] cmdparms) + { + if (SceneManager.Instance == null || SceneManager.Instance.CurrentScene == null) + { + WriteError("Error: no region selected. Use 'change region' to select a region."); + return; + } + Scene scene = SceneManager.Instance.CurrentScene; + + IPhysicsParameters physScene = scene.PhysicsScene as IPhysicsParameters; + if (physScene != null) + { + WriteOut("Available physics parameters:"); + PhysParameterEntry[] parms = physScene.GetParameterList(); + foreach (PhysParameterEntry ent in parms) + { + WriteOut(" {0}: {1}", ent.name, ent.desc); + } + } + else + { + WriteError("Current regions's physics engine has no settable physics parameters"); + } + return; + } + + private void WriteOut(string msg, params object[] args) + { + m_log.InfoFormat(msg, args); + // MainConsole.Instance.OutputFormat(msg, args); + } + + private void WriteError(string msg, params object[] args) + { + m_log.ErrorFormat(msg, args); + // MainConsole.Instance.OutputFormat(msg, args); + } + } +} \ No newline at end of file -- cgit v1.1