示例#1
0
 // Helper for GetModelMeshPayloads() -- this is the level 3 iteration.
 // Enumerates all the GameObjects in a "prefab" and creates geometry for them.
 // Because Unity, the result is an array; but it'll almost certainly be length 1.
 static IEnumerable <PrefabGeometry[]> GetPrefabGameObjs(
     SceneStatePayload payload, Model prefab)
 {
     foreach ((MeshFilter meshFilter, int index) in prefab.GetMeshes().WithIndex())
     {
         // Previous code let these nulls pass silently. I'm not sure why; it was definitely
         // not okay because skipping elements could cause the paired iteration in GetModelMeshes
         // to break. These things should also never happen (AFAIK), so let's add some explicit
         // checking which we can remove later when we're more confident.
         if (meshFilter == null)
         {
             Debug.LogError("Internal error: null meshFilter");
             yield return(null);
         }
         var renderer = meshFilter.GetComponent <MeshRenderer>();
         if (renderer == null)
         {
             Debug.LogError("Internal error: null mesh renderer");
             yield return(null);
         }
         yield return(GetPrefabGameObjMeshes(
                          meshFilter.sharedMesh, renderer.sharedMaterials,
                          payload, prefab, index).ToArray());
     }
 }
示例#2
0
        // -------------------------------------------------------------------------------------------- //
        // Lights
        // -------------------------------------------------------------------------------------------- //

        // Returns lights in "srgb-ish" color space.
        // Note that light values may be > 1, which is not really kosher in sRGB
        static void BuildLights(SceneStatePayload payload)
        {
            var lightPayload = payload.lights;

            lightPayload.ambientColor = RenderSettings.ambientLight;

            for (int i = 0; i < App.Scene.GetNumLights(); ++i)
            {
                var   transform  = App.Scene.GetLight(i).transform;
                Light unityLight = transform.GetComponent <Light>();
                Debug.Assert(unityLight != null);

                Color lightColor = unityLight.color * unityLight.intensity;
                lightColor.a = 1.0f; // No use for alpha with light color.

                // because transform.name might not be unique
                int uniquifyingId = payload.idGenerator.GetIdFromInstanceId(transform);
                // Match the old gltf export logic for easier diffing
                var transformNameNoSpaces = transform.name.Replace(" ", "_");
                lightPayload.lights.Add(new ExportUtils.LightPayload
                {
                    legacyUniqueName = $"{transformNameNoSpaces}_i{uniquifyingId}",
                    name             = transformNameNoSpaces,
                    type             = unityLight.type,
                    lightColor       = lightColor,
                    xform            = ExportUtils.ChangeBasis(transform, payload)
                });
            }
        }
示例#3
0
 static void BuildBrushMeshesFromExportCanvas(SceneStatePayload payload)
 {
     foreach (var exportGroup in ExportUtils.ExportMainCanvas().SplitByGroup())
     {
         payload.groups.Add(BuildGroupPayload(payload, exportGroup));
     }
 }
示例#4
0
 static void BuildModelMeshesFromGameObject(
     GameObject gameObject, SceneStatePayload payload, bool reverseWinding)
 {
     foreach (var modelMesh in GetModelMeshesFromGameObject(gameObject, payload, reverseWinding))
     {
         payload.modelMeshes.Add(BuildModelMeshPayload(modelMesh));
     }
 }
示例#5
0
        static ExportUtils.GroupPayload BuildGroupPayload(SceneStatePayload payload,
                                                          ExportUtils.ExportGroup exportGroup)
        {
            var group = new ExportUtils.GroupPayload();

            group.id = exportGroup.m_group == SketchGroupTag.None ? 0
                : payload.groupIdMapping.GetId(exportGroup.m_group);

            // Flattens the two-level (brush, batch) iteration to a single list of meshes
            // with heterogeneous materials.
            foreach (ExportUtils.ExportBrush brush in exportGroup.SplitByBrush())
            {
                var desc = brush.m_desc;
                foreach (var(batch, batchIndex) in brush.ToGeometryBatches().WithIndex())
                {
                    GeometryPool  geometry = batch.pool;
                    List <Stroke> strokes  = batch.strokes;

                    string legacyUniqueName     = $"{desc.m_DurableName}_{desc.m_Guid}_{group.id}_i{batchIndex}";
                    string friendlyGeometryName = $"brush_{desc.m_DurableName}_g{group.id}_b{batchIndex}";

                    UnityEngine.Profiling.Profiler.BeginSample("ConvertToMetersAndChangeBasis");
                    ExportUtils.ConvertUnitsAndChangeBasis(geometry, payload);
                    UnityEngine.Profiling.Profiler.EndSample();

                    if (payload.reverseWinding)
                    {
                        // Note: this triangle flip intentionally un-does the Unity FBX import flip.
                        ExportUtils.ReverseTriangleWinding(geometry, 1, 2);
                    }

                    if (App.PlatformConfig.EnableExportMemoryOptimization &&
                        payload.temporaryDirectory != null)
                    {
                        string filename = Path.Combine(
                            payload.temporaryDirectory,
                            legacyUniqueName + ".Gpoo");
                        geometry.MakeGeometryNotResident(filename);
                    }
                    group.brushMeshes.Add(new ExportUtils.BrushMeshPayload(
                                              payload.groupIdMapping.GetId(exportGroup.m_group))
                    {
                        legacyUniqueName = legacyUniqueName,
                        // This is the only instance of the mesh, so the node doesn't need an extra instance id
                        nodeName           = friendlyGeometryName,
                        xform              = Matrix4x4.identity,
                        geometry           = geometry,
                        geometryName       = friendlyGeometryName,
                        exportableMaterial = brush.m_desc,
                        strokes            = strokes,
                    });
                }
            }
            return(group);
        }
示例#6
0
        // widget.ReferenceImage must be != null
        // Never returns null
        // id is an instance id
        static ImageQuadPayload BuildImageQuadPayload(
            SceneStatePayload payload, ImageWidget widget, DynamicExportableMaterial material, int id)
        {
            string nodeName = $"image_{widget.GetExportName()}_{id}";

            // The child has no T or R but has some non-uniform S that we need to preserve.
            // I'm going to do this by baking it into the GeometryPool

            GameObject widgetChild = widget.m_ImageQuad.gameObject;
            Matrix4x4  xform       = ExportUtils.ChangeBasis(widget.transform, payload);
            Vector3    localScale  = widgetChild.transform.localScale;

            // localScale is a muddle of aspect ratio and overall size. We don't know which of x or y
            // was modified to set the aspect ratio, so get the size from z.
            if (localScale.z > 0)
            {
                float overallSize = localScale.z;
                localScale /= overallSize;
                xform       = xform * Matrix4x4.Scale(Vector3.one * overallSize);
            }

            // Create pool and bake in the leftover non-uniform scale
            GeometryPool pool = new GeometryPool();

            pool.Layout = material.VertexLayout;
            pool.Append(widgetChild.GetComponent <MeshFilter>().sharedMesh, fallbackColor: Color.white);
            pool.ApplyTransform(
                Matrix4x4.Scale(localScale), Matrix4x4.identity, 1f,
                0, pool.NumVerts);

            // Important: This transform should only be applied once, since the pools are shared, and
            // cannot include any mesh-local transformations.
            ExportUtils.ConvertUnitsAndChangeBasis(pool, payload);
            if (payload.reverseWinding)
            {
                // Note: this triangle flip intentionally un-does the Unity FBX import flip.
                ExportUtils.ReverseTriangleWinding(pool, 1, 2);
            }

            return(new ExportUtils.ImageQuadPayload(payload.groupIdMapping.GetId(widget.Group))
            {
                // because Count always increments, this is guaranteed unique even if two different images
                // have the same export name
                legacyUniqueName = $"refimage_i{payload.imageQuads.Count}",
                // We could (but don't) share the same aspect-ratio'd-quad for all instances of a refimage.
                // Since the mesh is unique to the node, it can have the same name as the node.
                geometryName = nodeName,
                nodeName = nodeName,
                xform = xform,
                geometry = pool,
                exportableMaterial = material,
            });
        }
示例#7
0
        // -------------------------------------------------------------------------------------------- //
        // Xform only, no mesh data
        // -------------------------------------------------------------------------------------------- //

        static void BuildEmptyXforms(SceneStatePayload payload, IEnumerable <MediaWidget> widgets)
        {
            foreach (var mediaWidget in widgets)
            {
                payload.referenceThings.Add(new ExportUtils.XformPayload(
                                                payload.groupIdMapping.GetId(mediaWidget.Group))
                {
                    name  = mediaWidget.GetExportName(),
                    xform = ExportUtils.ChangeBasis(mediaWidget.transform, payload)
                });
            }
        }
示例#8
0
        // Returns meshes in meters, in the proper basis, with proper winding
        static IEnumerable <ModelMesh> GetModelMeshesFromGameObject(GameObject obj,
                                                                    SceneStatePayload payload,
                                                                    bool reverseWinding)
        {
            int    i          = -1;
            string exportName = obj.name;

            foreach (MeshData data in VisitMeshes(obj))
            {
                i++;
                var mesh = data.mesh;
                for (int sm = 0; sm < mesh.subMeshCount; sm++)
                {
                    var exportableMaterial = GetMaterialForMeshData(data);

                    // TODO: The geometry pools could be aggregated, for faster downstream rendering.
                    var geo = new GeometryPool();
                    geo.Layout = exportableMaterial.VertexLayout;
                    geo.Append(mesh, geo.Layout);

                    // Important: This transform should only be applied once, since the pools are shared, and
                    // cannot include any mesh-local transformations.
                    ExportUtils.ConvertToMetersAndChangeBasis(geo, ExportUtils.GetBasisMatrix(payload));

                    if (reverseWinding)
                    {
                        // Note: this triangle flip intentionally un-does the Unity FBX import flip.
                        ExportUtils.ReverseTriangleWinding(geo, 1, 2);
                    }

                    var objectMesh = new ModelMesh {
                        model = null, // The model is only used for uniquefying the texture names.
                        name  = exportName + "_" + i + "_" + sm,
                        id    = data.renderer.gameObject.GetInstanceID(),
                        pool  = geo,
                        xform = ExportUtils.ChangeBasisNonUniformScale(payload, data.renderer.localToWorldMatrix),
                        exportableMaterial = exportableMaterial,
                        meshIndex          = i
                    };

                    yield return(objectMesh);
                }
            }
        }
示例#9
0
        // Unused and untested
#if false
        /// Converts the existing payload to the new color space and vector basis.
        /// Note that scale is never converted and only gamma -> linear is currently supported.
        public static void ConvertPayload(ColorSpace newColorSpace,
                                          Vector3[] newVectorBasis,
                                          SceneStatePayload payload)
        {
            // We don't handle uninitialized color spaces or linear -> srgb conversions.
            // This is just not currently part of the export logic, so it's not implemented here.
            if (newColorSpace == ColorSpace.Uninitialized ||
                payload.colorSpace == ColorSpace.Uninitialized ||
                (payload.colorSpace == ColorSpace.Linear && newColorSpace == ColorSpace.Gamma))
            {
                throw new NotImplementedException();
            }

            if (newColorSpace != payload.colorSpace)
            {
                ExportUtils.ConvertToLinearColorspace(payload.env);
                ExportUtils.ConvertToLinearColorspace(payload.lights);
                foreach (var group in payload.groups)
                {
                    ExportUtils.ConvertToLinearColorspace(group.brushMeshes);
                }
                ExportUtils.ConvertToLinearColorspace(payload.modelMeshes);
            }

            if (newVectorBasis[0] != payload.vectorBasis[0] ||
                newVectorBasis[1] != payload.vectorBasis[1] ||
                newVectorBasis[2] != payload.vectorBasis[2])
            {
                // Never apply a scale change when changing basis.
                Matrix4x4 basis = ExportUtils.GetBasisMatrix(payload);
                foreach (var group in payload.groups)
                {
                    ExportUtils.ChangeBasis(group.brushMeshes, basis);
                }
                ExportUtils.ChangeBasis(payload.modelMeshes, basis);
                ExportUtils.ChangeBasis(payload.referenceImages, basis);
                ExportUtils.ChangeBasis(payload.referenceModels, basis);
            }

            payload.colorSpace  = newColorSpace;
            payload.vectorBasis = newVectorBasis;
        }
示例#10
0
        // -------------------------------------------------------------------------------------------- //
        // Environment
        // -------------------------------------------------------------------------------------------- //

        static void BuildEnvironment(SceneStatePayload payload, bool includeSkyCubemap = false)
        {
            var settings = SceneSettings.m_Instance;

            payload.env.guid        = settings.GetDesiredPreset().m_Guid;
            payload.env.description = settings.GetDesiredPreset().m_Description;
            if (includeSkyCubemap)
            {
                // Most of the environment payload is very small data but if the skybox cubemap is included
                // here, it will export the full texture as part of the export process, which is usually not
                // what we want to do.
                payload.env.skyCubemap = settings.GetDesiredPreset().m_RenderSettings.m_SkyboxCubemap;
            }
            payload.env.useGradient    = settings.InGradient;
            payload.env.skyColorA      = settings.SkyColorA;
            payload.env.skyColorB      = settings.SkyColorB;
            payload.env.skyGradientDir = settings.GradientOrientation * Vector3.up;
            payload.env.fogColor       = settings.FogColor;
            payload.env.fogDensity     = settings.FogDensity;
        }
示例#11
0
        public static SceneStatePayload GetExportPayloadForGameObject(GameObject gameObject,
                                                                      AxisConvention axes,
                                                                      Environment env)
        {
            var payload = new SceneStatePayload(axes);

            payload.env.skyCubemap = env == null ? null : env.m_RenderSettings.m_SkyboxCubemap;
            payload.lights         = new ExportUtils.LightsPayload();
            // unused test code
#if TEST_ENVIRONMENTS_WITH_SCENE_LIGHTS
            {
                var lights = payload.lights;
                lights.ambientColor = RenderSettings.ambientLight;

#if true
                // Scene lights from Standard enviroment
                lights.elements.Add(new ExportUtils.Light {
                    name       = "SceneLight0",
                    id         = 0,
                    type       = LightType.Directional,
                    lightColor = new Color32(198, 208, 253),
                    xform      = ExportUtils.ChangeBasisNonUniformScale(
                        payload, Matrix4x4.TRS(
                            new Vector3(0f, 0.21875f, -.545875f),
                            Quaternion.Euler(60, 0, 26),
                            Vector3.one))
                });

                lights.elements.Add(new ExportUtils.Light {
                    name       = "SceneLight1",
                    id         = 1,
                    type       = LightType.Directional,
                    lightColor = new Color32(109, 107, 88),
                    xform      = ExportUtils.ChangeBasisNonUniformScale(
                        payload,
                        Matrix4x4.TRS(
                            new Vector3(0f, 0.21875f, -.545875f),
                            Quaternion.Euler(140, 0, 40),
                            Vector3.one)),
                });
#else
                // Scene lights from Dress Form environment
                lights.elements.Add(new ExportUtils.Light {
                    name       = "SceneLight0",
                    id         = 0,
                    type       = LightType.Directional,
                    lightColor = new Color32(255, 234, 198),
                    xform      = ExportUtils.ChangeBasisNonUniformScale(
                        payload, Matrix4x4.TRS(
                            new Vector3(0f, 0.7816665f, -.220875f),
                            Quaternion.Euler(50, 42, 26),
                            Vector3.one))
                });

                lights.elements.Add(new ExportUtils.Light {
                    name       = "SceneLight1",
                    id         = 1,
                    type       = LightType.Directional,
                    lightColor = new Color32(91, 90, 74),
                    xform      = ExportUtils.ChangeBasisNonUniformScale(
                        payload,
                        Matrix4x4.TRS(
                            new Vector3(0f, .636532f, -.6020539f),
                            Quaternion.Euler(140, 47, 40),
                            Vector3.one)),
                });
#endif
            }
#endif

            // The determinant can be used to detect if the basis-change has a mirroring.
            // This matters because a mirroring turns the triangles inside-out, requiring
            // us to flip their winding to preserve the surface orientation.
            bool reverseTriangleWinding = (ExportUtils.GetBasisMatrix(payload).determinant < 0);

            BuildModelMeshesFromGameObject(gameObject, payload, reverseTriangleWinding);
            return(payload);
        }
示例#12
0
        // Helper for GetModelMeshPayloads() -- this is the level 4 iteration.
        // Pass:
        //   mesh / meshMaterials - the Mesh to generate geometry for
        //   payload - the payload being exported
        //   prefab - the owner "prefab"
        //   meshIndex - the index of this Mesh within its owner "prefab"
        static IEnumerable <PrefabGeometry> GetPrefabGameObjMeshes(
            Mesh mesh, Material[] meshMaterials,
            SceneStatePayload payload, Model prefab, int meshIndex)
        {
            if (meshMaterials.Length != mesh.subMeshCount)
            {
                throw new ArgumentException("meshMaterials length");
            }
            string exportName = prefab.GetExportName();

            IExportableMaterial[] exportableMaterials = meshMaterials.Select(
                mat => prefab.GetExportableMaterial(mat)).ToArray();
            VertexLayout?[] layouts = exportableMaterials.Select(iem => iem?.VertexLayout).ToArray();
            // TODO(b/142396408)
            // Is it better to write color/texcoord that we don't need, just to satisfy the layout?
            // Or should we remove color/texcoord from the layout if the Mesh doesn't have them?
            // Right now we do the former. I think the fix should probably be in the collector;
            // it shouldn't return an exportableMaterial that is a superset of what the mesh contains.
            GeometryPool[] subMeshPools = GeometryPool.FromMesh(
                mesh, layouts, fallbackColor: Color.white, useFallbackTexcoord: true);

            for (int subMeshIndex = 0; subMeshIndex < mesh.subMeshCount; subMeshIndex++)
            {
                // See if this material is a Blocks material.
                Material mat = meshMaterials[subMeshIndex];

                // At import time, ImportMaterialCollector now ensures that _every_ UnityEngine.Material
                // imported also comes with an IExportableMaterial of some kind (BrushDescriptor for
                // Blocks/TB, and DynamicExportableMaterial for everything else). This lookup shouldn't fail.
                IExportableMaterial exportableMaterial = exportableMaterials[subMeshIndex];
                if (exportableMaterial == null)
                {
                    Debug.LogWarning($"Model {prefab.HumanName} has a non-exportable material {mat.name}");
                    continue;
                }

                GeometryPool geo = subMeshPools[subMeshIndex];
                // TODO(b/140634751): lingering sanity-checking; we can probably remove this for M24
                if (geo.Layout.bUseColors)
                {
                    Debug.Assert(geo.m_Colors.Count == geo.NumVerts);
                }

                // Important: This transform should only be applied once per prefab, since the pools are
                // shared among all the instances, and cannot include any mesh-local transformations.
                // If the pools share data (which is currently impossible), then additionally
                // the transform should only be applied once to each set of vertex data.
                ExportUtils.ConvertUnitsAndChangeBasis(geo, payload);

                if (payload.reverseWinding)
                {
                    // There are many ways of reversing winding; choose the one that matches Unity's fbx flip
                    ExportUtils.ReverseTriangleWinding(geo, 1, 2);
                }

                yield return(new PrefabGeometry
                {
                    model = prefab,
                    name = exportName + "_" + meshIndex + "_" + subMeshIndex,
                    pool = geo,
                    exportableMaterial = exportableMaterial,
                });
            }
        }
示例#13
0
        private static void BuildModelsAsModelMeshes(
            SceneStatePayload payload, IEnumerable <ModelWidget> modelWidgets)
        {
            // This is a quadruple-nested loop that's triply flattened into a single IEnumerable.
            // The structure of the data is is:
            // 1. There are 1+ Models (which I'll call "prefab" because Model is a loaded term here)
            // 2. Each "prefab" is used by 1+ ModelWidgets ("instance")
            // 3. Each ModelWidget, and the "prefab", contains 1+ GameObjects (which has a single Mesh)
            // 4. Each Mesh has 1+ unity submeshes (almost always exactly 1)
            //    These are converted to ModelMeshPayload
            //
            // The resulting ModelMeshPayloads are a mixture of data from all 4 levels, for example
            // - ModelMeshPayload.model comes from level 1
            // - ModelMeshPayload.modelId comes from level 2
            // - ModelMeshPayload.xform comes from level 3
            // - ModelMeshPayload.pool comes from level 4
            //
            // Orthogonal to this nesting, some data comes from the "prefab" and some from the "instance",
            // since we don't want to have to convert a mesh into GeometryPool once per instance.
            // So we iterate level 3 for the Model once, up front; then each ModelWidget level 3 is
            // a parallel iteration with that Model's pre-computed iteration.
            foreach (var group in modelWidgets.GroupBy(widget => widget.Model))
            {
                Model prefab = group.Key;
                // Each element represents a GameObject in the "prefab"
                List <PrefabGeometry[]> prefabObjs = GetPrefabGameObjs(payload, prefab).ToList();

                foreach ((ModelWidget widget, int widgetIndex) in group.WithIndex())
                {
                    Matrix4x4 widgetXform = ExportUtils.ChangeBasis(widget.transform, payload);
                    // Acts like our AsScene[], AsCanvas[] accessors
                    var AsWidget = new TransformExtensions.RelativeAccessor(widget.transform);

                    // Verify that it's okay to parallel-iterate over the prefab and instance gameObjs.
                    // It should be, unless one or the other has mucked with their m_MeshChildren.
                    MeshFilter[] instanceObjs = widget.GetMeshes();
                    if (prefabObjs.Count != instanceObjs.Length)
                    {
                        Debug.LogError($"Bad Model instance: {prefabObjs.Count} {instanceObjs.Length}");
                        // TODO: check order as well, somehow
                        continue;
                    }

                    // Parallel iterate, taking shared things (GeometryPool, material, name) from the
                    // "prefab" and xforms, unique ids, etc from the "instance".
                    for (int objIndex = 0; objIndex < prefabObjs.Count; ++objIndex)
                    {
                        PrefabGeometry[] prefabSubMeshes = prefabObjs[objIndex];
                        GameObject       instanceObj     = instanceObjs[objIndex].gameObject;
                        Matrix4x4        localXform      = ExportUtils.ChangeBasis(AsWidget[instanceObj.transform], payload);

                        int       objId = payload.idGenerator.GetIdFromInstanceId(instanceObj);
                        Matrix4x4 xform = ExportUtils.ChangeBasis(instanceObj.transform, payload);
                        foreach (PrefabGeometry prefabSubMesh in prefabSubMeshes)
                        {
                            payload.modelMeshes.Add(new ExportUtils.ModelMeshPayload(
                                                        payload.groupIdMapping.GetId(widget.Group))
                            {
                                // Copied from "prefab"
                                model              = prefabSubMesh.model,
                                geometry           = prefabSubMesh.pool,
                                exportableMaterial = prefabSubMesh.exportableMaterial,
                                geometryName       = prefabSubMesh.name,
                                // Unique to instance
                                legacyUniqueName = $"{prefabSubMesh.name}_i{objId}",
                                nodeName         = $"{prefabSubMesh.name}_{widgetIndex}",
                                parentXform      = widgetXform,
                                localXform       = localXform,
                                modelId          = widgetIndex,
                                xform            = xform,
                            });
                        }
                    }
                }
            }
        }
示例#14
0
        // -------------------------------------------------------------------------------------------- //
        // Public API
        // -------------------------------------------------------------------------------------------- //

        public static SceneStatePayload GetExportPayload(
            AxisConvention axes,
            bool includeLocalMediaContent = false,
            string temporaryDirectory     = null)
        {
            UnityEngine.Profiling.Profiler.BeginSample("GetSceneStatePayload");

            var payload = new SceneStatePayload(axes, temporaryDirectory);

            BuildGenerator(payload);
            BuildEnvironment(payload);
            BuildLights(payload);

            UnityEngine.Profiling.Profiler.BeginSample("BuildBrushMeshes");
            BuildBrushMeshes(payload);
            UnityEngine.Profiling.Profiler.EndSample();

            {
                bool IsModelExportable(ModelWidget w)
                {
                    if (!w.Model.AllowExport)
                    {
                        return(false);
                    }
                    if (w.Model.GetLocation().GetLocationType() == Model.Location.Type.LocalFile)
                    {
                        return(includeLocalMediaContent && App.Config.m_EnableReferenceModelExport);
                    }
                    else
                    {
                        return(true);
                    }
                }

                UnityEngine.Profiling.Profiler.BeginSample("BuildModelMeshes");
                // TODO: inactive ModelWidgets should be fixed in WidgetManager.
                var(exportable, notExportable) = WidgetManager.m_Instance.ModelWidgets
                                                 .Where(w => w.Model != null && w.isActiveAndEnabled)
                                                 .Partition(IsModelExportable);
                BuildModelsAsModelMeshes(payload, exportable);
                BuildEmptyXforms(payload, notExportable);
                UnityEngine.Profiling.Profiler.EndSample();
            }

            {
                bool IsImageExportable(ImageWidget w)
                {
                    return(includeLocalMediaContent && w.ReferenceImage != null);
                }

                var media2dWidgets = WidgetManager.m_Instance.MediaWidgets
                                     .Select(grab => grab.m_WidgetScript as Media2dWidget)
                                     .Where(w => w != null && w.isActiveAndEnabled);
                var(images, notImages)         = media2dWidgets.Partition(w => w is ImageWidget);
                var(exportable, notExportable) = images.Cast <ImageWidget>().Partition(IsImageExportable);

                foreach (var group in exportable.GroupBy(widget => widget.ReferenceImage))
                {
                    ReferenceImage ri = group.Key;
                    if (ri == null)
                    {
                        Debug.Assert(false, "Empty ImageWidgets");
                        continue;
                    }
                    var material = CreateImageQuadMaterial(ri);
                    foreach ((ImageWidget image, int idx) in group.WithIndex())
                    {
                        payload.imageQuads.Add(BuildImageQuadPayload(payload, image, material, idx));
                    }
                }

                BuildEmptyXforms(payload, notImages);
                BuildEmptyXforms(payload, notExportable);
            }

            UnityEngine.Profiling.Profiler.EndSample();
            return(payload);
        }
示例#15
0
        // -------------------------------------------------------------------------------------------- //
        // Brush Meshes
        // -------------------------------------------------------------------------------------------- //

        static void BuildBrushMeshes(SceneStatePayload payload)
        {
            BuildBrushMeshesFromExportCanvas(payload);
        }
示例#16
0
        // -------------------------------------------------------------------------------------------- //
        // Generator
        // -------------------------------------------------------------------------------------------- //

        static void BuildGenerator(SceneStatePayload payload)
        {
            payload.generator = string.Format(payload.generator,
                                              App.Config.m_VersionNumber,
                                              App.Config.m_BuildStamp);
        }