/// <summary> /// Asynchronously imports the given .obj file from the specified url /// </summary> /// <param name="url">The url to the .obj file</param> /// <returns>The GameObject that was created for the imported .obj</returns> public async Task <GameObject> ImportAsync(string url) { i5Debug.Log("Starting import", this); Uri uri = new Uri(url); // fetch the model WebResponse <string> resp = await FetchModelAsync(uri); // if there was an error, we cannot create anything if (!resp.Successful) { i5Debug.LogError("Error fetching obj. No object imported.\n" + resp.ErrorMessage, this); return(null); } // create the parent object // it is a standard GameObject; its only purpose is to bundle the child objects GameObject parentObject = ObjectPool <GameObject> .RequestResource(() => { return(new GameObject()); }); parentObject.name = System.IO.Path.GetFileNameWithoutExtension(uri.LocalPath); // parse the .obj file List <ObjParseResult> parseResults = await ParseModelAsync(resp.Content); // for each sub-object in the .obj file, an own parse result was created foreach (ObjParseResult parseResult in parseResults) { // check that the referenced mtl library is already loaded; if not: load it if (!MtlLibrary.LibraryLoaded(parseResult.LibraryPath)) { string mtlUri = UriUtils.RewriteFileUriPath(uri, parseResult.LibraryPath); string libraryName = System.IO.Path.GetFileNameWithoutExtension(uri.LocalPath); bool successful = await MtlLibrary.LoadLibraryAsyc(new Uri(mtlUri), libraryName); if (!successful) { i5Debug.LogError("Could not load .mtl file " + parseResult.LibraryPath, this); } } // get the material constructor of the sub-object MaterialConstructor mat = MtlLibrary.GetMaterialConstructor( System.IO.Path.GetFileNameWithoutExtension(uri.LocalPath), parseResult.MaterialName); if (mat != null) { // first get dependencies; this will e.g. fetch referenced textures await mat.FetchDependencies(); parseResult.ObjectConstructor.MaterialConstructor = mat; } // construct the object and make it a child of the parentObject parseResult.ObjectConstructor.ConstructObject(parentObject.transform); } return(parentObject); }
public IEnumerator FetchDependencies_NoTexturesProvided_ReturnsTrue() { MaterialConstructor materialConstructor = new MaterialConstructor(); Task <bool> task = materialConstructor.FetchDependencies(); yield return(AsyncTest.WaitForTask(task)); bool success = task.Result; Assert.True(success); }
public IEnumerator FetchDependencies_TextureFetchFail_ReturnsFalse() { MaterialConstructor materialConstructor = new MaterialConstructor(); ITextureConstructor fakeTextureConstructorFail = A.Fake <ITextureConstructor>(); A.CallTo(() => fakeTextureConstructorFail.FetchTextureAsync()).Returns(Task.FromResult <Texture2D>(null)); materialConstructor.SetTexture("tex", fakeTextureConstructorFail); Task <bool> task = materialConstructor.FetchDependencies(); yield return(AsyncTest.WaitForTask(task)); bool success = task.Result; Assert.False(success); }
public IEnumerator ConstructMaterial_FetchedTexture_TextureSetInMaterial() { MaterialConstructor materialConstructor = new MaterialConstructor(); Texture2D expectedTexture = new Texture2D(2, 2); ITextureConstructor fakeTextureConstructor = A.Fake <ITextureConstructor>(); A.CallTo(() => fakeTextureConstructor.FetchTextureAsync()).Returns(Task.FromResult(expectedTexture)); materialConstructor.SetTexture("_MainTex", fakeTextureConstructor); Task <bool> task = materialConstructor.FetchDependencies(); yield return(AsyncTest.WaitForTask(task)); bool success = task.Result; Assert.True(success); Material mat = materialConstructor.ConstructMaterial(); Assert.NotNull(mat.mainTexture); Assert.AreEqual(expectedTexture.imageContentsHash, mat.mainTexture.imageContentsHash); }