internal async Task <IList <Actor> > CreateFromGLTF(string resourceUrl, string assetName, Guid?parentId, ColliderType colliderType)
        {
            UtilMethods.GetUrlParts(resourceUrl, out string rootUrl, out string filename);
            var loader   = new WebRequestLoader(rootUrl);
            var importer = MREAPI.AppsAPI.GLTFImporterFactory.CreateImporter(filename, loader, _asyncHelper);

            var parent = _app.FindActor(parentId ?? Guid.Empty) as Actor;

            importer.SceneParent = parent?.transform ?? _app.SceneRoot.transform;

            importer.Collider = colliderType.ToGLTFColliderType();

            await importer.LoadSceneAsync().ConfigureAwait(true);

            // note: actor properties are set in App#ProcessCreatedActors
            IList <Actor> actors = new List <Actor>();

            importer.LastLoadedScene.name = assetName;
            MWGOTreeWalker.VisitTree(importer.LastLoadedScene, (go) =>
            {
                go.layer = UnityConstants.ActorLayerIndex;
                actors.Add(go.AddComponent <Actor>());
            });

            importer.Dispose();

            return(actors);
        }
예제 #2
0
        internal IList <Actor> CreateFromPrefab(Guid prefabId, Guid?parentId, CollisionLayer?collisionLayer)
        {
            GameObject prefab = MREAPI.AppsAPI.AssetCache.GetAsset(prefabId) as GameObject;

            GameObject instance = UnityEngine.Object.Instantiate(
                prefab, GetGameObjectFromParentId(parentId).transform, false);

            // note: actor properties are set in App#ProcessCreatedActors
            var actorList = new List <Actor>();

            MWGOTreeWalker.VisitTree(instance, go =>
            {
                var collider = go.GetComponent <UnityEngine.Collider>();
                if (collider != null)
                {
                    MREAPI.AppsAPI.LayerApplicator.ApplyLayerToCollider(collisionLayer, collider);
                }
                else
                {
                    go.layer = MREAPI.AppsAPI.LayerApplicator.DefaultLayer;
                }

                actorList.Add(go.AddComponent <Actor>());
            });

            return(actorList);
        }
        private Asset GenerateAssetPatch(UnityEngine.Object unityAsset, Guid id)
        {
            if (unityAsset is GameObject go)
            {
                int actorCount = 0;
                MWGOTreeWalker.VisitTree(go, _ =>
                {
                    actorCount++;
                });

                return(new Asset
                {
                    Id = id,
                    Prefab = new Prefab()
                    {
                        ActorCount = actorCount
                    }
                });
            }
            else if (unityAsset is UnityEngine.Material mat)
            {
                return(new Asset()
                {
                    Id = id,
                    Material = MREAPI.AppsAPI.MaterialPatcher.GeneratePatch(mat)
                });
            }
            else if (unityAsset is UnityEngine.Texture tex)
            {
                return(new Asset()
                {
                    Id = id,
                    Texture = new MWTexture()
                    {
                        Resolution = new Vector2Patch()
                        {
                            X = tex.width,
                            Y = tex.height
                        },
                        WrapModeU = tex.wrapModeU,
                        WrapModeV = tex.wrapModeV
                    }
                });
            }
            else if (unityAsset is AudioClip sound)
            {
                return(new Asset()
                {
                    Id = id,
                    Sound = new MWSound()
                    {
                        Duration = sound.length
                    }
                });
            }
            else
            {
                throw new Exception($"Asset {id} is not patchable, or not of the right type!");
            }
        }
예제 #4
0
        internal IList <Actor> CreateFromPrefab(Guid prefabId, Guid?parentId, CollisionLayer?collisionLayer)
        {
            var     asset  = _app.AssetManager.GetById(prefabId)?.Asset as Node;
            Spatial prefab = asset.Duplicate() as Spatial;

            // restore assigned animation.
            var animationPlayer = asset.GetChild <AnimationPlayer>();

            if (animationPlayer != null)
            {
                var prefabAnimationPlayer = prefab.GetNode <AnimationPlayer>(animationPlayer.Name);
                prefabAnimationPlayer.AssignedAnimation = animationPlayer.AssignedAnimation;
            }

            Spatial parent = GetGameObjectFromParentId(parentId);

            parent.AddChild(prefab);

            // copy animation target mapping
            var sourceMap = prefab.GetChild <PrefabAnimationTargets>();
            var destMap   = asset.GetChild <PrefabAnimationTargets>();

            if (sourceMap != null && destMap != null)
            {
                destMap.AnimationTargets = sourceMap.AnimationTargets;
            }

            // note: actor properties are set in App#ProcessCreatedActors
            var actorList = new List <Actor>();

            MWGOTreeWalker.VisitTree(prefab, go =>
            {
                var collider = go.GetChild <Area>();
                if (collider != null)
                {
                    MREAPI.AppsAPI.LayerApplicator.ApplyLayerToCollider(collisionLayer, collider);
                }

                if (go is Spatial)
                {
                    var newActor = Actor.Instantiate((Spatial)go);
                    actorList.Add(newActor);
                }
            });

            return(actorList);
        }
        internal IList <Actor> CreateFromPrefab(Guid prefabId, Guid?parentId)
        {
            GameObject prefab = MREAPI.AppsAPI.AssetCache.GetAsset(prefabId) as GameObject;

            GameObject instance = UnityEngine.Object.Instantiate(
                prefab, GetGameObjectFromParentId(parentId).transform, false);

            // note: actor properties are set in App#ProcessCreatedActors
            var actorList = new List <Actor>();

            MWGOTreeWalker.VisitTree(instance, go =>
            {
                go.layer = UnityConstants.ActorLayerIndex;
                actorList.Add(go.AddComponent <Actor>());
            });

            return(actorList);
        }
예제 #6
0
        internal IList <Actor> CreateFromPrefab(Guid prefabId, Guid?parentId, CollisionLayer?collisionLayer)
        {
            GameObject prefab = _app.AssetManager.GetById(prefabId)?.Asset as GameObject;

            GameObject instance = UnityEngine.Object.Instantiate(
                prefab, GetGameObjectFromParentId(parentId).transform, false);

            // copy animation target mapping
            var sourceMap = prefab.GetComponent <PrefabAnimationTargets>();
            var destMap   = instance.GetComponent <PrefabAnimationTargets>();

            if (sourceMap != null && destMap != null)
            {
                destMap.AnimationTargets = sourceMap.AnimationTargets;
            }

            // note: actor properties are set in App#ProcessCreatedActors
            var actorList = new List <Actor>();

            MWGOTreeWalker.VisitTree(instance, go =>
            {
                var collider = go.GetComponent <UnityEngine.Collider>();
                if (collider != null)
                {
                    MREAPI.AppsAPI.LayerApplicator.ApplyLayerToCollider(collisionLayer, collider);
                }
                else
                {
                    go.layer = MREAPI.AppsAPI.LayerApplicator.DefaultLayer;
                }

                actorList.Add(go.AddComponent <Actor>());
            });

            return(actorList);
        }
예제 #7
0
        private Asset GenerateAssetPatch(UnityEngine.Object unityAsset, Guid id)
        {
            if (unityAsset is GameObject go)
            {
                int actorCount = 0;
                MWGOTreeWalker.VisitTree(go, _ =>
                {
                    actorCount++;
                });

                return(new Asset
                {
                    Id = id,
                    Prefab = new Prefab()
                    {
                        ActorCount = actorCount
                    }
                });
            }
            else if (unityAsset is UnityEngine.Material mat)
            {
                return(new Asset()
                {
                    Id = id,
                    Material = MREAPI.AppsAPI.MaterialPatcher.GeneratePatch(_app, mat)
                });
            }
            else if (unityAsset is UnityEngine.Texture tex)
            {
                return(new Asset()
                {
                    Id = id,
                    Texture = new MWTexture()
                    {
                        Resolution = new Vector2Patch()
                        {
                            X = tex.width,
                            Y = tex.height
                        },
                        WrapModeU = tex.wrapModeU,
                        WrapModeV = tex.wrapModeV
                    }
                });
            }
            else if (unityAsset is UnityEngine.Mesh mesh)
            {
                return(new Asset()
                {
                    Id = id,
                    Mesh = new MWMesh()
                    {
                        VertexCount = mesh.vertexCount,
                        TriangleCount = mesh.triangles.Length / 3,
                        BoundingBoxDimensions = new Vector3Patch()
                        {
                            X = mesh.bounds.size.x,
                            Y = mesh.bounds.size.y,
                            Z = mesh.bounds.size.z
                        },
                        BoundingBoxCenter = new Vector3Patch()
                        {
                            X = mesh.bounds.center.x,
                            Y = mesh.bounds.center.y,
                            Z = mesh.bounds.center.z
                        }
                    }
                });
            }
            else if (unityAsset is AudioClip sound)
            {
                return(new Asset()
                {
                    Id = id,
                    Sound = new MWSound()
                    {
                        Duration = sound.length
                    }
                });
            }
            else if (unityAsset is VideoStreamDescription videoStream)
            {
                return(new Asset()
                {
                    Id = id,
                    VideoStream = new MWVideoStream()
                    {
                        Duration = videoStream.Duration
                    }
                });
            }
            else if (unityAsset is AnimationDataCached animData)
            {
                return(new Asset()
                {
                    Id = id
                });
            }
            else
            {
                throw new Exception($"Asset {id} is not patchable, or not of the right type!");
            }
        }
예제 #8
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);
        }
        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);
        }
예제 #10
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);
        }
예제 #11
0
        private Asset GenerateAssetPatch(Godot.Object unityAsset, Guid id)
        {
            if (unityAsset is Node go)
            {
                int actorCount = 0;
                MWGOTreeWalker.VisitTree(go, _ =>
                {
                    actorCount++;
                });

                return(new Asset
                {
                    Id = id,
                    Prefab = new Prefab()
                    {
                        ActorCount = actorCount
                    }
                });
            }
            else if (unityAsset is Godot.SpatialMaterial mat)
            {
                return(new Asset()
                {
                    Id = id,
                    Material = MREAPI.AppsAPI.MaterialPatcher.GeneratePatch(_app, mat)
                });
            }
            else if (unityAsset is Godot.Texture tex)
            {
                return(new Asset()
                {
                    Id = id,
                    Texture = new MWTexture()
                    {
                        Resolution = new Vector2Patch(tex.GetSize()),
                        Flags = tex.Flags,
                    }
                });
            }
            else if (unityAsset is Godot.Mesh mesh)
            {
                ArrayMesh arrayMesh           = mesh as ArrayMesh;
                Godot.Collections.Array array = arrayMesh.SurfaceGetArrays(0);
                var aabb        = arrayMesh.GetAabb();
                var vertexCount = (array[(int)ArrayMesh.ArrayType.Vertex] as Array).Length;


                return(new Asset()
                {
                    Id = id,
                    Mesh = new MWMesh()
                    {
                        VertexCount = vertexCount,
                        //FIXME
                        //TriangleCount = mesh.triangles.Length / 3,

                        BoundingBoxDimensions = new Vector3Patch()
                        {
                            X = aabb.Size.x,
                            Y = aabb.Size.y,
                            Z = aabb.Size.z
                        },
                        BoundingBoxCenter = new Vector3Patch()
                        {
                            X = aabb.Position.x,
                            Y = aabb.Position.y,
                            Z = aabb.Position.z
                        }
                    }
                });
            }
            else if (unityAsset is AudioStream sound)
            {
                return(new Asset()
                {
                    Id = id,
                    Sound = new MWSound()
                    {
                        Duration = sound.GetLength()
                    }
                });
            }

            /*
             * else if (unityAsset is VideoStreamDescription videoStream)
             * {
             *      return new Asset()
             *      {
             *              Id = id,
             *              VideoStream = new MWVideoStream()
             *              {
             *                      Duration = videoStream.Duration
             *              }
             *      };
             * }
             */
            else if (unityAsset is AnimationDataCached animData)
            {
                return(new Asset()
                {
                    Id = id
                });
            }

            else
            {
                throw new Exception($"Asset {id} is not patchable, or not of the right type!");
            }
        }