[csharp] Ported skin API changes part2, see #841. Port of changes of commit ff5b854860f639af1c111596bc407cbe12124d1e.

This commit is contained in:
Harald Csaszar 2019-05-20 11:43:00 +02:00
parent a009c35b82
commit 0791df8c4c
13 changed files with 123 additions and 109 deletions

View File

@ -235,8 +235,10 @@ namespace Spine {
}
private void SortPathConstraintAttachment (Skin skin, int slotIndex, Bone slotBone) {
foreach (var entry in skin.Attachments.Keys)
foreach (var entryObj in skin.Attachments.Keys) {
var entry = (Skin.SkinEntry)entryObj;
if (entry.SlotIndex == slotIndex) SortPathConstraintAttachment(entry.Attachment, slotBone);
}
}
private void SortPathConstraintAttachment (Attachment attachment, Bone slotBone) {

View File

@ -28,7 +28,9 @@
*****************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
namespace Spine {
/// <summary>Stores attachments by slot index and attachment name.
@ -37,11 +39,10 @@ namespace Spine {
/// </summary>
public class Skin {
internal string name;
private Dictionary<SkinEntry, Attachment> attachments =
new Dictionary<SkinEntry, Attachment>(SkinEntryComparer.Instance);
private OrderedDictionary attachments = new OrderedDictionary(SkinEntryComparer.Instance); // contains <SkinEntry, Attachment>
public string Name { get { return name; } }
public Dictionary<SkinEntry, Attachment> Attachments { get { return attachments; } }
public OrderedDictionary Attachments { get { return attachments; } }
public Skin (string name) {
if (name == null) throw new ArgumentNullException("name", "name cannot be null.");
@ -56,19 +57,30 @@ namespace Spine {
attachments[new SkinEntry(slotIndex, name, attachment)] = attachment;
}
///<summary>Adds all attachments from the specified skin to this skin.</summary>
///<summary>Adds all attachments, bones, and constraints from the specified skin to this skin.</summary>
public void AddSkin (Skin skin) {
foreach (SkinEntry entry in skin.attachments.Keys)
SetAttachment(entry.SlotIndex, entry.Name, entry.Attachment);
}
///<summary>Adds all attachments from the specified skin to this skin. Attachments are deep copied.</summary>
public void CopySkin (Skin skin) {
// note: bones and constraints are added in a separate commit.
foreach (SkinEntry entry in skin.attachments.Keys) {
Attachment attachment = entry.Attachment.Copy();
if (attachment is MeshAttachment) {
}
SetAttachment(entry.SlotIndex, entry.Name, attachment);
}
}
/// <summary>Returns the attachment for the specified slot index and name, or null.</summary>
/// <returns>May be null.</returns>
public Attachment GetAttachment (int slotIndex, string name) {
Attachment attachment;
var lookup = new SkinEntry(slotIndex, name, null);
attachments.TryGetValue(lookup, out attachment);
return attachment;
var obj = attachments[lookup];
return (obj == null) ? null : (Attachment)obj;
}
/// <summary> Removes the attachment in the skin for the specified slot index and name, if any.</summary>
@ -86,13 +98,11 @@ namespace Spine {
return entries;
}
/// <summary>Returns all <see cref="SkinEntry"/> instances for the given slot contained in this skin.</summary>
/// <summary>Returns all attachments for the given slot in this skin.</summary>
/// <param name="slotIndex">The target slotIndex. To find the slot index, use <see cref="Spine.Skeleton.FindSlotIndex"/> or <see cref="Spine.SkeletonData.FindSlotIndex"/>
public List<SkinEntry> GetEntries (int slotIndex) {
List<SkinEntry> entries = new List<SkinEntry>();
public void GetAttachments (int slotIndex, List<SkinEntry> attachments) {
foreach (SkinEntry entry in this.attachments.Keys)
if (entry.SlotIndex == slotIndex) entries.Add(entry);
return entries;
if (entry.SlotIndex == slotIndex) attachments.Add(entry);
}
override public string ToString () {
@ -144,18 +154,21 @@ namespace Spine {
}
}
// Avoids boxing in the dictionary.
class SkinEntryComparer : IEqualityComparer<SkinEntry> {
// Avoids boxing in the dictionary and is necessary to omit entry.attachment in the comparison.
class SkinEntryComparer : IEqualityComparer {
internal static readonly SkinEntryComparer Instance = new SkinEntryComparer();
bool IEqualityComparer<SkinEntry>.Equals (SkinEntry o1, SkinEntry o2) {
if (o1.SlotIndex != o2.SlotIndex) return false;
if (!string.Equals(o1.Name, o2.Name, StringComparison.Ordinal)) return false;
bool IEqualityComparer.Equals (object o1, object o2) {
var e1 = (SkinEntry)o1;
var e2 = (SkinEntry)o2;
if (e1.SlotIndex != e2.SlotIndex) return false;
if (!string.Equals(e1.Name, e2.Name, StringComparison.Ordinal)) return false;
return true;
}
int IEqualityComparer<SkinEntry>.GetHashCode (SkinEntry o) {
return o.Name.GetHashCode() + o.SlotIndex * 37;
int IEqualityComparer.GetHashCode (object o) {
var e = (SkinEntry)o;
return e.Name.GetHashCode() + e.SlotIndex * 37;
}
}
}

View File

@ -27,6 +27,7 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System.Collections;
using UnityEditor;
using UnityEngine;
@ -110,10 +111,10 @@ namespace Spine.Unity.Editor {
}
static void DrawPointsInSkin (Skin skin, Skeleton skeleton, Transform transform) {
foreach (var skinEntry in skin.Attachments) {
foreach (DictionaryEntry skinEntry in skin.Attachments) {
var attachment = skinEntry.Value as PointAttachment;
if (attachment != null) {
var skinKey = skinEntry.Key;
var skinKey = (Skin.SkinEntry)skinEntry.Key;
var slot = skeleton.Slots.Items[skinKey.SlotIndex];
DrawPointAttachmentWithLabel(attachment, slot.Bone, transform);
}

View File

@ -228,13 +228,11 @@ namespace Spine.Unity.Editor {
List<string> attachmentNames = new List<string>();
for (int i = 0; i < skinCount; i++) {
var skin = skins.Items[i];
List<string> temp = new List<string>();
var entries = skin.GetEntries(s);
foreach (var entry in entries)
temp.Add(entry.Name);
foreach (string str in temp) {
if (!attachmentNames.Contains(str))
attachmentNames.Add(str);
var skinEntries = new List<Skin.SkinEntry>();
skin.GetAttachments(s, skinEntries);
foreach (var entry in skinEntries) {
if (!attachmentNames.Contains(entry.Name))
attachmentNames.Add(entry.Name);
}
}
slotLookup.Add(s, attachmentNames);
@ -335,8 +333,8 @@ namespace Spine.Unity.Editor {
}
//create slots and attachments
for (int i = 0; i < skeletonData.Slots.Count; i++) {
var slotData = skeletonData.Slots.Items[i];
for (int slotIndex = 0; slotIndex < skeletonData.Slots.Count; slotIndex++) {
var slotData = skeletonData.Slots.Items[slotIndex];
Transform slotTransform = SpineEditorUtilities.EditorInstantiation.NewGameObject(slotData.Name).transform;
slotTransform.parent = prefabRoot.transform;
slotTable.Add(slotData.Name, slotTransform);
@ -344,15 +342,17 @@ namespace Spine.Unity.Editor {
List<Attachment> attachments = new List<Attachment>();
List<string> attachmentNames = new List<string>();
var entries = skin.GetEntries(i);
foreach (var entry in entries) {
var skinEntries = new List<Skin.SkinEntry>();
skin.GetAttachments(slotIndex, skinEntries);
foreach (var entry in skinEntries) {
attachments.Add(entry.Attachment);
attachmentNames.Add(entry.Name);
}
if (skin != skeletonData.DefaultSkin) {
entries = skeletonData.DefaultSkin.GetEntries(i);
foreach (var entry in entries) {
skinEntries.Clear();
skeletonData.DefaultSkin.GetAttachments(slotIndex, skinEntries);
foreach (var entry in skinEntries) {
attachments.Add(entry.Attachment);
attachmentNames.Add(entry.Name);
}
@ -388,7 +388,7 @@ namespace Spine.Unity.Editor {
rotation = 0;
if (isWeightedMesh)
mesh = ExtractWeightedMeshAttachment(attachmentMeshName, meshAttachment, i, skeletonData, boneList, mesh);
mesh = ExtractWeightedMeshAttachment(attachmentMeshName, meshAttachment, slotIndex, skeletonData, boneList, mesh);
else
mesh = ExtractMeshAttachment(attachmentMeshName, meshAttachment, mesh);
@ -418,7 +418,7 @@ namespace Spine.Unity.Editor {
}
attachmentTransform.GetComponent<Renderer>().sharedMaterial = material;
attachmentTransform.GetComponent<Renderer>().sortingOrder = i;
attachmentTransform.GetComponent<Renderer>().sortingOrder = slotIndex;
if (attachmentName != slotData.AttachmentName)
attachmentTransform.gameObject.SetActive(false);

View File

@ -498,23 +498,26 @@ namespace Spine.Unity.Editor {
using (new SpineInspectorUtility.IndentScope()) {
{
var entries = skin.GetEntries(i);
foreach (var entry in entries) {
var skinEntries = new List<Skin.SkinEntry>();
skin.GetAttachments(i, skinEntries);
foreach (var entry in skinEntries) {
slotAttachments.Add(entry.Attachment);
slotAttachmentNames.Add(entry.Name);
}
if (skin != defaultSkin) {
entries = defaultSkin.GetEntries(i);
foreach (var entry in entries) {
skinEntries.Clear();
defaultSkin.GetAttachments(i, skinEntries);
foreach (var entry in skinEntries) {
slotAttachments.Add(entry.Attachment);
slotAttachmentNames.Add(entry.Name);
defaultSkinAttachmentNames.Add(entry.Name);
}
} else {
entries = defaultSkin.GetEntries(i);
foreach (var entry in entries) {
skinEntries.Clear();
defaultSkin.GetAttachments(i, skinEntries);
foreach (var entry in skinEntries) {
defaultSkinAttachmentNames.Add(entry.Name);
}
}

View File

@ -575,13 +575,15 @@ namespace Spine.Unity.Editor {
var attachments = new List<Attachment>();
attachmentTable.Add(skeleton.Slots.Items[i], attachments);
// Add skin attachments.
var entries = skin.GetEntries(i);
foreach (var entry in entries) {
var skinEntries = new List<Skin.SkinEntry>();
skin.GetAttachments(i, skinEntries);
foreach (var entry in skinEntries) {
attachments.Add(entry.Attachment);
}
if (notDefaultSkin) { // Add default skin attachments.
entries = defaultSkin.GetEntries(i);
foreach (var entry in entries) {
skinEntries.Clear();
defaultSkin.GetAttachments(i, skinEntries);
foreach (var entry in skinEntries) {
attachments.Add(entry.Attachment);
}
}

View File

@ -177,23 +177,19 @@ namespace Spine.Unity.Editor {
if (TargetAttribute.includeNone)
menu.AddItem(new GUIContent(NoneString), !property.hasMultipleDifferentValues && string.IsNullOrEmpty(property.stringValue), HandleSelect, new SpineDrawerValuePair(string.Empty, property));
for (int i = 0; i < data.Slots.Count; i++) {
string name = data.Slots.Items[i].Name;
for (int slotIndex = 0; slotIndex < data.Slots.Count; slotIndex++) {
string name = data.Slots.Items[slotIndex].Name;
if (name.StartsWith(targetAttribute.startsWith, StringComparison.Ordinal)) {
if (targetAttribute.containsBoundingBoxes) {
int slotIndex = i;
var attachments = new List<Attachment>();
var skinEntries = new List<Skin.SkinEntry>();
foreach (var skin in data.Skins) {
var entries = skin.GetEntries(slotIndex);
foreach (var entry in entries) {
attachments.Add(entry.Attachment);
}
skin.GetAttachments(slotIndex, skinEntries);
}
bool hasBoundingBox = false;
foreach (var attachment in attachments) {
var bbAttachment = attachment as BoundingBoxAttachment;
foreach (var entry in skinEntries) {
var bbAttachment = entry.Attachment as BoundingBoxAttachment;
if (bbAttachment != null) {
string menuLabel = bbAttachment.IsWeighted() ? name + " (!)" : name;
menu.AddItem(new GUIContent(menuLabel), !property.hasMultipleDifferentValues && name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property));
@ -474,17 +470,19 @@ namespace Spine.Unity.Editor {
attachmentNames.Clear();
placeholderNames.Clear();
var entries = skin.GetEntries(i);
foreach (var entry in entries) {
var skinEntries = new List<Skin.SkinEntry>();
skin.GetAttachments(i, skinEntries);
foreach (var entry in skinEntries) {
attachmentNames.Add(entry.Name);
}
if (skin != defaultSkin) {
foreach (var entry in entries) {
foreach (var entry in skinEntries) {
placeholderNames.Add(entry.Name);
}
entries = defaultSkin.GetEntries(i);
foreach (var entry in entries) {
skinEntries.Clear();
defaultSkin.GetAttachments(i, skinEntries);
foreach (var entry in skinEntries) {
attachmentNames.Add(entry.Name);
}
}

View File

@ -81,8 +81,10 @@ namespace Spine.Unity.Editor {
Slot slot = skeletonUtility.skeletonRenderer.skeleton.Slots.Items[i];
if (slot.Bone == utilityBone.bone) {
var slotAttachments = new List<Attachment>();
var entries = skin.GetEntries(skeleton.FindSlotIndex(slot.Data.Name));
foreach (var entry in entries) {
var skinEntries = new List<Skin.SkinEntry>();
int slotIndex = skeleton.FindSlotIndex(slot.Data.Name);
skin.GetAttachments(slotIndex, skinEntries);
foreach (var entry in skinEntries) {
slotAttachments.Add(entry.Attachment);
}

View File

@ -52,19 +52,16 @@ namespace Spine.Unity {
if (skeletonData == null) throw new ArgumentNullException("skeletonData");
using (var materialCache = new AtlasMaterialCache()) {
var attachmentBuffer = new List<Attachment>();
var entryBuffer = new List<Skin.SkinEntry>();
var slotsItems = skeletonData.Slots.Items;
for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++) {
var slot = slotsItems[slotIndex];
if (slot.blendMode == BlendMode.Normal) continue;
if (!includeAdditiveSlots && slot.blendMode == BlendMode.Additive) continue;
attachmentBuffer.Clear();
foreach (var skin in skeletonData.Skins) {
var entries = skin.GetEntries(slotIndex);
foreach (var entry in entries)
attachmentBuffer.Add(entry.Attachment);
}
entryBuffer.Clear();
foreach (var skin in skeletonData.Skins)
skin.GetAttachments(slotIndex, entryBuffer);
Material templateMaterial = null;
switch (slot.blendMode) {
@ -80,8 +77,8 @@ namespace Spine.Unity {
}
if (templateMaterial == null) continue;
foreach (var attachment in attachmentBuffer) {
var renderableAttachment = attachment as IHasRendererObject;
foreach (var entry in entryBuffer) {
var renderableAttachment = entry.Attachment as IHasRendererObject;
if (renderableAttachment != null) {
renderableAttachment.RendererObject = materialCache.CloneAtlasRegionWithMaterial((AtlasRegion)renderableAttachment.RendererObject, templateMaterial);
}

View File

@ -29,6 +29,7 @@
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
namespace Spine.Unity.Modules.AttachmentTools {
public static class AttachmentRegionExtensions {
@ -503,9 +504,10 @@ namespace Spine.Unity.Modules.AttachmentTools {
var texturesToPack = new List<Texture2D>();
var originalRegions = new List<AtlasRegion>();
int newRegionIndex = 0;
foreach (var skinEntry in skinAttachments) {
var originalKey = skinEntry.Key;
var originalAttachment = skinEntry.Value;
foreach (DictionaryEntry skinEntry in skinAttachments) {
var originalKey = (Skin.SkinEntry)skinEntry.Key;
var originalAttachment = (Attachment)skinEntry.Value;
Attachment newAttachment;
if (IsRenderable(originalAttachment)) {
@ -793,7 +795,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
var newSkin = new Skin(original.name + " clone");
var newSkinAttachments = newSkin.Attachments;
foreach (var a in original.Attachments)
foreach (DictionaryEntry a in original.Attachments)
newSkinAttachments[a.Key] = a.Value;
return newSkin;
@ -848,21 +850,21 @@ namespace Spine.Unity.Modules.AttachmentTools {
if (cloneAttachments) {
if (overwrite) {
foreach (var e in sourceAttachments)
destinationAttachments[e.Key] = e.Value.GetClone(cloneMeshesAsLinked);
foreach (DictionaryEntry e in sourceAttachments)
destinationAttachments[e.Key] = ((Attachment)e.Value).GetClone(cloneMeshesAsLinked);
} else {
foreach (var e in sourceAttachments) {
if (destinationAttachments.ContainsKey(e.Key)) continue;
destinationAttachments.Add(e.Key, e.Value.GetClone(cloneMeshesAsLinked));
foreach (DictionaryEntry e in sourceAttachments) {
if (destinationAttachments.Contains(e.Key)) continue;
destinationAttachments.Add(e.Key, ((Attachment)e.Value).GetClone(cloneMeshesAsLinked));
}
}
} else {
if (overwrite) {
foreach (var e in sourceAttachments)
foreach (DictionaryEntry e in sourceAttachments)
destinationAttachments[e.Key] = e.Value;
} else {
foreach (var e in sourceAttachments) {
if (destinationAttachments.ContainsKey(e.Key)) continue;
foreach (DictionaryEntry e in sourceAttachments) {
if (destinationAttachments.Contains(e.Key)) continue;
destinationAttachments.Add(e.Key, e.Value);
}
}

View File

@ -139,13 +139,11 @@ namespace Spine.Unity {
void AddSkin (Skin skin, int slotIndex) {
if (skin == null) return;
var attachmentNames = new List<string>();
var entries = skin.GetEntries(slotIndex);
foreach (var entry in entries)
attachmentNames.Add(entry.Name);
var skinEntries = new List<Skin.SkinEntry>();
skin.GetAttachments(slotIndex, skinEntries);
foreach (var skinKey in attachmentNames) {
var attachment = skin.GetAttachment(slotIndex, skinKey);
foreach (var entry in skinEntries) {
var attachment = skin.GetAttachment(slotIndex, entry.Name);
var boundingBoxAttachment = attachment as BoundingBoxAttachment;
if (BoundingBoxFollower.DebugMessages && attachment != null && boundingBoxAttachment == null)
@ -159,7 +157,7 @@ namespace Spine.Unity {
bbCollider.hideFlags = HideFlags.NotEditable;
bbCollider.isTrigger = IsTrigger;
colliderTable.Add(boundingBoxAttachment, bbCollider);
nameTable.Add(boundingBoxAttachment, skinKey);
nameTable.Add(boundingBoxAttachment, entry.Name);
}
}
}

View File

@ -365,17 +365,15 @@ namespace Spine.Unity.Modules {
GameObject go = t.gameObject;
var skin = skeleton.Skin ?? skeleton.Data.DefaultSkin;
var attachments = new List<Attachment>();
var skinEntries = new List<Skin.SkinEntry>();
foreach (Slot s in skeleton.Slots) {
if (s.Bone == b) {
var entries = skin.GetEntries(skeleton.Slots.IndexOf(s));
foreach (var entry in entries)
attachments.Add(entry.Attachment);
skin.GetAttachments(skeleton.Slots.IndexOf(s), skinEntries);
foreach (var a in attachments) {
var bbAttachment = a as BoundingBoxAttachment;
foreach (var entry in skinEntries) {
var bbAttachment = entry.Attachment as BoundingBoxAttachment;
if (bbAttachment != null) {
if (!a.Name.ToLower().Contains(AttachmentNameMarker))
if (!entry.Name.ToLower().Contains(AttachmentNameMarker))
continue;
var bbCollider = go.AddComponent<BoxCollider>();

View File

@ -360,18 +360,16 @@ namespace Spine.Unity.Modules {
var colliders = new List<Collider2D>();
var skin = skeleton.Skin ?? skeleton.Data.DefaultSkin;
var attachments = new List<Attachment>();
var skinEntries = new List<Skin.SkinEntry>();
foreach (Slot slot in skeleton.Slots) {
if (slot.bone == b) {
var entries = skin.GetEntries(skeleton.Slots.IndexOf(slot));
foreach (var entry in entries)
attachments.Add(entry.Attachment);
skin.GetAttachments(skeleton.Slots.IndexOf(slot), skinEntries);
bool bbAttachmentAdded = false;
foreach (var a in attachments) {
var bbAttachment = a as BoundingBoxAttachment;
foreach (var entry in skinEntries) {
var bbAttachment = entry.Attachment as BoundingBoxAttachment;
if (bbAttachment != null) {
if (!a.Name.ToLower().Contains(AttachmentNameMarker))
if (!entry.Name.ToLower().Contains(AttachmentNameMarker))
continue;
bbAttachmentAdded = true;