mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Initial commit
This commit is contained in:
commit
3c7cc0c973
8391 changed files with 704313 additions and 0 deletions
|
@ -0,0 +1,213 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Common
|
||||
{
|
||||
internal interface IImagePackNodeVisitor
|
||||
{
|
||||
void Visit(ImagePackNode node);
|
||||
}
|
||||
|
||||
class CollectEmptyNodePositionVisitor : IImagePackNodeVisitor
|
||||
{
|
||||
public List<RectInt> emptyAreas = new List<RectInt>();
|
||||
public void Visit(ImagePackNode node)
|
||||
{
|
||||
if (node.imageId == -1)
|
||||
{
|
||||
emptyAreas.Add(node.rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CollectPackNodePositionVisitor : IImagePackNodeVisitor
|
||||
{
|
||||
public CollectPackNodePositionVisitor()
|
||||
{
|
||||
positions = new Vector2Int[0];
|
||||
}
|
||||
|
||||
public void Visit(ImagePackNode node)
|
||||
{
|
||||
if (node.imageId != -1)
|
||||
{
|
||||
if (positions.Length < node.imageId + 1)
|
||||
{
|
||||
var p = positions;
|
||||
Array.Resize(ref p, node.imageId + 1);
|
||||
positions = p;
|
||||
}
|
||||
|
||||
positions[node.imageId].x = node.rect.x;
|
||||
positions[node.imageId].y = node.rect.y;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2Int[] positions { get; private set; }
|
||||
}
|
||||
|
||||
internal class ImagePackNode
|
||||
{
|
||||
public ImagePackNode left;
|
||||
public ImagePackNode right;
|
||||
public RectInt rect;
|
||||
public Vector2Int imageWidth;
|
||||
public int imageId = -1;
|
||||
|
||||
public void AcceptVisitor(IImagePackNodeVisitor visitor)
|
||||
{
|
||||
visitor.Visit(this);
|
||||
if (left != null)
|
||||
left.AcceptVisitor(visitor);
|
||||
if (right != null)
|
||||
right.AcceptVisitor(visitor);
|
||||
}
|
||||
|
||||
public void AdjustSize(int oriWidth, int oriHeight, int deltaW, int deltaH, out int adjustx, out int adjusty)
|
||||
{
|
||||
adjustx = adjusty = 0;
|
||||
int adjustXleft = 0, adjustYleft = 0, adjustXRight = 0, adjustYRight = 0;
|
||||
if (imageId == -1 || left == null)
|
||||
{
|
||||
if (rect.x + rect.width == oriWidth)
|
||||
{
|
||||
rect.width += deltaW;
|
||||
adjustx = deltaW;
|
||||
}
|
||||
if (rect.y + rect.height == oriHeight)
|
||||
{
|
||||
rect.height += deltaH;
|
||||
adjusty = deltaH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
left.AdjustSize(oriWidth, oriHeight, deltaW, deltaH, out adjustXleft, out adjustYleft);
|
||||
right.AdjustSize(oriWidth, oriHeight, deltaW, deltaH, out adjustXRight, out adjustYRight);
|
||||
|
||||
adjustx = Mathf.Max(adjustXleft, adjustXRight);
|
||||
rect.width += adjustx;
|
||||
adjusty = Mathf.Max(adjustYleft, adjustYRight);
|
||||
rect.height += adjusty;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryInsert(ImagePacker.ImagePackRect insert, int padding, out Vector2Int remainingSpace)
|
||||
{
|
||||
remainingSpace = Vector2Int.zero;
|
||||
int insertWidth = insert.rect.width + padding * 2;
|
||||
int insertHeight = insert.rect.height + padding * 2;
|
||||
if (insertWidth > rect.width || insertHeight > rect.height)
|
||||
return false;
|
||||
|
||||
if (imageId == -1)
|
||||
{
|
||||
remainingSpace.x = rect.width - insertWidth;
|
||||
remainingSpace.y = rect.height - insertHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2Int spaceLeft, spaceRight;
|
||||
bool insertLeft, insertRight;
|
||||
ImagePackNode tryLeft, tryRight;
|
||||
tryLeft = left;
|
||||
tryRight = right;
|
||||
if (left == null && !SplitRects(this, insert, padding, out tryLeft, out tryRight))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
insertLeft = tryLeft.TryInsert(insert, padding, out spaceLeft);
|
||||
insertRight = tryRight.TryInsert(insert, padding, out spaceRight);
|
||||
if (insertLeft && insertRight)
|
||||
{
|
||||
remainingSpace = spaceLeft.sqrMagnitude < spaceRight.sqrMagnitude ? spaceLeft : spaceRight;
|
||||
}
|
||||
else if (insertLeft)
|
||||
remainingSpace = spaceLeft;
|
||||
else if (insertRight)
|
||||
remainingSpace = spaceRight;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SplitRects(ImagePackNode node, ImagePacker.ImagePackRect insert, int padding, out ImagePackNode left, out ImagePackNode right)
|
||||
{
|
||||
// Find the best way to split the rect based on a new rect
|
||||
left = right = null;
|
||||
var tryRects = new[]
|
||||
{
|
||||
new ImagePackNode(), new ImagePackNode(),
|
||||
new ImagePackNode(), new ImagePackNode()
|
||||
};
|
||||
|
||||
tryRects[0].rect = new RectInt(node.rect.x + node.imageWidth.x, node.rect.y, node.rect.width - node.imageWidth.x, node.rect.height);
|
||||
tryRects[1].rect = new RectInt(node.rect.x, node.rect.y + node.imageWidth.y, node.imageWidth.x, node.rect.height - node.imageWidth.y);
|
||||
tryRects[2].rect = new RectInt(node.rect.x, node.rect.y + node.imageWidth.y, node.rect.width, node.rect.height - node.imageWidth.y);
|
||||
tryRects[3].rect = new RectInt(node.rect.x + node.imageWidth.x, node.rect.y, node.rect.width - node.imageWidth.x, node.imageWidth.y);
|
||||
float smallestSpace = float.MinValue;
|
||||
for (int i = 0; i < tryRects.GetLength(0); ++i)
|
||||
{
|
||||
//for (int j = 0; j < tryRects.GetLength(1); ++j)
|
||||
{
|
||||
Vector2Int newSpaceLeft;
|
||||
if (tryRects[i].TryInsert(insert, padding, out newSpaceLeft))
|
||||
{
|
||||
if (smallestSpace < newSpaceLeft.sqrMagnitude)
|
||||
{
|
||||
smallestSpace = newSpaceLeft.sqrMagnitude;
|
||||
int index = i / 2 * 2;
|
||||
left = tryRects[index];
|
||||
right = tryRects[index + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return left != null;
|
||||
}
|
||||
|
||||
public bool Insert(ImagePacker.ImagePackRect insert, int padding)
|
||||
{
|
||||
int insertWidth = insert.rect.width + padding * 2;
|
||||
int insertHeight = insert.rect.height + padding * 2;
|
||||
if (insertWidth > rect.width || insertHeight > rect.height)
|
||||
return false;
|
||||
|
||||
if (imageId == -1)
|
||||
{
|
||||
imageId = insert.index;
|
||||
imageWidth = new Vector2Int(insertWidth, insertHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left == null && !SplitRects(this, insert, padding, out left, out right))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// We assign to the node that has a better fit for the image
|
||||
Vector2Int spaceLeft, spaceRight;
|
||||
bool insertLeft, insertRight;
|
||||
insertLeft = left.TryInsert(insert, padding, out spaceLeft);
|
||||
insertRight = right.TryInsert(insert, padding, out spaceRight);
|
||||
if (insertLeft && insertRight)
|
||||
{
|
||||
if (spaceLeft.sqrMagnitude < spaceRight.sqrMagnitude)
|
||||
left.Insert(insert, padding);
|
||||
else
|
||||
right.Insert(insert, padding);
|
||||
}
|
||||
else if (insertLeft)
|
||||
left.Insert(insert, padding);
|
||||
else if (insertRight)
|
||||
right.Insert(insert, padding);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue