Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spine {
|
||||
|
||||
/// <summary>
|
||||
/// An <see cref="AttachmentLoader"/> that configures attachments using texture regions from an <see cref="Atlas"/>.
|
||||
/// See <a href='http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data'>Loading Skeleton Data</a> in the Spine Runtimes Guide.
|
||||
/// </summary>
|
||||
public class AtlasAttachmentLoader : AttachmentLoader {
|
||||
private Atlas[] atlasArray;
|
||||
/// <summary>If true, <see cref="FindRegion(string, string)"/> may return null. If false, an error is raised if the texture region is not
|
||||
/// found. Default is false.</summary>
|
||||
public bool allowMissingRegions;
|
||||
|
||||
public AtlasAttachmentLoader (params Atlas[] atlasArray)
|
||||
: this(false, atlasArray) {
|
||||
}
|
||||
|
||||
public AtlasAttachmentLoader (bool allowMissingRegions, params Atlas[] atlasArray) {
|
||||
if (atlasArray == null) throw new ArgumentNullException("atlas", "atlas array cannot be null.");
|
||||
this.atlasArray = atlasArray;
|
||||
this.allowMissingRegions = allowMissingRegions;
|
||||
}
|
||||
|
||||
/// <summary>Sets each <see cref="Sequence.Regions"/> by calling <see cref="FindRegion(string, string)"/> for each texture region using
|
||||
/// <see cref="Sequence.GetPath(string, int)"/>.</summary>
|
||||
protected void FindRegions (string name, string basePath, Sequence sequence) {
|
||||
TextureRegion[] regions = sequence.Regions;
|
||||
for (int i = 0, n = regions.Length; i < n; i++) {
|
||||
regions[i] = FindRegion(name, sequence.GetPath(basePath, i));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Looks for the region with the specified path. If not found and <see cref="allowMissingRegions"/> is false, an error is
|
||||
/// raised.</summary>
|
||||
protected AtlasRegion FindRegion (string name, string path) {
|
||||
for (int i = 0; i < atlasArray.Length; i++) {
|
||||
AtlasRegion region = atlasArray[i].FindRegion(path);
|
||||
if (region != null)
|
||||
return region;
|
||||
}
|
||||
if (!allowMissingRegions)
|
||||
throw new ArgumentException(string.Format("Region not found in atlas: {0} (attachment: {1})", path, name));
|
||||
return null;
|
||||
}
|
||||
|
||||
public RegionAttachment NewRegionAttachment (Skin skin, string placeholder, string name, string path, Sequence sequence) {
|
||||
FindRegions(name, path, sequence);
|
||||
return new RegionAttachment(name, sequence);
|
||||
}
|
||||
|
||||
public MeshAttachment NewMeshAttachment (Skin skin, string placeholder, string name, string path, Sequence sequence) {
|
||||
FindRegions(name, path, sequence);
|
||||
return new MeshAttachment(name, sequence);
|
||||
}
|
||||
|
||||
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string placeholder, string name) {
|
||||
return new BoundingBoxAttachment(name);
|
||||
}
|
||||
|
||||
public PathAttachment NewPathAttachment (Skin skin, string placeholder, string name) {
|
||||
return new PathAttachment(name);
|
||||
}
|
||||
|
||||
public PointAttachment NewPointAttachment (Skin skin, string placeholder, string name) {
|
||||
return new PointAttachment(name);
|
||||
}
|
||||
|
||||
public ClippingAttachment NewClippingAttachment (Skin skin, string placeholder, string name) {
|
||||
return new ClippingAttachment(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e6ff30e27c28344bad3e67d308c94cd
|
||||
timeCreated: 1466772712
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spine {
|
||||
|
||||
/// <summary>The base class for all attachments. Multiple <see cref="Skeleton"/> instances, slots, or skins can use the same
|
||||
/// attachments.</summary>
|
||||
abstract public class Attachment {
|
||||
static private readonly int[] Empty = new int[0];
|
||||
|
||||
internal Attachment timelineAttachment;
|
||||
internal int[] timelineSlots = Empty;
|
||||
|
||||
/// <summary>The attachment's name.</summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>Timelines for the timeline attachment are also applied to this attachment.
|
||||
/// May be null if no attachment-specific timelines should be applied.</summary>
|
||||
public Attachment TimelineAttachment { get { return timelineAttachment; } set { timelineAttachment = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Slots that can have attachments whose <see cref="timelineAttachment"/> is this attachment.
|
||||
/// </summary>
|
||||
public int[] TimelineSlots { get { return timelineSlots; } set { timelineSlots = value; } }
|
||||
|
||||
protected Attachment (string name) {
|
||||
if (name == null) throw new ArgumentNullException("name", "name cannot be null");
|
||||
this.Name = name;
|
||||
timelineAttachment = this;
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor.</summary>
|
||||
protected Attachment (Attachment other) {
|
||||
Name = other.Name;
|
||||
timelineAttachment = other.timelineAttachment;
|
||||
timelineSlots = other.timelineSlots;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the <c>slotIndex</c> or any <see cref="timelineSlots"/> have an attachment whose <see cref="timelineAttachment"/> is
|
||||
/// this attachment.
|
||||
/// </summary>
|
||||
/// <param name="slots">The <see cref="Skeleton.Slots"/>.</param>
|
||||
/// <param name="slotIndex">The timeline's primary slot index.</param>
|
||||
public bool IsTimelineActive (Slot[] slots, int slotIndex, bool appliedPose) {
|
||||
Slot slot = slots[slotIndex];
|
||||
if (slot.Bone.Active) {
|
||||
Attachment other = (appliedPose ? slot.AppliedPose : slot.Pose).Attachment;
|
||||
if (other != null && other.timelineAttachment == this) return true;
|
||||
}
|
||||
for (int i = 0, n = timelineSlots.Length; i < n; i++) {
|
||||
slot = slots[timelineSlots[i]];
|
||||
if (!slot.Bone.Active) continue;
|
||||
Attachment other = (appliedPose ? slot.AppliedPose : slot.Pose).Attachment;
|
||||
if (other != null && other.timelineAttachment == this) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
override public string ToString () {
|
||||
return Name;
|
||||
}
|
||||
|
||||
/// <summary>Returns a copy of the attachment.</summary>
|
||||
public abstract Attachment Copy ();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05b56321b2ddd8145a888746bc6ab917
|
||||
timeCreated: 1456265153
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
namespace Spine {
|
||||
public interface AttachmentLoader {
|
||||
/// <return>May be null to not load any attachment.</return>
|
||||
RegionAttachment NewRegionAttachment (Skin skin, string placeholder, string name, string path, Sequence sequence);
|
||||
|
||||
/// <return>May be null to not load any attachment.</return>
|
||||
MeshAttachment NewMeshAttachment (Skin skin, string placeholder, string name, string path, Sequence sequence);
|
||||
|
||||
/// <return>May be null to not load any attachment.</return>
|
||||
BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, string placeholder, string name);
|
||||
|
||||
/// <returns>May be null to not load any attachment</returns>
|
||||
PathAttachment NewPathAttachment (Skin skin, string placeholder, string name);
|
||||
|
||||
PointAttachment NewPointAttachment (Skin skin, string placeholder, string name);
|
||||
|
||||
ClippingAttachment NewClippingAttachment (Skin skin, string placeholder, string name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95466a4f5a30dca4aa69e8ee7df8ae85
|
||||
timeCreated: 1466772712
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
namespace Spine {
|
||||
public enum AttachmentType {
|
||||
Region, Boundingbox, Mesh, Linkedmesh, Path, Point, Clipping, Sequence
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6b1941960a9f6f47be3e865554d8695
|
||||
timeCreated: 1466772712
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spine {
|
||||
/// <summary>Attachment that has a polygon for bounds checking.</summary>
|
||||
public class BoundingBoxAttachment : VertexAttachment {
|
||||
public BoundingBoxAttachment (string name)
|
||||
: base(name) {
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor.</summary>
|
||||
protected BoundingBoxAttachment (BoundingBoxAttachment other)
|
||||
: base(other) {
|
||||
}
|
||||
|
||||
public override Attachment Copy () {
|
||||
return new BoundingBoxAttachment(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd8ad8fc0f5bce448ba26d096ab32e85
|
||||
timeCreated: 1466772712
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,69 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spine {
|
||||
public class ClippingAttachment : VertexAttachment {
|
||||
internal SlotData endSlot;
|
||||
internal bool convex, inverse;
|
||||
|
||||
/// <summary>Clipping is performed between the clipping attachment's slot and the end slot. If null, clipping is done until the end of
|
||||
/// the skeleton's rendering.</summary>
|
||||
public SlotData EndSlot { get { return endSlot; } set { endSlot = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// When true the clipping polygon is treated as convex for more efficient clipping. If the polygon deforms to concave then the
|
||||
/// convex hull is used.When false the clipping polygon can be concave and if so has an additional CPU cost.Inverse clipping
|
||||
/// always uses convex.
|
||||
/// </summary>
|
||||
public bool Convex { get { return convex; } set { convex = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// When false, everything inside the clipping polygon is visible. When true, everything outside the clipping polygon is
|
||||
/// visible and clipping is convex.
|
||||
/// </summary>
|
||||
public bool Inverse { get { return inverse; } set { inverse = value; } }
|
||||
|
||||
public ClippingAttachment (string name) : base(name) {
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor.</summary>
|
||||
protected ClippingAttachment (ClippingAttachment other)
|
||||
: base(other) {
|
||||
endSlot = other.endSlot;
|
||||
convex = other.convex;
|
||||
inverse = other.inverse;
|
||||
}
|
||||
|
||||
public override Attachment Copy () {
|
||||
return new ClippingAttachment(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3380954b107f38b4c85a4cdfeceace42
|
||||
timeCreated: 1492744746
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#if (UNITY_5 || UNITY_5_3_OR_NEWER || UNITY_WSA || UNITY_WP8 || UNITY_WP8_1)
|
||||
#define IS_UNITY
|
||||
#endif
|
||||
|
||||
namespace Spine {
|
||||
#if IS_UNITY
|
||||
using Color32F = UnityEngine.Color;
|
||||
#endif
|
||||
|
||||
/// <summary>Interface for an attachment that gets 1 or more texture regions from a <see cref="Sequence"/>.</summary>
|
||||
public interface IHasSequence {
|
||||
/// <summary>The base path for the attachment's texture region.</summary>
|
||||
string Path { get; set; }
|
||||
/// <summary>The color the attachment is tinted, to be combined with <see cref="SlotPose.Color"/>.</summary>
|
||||
Color32F GetColor ();
|
||||
void SetColor (Color32F color);
|
||||
void SetColor (float r, float g, float b, float a);
|
||||
/// <summary>The sequence that provides texture regions, UVs, and vertex offsets for rendering this attachment.</summary>
|
||||
Sequence Sequence { get; }
|
||||
void UpdateSequence ();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0e8b0a33cae75d498aa8c328787cafb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,236 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#if (UNITY_5 || UNITY_5_3_OR_NEWER || UNITY_WSA || UNITY_WP8 || UNITY_WP8_1)
|
||||
#define IS_UNITY
|
||||
#endif
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spine {
|
||||
#if IS_UNITY
|
||||
using Color32F = UnityEngine.Color;
|
||||
#endif
|
||||
|
||||
/// <summary>Attachment that displays a texture region using a mesh.</summary>
|
||||
public class MeshAttachment : VertexAttachment, IHasSequence {
|
||||
internal readonly Sequence sequence;
|
||||
internal float[] regionUVs;
|
||||
internal int[] triangles;
|
||||
internal int hullLength;
|
||||
internal string path;
|
||||
// Color is a struct, set to protected to prevent
|
||||
// Color color = slot.color; color.a = 0.5;
|
||||
// modifying just a copy of the struct instead of the original
|
||||
// object as in reference implementation.
|
||||
protected Color32F color = new Color32F(1, 1, 1, 1);
|
||||
private MeshAttachment sourceMesh;
|
||||
|
||||
public int HullLength { get { return hullLength; } set { hullLength = value; } }
|
||||
|
||||
/// <summary>The UV pair for each vertex, normalized within the texture region.</summary>
|
||||
public float[] RegionUVs { get { return regionUVs; } set { regionUVs = value; } }
|
||||
/// <summary>Triplets of vertex indices which describe the mesh's triangulation.</summary>
|
||||
public int[] Triangles { get { return triangles; } set { triangles = value; } }
|
||||
|
||||
public Color32F GetColor () {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void SetColor (Color32F color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public void SetColor (float r, float g, float b, float a) {
|
||||
color = new Color32F(r, g, b, a);
|
||||
}
|
||||
|
||||
public string Path { get { return path; } set { path = value; } }
|
||||
public Sequence Sequence { get { return sequence; } }
|
||||
|
||||
/// <summary>
|
||||
/// The source mesh if this is a linked mesh, else null. A linked mesh shares the
|
||||
/// <see cref="VertexAttachment.Bones">Bones</see>, <see cref="VertexAttachment.Vertices">Vertices</see>,
|
||||
/// <see cref="RegionUVs"/>, <see cref="Triangles"/>, <see cref="HullLength"/>, <see cref="Edges"/>,
|
||||
/// <see cref="Width"/>, <see cref="Height"/> with the
|
||||
/// source mesh, but may have a different <see cref="name"/> or <see cref="path"/>, and therefore a different texture region.
|
||||
/// </summary>
|
||||
public MeshAttachment SourceMesh {
|
||||
get { return sourceMesh; }
|
||||
set {
|
||||
sourceMesh = value;
|
||||
if (value != null) {
|
||||
bones = value.bones;
|
||||
vertices = value.vertices;
|
||||
worldVerticesLength = value.worldVerticesLength;
|
||||
regionUVs = value.regionUVs;
|
||||
triangles = value.triangles;
|
||||
HullLength = value.HullLength;
|
||||
Edges = value.Edges;
|
||||
Width = value.Width;
|
||||
Height = value.Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nonessential.
|
||||
/// <summary>
|
||||
/// Vertex index pairs describing edges for controlling triangulation, or null if nonessential data was not exported. Mesh
|
||||
/// triangles do not cross edges. Triangulation is not performed at runtime.
|
||||
/// </summary>
|
||||
public int[] Edges { get; set; }
|
||||
public float Width { get; set; }
|
||||
public float Height { get; set; }
|
||||
|
||||
public MeshAttachment (string name, Sequence sequence)
|
||||
: base(name) {
|
||||
if (sequence == null) throw new ArgumentException("sequence cannot be null.", "sequence");
|
||||
this.sequence = sequence;
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor. Use <see cref="NewLinkedMesh"/> if the other mesh is a linked mesh.</summary>
|
||||
protected MeshAttachment (MeshAttachment other)
|
||||
: base(other) {
|
||||
|
||||
if (sourceMesh != null) throw new ArgumentException("Use newLinkedMesh to copy a linked mesh.");
|
||||
|
||||
path = other.path;
|
||||
color = other.color;
|
||||
|
||||
regionUVs = new float[other.regionUVs.Length];
|
||||
Array.Copy(other.regionUVs, 0, regionUVs, 0, regionUVs.Length);
|
||||
|
||||
triangles = new int[other.triangles.Length];
|
||||
Array.Copy(other.triangles, 0, triangles, 0, triangles.Length);
|
||||
|
||||
hullLength = other.hullLength;
|
||||
sequence = new Sequence(other.sequence);
|
||||
|
||||
// Nonessential.
|
||||
if (other.Edges != null) {
|
||||
Edges = new int[other.Edges.Length];
|
||||
Array.Copy(other.Edges, 0, Edges, 0, Edges.Length);
|
||||
}
|
||||
Width = other.Width;
|
||||
Height = other.Height;
|
||||
}
|
||||
|
||||
public void UpdateSequence () {
|
||||
sequence.Update(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new mesh with the <see cref="SourceMesh"/> set to this mesh's source mesh, if any, else to this mesh.
|
||||
/// </summary>
|
||||
public MeshAttachment NewLinkedMesh () {
|
||||
var mesh = new MeshAttachment(Name, new Sequence(sequence));
|
||||
|
||||
mesh.timelineAttachment = timelineAttachment;
|
||||
mesh.path = path;
|
||||
mesh.color = color;
|
||||
mesh.SourceMesh = sourceMesh != null ? sourceMesh : this;
|
||||
mesh.UpdateSequence();
|
||||
return mesh;
|
||||
}
|
||||
|
||||
public override Attachment Copy () {
|
||||
return sourceMesh != null ? NewLinkedMesh() : new MeshAttachment(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes <see cref="Sequence.GetUVs(int)">UVs</see> for a mesh attachment.
|
||||
/// </summary>
|
||||
/// <param name="uvs">Output array for the computed UVs, same length as regionUVs.</param>
|
||||
internal static void ComputeUVs (TextureRegion region, float[] regionUVs, float[] uvs) {
|
||||
int n = uvs.Length;
|
||||
float u, v, width, height;
|
||||
AtlasRegion r = region as AtlasRegion;
|
||||
if (r != null) {
|
||||
u = r.u;
|
||||
v = r.v;
|
||||
float textureWidth = region.width / (region.u2 - region.u);
|
||||
float textureHeight = region.height / (region.v2 - region.v);
|
||||
switch (r.degrees) {
|
||||
case 90: {
|
||||
u -= (r.originalHeight - r.offsetY - r.packedWidth) / textureWidth;
|
||||
v -= (r.originalWidth - r.offsetX - r.packedHeight) / textureHeight;
|
||||
width = r.originalHeight / textureWidth;
|
||||
height = r.originalWidth / textureHeight;
|
||||
for (int i = 0; i < n; i += 2) {
|
||||
uvs[i] = u + regionUVs[i + 1] * width;
|
||||
uvs[i + 1] = v + (1 - regionUVs[i]) * height;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 180: {
|
||||
u -= (r.originalWidth - r.offsetX - r.packedWidth) / textureWidth;
|
||||
v -= r.offsetY / textureHeight;
|
||||
width = r.originalWidth / textureWidth;
|
||||
height = r.originalHeight / textureHeight;
|
||||
for (int i = 0; i < n; i += 2) {
|
||||
uvs[i] = u + (1 - regionUVs[i]) * width;
|
||||
uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 270: {
|
||||
u -= r.offsetY / textureWidth;
|
||||
v -= r.offsetX / textureHeight;
|
||||
width = r.originalHeight / textureWidth;
|
||||
height = r.originalWidth / textureHeight;
|
||||
for (int i = 0; i < n; i += 2) {
|
||||
uvs[i] = u + (1 - regionUVs[i + 1]) * width;
|
||||
uvs[i + 1] = v + regionUVs[i] * height;
|
||||
}
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
u -= r.offsetX / textureWidth;
|
||||
v -= (r.originalHeight - r.offsetY - r.packedHeight) / textureHeight;
|
||||
width = r.originalWidth / textureWidth;
|
||||
height = r.originalHeight / textureHeight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (region == null) {
|
||||
u = v = 0;
|
||||
width = height = 1;
|
||||
} else {
|
||||
u = region.u;
|
||||
v = region.v;
|
||||
width = region.u2 - u;
|
||||
height = region.v2 - v;
|
||||
}
|
||||
for (int i = 0; i < n; i += 2) {
|
||||
uvs[i] = u + regionUVs[i] * width;
|
||||
uvs[i + 1] = v + regionUVs[i + 1] * height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7f7514a003143844b6d01ecc93ed4d5
|
||||
timeCreated: 1466772712
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,65 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spine {
|
||||
public class PathAttachment : VertexAttachment {
|
||||
internal float[] lengths;
|
||||
internal bool closed, constantSpeed;
|
||||
|
||||
/// <summary>The length in the setup pose from the start of the path to the end of each curve.</summary>
|
||||
public float[] Lengths { get { return lengths; } set { lengths = value; } }
|
||||
/// <summary>If true, the start and end knots are connected.</summary>
|
||||
public bool Closed { get { return closed; } set { closed = value; } }
|
||||
/// <summary>If true, additional calculations are performed to make computing positions along the path more accurate so movement along
|
||||
/// the path has a constant speed.</summary>
|
||||
public bool ConstantSpeed { get { return constantSpeed; } set { constantSpeed = value; } }
|
||||
|
||||
public PathAttachment (String name)
|
||||
: base(name) {
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor.</summary>
|
||||
protected PathAttachment (PathAttachment other)
|
||||
: base(other) {
|
||||
|
||||
lengths = new float[other.lengths.Length];
|
||||
Array.Copy(other.lengths, 0, lengths, 0, lengths.Length);
|
||||
|
||||
closed = other.closed;
|
||||
constantSpeed = other.constantSpeed;
|
||||
}
|
||||
|
||||
public override Attachment Copy () {
|
||||
return new PathAttachment(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c77d9bf384a1e9f41966464e7e3b4870
|
||||
timeCreated: 1466772712
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spine {
|
||||
/// <summary>
|
||||
/// An attachment which is a single point and a rotation. This can be used to spawn projectiles, particles, etc. A bone can be
|
||||
/// used in similar ways, but a PointAttachment is slightly less expensive to compute and can be hidden, shown, and placed in a
|
||||
/// skin.
|
||||
/// <p>
|
||||
/// See <a href="https://esotericsoftware.com/spine-points">Point Attachments</a> in the Spine User Guide.
|
||||
/// </summary>
|
||||
public class PointAttachment : Attachment {
|
||||
internal float x, y, rotation;
|
||||
/// <summary>The local x position.</summary>
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
/// <summary>The local y position.</summary>
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
/// <summary>The local rotation in degrees, counter clockwise.</summary>
|
||||
public float Rotation { get { return rotation; } set { rotation = value; } }
|
||||
|
||||
public PointAttachment (string name)
|
||||
: base(name) {
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor.</summary>
|
||||
protected PointAttachment (PointAttachment other)
|
||||
: base(other) {
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
rotation = other.rotation;
|
||||
}
|
||||
|
||||
/// <summary>Computes the world position from the local position.</summary>
|
||||
public void ComputeWorldPosition (BonePose bone, out float ox, out float oy) {
|
||||
bone.LocalToWorld(this.x, this.y, out ox, out oy);
|
||||
}
|
||||
|
||||
/// <summary>Computes the world rotation from the local rotation.</summary>
|
||||
public float ComputeWorldRotation (BonePose bone) {
|
||||
float r = rotation * MathUtils.DegRad, cos = (float)Math.Cos(r), sin = (float)Math.Sin(r);
|
||||
float x = cos * bone.a + sin * bone.b;
|
||||
float y = cos * bone.c + sin * bone.d;
|
||||
return MathUtils.Atan2Deg(y, x);
|
||||
}
|
||||
|
||||
public override Attachment Copy () {
|
||||
return new PointAttachment(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fdde4cc4df0952468946f4f913dcb36
|
||||
timeCreated: 1485603478
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,229 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#if (UNITY_5 || UNITY_5_3_OR_NEWER || UNITY_WSA || UNITY_WP8 || UNITY_WP8_1)
|
||||
#define IS_UNITY
|
||||
#endif
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spine {
|
||||
#if IS_UNITY
|
||||
using Color32F = UnityEngine.Color;
|
||||
#endif
|
||||
|
||||
/// <summary>Attachment that displays a texture region.</summary>
|
||||
public class RegionAttachment : Attachment, IHasSequence {
|
||||
public const int BLX = 0, BLY = 1;
|
||||
public const int ULX = 2, ULY = 3;
|
||||
public const int URX = 4, URY = 5;
|
||||
public const int BRX = 6, BRY = 7;
|
||||
|
||||
internal readonly Sequence sequence;
|
||||
internal float x, y, rotation, scaleX = 1, scaleY = 1, width, height;
|
||||
// Color is a struct, set to protected to prevent
|
||||
// Color color = slot.color; color.a = 0.5;
|
||||
// modifying just a copy of the struct instead of the original
|
||||
// object as in reference implementation.
|
||||
protected Color32F color = new Color32F(1, 1, 1, 1);
|
||||
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
/// <summary>The local rotation in degrees, counter clockwise.</summary>
|
||||
public float Rotation { get { return rotation; } set { rotation = value; } }
|
||||
public float ScaleX { get { return scaleX; } set { scaleX = value; } }
|
||||
public float ScaleY { get { return scaleY; } set { scaleY = value; } }
|
||||
public float Width { get { return width; } set { width = value; } }
|
||||
public float Height { get { return height; } set { height = value; } }
|
||||
|
||||
public Color32F GetColor () {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void SetColor (Color32F color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public void SetColor (float r, float g, float b, float a) {
|
||||
color = new Color32F(r, g, b, a);
|
||||
}
|
||||
|
||||
public string Path { get; set; }
|
||||
public Sequence Sequence { get { return sequence; } }
|
||||
|
||||
public RegionAttachment (string name, Sequence sequence)
|
||||
: base(name) {
|
||||
if (sequence == null) throw new ArgumentException("sequence cannot be null.", "sequence");
|
||||
this.sequence = sequence;
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor.</summary>
|
||||
public RegionAttachment (RegionAttachment other)
|
||||
: base(other) {
|
||||
Path = other.Path;
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
scaleX = other.scaleX;
|
||||
scaleY = other.scaleY;
|
||||
rotation = other.rotation;
|
||||
width = other.width;
|
||||
height = other.height;
|
||||
color = other.color;
|
||||
sequence = new Sequence(other.sequence);
|
||||
}
|
||||
|
||||
/// <summary><para>
|
||||
/// Transforms the attachment's four vertices to world coordinates. If the attachment has a <see cref="Sequence"/> the region may
|
||||
/// be changed.</para>
|
||||
/// <para>
|
||||
/// See <see href='https://esotericsoftware.com/spine-runtime-skeletons#World-transforms'>World transforms</a> in the Spine
|
||||
/// Runtimes Guide.</para></summary>
|
||||
/// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to offset + 8.</param>
|
||||
/// <param name="vertexOffsets">The vertex <see cref="Sequence.GetOffsets(int)">offsets</see>.</param>
|
||||
/// <param name="offset">The worldVertices index to begin writing values.</param>
|
||||
/// <param name="stride">The number of worldVertices entries between the value pairs written.</param>
|
||||
public void ComputeWorldVertices (Slot slot, float[] vertexOffsets, float[] worldVertices, int offset, int stride = 2) {
|
||||
BonePose bone = slot.Bone.AppliedPose;
|
||||
float bwx = bone.worldX, bwy = bone.worldY;
|
||||
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
||||
|
||||
// Vertex order is different from RegionAttachment.java
|
||||
float offsetX = vertexOffsets[BRX]; // 0
|
||||
float offsetY = vertexOffsets[BRY]; // 1
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // bl
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffsets[BLX]; // 2
|
||||
offsetY = vertexOffsets[BLY]; // 3
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ul
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffsets[ULX]; // 4
|
||||
offsetY = vertexOffsets[ULY]; // 5
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ur
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffsets[URX]; // 6
|
||||
offsetY = vertexOffsets[URY]; // 7
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // br
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
//offset += stride;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the vertex <see cref="Sequence.GetOffsets(int)">offsets</see> for the specified slot pose.
|
||||
/// </summary>
|
||||
public float[] GetOffsets (SlotPose pose) {
|
||||
return sequence.GetOffsets(sequence.ResolveIndex(pose));
|
||||
}
|
||||
|
||||
public void UpdateSequence () {
|
||||
sequence.Update(this);
|
||||
}
|
||||
|
||||
public override Attachment Copy () {
|
||||
return new RegionAttachment(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes <see cref="Sequence.GetUVs(int)">UVs</see> and <see cref="Sequence.GetOffsets(int)">offsets</see> for a region attachment.
|
||||
/// </summary>
|
||||
/// <param name="uvs">Output array for the computed UVs, length of 8.</param>
|
||||
/// <param name="offset">Output array for the computed vertex offsets, length of 8.</param>
|
||||
internal static void ComputeUVs (TextureRegion region, float x, float y, float scaleX, float scaleY, float rotation, float width,
|
||||
float height, float[] offset, float[] uvs) {
|
||||
float localX2 = width / 2, localY2 = height / 2;
|
||||
float localX = -localX2, localY = -localY2;
|
||||
bool rotated = false;
|
||||
AtlasRegion r = region as AtlasRegion;
|
||||
if (r != null) {
|
||||
localX += r.offsetX / r.originalWidth * width;
|
||||
localY += r.offsetY / r.originalHeight * height;
|
||||
if (r.degrees == 90) {
|
||||
rotated = true;
|
||||
localX2 -= (r.originalWidth - r.offsetX - r.packedHeight) / r.originalWidth * width;
|
||||
localY2 -= (r.originalHeight - r.offsetY - r.packedWidth) / r.originalHeight * height;
|
||||
} else {
|
||||
localX2 -= (r.originalWidth - r.offsetX - r.packedWidth) / r.originalWidth * width;
|
||||
localY2 -= (r.originalHeight - r.offsetY - r.packedHeight) / r.originalHeight * height;
|
||||
}
|
||||
}
|
||||
localX *= scaleX;
|
||||
localY *= scaleY;
|
||||
localX2 *= scaleX;
|
||||
localY2 *= scaleY;
|
||||
float rot = rotation * MathUtils.DegRad, cos = (float)Math.Cos(rot), sin = (float)Math.Sin(rot);
|
||||
float localXCos = localX * cos + x;
|
||||
float localXSin = localX * sin;
|
||||
float localYCos = localY * cos + y;
|
||||
float localYSin = localY * sin;
|
||||
float localX2Cos = localX2 * cos + x;
|
||||
float localX2Sin = localX2 * sin;
|
||||
float localY2Cos = localY2 * cos + y;
|
||||
float localY2Sin = localY2 * sin;
|
||||
offset[BLX] = localXCos - localYSin;
|
||||
offset[BLY] = localYCos + localXSin;
|
||||
offset[ULX] = localXCos - localY2Sin;
|
||||
offset[ULY] = localY2Cos + localXSin;
|
||||
offset[URX] = localX2Cos - localY2Sin;
|
||||
offset[URY] = localY2Cos + localX2Sin;
|
||||
offset[BRX] = localX2Cos - localYSin;
|
||||
offset[BRY] = localYCos + localX2Sin;
|
||||
if (region == null) {
|
||||
uvs[BLX] = 0;
|
||||
uvs[BLY] = 0;
|
||||
uvs[ULX] = 0;
|
||||
uvs[ULY] = 1;
|
||||
uvs[URX] = 1;
|
||||
uvs[URY] = 1;
|
||||
uvs[BRX] = 1;
|
||||
uvs[BRY] = 0;
|
||||
} else {
|
||||
uvs[BLX] = region.u2;
|
||||
uvs[ULY] = region.v2;
|
||||
uvs[URX] = region.u;
|
||||
uvs[BRY] = region.v;
|
||||
if (rotated) {
|
||||
uvs[BLY] = region.v;
|
||||
uvs[ULX] = region.u2;
|
||||
uvs[URY] = region.v2;
|
||||
uvs[BRX] = region.u;
|
||||
} else {
|
||||
uvs[BLY] = region.v2;
|
||||
uvs[ULX] = region.u;
|
||||
uvs[URY] = region.v;
|
||||
uvs[BRX] = region.u2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89cefdd024734a941952a05d2b5dff71
|
||||
timeCreated: 1466772712
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,173 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Spine {
|
||||
/// <summary>
|
||||
/// Holds texture regions, UVs, and vertex offsets for rendering a region or mesh attachment. <see cref="Regions"/> must
|
||||
/// be populated and <see cref="Update(IHasSequence)"/> called before use.
|
||||
/// </summary>
|
||||
public class Sequence {
|
||||
static int nextID = 0;
|
||||
static readonly Object nextIdLock = new Object();
|
||||
|
||||
internal readonly int id;
|
||||
internal readonly TextureRegion[] regions;
|
||||
internal readonly bool pathSuffix;
|
||||
internal float[][] uvs, offsets;
|
||||
internal int start, digits, setupIndex;
|
||||
|
||||
/// <summary>The starting number for the numeric <see cref="GetPath(string, int)">path</see> suffix.</summary>
|
||||
public int Start { get { return start; } set { start = value; } }
|
||||
/// <summary>The minimum number of digits in the numeric <see cref="GetPath(string, int)">path</see> suffix, for zero
|
||||
/// padding. 0 for no zero padding.</summary>
|
||||
public int Digits { get { return digits; } set { digits = value; } }
|
||||
/// <summary>The index of the region to show for the setup pose.</summary>
|
||||
public int SetupIndex { get { return setupIndex; } set { setupIndex = value; } }
|
||||
/// <summary>The list of texture regions this sequence will display.</summary>
|
||||
public TextureRegion[] Regions { get { return regions; } }
|
||||
/// <summary>Returns true if the <see cref="GetPath(string, int)">path</see> has a numeric suffix.</summary>
|
||||
public bool HasPathSuffix { get { return pathSuffix; } }
|
||||
/// <summary>Returns a unique ID for this attachment.</summary>
|
||||
public int Id { get { return id; } }
|
||||
|
||||
/// <param name="count">The number of texture regions this sequence will display.</param>
|
||||
/// <param name="pathSuffix">If true, the <see cref="GetPath(string, int)">path</see> has a numeric suffix. If false, all
|
||||
/// regions will use the same path, so <c>count</c> should be 1.</param>
|
||||
public Sequence (int count, bool pathSuffix) {
|
||||
lock (Sequence.nextIdLock) {
|
||||
id = Sequence.nextID++;
|
||||
}
|
||||
regions = new TextureRegion[count];
|
||||
this.pathSuffix = pathSuffix;
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor.</summary>
|
||||
public Sequence (Sequence other) {
|
||||
lock (Sequence.nextIdLock) {
|
||||
id = Sequence.nextID++;
|
||||
}
|
||||
int regionCount = other.regions.Length;
|
||||
regions = new TextureRegion[regionCount];
|
||||
Array.Copy(other.regions, 0, regions, 0, regionCount);
|
||||
|
||||
start = other.start;
|
||||
digits = other.digits;
|
||||
setupIndex = other.setupIndex;
|
||||
pathSuffix = other.pathSuffix;
|
||||
|
||||
if (other.uvs != null) {
|
||||
int length = other.uvs[0].Length;
|
||||
uvs = new float[regionCount][];
|
||||
for (int i = 0; i < regionCount; i++) {
|
||||
uvs[i] = new float[length];
|
||||
Array.Copy(other.uvs[i], 0, uvs[i], 0, length);
|
||||
}
|
||||
}
|
||||
if (other.offsets != null) {
|
||||
offsets = new float[regionCount][];
|
||||
for (int i = 0; i < regionCount; i++) {
|
||||
offsets[i] = new float[8];
|
||||
Array.Copy(other.offsets[i], 0, offsets[i], 0, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update (IHasSequence attachment) {
|
||||
int regionCount = regions.Length;
|
||||
RegionAttachment region = attachment as RegionAttachment;
|
||||
if (region != null) {
|
||||
uvs = new float[regionCount][];
|
||||
offsets = new float[regionCount][];
|
||||
for (int i = 0; i < regionCount; i++) {
|
||||
uvs[i] = new float[8];
|
||||
offsets[i] = new float[8];
|
||||
RegionAttachment.ComputeUVs(regions[i], region.x, region.y, region.scaleX, region.scaleY, region.rotation,
|
||||
region.width, region.height, offsets[i], uvs[i]);
|
||||
}
|
||||
} else {
|
||||
MeshAttachment mesh = attachment as MeshAttachment;
|
||||
if (mesh != null) {
|
||||
float[] regionUVs = mesh.regionUVs;
|
||||
uvs = new float[regionCount][];
|
||||
offsets = null;
|
||||
for (int i = 0; i < regionCount; i++) {
|
||||
uvs[i] = new float[regionUVs.Length];
|
||||
MeshAttachment.ComputeUVs(regions[i], regionUVs, uvs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns the <see cref="Regions"/> index for the <see cref="SlotPose.SequenceIndex"/>.</summary>
|
||||
public int ResolveIndex (SlotPose pose) {
|
||||
int index = pose.SequenceIndex;
|
||||
if (index == -1) index = setupIndex;
|
||||
if (index >= regions.Length) index = regions.Length - 1;
|
||||
return index;
|
||||
}
|
||||
|
||||
/// <summary>Returns the texture region from <see cref="Regions"/> for the specified index.</summary>
|
||||
public TextureRegion GetRegion (int index) {
|
||||
return regions[index];
|
||||
}
|
||||
|
||||
/// <summary>Returns the UVs for the specified index. <see cref="Regions">Regions</see> must be populated and
|
||||
/// <see cref="Update(IHasSequence)"/> called before calling this method.</summary>
|
||||
public float[] GetUVs (int index) {
|
||||
return uvs[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns vertex offsets from the center of a <see cref="RegionAttachment"/>. Invalid to call for a <see cref="MeshAttachment"/>.
|
||||
/// </summary>
|
||||
public float[] GetOffsets (int index) {
|
||||
return offsets[index];
|
||||
}
|
||||
|
||||
/// <summary>Returns the specified base path with an optional numeric suffix for the specified index.</summary>
|
||||
public string GetPath (string basePath, int index) {
|
||||
if (!pathSuffix) return basePath;
|
||||
var buffer = new StringBuilder(basePath.Length + digits);
|
||||
buffer.Append(basePath);
|
||||
string frame = (start + index).ToString();
|
||||
for (int i = digits - frame.Length; i > 0; i--)
|
||||
buffer.Append('0');
|
||||
buffer.Append(frame);
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Controls how <see cref="Sequence.Regions"/> are displayed over time.</summary>
|
||||
public enum SequenceMode {
|
||||
Hold, Once, Loop, Pingpong, OnceReverse, LoopReverse, PingpongReverse
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 522632bd4e297fe47acf78100bfd8689
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,159 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2026, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 LLC 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
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Spine {
|
||||
/// <summary>Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by
|
||||
/// <see cref="SlotPose.Deform"/>.</summary>
|
||||
public abstract class VertexAttachment : Attachment {
|
||||
static int nextID = 0;
|
||||
static readonly Object nextIdLock = new Object();
|
||||
|
||||
internal readonly int id;
|
||||
internal int[] bones;
|
||||
internal float[] vertices;
|
||||
internal int worldVerticesLength;
|
||||
|
||||
/// <summary>Gets a unique ID for this attachment.</summary>
|
||||
public int Id { get { return id; } }
|
||||
/// <summary>The bones that affect the <see cref="Vertices"/>. The entries are, for each vertex, the number of bones affecting the
|
||||
/// vertex followed by that many bone indices, which is <see cref="Skeleton.Bones"/> index. Null if this attachment has no
|
||||
/// weights.</summary>
|
||||
public int[] Bones { get { return bones; } set { bones = value; } }
|
||||
/// <summary>The vertex positions in the bone's coordinate system. For a non-weighted attachment, the values are <c>x,y</c> pairs
|
||||
/// for each vertex. For a weighted attachment, the values are <c>x,y,weight</c> triplets for each bone affecting each
|
||||
/// vertex.</summary>
|
||||
public float[] Vertices { get { return vertices; } set { vertices = value; } }
|
||||
public int WorldVerticesLength { get { return worldVerticesLength; } set { worldVerticesLength = value; } }
|
||||
|
||||
public VertexAttachment (string name)
|
||||
: base(name) {
|
||||
|
||||
lock (VertexAttachment.nextIdLock) {
|
||||
id = VertexAttachment.nextID++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Copy constructor.</summary>
|
||||
public VertexAttachment (VertexAttachment other)
|
||||
: base(other) {
|
||||
|
||||
lock (VertexAttachment.nextIdLock) {
|
||||
id = VertexAttachment.nextID++;
|
||||
}
|
||||
timelineAttachment = other.timelineAttachment;
|
||||
if (other.bones != null) {
|
||||
bones = new int[other.bones.Length];
|
||||
Array.Copy(other.bones, 0, bones, 0, bones.Length);
|
||||
} else
|
||||
bones = null;
|
||||
|
||||
if (other.vertices != null) {
|
||||
vertices = new float[other.vertices.Length];
|
||||
Array.Copy(other.vertices, 0, vertices, 0, vertices.Length);
|
||||
} else
|
||||
vertices = null;
|
||||
|
||||
worldVerticesLength = other.worldVerticesLength;
|
||||
}
|
||||
|
||||
public void ComputeWorldVertices (Skeleton skeleton, Slot slot, float[] worldVertices) {
|
||||
ComputeWorldVertices(skeleton, slot, 0, worldVerticesLength, worldVertices, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the attachment's local <see cref="Vertices"/> to world coordinates. If <see cref="SlotPose.Deform"/>
|
||||
/// is not empty, it is used to deform the vertices.
|
||||
/// <para />
|
||||
/// See <a href="http://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
/// Runtimes Guide.
|
||||
/// </summary>
|
||||
/// <param name="start">The index of the first <see cref="Vertices"/> value to transform. Each vertex has 2 values, x and y.</param>
|
||||
/// <param name="count">The number of world vertex values to output. Must be less than or equal to <see cref="WorldVerticesLength"/> - start.</param>
|
||||
/// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to <paramref name="offset"/> + <paramref name="count"/>.</param>
|
||||
/// <param name="offset">The <paramref name="worldVertices"/> index to begin writing values.</param>
|
||||
/// <param name="stride">The number of <paramref name="worldVertices"/> entries between the value pairs written.</param>
|
||||
public virtual void ComputeWorldVertices (Skeleton skeleton, Slot slot, int start, int count, float[] worldVertices, int offset, int stride = 2) {
|
||||
count = offset + (count >> 1) * stride;
|
||||
ExposedList<float> deformArray = slot.AppliedPose.deform;
|
||||
float[] vertices = this.vertices;
|
||||
int[] bones = this.bones;
|
||||
if (bones == null) {
|
||||
if (deformArray.Count > 0) vertices = deformArray.Items;
|
||||
BonePose bone = slot.bone.AppliedPose;
|
||||
float x = bone.worldX, y = bone.worldY;
|
||||
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
||||
for (int vv = start, w = offset; w < count; vv += 2, w += stride) {
|
||||
float vx = vertices[vv], vy = vertices[vv + 1];
|
||||
worldVertices[w] = vx * a + vy * b + x;
|
||||
worldVertices[w + 1] = vx * c + vy * d + y;
|
||||
}
|
||||
return;
|
||||
}
|
||||
int v = 0, skip = 0;
|
||||
for (int i = 0; i < start; i += 2) {
|
||||
int n = bones[v];
|
||||
v += n + 1;
|
||||
skip += n;
|
||||
}
|
||||
Bone[] skeletonBones = skeleton.bones.Items;
|
||||
if (deformArray.Count == 0) {
|
||||
for (int w = offset, b = skip * 3; w < count; w += stride) {
|
||||
float wx = 0, wy = 0;
|
||||
int n = bones[v++];
|
||||
n += v;
|
||||
for (; v < n; v++, b += 3) {
|
||||
BonePose bone = skeletonBones[bones[v]].AppliedPose;
|
||||
float vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2];
|
||||
wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
|
||||
wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
|
||||
}
|
||||
worldVertices[w] = wx;
|
||||
worldVertices[w + 1] = wy;
|
||||
}
|
||||
} else {
|
||||
float[] deform = deformArray.Items;
|
||||
for (int w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) {
|
||||
float wx = 0, wy = 0;
|
||||
int n = bones[v++];
|
||||
n += v;
|
||||
for (; v < n; v++, b += 3, f += 2) {
|
||||
BonePose bone = skeletonBones[bones[v]].AppliedPose;
|
||||
float vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2];
|
||||
wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
|
||||
wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight;
|
||||
}
|
||||
worldVertices[w] = wx;
|
||||
worldVertices[w + 1] = wy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b40cfb462a8b774891e1604e5360d32
|
||||
timeCreated: 1466772712
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user