GameObject LoadGltf(List <string> warnings) { // This is intended to be identical to using GltfModelBuilder, except synchronous. GameObject go; bool fromPoly = (m_Location.GetLocationType() == Location.Type.PolyAssetId); string localPath = m_Location.AbsolutePath; string assetLocation = Path.GetDirectoryName(localPath); // Synchronous, so don't use slow image loading var loader = new TiltBrushUriLoader(localPath, assetLocation, loadImages: false); try { ImportGltf.GltfImportResult result = ImportGltf.Import( localPath, loader, new ImportMaterialCollector(assetLocation, uniqueSeed: localPath), fromPoly ? kPolyGltfImportOptions : kGltfImportOptions); go = result.root; m_ImportMaterialCollector = (ImportMaterialCollector)result.materialCollector; } catch (Exception ex) { m_LoadError = new LoadError("Invalid data", ex.Message); go = null; m_AllowExport = false; Debug.LogException(ex); } m_AllowExport = (go != null); return(go); }
protected override GameObject DoUnityThreadWork(IDisposable state__, out IEnumerable <Null> meshEnumerable, out ImportMaterialCollector importMaterialCollector) { meshEnumerable = null; importMaterialCollector = null; GameObject rootObject = null; using (IDisposable state_ = state__) { var state = state_ as ImportGltf.ImportState; if (state != null) { string assetLocation = Path.GetDirectoryName(m_localPath); // EndImport doesn't try to use the loadImages functionality of UriLoader anyway. // It knows it's on the main thread, so chooses to use Unity's fast loading. var loader = new TiltBrushUriLoader(m_localPath, assetLocation, loadImages: false); ImportGltf.GltfImportResult result = ImportGltf.EndImport( state, loader, new ImportMaterialCollector(assetLocation, uniqueSeed: m_localPath), out meshEnumerable); if (result != null) { rootObject = result.root; importMaterialCollector = (ImportMaterialCollector)result.materialCollector; } } } IsValid = (rootObject != null); return(rootObject); }
public FbxReader(string path) { m_standardMaterial = ModelCatalog.m_Instance.m_ObjLoaderStandardMaterial; m_transparentMaterial = ModelCatalog.m_Instance.m_ObjLoaderTransparentMaterial; m_path = path; m_dir = Path.GetDirectoryName(path); m_collector = new ImportMaterialCollector(m_dir, m_path); }
/// Load model using FBX SDK. GameObject LoadFbx(List <string> warningsOut) { #if !FBX_SUPPORTED m_LoadError = new LoadError("fbx not supported"); return(null); #else try { var reader = new FbxReader(m_Location.AbsolutePath); var(gameObject, warnings, collector) = reader.Import(); warningsOut.AddRange(warnings); m_ImportMaterialCollector = collector; m_AllowExport = (m_ImportMaterialCollector != null); return(gameObject); } catch (Exception ex) { m_LoadError = new LoadError("Invalid data", ex.Message); m_AllowExport = false; Debug.LogException(ex); return(null); } #endif }
// Performs whatever portion of the import process that is left. // // Pass: // state - the value returned from DoBackgroundThreadWork. Ownership is transferred; // callee is responsible for Disposing it. // Returns: // GameObject - the root of the object hierarchy. // ImportMaterialCollector - the materials that were created, and info about them // IEnumerable<Null> - a coroutine that will be pumped to completion protected abstract GameObject DoUnityThreadWork( IDisposable state, out IEnumerable <Null> meshCreator, out ImportMaterialCollector importMaterialCollector);
/// Returns: /// bool - false if incomplete, true upon successful completion. /// GameObject - caller should check output GameObject to determine success. /// ImportMaterialCollector - non-null upon successful completion. /// Raises an exception on unsuccessful completion. public bool TryEndAsyncLoad(out GameObject root, out ImportMaterialCollector importMaterialCollector) { // Three things happen in this function. // 1: It waits to try and get the result of reading the model on a background thread // 2: It checks the rate limiter to make sure we don't have too many of these going on at once. // 3: It enumerates through, creating meshes for the model. These are time-limited so that // it will stop if it has taken too long in a single frame. root = null; importMaterialCollector = null; if (m_meshEnumerator == null) { IDisposable state; if (!m_stateReader.TryGetResult(out state)) { return(false); } IEnumerable <Null> enumerable; m_root = DoUnityThreadWork(state, out enumerable, out m_ImportMaterialCollector); // TODO: Possible bugs if DoUnityThreadWork ever did fail: // We assume the invariant that (root == null) == (IsValid == false) // We assume the invariant that m_ImportMaterialCollector != null // We don't dispose the GameObject or the enumerable // If the user calls TryEndAsyncLoad again we might try to call DoUnityThreadWork again if (m_root == null) { return(false); } m_meshEnumerator = enumerable.GetEnumerator(); m_root.SetActive(false); } // Yield until the limiter unblocks. // Multiple calls to TryGetResult above are harmless. if (sm_Limiter.IsBlocked()) { return(false); } // Finish constructing the actual game object. Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); long numTicks = (long)((Stopwatch.Frequency * kMeshMsPerFrame) / 1000); while (true) { if (!m_meshEnumerator.MoveNext()) { m_root.SetActive(true); root = m_root; importMaterialCollector = m_ImportMaterialCollector; stopwatch.Stop(); return(true); } if (stopwatch.ElapsedTicks > numTicks) { stopwatch.Stop(); return(false); } } }