Merge branch '3.6' into 3.7-beta

This commit is contained in:
badlogic 2018-03-14 10:24:44 +01:00
commit 4c104ef885
22 changed files with 1140 additions and 990 deletions

View File

@ -174,7 +174,7 @@ namespace Spine {
protected const float LINEAR = 0, STEPPED = 1, BEZIER = 2;
protected const int BEZIER_SIZE = 10 * 2 - 1;
private float[] curves; // type, x, y, ...
internal float[] curves; // type, x, y, ...
public int FrameCount { get { return curves.Length / BEZIER_SIZE + 1; } }
public CurveTimeline (int frameCount) {
@ -689,18 +689,20 @@ namespace Spine {
protected const int PREV_R2 = -3, PREV_G2 = -2, PREV_B2 = -1;
protected const int R = 1, G = 2, B = 3, A = 4, R2 = 5, G2 = 6, B2 = 7;
internal float[] frames; // time, r, g, b, a, r2, g2, b2, ...
public float[] Frames { get { return frames; } }
internal int slotIndex;
internal float[] frames; // time, r, g, b, a, r2, g2, b2, ...
public int SlotIndex {
get { return slotIndex; }
set {
if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0.");
if (value < 0)
throw new ArgumentOutOfRangeException("index must be >= 0.");
slotIndex = value;
}
}
public float[] Frames { get { return frames; } }
override public int PropertyId {
get { return ((int)TimelineType.TwoColor << 24) + slotIndex; }
}
@ -827,11 +829,11 @@ namespace Spine {
public class AttachmentTimeline : Timeline {
internal int slotIndex;
internal float[] frames;
private String[] attachmentNames;
internal string[] attachmentNames;
public int SlotIndex { get { return slotIndex; } set { slotIndex = value; } }
public float[] Frames { get { return frames; } set { frames = value; } } // time, ...
public String[] AttachmentNames { get { return attachmentNames; } set { attachmentNames = value; } }
public string[] AttachmentNames { get { return attachmentNames; } set { attachmentNames = value; } }
public int FrameCount { get { return frames.Length; } }
public int PropertyId {

View File

@ -79,14 +79,22 @@ namespace Spine {
public void UpdateOffset () {
float width = this.width;
float height = this.height;
float localX2 = width * 0.5f;
float localY2 = height * 0.5f;
float localX = -localX2;
float localY = -localY2;
if (regionOriginalWidth != 0) { // if (region != null)
localX += regionOffsetX / regionOriginalWidth * width;
localY += regionOffsetY / regionOriginalHeight * height;
localX2 -= (regionOriginalWidth - regionOffsetX - regionWidth) / regionOriginalWidth * width;
localY2 -= (regionOriginalHeight - regionOffsetY - regionHeight) / regionOriginalHeight * height;
}
float scaleX = this.scaleX;
float scaleY = this.scaleY;
float regionScaleX = width / regionOriginalWidth * scaleX;
float regionScaleY = height / regionOriginalHeight * scaleY;
float localX = -width / 2 * scaleX + regionOffsetX * regionScaleX;
float localY = -height / 2 * scaleY + regionOffsetY * regionScaleY;
float localX2 = localX + regionWidth * regionScaleX;
float localY2 = localY + regionHeight * regionScaleY;
localX *= scaleX;
localY *= scaleY;
localX2 *= scaleX;
localY2 *= scaleY;
float rotation = this.rotation;
float cos = MathUtils.CosDeg(rotation);
float sin = MathUtils.SinDeg(rotation);

View File

@ -69,11 +69,11 @@ namespace Spine {
}
}
public SkeletonData ReadSkeletonData (String path) {
public SkeletonData ReadSkeletonData (string path) {
return this.ReadFile(path).Result;
}
#else
public SkeletonData ReadSkeletonData (String path) {
public SkeletonData ReadSkeletonData (string path) {
#if WINDOWS_PHONE
using (var reader = new StreamReader(Microsoft.Xna.Framework.TitleContainer.OpenStream(path))) {
#else
@ -89,17 +89,17 @@ namespace Spine {
public SkeletonData ReadSkeletonData (TextReader reader) {
if (reader == null) throw new ArgumentNullException("reader", "reader cannot be null.");
var scale = this.Scale;
float scale = this.Scale;
var skeletonData = new SkeletonData();
var root = Json.Deserialize(reader) as Dictionary<String, Object>;
var root = Json.Deserialize(reader) as Dictionary<string, Object>;
if (root == null) throw new Exception("Invalid JSON.");
// Skeleton.
if (root.ContainsKey("skeleton")) {
var skeletonMap = (Dictionary<String, Object>)root["skeleton"];
skeletonData.hash = (String)skeletonMap["hash"];
skeletonData.version = (String)skeletonMap["spine"];
var skeletonMap = (Dictionary<string, Object>)root["skeleton"];
skeletonData.hash = (string)skeletonMap["hash"];
skeletonData.version = (string)skeletonMap["spine"];
skeletonData.width = GetFloat(skeletonMap, "width", 0);
skeletonData.height = GetFloat(skeletonMap, "height", 0);
skeletonData.fps = GetFloat(skeletonMap, "fps", 0);
@ -108,14 +108,14 @@ namespace Spine {
}
// Bones.
foreach (Dictionary<String, Object> boneMap in (List<Object>)root["bones"]) {
foreach (Dictionary<string, Object> boneMap in (List<Object>)root["bones"]) {
BoneData parent = null;
if (boneMap.ContainsKey("parent")) {
parent = skeletonData.FindBone((String)boneMap["parent"]);
parent = skeletonData.FindBone((string)boneMap["parent"]);
if (parent == null)
throw new Exception("Parent bone not found: " + boneMap["parent"]);
}
var data = new BoneData(skeletonData.Bones.Count, (String)boneMap["name"], parent);
var data = new BoneData(skeletonData.Bones.Count, (string)boneMap["name"], parent);
data.length = GetFloat(boneMap, "length", 0) * scale;
data.x = GetFloat(boneMap, "x", 0) * scale;
data.y = GetFloat(boneMap, "y", 0) * scale;
@ -133,15 +133,15 @@ namespace Spine {
// Slots.
if (root.ContainsKey("slots")) {
foreach (Dictionary<String, Object> slotMap in (List<Object>)root["slots"]) {
var slotName = (String)slotMap["name"];
var boneName = (String)slotMap["bone"];
foreach (Dictionary<string, Object> slotMap in (List<Object>)root["slots"]) {
var slotName = (string)slotMap["name"];
var boneName = (string)slotMap["bone"];
BoneData boneData = skeletonData.FindBone(boneName);
if (boneData == null) throw new Exception("Slot bone not found: " + boneName);
var data = new SlotData(skeletonData.Slots.Count, slotName, boneData);
if (slotMap.ContainsKey("color")) {
var color = (String)slotMap["color"];
string color = (string)slotMap["color"];
data.r = ToColor(color, 0);
data.g = ToColor(color, 1);
data.b = ToColor(color, 2);
@ -149,7 +149,7 @@ namespace Spine {
}
if (slotMap.ContainsKey("dark")) {
var color2 = (String)slotMap["dark"];
var color2 = (string)slotMap["dark"];
data.r2 = ToColor(color2, 0, 6); // expectedLength = 6. ie. "RRGGBB"
data.g2 = ToColor(color2, 1, 6);
data.b2 = ToColor(color2, 2, 6);
@ -158,7 +158,7 @@ namespace Spine {
data.attachmentName = GetString(slotMap, "attachment", null);
if (slotMap.ContainsKey("blend"))
data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], true);
data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (string)slotMap["blend"], true);
else
data.blendMode = BlendMode.Normal;
skeletonData.slots.Add(data);
@ -167,17 +167,17 @@ namespace Spine {
// IK constraints.
if (root.ContainsKey("ik")) {
foreach (Dictionary<String, Object> constraintMap in (List<Object>)root["ik"]) {
IkConstraintData data = new IkConstraintData((String)constraintMap["name"]);
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["ik"]) {
IkConstraintData data = new IkConstraintData((string)constraintMap["name"]);
data.order = GetInt(constraintMap, "order", 0);
foreach (String boneName in (List<Object>)constraintMap["bones"]) {
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
BoneData bone = skeletonData.FindBone(boneName);
if (bone == null) throw new Exception("IK constraint bone not found: " + boneName);
data.bones.Add(bone);
}
String targetName = (String)constraintMap["target"];
string targetName = (string)constraintMap["target"];
data.target = skeletonData.FindBone(targetName);
if (data.target == null) throw new Exception("Target bone not found: " + targetName);
@ -190,17 +190,17 @@ namespace Spine {
// Transform constraints.
if (root.ContainsKey("transform")) {
foreach (Dictionary<String, Object> constraintMap in (List<Object>)root["transform"]) {
TransformConstraintData data = new TransformConstraintData((String)constraintMap["name"]);
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["transform"]) {
TransformConstraintData data = new TransformConstraintData((string)constraintMap["name"]);
data.order = GetInt(constraintMap, "order", 0);
foreach (String boneName in (List<Object>)constraintMap["bones"]) {
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
BoneData bone = skeletonData.FindBone(boneName);
if (bone == null) throw new Exception("Transform constraint bone not found: " + boneName);
data.bones.Add(bone);
}
String targetName = (String)constraintMap["target"];
string targetName = (string)constraintMap["target"];
data.target = skeletonData.FindBone(targetName);
if (data.target == null) throw new Exception("Target bone not found: " + targetName);
@ -225,17 +225,17 @@ namespace Spine {
// Path constraints.
if(root.ContainsKey("path")) {
foreach (Dictionary<String, Object> constraintMap in (List<Object>)root["path"]) {
PathConstraintData data = new PathConstraintData((String)constraintMap["name"]);
foreach (Dictionary<string, Object> constraintMap in (List<Object>)root["path"]) {
PathConstraintData data = new PathConstraintData((string)constraintMap["name"]);
data.order = GetInt(constraintMap, "order", 0);
foreach (String boneName in (List<Object>)constraintMap["bones"]) {
foreach (string boneName in (List<Object>)constraintMap["bones"]) {
BoneData bone = skeletonData.FindBone(boneName);
if (bone == null) throw new Exception("Path bone not found: " + boneName);
data.bones.Add(bone);
}
String targetName = (String)constraintMap["target"];
string targetName = (string)constraintMap["target"];
data.target = skeletonData.FindSlot(targetName);
if (data.target == null) throw new Exception("Target slot not found: " + targetName);
@ -256,13 +256,13 @@ namespace Spine {
// Skins.
if (root.ContainsKey("skins")) {
foreach (KeyValuePair<String, Object> skinMap in (Dictionary<String, Object>)root["skins"]) {
foreach (KeyValuePair<string, Object> skinMap in (Dictionary<string, Object>)root["skins"]) {
var skin = new Skin(skinMap.Key);
foreach (KeyValuePair<String, Object> slotEntry in (Dictionary<String, Object>)skinMap.Value) {
foreach (KeyValuePair<string, Object> slotEntry in (Dictionary<string, Object>)skinMap.Value) {
int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
foreach (KeyValuePair<String, Object> entry in ((Dictionary<String, Object>)slotEntry.Value)) {
foreach (KeyValuePair<string, Object> entry in ((Dictionary<string, Object>)slotEntry.Value)) {
try {
Attachment attachment = ReadAttachment((Dictionary<String, Object>)entry.Value, skin, slotIndex, entry.Key, skeletonData);
Attachment attachment = ReadAttachment((Dictionary<string, Object>)entry.Value, skin, slotIndex, entry.Key, skeletonData);
if (attachment != null) skin.AddAttachment(slotIndex, entry.Key, attachment);
} catch (Exception e) {
throw new Exception("Error reading attachment: " + entry.Key + ", skin: " + skin, e);
@ -288,8 +288,8 @@ namespace Spine {
// Events.
if (root.ContainsKey("events")) {
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["events"]) {
var entryMap = (Dictionary<String, Object>)entry.Value;
foreach (KeyValuePair<string, Object> entry in (Dictionary<string, Object>)root["events"]) {
var entryMap = (Dictionary<string, Object>)entry.Value;
var data = new EventData(entry.Key);
data.Int = GetInt(entryMap, "int", 0);
data.Float = GetFloat(entryMap, "float", 0);
@ -301,9 +301,9 @@ namespace Spine {
// Animations.
if (root.ContainsKey("animations")) {
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["animations"]) {
foreach (KeyValuePair<string, Object> entry in (Dictionary<string, Object>)root["animations"]) {
try {
ReadAnimation((Dictionary<String, Object>)entry.Value, entry.Key, skeletonData);
ReadAnimation((Dictionary<string, Object>)entry.Value, entry.Key, skeletonData);
} catch (Exception e) {
throw new Exception("Error reading animation: " + entry.Key, e);
}
@ -319,8 +319,8 @@ namespace Spine {
return skeletonData;
}
private Attachment ReadAttachment (Dictionary<String, Object> map, Skin skin, int slotIndex, String name, SkeletonData skeletonData) {
var scale = this.Scale;
private Attachment ReadAttachment (Dictionary<string, Object> map, Skin skin, int slotIndex, string name, SkeletonData skeletonData) {
float scale = this.Scale;
name = GetString(map, "name", name);
var typeName = GetString(map, "type", "region");
@ -329,7 +329,7 @@ namespace Spine {
if (typeName == "weightedlinkedmesh") typeName = "linkedmesh";
var type = (AttachmentType)Enum.Parse(typeof(AttachmentType), typeName, true);
String path = GetString(map, "path", name);
string path = GetString(map, "path", name);
switch (type) {
case AttachmentType.Region:
@ -343,10 +343,9 @@ namespace Spine {
region.rotation = GetFloat(map, "rotation", 0);
region.width = GetFloat(map, "width", 32) * scale;
region.height = GetFloat(map, "height", 32) * scale;
region.UpdateOffset();
if (map.ContainsKey("color")) {
var color = (String)map["color"];
var color = (string)map["color"];
region.r = ToColor(color, 0);
region.g = ToColor(color, 1);
region.b = ToColor(color, 2);
@ -367,7 +366,7 @@ namespace Spine {
mesh.Path = path;
if (map.ContainsKey("color")) {
var color = (String)map["color"];
var color = (string)map["color"];
mesh.r = ToColor(color, 0);
mesh.g = ToColor(color, 1);
mesh.b = ToColor(color, 2);
@ -377,7 +376,7 @@ namespace Spine {
mesh.Width = GetFloat(map, "width", 0) * scale;
mesh.Height = GetFloat(map, "height", 0) * scale;
String parent = GetString(map, "parent", null);
string parent = GetString(map, "parent", null);
if (parent != null) {
mesh.InheritDeform = GetBoolean(map, "deform", true);
linkedMeshes.Add(new LinkedMesh(mesh, GetString(map, "skin", null), slotIndex, parent));
@ -439,7 +438,7 @@ namespace Spine {
return null;
}
private void ReadVertices (Dictionary<String, Object> map, VertexAttachment attachment, int verticesLength) {
private void ReadVertices (Dictionary<string, Object> map, VertexAttachment attachment, int verticesLength) {
attachment.WorldVerticesLength = verticesLength;
float[] vertices = GetFloatArray(map, "vertices", 1);
float scale = Scale;
@ -468,28 +467,28 @@ namespace Spine {
attachment.vertices = weights.ToArray();
}
private void ReadAnimation (Dictionary<String, Object> map, String name, SkeletonData skeletonData) {
private void ReadAnimation (Dictionary<string, Object> map, string name, SkeletonData skeletonData) {
var scale = this.Scale;
var timelines = new ExposedList<Timeline>();
float duration = 0;
// Slot timelines.
if (map.ContainsKey("slots")) {
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["slots"]) {
String slotName = entry.Key;
foreach (KeyValuePair<string, Object> entry in (Dictionary<string, Object>)map["slots"]) {
string slotName = entry.Key;
int slotIndex = skeletonData.FindSlotIndex(slotName);
var timelineMap = (Dictionary<String, Object>)entry.Value;
foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
var timelineMap = (Dictionary<string, Object>)entry.Value;
foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
var values = (List<Object>)timelineEntry.Value;
var timelineName = (String)timelineEntry.Key;
var timelineName = (string)timelineEntry.Key;
if (timelineName == "attachment") {
var timeline = new AttachmentTimeline(values.Count);
timeline.slotIndex = slotIndex;
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
foreach (Dictionary<string, Object> valueMap in values) {
float time = (float)valueMap["time"];
timeline.SetFrame(frameIndex++, time, (String)valueMap["name"]);
timeline.SetFrame(frameIndex++, time, (string)valueMap["name"]);
}
timelines.Add(timeline);
duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
@ -534,20 +533,20 @@ namespace Spine {
// Bone timelines.
if (map.ContainsKey("bones")) {
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["bones"]) {
String boneName = entry.Key;
foreach (KeyValuePair<string, Object> entry in (Dictionary<string, Object>)map["bones"]) {
string boneName = entry.Key;
int boneIndex = skeletonData.FindBoneIndex(boneName);
if (boneIndex == -1) throw new Exception("Bone not found: " + boneName);
var timelineMap = (Dictionary<String, Object>)entry.Value;
foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
var timelineMap = (Dictionary<string, Object>)entry.Value;
foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
var values = (List<Object>)timelineEntry.Value;
var timelineName = (String)timelineEntry.Key;
var timelineName = (string)timelineEntry.Key;
if (timelineName == "rotate") {
var timeline = new RotateTimeline(values.Count);
timeline.boneIndex = boneIndex;
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
foreach (Dictionary<string, Object> valueMap in values) {
timeline.SetFrame(frameIndex, (float)valueMap["time"], (float)valueMap["angle"]);
ReadCurve(valueMap, timeline, frameIndex);
frameIndex++;
@ -569,7 +568,7 @@ namespace Spine {
timeline.boneIndex = boneIndex;
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
foreach (Dictionary<string, Object> valueMap in values) {
float time = (float)valueMap["time"];
float x = GetFloat(valueMap, "x", 0);
float y = GetFloat(valueMap, "y", 0);
@ -588,13 +587,13 @@ namespace Spine {
// IK constraint timelines.
if (map.ContainsKey("ik")) {
foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["ik"]) {
foreach (KeyValuePair<string, Object> constraintMap in (Dictionary<string, Object>)map["ik"]) {
IkConstraintData constraint = skeletonData.FindIkConstraint(constraintMap.Key);
var values = (List<Object>)constraintMap.Value;
var timeline = new IkConstraintTimeline(values.Count);
timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint);
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
foreach (Dictionary<string, Object> valueMap in values) {
float time = (float)valueMap["time"];
float mix = GetFloat(valueMap, "mix", 1);
bool bendPositive = GetBoolean(valueMap, "bendPositive", true);
@ -609,13 +608,13 @@ namespace Spine {
// Transform constraint timelines.
if (map.ContainsKey("transform")) {
foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["transform"]) {
foreach (KeyValuePair<string, Object> constraintMap in (Dictionary<string, Object>)map["transform"]) {
TransformConstraintData constraint = skeletonData.FindTransformConstraint(constraintMap.Key);
var values = (List<Object>)constraintMap.Value;
var timeline = new TransformConstraintTimeline(values.Count);
timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint);
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
foreach (Dictionary<string, Object> valueMap in values) {
float time = (float)valueMap["time"];
float rotateMix = GetFloat(valueMap, "rotateMix", 1);
float translateMix = GetFloat(valueMap, "translateMix", 1);
@ -632,14 +631,14 @@ namespace Spine {
// Path constraint timelines.
if (map.ContainsKey("paths")) {
foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["paths"]) {
foreach (KeyValuePair<string, Object> constraintMap in (Dictionary<string, Object>)map["paths"]) {
int index = skeletonData.FindPathConstraintIndex(constraintMap.Key);
if (index == -1) throw new Exception("Path constraint not found: " + constraintMap.Key);
PathConstraintData data = skeletonData.pathConstraints.Items[index];
var timelineMap = (Dictionary<String, Object>)constraintMap.Value;
foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
var timelineMap = (Dictionary<string, Object>)constraintMap.Value;
foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
var values = (List<Object>)timelineEntry.Value;
var timelineName = (String)timelineEntry.Key;
var timelineName = (string)timelineEntry.Key;
if (timelineName == "position" || timelineName == "spacing") {
PathConstraintPositionTimeline timeline;
float timelineScale = 1;
@ -653,7 +652,7 @@ namespace Spine {
}
timeline.pathConstraintIndex = index;
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
foreach (Dictionary<string, Object> valueMap in values) {
timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, timelineName, 0) * timelineScale);
ReadCurve(valueMap, timeline, frameIndex);
frameIndex++;
@ -665,7 +664,7 @@ namespace Spine {
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count);
timeline.pathConstraintIndex = index;
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
foreach (Dictionary<string, Object> valueMap in values) {
timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, "rotateMix", 1), GetFloat(valueMap, "translateMix", 1));
ReadCurve(valueMap, timeline, frameIndex);
frameIndex++;
@ -679,12 +678,12 @@ namespace Spine {
// Deform timelines.
if (map.ContainsKey("deform")) {
foreach (KeyValuePair<String, Object> deformMap in (Dictionary<String, Object>)map["deform"]) {
foreach (KeyValuePair<string, Object> deformMap in (Dictionary<string, Object>)map["deform"]) {
Skin skin = skeletonData.FindSkin(deformMap.Key);
foreach (KeyValuePair<String, Object> slotMap in (Dictionary<String, Object>)deformMap.Value) {
foreach (KeyValuePair<string, Object> slotMap in (Dictionary<string, Object>)deformMap.Value) {
int slotIndex = skeletonData.FindSlotIndex(slotMap.Key);
if (slotIndex == -1) throw new Exception("Slot not found: " + slotMap.Key);
foreach (KeyValuePair<String, Object> timelineMap in (Dictionary<String, Object>)slotMap.Value) {
foreach (KeyValuePair<string, Object> timelineMap in (Dictionary<string, Object>)slotMap.Value) {
var values = (List<Object>)timelineMap.Value;
VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, timelineMap.Key);
if (attachment == null) throw new Exception("Deform attachment not found: " + timelineMap.Key);
@ -697,7 +696,7 @@ namespace Spine {
timeline.attachment = attachment;
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
foreach (Dictionary<string, Object> valueMap in values) {
float[] deform;
if (!valueMap.ContainsKey("vertices")) {
deform = weighted ? new float[deformLength] : vertices;
@ -734,7 +733,7 @@ namespace Spine {
var timeline = new DrawOrderTimeline(values.Count);
int slotCount = skeletonData.slots.Count;
int frameIndex = 0;
foreach (Dictionary<String, Object> drawOrderMap in values) {
foreach (Dictionary<string, Object> drawOrderMap in values) {
int[] drawOrder = null;
if (drawOrderMap.ContainsKey("offsets")) {
drawOrder = new int[slotCount];
@ -743,8 +742,8 @@ namespace Spine {
var offsets = (List<Object>)drawOrderMap["offsets"];
int[] unchanged = new int[slotCount - offsets.Count];
int originalIndex = 0, unchangedIndex = 0;
foreach (Dictionary<String, Object> offsetMap in offsets) {
int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]);
foreach (Dictionary<string, Object> offsetMap in offsets) {
int slotIndex = skeletonData.FindSlotIndex((string)offsetMap["slot"]);
if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]);
// Collect unchanged items.
while (originalIndex != slotIndex)
@ -771,8 +770,8 @@ namespace Spine {
var eventsMap = (List<Object>)map["events"];
var timeline = new EventTimeline(eventsMap.Count);
int frameIndex = 0;
foreach (Dictionary<String, Object> eventMap in eventsMap) {
EventData eventData = skeletonData.FindEvent((String)eventMap["name"]);
foreach (Dictionary<string, Object> eventMap in eventsMap) {
EventData eventData = skeletonData.FindEvent((string)eventMap["name"]);
if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
var e = new Event((float)eventMap["time"], eventData);
e.Int = GetInt(eventMap, "int", eventData.Int);
@ -788,7 +787,7 @@ namespace Spine {
skeletonData.animations.Add(new Animation(name, timelines, duration));
}
static void ReadCurve (Dictionary<String, Object> valueMap, CurveTimeline timeline, int frameIndex) {
static void ReadCurve (Dictionary<string, Object> valueMap, CurveTimeline timeline, int frameIndex) {
if (!valueMap.ContainsKey("curve"))
return;
Object curveObject = valueMap["curve"];
@ -802,11 +801,11 @@ namespace Spine {
}
internal class LinkedMesh {
internal String parent, skin;
internal string parent, skin;
internal int slotIndex;
internal MeshAttachment mesh;
public LinkedMesh (MeshAttachment mesh, String skin, int slotIndex, String parent) {
public LinkedMesh (MeshAttachment mesh, string skin, int slotIndex, string parent) {
this.mesh = mesh;
this.skin = skin;
this.slotIndex = slotIndex;
@ -814,7 +813,7 @@ namespace Spine {
}
}
static float[] GetFloatArray(Dictionary<String, Object> map, String name, float scale) {
static float[] GetFloatArray(Dictionary<string, Object> map, string name, float scale) {
var list = (List<Object>)map[name];
var values = new float[list.Count];
if (scale == 1) {
@ -827,7 +826,7 @@ namespace Spine {
return values;
}
static int[] GetIntArray(Dictionary<String, Object> map, String name) {
static int[] GetIntArray(Dictionary<string, Object> map, string name) {
var list = (List<Object>)map[name];
var values = new int[list.Count];
for (int i = 0, n = list.Count; i < n; i++)
@ -835,31 +834,31 @@ namespace Spine {
return values;
}
static float GetFloat(Dictionary<String, Object> map, String name, float defaultValue) {
static float GetFloat(Dictionary<string, Object> map, string name, float defaultValue) {
if (!map.ContainsKey(name))
return defaultValue;
return (float)map[name];
}
static int GetInt(Dictionary<String, Object> map, String name, int defaultValue) {
static int GetInt(Dictionary<string, Object> map, string name, int defaultValue) {
if (!map.ContainsKey(name))
return defaultValue;
return (int)(float)map[name];
}
static bool GetBoolean(Dictionary<String, Object> map, String name, bool defaultValue) {
static bool GetBoolean(Dictionary<string, Object> map, string name, bool defaultValue) {
if (!map.ContainsKey(name))
return defaultValue;
return (bool)map[name];
}
static String GetString(Dictionary<String, Object> map, String name, String defaultValue) {
static string GetString(Dictionary<string, Object> map, string name, string defaultValue) {
if (!map.ContainsKey(name))
return defaultValue;
return (String)map[name];
return (string)map[name];
}
static float ToColor(String hexString, int colorIndex, int expectedLength = 8) {
static float ToColor(string hexString, int colorIndex, int expectedLength = 8) {
if (hexString.Length != expectedLength)
throw new ArgumentException("Color hexidecimal length must be " + expectedLength + ", recieved: " + hexString, "hexString");
return Convert.ToInt32(hexString.Substring(colorIndex * 2, 2), 16) / (float)255;

View File

@ -114,7 +114,7 @@ namespace Spine {
internal static readonly AttachmentKeyTupleComparer Instance = new AttachmentKeyTupleComparer();
bool IEqualityComparer<AttachmentKeyTuple>.Equals (AttachmentKeyTuple o1, AttachmentKeyTuple o2) {
return o1.slotIndex == o2.slotIndex && o1.nameHashCode == o2.nameHashCode && o1.name == o2.name;
return o1.slotIndex == o2.slotIndex && o1.nameHashCode == o2.nameHashCode && string.Equals(o1.name, o2.name, StringComparison.Ordinal);
}
int IEqualityComparer<AttachmentKeyTuple>.GetHashCode (AttachmentKeyTuple o) {

View File

@ -0,0 +1,84 @@
/******************************************************************************
* Spine Runtimes Software License v2.5
*
* Copyright (c) 2013-2016, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable, and
* non-transferable license to use, install, execute, and perform the Spine
* Runtimes software and derivative works solely for personal or internal
* use. Without the written permission of Esoteric Software (see Section 2 of
* the Spine Software License Agreement), you may not (a) modify, translate,
* adapt, or develop new applications using the Spine Runtimes or otherwise
* create derivative works or improvements of the Spine Runtimes or (b) remove,
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
* or other intellectual property or proprietary rights notices on or in the
* Software, including any copy thereof. Redistributions in binary or source
* form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
* USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
using System;
using UnityEngine;
namespace Spine.Unity {
public class RegionlessAttachmentLoader : AttachmentLoader {
static AtlasRegion emptyRegion;
static AtlasRegion EmptyRegion {
get {
if (emptyRegion == null) {
emptyRegion = new AtlasRegion {
name = "Empty AtlasRegion",
page = new AtlasPage {
name = "Empty AtlasPage",
rendererObject = new Material(Shader.Find("Spine/Special/HiddenPass")) { name = "NoRender Material" }
}
};
}
return emptyRegion;
}
}
public RegionAttachment NewRegionAttachment (Skin skin, string name, string path) {
RegionAttachment attachment = new RegionAttachment(name) {
RendererObject = EmptyRegion
};
return attachment;
}
public MeshAttachment NewMeshAttachment (Skin skin, string name, string path) {
MeshAttachment attachment = new MeshAttachment(name) {
RendererObject = EmptyRegion
};
return attachment;
}
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string name) {
return new BoundingBoxAttachment(name);
}
public PathAttachment NewPathAttachment (Skin skin, string name) {
return new PathAttachment(name);
}
public PointAttachment NewPointAttachment (Skin skin, string name) {
return new PointAttachment(name);
}
public ClippingAttachment NewClippingAttachment (Skin skin, string name) {
return new ClippingAttachment(name);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 15f0f78b87720c047a320c5e0e3f91b7
timeCreated: 1520505662
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -126,7 +126,7 @@ namespace Spine.Unity {
Atlas[] atlasArray = this.GetAtlasArray();
#if !SPINE_TK2D
attachmentLoader = new AtlasAttachmentLoader(atlasArray);
attachmentLoader = (atlasArray.Length == 0) ? (AttachmentLoader)new RegionlessAttachmentLoader() : (AttachmentLoader)new AtlasAttachmentLoader(atlasArray);
skeletonDataScale = scale;
#else
if (spriteCollection != null) {

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 954179821df28404683b8289f05d0c6f
folderAsset: yes
timeCreated: 1518344191
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -274,6 +274,9 @@ namespace Spine.Unity.Editor {
EditorGUILayout.LabelField("spine-tk2d", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(spriteCollection, true);
#endif
if (atlasAssets.arraySize == 0)
EditorGUILayout.HelpBox("AtlasAssets array is empty. Skeleton's attachments will load without being mapped to images.", MessageType.Info);
}
void HandleAtlasAssetsNulls () {
@ -485,7 +488,7 @@ namespace Spine.Unity.Editor {
}
void DrawWarningList () {
foreach (var line in warnings)
foreach (string line in warnings)
EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(line, Icons.warning));
}
@ -525,7 +528,9 @@ namespace Spine.Unity.Editor {
if (detectedNullAtlasEntry) {
warnings.Add("AtlasAsset elements should not be null.");
} else {
var missingPaths = SpineEditorUtilities.GetRequiredAtlasRegions(AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue));
List<string> missingPaths = null;
if (atlasAssets.arraySize > 0) {
missingPaths = SpineEditorUtilities.GetRequiredAtlasRegions(AssetDatabase.GetAssetPath(skeletonJSON.objectReferenceValue));
foreach (var atlas in atlasList) {
for (int i = 0; i < missingPaths.Count; i++) {
@ -540,9 +545,12 @@ namespace Spine.Unity.Editor {
if (missingPaths.Count > 0)
warnings.Add("Missing regions. SkeletonDataAsset requires tk2DSpriteCollectionData or Spine AtlasAssets.");
#endif
}
foreach (var str in missingPaths)
if (missingPaths != null) {
foreach (string str in missingPaths)
warnings.Add("Missing Region: '" + str + "'");
}
}
}
@ -629,7 +637,10 @@ namespace Spine.Unity.Editor {
PreviewRenderUtility previewRenderUtility;
Camera PreviewUtilityCamera {
get {
if (previewRenderUtility == null) return null;
if (previewRenderUtility == null) {
return null;
}
#if UNITY_2017_1_OR_NEWER
return previewRenderUtility.camera;
@ -770,7 +781,7 @@ namespace Spine.Unity.Editor {
skeleton.SetToSetupPose();
animationState.SetAnimation(0, targetAnimation, loop);
} else {
var sameAnimation = (currentTrack.Animation == targetAnimation);
bool sameAnimation = (currentTrack.Animation == targetAnimation);
if (sameAnimation) {
currentTrack.TimeScale = (currentTrack.TimeScale == 0) ? 1f : 0f; // pause/play
} else {
@ -974,18 +985,19 @@ namespace Spine.Unity.Editor {
for (int i = 0; i < currentAnimationEvents.Count; i++) {
float fr = currentAnimationEventTimes[i];
var evRect = new Rect(barRect);
evRect.x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (Icons.userEvent.width / 2), barRect.x, float.MaxValue);
evRect.width = Icons.userEvent.width;
evRect.height = Icons.userEvent.height;
evRect.y += Icons.userEvent.height;
var evRect = new Rect(barRect) {
x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (Icons.userEvent.width / 2), barRect.x, float.MaxValue),
y = barRect.y + Icons.userEvent.height,
width = Icons.userEvent.width,
height = Icons.userEvent.height
};
GUI.DrawTexture(evRect, Icons.userEvent);
Event ev = Event.current;
if (ev.type == EventType.Repaint) {
if (evRect.Contains(ev.mousePosition)) {
Rect tooltipRect = new Rect(evRect);
GUIStyle tooltipStyle = EditorStyles.helpBox;
Rect tooltipRect = new Rect(evRect);
tooltipRect.width = tooltipStyle.CalcSize(new GUIContent(currentAnimationEvents[i].Data.Name)).x;
tooltipRect.y -= 4;
tooltipRect.x += 4;

View File

@ -155,16 +155,15 @@ namespace Spine.Unity.Editor {
public static string editorGUIPath = "";
public static bool initialized;
/// This list keeps the asset reference temporarily during importing.
/// HACK: This list keeps the asset reference temporarily during importing.
///
/// In cases of very large projects/sufficient RAM pressure, when AssetDatabase.SaveAssets is called,
/// Unity can mistakenly unload assets whose references are only on the stack.
/// This leads to MissingReferenceException and other errors.
static readonly List<ScriptableObject> protectFromStackGarbageCollection = new List<ScriptableObject>();
static HashSet<string> assetsImportedInWrongState;
static Dictionary<int, GameObject> skeletonRendererTable;
static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable;
static Dictionary<int, BoundingBoxFollower> boundingBoxFollowerTable;
static HashSet<string> assetsImportedInWrongState = new HashSet<string>();
#if SPINE_TK2D
const float DEFAULT_DEFAULT_SCALE = 1f;
@ -220,29 +219,23 @@ namespace Spine.Unity.Editor {
Icons.Initialize();
assetsImportedInWrongState = new HashSet<string>();
skeletonRendererTable = new Dictionary<int, GameObject>();
skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
boundingBoxFollowerTable = new Dictionary<int, BoundingBoxFollower>();
// Drag and Drop
SceneView.onSceneGUIDelegate -= SceneViewDragAndDrop;
SceneView.onSceneGUIDelegate += SceneViewDragAndDrop;
EditorApplication.hierarchyWindowItemOnGUI -= HierarchyDragAndDrop;
EditorApplication.hierarchyWindowItemOnGUI += HierarchyDragAndDrop;
EditorApplication.hierarchyWindowItemOnGUI -= SpineEditorHierarchyHandler.HierarchyDragAndDrop;
EditorApplication.hierarchyWindowItemOnGUI += SpineEditorHierarchyHandler.HierarchyDragAndDrop;
// Hierarchy Icons
#if UNITY_2017_2_OR_NEWER
EditorApplication.playModeStateChanged -= HierarchyIconsOnPlaymodeStateChanged;
EditorApplication.playModeStateChanged += HierarchyIconsOnPlaymodeStateChanged;
HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
EditorApplication.playModeStateChanged -= SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged;
EditorApplication.playModeStateChanged += SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged;
SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
#else
EditorApplication.playmodeStateChanged -= HierarchyIconsOnPlaymodeStateChanged;
EditorApplication.playmodeStateChanged += HierarchyIconsOnPlaymodeStateChanged;
HierarchyIconsOnPlaymodeStateChanged();
EditorApplication.playmodeStateChanged -= SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged;
EditorApplication.playmodeStateChanged += SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged;
SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged();
#endif
initialized = true;
}
@ -265,9 +258,9 @@ namespace Spine.Unity.Editor {
if (EditorGUI.EndChangeCheck()) {
EditorPrefs.SetBool(SHOW_HIERARCHY_ICONS_KEY, showHierarchyIcons);
#if UNITY_2017_2_OR_NEWER
HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged(PlayModeStateChange.EnteredEditMode);
#else
HierarchyIconsOnPlaymodeStateChanged();
SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged();
#endif
}
@ -323,10 +316,9 @@ namespace Spine.Unity.Editor {
#endregion
#region Drag and Drop Instantiation
public delegate Component InstantiateDelegate (SkeletonDataAsset skeletonDataAsset);
struct SpawnMenuData {
public struct SpawnMenuData {
public Vector3 spawnPoint;
public SkeletonDataAsset skeletonDataAsset;
public InstantiateDelegate instantiateDelegate;
@ -339,7 +331,7 @@ namespace Spine.Unity.Editor {
public bool isUI;
}
public static readonly List<SkeletonComponentSpawnType> additionalSpawnTypes = new List<SkeletonComponentSpawnType>();
internal static readonly List<SkeletonComponentSpawnType> additionalSpawnTypes = new List<SkeletonComponentSpawnType>();
static void SceneViewDragAndDrop (SceneView sceneview) {
var current = UnityEngine.Event.current;
@ -378,45 +370,6 @@ namespace Spine.Unity.Editor {
}
}
static void HierarchyDragAndDrop (int instanceId, Rect selectionRect) {
// HACK: Uses EditorApplication.hierarchyWindowItemOnGUI.
// Only works when there is at least one item in the scene.
var current = UnityEngine.Event.current;
var eventType = current.type;
bool isDraggingEvent = eventType == EventType.DragUpdated;
bool isDropEvent = eventType == EventType.DragPerform;
if (isDraggingEvent || isDropEvent) {
var mouseOverWindow = EditorWindow.mouseOverWindow;
if (mouseOverWindow != null) {
// One, existing, valid SkeletonDataAsset
var references = DragAndDrop.objectReferences;
if (references.Length == 1) {
var skeletonDataAsset = references[0] as SkeletonDataAsset;
if (skeletonDataAsset != null && skeletonDataAsset.GetSkeletonData(true) != null) {
// Allow drag-and-dropping anywhere in the Hierarchy Window.
// HACK: string-compare because we can't get its type via reflection.
const string HierarchyWindow = "UnityEditor.SceneHierarchyWindow";
if (HierarchyWindow.Equals(mouseOverWindow.GetType().ToString(), System.StringComparison.Ordinal)) {
if (isDraggingEvent) {
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
current.Use();
} else if (isDropEvent) {
ShowInstantiateContextMenu(skeletonDataAsset, Vector3.zero);
DragAndDrop.AcceptDrag();
current.Use();
return;
}
}
}
}
}
}
}
public static void ShowInstantiateContextMenu (SkeletonDataAsset skeletonDataAsset, Vector3 spawnPoint) {
var menu = new GenericMenu();
@ -454,8 +407,8 @@ namespace Spine.Unity.Editor {
menu.ShowAsContext();
}
public static void HandleSkeletonComponentDrop (object menuData) {
var data = (SpawnMenuData)menuData;
public static void HandleSkeletonComponentDrop (object spawnMenuData) {
var data = (SpawnMenuData)spawnMenuData;
if (data.skeletonDataAsset.GetSkeletonData(true) == null) {
EditorUtility.DisplayDialog("Invalid SkeletonDataAsset", "Unable to create Spine GameObject.\n\nPlease check your SkeletonDataAsset.", "Ok");
@ -464,16 +417,15 @@ namespace Spine.Unity.Editor {
bool isUI = data.isUI;
GameObject newGameObject = null;
Component newSkeletonComponent = data.instantiateDelegate.Invoke(data.skeletonDataAsset);
newGameObject = newSkeletonComponent.gameObject;
var transform = newGameObject.transform;
GameObject newGameObject = newSkeletonComponent.gameObject;
Transform newTransform = newGameObject.transform;
var activeGameObject = Selection.activeGameObject;
if (isUI && activeGameObject != null)
transform.SetParent(activeGameObject.transform, false);
newTransform.SetParent(activeGameObject.transform, false);
newGameObject.transform.position = isUI ? data.spawnPoint : RoundVector(data.spawnPoint, 2);
newTransform.position = isUI ? data.spawnPoint : RoundVector(data.spawnPoint, 2);
if (isUI && (activeGameObject == null || activeGameObject.GetComponent<RectTransform>() == null))
Debug.Log("Created a UI Skeleton GameObject not under a RectTransform. It may not be visible until you parent it to a canvas.");
@ -509,10 +461,15 @@ namespace Spine.Unity.Editor {
#endregion
#region Hierarchy
static class SpineEditorHierarchyHandler {
static Dictionary<int, GameObject> skeletonRendererTable = new Dictionary<int, GameObject>();
static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
static Dictionary<int, BoundingBoxFollower> boundingBoxFollowerTable = new Dictionary<int, BoundingBoxFollower>();
#if UNITY_2017_2_OR_NEWER
static void HierarchyIconsOnPlaymodeStateChanged (PlayModeStateChange stateChange) {
internal static void HierarchyIconsOnPlaymodeStateChanged (PlayModeStateChange stateChange) {
#else
static void HierarchyIconsOnPlaymodeStateChanged () {
internal static void HierarchyIconsOnPlaymodeStateChanged () {
#endif
skeletonRendererTable.Clear();
skeletonUtilityBoneTable.Clear();
@ -528,25 +485,25 @@ namespace Spine.Unity.Editor {
}
}
static void HierarchyIconsOnChanged () {
internal static void HierarchyIconsOnChanged () {
skeletonRendererTable.Clear();
skeletonUtilityBoneTable.Clear();
boundingBoxFollowerTable.Clear();
SkeletonRenderer[] arr = Object.FindObjectsOfType<SkeletonRenderer>();
foreach (SkeletonRenderer r in arr)
skeletonRendererTable.Add(r.gameObject.GetInstanceID(), r.gameObject);
skeletonRendererTable[r.gameObject.GetInstanceID()] = r.gameObject;
SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType<SkeletonUtilityBone>();
foreach (SkeletonUtilityBone b in boneArr)
skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b);
skeletonUtilityBoneTable[b.gameObject.GetInstanceID()] = b;
BoundingBoxFollower[] bbfArr = Object.FindObjectsOfType<BoundingBoxFollower>();
foreach (BoundingBoxFollower bbf in bbfArr)
boundingBoxFollowerTable.Add(bbf.gameObject.GetInstanceID(), bbf);
boundingBoxFollowerTable[bbf.gameObject.GetInstanceID()] = bbf;
}
static void HierarchyIconsOnGUI (int instanceId, Rect selectionRect) {
internal static void HierarchyIconsOnGUI (int instanceId, Rect selectionRect) {
Rect r = new Rect(selectionRect);
if (skeletonRendererTable.ContainsKey(instanceId)) {
r.x = r.width - 15;
@ -577,6 +534,46 @@ namespace Spine.Unity.Editor {
}
}
}
internal static void HierarchyDragAndDrop (int instanceId, Rect selectionRect) {
// HACK: Uses EditorApplication.hierarchyWindowItemOnGUI.
// Only works when there is at least one item in the scene.
var current = UnityEngine.Event.current;
var eventType = current.type;
bool isDraggingEvent = eventType == EventType.DragUpdated;
bool isDropEvent = eventType == EventType.DragPerform;
if (isDraggingEvent || isDropEvent) {
var mouseOverWindow = EditorWindow.mouseOverWindow;
if (mouseOverWindow != null) {
// One, existing, valid SkeletonDataAsset
var references = DragAndDrop.objectReferences;
if (references.Length == 1) {
var skeletonDataAsset = references[0] as SkeletonDataAsset;
if (skeletonDataAsset != null && skeletonDataAsset.GetSkeletonData(true) != null) {
// Allow drag-and-dropping anywhere in the Hierarchy Window.
// HACK: string-compare because we can't get its type via reflection.
const string HierarchyWindow = "UnityEditor.SceneHierarchyWindow";
if (HierarchyWindow.Equals(mouseOverWindow.GetType().ToString(), System.StringComparison.Ordinal)) {
if (isDraggingEvent) {
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
current.Use();
} else if (isDropEvent) {
ShowInstantiateContextMenu(skeletonDataAsset, Vector3.zero);
DragAndDrop.AcceptDrag();
current.Use();
return;
}
}
}
}
}
}
}
}
#endregion
#region Auto-Import Entry Point
@ -669,7 +666,7 @@ namespace Spine.Unity.Editor {
bool resolved = false;
while (!resolved) {
var filename = Path.GetFileNameWithoutExtension(sp);
string filename = Path.GetFileNameWithoutExtension(sp);
int result = EditorUtility.DisplayDialogComplex(
string.Format("AtlasAsset for \"{0}\"", filename),
string.Format("Could not automatically set the AtlasAsset for \"{0}\". You may set it manually.", filename),
@ -1243,7 +1240,8 @@ namespace Spine.Unity.Editor {
#endregion
#region Checking Methods
static int[][] compatibleVersions = { new[] {3, 6, 0}, new[] {3, 5, 0} };
static int[][] compatibleBinaryVersions = { new[] {3, 6, 0}, new[] {3, 5, 0} };
static int[][] compatibleJsonVersions = { new[] { 3, 6, 0 }, new[] { 3, 7, 0 }, new[] { 3, 5, 0 } };
//static bool isFixVersionRequired = false;
static bool CheckForValidSkeletonData (string skeletonJSONPath) {
@ -1269,17 +1267,18 @@ namespace Spine.Unity.Editor {
bool isSpineData = false;
string rawVersion = null;
int[][] compatibleVersions;
if (asset.name.Contains(".skel")) {
try {
rawVersion = SkeletonBinary.GetVersionString(new MemoryStream(asset.bytes));
//Debug.Log(rawVersion);
isSpineData = !(string.IsNullOrEmpty(rawVersion));
compatibleVersions = compatibleBinaryVersions;
} catch (System.Exception e) {
Debug.LogErrorFormat("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}", asset.name, e);
return false;
}
} else {
var obj = Json.Deserialize(new StringReader(asset.text));
object obj = Json.Deserialize(new StringReader(asset.text));
if (obj == null) {
Debug.LogErrorFormat("'{0}' is not valid JSON.", asset.name);
return false;
@ -1298,14 +1297,16 @@ namespace Spine.Unity.Editor {
skeletonInfo.TryGetValue("spine", out jv);
rawVersion = jv as string;
}
compatibleVersions = compatibleJsonVersions;
}
// Version warning
if (isSpineData) {
string runtimeVersionDebugString = compatibleVersions[0][0] + "." + compatibleVersions[0][1];
string primaryRuntimeVersionDebugString = compatibleVersions[0][0] + "." + compatibleVersions[0][1];
if (string.IsNullOrEmpty(rawVersion)) {
Debug.LogWarningFormat("Skeleton '{0}' has no version information. It may be incompatible with your runtime version: spine-unity v{1}", asset.name, runtimeVersionDebugString);
Debug.LogWarningFormat("Skeleton '{0}' has no version information. It may be incompatible with your runtime version: spine-unity v{1}", asset.name, primaryRuntimeVersionDebugString);
} else {
string[] versionSplit = rawVersion.Split('.');
bool match = false;
@ -1322,7 +1323,7 @@ namespace Spine.Unity.Editor {
}
if (!match)
Debug.LogWarningFormat("Skeleton '{0}' (exported with Spine {1}) may be incompatible with your runtime version: spine-unity v{2}", asset.name, rawVersion, runtimeVersionDebugString);
Debug.LogWarningFormat("Skeleton '{0}' (exported with Spine {1}) may be incompatible with your runtime version: spine-unity v{2}", asset.name, rawVersion, primaryRuntimeVersionDebugString);
}
}
@ -1657,11 +1658,12 @@ namespace Spine.Unity.Editor {
public static GUIStyle BoneNameStyle {
get {
if (_boneNameStyle == null) {
_boneNameStyle = new GUIStyle(EditorStyles.whiteMiniLabel);
_boneNameStyle.alignment = TextAnchor.MiddleCenter;
_boneNameStyle.stretchWidth = true;
_boneNameStyle.padding = new RectOffset(0, 0, 0, 0);
_boneNameStyle.contentOffset = new Vector2(-5f, 0f);
_boneNameStyle = new GUIStyle(EditorStyles.whiteMiniLabel) {
alignment = TextAnchor.MiddleCenter,
stretchWidth = true,
padding = new RectOffset(0, 0, 0, 0),
contentOffset = new Vector2(-5f, 0f)
};
}
return _boneNameStyle;
}
@ -1983,7 +1985,7 @@ namespace Spine.Unity.Editor {
}
static void DrawArrowhead (Matrix4x4 m) {
var s = SpineHandles.handleScale;
float s = SpineHandles.handleScale;
m.m00 *= s;
m.m01 *= s;
m.m02 *= s;

View File

@ -86,13 +86,34 @@ namespace Spine.Unity.Editor {
#region SerializedProperty Helpers
public static SerializedProperty FindBaseOrSiblingProperty (this SerializedProperty property, string propertyName) {
if (string.IsNullOrEmpty(propertyName)) return null;
SerializedProperty relativeProperty = property.serializedObject.FindProperty(propertyName); // baseProperty
if (relativeProperty == null) { // If no baseProperty, find sibling property.
int nameLength = property.name.Length;
// If base property is not found, look for the sibling property.
if (relativeProperty == null) {
string propertyPath = property.propertyPath;
propertyPath = propertyPath.Remove(propertyPath.Length - nameLength, nameLength) + propertyName;
int localPathLength = 0;
if (property.isArray) {
const int internalArrayPathLength = 14; // int arrayPathLength = ".Array.data[x]".Length;
int propertyPathLength = propertyPath.Length;
int n = propertyPathLength - internalArrayPathLength;
// Find the dot before the array property name and
// store the total length from the name of the array until the end of the propertyPath.
for (int i = internalArrayPathLength + 1; i < n; i++) {
if (propertyPath[propertyPathLength - i] == '.') {
localPathLength = i - 1;
break;
}
}
} else {
localPathLength = property.name.Length;
}
propertyPath = propertyPath.Remove(propertyPath.Length - localPathLength, localPathLength) + propertyName;
relativeProperty = property.serializedObject.FindProperty(propertyPath);
}
return relativeProperty;
}
#endregion

View File

@ -113,6 +113,7 @@ Shader "Spine/Skeleton Lit" {
float3 eyePos = UnityObjectToViewPos(float4(v.pos, 1)).xyz; //mul(UNITY_MATRIX_MV, float4(v.pos,1)).xyz;
half3 fixedNormal = half3(0,0,-1);
half3 eyeNormal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, fixedNormal));
//half3 eyeNormal = half3(0,0,1);
half3 viewDir = 0.0;
// Lights