// Pass: // parameterName - // used for the FbxTexture name. Can be something arbitrary since as far as I know, // the texture node's name is unused by importers. private static void AddTextureToMaterial( FbxExportGlobals G, ExportFileReference fileRef, FbxSurfaceLambert fbxMaterial, string parameterName) { Debug.Assert(File.Exists(fileRef.m_originalLocation)); var destPath = Path.Combine(G.m_outputDir, fileRef.m_uri); if (!File.Exists(destPath)) { if (!FileUtils.InitializeDirectoryWithUserError(Path.GetDirectoryName(destPath))) { return; } File.Copy(fileRef.m_originalLocation, destPath); } // It's kind of weird that the parameter name is used for the texture node's name, // but as far as I can tell nobody cares about that name, so whatever. FbxFileTexture fbxTexture = FbxFileTexture.Create(G.m_scene, parameterName); fbxTexture.SetFileName(destPath); fbxTexture.SetTextureUse(FbxTexture.ETextureUse.eStandard); fbxTexture.SetMappingType(FbxTexture.EMappingType.eUV); fbxTexture.SetMaterialUse(FbxFileTexture.EMaterialUse.eModelMaterial); fbxTexture.UVSet.Set(new FbxString("uv0")); // It's also weird that we only ever assign to the Diffuse slot. // Shouldn't we be looking at the parameter name and assigning to Diffuse, Normal, etc // based on what we see? // TODO: check fbxMaterial.Diffuse.ConnectSrcObject(fbxTexture); fbxMaterial.TransparentColor.ConnectSrcObject(fbxTexture); }
public void TestGetOrCreateSafeLocal() { var dp = Application.dataPath; var ctx = new ExportFileReference.DisambiguationContext(); var paper = ExportFileReference.GetOrCreateSafeLocal( ctx, "main.png", dp + @"\Resources\Brushes\Basic\Paper"); var paper2 = ExportFileReference.GetOrCreateSafeLocal( ctx, "main.png", dp + @"\Resources\Brushes\Basic\Paper"); Assert.AreEqual(paper, paper2); // reference equality Assert.AreEqual("main.png", paper.m_uri); Assert.AreEqual("main.png", paper2.m_uri); var ductTape = ExportFileReference.GetOrCreateSafeLocal( ctx, "main.png", dp + @"\Resources\Brushes\Basic\DuctTape"); Assert.AreNotEqual(paper, ductTape); Assert.AreEqual("main_1.png", ductTape.m_uri); var peverse = ExportFileReference.GetOrCreateSafeLocal( ctx, "main_1.png", dp + @"\Editor\Tests\TestData"); Assert.AreEqual("main_1_1.png", peverse.m_uri); var withNamespace = ExportFileReference.GetOrCreateSafeLocal( ctx, "main.png", dp + @"\Resources\Brushes\Basic\Hypercolor", @"subdirectory\brush_main.png"); Assert.AreEqual("brush_main.png", withNamespace.m_uri); }
public static GlTF_Image LookupOrCreate(GlTF_Globals G, GlTF_FileReference fileRef, string proposedName = null) { if (!G.imagesByFileRefUri.ContainsKey(fileRef.m_uri)) { string name = "image_" + (proposedName ?? $"{G.imagesByFileRefUri.Count}"); G.imagesByFileRefUri.Add(fileRef.m_uri, new GlTF_Image(G, name, fileRef)); } return(G.imagesByFileRefUri[fileRef.m_uri]); }
private ExportResults ExportHelper( SceneStatePayload payload, string outputFile, bool binary, bool doExtras, int gltfVersion, bool allowHttpUri) { // TODO: Ownership of this temp directory is sloppy. // Payload and export share the same dir and we assume that the exporter: // 1. will not write files whose names conflict with payload's // 2. will clean up the entire directory when done // This works, as long as the payload isn't used for more than one export (it currently isn't) using (var exporter = new GlTF_ScriptableExporter(payload.temporaryDirectory, gltfVersion)) { exporter.AllowHttpUri = allowHttpUri; try { m_exporter = exporter; exporter.G.binary = binary; exporter.BeginExport(outputFile); exporter.SetMetadata(payload.generator, copyright: null); if (doExtras) { SetExtras(exporter, payload); } if (payload.env.skyCubemap != null) { // Add the skybox texture to the export. string texturePath = ExportUtils.GetTexturePath(payload.env.skyCubemap); string textureFilename = Path.GetFileName(texturePath); exporter.G.extras["TB_EnvironmentSkybox"] = ExportFileReference.CreateLocal(texturePath, textureFilename); } WriteObjectsAndConnections(exporter, payload); string[] exportedFiles = exporter.EndExport(); return(new ExportResults { success = true, exportedFiles = exportedFiles, numTris = exporter.NumTris }); } catch (InvalidOperationException e) { OutputWindowScript.Error("glTF export failed", e.Message); // TODO: anti-pattern. Let the exception bubble up so caller can log it properly // Actually, InvalidOperationException is now somewhat expected in experimental, since // the gltf exporter does not check IExportableMaterial.SupportsDetailedMaterialInfo. // But we still want the logging for standalone builds. Debug.LogException(e); return(new ExportResults { success = false }); } catch (IOException e) { OutputWindowScript.Error("glTF export failed", e.Message); return(new ExportResults { success = false }); } finally { payload.Destroy(); // The lifetime of ExportGlTF, GlTF_ScriptableExporter, and GlTF_Globals instances // is identical. This is solely to be pedantic. m_exporter = null; } } }
public bool IsHttp() { return(ExportFileReference.IsHttp(m_uri)); }
internal static FbxSurfaceMaterial CreateFbxMaterial( FbxExportGlobals G, string meshNamespace, IExportableMaterial exportableMaterial, HashSet <string> createdMaterialNames) { string materialName; if (exportableMaterial is BrushDescriptor) { // Toolkit uses this guid (in "N" format) to look up a BrushDescriptor. // See Toolkit's ModelImportSettings.GetDescriptorForStroke materialName = $"{exportableMaterial.UniqueName:N}_{meshNamespace}_{exportableMaterial.DurableName}"; } else if (exportableMaterial is DynamicExportableMaterial dem) { // Comes from {fbx,obj,gltf,...} import from {Poly, Media Library} // This is a customized version of a BrushDescriptor -- almost certainly // Pbr{Blend,Opaque}{Double,Single}Sided with maybe an added texture and // some of its params customized. // TBT will merge the material created by Unity for this FbxMaterial with // the premade material it has for the parent guid. materialName = $"{dem.Parent.m_Guid:N}_{meshNamespace}_{dem.DurableName}"; } else { Debug.LogWarning($"Unknown class {exportableMaterial.GetType().Name}"); materialName = $"{meshNamespace}_{exportableMaterial.DurableName}"; } // If only ExportFbx were a non-static class we could merge it with FbxExportGlobals materialName = ExportUtils.CreateUniqueName(materialName, createdMaterialNames); FbxSurfaceLambert material = FbxSurfaceLambert.Create(G.m_scene, materialName); material.Ambient.Set(new FbxDouble3(0, 0, 0)); material.Diffuse.Set(new FbxDouble3(1.0, 1.0, 1.0)); if (exportableMaterial.EmissiveFactor > 0) { material.EmissiveFactor.Set(exportableMaterial.EmissiveFactor); material.Emissive.Set(new FbxDouble3(1.0, 1.0, 1.0)); } if (exportableMaterial.BlendMode != ExportableMaterialBlendMode.None) { var blendMode = FbxProperty.Create(material, Globals.FbxStringDT, "BlendMode"); switch (exportableMaterial.BlendMode) { case ExportableMaterialBlendMode.AlphaMask: blendMode.SetString(new FbxString("AlphaMask")); material.TransparencyFactor.Set(0.2); break; case ExportableMaterialBlendMode.AdditiveBlend: blendMode.SetString(new FbxString("AdditiveBlend")); break; } } // Export the texture if (exportableMaterial.HasExportTexture()) { // This is not perfectly unique, but it is good enough for fbx export // better would be to use <durable>_<guid> but that's ugly, and nobody uses // the textures anyway, so... let's leave well enough alone for now. string albedoTextureName = exportableMaterial.DurableName; var fullTextureDir = Path.Combine(G.m_outputDir, kRelativeTextureDir); if (!Directory.Exists(fullTextureDir)) { if (!FileUtils.InitializeDirectoryWithUserError(fullTextureDir)) { throw new IOException("Cannot write textures"); } } string src = exportableMaterial.GetExportTextureFilename(); var textureFileName = albedoTextureName + ".png"; var textureFilePath = Path.Combine(fullTextureDir, textureFileName); FileInfo srcInfo = new FileInfo(src); if (srcInfo.Exists && !new FileInfo(textureFilePath).Exists) { srcInfo.CopyTo(textureFilePath); } FbxFileTexture texture = FbxFileTexture.Create(G.m_scene, albedoTextureName + "_texture"); texture.SetFileName(textureFilePath); texture.SetTextureUse(FbxTexture.ETextureUse.eStandard); texture.SetMappingType(FbxTexture.EMappingType.eUV); texture.SetMaterialUse(FbxFileTexture.EMaterialUse.eModelMaterial); texture.UVSet.Set(new FbxString("uv0")); material.Diffuse.ConnectSrcObject(texture); material.TransparentColor.ConnectSrcObject(texture); } else { foreach (var kvp in exportableMaterial.TextureUris) { string parameterName = kvp.Key; string textureUri = kvp.Value; if (ExportFileReference.IsHttp(textureUri)) { // fbx can't deal with http references to textures continue; } ExportFileReference fileRef = ExportFileReference.GetOrCreateSafeLocal( G.m_disambiguationContext, textureUri, exportableMaterial.UriBase, $"{meshNamespace}_{Path.GetFileName(textureUri)}"); AddTextureToMaterial(G, fileRef, material, parameterName); } } return(material); }
private GlTF_Image(GlTF_Globals globals, string name, GlTF_FileReference fileRef) : base(globals) { this.name = name; this.uri = fileRef; }