Esempio n. 1
0
        // 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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
 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]);
 }
Esempio n. 4
0
        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;
                }
            }
        }
Esempio n. 5
0
 public bool IsHttp()
 {
     return(ExportFileReference.IsHttp(m_uri));
 }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
 private GlTF_Image(GlTF_Globals globals, string name, GlTF_FileReference fileRef)
     : base(globals)
 {
     this.name = name;
     this.uri  = fileRef;
 }