Ejemplo n.º 1
0
        // Populates glTF metadata and scene extras fields.
        private void SetExtras(
            GlTF_ScriptableExporter exporter, ExportUtils.SceneStatePayload payload)
        {
            Color   skyColorA      = payload.env.skyColorA;
            Color   skyColorB      = payload.env.skyColorB;
            Vector3 skyGradientDir = payload.env.skyGradientDir;

            // Scene-level extras:
            exporter.G.extras["TB_EnvironmentGuid"] = payload.env.guid.ToString("D");
            exporter.G.extras["TB_Environment"]     = payload.env.description;
            exporter.G.extras["TB_UseGradient"]     = payload.env.useGradient ? "true" : "false";
            exporter.G.extras["TB_SkyColorA"]       = CommaFormattedFloatRGB(skyColorA);
            exporter.G.extras["TB_SkyColorB"]       = CommaFormattedFloatRGB(skyColorB);
            Matrix4x4 exportFromUnity = AxisConvention.GetFromUnity(payload.axes);

            exporter.G.extras["TB_SkyGradientDirection"] = CommaFormattedVector3(
                exportFromUnity * skyGradientDir);
            exporter.G.extras["TB_FogColor"]   = CommaFormattedFloatRGB(payload.env.fogColor);
            exporter.G.extras["TB_FogDensity"] = payload.env.fogDensity.ToString();

            // TODO: remove when Poly starts using the new color data
            exporter.G.extras["TB_SkyColorHorizon"] = CommaFormattedFloatRGB(skyColorA);
            exporter.G.extras["TB_SkyColorZenith"]  = CommaFormattedFloatRGB(skyColorB);
        }
Ejemplo n.º 2
0
        private void WriteObjectsAndConnections(GlTF_ScriptableExporter exporter,
                                                SceneStatePayload payload)
        {
            foreach (BrushMeshPayload meshPayload in payload.groups.SelectMany(g => g.brushMeshes))
            {
                exporter.ExportMeshPayload(payload, meshPayload, GetGroupNode(meshPayload.group));
            }

            foreach (var sameInstance in payload.modelMeshes.GroupBy(m => (m.model, m.modelId)))
            {
                var modelMeshPayloads = sameInstance.ToList();
                if (modelMeshPayloads.Count == 0)
                {
                    continue;
                }

                // All of these pieces will come from the same Widget and therefore will have
                // the same group id, root transform, etc
                var       first     = modelMeshPayloads[0];
                GlTF_Node groupNode = GetGroupNode(first.group);

                if (exporter.G.Gltf2)
                {
                    // Non-Poly exports get a multi-level structure for meshes: transform node on top,
                    // all the contents as direct children.
                    string rootNodeName = $"model_{first.model.GetExportName()}_{first.modelId}";
                    if (modelMeshPayloads.Count == 1 && first.localXform.isIdentity)
                    {
                        // Condense the two levels into one; give the top-level node the same name
                        // it would have had had it been multi-level.
                        GlTF_Node newNode = exporter.ExportMeshPayload(payload, first, groupNode);
                        newNode.PresentationNameOverride = rootNodeName;
                    }
                    else
                    {
                        GlTF_Node parentNode = GlTF_Node.Create(
                            exporter.G, rootNodeName,
                            first.parentXform, groupNode);
                        foreach (var modelMeshPayload in modelMeshPayloads)
                        {
                            exporter.ExportMeshPayload(payload, modelMeshPayload, parentNode,
                                                       modelMeshPayload.localXform);
                        }
                    }
                }
                else
                {
                    // The new code's been tested with Poly and works fine, but out of
                    // an abundance of caution, keep Poly unchanged
                    foreach (var modelMeshPayload in modelMeshPayloads)
                    {
                        exporter.ExportMeshPayload(payload, modelMeshPayload, groupNode);
                    }
                }
            }

            foreach (ImageQuadPayload meshPayload in payload.imageQuads)
            {
                exporter.ExportMeshPayload(payload, meshPayload, GetGroupNode(meshPayload.group));
            }

            foreach (var(xformPayload, i) in payload.referenceThings.WithIndex())
            {
                string uniqueName = $"empty_{xformPayload.name}_{i}";
                var    node       = GlTF_Node.Create(exporter.G, uniqueName, xformPayload.xform, null);
                node.PresentationNameOverride = $"empty_{xformPayload.name}";
            }
        }
Ejemplo n.º 3
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;
                }
            }
        }