diff --git a/spine-as3/spine-as3-example/lib/spine-as3.swc b/spine-as3/spine-as3-example/lib/spine-as3.swc index 404d9a6e4..6ae93d136 100644 Binary files a/spine-as3/spine-as3-example/lib/spine-as3.swc and b/spine-as3/spine-as3-example/lib/spine-as3.swc differ diff --git a/spine-as3/spine-as3/src/spine/SkeletonJson.as b/spine-as3/spine-as3/src/spine/SkeletonJson.as index 00d671100..108df5a94 100644 --- a/spine-as3/spine-as3/src/spine/SkeletonJson.as +++ b/spine-as3/spine-as3/src/spine/SkeletonJson.as @@ -238,7 +238,7 @@ package spine { for (var attachmentName : String in slotEntry) { var attachment : Attachment = readAttachment(slotEntry[attachmentName], skin, slotIndex, attachmentName, skeletonData); if (attachment != null) - skin.addAttachment(slotIndex, attachmentName, attachment); + skin.setAttachment(slotIndex, attachmentName, attachment); } } skeletonData.skins[skeletonData.skins.length] = skin; diff --git a/spine-as3/spine-as3/src/spine/Skin.as b/spine-as3/spine-as3/src/spine/Skin.as index 82e028ba8..ac6db68ec 100644 --- a/spine-as3/spine-as3/src/spine/Skin.as +++ b/spine-as3/spine-as3/src/spine/Skin.as @@ -28,6 +28,7 @@ *****************************************************************************/ package spine { + import spine.attachments.MeshAttachment; import flash.utils.Dictionary; import spine.attachments.Attachment; @@ -36,6 +37,8 @@ package spine { public class Skin { internal var _name : String; private var _attachments : Vector. = new Vector.(); + private var _bones: Vector. = new Vector.(); + private var _constraints: Vector. = new Vector.(); public function Skin(name : String) { if (name == null) throw new ArgumentError("name cannot be null."); @@ -44,21 +47,149 @@ package spine { public function setAttachment(slotIndex : int, name : String, attachment : Attachment) : void { if (attachment == null) throw new ArgumentError("attachment cannot be null."); - if (slotIndex >= attachments.length) attachments.length = slotIndex + 1; - if (!attachments[slotIndex]) attachments[slotIndex] = new Dictionary(); - attachments[slotIndex][name] = attachment; + if (slotIndex >= _attachments.length) _attachments.length = slotIndex + 1; + if (!_attachments[slotIndex]) _attachments[slotIndex] = new Dictionary(); + _attachments[slotIndex][name] = attachment; } + + public function addSkin (skin: Skin) : void { + var i : Number = 0, j : Number = 0; + var contained : Boolean = false; + + for(i = 0; i < skin._bones.length; i++) { + var bone : BoneData = skin._bones[i]; + contained = false; + for (j = 0; j < _bones.length; j++) { + if (_bones[j] == bone) { + contained = true; + break; + } + } + if (!contained) _bones.push(bone); + } - /** @return May be null. */ + for(i = 0; i < skin._constraints.length; i++) { + var constraint : Constraint = skin._constraints[i]; + contained = false; + for (j = 0; j < this._constraints.length; j++) { + if (_constraints[j] == constraint) { + contained = true; + break; + } + } + if (!contained) _constraints.push(constraint); + } + + var attachments : Vector. = skin.getAttachments(); + for (i = 0; i < attachments.length; i++) { + var attachment : SkinEntry = attachments[i]; + setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + } + + public function copySkin (skin: Skin) : void { + var i : Number = 0, j : Number = 0; + var contained : Boolean = false; + var attachment : SkinEntry; + + for(i = 0; i < skin._bones.length; i++) { + var bone : BoneData = skin._bones[i]; + contained = false; + for (j = 0; j < _bones.length; j++) { + if (_bones[j] == bone) { + contained = true; + break; + } + } + if (!contained) _bones.push(bone); + } + + for(i = 0; i < skin._constraints.length; i++) { + var constraint : Constraint = skin._constraints[i]; + contained = false; + for (j = 0; j < this._constraints.length; j++) { + if (_constraints[j] == constraint) { + contained = true; + break; + } + } + if (!contained) _constraints.push(constraint); + } + + var attachments : Vector. = skin.getAttachments(); + for (i = 0; i < attachments.length; i++) { + attachment = attachments[i]; + attachment.attachment = attachment.attachment.copy(); + setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + + attachments = this.getAttachments(); + for (i = 0; i < attachments.length; i++) { + attachment = attachments[i]; + if (attachment.attachment instanceof MeshAttachment) { + var mesh : MeshAttachment = attachment.attachment as MeshAttachment; + if (mesh.parentMesh) { + mesh.parentMesh = this.getAttachment(attachment.slotIndex, mesh.parentMesh.name) as MeshAttachment; + mesh.updateUVs(); + } + } + } + } + public function getAttachment(slotIndex : int, name : String) : Attachment { - if (slotIndex >= attachments.length) return null; - var dictionary : Dictionary = attachments[slotIndex]; + if (slotIndex >= _attachments.length) return null; + var dictionary : Dictionary = _attachments[slotIndex]; return dictionary ? dictionary[name] : null; } - + + public function removeAttachment (slotIndex : Number, name : String) : void { + var dictionary : Dictionary = _attachments[slotIndex]; + if (dictionary) dictionary[name] = null; + } + + public function getAttachments() : Vector. { + var entries : Vector. = new Vector.(); + for (var slotIndex : int = 0; slotIndex < _attachments.length; slotIndex++) { + var attachments : Dictionary = _attachments[slotIndex]; + if (attachments) { + for (var name : String in attachments) { + var attachment : Attachment = attachments[name]; + if (attachment) entries.push(new SkinEntry(slotIndex, name, attachment)); + } + } + } + return entries; + } + + public function getAttachmentsForSlot(slotIndex: int) : Vector. { + var entries : Vector. = new Vector.(); + var attachments : Dictionary = _attachments[slotIndex]; + if (attachments) { + for (var name : String in attachments) { + var attachment : Attachment = attachments[name]; + if (attachment) entries.push(new SkinEntry(slotIndex, name, attachment)); + } + } + return entries; + } + + public function clear () : void { + _attachments.length = 0; + _bones.length = 0; + _constraints.length = 0; + } + public function get attachments() : Vector. { return _attachments; } + + public function get bones() : Vector. { + return _bones; + } + + public function get constraints() : Vector. { + return _constraints; + } public function get name() : String { return _name; @@ -73,8 +204,8 @@ package spine { var slotIndex : int = 0; for each (var slot : Slot in skeleton.slots) { var slotAttachment : Attachment = slot.attachment; - if (slotAttachment && slotIndex < oldSkin.attachments.length) { - var dictionary : Dictionary = oldSkin.attachments[slotIndex]; + if (slotAttachment && slotIndex < oldSkin._attachments.length) { + var dictionary : Dictionary = oldSkin._attachments[slotIndex]; for (var name : String in dictionary) { var skinAttachment : Attachment = dictionary[name]; if (slotAttachment == skinAttachment) { @@ -87,5 +218,5 @@ package spine { slotIndex++; } } - } + } } diff --git a/spine-as3/spine-as3/src/spine/SkinEntry.as b/spine-as3/spine-as3/src/spine/SkinEntry.as new file mode 100644 index 000000000..17c64b987 --- /dev/null +++ b/spine-as3/spine-as3/src/spine/SkinEntry.as @@ -0,0 +1,15 @@ +package spine { + import spine.attachments.Attachment; + + public class SkinEntry { + public var slotIndex : int; + public var name : String; + public var attachment : Attachment; + + public function SkinEntry(slotIndex : int, name: String, attachment: Attachment) { + this.slotIndex = slotIndex; + this.name = name; + this.attachment = attachment; + } + } +} \ No newline at end of file diff --git a/spine-as3/spine-as3/src/spine/attachments/Attachment.as b/spine-as3/spine-as3/src/spine/attachments/Attachment.as index ccf4e64a4..7ebe78d13 100644 --- a/spine-as3/spine-as3/src/spine/attachments/Attachment.as +++ b/spine-as3/spine-as3/src/spine/attachments/Attachment.as @@ -28,6 +28,7 @@ *****************************************************************************/ package spine.attachments { + import flash.errors.IllegalOperationError; public class Attachment { internal var _name : String; @@ -44,5 +45,9 @@ package spine.attachments { public function toString() : String { return name; } - } + + public function copy() : Attachment { + throw new IllegalOperationError("Not implemented"); + } + } } diff --git a/spine-as3/spine-as3/src/spine/attachments/BoundingBoxAttachment.as b/spine-as3/spine-as3/src/spine/attachments/BoundingBoxAttachment.as index e4a561990..0425d02c6 100644 --- a/spine-as3/spine-as3/src/spine/attachments/BoundingBoxAttachment.as +++ b/spine-as3/spine-as3/src/spine/attachments/BoundingBoxAttachment.as @@ -32,5 +32,11 @@ package spine.attachments { public function BoundingBoxAttachment(name : String) { super(name); } + + override public function copy (): Attachment { + var copy : BoundingBoxAttachment = new BoundingBoxAttachment(name); + copyTo(copy); + return copy; + } } } diff --git a/spine-as3/spine-as3/src/spine/attachments/ClippingAttachment.as b/spine-as3/spine-as3/src/spine/attachments/ClippingAttachment.as index 3fd423a5f..d9e448000 100644 --- a/spine-as3/spine-as3/src/spine/attachments/ClippingAttachment.as +++ b/spine-as3/spine-as3/src/spine/attachments/ClippingAttachment.as @@ -38,5 +38,13 @@ package spine.attachments { public function ClippingAttachment(name : String) { super(name); } + + override public function copy (): Attachment { + var copy : ClippingAttachment = new ClippingAttachment(name); + copyTo(copy); + copy.endSlot = endSlot; + copy.color.setFromColor(color); + return copy; + } } } diff --git a/spine-as3/spine-as3/src/spine/attachments/MeshAttachment.as b/spine-as3/spine-as3/src/spine/attachments/MeshAttachment.as index 792f70788..1f06411d8 100644 --- a/spine-as3/spine-as3/src/spine/attachments/MeshAttachment.as +++ b/spine-as3/spine-as3/src/spine/attachments/MeshAttachment.as @@ -121,34 +121,6 @@ package spine.attachments { } } } - - /*var i : int, n : int = regionUVs.length; - var u: Number, v: Number, width: Number, height: Number; - var textureWidth: Number, textureHeight: Number; - if (!uvs || uvs.length != n) uvs = new Vector.(n, true); - if (regionRotate) { - textureHeight = regionWidth / (regionV2 - regionV); - textureWidth = regionHeight / (regionU2 - regionU); - u = regionU - (regionOriginalHeight - regionOffsetY - regionHeight) / textureWidth; - v = regionV - (regionOriginalWidth - regionOffsetX - regionWidth) / textureHeight; - width = regionOriginalHeight / textureWidth; - height = regionOriginalWidth / textureHeight; - for (i = 0; i < n; i += 2) { - uvs[i] = u + regionUVs[int(i + 1)] * width; - uvs[int(i + 1)] = v + height - regionUVs[i] * height; - } - } else { - textureWidth = regionWidth / (regionU2 - regionU); - textureHeight = regionHeight / (regionV2 - regionV); - u = regionU - regionOffsetX / textureWidth; - v = regionV - (regionOriginalHeight - regionOffsetY - regionHeight) / textureHeight; - width = regionOriginalWidth / textureWidth; - height = regionOriginalHeight / textureHeight; - for (i = 0; i < n; i += 2) { - uvs[i] = u + regionUVs[i] * width; - uvs[int(i + 1)] = v + regionUVs[int(i + 1)] * height; - } - }*/ } override public function applyDeform(sourceAttachment : VertexAttachment) : Boolean { @@ -172,6 +144,46 @@ package spine.attachments { width = parentMesh.width; height = parentMesh.height; } + }; + + override public function copy (): Attachment { + var copy : MeshAttachment = new MeshAttachment(name); + copy.rendererObject = rendererObject; + copy.regionU = regionU; + copy.regionV = regionV; + copy.regionU2 = regionU2; + copy.regionV2 = regionV2; + copy.regionRotate = regionRotate; + copy.regionDegrees = regionDegrees; + copy.regionOffsetX = regionOffsetX; + copy.regionOffsetY = regionOffsetY; + copy.regionWidth = regionWidth; + copy.regionHeight = regionHeight; + copy.regionOriginalWidth = regionOriginalWidth; + copy.regionOriginalHeight = regionOriginalHeight; + copy.path = path; + + if (parentMesh == null) { + this.copyTo(copy); + copy.regionUVs = regionUVs.concat(); + copy.uvs = uvs.concat(); + copy.triangles = triangles.concat(); + copy.color.setFromColor(color); + copy.hullLength = hullLength; + + copy.inheritDeform = inheritDeform; + + // Nonessential. + if (edges != null) + copy.edges = edges.concat(); + copy.width = width; + copy.height = height; + } else { + copy.parentMesh = parentMesh; + copy.updateUVs(); + } + + return copy; } } } diff --git a/spine-as3/spine-as3/src/spine/attachments/PathAttachment.as b/spine-as3/spine-as3/src/spine/attachments/PathAttachment.as index 2ae7437d8..834bd5896 100644 --- a/spine-as3/spine-as3/src/spine/attachments/PathAttachment.as +++ b/spine-as3/spine-as3/src/spine/attachments/PathAttachment.as @@ -35,5 +35,14 @@ package spine.attachments { public function PathAttachment(name : String) { super(name); } + + override public function copy (): Attachment { + var copy : PathAttachment = new PathAttachment(name); + copyTo(copy); + copy.lengths = lengths.concat(); + copy.closed = closed; + copy.constantSpeed = constantSpeed; + return copy; + } } } diff --git a/spine-as3/spine-as3/src/spine/attachments/PointAttachment.as b/spine-as3/spine-as3/src/spine/attachments/PointAttachment.as index 9e4065b50..413696f33 100644 --- a/spine-as3/spine-as3/src/spine/attachments/PointAttachment.as +++ b/spine-as3/spine-as3/src/spine/attachments/PointAttachment.as @@ -52,5 +52,14 @@ package spine.attachments { var y : Number = cos * bone.c + sin * bone.d; return Math.atan2(y, x) * MathUtils.radDeg; } + + override public function copy (): Attachment { + var copy : PointAttachment = new PointAttachment(name); + copy.x = x; + copy.y = y; + copy.rotation = rotation; + copy.color.setFromColor(color); + return copy; + } } } diff --git a/spine-as3/spine-as3/src/spine/attachments/RegionAttachment.as b/spine-as3/spine-as3/src/spine/attachments/RegionAttachment.as index e74b104f5..90f1b63da 100644 --- a/spine-as3/spine-as3/src/spine/attachments/RegionAttachment.as +++ b/spine-as3/spine-as3/src/spine/attachments/RegionAttachment.as @@ -145,5 +145,28 @@ package spine.attachments { worldVertices[offset] = offsetX * a + offsetY * b + x; // ur worldVertices[offset + 1] = offsetX * c + offsetY * d + y; } + + override public function copy (): Attachment { + var copy : RegionAttachment = new RegionAttachment(name); + copy.regionWidth = regionWidth; + copy.regionHeight = regionHeight; + copy.regionOffsetX = regionOffsetX; + copy.regionOffsetY = regionOffsetY; + copy.regionOriginalWidth = regionOriginalWidth; + copy.regionOriginalHeight = regionOriginalHeight; + copy.rendererObject = rendererObject; + copy.path = path; + copy.x = x; + copy.y = y; + copy.scaleX = scaleX; + copy.scaleY = scaleY; + copy.rotation = rotation; + copy.width = width; + copy.height = height; + copy.uvs = uvs.concat(); + copy.offset = offset.concat(); + copy.color.setFromColor(color); + return copy; + } } } diff --git a/spine-as3/spine-as3/src/spine/attachments/VertexAttachment.as b/spine-as3/spine-as3/src/spine/attachments/VertexAttachment.as index 68f289704..cfd24be8a 100644 --- a/spine-as3/spine-as3/src/spine/attachments/VertexAttachment.as +++ b/spine-as3/spine-as3/src/spine/attachments/VertexAttachment.as @@ -129,5 +129,19 @@ package spine.attachments { public function applyDeform(sourceAttachment : VertexAttachment) : Boolean { return this == sourceAttachment; } + + public function copyTo(attachment : VertexAttachment) : void { + if (bones != null) { + attachment.bones = bones.concat(); + } else + attachment.bones = null; + + if (this.vertices != null) { + attachment.vertices = vertices.concat(); + } else + attachment.vertices = null; + + attachment.worldVerticesLength = worldVerticesLength; + } } } diff --git a/spine-starling/spine-starling-example/lib/spine-as3.swc b/spine-starling/spine-starling-example/lib/spine-as3.swc index 62392cd02..6ae93d136 100644 Binary files a/spine-starling/spine-starling-example/lib/spine-as3.swc and b/spine-starling/spine-starling-example/lib/spine-as3.swc differ diff --git a/spine-starling/spine-starling-example/src/spine/examples/OwlExample.as b/spine-starling/spine-starling-example/src/spine/examples/OwlExample.as index 33a047e78..a4baa3f9c 100644 --- a/spine-starling/spine-starling-example/src/spine/examples/OwlExample.as +++ b/spine-starling/spine-starling-example/src/spine/examples/OwlExample.as @@ -28,6 +28,7 @@ *****************************************************************************/ package spine.examples { + import spine.Skin; import spine.animation.MixBlend; import spine.animation.TrackEntry; import starling.display.DisplayObjectContainer; @@ -88,6 +89,11 @@ package spine.examples { skeleton.state.update(0.25); skeleton.state.apply(skeleton.skeleton); skeleton.skeleton.updateWorldTransform(); + + var skin : Skin = new Skin("test"); + skin.addSkin(skeletonData.findSkin("default")); + skeleton.skeleton.skin = skin; + skeleton.skeleton.setToSetupPose(); addChild(skeleton); Starling.juggler.add(skeleton); diff --git a/spine-starling/spine-starling/lib/spine-as3.swc b/spine-starling/spine-starling/lib/spine-as3.swc index 62392cd02..6ae93d136 100644 Binary files a/spine-starling/spine-starling/lib/spine-as3.swc and b/spine-starling/spine-starling/lib/spine-as3.swc differ