// // IRegionModuleBase.Close public void Close() { // Stop the region processor. if (_regionProcessor != null) { _regionProcessor.Shutdown(); _regionProcessor = null; } }
// IRegionModuleBase.RegionLoaded // Called once for each region loaded after all other regions have been loaded. public void RegionLoaded(Scene scene) { if (_lcontext.parms.P <bool>("Enabled")) { // Start a processing thread for the region we're managing _regionProcessor = new LodenRegion(_scene, _lcontext); _regionProcessor.Start(); } // That's nice. }
// Create a region hash made of the hashes of all the SOGs in the region public static BHash CreateRegionHash(Scene pScene) { BHasher regionHasher = new BHasherSHA256(); regionHasher.Add(pScene.RegionInfo.RegionID.GetBytes(), 0, 16); foreach (SceneObjectGroup sog in pScene.GetSceneObjectGroups().OrderBy(x => x.UUID)) { regionHasher.Add(LodenRegion.CreateSOGHash(sog)); } return(regionHasher.Finish()); }
// Create a uniquifying hash for this SOG instance. // The hash includes the UUID, a hash of the prim paramters, and the position in the scene. public static BHash CreateSOGHash(SceneObjectGroup pSog) { BHasher sogHasher = new BHasherSHA256(); sogHasher.Add(pSog.UUID.GetBytes(), 0, 16); foreach (SceneObjectPart sop in pSog.Parts.OrderBy(x => x.UUID)) { sogHasher.Add(sop.UUID.GetBytes(), 0, 16); sogHasher.Add(sop.Shape.GetMeshKey(sop.Scale, (float)OMVR.DetailLevel.Highest)); LodenRegion.AddPositionToHash(sogHasher, sop.AbsolutePosition, sop.RotationOffset); } ; return(sogHasher.Finish()); }
private async Task ConvertRegionAssets() { _assetTools = new LodenAssets(_scene, LContext); // Subscribe to changes in the region so we know when to start rebuilding // TODO: BHash regionHash = LodenRegion.CreateRegionHash(_scene); LContext.log.DebugFormat("{0} SOGs in region: {1}", _logHeader, _scene.GetSceneObjectGroups().Count); LContext.log.DebugFormat("{0} Computed region hash: {1}", _logHeader, regionHash.ToString()); // Cleaned up region identifier string regionIdentifier = _scene.RegionInfo.RegionID.ToString().Replace("-", ""); using (AssetManager assetManager = new AssetManager(_scene.AssetService, LContext.log, LContext.parms)) { string specFilename = regionIdentifier + ".json"; RegionTopLevelSpecURL = CreateFileURI(regionIdentifier + ".json", LContext.parms); // See if region specification file has been built bool buildRegion = true; try { string regionSpec = await assetManager.AssetStorage.FetchText(specFilename); if (!String.IsNullOrEmpty(regionSpec)) { // Read in the spec file TileSet regionTiles = TileSet.FromString(regionSpec); if (regionTiles.root.content.extras.ContainsKey("contentHash")) { // If the content hash matches, the region doesn't need rebuilding if ((string)regionTiles.root.content.extras["contentHash"] == regionHash.ToString()) { LContext.log.DebugFormat("{0} Content hash matches. Not rebuilding", _logHeader); buildRegion = false; } else { LContext.log.DebugFormat("{0} Content hash does not match. Rebuilding", _logHeader); } } } } catch (Exception e) { LContext.log.ErrorFormat("{0} Exception reading region spec file: {1}", _logHeader, e); buildRegion = true; } if (buildRegion) { // The region has not been built. LContext.log.DebugFormat("{0}: region does not match. Rebuilding", _logHeader); // Convert the OpenSimulator scene to BScene object for manipulation BScene bScene = await ConvertSceneToBScene(assetManager); // Write out the 'top level' (highest quality) version of the region LHandle topLevelHandle = await WriteOutLevel(regionHash, bScene, assetManager); // Create the region specification which defines the top of the region LOD tree LHandle regionSpecFile = await WriteRegionSpec(assetManager, regionHash, specFilename, topLevelHandle.Filename); } else { LContext.log.DebugFormat("{0}: region spec file exists.", _logHeader); } } // Partition region and verify all partitions have been created and not different. // TODO: // Walk up the LOD chain and verify existance or build each LOD level // TODO: // Wait for changes and do rebuilds of necessary // TODO: }