public IEnumerator Load() { GLTFSceneImporter sceneImporter = null; ILoader loader = null; try { string directoryPath = URIHelper.GetDirectoryName(GLTFUri); loader = new WebRequestLoader(directoryPath); sceneImporter = new GLTFSceneImporter( URIHelper.GetFileFromUri(new Uri(GLTFUri)), loader ); sceneImporter.SceneParent = gameObject.transform; sceneImporter.Collider = Collider; sceneImporter.MaximumLod = MaximumLod; sceneImporter.Timeout = Timeout; sceneImporter.isMultithreaded = Multithreaded; sceneImporter.CustomShaderName = shaderOverride ? shaderOverride.name : null; yield return(sceneImporter.LoadScene(-1)); // Override the shaders on all materials if a shader is provided if (shaderOverride != null) { Renderer[] renderers = gameObject.GetComponentsInChildren <Renderer>(); foreach (Renderer renderer in renderers) { renderer.sharedMaterial.shader = shaderOverride; } } if (gameObject.GetComponentInChildren <Animation>() != null) { anim = gameObject.GetComponentInChildren <Animation>(); } if (anim != null) { anim.Play(); } } finally { if (loader != null) { sceneImporter.Dispose(); sceneImporter = null; loader = null; } } }
IEnumerator Start() { ILoader loader = new WebRequestLoader(URIHelper.GetDirectoryName(Url)); var sceneImporter = new GLTFSceneImporter( URIHelper.GetFileFromUri(new Uri(Url)), loader ); sceneImporter.SceneParent = gameObject.transform; sceneImporter.isMultithreaded = Multithreaded; yield return(sceneImporter.LoadScene(-1)); IntegrationTest.Pass(); }
private void Awake() { GameObject timeProvidersGo = new GameObject("-TimeProvider"); SimpleTimeProvider mainCoroutineTimeProvider = timeProvidersGo.AddComponent <SimpleTimeProvider>(); CoroutineManager coroutineManager = new CoroutineManager(); coroutineManager.TimeProvider = mainCoroutineTimeProvider; resourceStorage = new ResourceStorage(100); WebRequestLoader webLoader = new WebRequestLoader(coroutineManager); webLoader.RegisterResourceCreator(new TextureDataCreator()); webLoader.RegisterResourceCreator(new StringDataCreator()); resourceStorage.RegisterResourceLoader(webLoader); }
public IEnumerator Load() { GLTFSceneImporter sceneImporter = null; ILoader loader = null; if (UseStream) { // Path.Combine treats paths that start with the separator character // as absolute paths, ignoring the first path passed in. This removes // that character to properly handle a filename written with it. GLTFUri = GLTFUri.TrimStart(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); string fullPath = Path.Combine(Application.streamingAssetsPath, GLTFUri); string directoryPath = URIHelper.GetDirectoryName(fullPath); loader = new FileLoader(directoryPath); sceneImporter = new GLTFSceneImporter( Path.GetFileName(GLTFUri), loader ); } else { string directoryPath = URIHelper.GetDirectoryName(GLTFUri); loader = new WebRequestLoader(directoryPath); sceneImporter = new GLTFSceneImporter( URIHelper.GetFileFromUri(new Uri(GLTFUri)), loader ); } sceneImporter.SceneParent = gameObject.transform; sceneImporter.Collider = Collider; sceneImporter.MaximumLod = MaximumLod; sceneImporter.CustomShaderName = shaderOverride ? shaderOverride.name : null; yield return(sceneImporter.LoadScene(-1, Multithreaded)); // Override the shaders on all materials if a shader is provided if (shaderOverride != null) { Renderer[] renderers = gameObject.GetComponentsInChildren <Renderer>(); foreach (Renderer renderer in renderers) { renderer.sharedMaterial.shader = shaderOverride; } } SendMessageUpwards("GLTFLoadComplete", gameObject, SendMessageOptions.DontRequireReceiver); }
private IEnumerator InitProcess() { Debug.Log("Start Init process"); resourceStorage = new ResourceStorage(100); var manifestLoader = new WebRequestLoader(coroutineManager); manifestLoader.RegisterResourceCreator(new StringDataCreator()); UnityResourceFromBundleLoader resFromBundlesLoader = new UnityResourceFromBundleLoader(coroutineManager); WebRequestBundlesLoader bundlesLoader = new WebRequestBundlesLoader(serverStaticPath, coroutineManager); resourceStorage.RegisterResourceLoader(manifestLoader); resourceStorage.RegisterResourceLoader(resFromBundlesLoader); resourceStorage.RegisterResourceLoader(bundlesLoader); //Load Manifest ManifestResourceHolder manifestHolder = new ManifestResourceHolder(); var manifestLoadingOperation = resourceStorage.LoadResource <string>(manifestHolder, Path.Combine(serverStaticPath, manifestName)); yield return(manifestLoadingOperation); Debug.Log("Manifest loaded: " + manifestLoadingOperation.Resource); var jsonSerializer = new JsonSerializer(new JsonSerializerSettings { Formatting = Formatting.Indented }, Encoding.UTF8); var manifestAsJson = jsonSerializer.DeserializeString <AssetBundleManifest>(manifestLoadingOperation.Resource); bundlesLoader.Manifest.AddManifestPart(manifestAsJson); resourceStorage.ReleaseAllOwnerResourcesFromCache(manifestHolder); _prefabsResourceHolder = new PrefabsResourceHolder(); Debug.Log("Init process pass"); }
private async void DownloadSampleModelList() { var pathRoot = serializedObject.FindProperty(SampleModelList.PathRootFieldName).stringValue; var manifestRelativePath = serializedObject.FindProperty(SampleModelList.ManifestRelativePathFieldName).stringValue; var loader = new WebRequestLoader(pathRoot); Stream stream; try { stream = await loader.LoadStreamAsync(manifestRelativePath); } catch (HttpRequestException) { Debug.LogError($"Failed to download sample model list manifest from: {pathRoot}{manifestRelativePath}", serializedObject.targetObject); throw; } var jsonReader = CreateJsonReaderFromStream(stream); jsonReader.Read(); var listType = SampleModelListParser.DetermineListSource(jsonReader); jsonReader = CreateJsonReaderFromStream(stream); jsonReader.Read(); if (listType == SampleModelListParser.ListType.SampleModels) { models = SampleModelListParser.ParseSampleModels(jsonReader); } else { models = SampleModelListParser.ParseAssetGeneratorModels(jsonReader); } }
public async Task Load() { asyncCoroutineHelper = gameObject.AddComponent <AsyncCoroutineHelper>(); GLTFSceneImporter sceneImporter = null; ILoader loader = null; try { if (UseStream) { // Path.Combine treats paths that start with the separator character // as absolute paths, ignoring the first path passed in. This removes // that character to properly handle a filename written with it. GLTFUri = GLTFUri.TrimStart(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); string fullPath = Path.Combine(Application.streamingAssetsPath, GLTFUri); string directoryPath = URIHelper.GetDirectoryName(fullPath); loader = new FileLoader(directoryPath); sceneImporter = new GLTFSceneImporter( Path.GetFileName(GLTFUri), loader, asyncCoroutineHelper ); } else { string directoryPath = URIHelper.GetDirectoryName(GLTFUri); loader = new WebRequestLoader(directoryPath, asyncCoroutineHelper); sceneImporter = new GLTFSceneImporter( URIHelper.GetFileFromUri(new Uri(GLTFUri)), loader, asyncCoroutineHelper ); } sceneImporter.SceneParent = gameObject.transform; sceneImporter.Collider = Collider; sceneImporter.MaximumLod = MaximumLod; sceneImporter.Timeout = Timeout; sceneImporter.isMultithreaded = Multithreaded; sceneImporter.CustomShaderName = shaderOverride ? shaderOverride.name : null; await sceneImporter.LoadSceneAsync(-1); // Override the shaders on all materials if a shader is provided if (shaderOverride != null) { Renderer[] renderers = gameObject.GetComponentsInChildren <Renderer>(); foreach (Renderer renderer in renderers) { renderer.sharedMaterial.shader = shaderOverride; } } } finally { if (loader != null) { sceneImporter?.Dispose(); sceneImporter = null; loader = null; } } }
private async Task <IList <UnityEngine.Object> > LoadGltfFromStream(WebRequestLoader loader, Stream stream, ColliderType colliderType) { var assets = new List <UnityEngine.Object>(30); // pre-parse glTF document so we can get a scene count // run this on a threadpool thread so that the Unity main thread is not blocked GLTF.Schema.GLTFRoot gltfRoot = null; try { await Task.Run(() => { GLTF.GLTFParser.ParseJson(stream, out gltfRoot); }); } catch (Exception e) { Debug.LogError(e); } if (gltfRoot == null) { throw new GLTFLoadException("Failed to parse glTF"); } stream.Position = 0; using (GLTFSceneImporter importer = MREAPI.AppsAPI.GLTFImporterFactory.CreateImporter(gltfRoot, loader, _asyncHelper, stream)) { importer.SceneParent = MREAPI.AppsAPI.AssetCache.CacheRootGO.transform; importer.Collider = colliderType.ToGLTFColliderType(); // load textures if (gltfRoot.Textures != null) { for (var i = 0; i < gltfRoot.Textures.Count; i++) { await importer.LoadTextureAsync(gltfRoot.Textures[i], i, true); var texture = importer.GetTexture(i); texture.name = gltfRoot.Textures[i].Name ?? $"texture:{i}"; assets.Add(texture); } } // load meshes if (gltfRoot.Meshes != null) { var cancellationSource = new System.Threading.CancellationTokenSource(); for (var i = 0; i < gltfRoot.Meshes.Count; i++) { var mesh = await importer.LoadMeshAsync(i, cancellationSource.Token); mesh.name = gltfRoot.Meshes[i].Name ?? $"mesh:{i}"; assets.Add(mesh); } } // load materials if (gltfRoot.Materials != null) { for (var i = 0; i < gltfRoot.Materials.Count; i++) { var matdef = gltfRoot.Materials[i]; var material = await importer.LoadMaterialAsync(i); material.name = matdef.Name ?? $"material:{i}"; assets.Add(material); } } // load prefabs if (gltfRoot.Scenes != null) { for (var i = 0; i < gltfRoot.Scenes.Count; i++) { await importer.LoadSceneAsync(i).ConfigureAwait(true); GameObject rootObject = importer.LastLoadedScene; rootObject.name = gltfRoot.Scenes[i].Name ?? $"scene:{i}"; var animation = rootObject.GetComponent <UnityEngine.Animation>(); if (animation != null) { animation.playAutomatically = false; // initialize mapping so we know which gameobjects are targeted by which animation clips var mapping = rootObject.AddComponent <PrefabAnimationTargets>(); mapping.Initialize(gltfRoot, i); } MWGOTreeWalker.VisitTree(rootObject, (go) => { go.layer = MREAPI.AppsAPI.LayerApplicator.DefaultLayer; }); assets.Add(rootObject); } } } return(assets); }
private async Task <IList <Asset> > LoadAssetsFromGLTF(AssetSource source, Guid containerId, ColliderType colliderType) { WebRequestLoader loader = null; Stream stream = null; source.ParsedUri = new Uri(_app.ServerAssetUri, source.ParsedUri); var rootUri = URIHelper.GetDirectoryName(source.ParsedUri.AbsoluteUri); var cachedVersion = MREAPI.AppsAPI.AssetCache.SupportsSync ? MREAPI.AppsAPI.AssetCache.GetVersionSync(source.ParsedUri) : await MREAPI.AppsAPI.AssetCache.GetVersion(source.ParsedUri); // Wait asynchronously until the load throttler lets us through. using (var scope = await AssetLoadThrottling.AcquireLoadScope()) { // set up loader loader = new WebRequestLoader(rootUri); if (!string.IsNullOrEmpty(cachedVersion)) { loader.BeforeRequestCallback += (msg) => { if (msg.RequestUri == source.ParsedUri) { msg.Headers.Add("If-None-Match", cachedVersion); } }; } // download root gltf file, check for cache hit try { stream = await loader.LoadStreamAsync(URIHelper.GetFileFromUri(source.ParsedUri)); source.Version = loader.LastResponse.Headers.ETag?.Tag ?? ""; } catch (HttpRequestException) { if (loader.LastResponse.StatusCode == System.Net.HttpStatusCode.NotModified) { source.Version = cachedVersion; } else { throw; } } } IList <Asset> assetDefs = new List <Asset>(30); DeterministicGuids guidGenerator = new DeterministicGuids(UtilMethods.StringToGuid( $"{containerId}:{source.ParsedUri.AbsoluteUri}")); IList <UnityEngine.Object> assets; // fetch assets from glTF stream or cache if (source.Version != cachedVersion) { assets = await LoadGltfFromStream(loader, stream, colliderType); MREAPI.AppsAPI.AssetCache.StoreAssets(source.ParsedUri, assets, source.Version); } else { var assetsEnum = MREAPI.AppsAPI.AssetCache.SupportsSync ? MREAPI.AppsAPI.AssetCache.LeaseAssetsSync(source.ParsedUri) : await MREAPI.AppsAPI.AssetCache.LeaseAssets(source.ParsedUri); assets = assetsEnum.ToList(); } // catalog assets int textureIndex = 0, meshIndex = 0, materialIndex = 0, prefabIndex = 0; foreach (var asset in assets) { var assetDef = GenerateAssetPatch(asset, guidGenerator.Next()); assetDef.Name = asset.name; string internalId = null; if (asset is UnityEngine.Texture) { internalId = $"texture:{textureIndex++}"; } else if (asset is UnityEngine.Mesh) { internalId = $"mesh:{meshIndex++}"; } else if (asset is UnityEngine.Material) { internalId = $"material:{materialIndex++}"; } else if (asset is GameObject) { internalId = $"scene:{prefabIndex++}"; } assetDef.Source = new AssetSource(source.ContainerType, source.ParsedUri.AbsoluteUri, internalId, source.Version); ColliderGeometry colliderGeo = null; if (asset is UnityEngine.Mesh mesh) { colliderGeo = colliderType == ColliderType.Mesh ? (ColliderGeometry) new MeshColliderGeometry() { MeshId = assetDef.Id } : (ColliderGeometry) new BoxColliderGeometry() { Size = (mesh.bounds.size * 0.8f).CreateMWVector3(), Center = mesh.bounds.center.CreateMWVector3() }; } _app.AssetManager.Set(assetDef.Id, containerId, asset, colliderGeo, assetDef.Source); assetDefs.Add(assetDef); } return(assetDefs); }
public async Task Load() { asyncCoroutineHelper = gameObject.GetComponent <AsyncCoroutineHelper>() ?? gameObject.AddComponent <AsyncCoroutineHelper>(); GLTFSceneImporter sceneImporter = null; ILoader loader = null; try { if (UseStream) { // Path.Combine treats paths that start with the separator character // as absolute paths, ignoring the first path passed in. This removes // that character to properly handle a filename written with it. GLTFUri = GLTFUri.TrimStart(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); string fullPath; if (AppendStreamingAssets) { fullPath = Path.Combine(Application.streamingAssetsPath, GLTFUri); } else { fullPath = GLTFUri; } string directoryPath = URIHelper.GetDirectoryName(fullPath); loader = new FileLoader(directoryPath); sceneImporter = new GLTFSceneImporter( Path.GetFileName(GLTFUri), loader, asyncCoroutineHelper ); } else { string directoryPath = URIHelper.GetDirectoryName(GLTFUri); loader = new WebRequestLoader(directoryPath); sceneImporter = new GLTFSceneImporter( URIHelper.GetFileFromUri(new Uri(GLTFUri)), loader, asyncCoroutineHelper ); } sceneImporter.SceneParent = gameObject.transform; sceneImporter.Collider = Collider; sceneImporter.MaximumLod = MaximumLod; sceneImporter.Timeout = Timeout; sceneImporter.IsMultithreaded = Multithreaded; sceneImporter.CustomShaderName = shaderOverride ? shaderOverride.name : null; if (MaterialsOnly) { var mat = await sceneImporter.LoadMaterialAsync(0); var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.transform.SetParent(gameObject.transform); var renderer = cube.GetComponent <Renderer>(); renderer.sharedMaterial = mat; } else { await sceneImporter.LoadSceneAsync(); } // Override the shaders on all materials if a shader is provided if (shaderOverride != null) { Renderer[] renderers = gameObject.GetComponentsInChildren <Renderer>(); foreach (Renderer renderer in renderers) { renderer.sharedMaterial.shader = shaderOverride; } } if (PlayAnimationOnLoad) { Animation[] animations = sceneImporter.LastLoadedScene.GetComponents <Animation>(); foreach (Animation anim in animations) { anim.Play(); } } } finally { if (loader != null) { sceneImporter?.Dispose(); sceneImporter = null; loader = null; } } }
public IEnumerator LoadAssetCoroutine() { if (!string.IsNullOrEmpty(GLTFUri)) { if (VERBOSE) { Debug.Log("LoadAssetCoroutine() GLTFUri ->" + GLTFUri); } asyncCoroutineHelper = gameObject.GetComponent <AsyncCoroutineHelper>() ?? gameObject.AddComponent <AsyncCoroutineHelper>(); sceneImporter = null; ILoader loader = null; Destroy(loadedAssetRootGameObject); try { if (UseStream) { // Path.Combine treats paths that start with the separator character // as absolute paths, ignoring the first path passed in. This removes // that character to properly handle a filename written with it. GLTFUri = GLTFUri.TrimStart(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); string fullPath = Path.Combine(Application.streamingAssetsPath, GLTFUri); string directoryPath = URIHelper.GetDirectoryName(fullPath); loader = new FileLoader(directoryPath); sceneImporter = new GLTFSceneImporter( Path.GetFileName(GLTFUri), loader, asyncCoroutineHelper ); } else { loader = new WebRequestLoader(""); if (OnWebRequestStartEvent != null) { (loader as WebRequestLoader).OnLoadStreamStart += OnWebRequestStartEvent; } sceneImporter = new GLTFSceneImporter( GLTFUri, loader, asyncCoroutineHelper ); } if (sceneImporter.CreatedObject != null) { Destroy(sceneImporter.CreatedObject); } sceneImporter.SceneParent = gameObject.transform; sceneImporter.Collider = Collider; sceneImporter.maximumLod = MaximumLod; sceneImporter.Timeout = Timeout; sceneImporter.isMultithreaded = Multithreaded; sceneImporter.useMaterialTransition = UseVisualFeedback; sceneImporter.CustomShaderName = shaderOverride ? shaderOverride.name : null; sceneImporter.LoadingTextureMaterial = LoadingTextureMaterial; sceneImporter.initialVisibility = initialVisibility; sceneImporter.addMaterialsToPersistentCaching = addMaterialsToPersistentCaching; float time = Time.realtimeSinceStartup; queueCount++; state = State.QUEUED; Func <bool> funcTestDistance = () => TestDistance(); yield return(new WaitUntil(funcTestDistance)); queueCount--; totalDownloadedCount++; IncrementDownloadCount(); state = State.DOWNLOADING; yield return(sceneImporter.LoadScene(-1)); state = State.COMPLETED; DecrementDownloadCount(); // Override the shaders on all materials if a shader is provided if (shaderOverride != null) { Renderer[] renderers = gameObject.GetComponentsInChildren <Renderer>(); foreach (Renderer renderer in renderers) { renderer.sharedMaterial.shader = shaderOverride; } } } finally { if (loader != null) { if (sceneImporter == null) { Debug.Log("sceneImporter is null, could be due to an invalid URI.", this); } else { loadedAssetRootGameObject = sceneImporter.CreatedObject; sceneImporter?.Dispose(); sceneImporter = null; } if (OnWebRequestStartEvent != null) { (loader as WebRequestLoader).OnLoadStreamStart -= OnWebRequestStartEvent; OnWebRequestStartEvent = null; } loader = null; } alreadyLoadedAsset = true; OnFinishedLoadingAsset?.Invoke(); } } else { Debug.Log("couldn't load GLTF because url is empty"); } CoroutineStarter.Stop(loadingRoutine); loadingRoutine = null; Destroy(loadingPlaceholder); Destroy(this); }
private async Task <IList <Asset> > LoadAssetsFromGLTF(AssetSource source, Guid containerId, ColliderType colliderType) { IList <Asset> assets = new List <Asset>(); DeterministicGuids guidGenerator = new DeterministicGuids(UtilMethods.StringToGuid( $"{containerId}:{source.ParsedUri.AbsoluteUri}")); // download file UtilMethods.GetUrlParts(source.ParsedUri.AbsoluteUri, out string rootUrl, out string filename); var loader = new WebRequestLoader(rootUrl); await loader.LoadStream(filename); // pre-parse glTF document so we can get a scene count // TODO: run this in thread GLTF.GLTFParser.ParseJson(loader.LoadedStream, out GLTF.Schema.GLTFRoot gltfRoot); GLTFSceneImporter importer = MREAPI.AppsAPI.GLTFImporterFactory.CreateImporter(gltfRoot, loader, _asyncHelper, loader.LoadedStream); importer.SceneParent = MREAPI.AppsAPI.AssetCache.CacheRootGO().transform; importer.Collider = colliderType.ToGLTFColliderType(); // load prefabs if (gltfRoot.Scenes != null) { for (var i = 0; i < gltfRoot.Scenes.Count; i++) { await importer.LoadSceneAsync(i); GameObject rootObject = importer.LastLoadedScene; rootObject.name = gltfRoot.Scenes[i].Name ?? $"scene:{i}"; MWGOTreeWalker.VisitTree(rootObject, (go) => { go.layer = UnityConstants.ActorLayerIndex; }); var def = GenerateAssetPatch(rootObject, guidGenerator.Next()); def.Name = rootObject.name; def.Source = new AssetSource(source.ContainerType, source.Uri, $"scene:{i}"); MREAPI.AppsAPI.AssetCache.CacheAsset(rootObject, def.Id, containerId, source); assets.Add(def); } } // load textures if (gltfRoot.Textures != null) { for (var i = 0; i < gltfRoot.Textures.Count; i++) { await importer.LoadTextureAsync(gltfRoot.Textures[i], i, true); var texture = importer.GetTexture(i); texture.name = gltfRoot.Textures[i].Name ?? $"texture:{i}"; var asset = GenerateAssetPatch(texture, guidGenerator.Next()); asset.Name = texture.name; asset.Source = new AssetSource(source.ContainerType, source.Uri, $"texture:{i}"); MREAPI.AppsAPI.AssetCache.CacheAsset(texture, asset.Id, containerId, source); assets.Add(asset); } } // load materials if (gltfRoot.Materials != null) { for (var i = 0; i < gltfRoot.Materials.Count; i++) { var matdef = gltfRoot.Materials[i]; var material = await importer.LoadMaterialAsync(i); material.name = matdef.Name ?? $"material:{i}"; var asset = GenerateAssetPatch(material, guidGenerator.Next()); asset.Name = material.name; asset.Source = new AssetSource(source.ContainerType, source.Uri, $"material:{i}"); MREAPI.AppsAPI.AssetCache.CacheAsset(material, asset.Id, containerId, source); assets.Add(asset); } } importer.Dispose(); return(assets); }
private async Task <IList <Asset> > LoadAssetsFromGLTF(AssetSource source, Guid containerId, ColliderType colliderType) { IList <Asset> assets = new List <Asset>(); DeterministicGuids guidGenerator = new DeterministicGuids(UtilMethods.StringToGuid( $"{containerId}:{source.ParsedUri.AbsoluteUri}")); // download file var rootUrl = URIHelper.GetDirectoryName(source.ParsedUri.AbsoluteUri); var loader = new WebRequestLoader(rootUrl); var stream = await loader.LoadStreamAsync(URIHelper.GetFileFromUri(source.ParsedUri)); // pre-parse glTF document so we can get a scene count // TODO: run this in thread GLTF.GLTFParser.ParseJson(stream, out GLTF.Schema.GLTFRoot gltfRoot); stream.Position = 0; GLTFSceneImporter importer = MREAPI.AppsAPI.GLTFImporterFactory.CreateImporter(gltfRoot, loader, _asyncHelper, stream); importer.SceneParent = MREAPI.AppsAPI.AssetCache.CacheRootGO().transform; importer.Collider = colliderType.ToGLTFColliderType(); // load textures if (gltfRoot.Textures != null) { for (var i = 0; i < gltfRoot.Textures.Count; i++) { await importer.LoadTextureAsync(gltfRoot.Textures[i], i, true); var texture = importer.GetTexture(i); texture.name = gltfRoot.Textures[i].Name ?? $"texture:{i}"; var asset = GenerateAssetPatch(texture, guidGenerator.Next()); asset.Name = texture.name; asset.Source = new AssetSource(source.ContainerType, source.Uri, $"texture:{i}"); MREAPI.AppsAPI.AssetCache.CacheAsset(texture, asset.Id, containerId, source); assets.Add(asset); } } // load meshes if (gltfRoot.Meshes != null) { var cancellationSource = new System.Threading.CancellationTokenSource(); for (var i = 0; i < gltfRoot.Meshes.Count; i++) { var mesh = await importer.LoadMeshAsync(i, cancellationSource.Token); mesh.name = gltfRoot.Meshes[i].Name ?? $"mesh:{i}"; var asset = GenerateAssetPatch(mesh, guidGenerator.Next()); asset.Name = mesh.name; asset.Source = new AssetSource(source.ContainerType, source.Uri, $"mesh:{i}"); var colliderGeo = colliderType == ColliderType.Mesh ? (ColliderGeometry) new MeshColliderGeometry() { MeshId = asset.Id } : (ColliderGeometry) new BoxColliderGeometry() { Size = (mesh.bounds.size * 0.8f).CreateMWVector3() }; MREAPI.AppsAPI.AssetCache.CacheAsset(mesh, asset.Id, containerId, source, colliderGeo); assets.Add(asset); } } // load materials if (gltfRoot.Materials != null) { for (var i = 0; i < gltfRoot.Materials.Count; i++) { var matdef = gltfRoot.Materials[i]; var material = await importer.LoadMaterialAsync(i); material.name = matdef.Name ?? $"material:{i}"; var asset = GenerateAssetPatch(material, guidGenerator.Next()); asset.Name = material.name; asset.Source = new AssetSource(source.ContainerType, source.Uri, $"material:{i}"); MREAPI.AppsAPI.AssetCache.CacheAsset(material, asset.Id, containerId, source); assets.Add(asset); } } // load prefabs if (gltfRoot.Scenes != null) { for (var i = 0; i < gltfRoot.Scenes.Count; i++) { await importer.LoadSceneAsync(i).ConfigureAwait(true); GameObject rootObject = importer.LastLoadedScene; rootObject.name = gltfRoot.Scenes[i].Name ?? $"scene:{i}"; var animation = rootObject.GetComponent <UnityEngine.Animation>(); if (animation != null) { animation.playAutomatically = false; // initialize mapping so we know which gameobjects are targeted by which animation clips var mapping = rootObject.AddComponent <PrefabAnimationTargets>(); mapping.Initialize(gltfRoot, i); } MWGOTreeWalker.VisitTree(rootObject, (go) => { go.layer = MREAPI.AppsAPI.LayerApplicator.DefaultLayer; }); var def = GenerateAssetPatch(rootObject, guidGenerator.Next()); def.Name = rootObject.name; def.Source = new AssetSource(source.ContainerType, source.Uri, $"scene:{i}"); MREAPI.AppsAPI.AssetCache.CacheAsset(rootObject, def.Id, containerId, source); assets.Add(def); } } importer.Dispose(); return(assets); }
private async Task <IList <Godot.Object> > LoadGltfFromStream(WebRequestLoader loader, Stream stream, ColliderType colliderType) { var assets = new List <Godot.Object>(30); // pre-parse glTF document so we can get a scene count // run this on a threadpool thread so that the Unity main thread is not blocked GLTF.Schema.GLTFRoot gltfRoot = null; try { await Task.Run(() => { GLTF.GLTFParser.ParseJson(stream, out gltfRoot); }); } catch (Exception e) { GD.PrintErr(e); } if (gltfRoot == null) { throw new GLTFLoadException("Failed to parse glTF"); } stream.Position = 0; using (GLTFSceneImporter importer = MREAPI.AppsAPI.GLTFImporterFactory.CreateImporter(gltfRoot, loader, null /* FIXME _asyncHelper*/, stream)) { importer.SceneParent = MREAPI.AppsAPI.AssetCache.CacheRootGO; importer.Collider = colliderType.ToGLTFColliderType(); if (gltfRoot.Textures != null) { for (var i = 0; i < gltfRoot.Textures.Count; i++) { await importer.LoadTextureAsync(gltfRoot.Textures[i], i, true); var texture = importer.GetTexture(i); texture.ResourceName = gltfRoot.Textures[i].Name ?? $"texture:{i}"; assets.Add(texture); } } // load meshes if (gltfRoot.Meshes != null) { var cancellationSource = new System.Threading.CancellationTokenSource(); for (var i = 0; i < gltfRoot.Meshes.Count; i++) { var mesh = await importer.LoadMeshAsync(i, cancellationSource.Token); mesh.ResourceName = gltfRoot.Meshes[i].Name ?? $"mesh:{i}"; assets.Add(mesh); } } // load materials if (gltfRoot.Materials != null) { for (var i = 0; i < gltfRoot.Materials.Count; i++) { var matdef = gltfRoot.Materials[i]; var material = await importer.LoadMaterialAsync(i); material.ResourceName = matdef.Name ?? $"material:{i}"; assets.Add(material); } } // load prefabs if (gltfRoot.Scenes != null) { for (var i = 0; i < gltfRoot.Scenes.Count; i++) { await importer.LoadSceneAsync(i).ConfigureAwait(true); Node rootObject = importer.LastLoadedScene; rootObject.Name = gltfRoot.Scenes[i].Name ?? $"scene:{i}"; var animation = rootObject.GetChild <Godot.AnimationPlayer>(); if (animation != null) { animation.AssignedAnimation = null; // initialize mapping so we know which gameobjects are targeted by which animation clips var mapping = new PrefabAnimationTargets(); rootObject.AddChild(mapping); mapping.Initialize(gltfRoot, i); } assets.Add(rootObject); } } } return(assets); }