private static RectangleTransform[] GenerateUVTransforms(Size originalSize, Size newSize, Rectangle[] sourceRects, Rectangle[] destinationRects) { var outputTransforms = new RectangleTransform[sourceRects.Length]; for (int i = 0; i < sourceRects.Length; i++) { Rectangle s = sourceRects[i]; Rectangle d = destinationRects[i]; var transform = new RectangleTransform { // figure out total image size and convert rects to percentages Top = 1 - (s.Top / (double)originalSize.Height), Bottom = 1 - (s.Bottom / (double)originalSize.Height), Left = s.Left / (double)originalSize.Width, Right = s.Right / (double)originalSize.Width, OffsetX = (s.Left / (double)originalSize.Width) - (d.Left / (double)newSize.Width), OffsetY = ((s.Top / (double)originalSize.Height) - (d.Top / (double)newSize.Height)), ScaleX = (double)originalSize.Width / (double)newSize.Width, ScaleY = (double)originalSize.Height / (double)newSize.Height }; outputTransforms[i] = transform; } return(outputTransforms); }
public void TransformUVsForTextureTile(SlicingOptions options, Vector2 textureTile, RectangleTransform[] uvTransforms, CancellationToken cancellationToken) { Trace.TraceInformation("Transforming UV points for texture tile {0},{1}", textureTile.X, textureTile.Y); int newUVCount = 0, failedUVCount = 0, transformUVCount = 0; cancellationToken.ThrowIfCancellationRequested(); var faces = Texture.GetFaceListFromTextureTile( options.TextureSliceY, options.TextureSliceX, textureTile.X, textureTile.Y, this); var uvIndices = faces.AsParallel().SelectMany(f => f.TextureVertexIndexList).WithCancellation(cancellationToken).Distinct(); var uvs = uvIndices.Select(i => TextureList[i - 1]).ToList(); Trace.TraceInformation("Selected UVs"); foreach (var uv in uvs) { cancellationToken.ThrowIfCancellationRequested(); var transforms = uvTransforms.Where(t => t.ContainsPoint(uv.OriginalX, uv.OriginalY)); if (transforms.Any()) { RectangleTransform transform = transforms.First(); lock (uv) { if (uv.Transformed) { // This was already transformed in another extent, so we'll have to copy it int newIndex = uv.CloneOriginal(TextureList); TextureList[newIndex - 1].Transform(transform); // Update all faces using the old UV in this extent faces.AsParallel().Where(f => f.TextureVertexIndexList.Contains(uv.Index)).WithCancellation(cancellationToken).ForAll(face => face.UpdateTextureVertexIndex(uv.Index, newIndex, false)); newUVCount++; } else { uv.Transform(transform); transformUVCount++; } } } else { failedUVCount++; } } Trace.TraceInformation("UV Transform results ({3},{4}): {0} success, {1} new, {2} failed.", transformUVCount, newUVCount, failedUVCount, textureTile.X, textureTile.Y); // Write out a marked up image file showing where lost UV's occured if (options.Debug) { var notTransformedUVs = uvs.Where(u => !u.Transformed).ToArray(); var relevantTransforms = uvTransforms; options.TextureInstance.MarkupTextureTransforms(options.Texture, relevantTransforms, notTransformedUVs, textureTile); } }