Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }