Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
## [6.0.9] - 2023-12-14
### Fixed
- Provide custom packing override for users to override to address DANB-526. (Case DANB-526)
  • Loading branch information
Unity Technologies committed Dec 14, 2023
1 parent 3481609 commit 2028437
Show file tree
Hide file tree
Showing 25 changed files with 676 additions and 64 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# Changelog

## [6.0.9] - 2023-12-14
### Fixed
- Provide custom packing override for users to override to address DANB-526. (Case DANB-526)

## [6.0.8] - 2023-10-25
### Fixed
- Fixed an issue where PSDImporter atlas size does not follow PVRTC compression format for the iOS platform
- Fixed an issue where PSDImporter atlas size does not follow PVRTC compression format for the iOS platform.

## [6.0.7] - 2022-12-01
### Fixed
Expand Down
155 changes: 100 additions & 55 deletions Editor/PSDImporter.cs

Large diffs are not rendered by default.

16 changes: 14 additions & 2 deletions Editor/PSDImporterEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct InspectorGUI
SerializedProperty m_GeneratePhysicsShape;
SerializedProperty m_LayerMappingOption;
SerializedProperty m_PlatformSettingsArrProp;
SerializedProperty m_Pipeline;

private SkeletonAsset m_SkeletonAsset;
readonly int[] m_FilterModeOptions = (int[])(Enum.GetValues(typeof(FilterMode)));
Expand Down Expand Up @@ -108,6 +109,7 @@ public override void OnEnable()
m_SkeletonAssetReferenceID = serializedObject.FindProperty("m_SkeletonAssetReferenceID");
m_GeneratePhysicsShape = serializedObject.FindProperty("m_GeneratePhysicsShape");
m_LayerMappingOption = serializedObject.FindProperty("m_LayerMappingOption");
m_Pipeline = serializedObject.FindProperty("m_Pipeline");

var textureImporterSettingsSP = serializedObject.FindProperty("m_TextureImporterSettings");
m_TextureType = textureImporterSettingsSP.FindPropertyRelative("m_TextureType");
Expand Down Expand Up @@ -154,15 +156,17 @@ public override void OnEnable()
AlphaHandlingGUI,
POTScaleGUI,
ReadableGUI,
MipMapGUI
MipMapGUI,
CustomPipelineGUI,
};
m_AdvanceInspectorGUI.Add(TextureImporterType.Sprite, advanceGUIAction);

advanceGUIAction = new Action[]
{
POTScaleGUI,
ReadableGUI,
MipMapGUI
MipMapGUI,
CustomPipelineGUI,
};
m_AdvanceInspectorGUI.Add(TextureImporterType.Default, advanceGUIAction);

Expand All @@ -187,6 +191,14 @@ public override void OnEnable()
InitPreview();
}

void CustomPipelineGUI()
{
if (Unsupported.IsDeveloperMode())
{
EditorGUILayout.PropertyField(m_Pipeline);
}
}

/// <summary>
/// Override for AssetImporter.extraDataType
/// </summary>
Expand Down
14 changes: 14 additions & 0 deletions Editor/Pipeline.asset
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 90847c0a31834ab383dcd062f4ec41bd, type: 3}
m_Name: Pipeline
m_EditorClassIdentifier:
8 changes: 8 additions & 0 deletions Editor/Pipeline.asset.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions Editor/Pipeline.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Unity.Collections;
using UnityEditor.U2D.Common;
using UnityEngine;

namespace UnityEditor.U2D.PSD
{
//[CreateAssetMenu(fileName = "Pipeline.asset", menuName = "2D/PSDImporter Pipeline")]
class Pipeline : ScriptableObject
{
void PackImage(NativeArray<Color32>[] buffers,
int[] width, int[] height, int padding,
uint spriteSizeExpand,
out NativeArray<Color32> outPackedBuffer,
out int outPackedBufferWidth, out int outPackedBufferHeight,
out RectInt[] outPackedRect, out Vector2Int[] outUVTransform,
bool requireSquarePOT)
{
ImagePacker.Pack(buffers, width, height, padding, out outPackedBuffer, out outPackedBufferWidth, out outPackedBufferHeight, out outPackedRect, out outUVTransform);
}
}
}
3 changes: 3 additions & 0 deletions Editor/Pipeline.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Samples~/PSDImporterSamples/.sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"displayName": "2D PSDImporter Samples",
"interactiveImport": "true",
"description": "Various examples demonstrating the usage of 2D PSDImporter."
}
5 changes: 5 additions & 0 deletions Samples~/PSDImporterSamples/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
com.unity.2d.psdimporter Samples © 2023 Unity Technologies

Licensed under the Unity Companion License for Unity-dependent projects (see https://unity3d.com/legal/licenses/unity_companion_license).

Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions.
7 changes: 7 additions & 0 deletions Samples~/PSDImporterSamples/LICENSE.md.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Samples~/PSDImporterSamples/PSDImporterCustomPacker.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
using System;
using System.Collections.Generic;
using UnityEngine;

namespace PSDImporterCustomPacker
{
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

0 comments on commit 2028437

Please sign in to comment.