// Given a BScene, write out a GLTF version and return a handle to the version. private async Task <LHandle> WriteOutLevel(BHash pLevelHash, BScene pBScene, AssetManager pAssetManager) { Gltf gltf; try { gltf = new Gltf(_scene.Name, LContext.log, LContext.parms); gltf.LoadScene(pBScene); } catch (Exception e) { string emsg = String.Format("{0} Exeception loading scene into Gltf: {1}", _logHeader, e); LContext.log.ErrorFormat(emsg); throw new Exception(emsg); } string topLevelFilename = pLevelHash.ToString() + ".gltf"; LContext.log.DebugFormat("{0}: writing top level region GLTF to {1}", _logHeader, topLevelFilename); try { using (var outm = new MemoryStream()) { using (StreamWriter outt = new StreamWriter(outm)) { gltf.ToJSON(outt); } await pAssetManager.AssetStorage.Store(topLevelFilename, outm.ToArray()); } gltf.WriteBinaryFiles(pAssetManager.AssetStorage); gltf.WriteImages(pAssetManager.AssetStorage); } catch (Exception e) { string emsg = String.Format("{0} Exeception writing top level GLTF files: {1}", _logHeader, e); LContext.log.ErrorFormat(emsg); throw new Exception(emsg); } return(new LHandle(pLevelHash, topLevelFilename)); }
// Convert the region into the optimizable and convertable BScene. private async Task <BScene> ConvertSceneToBScene(AssetManager pAssetManager) { BScene bScene = null; try { BConverterOS converter = new BConverterOS(LContext.log, LContext.parms); bScene = await converter.ConvertRegionToBScene(_scene, pAssetManager); } catch (Exception e) { LContext.log.ErrorFormat("{0} Exeception converting region to BScene: {1}", _logHeader, e); } return(bScene); }
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: }