// 'engineName' is the Bullet engine to use. Either null (for unmanaged), "BulletUnmanaged" or "BulletXNA" // 'params' is a set of keyValue pairs to set in the engine's configuration file (override defaults) // May be 'null' if there are no overrides. public static BSScene CreateBasicPhysicsEngine(Dictionary <string, string> paramOverrides) { IConfigSource openSimINI = new IniConfigSource(); IConfig startupConfig = openSimINI.AddConfig("Startup"); startupConfig.Set("physics", "BulletSim"); startupConfig.Set("meshing", "Meshmerizer"); startupConfig.Set("cacheSculptMaps", "false"); // meshmerizer shouldn't save maps IConfig bulletSimConfig = openSimINI.AddConfig("BulletSim"); // If the caller cares, specify the bullet engine otherwise it will default to "BulletUnmanaged". // bulletSimConfig.Set("BulletEngine", "BulletUnmanaged"); // bulletSimConfig.Set("BulletEngine", "BulletXNA"); bulletSimConfig.Set("MeshSculptedPrim", "false"); bulletSimConfig.Set("ForceSimplePrimMeshing", "true"); if (paramOverrides != null) { foreach (KeyValuePair <string, string> kvp in paramOverrides) { bulletSimConfig.Set(kvp.Key, kvp.Value); } } // If a special directory exists, put detailed logging therein. // This allows local testing/debugging without having to worry that the build engine will output logs. if (Directory.Exists("physlogs")) { bulletSimConfig.Set("PhysicsLoggingDir", "./physlogs"); bulletSimConfig.Set("PhysicsLoggingEnabled", "True"); bulletSimConfig.Set("PhysicsLoggingDoFlush", "True"); bulletSimConfig.Set("VehicleLoggingEnabled", "True"); } Vector3 regionExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); RegionInfo info = new RegionInfo(); info.RegionName = "BSTestRegion"; info.RegionSizeX = info.RegionSizeY = info.RegionSizeZ = Constants.RegionSize; OpenSim.Region.Framework.Scenes.Scene scene = new OpenSim.Region.Framework.Scenes.Scene(info); IMesher mesher = new OpenSim.Region.PhysicsModule.Meshing.Meshmerizer(); INonSharedRegionModule mod = mesher as INonSharedRegionModule; mod.Initialise(openSimINI); mod.AddRegion(scene); mod.RegionLoaded(scene); BSScene pScene = new BSScene(); mod = (pScene as INonSharedRegionModule); mod.Initialise(openSimINI); mod.AddRegion(scene); mod.RegionLoaded(scene); // Since the asset requestor is not initialized, any mesh or sculptie will be a cube. // In the future, add a fake asset fetcher to get meshes and sculpts. // bsScene.RequestAssetMethod = ???; return(pScene); }
// The root of all evil. // This is where we handle adding the modules to scenes when they // load. This means that here we deal with replaceable interfaces, // nonshared modules, etc. // public void AddRegionToModules(Scene scene) { Dictionary <Type, ISharedRegionModule> deferredSharedModules = new Dictionary <Type, ISharedRegionModule>(); Dictionary <Type, INonSharedRegionModule> deferredNonSharedModules = new Dictionary <Type, INonSharedRegionModule>(); // We need this to see if a module has already been loaded and // has defined a replaceable interface. It's a generic call, // so this can't be used directly. It will be used later Type s = scene.GetType(); MethodInfo mi = s.GetMethod("RequestModuleInterface"); // This will hold the shared modules we actually load List <ISharedRegionModule> sharedlist = new List <ISharedRegionModule>(); // Iterate over the shared modules that have been loaded // Add them to the new Scene foreach (ISharedRegionModule module in m_sharedInstances) { // Here is where we check if a replaceable interface // is defined. If it is, the module is checked against // the interfaces already defined. If the interface is // defined, we simply skip the module. Else, if the module // defines a replaceable interface, we add it to the deferred // list. Type replaceableInterface = module.ReplaceableInterface; if (replaceableInterface != null) { MethodInfo mii = mi.MakeGenericMethod(replaceableInterface); if (mii.Invoke(scene, new object[0]) != null) { m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString()); continue; } deferredSharedModules[replaceableInterface] = module; m_log.DebugFormat("[REGIONMODULE]: Deferred load of {0}", module.Name); continue; } m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to shared module {1}", scene.RegionInfo.RegionName, module.Name); module.AddRegion(scene); scene.AddRegionModule(module.Name, module); sharedlist.Add(module); } IConfig modulesConfig = m_openSim.ConfigSource.Source.Configs["Modules"]; // Scan for, and load, nonshared modules List <INonSharedRegionModule> list = new List <INonSharedRegionModule>(); foreach (TypeExtensionNode node in m_nonSharedModules) { Object[] ctorArgs = new Object[] { 0 }; // Read the config string moduleString = modulesConfig.GetString("Setup_" + node.Id, String.Empty); // Get the port number, if there is one if (moduleString != String.Empty) { // Get the port number from the string string[] moduleParts = moduleString.Split(new char[] { '/' }, 2); if (moduleParts.Length > 1) { ctorArgs[0] = Convert.ToUInt32(moduleParts[0]); } } // Actually load it INonSharedRegionModule module = null; Type[] ctorParamTypes = new Type[ctorArgs.Length]; for (int i = 0; i < ctorParamTypes.Length; i++) { ctorParamTypes[i] = ctorArgs[i].GetType(); } if (node.Type.GetConstructor(ctorParamTypes) != null) { module = (INonSharedRegionModule)Activator.CreateInstance(node.Type, ctorArgs); } else { module = (INonSharedRegionModule)Activator.CreateInstance(node.Type); } // Check for replaceable interfaces Type replaceableInterface = module.ReplaceableInterface; if (replaceableInterface != null) { MethodInfo mii = mi.MakeGenericMethod(replaceableInterface); if (mii.Invoke(scene, new object[0]) != null) { m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString()); continue; } deferredNonSharedModules[replaceableInterface] = module; m_log.DebugFormat("[REGIONMODULE]: Deferred load of {0}", module.Name); continue; } m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to non-shared module {1}", scene.RegionInfo.RegionName, module.Name); // Initialise the module module.Initialise(m_openSim.ConfigSource.Source); list.Add(module); } // Now add the modules that we found to the scene. If a module // wishes to override a replaceable interface, it needs to // register it in Initialise, so that the deferred module // won't load. foreach (INonSharedRegionModule module in list) { module.AddRegion(scene); scene.AddRegionModule(module.Name, module); } // Now all modules without a replaceable base interface are loaded // Replaceable modules have either been skipped, or omitted. // Now scan the deferred modules here foreach (ISharedRegionModule module in deferredSharedModules.Values) { // Determine if the interface has been replaced Type replaceableInterface = module.ReplaceableInterface; MethodInfo mii = mi.MakeGenericMethod(replaceableInterface); if (mii.Invoke(scene, new object[0]) != null) { m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString()); continue; } m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to shared module {1} (deferred)", scene.RegionInfo.RegionName, module.Name); // Not replaced, load the module module.AddRegion(scene); scene.AddRegionModule(module.Name, module); sharedlist.Add(module); } // Same thing for nonshared modules, load them unless overridden List <INonSharedRegionModule> deferredlist = new List <INonSharedRegionModule>(); foreach (INonSharedRegionModule module in deferredNonSharedModules.Values) { // Check interface override Type replaceableInterface = module.ReplaceableInterface; if (replaceableInterface != null) { MethodInfo mii = mi.MakeGenericMethod(replaceableInterface); if (mii.Invoke(scene, new object[0]) != null) { m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString()); continue; } } m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to non-shared module {1} (deferred)", scene.RegionInfo.RegionName, module.Name); module.Initialise(m_openSim.ConfigSource.Source); list.Add(module); deferredlist.Add(module); } // Finally, load valid deferred modules foreach (INonSharedRegionModule module in deferredlist) { module.AddRegion(scene); scene.AddRegionModule(module.Name, module); } // This is needed for all module types. Modules will register // Interfaces with scene in AddScene, and will also need a means // to access interfaces registered by other modules. Without // this extra method, a module attempting to use another modules's // interface would be successful only depending on load order, // which can't be depended upon, or modules would need to resort // to ugly kludges to attempt to request interfaces when needed // and unneccessary caching logic repeated in all modules. // The extra function stub is just that much cleaner // foreach (ISharedRegionModule module in sharedlist) { module.RegionLoaded(scene); } foreach (INonSharedRegionModule module in list) { module.RegionLoaded(scene); } }