From 2b86668f4ec06c010fcd2a0753d4a1871ab6448d Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Tue, 24 Sep 2013 11:10:10 +0200 Subject: [PATCH] More efficient draw order when bind pose order is keyed. --- spine-csharp/src/Animation.cs | 12 +++-- spine-csharp/src/SkeletonJson.cs | 47 ++++++++++--------- .../com/esotericsoftware/spine/Animation.java | 11 +++-- .../esotericsoftware/spine/SkeletonJson.java | 40 +++++++++------- spine-libgdx/test/spineboy.json | 12 +---- spine-xna/example/data/spineboy.json | 5 +- 6 files changed, 66 insertions(+), 61 deletions(-) diff --git a/spine-csharp/src/Animation.cs b/spine-csharp/src/Animation.cs index d424f5ea1..b01cbf32e 100644 --- a/spine-csharp/src/Animation.cs +++ b/spine-csharp/src/Animation.cs @@ -513,7 +513,8 @@ namespace Spine { drawOrders = new int[frameCount][]; } - /** Sets the time and value of the specified keyframe. */ + /** Sets the time and value of the specified keyframe. + * @param drawOrder May be null to use bind pose draw order. */ public void setFrame (int frameIndex, float time, int[] drawOrder) { frames[frameIndex] = time; drawOrders[frameIndex] = drawOrder; @@ -532,8 +533,13 @@ namespace Spine { List drawOrder = skeleton.drawOrder; List slots = skeleton.slots; int[] drawOrderToSetupIndex = drawOrders[frameIndex]; - for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++) - drawOrder[i] = slots[drawOrderToSetupIndex[i]]; + if (drawOrderToSetupIndex == null) { + drawOrder.Clear(); + drawOrder.AddRange(slots); + } else { + for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++) + drawOrder[i] = slots[drawOrderToSetupIndex[i]]; + } } } } diff --git a/spine-csharp/src/SkeletonJson.cs b/spine-csharp/src/SkeletonJson.cs index 62c0a9c1e..0aae8de0e 100644 --- a/spine-csharp/src/SkeletonJson.cs +++ b/spine-csharp/src/SkeletonJson.cs @@ -29,8 +29,8 @@ * 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 System.IO; using System.Collections.Generic; @@ -372,27 +372,30 @@ namespace Spine { int slotCount = skeletonData.slots.Count; int frameIndex = 0; foreach (Dictionary drawOrderMap in values) { - int[] drawOrder = new int[slotCount]; - for (int i = slotCount - 1; i >= 0; i--) - drawOrder[i] = -1; - List offsets = (List)drawOrderMap["offsets"]; - int[] unchanged = new int[slotCount - offsets.Count]; - int originalIndex = 0, unchangedIndex = 0; - foreach (Dictionary 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) + int[] drawOrder = null; + if (drawOrderMap.ContainsKey("offsets")) { + drawOrder = new int[slotCount]; + for (int i = slotCount - 1; i >= 0; i--) + drawOrder[i] = -1; + List offsets = (List)drawOrderMap["offsets"]; + int[] unchanged = new int[slotCount - offsets.Count]; + int originalIndex = 0, unchangedIndex = 0; + foreach (Dictionary 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) + unchanged[unchangedIndex++] = originalIndex++; + // Set changed items. + drawOrder[originalIndex + (int)(float)offsetMap["offset"]] = originalIndex++; + } + // Collect remaining unchanged items. + while (originalIndex < slotCount) unchanged[unchangedIndex++] = originalIndex++; - // Set changed items. - drawOrder[originalIndex + (int)(float)offsetMap["offset"]] = originalIndex++; + // Fill in unchanged items. + for (int i = slotCount - 1; i >= 0; i--) + if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex]; } - // Collect remaining unchanged items. - while (originalIndex < slotCount) - unchanged[unchangedIndex++] = originalIndex++; - // Fill in unchanged items. - for (int i = slotCount - 1; i >= 0; i--) - if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex]; timeline.setFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder); } timelines.Add(timeline); @@ -415,4 +418,4 @@ namespace Spine { } } } -} +} diff --git a/spine-libgdx/src/com/esotericsoftware/spine/Animation.java b/spine-libgdx/src/com/esotericsoftware/spine/Animation.java index 4ebb8813e..fdf3ee64f 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/Animation.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/Animation.java @@ -594,7 +594,8 @@ public class Animation { return drawOrders; } - /** Sets the time of the specified keyframe. */ + /** Sets the time of the specified keyframe. + * @param drawOrder May be null to use bind pose draw order. */ public void setFrame (int frameIndex, float time, int[] drawOrder) { frames[frameIndex] = time; drawOrders[frameIndex] = drawOrder; @@ -613,8 +614,12 @@ public class Animation { Array drawOrder = skeleton.drawOrder; Array slots = skeleton.slots; int[] drawOrderToSetupIndex = drawOrders[frameIndex]; - for (int i = 0, n = drawOrderToSetupIndex.length; i < n; i++) - drawOrder.set(i, slots.get(drawOrderToSetupIndex[i])); + if (drawOrderToSetupIndex == null) + System.arraycopy(slots.items, 0, drawOrder.items, 0, slots.size); + else { + for (int i = 0, n = drawOrderToSetupIndex.length; i < n; i++) + drawOrder.set(i, slots.get(drawOrderToSetupIndex[i])); + } } } } diff --git a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java index f025e6929..d3a48380f 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java @@ -320,26 +320,30 @@ public class SkeletonJson { int slotCount = skeletonData.slots.size; int frameIndex = 0; for (JsonValue drawOrderMap = drawOrdersMap.child; drawOrderMap != null; drawOrderMap = drawOrderMap.next()) { - int[] drawOrder = new int[slotCount]; - for (int i = slotCount - 1; i >= 0; i--) - drawOrder[i] = -1; - int[] unchanged = new int[slotCount - drawOrderMap.get("offsets").size]; - int originalIndex = 0, unchangedIndex = 0; - for (JsonValue offsetMap = drawOrderMap.getChild("offsets"); offsetMap != null; offsetMap = offsetMap.next()) { - int slotIndex = skeletonData.findSlotIndex(offsetMap.getString("slot")); - if (slotIndex == -1) throw new SerializationException("Slot not found: " + offsetMap.getString("slot")); - // Collect unchanged items. - while (originalIndex != slotIndex) + int[] drawOrder = null; + JsonValue offsets = drawOrderMap.get("offsets"); + if (offsets != null) { + drawOrder = new int[slotCount]; + for (int i = slotCount - 1; i >= 0; i--) + drawOrder[i] = -1; + int[] unchanged = new int[slotCount - offsets.size]; + int originalIndex = 0, unchangedIndex = 0; + for (JsonValue offsetMap = offsets.child; offsetMap != null; offsetMap = offsetMap.next()) { + int slotIndex = skeletonData.findSlotIndex(offsetMap.getString("slot")); + if (slotIndex == -1) throw new SerializationException("Slot not found: " + offsetMap.getString("slot")); + // Collect unchanged items. + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + // Set changed items. + drawOrder[originalIndex + offsetMap.getInt("offset")] = originalIndex++; + } + // Collect remaining unchanged items. + while (originalIndex < slotCount) unchanged[unchangedIndex++] = originalIndex++; - // Set changed items. - drawOrder[originalIndex + offsetMap.getInt("offset")] = originalIndex++; + // Fill in unchanged items. + for (int i = slotCount - 1; i >= 0; i--) + if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex]; } - // Collect remaining unchanged items. - while (originalIndex < slotCount) - unchanged[unchangedIndex++] = originalIndex++; - // Fill in unchanged items. - for (int i = slotCount - 1; i >= 0; i--) - if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex]; timeline.setFrame(frameIndex++, drawOrderMap.getFloat("time"), drawOrder); } timelines.add(timeline); diff --git a/spine-libgdx/test/spineboy.json b/spine-libgdx/test/spineboy.json index 7619ab6b6..acba1f13a 100644 --- a/spine-libgdx/test/spineboy.json +++ b/spine-libgdx/test/spineboy.json @@ -300,17 +300,7 @@ { "slot": "eyes", "offset": 3 } ] }, - { - "time": 2.6206, - "offsets": [ - { "slot": "head", "offset": -12 }, - { "slot": "eyes", "offset": -12 } - ] - }, - { - "time": 3.5862, - "offsets": [] - } + { "time": 2 } ] }, "jump": { diff --git a/spine-xna/example/data/spineboy.json b/spine-xna/example/data/spineboy.json index 7619ab6b6..113e72c33 100644 --- a/spine-xna/example/data/spineboy.json +++ b/spine-xna/example/data/spineboy.json @@ -307,10 +307,7 @@ { "slot": "eyes", "offset": -12 } ] }, - { - "time": 3.5862, - "offsets": [] - } + { "time": 3.5862 } ] }, "jump": {