示例#1
0
    public static async Task Load(GameObject gameObjectLoader, string url, Action callback, Action <GameObject> onInitializeGltfObject)
    {
        ImporterFactory Factory       = null;
        bool            UseStream     = true;
        string          GLTFUri       = url;
        bool            Multithreaded = true;
        int             MaximumLod    = 300;
        int             Timeout       = 8;

        var importOptions = new ImportOptions
        {
            AsyncCoroutineHelper = gameObjectLoader.GetComponent <AsyncCoroutineHelper>() ?? gameObjectLoader.AddComponent <AsyncCoroutineHelper>()
        };

        GLTFSceneImporter sceneImporter = null;
        var cancelToken = new CancellationTokenSource();

        try
        {
            Factory = Factory ?? ScriptableObject.CreateInstance <DefaultImporterFactory>();
            if (UseStream)
            {
                var    fullPath      = GLTFUri;
                string directoryPath = URIHelper.GetDirectoryName(fullPath);
                importOptions.DataLoader = new FileLoader(directoryPath);
                sceneImporter            = Factory.CreateSceneImporter(Path.GetFileName(GLTFUri), importOptions);
            }
            else
            {
                string directoryPath = URIHelper.GetDirectoryName(GLTFUri);
                importOptions.DataLoader = new WebRequestLoader(directoryPath);
                sceneImporter            = Factory.CreateSceneImporter(URIHelper.GetFileFromUri(new Uri(GLTFUri)), importOptions);
            }
            sceneImporter.SceneParent            = gameObjectLoader.transform;
            sceneImporter.MaximumLod             = MaximumLod;
            sceneImporter.Timeout                = Timeout;
            sceneImporter.IsMultithreaded        = Multithreaded;
            sceneImporter.OnInitializeGltfObject = onInitializeGltfObject;
            mTasks.Add(cancelToken);
            await sceneImporter.LoadSceneAsync(-1, true, null, cancelToken.Token);
        }
        finally
        {
            if (importOptions.DataLoader != null)
            {
                if (sceneImporter != null)
                {
                    mCreatedScenes.Add(sceneImporter.CreatedObject);
                    if (cancelToken.IsCancellationRequested)
                    {
                        sceneImporter.CreatedObject.DestroySelf();
                    }
                    sceneImporter.Dispose();
                    sceneImporter = null;
                }
                importOptions.DataLoader = null;
            }
            callback.InvokeGracefully();
        }
    }
示例#2
0
        public static void Load(string path, Action <GameObject> onLoad)
        {
            //GLTF Component Settings
            int               MaximumLod     = 300;
            bool              Multithreaded  = true;
            ILoader           loader         = null;
            Shader            shaderOverride = null;
            GLTFSceneImporter sceneImporter  = null;

            string directoryPath = URIHelper.GetDirectoryName(path);

            loader = new WebRequestLoader(directoryPath);

            sceneImporter = new GLTFSceneImporter(
                Path.GetFileName(path),
                loader
                );

            sceneImporter.Collider         = GLTFSceneImporter.ColliderType.None;
            sceneImporter.MaximumLod       = MaximumLod;
            sceneImporter.CustomShaderName = shaderOverride ? shaderOverride.name : null;

            Action <GameObject> newOnLoad = (go) =>
            {
                onLoad(go);
            };

            // Call coroutine to load AR object
            ThreadHelper.Instance.StartCoroutine(LoadScene(sceneImporter, Multithreaded, newOnLoad));
        }
示例#3
0
    IEnumerator Start()
    {
        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    = Colliders;
        sceneImporter.MaximumLod  = MaximumLod;
        yield return(sceneImporter.LoadScene(-1, Multithreaded, HandleAction));
    }
示例#4
0
    public IEnumerator CurvesAreOptimizedCorrectly()
    {
        var curvesSource = Resources.Load <AnimationCurveContainer>("CurveOptimizedCorrectlySource");
        //NOTE(Brian): We are going to output the optimization result in this SO, so it can be debugged more easily
        var curvesResult = Resources.Load <AnimationCurveContainer>("CurveOptimizedCorrectlyResult");

        curvesResult.curves = new AnimationCurve[curvesSource.curves.Length];

        for (int i = 0; i < curvesSource.curves.Length; i++)
        {
            var curve = curvesSource.curves[i];

            List <Keyframe> keys = new List <Keyframe>();

            for (int i1 = 0; i1 < curve.length; i1++)
            {
                keys.Add(curve[i1]);
            }

            var result        = GLTFSceneImporter.OptimizeKeyFrames(keys.ToArray());
            var modifiedCurve = new AnimationCurve(result);

            curvesResult.curves[i] = modifiedCurve;

            for (float time = 0; time < 1.0f; time += 0.032f)
            {
                var v1 = curve.Evaluate(time);
                var v2 = modifiedCurve.Evaluate(time);

                UnityEngine.Assertions.Assert.AreApproximatelyEqual(v1, v2, 0.01f);
            }
        }

        yield break;
    }
示例#5
0
    private IEnumerator LoadGLB(byte[] bytes)
    {
        // Define the publiclyVisible=true, otherwise will get an error.
        // https://stackoverflow.com/questions/1646193/why-does-memorystream-getbuffer-always-throw

        Stream stream = new MemoryStream(bytes, 0, bytes.Length, false, true);

        GLTFRoot gLTFRoot;

        GLTFParser.ParseJson(stream, out gLTFRoot);

        Debug.Log("Successfully parsed INIT packet!");

        GLTFSceneImporter loader = new GLTFSceneImporter(gLTFRoot, null, null, stream);

        loader.Collider        = GLTFSceneImporter.ColliderType.Box;
        loader.IsMultithreaded = false;

        loader.LoadSceneAsync().Wait();

        GameObject obj = loader.LastLoadedScene;

        obj.transform.parent = hyperverseRoot.transform;

        Debug.Log("Loaded scene from INIT packet!");

        // TEST:
        ResetSceneGraph();

        yield return(null);
    }
    private void Load(Stream stream)
    {
        GLTFRoot gLTFRoot;

        GLTFParser.ParseJson(stream, out gLTFRoot);
        var loader = new GLTFSceneImporter(gLTFRoot, null, null, stream);

        loader.LoadSceneAsync();
    }
示例#7
0
        public static IEnumerator LoadScene(GLTFSceneImporter sceneImporter, bool Multithreaded, Action <GameObject> onLoad)
        {
            yield return(sceneImporter.LoadScene(-1, Multithreaded));

            if (onLoad != null)
            {
                onLoad(sceneImporter.CreatedObject);
            }
        }
示例#8
0
 void Start()
 {
     Debug.Log("Hit spacebar to change the scene.");
     loader = new GLTFSceneImporter(
         Url,
         gameObject.transform
         );
     StartCoroutine(LoadScene(SceneIndex));
 }
示例#9
0
 void Start()
 {
     Debug.Log("Hit spacebar to change the scene.");
     loader = new GLTFSceneImporter(
         Url,
         gameObject.transform
         );
     loader.SetShaderForMaterialType(GLTFSceneImporter.MaterialType.PbrMetallicRoughness, GLTFStandardShader);
     StartCoroutine(LoadScene(SceneIndex));
 }
示例#10
0
        IEnumerator Start()
        {
            var loader = new GLTFSceneImporter(
                Url,
                gameObject.transform
                );

            yield return(loader.Load(-1, Multithreaded));

            IntegrationTest.Pass();
        }
示例#11
0
        IEnumerator Start()
        {
            var loader = new GLTFSceneImporter(
                Url,
                gameObject.transform
                );

            loader.SetShaderForMaterialType(GLTFSceneImporter.MaterialType.PbrMetallicRoughness, GLTFStandard);
            yield return(loader.Load(-1, Multithreaded));
            //IntegrationTest.Pass();
        }
示例#12
0
        IEnumerator Start()
        {
            ILoader loader        = new WebRequestLoader(URIHelper.GetDirectoryName(Url));
            var     sceneImporter = new GLTFSceneImporter(
                URIHelper.GetFileFromUri(new Uri(Url)),
                loader
                );

            sceneImporter.SceneParent = gameObject.transform;
            yield return(sceneImporter.LoadScene(-1, Multithreaded));

            IntegrationTest.Pass();
        }
示例#13
0
    public IEnumerator TexturesOffsetAndScaleWorkProperly()
    {
        DecentralandEntity entity = null;

        PersistentAssetCache.ImageCacheByUri.Clear();
        yield return(LoadModel("/GLB/PlaneUVsOffset/planeUVsOffset.glb", (e, model) => entity = e));

        MeshRenderer meshRenderer = entity.gameObject.GetComponentInChildren <MeshRenderer>();

        var unityOffset = GLTFSceneImporter.GLTFOffsetToUnitySpace(new Vector2(0.35f, 0.35f), 2.5f);

        Assert.AreEqual(unityOffset, meshRenderer.material.GetTextureOffset("_BaseMap"));
        Assert.AreEqual(Vector2.one * 2.5f, meshRenderer.material.GetTextureScale("_BaseMap"));
    }
示例#14
0
    /// <summary>
    /// Permet de charger le fichier GLTF voulue
    /// </summary>
    /// <param name="filePath"> Chemin fichier à charger</param>
    /// <param name="parent"> Object parent auquel rattaché l'objet gltf chargé</param>
    /// <returns></returns>
    public IEnumerator CreateComponentFromFile(string filePath, GameObject parent)
    {
        GLTFSceneImporter loader = null;
        string            Url    = filePath;

        if (UseStream)
        {
            string fullPath = "";

            if (GLTFStream == null)
            {
                fullPath = Url; //Path.Combine(Application.streamingAssetsPath, Url);
                Debug.Log("FullPath : " + fullPath);
                GLTFStream = File.OpenRead(fullPath);
            }
            loader = new GLTFSceneImporter(
                fullPath,
                GLTFStream,
                parent.transform,
                addColliders
                );
        }
        else
        {
            loader = new GLTFSceneImporter(
                Url,
                parent.transform,
                addColliders
                );
        }
        loader.SetShaderForMaterialType(GLTFSceneImporter.MaterialType.PbrMetallicRoughness, GLTFStandard);
        loader.SetShaderForMaterialType(GLTFSceneImporter.MaterialType.KHR_materials_pbrSpecularGlossiness, GLTFStandardSpecular);
        loader.SetShaderForMaterialType(GLTFSceneImporter.MaterialType.CommonConstant, GLTFConstant);
        loader.MaximumLod = MaximumLod;
        yield return(loader.Load(-1, Multithreaded));

        if (GLTFStream != null)
        {
#if WINDOWS_UWP
            GLTFStream.Dispose();
#else
            GLTFStream.Close();
#endif

            GLTFStream = null;
        }

        IsLoaded = true;
    }
        async void LoadScene(int SceneIndex)
        {
            foreach (Transform child in transform)
            {
                GameObject.Destroy(child.gameObject);
            }

            _importer = new GLTFSceneImporter(
                _fileName,
                _importOptions
                );

            _importer.SceneParent = gameObject.transform;
            await _importer.LoadSceneAsync(SceneIndex);
        }
示例#16
0
        IEnumerator LoadScene(int SceneIndex)
        {
            foreach (Transform child in transform)
            {
                GameObject.Destroy(child.gameObject);
            }

            _importer = new GLTFSceneImporter(
                _fileName,
                _loader
                );

            _importer.SceneParent = gameObject.transform;
            yield return(_importer.LoadScene(SceneIndex));
        }
示例#17
0
    public async void OpenNewModelAsync(Action <GameObject> completionCallback)
    {
        // Get rid of the previous model regardless of whether the user chooses
        // a new one or not with a review to avoiding cluttering the screen.
        this.DisposeExistingGLTFModel();

        // Note - this method will throw inside of the editor, only does something
        // on the UWP platform.
        var filePath = await FileDialogHelper.PickGLTFFileAsync();

        if (!string.IsNullOrEmpty(filePath))
        {
            this.ShowCursor(false);

            ProgressIndicator.Instance.Open(
                IndicatorStyleEnum.AnimatedOrbs,
                ProgressStyleEnum.None,
                ProgressMessageStyleEnum.Visible,
                "Loading...");

            var loader = new FileLoader(Path.GetDirectoryName(filePath));

            GLTFSceneImporter importer = new GLTFSceneImporter(Path.GetFileName(filePath), loader);

            importer.Collider = GLTFSceneImporter.ColliderType.Box;

            try
            {
                await base.RunCoroutineAsync(
                    importer.LoadScene(
                        -1,
                        gameObject => this.LoadedCompletionHandler(gameObject, completionCallback)
                        )
                    );
            }
            catch (Exception ex)
            {
                this.LoadedCompletionHandler(null, completionCallback);
            }
        }
        else
        {
            completionCallback?.Invoke(null);
        }
    }
示例#18
0
        public IEnumerator Download(Promise <bool> loadComplete)
        {
            string            directoryPath = URIHelper.GetDirectoryName(Url);
            string            relativePath  = Url.Replace(directoryPath, "");
            var               wrl           = new B3DMLoader(new WebRequestLoader(directoryPath));
            GLTFSceneImporter sceneImporter = new GLTFSceneImporter(
                relativePath,
                wrl
                );

            sceneImporter.SceneParent      = gameObject.transform;
            sceneImporter.CustomShaderName = ShaderOverride ? ShaderOverride.name : null;
            sceneImporter.MaximumLod       = MaximumLod;
            if (addColliders)
            {
                sceneImporter.Collider = GLTFSceneImporter.ColliderType.Mesh;
            }
            yield return(sceneImporter.LoadScene(-1, Multithreaded, sceneObject =>
            {
                if (sceneObject != null)
                {
                    loadComplete.Resolve(true);
                }
                else
                {
                    loadComplete.Resolve(false);
                }
                Destroy(this);
            }));

            // 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;
                }
            }
        }
示例#19
0
    async Task <ImportedModelInfo> ImportGLTFModelFromFileAsync(string filePath)
    {
        this.ShowBusy("Loading model...");

        ImportedModelInfo modelDetails = null;

        try
        {
            modelDetails = new ImportedModelInfo(
                new RecordingFileLoader(Path.GetDirectoryName(filePath)));

            GLTFSceneImporter importer = new GLTFSceneImporter(
                Path.GetFileName(filePath), modelDetails.FileLoader);

            importer.Collider = GLTFSceneImporter.ColliderType.Box;

            await base.RunCoroutineAsync(
                importer.LoadScene(
                    -1,
                    gameObject => modelDetails.GameObject = gameObject)
                );
        }
        catch
        {
            // TODO: figure out sensible exceptions here.
        }
        this.HideBusy();

        if (modelDetails?.GameObject != null)
        {
            this.AudioManager?.PlayClipOnceOnly(AudioClipType.FirstModelOpened);
        }
        else
        {
            this.AudioManager?.PlayClip(AudioClipType.LoadError);
        }
        return(modelDetails);
    }
        public IEnumerator Load()
        {
            GLTFSceneImporter sceneImporter = null;
            ILoader           loader        = new loadFromXML(preLoadScene.blobName, MeshNum);

            sceneImporter = new GLTFSceneImporter(preLoadScene.blobName, 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;
                }
            }
        }
示例#21
0
        public IEnumerator Download(Promise <bool> loadComplete)
        {
            string url  = UrlUtils.ReplaceDataProtocol(Url);
            string dir  = UrlUtils.GetBaseUri(url);
            string file = UrlUtils.GetLastPathSegment(url);

            ILoader loader = AbstractWebRequestLoader.CreateDefaultRequestLoader(dir); //.glb, .gltf

            if (file.EndsWith(".b3dm", StringComparison.OrdinalIgnoreCase))
            {
                loader = new B3DMLoader(loader);
            }
            var sceneImporter = new GLTFSceneImporter(file, loader);

            sceneImporter.SceneParent      = gameObject.transform;
            sceneImporter.CustomShaderName = ShaderOverride ? ShaderOverride.name : null;
            sceneImporter.MaximumLod       = MaximumLod;
            sceneImporter.Collider         =
                AddColliders ? GLTFSceneImporter.ColliderType.Mesh : GLTFSceneImporter.ColliderType.None;

            loadComplete = loadComplete ?? new Promise <bool>();
            yield return(sceneImporter.LoadScene(-1, Multithreaded,
                                                 sceneObject => loadComplete.Resolve(sceneObject != null)));
        }
        private IEnumerator LoadSourceControllerModel(InteractionSource source)
        {
            byte[]     fileBytes;
            GameObject controllerModelGameObject;

            if (GLTFMaterial == null)
            {
                Debug.Log("If using glTF, please specify a material on " + name + ".");
                yield break;
            }

#if !UNITY_EDITOR
            // This API returns the appropriate glTF file according to the motion controller you're currently using, if supported.
            IAsyncOperation <IRandomAccessStreamWithContentType> modelTask = source.TryGetRenderableModelAsync();

            if (modelTask == null)
            {
                Debug.Log("Model task is null; loading alternate.");
                LoadAlternateControllerModel(source);
                yield break;
            }

            while (modelTask.Status == AsyncStatus.Started)
            {
                yield return(null);
            }

            IRandomAccessStreamWithContentType modelStream = modelTask.GetResults();

            if (modelStream == null)
            {
                Debug.Log("Model stream is null; loading alternate.");
                LoadAlternateControllerModel(source);
                yield break;
            }

            if (modelStream.Size == 0)
            {
                Debug.Log("Model stream is empty; loading alternate.");
                LoadAlternateControllerModel(source);
                yield break;
            }

            fileBytes = new byte[modelStream.Size];

            using (DataReader reader = new DataReader(modelStream))
            {
                DataReaderLoadOperation loadModelOp = reader.LoadAsync((uint)modelStream.Size);

                while (loadModelOp.Status == AsyncStatus.Started)
                {
                    yield return(null);
                }

                reader.ReadBytes(fileBytes);
            }
#else
            IntPtr controllerModel = new IntPtr();
            uint   outputSize      = 0;

            if (TryGetMotionControllerModel(source.id, out outputSize, out controllerModel))
            {
                fileBytes = new byte[Convert.ToInt32(outputSize)];

                Marshal.Copy(controllerModel, fileBytes, 0, Convert.ToInt32(outputSize));
            }
            else
            {
                Debug.Log("Unable to load controller models; loading alternate.");
                LoadAlternateControllerModel(source);
                yield break;
            }
#endif

            controllerModelGameObject = new GameObject {
                name = "glTFController"
            };
            controllerModelGameObject.transform.Rotate(0, 180, 0);

            var sceneImporter = new GLTFSceneImporter(
                "",
                new MemoryStream(fileBytes, 0, fileBytes.Length, false, true),
                controllerModelGameObject.transform
                );

            sceneImporter.SetShaderForMaterialType(GLTFSceneImporter.MaterialType.PbrMetallicRoughness, GLTFMaterial.shader);
            sceneImporter.SetShaderForMaterialType(GLTFSceneImporter.MaterialType.KHR_materials_pbrSpecularGlossiness, GLTFMaterial.shader);
            sceneImporter.SetShaderForMaterialType(GLTFSceneImporter.MaterialType.CommonConstant, GLTFMaterial.shader);

            yield return(sceneImporter.Load());

            FinishControllerSetup(controllerModelGameObject, source.handedness, GenerateKey(source));
        }
        /// <summary>
        /// The Unity Update() method.
        /// </summary>
        public void Update()
        {
            _UpdateApplicationLifecycle();

            if (startedDownloading && this.ARCaptLoader.WWWLoader != null && this.ARCaptLoader.WWWLoader.isDone)
            {
                startedDownloading = !this.ARCaptLoader.WWWLoader.isDone;
                if (this.ARCaptLoader.WWWLoader.progress < 1)
                {
                    this.ARCaptLoader.StatusMsg = "Downloading 3D model.. " + (int)(this.ARCaptLoader.WWWLoader.progress * 100) + "%";
                }
            }

            if (this.TextMessages.text != this.ARCaptLoader.StatusMsg)
            {
                this.TextMessages.text = this.ARCaptLoader.StatusMsg;
            }

            // Hide snackbar when currently tracking at least one plane.
            Session.GetTrackables <DetectedPlane>(m_AllPlanes);
            bool showSearchingUI = true;

            for (int i = 0; i < m_AllPlanes.Count; i++)
            {
                if (m_AllPlanes[i].TrackingState == TrackingState.Tracking)
                {
                    showSearchingUI = false;
                    break;
                }
            }

            SearchingForPlaneUI.SetActive(showSearchingUI);

            if (GroupModel3D != null)
            {
                if (Input.touchCount == 1)
                {
                    if (Input.GetTouch(0).phase == TouchPhase.Began)
                    {
                        oldTouchPosition = Input.GetTouch(0).position.x;
                    }
                    else if (Input.GetTouch(0).phase == TouchPhase.Moved)
                    {
                        if (Math.Abs(oldTouchPosition - Input.GetTouch(0).position.x) < 50)
                        {
                            return;
                        }
                        if (oldTouchPosition > Input.GetTouch(0).position.x)
                        {
                            GroupModel3D.transform.Rotate(0, 5f, 0, Space.Self);
                        }
                        else
                        {
                            GroupModel3D.transform.Rotate(0, -5f, 0, Space.Self);
                        }

                        oldTouchPosition = Input.GetTouch(0).position.x;
                    }
                }
                if (Input.touchCount == 2)
                {
                    this.RotateModel();
                }
            }
            else
            {
                // If the player has not touched the screen, we are done with this update.
                Touch touch;
                if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
                {
                    return;
                }

                // If the mode is still loading, we are done with this update again.
                if (this.isModelLoading)
                {
                    return;
                }

                // Raycast against the location the player touched to search for planes.
                TrackableHit      hit;
                TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
                                                  TrackableHitFlags.FeaturePointWithSurfaceNormal;

                if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit))
                {
                    // Use hit pose and camera pose to check if hittest is from the
                    // back of the plane, if it is, no need to create the anchor.
                    if ((hit.Trackable is DetectedPlane) &&
                        Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position,
                                    hit.Pose.rotation * Vector3.up) < 0)
                    {
                        Debug.Log("Hit at back of the current DetectedPlane");
                    }
                    else
                    {
                        this.Hit = hit;
                        if (string.IsNullOrEmpty(this.ARCaptLoader.ModelPath))
                        {
                            return;
                        }

                        this.isModelLoading         = true;
                        this.ARCaptLoader.StatusMsg = "Loading 3D model. Please wait...";
                        var loader        = new FileLoader(Path.GetDirectoryName(this.ARCaptLoader.ModelPath));
                        var sceneImporter = new GLTFSceneImporter(this.ARCaptLoader.ModelPath, loader);
                        StartCoroutine(sceneImporter.LoadScene(0, true, OnImportedModel));
                    }
                }
            }
        }
示例#24
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);
        }
示例#25
0
        public async Task LoadGltfAsync(GameObject newObject, string fullPath, ModelImportOptions importOptions)
        {
            asyncCoroutineHelper = newObject.GetComponent <AsyncCoroutineHelper>() ?? gameObject.AddComponent <AsyncCoroutineHelper>();
            //GLTFSceneImporter sceneImporter = null;
            ILoader loader = null;

            try
            {
                // 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.
                fullPath = fullPath.TrimStart(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
                string directoryPath = URIHelper.GetDirectoryName(fullPath);
                loader        = new FileLoader(directoryPath);
                sceneImporter = new GLTFSceneImporter(
                    Path.GetFileName(fullPath),
                    loader,
                    asyncCoroutineHelper
                    );
                sceneImporter.SceneParent = newObject.transform;
                sceneImporter.Collider    = Collider;
                if (importOptions != null)
                {
                    if (importOptions.buildColliders)
                    {
                        sceneImporter.Collider = GLTFSceneImporter.ColliderType.MeshConvex;
                        //if (importOptions.colliderConvex)
                        //{
                        //    sceneImporter.Collider = GLTFSceneImporter.ColliderType.MeshConvex;
                        //}
                        //else
                        //{
                        //    sceneImporter.Collider = GLTFSceneImporter.ColliderType.Mesh;
                        //}
                    }
                    else
                    {
                        sceneImporter.Collider = GLTFSceneImporter.ColliderType.None;
                    }
                }
                sceneImporter.MaximumLod       = MaximumLod;
                sceneImporter.Timeout          = Timeout;
                sceneImporter.isMultithreaded  = Multithreaded;
                sceneImporter.CustomShaderName = shaderOverride ? shaderOverride.name : null;
                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;
                }
            }
        }
        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);
        }
示例#27
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);
        }
示例#28
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);
        }
    public void ImporterCanLoadSkeletonsByDefault()
    {
        var importer = new GLTFSceneImporter("", "", null, null);

        Assert.IsTrue(importer.importSkeleton, "Skeleton importing should be true by default or avatars won't load correctly!");
    }