public void GetMaterialConstructor_NonExistentMatLib_ReturnsNull() { mtlLibrary.ContentLoader = FakeContentLoaderFactory.CreateFakeLoader(content); MaterialConstructor res = mtlLibrary.GetMaterialConstructor("", ""); Assert.IsNull(res); }
/// <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 void ConstructMaterial_DefaultSettings_GeneratesStandardMaterial() { MaterialConstructor materialConstructor = new MaterialConstructor(); Material mat = materialConstructor.ConstructMaterial(); Assert.IsNotNull(mat); Assert.AreEqual(Shader.Find("Standard"), mat.shader); Assert.AreEqual(materialConstructor.Name, mat.name); }
public void ConstructMaterial_TexturesNotFetched_GivesWarning() { MaterialConstructor materialConstructor = new MaterialConstructor(); materialConstructor.SetTexture("_MainTex", A.Fake <ITextureConstructor>()); Material mat = materialConstructor.ConstructMaterial(); LogAssert.Expect(LogType.Warning, new Regex(@"\w*Constructed material which has unfetched textures.\w*")); }
public IEnumerator GetMaterialConstructor_ExistentMatLibExistentMat_ReturnsNotNull() { mtlLibrary.ContentLoader = FakeContentLoaderFactory.CreateFakeLoader(content); Task task = LoadLibrary(); yield return(AsyncTest.WaitForTask(task)); MaterialConstructor res = mtlLibrary.GetMaterialConstructor(libraryName, "BlueMat"); Assert.IsNotNull(res); }
public void ConstructMaterial_ShaderSet_MaterialHasShader() { MaterialConstructor materialConstructor = new MaterialConstructor(); string shaderName = "Unlit/Color"; materialConstructor.ShaderName = shaderName; Material mat = materialConstructor.ConstructMaterial(); Assert.IsNotNull(mat); Assert.AreEqual(Shader.Find(shaderName), mat.shader); }
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 GetMaterialConstructor_ExistentMatLibExistentMat_MatConstrColorSet() { mtlLibrary.ContentLoader = FakeContentLoaderFactory.CreateFakeLoader(content); Task task = LoadLibrary(); yield return(AsyncTest.WaitForTask(task)); MaterialConstructor res = mtlLibrary.GetMaterialConstructor(libraryName, "BlueMat"); Assert.IsNotNull(res); Assert.AreEqual(new Color(0.185991f, 0.249956f, 0.800000f), res.Color); }
public void ConstructMaterial_ColorSet_MaterialHasColor() { MaterialConstructor materialConstructor = new MaterialConstructor(); Color color = Random.ColorHSV(); materialConstructor.Color = color; Material mat = materialConstructor.ConstructMaterial(); Assert.IsNotNull(mat); Assert.AreEqual(Shader.Find("Standard"), mat.shader); Assert.AreEqual(color, mat.color); }
public void ConstructMaterial_NameSet_MaterialHasName() { MaterialConstructor materialConstructor = new MaterialConstructor(); string materialName = "My Material " + Random.Range(0, 10000); materialConstructor.Name = materialName; Material mat = materialConstructor.ConstructMaterial(); Assert.IsNotNull(mat); Assert.AreEqual(Shader.Find("Standard"), mat.shader); Assert.AreEqual(materialName, mat.name); }
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 void ConstructObject_MaterialConstructorGiven_AssignedMaterial() { ObjectConstructor objConstructor = new ObjectConstructor(); GeometryConstructor geometryConstructor = CreateSimpleGeometry(); MaterialConstructor materialConstructor = new MaterialConstructor(); materialConstructor.Color = Color.red; materialConstructor.Name = "RedMat"; objConstructor.GeometryConstructor = geometryConstructor; objConstructor.MaterialConstructor = materialConstructor; GameObject result = objConstructor.ConstructObject(); AssertGameObjectWithGeometry(result, geometryConstructor, out MeshRenderer meshRenderer); Assert.AreEqual(Color.red, meshRenderer.sharedMaterial.color); Assert.AreEqual(materialConstructor.Name, meshRenderer.sharedMaterial.name); }
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); }
/// <summary> /// Parses the contents of a .mtl file /// </summary> /// <param name="uri">The full URI where the .mtl file is stored</param> /// <param name="libraryContent">The line array of the file's content</param> /// <returns>A list a material constructor for each material in the library</returns> private List <MaterialConstructor> ParseMaterialLibrary(Uri uri, string[] libraryContent) { List <MaterialConstructor> materials = new List <MaterialConstructor>(); MaterialConstructor current = null; int numberOfErrors = 0; for (int i = 0; i < libraryContent.Length; i++) { string trimmedLine = libraryContent[i].Trim(); // newmtl and # (comment) can be executed also if there is no current material set // skip empty lines if (string.IsNullOrEmpty(trimmedLine)) { continue; } else if (trimmedLine.StartsWith("newmtl")) { if (current != null) { materials.Add(current); } current = new MaterialConstructor(); current.Name = trimmedLine.Substring(6).TrimStart(); } else if (trimmedLine.StartsWith("#")) { if (ExtendedLogging) { i5Debug.Log("Comment found: " + trimmedLine.Substring(1).TrimStart(), this); } } // all other commands require an already initialized material // this means that the line newmtl must have been read at least once until now else { if (current != null) { // Kd sets the diffuse color if (trimmedLine.StartsWith("Kd")) { string[] strValues = trimmedLine.Substring(2).TrimStart().Split(' '); if (strValues.Length != 3) { numberOfErrors++; if (ExtendedLogging) { i5Debug.LogError("Expected three color values but found " + strValues.Length, this); } continue; } if (ParserUtils.TryParseStringArrayToVector3(strValues, out Vector3 colorVector)) { // could successfully parse color vector Color albedo = colorVector.ToColor(); current.Color = albedo; } else { numberOfErrors++; if (ExtendedLogging) { i5Debug.LogError("Could not parse color data", this); } } } // Ks sets the specular intensity else if (trimmedLine.StartsWith("Ks")) { string[] strValues = trimmedLine.Substring(2).TrimStart().Split(' '); if (strValues.Length != 3 && strValues.Length != 1) { numberOfErrors++; if (ExtendedLogging) { i5Debug.LogError("Expected one or three smoothness values but found " + strValues.Length, this); } continue; } // we assume that all values are equal if (float.TryParse(strValues[0], NumberStyles.Any, CultureInfo.InvariantCulture, out float smoothness)) { // could successfully parse smoothness current.SetFloat("_Glossiness", smoothness); } else { numberOfErrors++; if (ExtendedLogging) { i5Debug.LogError("Could not parse color data", this); } } } // map_Kd sets the albedo texture else if (trimmedLine.StartsWith("map_Kd")) { string texturePath = trimmedLine.Substring(6).TrimStart(); // rewrite the URI to the texture's path and then add a texture constructor to the material string fullUri = UriUtils.RewriteFileUriPath(uri, texturePath); current.SetTexture("_MainTex", new TextureConstructor(fullUri)); } } else { i5Debug.LogWarning("Material instruction line found but material has not yet been initialized. The .mtl-file is probably malformed.", this); } } } if (current != null) { materials.Add(current); } // check if materials were created if (materials.Count == 0) { i5Debug.LogWarning(".mtl-file was read but no materials were parsed.", this); } return(materials); }