// indices arrays are optional - if null is passed the index will be 0, 1, 2... up to values array length.
        // this is done to avoid allocating a separate array just to pass linear indices
        internal static UVTransform CalculateDelta(IList <Vector2> src, IList <int> srcIndices, IList <Vector2> dst, IList <int> dstIndices)
        {
            // rotate to match target points by comparing the angle between old UV and new auto projection
            Vector2 srcAngle = src[GetIndex(srcIndices, 1)] - src[GetIndex(srcIndices, 0)];
            Vector2 dstAngle = dst[GetIndex(dstIndices, 1)] - dst[GetIndex(dstIndices, 0)];

            float rotation = Vector2.Angle(dstAngle, srcAngle);

            if (Vector2.Dot(Vector2.Perpendicular(dstAngle), srcAngle) < 0)
            {
                rotation = 360f - rotation;
            }

            Vector2 dstCenter = dstIndices == null?Bounds2D.Center(dst) : Bounds2D.Center(dst, dstIndices);

            // inverse the rotation to get an axis-aligned scale
            Vector2  dstSize   = GetRotatedSize(dst, dstIndices, dstCenter, -rotation);
            Bounds2D srcBounds = srcIndices == null ? new Bounds2D(src) : new Bounds2D(src, srcIndices);
            Vector2  scale     = dstSize.DivideBy(srcBounds.size);
            Vector2  srcCenter = srcBounds.center * scale;

            return(new UVTransform()
            {
                translation = dstCenter - srcCenter,
                rotation = rotation,
                scale = dstSize.DivideBy(srcBounds.size)
            });
        }
Example #2
0
        static void ApplyUVSettings(Vector2[] uvs, int[] indexes, AutoUnwrapSettings uvSettings)
        {
            int len = indexes.Length;

            switch (uvSettings.fill)
            {
            case AutoUnwrapSettings.Fill.Tile:
                break;

            case AutoUnwrapSettings.Fill.Fit:
                FitUVs(uvs, indexes);
                break;

            case AutoUnwrapSettings.Fill.Stretch:
                StretchUVs(uvs, indexes);
                break;
            }

            if (!uvSettings.useWorldSpace && uvSettings.anchor != AutoUnwrapSettings.Anchor.None)
            {
                ApplyUVAnchor(uvs, indexes, uvSettings.anchor);
            }

            // Apply transform last, so that fill and justify don't override it.
            if (uvSettings.scale.x != 1f ||
                uvSettings.scale.y != 1f ||
                uvSettings.rotation != 0f)
            {
                Vector2 center = Bounds2D.Center(uvs, indexes);

                for (int i = 0; i < len; i++)
                {
                    uvs[indexes[i]] = uvs[indexes[i]].ScaleAroundPoint(center, uvSettings.scale);
                    uvs[indexes[i]] = uvs[indexes[i]].RotateAroundPoint(center, uvSettings.rotation);
                }
            }

            if (uvSettings.flipU || uvSettings.flipV || uvSettings.swapUV)
            {
                for (int i = 0; i < len; i++)
                {
                    float u = uvs[indexes[i]].x,
                          v = uvs[indexes[i]].y;

                    if (uvSettings.flipU)
                    {
                        u = -u;
                    }

                    if (uvSettings.flipV)
                    {
                        v = -v;
                    }

                    if (!uvSettings.swapUV)
                    {
                        uvs[indexes[i]].x = u;
                        uvs[indexes[i]].y = v;
                    }
                    else
                    {
                        uvs[indexes[i]].x = v;
                        uvs[indexes[i]].y = u;
                    }
                }
            }

            for (int i = 0; i < indexes.Length; i++)
            {
                uvs[indexes[i]].x -= uvSettings.offset.x;
                uvs[indexes[i]].y -= uvSettings.offset.y;
            }
        }