Exemplo n.º 1
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);

            // The Sprite.Create(Rect, Vector2, float, Texture2D) method is internal. Using reflection
            // until it becomes public.
            var spriteCreateMethod = typeof(Sprite).GetMethod("Create", BindingFlags.Static | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Rect), typeof(Vector2), typeof(float), typeof(Texture2D) }, null);
            var sprite             = spriteCreateMethod.Invoke(null, new object[] { rect, pivot, svgPixelsPerUnit, texture }) as Sprite;

            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);
        }