From a76c396528d043e8b1140990d3b32b46bfbcc61a Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Mon, 28 Apr 2014 12:49:06 +0200 Subject: [PATCH] Separated updateRegions() from setMesh() to facilitate lazy loading atlas regions. Moved setting path into SkeletonJson. --- .../src/Attachments/AtlasAttachmentLoader.cs | 3 -- .../src/Attachments/MeshAttachment.cs | 21 ++++++++---- .../src/Attachments/SkinnedMeshAttachment.cs | 21 ++++++++---- spine-csharp/src/SkeletonJson.cs | 5 +++ .../spine/SkeletonBinary.java | 6 +++- .../esotericsoftware/spine/SkeletonJson.java | 5 +++ .../attachments/AtlasAttachmentLoader.java | 3 -- .../spine/attachments/MeshAttachment.java | 16 ++++++---- .../attachments/SkinnedMeshAttachment.java | 32 +++++++++++-------- 9 files changed, 71 insertions(+), 41 deletions(-) diff --git a/spine-csharp/src/Attachments/AtlasAttachmentLoader.cs b/spine-csharp/src/Attachments/AtlasAttachmentLoader.cs index be2f78621..37fdbb9fd 100644 --- a/spine-csharp/src/Attachments/AtlasAttachmentLoader.cs +++ b/spine-csharp/src/Attachments/AtlasAttachmentLoader.cs @@ -43,7 +43,6 @@ namespace Spine { AtlasRegion region = atlas.FindRegion(path); if (region == null) throw new Exception("Region not found in atlas: " + path + " (region attachment: " + name + ")"); RegionAttachment attachment = new RegionAttachment(name); - attachment.Path = path; attachment.RendererObject = region; attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate); attachment.regionOffsetX = region.offsetX; @@ -59,7 +58,6 @@ namespace Spine { AtlasRegion region = atlas.FindRegion(path); if (region == null) throw new Exception("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); MeshAttachment attachment = new MeshAttachment(name); - attachment.Path = path; attachment.RendererObject = region; attachment.RegionU = region.u; attachment.RegionV = region.v; @@ -79,7 +77,6 @@ namespace Spine { AtlasRegion region = atlas.FindRegion(path); if (region == null) throw new Exception("Region not found in atlas: " + path + " (skinned mesh attachment: " + name + ")"); SkinnedMeshAttachment attachment = new SkinnedMeshAttachment(name); - attachment.Path = path; attachment.RendererObject = region; attachment.RegionU = region.u; attachment.RegionV = region.v; diff --git a/spine-csharp/src/Attachments/MeshAttachment.cs b/spine-csharp/src/Attachments/MeshAttachment.cs index ee8a20607..bf5d1cf87 100644 --- a/spine-csharp/src/Attachments/MeshAttachment.cs +++ b/spine-csharp/src/Attachments/MeshAttachment.cs @@ -33,12 +33,13 @@ using System; namespace Spine { /// Attachment that displays a texture region. public class MeshAttachment : Attachment { - internal float[] vertices, uvs; + internal float[] vertices, uvs, regionUVs; internal int[] triangles; internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight; internal float r = 1, g = 1, b = 1, a = 1; public float[] Vertices { get { return vertices; } set { vertices = value; } } + public float[] RegionUVs { get { return regionUVs; } set { regionUVs = value; } } public float[] UVs { get { return uvs; } set { uvs = value; } } public int[] Triangles { get { return triangles; } set { triangles = value; } } @@ -71,20 +72,26 @@ namespace Spine { : base(name) { } - public void SetMesh (float[] vertices, int[] triangles, float[] uvs) { + public void SetMesh (float[] vertices, int[] triangles, float[] regionUVs) { this.vertices = vertices; this.triangles = triangles; - this.uvs = uvs; + this.regionUVs = regionUVs; + this.uvs = new float[regionUVs.Length]; + } + + public void UpdateUVs () { float u = RegionU, v = RegionV, width = RegionU2 - RegionU, height = RegionV2 - RegionV; + float[] regionUVs = this.regionUVs; + float[] uvs = this.uvs; if (RegionRotate) { for (int i = 0, n = uvs.Length; i < n; i += 2) { - uvs[i] = u + uvs[i + 1] * width; - uvs[i + 1] = v + height - uvs[i] * height; + uvs[i] = u + regionUVs[i + 1] * width; + uvs[i + 1] = v + height - regionUVs[i] * height; } } else { for (int i = 0, n = uvs.Length; i < n; i += 2) { - uvs[i] = u + uvs[i] * width; - uvs[i + 1] = v + uvs[i + 1] * height; + uvs[i] = u + regionUVs[i] * width; + uvs[i + 1] = v + regionUVs[i + 1] * height; } } } diff --git a/spine-csharp/src/Attachments/SkinnedMeshAttachment.cs b/spine-csharp/src/Attachments/SkinnedMeshAttachment.cs index 5e24d2fb9..cb32cfa54 100644 --- a/spine-csharp/src/Attachments/SkinnedMeshAttachment.cs +++ b/spine-csharp/src/Attachments/SkinnedMeshAttachment.cs @@ -35,13 +35,14 @@ namespace Spine { /// Attachment that displays a texture region. public class SkinnedMeshAttachment : Attachment { internal int[] bones; - internal float[] weights, uvs; + internal float[] weights, uvs, regionUVs; internal int[] triangles; internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight; internal float r = 1, g = 1, b = 1, a = 1; public int[] Bones { get { return bones; } set { bones = value; } } public float[] Weights { get { return weights; } set { weights = value; } } + public float[] RegionUVs { get { return regionUVs; } set { regionUVs = value; } } public float[] UVs { get { return uvs; } set { uvs = value; } } public int[] Triangles { get { return triangles; } set { triangles = value; } } @@ -74,21 +75,27 @@ namespace Spine { : base(name) { } - public void SetMesh (int[] bones, float[] weights, int[] triangles, float[] uvs) { + public void SetMesh (int[] bones, float[] weights, int[] triangles, float[] regionUVs) { this.bones = bones; this.weights = weights; this.triangles = triangles; - this.uvs = uvs; + this.regionUVs = regionUVs; + this.uvs = new float[regionUVs.Length]; + } + + public void UpdateUVs () { float u = RegionU, v = RegionV, width = RegionU2 - RegionU, height = RegionV2 - RegionV; + float[] regionUVs = this.regionUVs; + float[] uvs = this.uvs; if (RegionRotate) { for (int i = 0, n = uvs.Length; i < n; i += 2) { - uvs[i] = u + uvs[i + 1] * width; - uvs[i + 1] = v + height - uvs[i] * height; + uvs[i] = u + regionUVs[i + 1] * width; + uvs[i + 1] = v + height - regionUVs[i] * height; } } else { for (int i = 0, n = uvs.Length; i < n; i += 2) { - uvs[i] = u + uvs[i] * width; - uvs[i + 1] = v + uvs[i + 1] * height; + uvs[i] = u + regionUVs[i] * width; + uvs[i + 1] = v + regionUVs[i + 1] * height; } } } diff --git a/spine-csharp/src/SkeletonJson.cs b/spine-csharp/src/SkeletonJson.cs index a24f9d4df..20beca6a8 100644 --- a/spine-csharp/src/SkeletonJson.cs +++ b/spine-csharp/src/SkeletonJson.cs @@ -196,6 +196,7 @@ namespace Spine { case AttachmentType.region: RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path); if (region == null) return null; + region.Path = path; region.x = GetFloat(map, "x", 0) * Scale; region.y = GetFloat(map, "y", 0) * Scale; region.scaleX = GetFloat(map, "scaleX", 1); @@ -218,10 +219,12 @@ namespace Spine { MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path); if (mesh == null) return null; + mesh.Path = path; float[] uvs = GetFloatArray(map, "uvs", 1); int[] triangles = GetIntArray(map, "triangles"); float[] vertices = GetFloatArray(map, "vertices", Scale); mesh.SetMesh(vertices, triangles, uvs); + mesh.UpdateUVs(); if (map.ContainsKey("color")) { var color = (String)map["color"]; @@ -242,6 +245,7 @@ namespace Spine { SkinnedMeshAttachment mesh = attachmentLoader.NewSkinnedMeshAttachment(skin, name, path); if (mesh == null) return null; + mesh.Path = path; float[] uvs = GetFloatArray(map, "uvs", 1); int[] triangles = GetIntArray(map, "triangles"); @@ -261,6 +265,7 @@ namespace Spine { } } mesh.SetMesh(bones.ToArray(), weights.ToArray(), triangles, uvs); + mesh.UpdateUVs(); if (map.ContainsKey("color")) { var color = (String)map["color"]; diff --git a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java index 5ac73d980..c89892cca 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java @@ -202,6 +202,7 @@ public class SkeletonBinary { if (path == null) path = name; RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path); if (region == null) return null; + region.setPath(path); region.setX(input.readFloat() * scale); region.setY(input.readFloat() * scale); region.setScaleX(input.readFloat()); @@ -224,10 +225,12 @@ public class SkeletonBinary { if (path == null) path = name; MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path); if (mesh == null) return null; + mesh.setPath(path); float[] uvs = readFloatArray(input, 1); short[] triangles = readShortArray(input); float[] vertices = readFloatArray(input, scale); mesh.setMesh(vertices, triangles, uvs); + mesh.updateUVs(); Color.rgba8888ToColor(mesh.getColor(), input.readInt()); if (nonessential) { mesh.setEdges(readIntArray(input)); @@ -242,6 +245,7 @@ public class SkeletonBinary { if (path == null) path = name; SkinnedMeshAttachment mesh = attachmentLoader.newSkinnedMeshAttachment(skin, name, path); if (mesh == null) return null; + mesh.setPath(path); float[] uvs = readFloatArray(input, 1); short[] triangles = readShortArray(input); @@ -259,7 +263,7 @@ public class SkeletonBinary { } } mesh.setMesh(bones.toArray(), weights.toArray(), triangles, uvs); - + mesh.updateUVs(); Color.rgba8888ToColor(mesh.getColor(), input.readInt()); if (nonessential) { mesh.setEdges(readIntArray(input)); diff --git a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java index acafaed67..9c46e066d 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java @@ -176,6 +176,7 @@ public class SkeletonJson { case region: RegionAttachment region = attachmentLoader.newRegionAttachment(skin, name, path); if (region == null) return null; + region.setPath(path); region.setX(map.getFloat("x", 0) * scale); region.setY(map.getFloat("y", 0) * scale); region.setScaleX(map.getFloat("scaleX", 1)); @@ -203,6 +204,7 @@ public class SkeletonJson { case mesh: { MeshAttachment mesh = attachmentLoader.newMeshAttachment(skin, name, path); if (mesh == null) return null; + mesh.setPath(path); float[] uvs = map.require("uvs").asFloatArray(); short[] triangles = map.require("triangles").asShortArray(); @@ -212,6 +214,7 @@ public class SkeletonJson { vertices[i] *= scale; } mesh.setMesh(vertices, triangles, uvs); + mesh.updateUVs(); if (map.has("hull")) mesh.setHullLength(map.require("hull").asInt() * 2); if (map.has("edges")) mesh.setEdges(map.require("edges").asIntArray()); @@ -222,6 +225,7 @@ public class SkeletonJson { case skinnedmesh: { SkinnedMeshAttachment mesh = attachmentLoader.newSkinnedMeshAttachment(skin, name, path); if (mesh == null) return null; + mesh.setPath(path); float[] uvs = map.require("uvs").asFloatArray(); short[] triangles = map.require("triangles").asShortArray(); @@ -240,6 +244,7 @@ public class SkeletonJson { } } mesh.setMesh(bones.toArray(), weights.toArray(), triangles, uvs); + mesh.updateUVs(); if (map.has("hull")) mesh.setHullLength(map.require("hull").asInt() * 2); if (map.has("edges")) mesh.setEdges(map.require("edges").asIntArray()); diff --git a/spine-libgdx/src/com/esotericsoftware/spine/attachments/AtlasAttachmentLoader.java b/spine-libgdx/src/com/esotericsoftware/spine/attachments/AtlasAttachmentLoader.java index 642be8428..ca32cad23 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/attachments/AtlasAttachmentLoader.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/attachments/AtlasAttachmentLoader.java @@ -48,7 +48,6 @@ public class AtlasAttachmentLoader implements AttachmentLoader { if (region == null) throw new RuntimeException("Region not found in atlas: " + path + " (region attachment: " + name + ")"); RegionAttachment attachment = new RegionAttachment(name); - attachment.setPath(path); attachment.setRegion(region); return attachment; } @@ -57,7 +56,6 @@ public class AtlasAttachmentLoader implements AttachmentLoader { AtlasRegion region = atlas.findRegion(path); if (region == null) throw new RuntimeException("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); MeshAttachment attachment = new MeshAttachment(name); - attachment.setPath(path); attachment.setRegion(region); return attachment; } @@ -67,7 +65,6 @@ public class AtlasAttachmentLoader implements AttachmentLoader { if (region == null) throw new RuntimeException("Region not found in atlas: " + path + " (skinned mesh attachment: " + name + ")"); SkinnedMeshAttachment attachment = new SkinnedMeshAttachment(name); - attachment.setPath(path); attachment.setRegion(region); return attachment; } diff --git a/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java b/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java index 25bb162e9..94e59ab3f 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java @@ -44,7 +44,7 @@ import com.badlogic.gdx.utils.NumberUtils; public class MeshAttachment extends Attachment { private TextureRegion region; private String path; - private float[] vertices; + private float[] vertices, regionUVs; private short[] triangles; private float[] worldVertices; private final Color color = new Color(1, 1, 1, 1); @@ -68,13 +68,16 @@ public class MeshAttachment extends Attachment { return region; } - public void setMesh (float[] vertices, short[] triangles, float[] uvs) { + public void setMesh (float[] vertices, short[] triangles, float[] regionUVs) { this.vertices = vertices; this.triangles = triangles; + this.regionUVs = regionUVs; int worldVerticesLength = vertices.length / 2 * 5; if (worldVertices == null || worldVertices.length != worldVerticesLength) worldVertices = new float[worldVerticesLength]; + } + public void updateUVs () { float u, v, width, height; if (region == null) { u = v = 0; @@ -85,15 +88,16 @@ public class MeshAttachment extends Attachment { width = region.getU2() - u; height = region.getV2() - v; } + float[] regionUVs = this.regionUVs; if (region instanceof AtlasRegion && ((AtlasRegion)region).rotate) { for (int i = 0, w = 3, n = vertices.length; i < n; i += 2, w += 5) { - worldVertices[w] = u + uvs[i + 1] * width; - worldVertices[w + 1] = v + height - uvs[i] * height; + worldVertices[w] = u + regionUVs[i + 1] * width; + worldVertices[w + 1] = v + height - regionUVs[i] * height; } } else { for (int i = 0, w = 3, n = vertices.length; i < n; i += 2, w += 5) { - worldVertices[w] = u + uvs[i] * width; - worldVertices[w + 1] = v + uvs[i + 1] * height; + worldVertices[w] = u + regionUVs[i] * width; + worldVertices[w + 1] = v + regionUVs[i + 1] * height; } } } diff --git a/spine-libgdx/src/com/esotericsoftware/spine/attachments/SkinnedMeshAttachment.java b/spine-libgdx/src/com/esotericsoftware/spine/attachments/SkinnedMeshAttachment.java index a8ab4500e..0aa89dbc9 100644 --- a/spine-libgdx/src/com/esotericsoftware/spine/attachments/SkinnedMeshAttachment.java +++ b/spine-libgdx/src/com/esotericsoftware/spine/attachments/SkinnedMeshAttachment.java @@ -45,7 +45,7 @@ public class SkinnedMeshAttachment extends Attachment { private TextureRegion region; private String path; private int[] bones; - private float[] weights; + private float[] weights, regionUVs; private short[] triangles; private float[] worldVertices; private final Color color = new Color(1, 1, 1, 1); @@ -73,36 +73,40 @@ public class SkinnedMeshAttachment extends Attachment { * boneIndex, ... * @param weights For each bone affecting the vertex, the vertex position in the bone's coordinate system and the weight for * the bone's influence. Ie: x, y, weight, ... - * @param uvs For each vertex, a texure coordinate pair. Ie: u, v, ... + * @param regionUVs For each vertex, a texure coordinate pair. Ie: u, v, ... * @param triangles Vertex number triplets which describe the mesh's triangulation. */ - public void setMesh (int[] bones, float[] weights, short[] triangles, float[] uvs) { + public void setMesh (int[] bones, float[] weights, short[] triangles, float[] regionUVs) { this.bones = bones; this.weights = weights; this.triangles = triangles; + this.regionUVs = regionUVs; - int uvsLength = uvs.length; + int uvsLength = regionUVs.length; int worldVerticesLength = uvsLength / 2 * 5; if (worldVertices == null || worldVertices.length != worldVerticesLength) worldVertices = new float[worldVerticesLength]; + } - float u, v, w, h; + public void updateUVs () { + float u, v, width, height; if (region == null) { u = v = 0; - w = h = 1; + width = height = 1; } else { u = region.getU(); v = region.getV(); - w = region.getU2() - u; - h = region.getV2() - v; + width = region.getU2() - u; + height = region.getV2() - v; } + float[] regionUVs = this.regionUVs; if (region instanceof AtlasRegion && ((AtlasRegion)region).rotate) { - for (int i = 0, ii = 3; i < uvsLength; i += 2, ii += 5) { - worldVertices[ii] = u + uvs[i + 1] * w; - worldVertices[ii + 1] = v + h - uvs[i] * h; + for (int i = 0, w = 3, n = regionUVs.length; i < n; i += 2, w += 5) { + worldVertices[w] = u + regionUVs[i + 1] * width; + worldVertices[w + 1] = v + height - regionUVs[i] * height; } } else { - for (int i = 0, ii = 3; i < uvsLength; i += 2, ii += 5) { - worldVertices[ii] = u + uvs[i] * w; - worldVertices[ii + 1] = v + uvs[i + 1] * h; + for (int i = 0, w = 3, n = regionUVs.length; i < n; i += 2, w += 5) { + worldVertices[w] = u + regionUVs[i] * width; + worldVertices[w + 1] = v + regionUVs[i + 1] * height; } } }