コード例 #1
0
        internal static Texture2D RenderVectorImageToTexture2D(UnityEngine.Object o, int width, int height, Material mat, int antiAliasing = 1)
        {
            var vi = o as VectorImage;

            if (o == null)
            {
                return(null);
            }

            if (width <= 0 || height <= 0)
            {
                return(null);
            }

            RenderTexture rt        = null;
            var           oldActive = RenderTexture.active;

            var desc = new RenderTextureDescriptor(width, height, RenderTextureFormat.ARGB32, 0)
            {
                msaaSamples = antiAliasing,
                sRGB        = QualitySettings.activeColorSpace == ColorSpace.Linear
            };

            rt = RenderTexture.GetTemporary(desc);
            RenderTexture.active = rt;

            Vector2[] vertices       = null;
            UInt16[]  indices        = null;
            Vector2[] uvs            = null;
            Color[]   colors         = null;
            Vector2[] settingIndices = null;
            Texture2D atlas          = null;
            Vector2   size           = Vector2.zero;

            if (InternalBridge.GetDataFromVectorImage(o, ref vertices, ref indices, ref uvs, ref colors, ref settingIndices, ref atlas, ref size))
            {
                vertices = vertices.Select(v => new Vector2(v.x / size.x, 1.0f - v.y / size.y)).ToArray();
                var atlasWithEncodedSettings = vi.atlas != null?BuildAtlasWithEncodedSettings(vi.settings, vi.atlas) : null;

                VectorUtils.RenderFromArrays(vertices, indices, uvs, colors, settingIndices, atlasWithEncodedSettings, mat);
                Texture2D.DestroyImmediate(atlasWithEncodedSettings);
            }
            else
            {
                RenderTexture.active = oldActive;
                RenderTexture.ReleaseTemporary(rt);
                return(null);
            }

            Texture2D copy = new Texture2D(width, height, TextureFormat.RGBA32, false);

            copy.hideFlags = HideFlags.HideAndDontSave;
            copy.ReadPixels(new Rect(0, 0, width, height), 0, 0);
            copy.Apply();

            RenderTexture.active = oldActive;
            RenderTexture.ReleaseTemporary(rt);

            return(copy);
        }
コード例 #2
0
        /// <summary>Builds a sprite asset from a scene tessellation.</summary>
        /// <param name="geoms">The list of tessellated Geometry instances</param>
        /// <param name="rect">The position and size of the sprite geometry</param>
        /// <param name="svgPixelsPerUnit">How many SVG "pixels" map into a Unity unit</param>
        /// <param name="alignment">The position of the sprite origin</param>
        /// <param name="customPivot">If alignment is <see cref="Alignment.Custom"/>, customPivot is used to compute the sprite origin</param>
        /// <param name="gradientResolution">The maximum size of the texture holding gradient data</param>
        /// <param name="flipYAxis">True to have the positive Y axis to go downward.</param>
        /// <returns>A new Sprite containing the provided geometry. The Sprite may have a texture if the geometry has any texture and/or gradients</returns>
        public static Sprite BuildSprite(List <Geometry> geoms, Rect rect, float svgPixelsPerUnit, Alignment alignment, Vector2 customPivot, UInt16 gradientResolution, bool flipYAxis = false)
        {
            // Generate atlas
            var texAtlas = GenerateAtlasAndFillUVs(geoms, gradientResolution);

            List <Vector2> vertices;
            List <UInt16>  indices;
            List <Color>   colors;
            List <Vector2> uvs;
            List <Vector2> settingIndices;

            FillVertexChannels(geoms, 1.0f, texAtlas != null, out vertices, out indices, out colors, out uvs, out settingIndices, flipYAxis);

            Texture2D texture = texAtlas != null ? texAtlas.Texture : null;

            if (rect == Rect.zero)
            {
                rect = VectorUtils.Bounds(vertices);
                VectorUtils.RealignVerticesInBounds(vertices, rect, flipYAxis);
            }
            else if (flipYAxis)
            {
                VectorUtils.FlipVerticesInBounds(vertices, rect);

                // The provided rect should normally contain the whole geometry, but since VectorUtils.SceneNodeBounds doesn't
                // take the strokes into account, some triangles may appear outside the rect. We clamp the vertices as a workaround for now.
                VectorUtils.ClampVerticesInBounds(vertices, rect);
            }

            var pivot = GetPivot(alignment, customPivot, rect, flipYAxis);

            var sprite = InternalBridge.CreateSprite(rect, pivot, svgPixelsPerUnit, texture);

            sprite.OverrideGeometry(vertices.ToArray(), indices.ToArray());

            if (colors != null)
            {
                var colors32 = colors.Select(c => (Color32)c);
                using (var nativeColors = new NativeArray <Color32>(colors32.ToArray(), Allocator.Temp))
                    sprite.SetVertexAttribute <Color32>(VertexAttribute.Color, nativeColors);
            }
            if (uvs != null)
            {
                using (var nativeUVs = new NativeArray <Vector2>(uvs.ToArray(), Allocator.Temp))
                    sprite.SetVertexAttribute <Vector2>(VertexAttribute.TexCoord0, nativeUVs);
                using (var nativeSettingIndices = new NativeArray <Vector2>(settingIndices.ToArray(), Allocator.Temp))
                    sprite.SetVertexAttribute <Vector2>(VertexAttribute.TexCoord2, nativeSettingIndices);
            }

            return(sprite);
        }
コード例 #3
0
        internal static void MakeVectorImageAsset(IEnumerable <VectorUtils.Geometry> geoms, uint rasterSize, out UnityEngine.Object outAsset, out Texture2D outTexAtlas)
        {
            var atlas = VectorUtils.GenerateAtlas(geoms, rasterSize, false, false);

            if (atlas != null)
            {
                VectorUtils.FillUVs(geoms, atlas);
            }

            bool hasTexture = atlas != null && atlas.Texture != null;

            outTexAtlas = hasTexture ? atlas.Texture : null;

            var vertices = new List <InternalBridge.VectorImageVertexBridge>(100);
            var indices  = new List <UInt16>(300);
            var settings = new List <InternalBridge.GradientSettingsBridge>();

            var min = new Vector2(float.MaxValue, float.MaxValue);
            var max = new Vector2(float.MinValue, float.MinValue);

            foreach (var geom in geoms)
            {
                if (geom.Vertices.Length == 0)
                {
                    continue;
                }
                var b = VectorUtils.Bounds(geom.Vertices.Select(v => geom.WorldTransform.MultiplyPoint(v)));
                min = Vector2.Min(min, b.min);
                max = Vector2.Max(max, b.max);
            }
            var bounds = Rect.zero;

            if (min.x != float.MaxValue)
            {
                bounds = new Rect(min, max - min);
            }

            // Save written settings to avoid duplicates
            var writtenSettings = new HashSet <int>();

            writtenSettings.Add(0);

            // Create a map of filling -> atlas entry
            var fillEntries = new Dictionary <IFill, VectorUtils.PackRectItem>();

            if (atlas != null && atlas.Entries != null)
            {
                foreach (var entry in atlas.Entries)
                {
                    if (entry.Fill != null)
                    {
                        fillEntries[entry.Fill] = entry;
                    }
                }
            }

            if (hasTexture && atlas != null && atlas.Entries != null && atlas.Entries.Count > 0)
            {
                // Write the 'white' texel info
                var entry = atlas.Entries[atlas.Entries.Count - 1];
                settings.Add(new InternalBridge.GradientSettingsBridge()
                {
                    gradientType = InternalBridge.GradientTypeBridge.Linear,
                    addressMode  = InternalBridge.AddressModeBridge.Wrap,
                    radialFocus  = Vector2.zero,
                    location     = new RectInt((int)entry.Position.x, (int)entry.Position.y, (int)entry.Size.x, (int)entry.Size.y)
                });
            }

            foreach (var geom in geoms)
            {
                for (int i = 0; i < geom.Vertices.Length; ++i)
                {
                    var v = geom.WorldTransform.MultiplyPoint(geom.Vertices[i]);
                    v -= bounds.position;
                    geom.Vertices[i] = v;
                }

                VectorUtils.AdjustWinding(geom.Vertices, geom.Indices, VectorUtils.WindingDir.CCW);

                var count = vertices.Count;
                for (int i = 0; i < geom.Vertices.Length; ++i)
                {
                    Vector3 p = (Vector3)geom.Vertices[i];
                    p.z = Vertex.nearZ;
                    vertices.Add(new InternalBridge.VectorImageVertexBridge()
                    {
                        position     = p,
                        uv           = hasTexture ? geom.UVs[i] : Vector2.zero,
                        tint         = geom.Color,
                        settingIndex = (uint)geom.SettingIndex
                    });
                }

                indices.AddRange(geom.Indices.Select(i => (UInt16)(i + count)));

                if (atlas != null && atlas.Entries != null && atlas.Entries.Count > 0)
                {
                    VectorUtils.PackRectItem entry;
                    if (geom.Fill == null || !fillEntries.TryGetValue(geom.Fill, out entry) || writtenSettings.Contains(entry.SettingIndex))
                    {
                        continue;
                    }

                    writtenSettings.Add(entry.SettingIndex);

                    var gradientType = GradientFillType.Linear;
                    var radialFocus  = Vector2.zero;
                    var addressMode  = AddressMode.Wrap;

                    var gradientFill = geom.Fill as GradientFill;
                    if (gradientFill != null)
                    {
                        gradientType = gradientFill.Type;
                        radialFocus  = gradientFill.RadialFocus;
                        addressMode  = gradientFill.Addressing;
                    }

                    var textureFill = geom.Fill as TextureFill;
                    if (textureFill != null)
                    {
                        addressMode = textureFill.Addressing;
                    }

                    settings.Add(new InternalBridge.GradientSettingsBridge()
                    {
                        gradientType = (InternalBridge.GradientTypeBridge)gradientType,
                        addressMode  = (InternalBridge.AddressModeBridge)addressMode,
                        radialFocus  = radialFocus,
                        location     = new RectInt((int)entry.Position.x, (int)entry.Position.y, (int)entry.Size.x, (int)entry.Size.y)
                    });
                }
            }

            outAsset = InternalBridge.MakeVectorImageAsset(vertices, indices, outTexAtlas, settings, bounds.size);
        }