Пример #1
0
        // 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));
        }
Пример #2
0
        // If run from the command line, create instance and call 'Start' with args.
        // If run programmatically, create instance and call 'Start' with parameters.
        public async Task Start(CancellationToken cancelToken, string[] args)
        {
            Globals = new GlobalContext()
            {
                log = new LoggerLog4Net(),
                // log = new LoggerConsole(),
                stats = new ConvoarStats()
            };
            Globals.parms = new ConvoarParams(Globals.log);

            // A single parameter of '--help' outputs the invocation parameters
            if (args.Length > 0 && args[0] == "--help")
            {
                System.Console.Write(Invocation());
                return;
            }

            // 'ConvoarParams' initializes to default values.
            // Over ride default values with command line parameters.
            try {
                // Note that trailing parameters will be put into "InputOAR" parameter
                Globals.parms.MergeCommandLine(args, null, "InputOAR");
            }
            catch (Exception e) {
                Globals.log.ErrorFormat("ERROR: bad parameters: " + e.Message);
                Globals.log.ErrorFormat(Invocation());
                return;
            }

            if (Globals.parms.P <bool>("Verbose"))
            {
                Globals.log.SetVerbose(Globals.parms.P <bool>("Verbose"));
            }

            if (!Globals.parms.P <bool>("Quiet"))
            {
                System.Console.WriteLine("Convoar v" + Globals.version
                                         + " built " + Globals.buildDate
                                         + " commit " + Globals.gitCommit
                                         );
            }

            // Validate parameters
            if (String.IsNullOrEmpty(Globals.parms.P <string>("InputOAR")))
            {
                Globals.log.ErrorFormat("An input OAR file must be specified");
                Globals.log.ErrorFormat(Invocation());
                return;
            }
            if (String.IsNullOrEmpty(Globals.parms.P <string>("OutputDir")))
            {
                _outputDir = "./out";
                Globals.log.DebugFormat("Output directory defaulting to {0}", _outputDir);
            }

            // Base asset storage system -- 'MemAssetService' is in-memory storage
            using (MemAssetService memAssetService = new MemAssetService()) {
                // 'assetManager' is the asset cache and fetching code -- where all the mesh,
                //    material, and instance information is stored for later processing.
                using (AssetManager assetManager = new AssetManager(memAssetService, Globals.log, Globals.parms)) {
                    try {
                        BScene bScene = await LoadOAR(memAssetService, assetManager);

                        Globals.contextName = bScene.name;

                        Globals.log.DebugFormat("{0} Scene created. name={1}, instances={2}",
                                                _logHeader, bScene.name, bScene.instances.Count);
                        Globals.log.DebugFormat("{0}    num assetFetcher.images={1}", _logHeader, assetManager.Assets.Images.Count);
                        Globals.log.DebugFormat("{0}    num assetFetcher.materials={1}", _logHeader, assetManager.Assets.Materials.Count);
                        Globals.log.DebugFormat("{0}    num assetFetcher.meshes={1}", _logHeader, assetManager.Assets.Meshes.Count);
                        Globals.log.DebugFormat("{0}    num assetFetcher.renderables={1}", _logHeader, assetManager.Assets.Renderables.Count);

                        if (ConvOAR.Globals.parms.P <bool>("AddTerrainMesh"))
                        {
                            ConvOAR.Globals.log.DebugFormat("{0} Adding terrain to scene", _logHeader);
                            bScene.instances.Add(bScene.terrainInstance);
                        }

                        if (ConvOAR.Globals.parms.P <bool>("TerrainOnly"))
                        {
                            ConvOAR.Globals.log.DebugFormat("{0} Clearing out scene so there's only terrain (TerrainOnly)", _logHeader);
                            bScene.instances.Clear();
                            bScene.instances.Add(bScene.terrainInstance);
                        }

                        /*
                         * // Perform any optimizations on the scene and its instances
                         * if (Globals.parms.P<bool>("DoMeshSimplification")) {
                         *  // TODO:
                         * }
                         * if (Globals.parms.P<bool>("DoSceneOptimizations")) {
                         *  using (BSceneManipulation optimizer = new BSceneManipulation()) {
                         *      bScene = optimizer.OptimizeScene(bScene);
                         *      Globals.log.DebugFormat("{0} merged BScene. numInstances={1}", _logHeader, bScene.instances.Count);
                         *  }
                         * }
                         */
                        if (Globals.parms.P <bool>("MergeSharedMaterialMeshes"))
                        {
                            using (BSceneManipulation optimizer = new BSceneManipulation(Globals.log, Globals.parms)) {
                                bScene = optimizer.RebuildSceneBasedOnSharedMeshes(bScene);
                                Globals.log.DebugFormat("{0} merged meshes in scene. numInstances={1}", _logHeader, bScene.instances.Count);
                            }
                        }

                        // Output the transformed scene as Gltf version 2
                        Gltf gltf = new Gltf(bScene.name, Globals.log, Globals.parms);

                        try {
                            gltf.LoadScene(bScene);

                            Globals.log.DebugFormat("{0}   num Gltf.nodes={1}", _logHeader, gltf.nodes.Count);
                            Globals.log.DebugFormat("{0}   num Gltf.meshes={1}", _logHeader, gltf.meshes.Count);
                            Globals.log.DebugFormat("{0}   num Gltf.materials={1}", _logHeader, gltf.materials.Count);
                            Globals.log.DebugFormat("{0}   num Gltf.images={1}", _logHeader, gltf.images.Count);
                            Globals.log.DebugFormat("{0}   num Gltf.accessor={1}", _logHeader, gltf.accessors.Count);
                            Globals.log.DebugFormat("{0}   num Gltf.buffers={1}", _logHeader, gltf.buffers.Count);
                            Globals.log.DebugFormat("{0}   num Gltf.bufferViews={1}", _logHeader, gltf.bufferViews.Count);
                        }
                        catch (Exception e) {
                            Globals.log.ErrorFormat("{0} Exception loading GltfScene: {1}", _logHeader, e);
                        }

                        try {
                            if (gltf.scenes.Count > 0)
                            {
                                string gltfFilename = gltf.GetFilename(gltf.IdentifyingString);
                                using (var outm = new MemoryStream()) {
                                    using (var outt = new StreamWriter(outm)) {
                                        gltf.ToJSON(outt);
                                    }
                                    await assetManager.AssetStorage.Store(gltfFilename, outm.ToArray());
                                }
                                gltf.WriteBinaryFiles(assetManager.AssetStorage);

                                if (Globals.parms.P <bool>("ExportTextures"))
                                {
                                    gltf.WriteImages(assetManager.AssetStorage);
                                }
                            }
                            else
                            {
                                Globals.log.ErrorFormat("{0} Not writing out GLTF because no scenes", _logHeader);
                            }
                        }
                        catch (Exception e) {
                            Globals.log.ErrorFormat("{0} Exception writing GltfScene: {1}", _logHeader, e);
                        }

                        /*
                         * // Output all the instances in the scene as individual GLTF files
                         * if (Globals.parms.P<bool>("ExportIndividualGltf")) {
                         *  bScene.instances.ForEach(instance => {
                         *      string instanceName = instance.handle.ToString();
                         *      Gltf gltf = new Gltf(instanceName);
                         *      gltf.persist.baseDirectory = bScene.name;
                         *      // gltf.persist.baseDirectory = PersistRules.JoinFilePieces(bScene.name, instanceName);
                         *      GltfScene gltfScene = new GltfScene(gltf, instanceName);
                         *      gltf.defaultScene = gltfScene;
                         *
                         *      Displayable rootDisp = instance.Representation;
                         *      GltfNode rootNode = GltfNode.GltfNodeFactory(gltf, gltfScene, rootDisp, assetFetcher);
                         *      rootNode.translation = instance.Position;
                         *      rootNode.rotation = instance.Rotation;
                         *
                         *      gltf.BuildAccessorsAndBuffers();
                         *      gltf.UpdateGltfv2ReferenceIndexes();
                         *
                         *      // After the building, get rid of the default scene name as we're not outputting a scene
                         *      gltf.defaultScene = null;
                         *
                         *      PersistRules.ResolveAndCreateDir(gltf.persist.filename);
                         *
                         *      using (StreamWriter outt = File.CreateText(gltf.persist.filename)) {
                         *          gltf.ToJSON(outt);
                         *      }
                         *      gltf.WriteBinaryFiles();
                         *
                         *      if (Globals.parms.P<bool>("ExportTextures")) {
                         *          gltf.WriteImages();
                         *      }
                         *  });
                         * }
                         */
                    }
                    catch (Exception e) {
                        Globals.log.ErrorFormat("{0} Global exception converting scene: {1}", _logHeader, e);
                        // A common error is not having all the DLLs for OpenSimulator. Print out what's missing.
                        if (e is ReflectionTypeLoadException refE)
                        {
                            foreach (var ee in refE.LoaderExceptions)
                            {
                                Globals.log.ErrorFormat("{0} reference exception: {1}", _logHeader, ee);
                            }
                        }
                    }
                }
            }
        }