加入5套spine官方运行时

This commit is contained in:
tianmo
2026-09-07 21:40:29 +08:00
parent 98e51a259e
commit 6837ecada9
935 changed files with 204665 additions and 8 deletions
@@ -0,0 +1,184 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Animation_h
#define Spine_Animation_h
#include <spine/Array.h>
#include <spine/Color.h>
#include <spine/Map.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <spine/Property.h>
#include <spine/Timeline.h>
namespace spine {
class Timeline;
class BoneTimeline;
class Skeleton;
class Event;
class AnimationState;
/// Stores a list of timelines to animate a skeleton's pose over time.
///
/// See <a href='https://esotericsoftware.com/spine-applying-animations#Timeline-API'>Applying Animations</a> in the Spine
/// Runtimes Guide.
class SP_API Animation : public SpineObject {
friend class AnimationState;
friend class TrackEntry;
friend class AnimationStateData;
friend class AttachmentTimeline;
friend class RGBATimeline;
friend class RGBTimeline;
friend class AlphaTimeline;
friend class RGBA2Timeline;
friend class RGB2Timeline;
friend class DeformTimeline;
friend class DrawOrderTimeline;
friend class EventTimeline;
friend class IkConstraintTimeline;
friend class PathConstraintMixTimeline;
friend class PathConstraintPositionTimeline;
friend class PathConstraintSpacingTimeline;
friend class RotateTimeline;
friend class ScaleTimeline;
friend class ShearTimeline;
friend class TransformConstraintTimeline;
friend class TranslateTimeline;
friend class TranslateXTimeline;
friend class TranslateYTimeline;
friend class TwoColorTimeline;
friend class Slider;
public:
/// Creates a new animation. The timelines must be set before use.
Animation(const String &name);
~Animation();
/// If this list or the timelines it contains are modified, the timelines and bones must be set again to recompute the
/// animation's bone indices and timeline property IDs.
///
/// See setTimelines().
Array<Timeline *> &getTimelines();
/// Sets the timelines and bone indices.
void setTimelines(Array<Timeline *> &timelines, Array<int> &bones);
/// Returns true if this animation contains a timeline with any of the specified property IDs.
bool hasTimeline(Array<PropertyId> &ids);
/// The duration of the animation in seconds, which is usually the highest time of all frames in the timeline. The duration is
/// used to know when it has completed and when it should loop back to the start.
float getDuration();
void setDuration(float inValue);
/// Applies the animation's timelines to the specified skeleton.
///
/// See Timeline::apply() and
/// <a href='https://esotericsoftware.com/spine-applying-animations#Timeline-API'>Applying Animations</a> in the Spine
/// Runtimes Guide.
/// @param skeleton The skeleton the animation is applied to. This provides access to the bones, slots, and other skeleton
/// components the timelines may change.
/// @param lastTime The last time in seconds this animation was applied. Some timelines trigger only at discrete times, in
/// which case all keys are triggered between lastTime (exclusive) and time (inclusive). Pass -1 the first time an
/// animation is applied to ensure frame 0 is triggered.
/// @param time The time in seconds the skeleton is being posed for. Timelines find the frame before and after this time and
/// interpolate between the frame values.
/// @param loop True if time beyond the animation duration repeats the animation, else the last frame is used.
/// @param events If any events are fired, they are added to this list. Can be NULL to ignore fired events or if no timelines
/// fire events.
/// @param alpha 0 applies setup or current values (depending on from), 1 uses timeline values, and intermediate values
/// interpolate between them. Adjusting alpha over time can mix an animation in or out.
/// @param from If true, alpha transitions between setup and timeline values, setup values are used before the first
/// frame (current values are not used). If false, alpha transitions between current and timeline values, no change
/// is made before the first frame.
/// @param add If true, for timelines that support it, their values are added to the setup or current values (depending on
/// from).
/// @param out True when the animation is mixing out, else it is mixing in. Used by timelines that perform instant
/// transitions.
/// @param appliedPose True to modify getAppliedPose(), else the unconstrained pose is modified.
void apply(Skeleton &skeleton, float lastTime, float time, bool loop, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose);
/// The animation's name, which is unique across all animations in the skeleton.
const String &getName();
/// The Skeleton::getBones() indices affected by this animation.
///
/// See setTimelines() and BoneTimeline::getBoneIndex().
const Array<int> &getBones();
/// The color of the animation as it was in Spine, or a default color if nonessential data was not exported.
Color &getColor();
/// @param target After the first and before the last entry.
static int search(Array<float> &values, float target);
static int search(Array<float> &values, float target, int step);
protected:
Array<Timeline *> _timelines;
Map<PropertyId, bool> _timelineIds;
Array<int> _bones;
float _duration;
String _name;
Color _color;
};
}
#endif /* Spine_Animation_h */
@@ -0,0 +1,619 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_AnimationState_h
#define Spine_AnimationState_h
#include <spine/Array.h>
#include <spine/Map.h>
#include <spine/Pool.h>
#include <spine/Property.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <spine/Timeline.h>
#include <spine/HasRendererObject.h>
#include <spine/Interpolation.h>
#include "Slot.h"
#ifdef SPINE_USE_STD_FUNCTION
#include <functional>
#endif
namespace spine {
enum EventType {
EventType_Start = 0,
EventType_Interrupt,
EventType_End,
EventType_Dispose,
EventType_Complete,
EventType_Event
};
class AnimationState;
class TrackEntry;
class Animation;
class Event;
class AnimationStateData;
class Skeleton;
class RotateTimeline;
class AttachmentTimeline;
#ifdef SPINE_USE_STD_FUNCTION
typedef std::function<void(AnimationState *state, EventType type, TrackEntry *entry, Event *event)> AnimationStateListener;
#else
typedef void (*AnimationStateListener)(AnimationState *state, EventType type, TrackEntry *entry, Event *event, void *userData);
#endif
/// Abstract class to inherit from to create a callback object
class SP_API AnimationStateListenerObject {
public:
AnimationStateListenerObject() {};
virtual ~AnimationStateListenerObject() {};
public:
/// The callback function to be called
virtual void callback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) = 0;
};
/// State for the playback of an animation
class SP_API TrackEntry : public SpineObject, public HasRendererObject {
friend class EventQueue;
friend class AnimationState;
public:
TrackEntry();
virtual ~TrackEntry();
/// The index of the track where this entry is either current or queued.
int getTrackIndex();
/// The animation to apply for this track entry.
Animation &getAnimation();
/// Sets the animation for this track entry.
void setAnimation(Animation &animation);
TrackEntry *getPrevious();
/// If true, the animation will repeat. If false, it will not, instead its last frame is applied if played beyond its duration.
bool getLoop();
void setLoop(bool inValue);
/// When true, timelines in this animation that support additive have their values added to the setup or current pose values
/// instead of replacing them. Additive can be set for a new track entry only before AnimationState::apply() is next called.
bool getAdditive();
void setAdditive(bool inValue);
bool getReverse();
void setReverse(bool inValue);
bool getShortestRotation();
void setShortestRotation(bool inValue);
/// Seconds to postpone playing the animation. Must be >= 0. When this track entry is the current track entry,
/// delay postpones incrementing the track time. When this track entry is queued, delay is the time from the start of the
/// previous animation to when this track entry will become the current track entry (ie when the previous track entry's track
/// time >= this track entry's delay).
///
/// Time scale affects the delay.
///
/// When passing delay <= 0 to AnimationState::addAnimation(int, Animation, bool, float), this delay is set using a mix
/// duration from AnimationStateData. To change the mix duration afterward, use setMixDuration(float, float) so this delay is
/// adjusted.
float getDelay();
void setDelay(float inValue);
/// The time in seconds this track entry has been the current track entry, starting at 0 and increasing forever.
/// Compare to getAnimationTime(), which is always between animationStart and animationEnd.
///
/// The track time can be set to start the animation at a time other than 0, without affecting looping. When doing so,
/// animationLast can be set to the same value to avoid firing events from the start of the animation.
float getTrackTime();
void setTrackTime(float inValue);
/// The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float
/// value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time
/// is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the
/// properties keyed by the animation are set to the setup pose and the track is cleared.
///
/// It may be desired to use AnimationState::addEmptyAnimation(int, float, float) rather than have the animation
/// abruptly cease being applied, leaving the current pose.
float getTrackEnd();
void setTrackEnd(float inValue);
/// The time in seconds for the first frame of this animation, both initially and after looping. Defaults to 0.
///
/// When setting the animation start time, animationLast can be set to the same value to avoid firing events from the
/// start of the animation.
float getAnimationStart();
void setAnimationStart(float inValue);
/// The time in seconds for the last frame of this animation. Past this time, non-looping animations hold the pose at this
/// time while looping animations will loop back to animationStart. Defaults to the animation duration.
float getAnimationEnd();
void setAnimationEnd(float inValue);
/// The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this
/// animation is applied, event timelines will fire all events between the animation last time (exclusive) and animation time
/// (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation is applied.
float getAnimationLast();
void setAnimationLast(float inValue);
/// Uses the track time to compute animationTime, which is always between animationStart and animationEnd. When trackTime is
/// 0, animationTime is equal to animationStart.
float getAnimationTime();
/// Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or
/// faster. Defaults to 1.
///
/// Values < 0 are not supported. To play an animation in reverse, use reverse.
///
/// mixTime is not affected by track entry time scale, so mixDuration may need to be adjusted to match the animation speed.
///
/// When using AnimationState::addAnimation(int, Animation, bool, float) with a delay <= 0, delay is set using the mix
/// duration from AnimationStateData, assuming time scale to be 1. If the time scale is not 1, the delay may need to be
/// adjusted.
///
/// See AnimationState::getTimeScale() for affecting all animations.
float getTimeScale();
void setTimeScale(float inValue);
/// Values less than 1 mix this animation with the last skeleton pose. Defaults to 1, which overwrites the last skeleton pose with
/// this animation.
///
/// Typically track 0 is used to completely pose the skeleton, then alpha can be used on higher tracks. It doesn't make sense
/// to use alpha on track 0 if the skeleton pose is from the last frame render.
float getAlpha();
void setAlpha(float inValue);
///
/// When the interpolated mix percentage is less than the event threshold, event timelines for the animation being mixed out
/// will be applied. Defaults to 0, so event timelines are not applied for an animation being mixed out.
float getEventThreshold();
void setEventThreshold(float inValue);
/// When the interpolated mix percentage is less than the attachment threshold, attachment timelines for the animation being
/// mixed out will be applied. Defaults to 0, so attachment timelines are not applied for an animation being mixed out.
float getMixAttachmentThreshold();
void setMixAttachmentThreshold(float inValue);
/// When the computed alpha is greater than alphaAttachmentThreshold, attachment timelines are applied. The computed alpha
/// includes alpha and the interpolated mix percentage. Defaults to 0, so attachment timelines are always applied.
float getAlphaAttachmentThreshold();
void setAlphaAttachmentThreshold(float inValue);
/// When the interpolated mix percentage is less than the draw order threshold, draw order timelines for the animation being
/// mixed out will be applied. Defaults to 0, so draw order timelines are not applied for an animation being mixed out.
float getMixDrawOrderThreshold();
void setMixDrawOrderThreshold(float inValue);
/// The animation queued to start after this animation, or NULL.
TrackEntry *getNext();
/// Returns true if at least one loop has been completed.
bool isComplete();
/// Seconds from 0 to the mix duration when mixing from the previous animation to this animation. May be slightly more than
/// mixDuration when the mix is complete.
float getMixTime();
void setMixTime(float inValue);
/// Seconds for mixing from the previous animation to this animation. Defaults to the value provided by
/// AnimationStateData based on the animation before this animation (if any).
///
/// The mix duration can be set manually rather than use the value from AnimationStateData.GetMix.
/// In that case, the mixDuration must be set before AnimationState.update(float) is next called.
///
/// When using AnimationState::addAnimation(int, Animation, bool, float) with a delay
/// less than or equal to 0, note the Delay is set using the mix duration from the AnimationStateData
float getMixDuration();
void setMixDuration(float inValue);
/// Sets both mixDuration and delay.
/// @param delay If > 0, sets delay. If <= 0, the delay set is the duration of the previous track
/// entry minus the specified mix duration plus the specified delay (ie the mix ends at
/// (delay = 0) or before (delay < 0) the previous track entry duration). If the previous
/// entry is looping, its next loop completion is used instead of its duration.
void setMixDuration(float mixDuration, float delay);
/// The interpolation to apply to the mix percentage (mix time / mix duration) when mixing from the previous animation to
/// this animation. Defaults to linear.
Interpolation &getMixInterpolation();
void setMixInterpolation(Interpolation &mixInterpolation);
/// The track entry for the previous animation when mixing to this animation, or NULL if no mixing is currently occurring.
/// When mixing from multiple animations, MixingFrom makes up a doubly linked list with MixingTo.
TrackEntry *getMixingFrom();
/// The track entry for the next animation when mixing from this animation, or NULL if no mixing is currently occurring.
/// When mixing to multiple animations, MixingTo makes up a doubly linked list with MixingFrom.
TrackEntry *getMixingTo();
/// Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
/// long way around when using alpha and starting animations on other tracks.
///
/// Mixing involves finding a rotation between two others, which has two possible solutions: the short way or the long way around.
/// The two rotations likely change over time, so which direction is the short or long way also changes.
/// If the short way was always chosen, bones would flip to the other side when that direction became the long way.
/// TrackEntry chooses the short way the first time it is applied and remembers that direction.
void resetRotationDirections();
float getTrackComplete();
#ifdef SPINE_USE_STD_FUNCTION
void setListener(AnimationStateListener listener);
#else
void setListener(AnimationStateListener listener, void *userData = NULL);
#endif
void setListener(AnimationStateListenerObject *listener);
/// Returns true if this entry is for the empty animation.
bool isEmptyAnimation();
/// Returns true if this track entry has been applied at least once.
///
/// See AnimationState::apply(Skeleton).
bool wasApplied();
/// Returns true if there is a next track entry that is ready to become the current track entry during the
/// next AnimationState::update(float)}
bool isNextReady() {
return _next != NULL && _nextTrackLast - _next->_delay >= 0;
}
// The AnimationState this track entry belongs to. May be NULL if TrackEntry is directly instantiated.
AnimationState *getAnimationState() {
return _state;
}
void setAnimationState(AnimationState *state) {
_state = state;
}
private:
Animation *_animation;
TrackEntry *_previous;
TrackEntry *_next;
TrackEntry *_mixingFrom;
TrackEntry *_mixingTo;
int _trackIndex;
bool _loop, _additive, _reverse, _shortestRotation, _keepHold;
float _eventThreshold, _mixAttachmentThreshold, _alphaAttachmentThreshold, _mixDrawOrderThreshold;
float _animationStart, _animationEnd, _animationLast, _nextAnimationLast;
float _delay, _trackTime, _trackLast, _nextTrackLast, _trackEnd, _timeScale;
float _alpha, _mixTime, _mixDuration, _totalAlpha;
Interpolation *_mixInterpolation;
Array<int> _timelineMode;
Array<TrackEntry *> _timelineHoldMix;
Array<float> _timelinesRotation;
AnimationStateListener _listener;
#ifndef SPINE_USE_STD_FUNCTION
void *_listenerUserData;
#endif
AnimationStateListenerObject *_listenerObject;
AnimationState *_state;
float mix();
void reset();
};
class SP_API EventQueueEntry : public SpineObject {
friend class EventQueue;
public:
EventType _type;
TrackEntry *_entry;
Event *_event;
EventQueueEntry(EventType eventType, TrackEntry *trackEntry, Event *event = NULL);
};
class SP_API EventQueue : public SpineObject {
friend class AnimationState;
private:
Array<EventQueueEntry> _eventQueueEntries;
AnimationState &_state;
bool _drainDisabled;
static EventQueue *newEventQueue(AnimationState &state);
static EventQueueEntry newEventQueueEntry(EventType eventType, TrackEntry *entry, Event *event = NULL);
EventQueue(AnimationState &state);
~EventQueue();
void start(TrackEntry *entry);
void interrupt(TrackEntry *entry);
void end(TrackEntry *entry);
void dispose(TrackEntry *entry);
void complete(TrackEntry *entry);
void event(TrackEntry *entry, Event *event);
/// Raises all events in the queue and drains the queue.
void drain();
};
/// Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies
/// multiple animations on top of each other (layering).
///
/// See <a href='https://esotericsoftware.com/spine-applying-animations#AnimationState-API'>Applying Animations</a> in the
/// Spine Runtimes Guide.
class SP_API AnimationState : public SpineObject, public HasRendererObject {
friend class TrackEntry;
friend class EventQueue;
public:
explicit AnimationState(AnimationStateData &data);
~AnimationState();
/// Increments each track entry's track time, setting queued animations as current if needed.
void update(float delta);
/// Poses the skeleton using the track entry animations. The animation state is not changed, so can be applied to multiple
/// skeletons to pose them identically.
/// @return True if any animations were applied.
bool apply(Skeleton &skeleton);
/// Removes all animations from all tracks, leaving skeletons in their current pose.
///
/// It may be desired to use AnimationState::setEmptyAnimations(float) to mix the skeletons back to the setup pose,
/// rather than leaving them in their current pose.
void clearTracks();
/// Removes all animations from the track, leaving skeletons in their current pose.
///
/// It may be desired to use AnimationState::setEmptyAnimation(int, float) to mix the skeletons back to the setup pose,
/// rather than leaving them in their current pose.
void clearTrack(size_t trackIndex);
/// Sets an animation by name.
///
/// See setAnimation(int, Animation, bool).
TrackEntry &setAnimation(size_t trackIndex, const String &animationName, bool loop);
/// Sets the current animation for a track, discarding any queued animations.
///
/// If the formerly current track entry is for the same animation and was never applied to a skeleton, it is replaced (not mixed
/// from).
/// @param loop If true, the animation will repeat.
/// If false, it will not, instead its last frame is applied if played beyond its duration.
/// In either case TrackEntry.TrackEnd determines when the track is cleared.
/// @return
/// A track entry to allow further customization of animation playback. References to the track entry must not be kept
/// after AnimationState.Dispose.
TrackEntry &setAnimation(size_t trackIndex, Animation &animation, bool loop);
/// Queues an animation by name.
///
/// See addAnimation(int, Animation, bool, float).
TrackEntry &addAnimation(size_t trackIndex, const String &animationName, bool loop, float delay);
/// Adds an animation to be played delay seconds after the current or last queued animation
/// for a track. If the track has no entries, this is equivalent to calling setAnimation.
/// @param delay
/// Seconds to begin this animation after the start of the previous animation. May be &lt;= 0 to use the animation
/// duration of the previous track minus any mix duration plus the negative delay.
///
/// @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
/// after AnimationState.Dispose
TrackEntry &addAnimation(size_t trackIndex, Animation &animation, bool loop, float delay);
/// Sets an empty animation for a track, discarding any queued animations, and sets the track entry's
/// TrackEntry::getMixDuration(). An empty animation has no timelines and serves as a placeholder for mixing in or out.
///
/// Mixing out is done by setting an empty animation with a mix duration using either setEmptyAnimation(int, float),
/// setEmptyAnimations(float), or addEmptyAnimation(int, float, float). Mixing to an empty animation causes
/// the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation
/// transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of
/// 0 still mixes out over one frame.
///
/// Mixing in is done by first setting an empty animation, then adding an animation using
/// addAnimation(int, Animation, bool, float) with the desired delay (an empty animation has a duration of 0) and on
/// the returned track entry set TrackEntry::setMixDuration(float). Mixing from an empty animation causes the new
/// animation to be applied more and more over the mix duration. Properties keyed in the new animation transition from the value
/// from lower tracks or from the setup pose value if no lower tracks key the property to the value keyed in the new animation.
///
/// See <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine
/// Runtimes Guide.
TrackEntry &setEmptyAnimation(size_t trackIndex, float mixDuration);
/// Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's
/// TrackEntry::getMixDuration(). If the track has no entries, it is equivalent to calling
/// setEmptyAnimation(int, float).
///
/// See setEmptyAnimation(int, float) and
/// <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine
/// Runtimes Guide.
/// @param delay If > 0, sets TrackEntry::getDelay(). If <= 0, the delay set is the duration of the previous track entry
/// minus any mix duration plus the specified <code>delay</code> (ie the mix ends at (<code>delay</code> = 0) or before
/// (<code>delay</code> < 0) the previous track entry duration). If the previous entry is looping, its next loop completion
/// is used instead of its duration.
/// @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
/// after the AnimationStateListener::dispose(TrackEntry) event occurs.
TrackEntry &addEmptyAnimation(size_t trackIndex, float mixDuration, float delay);
/// Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix duration.
///
/// See <a href='https://esotericsoftware.com/spine-applying-animations#Empty-animations'>Empty animations</a> in the Spine
/// Runtimes Guide.
void setEmptyAnimations(float mixDuration);
/// @return The track entry for the animation currently playing on the track, or NULL if no animation is currently playing.
TrackEntry *getTrack(size_t trackIndex);
/// The AnimationStateData to look up mix durations.
AnimationStateData &getData();
/// The list of tracks that have had animations, which may contain null entries for tracks that currently have no animation.
Array<TrackEntry *> &getTracks();
/// Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower
/// or faster. Defaults to 1.
///
/// See TrackEntry::getTimeScale() for affecting a single animation.
float getTimeScale();
void setTimeScale(float inValue);
/// Adds a listener to receive events for all track entries.
#ifdef SPINE_USE_STD_FUNCTION
void setListener(AnimationStateListener listener);
#else
void setListener(AnimationStateListener listener, void *userData = NULL);
#endif
/// Adds a listener to receive events for all track entries.
void setListener(AnimationStateListenerObject *listener);
void disableQueue();
void enableQueue();
void setManualTrackEntryDisposal(bool inValue);
bool getManualTrackEntryDisposal();
void disposeTrackEntry(TrackEntry *entry);
private:
static const int Current = 0;
static const int Setup = 1;
static const int First = 2;
static const int Mode = 3;
static const int Hold = 4;
static const int AttachSetup = 1;
static const int AttachRetain = 2;
AnimationStateData *_data;
Pool<TrackEntry> _trackEntryPool;
Array<TrackEntry *> _tracks;
Array<Event *> _events;
EventQueue *_queue;
Map<PropertyId, TrackEntry *> _propertyIDs;
bool _animationsChanged;
AnimationStateListener _listener;
#ifndef SPINE_USE_STD_FUNCTION
void *_listenerUserData;
#endif
AnimationStateListenerObject *_listenerObject;
int _unkeyedState;
float _timeScale;
bool _manualTrackEntryDisposal;
static Animation *getEmptyAnimation();
/// Applies the rotate timeline, mixing with the current pose while keeping the same rotation direction chosen as the shortest
/// the first time the mixing was applied.
static void applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleton &skeleton, float time, float alpha, MixFrom from,
Array<float> &timelinesRotation, size_t i, bool firstFrame);
/// Applies the attachment timeline and sets Slot::attachmentState.
/// @param retain True if the attachment remains after apply, false if temporary for deform timelines.
void applyAttachmentTimeline(AttachmentTimeline *attachmentTimeline, Skeleton &skeleton, float animationTime, MixFrom from, bool retain);
/// Returns true when all mixing from entries are complete.
bool updateMixingFrom(TrackEntry *to, float delta);
float applyMixingFrom(TrackEntry *to, Skeleton &skeleton);
void queueEvents(TrackEntry *entry, float animationTime);
void eventsReverse(TrackEntry *entry, float animationLast, float animationTime);
/// Sets the active TrackEntry for a given track number.
void setTrack(size_t index, TrackEntry *current, bool interrupt);
/// Removes the specified entry's next track entry and all entries after it.
void clearNext(TrackEntry *entry);
TrackEntry *expandToIndex(size_t index);
/// Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values.
/// @param last May be NULL.
TrackEntry *newTrackEntry(size_t trackIndex, Animation *animation, bool loop, TrackEntry *last);
void animationsChanged();
void computeHold(TrackEntry *entry, TrackEntry *track);
int from(TrackEntry *track, Timeline *timeline, Array<PropertyId> &ids);
};
}
#endif /* Spine_AnimationState_h */
@@ -0,0 +1,95 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_AnimationStateData_h
#define Spine_AnimationStateData_h
#include <spine/Map.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <assert.h>
namespace spine {
class SkeletonData;
class Animation;
/// Stores mix (crossfade) durations to be applied when AnimationState animations are changed on the same track.
class SP_API AnimationStateData : public SpineObject {
friend class AnimationState;
public:
explicit AnimationStateData(SkeletonData &skeletonData);
/// The SkeletonData to look up animations when they are specified by name.
SkeletonData &getSkeletonData();
/// The mix duration to use when no mix duration has been specifically defined between two animations.
float getDefaultMix();
void setDefaultMix(float inValue);
/// Sets a mix duration by animation names.
void setMix(const String &fromName, const String &toName, float duration);
/// Sets a mix duration when changing from the specified animation to the other.
/// See TrackEntry.MixDuration.
void setMix(Animation &from, Animation &to, float duration);
/// Returns the mix duration to use when changing from the specified animation to the other on the same track,
/// or the default mix if no mix duration has been set.
float getMix(Animation &from, Animation &to);
/// Removes all mixes and sets the default mix to 0.
void clear();
private:
class AnimationPair : public SpineObject {
public:
Animation *_a1;
Animation *_a2;
explicit AnimationPair(Animation *a1 = NULL, Animation *a2 = NULL);
bool operator==(const AnimationPair &other) const;
};
class AnimationPairHash {
public:
size_t operator()(const AnimationPair &pair) const;
};
SkeletonData *_skeletonData;
float _defaultMix;
Map<AnimationPair, float, AnimationPairHash> _animationToMixTime;
};
}
#endif /* Spine_AnimationStateData_h */
@@ -0,0 +1,249 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Array_h
#define Spine_Array_h
#include <spine/Extension.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <assert.h>
namespace spine {
template<typename T>
class SP_API Array : public SpineObject {
public:
using size_type = size_t;
using value_type = T;
Array() : _size(0), _capacity(0), _buffer(NULL) {
}
Array(size_t capacity) : _size(0), _capacity(0), _buffer(NULL) {
ensureCapacity(capacity);
}
Array(const Array &inArray) : _size(inArray._size), _capacity(inArray._capacity), _buffer(NULL) {
if (_capacity > 0) {
_buffer = allocate(_capacity);
for (size_t i = 0; i < _size; ++i) {
construct(_buffer + i, inArray._buffer[i]);
}
}
}
~Array() {
clear();
deallocate(_buffer);
}
inline void clear() {
for (size_t i = 0; i < _size; ++i) {
destroy(_buffer + (_size - 1 - i));
}
_size = 0;
}
inline size_t getCapacity() const {
return _capacity;
}
inline size_t size() const {
return _size;
}
inline Array<T> &setSize(size_t newSize, const T &defaultValue) {
size_t oldSize = _size;
_size = newSize;
if (_capacity < newSize) {
if (_capacity == 0) {
_capacity = _size;
} else {
_capacity = (int) (_size * 1.75f);
}
if (_capacity < 8) _capacity = 8;
_buffer = SpineExtension::realloc<T>(_buffer, _capacity, __FILE__, __LINE__);
}
if (oldSize < _size) {
for (size_t i = oldSize; i < _size; i++) {
construct(_buffer + i, defaultValue);
}
} else {
for (size_t i = _size; i < oldSize; i++) {
destroy(_buffer + i);
}
}
return *this;
}
inline void ensureCapacity(size_t newCapacity = 0) {
if (_capacity >= newCapacity) return;
_capacity = newCapacity;
_buffer = SpineExtension::realloc<T>(_buffer, newCapacity, __FILE__, __LINE__);
}
inline void add(const T &inValue) {
if (_size == _capacity) {
// inValue might reference an element in this buffer
// When we reallocate, the reference becomes invalid.
// We thus need to create a defensive copy before
// reallocating.
T valueCopy = inValue;
_capacity = (int) (_size * 1.75f);
if (_capacity < 8) _capacity = 8;
_buffer = SpineExtension::realloc<T>(_buffer, _capacity, __FILE__, __LINE__);
construct(_buffer + _size++, valueCopy);
} else {
construct(_buffer + _size++, inValue);
}
}
inline void addAll(const Array<T> &inValue) {
ensureCapacity(this->size() + inValue.size());
for (size_t i = 0; i < inValue.size(); i++) {
add(inValue[i]);
}
}
inline void clearAndAddAll(const Array<T> &inValue) {
ensureCapacity(inValue.size());
for (size_t i = 0; i < inValue.size(); i++) _buffer[i] = inValue[i];
_size = inValue.size();
}
inline void removeAt(size_t inIndex) {
assert(inIndex < _size);
--_size;
if (inIndex != _size) {
for (size_t i = inIndex; i < _size; ++i) {
T tmp(_buffer[i]);
_buffer[i] = _buffer[i + 1];
_buffer[i + 1] = tmp;
}
}
destroy(_buffer + _size);
}
inline bool contains(const T &inValue) {
for (size_t i = 0; i < _size; ++i) {
if (_buffer[i] == inValue) {
return true;
}
}
return false;
}
inline int indexOf(const T &inValue) {
for (size_t i = 0; i < _size; ++i) {
if (_buffer[i] == inValue) {
return (int) i;
}
}
return -1;
}
inline T &operator[](size_t inIndex) {
assert(inIndex < _size);
return _buffer[inIndex];
}
inline const T &operator[](size_t inIndex) const {
assert(inIndex < _size);
return _buffer[inIndex];
}
inline friend bool operator==(Array<T> &lhs, Array<T> &rhs) {
if (lhs.size() != rhs.size()) {
return false;
}
for (size_t i = 0, n = lhs.size(); i < n; ++i) {
if (lhs[i] != rhs[i]) {
return false;
}
}
return true;
}
inline friend bool operator!=(Array<T> &lhs, Array<T> &rhs) {
return !(lhs == rhs);
}
Array &operator=(const Array &inArray) {
if (this != &inArray) {
clearAndAddAll(inArray);
}
return *this;
}
inline T *buffer() {
return _buffer;
}
private:
size_t _size;
size_t _capacity;
T *_buffer;
inline T *allocate(size_t n) {
assert(n > 0);
T *ptr = SpineExtension::calloc<T>(n, __FILE__, __LINE__);
assert(ptr);
return ptr;
}
inline void deallocate(T *buffer) {
if (_buffer) {
SpineExtension::free(buffer, __FILE__, __LINE__);
}
}
inline void construct(T *buffer, const T &val) {
new (buffer) T(val);
}
inline void destroy(T *buffer) {
buffer->~T();
}
};
}
#endif /* Spine_Array_h */
@@ -0,0 +1,128 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_ContainerUtil_h
#define Spine_ContainerUtil_h
#include <spine/Extension.h>
#include <spine/Array.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <assert.h>
namespace spine {
class SP_API ArrayUtils : public SpineObject {
public:
/// Finds an item by comparing each item's name.
/// It is more efficient to cache the results of this method than to call it multiple times.
/// @return May be NULL.
template<typename T>
static T *findWithName(Array<T *> &items, const String &name) {
assert(name.length() > 0);
for (size_t i = 0; i < items.size(); ++i) {
T *item = items[i];
if (item->getName() == name) {
return item;
}
}
return NULL;
}
/// @return -1 if the item was not found.
template<typename T>
static int findIndexWithName(Array<T *> &items, const String &name) {
assert(name.length() > 0);
for (size_t i = 0, len = items.size(); i < len; ++i) {
T *item = items[i];
if (item->getName() == name) {
return static_cast<int>(i);
}
}
return -1;
}
/// Finds an item by comparing each item's name.
/// It is more efficient to cache the results of this method than to call it multiple times.
/// @return May be NULL.
template<typename T>
static T *findWithDataName(Array<T *> &items, const String &name) {
assert(name.length() > 0);
for (size_t i = 0; i < items.size(); ++i) {
T *item = items[i];
if (item->getData().getName() == name) {
return item;
}
}
return NULL;
}
/// @return -1 if the item was not found.
template<typename T>
static int findIndexWithDataName(Array<T *> &items, const String &name) {
assert(name.length() > 0);
for (size_t i = 0, len = items.size(); i < len; ++i) {
T *item = items[i];
if (item->getData().getName() == name) {
return static_cast<int>(i);
}
}
return -1;
}
template<typename T>
static void deleteElements(Array<T *> &items) {
for (int i = (int) items.size() - 1; i >= 0; i--) {
T *item = items[i];
delete item;
items.removeAt(i);
}
}
private:
// ctor, copy ctor, and assignment should be private in a Singleton
ArrayUtils();
ArrayUtils(const ArrayUtils &);
ArrayUtils &operator=(const ArrayUtils &);
};
}
#endif /* Spine_ContainerUtil_h */
@@ -0,0 +1,273 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Atlas_h
#define Spine_Atlas_h
#include <spine/Array.h>
#include <spine/Extension.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <spine/HasRendererObject.h>
#include "TextureRegion.h"
#include "spine/MeshAttachment.h"
#include "spine/RegionAttachment.h"
namespace spine {
enum Format {
Format_Alpha,
Format_Intensity,
Format_LuminanceAlpha,
Format_RGB565,
Format_RGBA4444,
Format_RGB888,
Format_RGBA8888
};
// Our TextureFilter collides with UE4's TextureFilter in unity builds. We rename
// TextureFilter to SpineTextureFilter in UE4.
#ifdef SPINE_UE4
enum SpineTextureFilter {
TextureFilter_Unknown,
TextureFilter_Nearest,
TextureFilter_Linear,
TextureFilter_MipMap,
TextureFilter_MipMapNearestNearest,
TextureFilter_MipMapLinearNearest,
TextureFilter_MipMapNearestLinear,
TextureFilter_MipMapLinearLinear
};
#else
enum TextureFilter {
TextureFilter_Unknown,
TextureFilter_Nearest,
TextureFilter_Linear,
TextureFilter_MipMap,
TextureFilter_MipMapNearestNearest,
TextureFilter_MipMapLinearNearest,
TextureFilter_MipMapNearestLinear,
TextureFilter_MipMapLinearLinear
};
#endif
enum TextureWrap {
TextureWrap_MirroredRepeat,
TextureWrap_ClampToEdge,
TextureWrap_Repeat
};
class SP_API AtlasPage : public SpineObject {
public:
String name;
String texturePath;
Format format;
#ifdef SPINE_UE4
SpineTextureFilter minFilter;
SpineTextureFilter magFilter;
#else
TextureFilter minFilter;
TextureFilter magFilter;
#endif
TextureWrap uWrap;
TextureWrap vWrap;
int width, height;
bool pma;
int index;
void *texture;
explicit AtlasPage(const String &inName)
: name(inName), format(Format_RGBA8888), minFilter(TextureFilter_Nearest), magFilter(TextureFilter_Nearest),
uWrap(TextureWrap_ClampToEdge), vWrap(TextureWrap_ClampToEdge), width(0), height(0), pma(false), index(0), texture(nullptr) {
}
};
class SP_API AtlasRegion : public TextureRegion {
friend class Atlas;
friend class RegionAttachment;
friend class MeshAttachment;
RTTI_DECL
public:
AtlasRegion()
: TextureRegion(), _page(nullptr), _name(""), _index(0), _x(0), _y(0), _offsetX(0), _offsetY(0), _packedWidth(0), _packedHeight(0),
_originalWidth(0), _originalHeight(0), _rotate(false), _degrees(0) {
}
~AtlasRegion() {
}
AtlasPage *getPage() const {
return _page;
}
const String &getName() const {
return _name;
}
int getIndex() const {
return _index;
}
int getX() const {
return _x;
}
int getY() const {
return _y;
}
float getOffsetX() const {
return _offsetX;
}
float getOffsetY() const {
return _offsetY;
}
int getPackedWidth() const {
return _packedWidth;
}
int getPackedHeight() const {
return _packedHeight;
}
int getOriginalWidth() const {
return _originalWidth;
}
int getOriginalHeight() const {
return _originalHeight;
}
bool getRotate() const {
return _rotate;
}
int getDegrees() const {
return _degrees;
}
Array<int> &getSplits() {
return _splits;
}
Array<int> &getPads() {
return _pads;
}
Array<String> &getNames() {
return _names;
}
Array<float> &getValues() {
return _values;
}
void setPage(AtlasPage *value) {
_page = value;
}
void setName(const String &value) {
_name = value;
}
void setIndex(int value) {
_index = value;
}
void setX(int value) {
_x = value;
}
void setY(int value) {
_y = value;
}
void setOffsetX(float value) {
_offsetX = value;
}
void setOffsetY(float value) {
_offsetY = value;
}
void setPackedWidth(int value) {
_packedWidth = value;
}
void setPackedHeight(int value) {
_packedHeight = value;
}
void setOriginalWidth(int value) {
_originalWidth = value;
}
void setOriginalHeight(int value) {
_originalHeight = value;
}
void setRotate(bool value) {
_rotate = value;
}
void setDegrees(int value) {
_degrees = value;
}
void setSplits(const Array<int> &value) {
_splits = value;
}
void setPads(const Array<int> &value) {
_pads = value;
}
void setNames(const Array<String> &value) {
_names = value;
}
void setValues(const Array<float> &value) {
_values = value;
}
private:
AtlasPage *_page;
String _name;
int _index;
int _x, _y;
float _offsetX, _offsetY;
int _packedWidth, _packedHeight;
int _originalWidth, _originalHeight;
bool _rotate;
int _degrees;
Array<int> _splits;
Array<int> _pads;
Array<String> _names;
Array<float> _values;
};
class TextureLoader;
class SP_API Atlas : public SpineObject {
public:
Atlas(const String &path, TextureLoader *textureLoader, bool createTexture = true);
Atlas(const char *data, int length, const char *dir, TextureLoader *textureLoader, bool createTexture = true);
~Atlas();
void flipV();
/// Returns the first region found with the specified name. This method uses String comparison to find the region, so the result
/// should be cached rather than calling this method multiple times.
/// @return The region, or nullptr.
AtlasRegion *findRegion(const String &name);
Array<AtlasPage *> &getPages();
Array<AtlasRegion *> &getRegions();
private:
Array<AtlasPage *> _pages;
Array<AtlasRegion *> _regions;
TextureLoader *_textureLoader;
void load(const char *begin, int length, const char *dir, bool createTexture);
};
}// namespace spine
#endif /* Spine_Atlas_h */
@@ -0,0 +1,71 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_AtlasAttachmentLoader_h
#define Spine_AtlasAttachmentLoader_h
#include <spine/AttachmentLoader.h>
#include <spine/Array.h>
#include <spine/SpineString.h>
namespace spine {
class Atlas;
class AtlasRegion;
/// An AttachmentLoader that configures attachments using texture regions from an Atlas.
///
/// See https://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data Loading skeleton data in the
/// Spine Runtimes Guide.
class SP_API AtlasAttachmentLoader : public AttachmentLoader {
public:
explicit AtlasAttachmentLoader(Atlas &atlas);
virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &placeholder, const String &name, const String &path,
Sequence *sequence);
virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &placeholder, const String &name, const String &path, Sequence *sequence);
virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &placeholder, const String &name);
virtual PathAttachment *newPathAttachment(Skin &skin, const String &placeholder, const String &name);
virtual PointAttachment *newPointAttachment(Skin &skin, const String &placeholder, const String &name);
virtual ClippingAttachment *newClippingAttachment(Skin &skin, const String &placeholder, const String &name);
AtlasRegion *findRegion(const String &name);
private:
Atlas *_atlas;
};
}
#endif /* Spine_AtlasAttachmentLoader_h */
@@ -0,0 +1,81 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Attachment_h
#define Spine_Attachment_h
#include <spine/Array.h>
#include <spine/RTTI.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
namespace spine {
class Slot;
/// The base class for all attachments. Multiple Skeleton instances, slots, or skins can use the same attachments.
class SP_API Attachment : public SpineObject {
RTTI_DECL_NOPARENT
public:
explicit Attachment(const String &name);
virtual ~Attachment();
const String &getName() const;
virtual Attachment &copy() = 0;
Attachment *getTimelineAttachment();
void setTimelineAttachment(Attachment *attachment);
Array<int> &getTimelineSlots();
void setTimelineSlots(Array<int> &timelineSlots);
/// Returns true if the slotIndex or any getTimelineSlots() have an attachment whose getTimelineAttachment() is this attachment.
/// @param slots The Skeleton::getSlots().
/// @param slotIndex The timeline's primary slot index.
bool isTimelineActive(Array<Slot *> &slots, int slotIndex, bool appliedPose);
int getRefCount();
void reference();
void dereference();
private:
const String _name;
Attachment *_timelineAttachment;
Array<int> _timelineSlots;
int _refCount;
};
}
#endif /* Spine_Attachment_h */
@@ -0,0 +1,82 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_AttachmentLoader_h
#define Spine_AttachmentLoader_h
#include <spine/RTTI.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
namespace spine {
class Skin;
class Attachment;
class RegionAttachment;
class MeshAttachment;
class BoundingBoxAttachment;
class PathAttachment;
class PointAttachment;
class ClippingAttachment;
class Sequence;
class SP_API AttachmentLoader : public SpineObject {
public:
AttachmentLoader();
virtual ~AttachmentLoader();
/// @return May be NULL to not load any attachment.
virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &placeholder, const String &name, const String &path,
Sequence *sequence) = 0;
/// @return May be NULL to not load any attachment.
virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &placeholder, const String &name, const String &path,
Sequence *sequence) = 0;
/// @return May be NULL to not load any attachment.
virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &placeholder, const String &name) = 0;
/// @return May be NULL to not load any attachment
virtual PathAttachment *newPathAttachment(Skin &skin, const String &placeholder, const String &name) = 0;
virtual PointAttachment *newPointAttachment(Skin &skin, const String &placeholder, const String &name) = 0;
virtual ClippingAttachment *newClippingAttachment(Skin &skin, const String &placeholder, const String &name) = 0;
};
}
#endif /* Spine_AttachmentLoader_h */
@@ -0,0 +1,88 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_AttachmentTimeline_h
#define Spine_AttachmentTimeline_h
#include <spine/Timeline.h>
#include <spine/SpineObject.h>
#include <spine/Array.h>
#include <spine/SpineString.h>
#include <spine/SlotTimeline.h>
namespace spine {
class Skeleton;
class Slot;
class SlotPose;
class Event;
class SP_API AttachmentTimeline : public Timeline, public SlotTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit AttachmentTimeline(size_t frameCount, int slotIndex);
virtual ~AttachmentTimeline();
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
/// Sets the time and attachment name for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
void setFrame(int frame, float time, const String &attachmentName);
/// The attachment name for each frame. May contain null values to clear the attachment.
Array<String> &getAttachmentNames();
virtual int getSlotIndex() override {
return _slotIndex;
}
virtual void setSlotIndex(int inValue) override {
_slotIndex = inValue;
}
protected:
int _slotIndex;
Array<String> _attachmentNames;
void setAttachment(Skeleton &skeleton, SlotPose &pose, String *attachmentName);
};
}
#endif /* Spine_AttachmentTimeline_h */
@@ -0,0 +1,66 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_AttachmentType_h
#define Spine_AttachmentType_h
#include <string.h>
namespace spine {
enum AttachmentType {
AttachmentType_Region,
AttachmentType_Boundingbox,
AttachmentType_Mesh,
AttachmentType_Linkedmesh,
AttachmentType_Path,
AttachmentType_Point,
AttachmentType_Clipping
};
inline AttachmentType AttachmentType_valueOf(const char *value) {
if (strcmp(value, "region") == 0)
return AttachmentType_Region;
else if (strcmp(value, "mesh") == 0)
return AttachmentType_Mesh;
else if (strcmp(value, "linkedmesh") == 0)
return AttachmentType_Linkedmesh;
else if (strcmp(value, "boundingbox") == 0)
return AttachmentType_Boundingbox;
else if (strcmp(value, "path") == 0)
return AttachmentType_Path;
else if (strcmp(value, "clipping") == 0)
return AttachmentType_Clipping;
else if (strcmp(value, "point") == 0)
return AttachmentType_Point;
else
return AttachmentType_Region;// default
}
}
#endif /* Spine_AttachmentType_h */
@@ -0,0 +1,57 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_BlendMode_h
#define Spine_BlendMode_h
#include <string.h>
namespace spine {
enum BlendMode {
BlendMode_Normal = 0,
BlendMode_Additive,
BlendMode_Multiply,
BlendMode_Screen
};
inline BlendMode BlendMode_valueOf(const char *value) {
if (strcmp(value, "normal") == 0)
return BlendMode_Normal;
else if (strcmp(value, "additive") == 0)
return BlendMode_Additive;
else if (strcmp(value, "multiply") == 0)
return BlendMode_Multiply;
else if (strcmp(value, "screen") == 0)
return BlendMode_Screen;
else
return BlendMode_Normal;// default
}
}
#endif /* Spine_BlendMode_h */
@@ -0,0 +1,114 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_BlockAllocator_h
#define Spine_BlockAllocator_h
#include <cstdint>
#include <spine/SpineObject.h>
#include <spine/Extension.h>
#include <spine/MathUtil.h>
#include <spine/Array.h>
namespace spine {
struct Block {
int size;
int allocated;
uint8_t *memory;
int free() {
return size - allocated;
}
bool canFit(int numBytes) {
return free() >= numBytes;
}
uint8_t *allocate(int numBytes) {
uint8_t *ptr = memory + allocated;
allocated += numBytes;
return ptr;
}
};
class BlockAllocator : public SpineObject {
int initialBlockSize;
Array<Block> blocks;
public:
BlockAllocator(int initialBlockSize) : initialBlockSize(initialBlockSize) {
blocks.add(newBlock(initialBlockSize));
}
~BlockAllocator() {
for (int i = 0, n = (int) blocks.size(); i < n; i++) {
SpineExtension::free(blocks[i].memory, __FILE__, __LINE__);
}
}
template<typename T>
T *allocate(size_t num) {
return (T *) _allocate((int) (sizeof(T) * num));
}
void compress() {
if (blocks.size() == 1) {
blocks[0].allocated = 0;
return;
}
int totalSize = 0;
for (int i = 0, n = (int) blocks.size(); i < n; i++) {
totalSize += blocks[i].size;
SpineExtension::free(blocks[i].memory, __FILE__, __LINE__);
}
blocks.clear();
blocks.add(newBlock(totalSize));
}
private:
void *_allocate(int numBytes) {
// 16-byte align allocations
int alignedNumBytes = numBytes + (numBytes % 16 != 0 ? 16 - (numBytes % 16) : 0);
Block *block = &blocks[blocks.size() - 1];
if (!block->canFit(alignedNumBytes)) {
blocks.add(newBlock(MathUtil::max(initialBlockSize, alignedNumBytes)));
block = &blocks[blocks.size() - 1];
}
return block->allocate(alignedNumBytes);
}
Block newBlock(int numBytes) {
Block block = {MathUtil::max(initialBlockSize, numBytes), 0, nullptr};
block.memory = SpineExtension::alloc<uint8_t>(block.size, __FILE__, __LINE__);
return block;
}
};
}
#endif
@@ -0,0 +1,111 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Bone_h
#define Spine_Bone_h
#include <spine/Posed.h>
#include <spine/PosedActive.h>
#include <spine/BoneData.h>
#include <spine/BonePose.h>
#include <spine/Array.h>
namespace spine {
/// A node in a skeleton's hierarchy with a transform that affects its children and their attachments. A bone has a number of
/// poses:
/// - getData(): The setup pose data.
/// - getPose(): The unconstrained local pose. Set by animations and application code.
/// - getAppliedPose(): The local pose to use for rendering. Possibly modified by constraints.
/// - World transform: the local pose combined with the parent world transform. Computed on a pose by
/// BonePose::updateWorldTransform(Skeleton) and Skeleton::updateWorldTransform(Physics).
class SP_API Bone : public PosedGeneric<BoneData, BonePose, BonePose>, public PosedActive, public Update {
friend class AnimationState;
friend class RotateTimeline;
friend class IkConstraint;
friend class TransformConstraint;
friend class VertexAttachment;
friend class PathConstraint;
friend class PhysicsConstraint;
friend class Skeleton;
friend class Slider;
friend class RegionAttachment;
friend class PointAttachment;
friend class AttachmentTimeline;
friend class RGBATimeline;
friend class RGBTimeline;
friend class AlphaTimeline;
friend class RGBA2Timeline;
friend class RGB2Timeline;
friend class ScaleTimeline;
friend class ScaleXTimeline;
friend class ScaleYTimeline;
friend class ShearTimeline;
friend class ShearXTimeline;
friend class ShearYTimeline;
friend class TranslateTimeline;
friend class TranslateXTimeline;
friend class TranslateYTimeline;
friend class InheritTimeline;
RTTI_DECL
public:
/// @param parent May be NULL.
Bone(BoneData &data, Bone *parent);
/// Copy constructor. Does not copy the child bones.
Bone(Bone &bone, Bone *parent);
/// The parent bone, or null if this is the root bone.
Bone *getParent();
/// The immediate children of this bone.
Array<Bone *> &getChildren();
static bool isYDown() {
return yDown;
}
static void setYDown(bool value) {
yDown = value;
}
virtual void update(Skeleton &skeleton, Physics physics) override {
// No-op, need to extend Update so we can stuff Bone into Skeleton.updateCache temporarily.
// See Skeleton::updateCache().
}
private:
static bool yDown;
Bone *const _parent;
Array<Bone *> _children;
bool _sorted;
};
}
#endif /* Spine_Bone_h */
@@ -0,0 +1,115 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_BoneData_h
#define Spine_BoneData_h
#include <spine/PosedData.h>
#include <spine/BonePose.h>
#include <spine/SpineString.h>
#include <spine/Color.h>
#include <spine/RTTI.h>
namespace spine {
class SP_API BoneData : public PosedDataGeneric<BonePose> {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class AnimationState;
friend class RotateTimeline;
friend class ScaleTimeline;
friend class ScaleXTimeline;
friend class ScaleYTimeline;
friend class ShearTimeline;
friend class ShearXTimeline;
friend class ShearYTimeline;
friend class TranslateTimeline;
friend class TranslateXTimeline;
friend class TranslateYTimeline;
friend class Slot;
public:
BoneData(int index, const String &name, BoneData *parent = NULL);
/// The Skeleton::getBones() index for this bone.
int getIndex();
/// The parent bone, or NULL if this bone is the root.
BoneData *getParent();
float getLength();
void setLength(float inValue);
Color &getColor();
/// The bone icon name as it was in Spine, or empty if nonessential data was not exported.
const String &getIcon();
void setIcon(const String &icon);
/// The bone icon's display size scale, or 1 if nonessential data was not exported.
float getIconSize();
void setIconSize(float iconSize);
/// The bone icon's display rotation in degrees, or 0 if nonessential data was not exported.
float getIconRotation();
void setIconRotation(float iconRotation);
bool getVisible();
void setVisible(bool inValue);
private:
const int _index;
BoneData *_parent;
float _length;
Color _color;
String _icon;
float _iconSize;
float _iconRotation;
bool _visible;
};
}
#endif /* Spine_BoneData_h */
@@ -0,0 +1,127 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef SPINE_BONELOCAL_H_
#define SPINE_BONELOCAL_H_
#include <spine/SpineObject.h>
#include <spine/RTTI.h>
#include <spine/Pose.h>
#include <spine/Inherit.h>
namespace spine {
/// Stores a bone's local pose.
class SP_API BoneLocal : public Pose<BoneLocal> {
friend class IkConstraint;
friend class BoneTimeline1;
friend class BoneTimeline2;
friend class RotateTimeline;
friend class InheritTimeline;
friend class ScaleTimeline;
friend class ScaleXTimeline;
friend class ScaleYTimeline;
friend class ShearTimeline;
friend class ShearXTimeline;
friend class ShearYTimeline;
friend class TranslateTimeline;
friend class TranslateXTimeline;
friend class TranslateYTimeline;
friend class SkeletonJson;
friend class SkeletonBinary;
friend class Skeleton;
friend class FromProperty;
friend class ToProperty;
friend class FromRotate;
friend class ToRotate;
friend class FromX;
friend class ToX;
friend class FromY;
friend class ToY;
friend class FromScaleX;
friend class ToScaleX;
friend class FromScaleY;
friend class ToScaleY;
friend class FromShearY;
friend class ToShearY;
friend class AnimationState;
protected:
float _x, _y, _rotation, _scaleX, _scaleY, _shearX, _shearY;
Inherit _inherit;
public:
BoneLocal();
virtual ~BoneLocal();
virtual void set(BoneLocal &pose) override;
/// The local x translation.
float getX();
void setX(float x);
/// The local y translation.
float getY();
void setY(float y);
/// Sets local x and y translation.
void setPosition(float x, float y);
/// The local rotation in degrees, counter clockwise.
float getRotation();
void setRotation(float rotation);
/// The local scaleX.
float getScaleX();
void setScaleX(float scaleX);
/// The local scaleY.
float getScaleY();
void setScaleY(float scaleY);
/// Sets local scaleX and scaleY.
void setScale(float scaleX, float scaleY);
/// Sets local scaleX and scaleY to the same value.
void setScale(float scale);
/// The local shearX.
float getShearX();
void setShearX(float shearX);
/// The local shearY.
float getShearY();
void setShearY(float shearY);
/// Determines how parent world transforms affect this bone.
Inherit getInherit();
void setInherit(Inherit inherit);
};
}
#endif /* SPINE_BONELOCAL_H_ */
@@ -0,0 +1,173 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef SPINE_BONEPOSE_H_
#define SPINE_BONEPOSE_H_
#include <spine/BoneLocal.h>
#include <spine/Update.h>
#include <spine/RTTI.h>
namespace spine {
class Bone;
class Skeleton;
/// The applied local pose and world transform for a bone. This is the bone's unconstrained pose with constraints applied and
/// the world transform computed by Skeleton::updateWorldTransform(Physics) and updateWorldTransform(Skeleton).
///
/// If the world transform is changed, call updateLocalTransform(Skeleton) before using the local transform. The local
/// transform may be needed by other code (eg to apply another constraint).
///
/// After changing the world transform, call updateWorldTransform(Skeleton) on every descendant bone. It may be more
/// convenient to modify the local transform instead, then call Skeleton::updateWorldTransform(Physics) to update the world
/// transforms for all bones and apply constraints.
class SP_API BonePose : public BoneLocal, public Update {
friend class IkConstraint;
friend class PathConstraint;
friend class PhysicsConstraint;
friend class TransformConstraint;
friend class TransformConstraintData;
friend class FromRotate;
friend class ToRotate;
friend class FromX;
friend class ToX;
friend class FromY;
friend class ToY;
friend class FromScaleX;
friend class ToScaleX;
friend class FromScaleY;
friend class ToScaleY;
friend class FromShearX;
friend class ToShearX;
friend class FromShearY;
friend class ToShearY;
friend class Skeleton;
friend class Bone;
RTTI_DECL
public:
BonePose();
virtual ~BonePose();
/// Called by Skeleton::updateCache() to compute the world transform, if needed.
virtual void update(Skeleton &skeleton, Physics physics) override;
/// Computes the world transform using the parent bone's world transform and this applied local pose. Child bones are not
/// updated.
///
/// See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
/// Runtimes Guide.
void updateWorldTransform(Skeleton &skeleton);
/// Computes the local transform values from the world transform.
///
/// Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The local transform after
/// calling this method is equivalent to the local transform used to compute the world transform, but may not be identical.
void updateLocalTransform(Skeleton &skeleton);
/// If the world transform has been modified by constraints and the local transform no longer matches,
/// updateLocalTransform() is called. Call this after Skeleton::updateWorldTransform(Physics) before using the applied
/// local transform.
void validateLocalTransform(Skeleton &skeleton);
void modifyLocal(Skeleton &skeleton);
void modifyWorld(Skeleton &skeleton);
/// The world transform <code>[a b][c d]</code> x-axis x component.
float getA();
void setA(float a);
/// The world transform <code>[a b][c d]</code> y-axis x component.
float getB();
void setB(float b);
/// The world transform <code>[a b][c d]</code> x-axis y component.
float getC();
void setC(float c);
/// The world transform <code>[a b][c d]</code> y-axis y component.
float getD();
void setD(float d);
/// The world X position.
float getWorldX();
void setWorldX(float worldX);
/// The world Y position.
float getWorldY();
void setWorldY(float worldY);
/// The world rotation for the X axis, calculated using a and c. This is the direction the bone is pointing.
float getWorldRotationX();
/// The world rotation for the Y axis, calculated using b and d.
float getWorldRotationY();
/// The magnitude (always positive) of the world scale X, calculated using a and c.
float getWorldScaleX();
/// The magnitude (always positive) of the world scale Y, calculated using b and d.
float getWorldScaleY();
/// Transforms a point from world coordinates to the bone's local coordinates.
void worldToLocal(float worldX, float worldY, float &outLocalX, float &outLocalY);
/// Transforms a point from the bone's local coordinates to world coordinates.
void localToWorld(float localX, float localY, float &outWorldX, float &outWorldY);
/// Transforms a point from world coordinates to the parent bone's local coordinates.
void worldToParent(float worldX, float worldY, float &outParentX, float &outParentY);
/// Transforms a point from the parent bone's coordinates to world coordinates.
void parentToWorld(float parentX, float parentY, float &outWorldX, float &outWorldY);
/// Transforms a world rotation to a local rotation.
float worldToLocalRotation(float worldRotation);
/// Transforms a local rotation to a world rotation.
float localToWorldRotation(float localRotation);
/// Rotates the world transform the specified amount.
void rotateWorld(float degrees);
private:
void setLocal(float ra, float rb, float rc, float rd);
void setLocal(float ra, float rb, float rc, float rd, float ro);
void resetWorld(Skeleton &skeleton, int update);
protected:
Bone *_bone;
float _a, _b, _worldX;
float _c, _d, _worldY;
int _world, _local;
};
}// namespace spine
#endif /* SPINE_BONEPOSE_H_ */
@@ -0,0 +1,123 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_BoneTimeline_h
#define Spine_BoneTimeline_h
#include <cstddef>
#include <spine/dll.h>
#include <spine/CurveTimeline.h>
namespace spine {
class Skeleton;
class Event;
class BonePose;
/// An interface for timelines which change the property of a bone.
class SP_API BoneTimeline {
RTTI_DECL_NOPARENT
public:
BoneTimeline(int boneIndex) {
}
virtual ~BoneTimeline() {
}
/// The Skeleton::getBones() index of the bone that will be changed when this timeline is applied.
virtual int getBoneIndex() const = 0;
virtual void setBoneIndex(int inValue) = 0;
};
/// Base class for timelines that animate a single bone property.
class SP_API BoneTimeline1 : public CurveTimeline1, public BoneTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class AnimationState;
RTTI_DECL
public:
BoneTimeline1(size_t frameCount, size_t bezierCount, int boneIndex, Property property);
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
virtual int getBoneIndex() const override {
return _boneIndex;
}
virtual void setBoneIndex(int inValue) override {
_boneIndex = inValue;
}
protected:
/// Applies changes to the pose based on the timeline values.
virtual void _apply(BonePose &pose, BonePose &setup, float time, float alpha, MixFrom from, bool add, bool out) = 0;
int _boneIndex;
};
/// Base class for timelines that animate two bone properties.
class SP_API BoneTimeline2 : public CurveTimeline, public BoneTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class AnimationState;
RTTI_DECL
public:
BoneTimeline2(size_t frameCount, size_t bezierCount, int boneIndex, Property property1, Property property2);
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
virtual int getBoneIndex() const override {
return _boneIndex;
}
virtual void setBoneIndex(int inValue) override {
_boneIndex = inValue;
}
virtual void setFrame(size_t frame, float time, float value1, float value2);
protected:
/// Applies changes to the pose based on the timeline values.
virtual void _apply(BonePose &pose, BonePose &setup, float time, float alpha, MixFrom from, bool add, bool out) = 0;
int _boneIndex;
static const int ENTRIES;
static const int VALUE1;
static const int VALUE2;
};
}
#endif
@@ -0,0 +1,54 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_BoundingBoxAttachment_h
#define Spine_BoundingBoxAttachment_h
#include <spine/VertexAttachment.h>
#include <spine/Color.h>
#include <spine/SpineObject.h>
namespace spine {
/// Attachment that has a polygon for bounds checking.
class SP_API BoundingBoxAttachment : public VertexAttachment {
RTTI_DECL
public:
explicit BoundingBoxAttachment(const String &name);
Color &getColor();
virtual Attachment &copy() override;
private:
Color _color;
};
}
#endif /* Spine_BoundingBoxAttachment_h */
@@ -0,0 +1,82 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_ClippingAttachment_h
#define Spine_ClippingAttachment_h
#include <spine/VertexAttachment.h>
#include <spine/Color.h>
namespace spine {
class SlotData;
class SP_API ClippingAttachment : public VertexAttachment {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class SkeletonClipping;
RTTI_DECL
public:
explicit ClippingAttachment(const String &name);
/// 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.
SlotData *getEndSlot();
void setEndSlot(SlotData *inValue);
/// 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.
bool getConvex();
void setConvex(bool convex);
/// When false, everything inside the clipping polygon is visible. When true, everything outside the clipping polygon is
/// visible and clipping is convex.
bool getInverse();
void setInverse(bool inverse);
Color &getColor();
virtual Attachment &copy() override;
private:
SlotData *_endSlot;
bool _convex;
bool _inverse;
Color _color;
};
}
#endif /* Spine_ClippingAttachment_h */
@@ -0,0 +1,156 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef SPINE_COLOR_H
#define SPINE_COLOR_H
#include <spine/MathUtil.h>
#include <string.h>
#include <stdlib.h>
namespace spine {
class SP_API Color : public SpineObject {
public:
Color() : r(0), g(0), b(0), a(0) {
}
Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {
clamp();
}
inline Color &set(float _r, float _g, float _b, float _a) {
this->r = _r;
this->g = _g;
this->b = _b;
this->a = _a;
clamp();
return *this;
}
inline Color &set(float _r, float _g, float _b) {
this->r = _r;
this->g = _g;
this->b = _b;
clamp();
return *this;
}
inline Color &set(const Color &other) {
r = other.r;
g = other.g;
b = other.b;
a = other.a;
clamp();
return *this;
}
inline Color &add(float _r, float _g, float _b, float _a) {
this->r += _r;
this->g += _g;
this->b += _b;
this->a += _a;
clamp();
return *this;
}
inline Color &add(float _r, float _g, float _b) {
this->r += _r;
this->g += _g;
this->b += _b;
clamp();
return *this;
}
inline Color &add(const Color &other) {
r += other.r;
g += other.g;
b += other.b;
a += other.a;
clamp();
return *this;
}
inline Color &clamp() {
r = MathUtil::clamp(this->r, 0, 1);
g = MathUtil::clamp(this->g, 0, 1);
b = MathUtil::clamp(this->b, 0, 1);
a = MathUtil::clamp(this->a, 0, 1);
return *this;
}
// Parse hex color string like "ff0000ff" (RRGGBBAA) or "ff0000" (RRGGBB)
static Color valueOf(const char *hexString) {
Color color;
valueOf(hexString, color);
return color;
}
// Parse hex color string into existing Color object
static void valueOf(const char *hexString, Color &color) {
size_t len = strlen(hexString);
if (len >= 6) {
color.r = parseHex(hexString, 0);
color.g = parseHex(hexString, 1);
color.b = parseHex(hexString, 2);
color.a = len >= 8 ? parseHex(hexString, 3) : 1.0f;
}
}
static float parseHex(const char *value, size_t index) {
char digits[3];
digits[0] = value[index * 2];
digits[1] = value[index * 2 + 1];
digits[2] = '\0';
return strtoul(digits, NULL, 16) / 255.0f;
}
// Convert packed RGBA8888 integer to Color
static void rgba8888ToColor(Color &color, int value) {
unsigned int rgba = (unsigned int) value;
color.r = ((rgba & 0xff000000) >> 24) / 255.0f;
color.g = ((rgba & 0x00ff0000) >> 16) / 255.0f;
color.b = ((rgba & 0x0000ff00) >> 8) / 255.0f;
color.a = (rgba & 0x000000ff) / 255.0f;
}
// Convert packed RGB888 integer to Color (no alpha)
static void rgb888ToColor(Color &color, int value) {
unsigned int rgb = (unsigned int) value;
color.r = ((rgb & 0xff0000) >> 16) / 255.0f;
color.g = ((rgb & 0x00ff00) >> 8) / 255.0f;
color.b = (rgb & 0x0000ff) / 255.0f;
color.a = 1.0f;
}
float r, g, b, a;
};
}
#endif//SPINE_COLOR_H
@@ -0,0 +1,177 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_ColorTimeline_h
#define Spine_ColorTimeline_h
#include <spine/SlotCurveTimeline.h>
#include <spine/SlotTimeline.h>
namespace spine {
/// Changes a slot's color.
class SP_API RGBATimeline : public SlotCurveTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit RGBATimeline(size_t frameCount, size_t bezierCount, int slotIndex);
virtual ~RGBATimeline();
/// Sets the time and color for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
void setFrame(int frame, float time, float r, float g, float b, float a);
protected:
virtual void _apply(Slot &slot, SlotPose &pose, float time, float alpha, MixFrom from, bool add) override;
static const int ENTRIES = 5;
static const int R = 1;
static const int G = 2;
static const int B = 3;
static const int A = 4;
};
/// Changes RGB for a slot's color.
class SP_API RGBTimeline : public SlotCurveTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit RGBTimeline(size_t frameCount, size_t bezierCount, int slotIndex);
virtual ~RGBTimeline();
/// Sets the time and color for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
void setFrame(int frame, float time, float r, float g, float b);
protected:
virtual void _apply(Slot &slot, SlotPose &pose, float time, float alpha, MixFrom from, bool add) override;
static const int ENTRIES = 4;
static const int R = 1;
static const int G = 2;
static const int B = 3;
};
class SP_API AlphaTimeline : public CurveTimeline1, public SlotTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit AlphaTimeline(size_t frameCount, size_t bezierCount, int slotIndex);
virtual ~AlphaTimeline();
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
virtual int getSlotIndex() override;
virtual void setSlotIndex(int inValue) override;
protected:
int _slotIndex;
};
/// Changes a slot's light and dark colors for two color tinting.
class SP_API RGBA2Timeline : public SlotCurveTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit RGBA2Timeline(size_t frameCount, size_t bezierCount, int slotIndex);
virtual ~RGBA2Timeline();
/// Sets the time, light color, and dark color for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
void setFrame(int frame, float time, float r, float g, float b, float a, float r2, float g2, float b2);
protected:
virtual void _apply(Slot &slot, SlotPose &pose, float time, float alpha, MixFrom from, bool add) override;
static const int ENTRIES = 8;
static const int R = 1;
static const int G = 2;
static const int B = 3;
static const int A = 4;
static const int R2 = 5;
static const int G2 = 6;
static const int B2 = 7;
};
/// Changes RGB for a slot's light and dark colors for two color tinting.
class SP_API RGB2Timeline : public SlotCurveTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit RGB2Timeline(size_t frameCount, size_t bezierCount, int slotIndex);
virtual ~RGB2Timeline();
/// Sets the time, light color, and dark color for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
void setFrame(int frame, float time, float r, float g, float b, float r2, float g2, float b2);
protected:
virtual void _apply(Slot &slot, SlotPose &pose, float time, float alpha, MixFrom from, bool add) override;
static const int ENTRIES = 7;
static const int R = 1;
static const int G = 2;
static const int B = 3;
static const int R2 = 4;
static const int G2 = 5;
static const int B2 = 6;
};
}
#endif /* Spine_ColorTimeline_h */
@@ -0,0 +1,92 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Constraint_h
#define Spine_Constraint_h
#include <spine/Posed.h>
#include <spine/PosedActive.h>
#include <spine/Update.h>
#include <spine/RTTI.h>
#include <spine/ConstraintData.h>
namespace spine {
class Skeleton;
class SP_API Constraint : public Update {
friend class Skeleton;
public:
RTTI_DECL
Constraint();
virtual ~Constraint();
virtual ConstraintData &getData() = 0;
virtual void sort(Skeleton &skeleton) = 0;
virtual bool isSourceActive() = 0;
// Inherited from Update
virtual void update(Skeleton &skeleton, Physics physics) override = 0;
protected:
virtual void unconstrained() = 0;
virtual void setupPose() = 0;
bool _active;
};
template<class T, class D, class P>
class ConstraintGeneric : public PosedGeneric<D, P, P>, public PosedActive, public Constraint {
public:
ConstraintGeneric(D &data) : PosedGeneric<D, P, P>(data), PosedActive(), Constraint() {
}
virtual ~ConstraintGeneric() {
}
virtual D &getData() override {
return PosedGeneric<D, P, P>::getData();
}
protected:
virtual void unconstrained() override {
PosedGeneric<D, P, P>::unconstrained();
}
virtual void setupPose() override {
PosedGeneric<D, P, P>::setupPose();
}
};
}// namespace spine
#endif /* Spine_Constraint_h */
@@ -0,0 +1,108 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_ConstraintData_h
#define Spine_ConstraintData_h
#include <spine/SpineString.h>
#include <spine/SpineObject.h>
#include <spine/PosedData.h>
#include <spine/RTTI.h>
#include <string.h>
namespace spine {
class Skeleton;
class Constraint;
enum ScaleYMode {
ScaleYMode_None = 0,
ScaleYMode_Uniform,
ScaleYMode_Volume
};
inline ScaleYMode ScaleYMode_valueOf(const char *value) {
if (strcmp(value, "uniform") == 0)
return ScaleYMode_Uniform;
else if (strcmp(value, "volume") == 0)
return ScaleYMode_Volume;
else
return ScaleYMode_None;
}
inline const char *ScaleYMode_toString(ScaleYMode scaleYMode) {
switch (scaleYMode) {
case ScaleYMode_Uniform:
return "uniform";
case ScaleYMode_Volume:
return "volume";
default:
return "none";
}
}
class SP_API ConstraintData : public SpineObject {
RTTI_DECL_NOPARENT
friend class Skeleton;
friend class Constraint;
public:
ConstraintData(const String &name) : SpineObject(name) {
}
virtual ~ConstraintData() {
}
virtual Constraint &create(Skeleton &skeleton) = 0;
virtual const String &getName() const = 0;
virtual bool getSkinRequired() const = 0;
};
/// Base class for all constraint data types.
template<class T, class P>
class ConstraintDataGeneric : public PosedDataGeneric<P>, public ConstraintData {
public:
ConstraintDataGeneric(const String &name) : PosedDataGeneric<P>(name), ConstraintData(name) {
}
virtual ~ConstraintDataGeneric() {
}
virtual Constraint &create(Skeleton &skeleton) override = 0;
// Resolve ambiguity by forwarding to PosedData's implementation
virtual const String &getName() const override {
return PosedDataGeneric<P>::getName();
}
virtual bool getSkinRequired() const override {
return PosedDataGeneric<P>::getSkinRequired();
}
};
}
#endif /* Spine_ConstraintData_h */
@@ -0,0 +1,52 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_ConstraintTimeline_h
#define Spine_ConstraintTimeline_h
#include <spine/dll.h>
#include <spine/RTTI.h>
namespace spine {
/// An interface for timelines which change the property of a constraint.
class SP_API ConstraintTimeline {
RTTI_DECL_NOPARENT
public:
ConstraintTimeline();
virtual ~ConstraintTimeline();
/// The Skeleton::getConstraints() index of the constraint that will be changed when this timeline is applied.
virtual int getConstraintIndex() const = 0;
virtual void setConstraintIndex(int inValue) = 0;
};
}
#endif
@@ -0,0 +1,59 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated July 28, 2023. Replaces all prior versions.
*
* Copyright (c) 2013-2023, 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.
*****************************************************************************/
#ifndef Spine_ConstraintTimeline1_h
#define Spine_ConstraintTimeline1_h
#include <spine/ConstraintTimeline.h>
#include <spine/CurveTimeline.h>
#include <spine/Property.h>
namespace spine {
/// The base class for timelines that change 1 constraint property with a curve.
class SP_API ConstraintTimeline1 : public CurveTimeline1, public ConstraintTimeline {
RTTI_DECL
public:
ConstraintTimeline1(size_t frameCount, size_t bezierCount, int constraintIndex, Property property);
virtual ~ConstraintTimeline1();
virtual int getConstraintIndex() const override {
return _constraintIndex;
}
virtual void setConstraintIndex(int inValue) override {
_constraintIndex = inValue;
}
protected:
int _constraintIndex;
};
}// namespace spine
#endif /* Spine_ConstraintTimeline1_h */
@@ -0,0 +1,101 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_CurveTimeline_h
#define Spine_CurveTimeline_h
#include <spine/Timeline.h>
#include <spine/Array.h>
namespace spine {
/// Base class for frames that use an interpolation bezier curve.
class SP_API CurveTimeline : public Timeline {
RTTI_DECL
public:
explicit CurveTimeline(size_t frameCount, size_t frameEntries, size_t bezierCount);
virtual ~CurveTimeline();
void setLinear(size_t frame);
void setStepped(size_t frame);
virtual void setBezier(size_t bezier, size_t frame, float value, float time1, float value1, float cx1, float cy1, float cx2, float cy2,
float time2, float value2);
float getBezierValue(float time, size_t frame, size_t valueOffset, size_t i);
Array<float> &getCurves();
protected:
static const int LINEAR = 0;
static const int STEPPED = 1;
static const int BEZIER = 2;
static const int BEZIER_SIZE = 18;
Array<float> _curves;// type, x, y, ...
};
/// The base class for a CurveTimeline that sets one property.
class SP_API CurveTimeline1 : public CurveTimeline {
RTTI_DECL
public:
/// @param frameCount The number of frames for this timeline.
/// @param bezierCount The maximum number of Bezier curves.
explicit CurveTimeline1(size_t frameCount, size_t bezierCount);
virtual ~CurveTimeline1();
/// Sets the time and value for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
void setFrame(size_t frame, float time, float value);
/// Returns the interpolated value for the specified time.
float getCurveValue(float time);
float getRelativeValue(float time, float alpha, MixFrom from, bool add, float current, float setup);
float getAbsoluteValue(float time, float alpha, MixFrom from, bool add, float current, float setup);
float getAbsoluteValue(float time, float alpha, MixFrom from, bool add, float current, float setup, float value);
float getScaleValue(float time, float alpha, MixFrom from, bool add, bool out, float current, float setup);
static float beforeFirstKey(MixFrom from, float alpha, float current, float setup);
protected:
static const int ENTRIES = 2;
static const int VALUE = 1;
};
}
#endif /* Spine_CurveTimeline_h */
@@ -0,0 +1,368 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef SPINE_LOG_H
#define SPINE_LOG_H
#include <spine/Extension.h>
#include <spine/Array.h>
#ifndef SPINE_NO_CPP_RT
#include <unordered_map>
#endif
namespace spine {
#ifdef SPINE_NO_CPP_RT
// Need a copy as HashMap extends SpineObject, which would trigger
// infinite recursion when used in DebugExtension
template<typename K, typename V>
class DebugHashMap {
private:
class DebugEntry;
public:
class SP_API DebugPair {
public:
explicit DebugPair(K &k, V &v) : key(k), value(v) {
}
K &key;
V &value;
};
class SP_API DebugEntries {
public:
friend class DebugHashMap;
explicit DebugEntries(DebugEntry *entry) : _hasChecked(false) {
_start.next = entry;
_entry = &_start;
}
DebugPair next() {
assert(_entry);
assert(_hasChecked);
_entry = _entry->next;
DebugPair pair(_entry->_key, _entry->_value);
_hasChecked = false;
return pair;
}
bool hasNext() {
_hasChecked = true;
return _entry->next;
}
private:
bool _hasChecked;
DebugEntry _start;
DebugEntry *_entry;
};
DebugHashMap() : _head(NULL), _size(0) {
}
~DebugHashMap() {
clear();
}
void clear() {
for (DebugEntry *entry = _head; entry != NULL;) {
DebugEntry *next = entry->next;
delete entry;
entry = next;
}
_head = NULL;
_size = 0;
}
size_t size() {
return _size;
}
void put(const K &key, const V &value) {
DebugEntry *entry = find(key);
if (entry) {
entry->_key = key;
entry->_value = value;
} else {
entry = new DebugEntry();
entry->_key = key;
entry->_value = value;
DebugEntry *oldHead = _head;
if (oldHead) {
_head = entry;
oldHead->prev = entry;
entry->next = oldHead;
} else {
_head = entry;
}
_size++;
}
}
bool addAll(Array<K> &keys, const V &value) {
size_t oldSize = _size;
for (size_t i = 0; i < keys.size(); i++) {
put(keys[i], value);
}
return _size != oldSize;
}
bool containsKey(const K &key) {
return find(key) != NULL;
}
bool remove(const K &key) {
DebugEntry *entry = find(key);
if (!entry) return false;
DebugEntry *prev = entry->prev;
DebugEntry *next = entry->next;
if (prev)
prev->next = next;
else
_head = next;
if (next) next->prev = entry->prev;
delete entry;
_size--;
return true;
}
V operator[](const K &key) {
DebugEntry *entry = find(key);
if (entry)
return entry->_value;
else {
assert(false);
return 0;
}
}
DebugEntries getEntries() const {
return DebugEntries(_head);
}
private:
DebugEntry *find(const K &key) {
for (DebugEntry *entry = _head; entry != NULL; entry = entry->next) {
if (entry->_key == key) return entry;
}
return NULL;
}
class SP_API DebugEntry {
public:
K _key;
V _value;
DebugEntry *next;
DebugEntry *prev;
DebugEntry() : next(NULL), prev(NULL) {
}
};
DebugEntry *_head;
size_t _size;
};
#endif// SPINE_NO_CPP_RT
class SP_API DebugExtension : public SpineExtension {
struct Allocation {
void *address;
size_t size;
const char *fileName;
int line;
Allocation() : address(NULL), size(0), fileName(NULL), line(0) {
}
Allocation(void *a, size_t s, const char *f, int l) : address(a), size(s), fileName(f), line(l) {
}
};
public:
DebugExtension(SpineExtension *extension) : _extension(extension), _allocations(0), _reallocations(0), _frees(0) {
}
void reportLeaks() {
#ifdef SPINE_NO_CPP_RT
DebugHashMap<void *, Allocation>::DebugEntries entries = _allocated.getEntries();
while (entries.hasNext()) {
DebugHashMap<void *, Allocation>::DebugPair pair = entries.next();
printf("\"%s:%i (%zu bytes at %p)\n", pair.value.fileName, pair.value.line, pair.value.size, pair.value.address);
}
#else
for (const auto &pair : _allocated) {
printf("\"%s:%i (%zu bytes at %p)\n", pair.second.fileName, pair.second.line, pair.second.size, pair.second.address);
}
#endif
printf("allocations: %zu, reallocations: %zu, frees: %zu\n", _allocations, _reallocations, _frees);
if (_allocated.size() == 0) printf("No leaks detected\n");
}
void clearAllocations() {
_allocated.clear();
_usedMemory = 0;
}
virtual void *_alloc(size_t size, const char *file, int line) {
void *result = _extension->_alloc(size, file, line);
#ifdef SPINE_NO_CPP_RT
_allocated.put(result, Allocation(result, size, file, line));
#else
_allocated[result] = Allocation(result, size, file, line);
#endif
_allocations++;
_usedMemory += size;
return result;
}
virtual void *_calloc(size_t size, const char *file, int line) {
void *result = _extension->_calloc(size, file, line);
#ifdef SPINE_NO_CPP_RT
_allocated.put(result, Allocation(result, size, file, line));
#else
_allocated[result] = Allocation(result, size, file, line);
#endif
_allocations++;
_usedMemory += size;
return result;
}
virtual void *_realloc(void *ptr, size_t size, const char *file, int line) {
#ifdef SPINE_NO_CPP_RT
if (_allocated.containsKey(ptr)) {
// Find and store the size before removing
DebugHashMap<void *, Allocation>::DebugEntries entries = _allocated.getEntries();
while (entries.hasNext()) {
DebugHashMap<void *, Allocation>::DebugPair pair = entries.next();
if (pair.key == ptr) {
_usedMemory -= pair.value.size;
break;
}
}
_allocated.remove(ptr);
}
#else
auto it = _allocated.find(ptr);
if (it != _allocated.end()) {
_usedMemory -= it->second.size;
_allocated.erase(it);
}
#endif
void *result = _extension->_realloc(ptr, size, file, line);
_reallocations++;
#ifdef SPINE_NO_CPP_RT
_allocated.put(result, Allocation(result, size, file, line));
#else
_allocated[result] = Allocation(result, size, file, line);
#endif
_usedMemory += size;
return result;
}
virtual void _free(void *mem, const char *file, int line) {
#ifdef SPINE_NO_CPP_RT
if (_allocated.containsKey(mem)) {
_extension->_free(mem, file, line);
_frees++;
// Find and store the size before removing
DebugHashMap<void *, Allocation>::DebugEntries entries = _allocated.getEntries();
while (entries.hasNext()) {
DebugHashMap<void *, Allocation>::DebugPair pair = entries.next();
if (pair.key == mem) {
_usedMemory -= pair.value.size;
break;
}
}
_allocated.remove(mem);
return;
}
#else
auto it = _allocated.find(mem);
if (it != _allocated.end()) {
_extension->_free(mem, file, line);
_frees++;
_usedMemory -= it->second.size;
_allocated.erase(it);
return;
}
#endif
printf("%s:%i (address %p): Double free or not allocated through SpineExtension\n", file, line, mem);
_extension->_free(mem, file, line);
}
virtual char *_readFile(const String &path, int *length) {
auto data = _extension->_readFile(path, length);
#ifdef SPINE_NO_CPP_RT
if (!_allocated.containsKey(data)) {
_allocated.put(data, Allocation(data, sizeof(char) * (*length), nullptr, 0));
_allocations++;
_usedMemory += sizeof(char) * (*length);
}
#else
if (_allocated.find(data) == _allocated.end()) {
_allocated[data] = Allocation(data, sizeof(char) * (*length), nullptr, 0);
_allocations++;
_usedMemory += sizeof(char) * (*length);
}
#endif
return data;
}
size_t getUsedMemory() {
return _usedMemory;
}
private:
SpineExtension *_extension;
#ifdef SPINE_NO_CPP_RT
DebugHashMap<void *, Allocation> _allocated;
#else
std::unordered_map<void *, Allocation> _allocated;
#endif
size_t _allocations;
size_t _reallocations;
size_t _frees;
size_t _usedMemory;
};
}
#endif//SPINE_LOG_H
@@ -0,0 +1,87 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_DeformTimeline_h
#define Spine_DeformTimeline_h
#include <spine/SlotCurveTimeline.h>
namespace spine {
class VertexAttachment;
/// Changes a slot's deform to deform a VertexAttachment.
class SP_API DeformTimeline : public SlotCurveTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit DeformTimeline(size_t frameCount, size_t bezierCount, int slotIndex, VertexAttachment &attachment);
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
/// Sets the time and vertices for the specified frame.
void setFrame(int frameIndex, float time, Array<float> &vertices);
/// The vertices for each frame.
Array<Array<float>> &getVertices();
/// The attachment whose vertices will be deformed.
VertexAttachment &getAttachment();
void setAttachment(VertexAttachment &inValue);
virtual void setBezier(size_t bezier, size_t frame, float value, float time1, float value1, float cx1, float cy1, float cx2, float cy2,
float time2, float value2) override;
float getCurvePercent(float time, int frame);
size_t getFrameCount() {
return _frames.size();
}
protected:
void _apply(Slot &slot, SlotPose &pose, float time, float alpha, MixFrom from, bool add) override;
private:
void applyBeforeFirst(Slot &slot, bool appliedPose, float alpha, MixFrom from);
void applyToPose(SlotPose &pose, Array<float> &v1, Array<float> *v2, float percent, size_t vertexCount, float alpha, MixFrom from, bool add);
void applyToSlot(Slot &slot, bool appliedPose, Array<float> &v1, Array<float> *v2, float percent, size_t vertexCount, float alpha,
MixFrom from, bool add);
Array<Array<float>> _vertices;
VertexAttachment *_attachment;
};
}
#endif /* Spine_DeformTimeline_h */
@@ -0,0 +1,79 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_DrawOrder_h
#define Spine_DrawOrder_h
#include <spine/Array.h>
#include <spine/SpineObject.h>
namespace spine {
class Slot;
/// Stores the skeleton's draw order, which is the order that each slot's attachment is rendered.
class SP_API DrawOrder : public SpineObject {
friend class Skeleton;
friend class DrawOrderTimeline;
friend class DrawOrderFolderTimeline;
friend class Slider;
public:
explicit DrawOrder(Array<Slot *> &setupPose);
/// Sets the unconstrained draw order to the setup pose order.
void setupPose();
/// The unconstrained draw order, set by animations and application code.
Array<Slot *> &getPose();
/// The constrained draw order for rendering. If no constraints modify the draw order, this is the same as getPose().
/// Otherwise it is a copy of getPose() modified by constraints.
Array<Slot *> &getAppliedPose();
private:
/// Sets the applied pose to the unconstrained pose, for when no constraints will modify the draw order.
void unconstrained();
/// Sets the applied pose to the constrained pose, in anticipation of the applied pose being modified by constraints.
void constrained();
/// Copies the unconstrained pose to the constrained pose, as a starting point for constraints to be applied.
void reset();
Array<Slot *> &_setupPose;
Array<Slot *> _pose;
Array<Slot *> _constrainedPose;
Array<Slot *> *_appliedPose;
};
}
#endif /* Spine_DrawOrder_h */
@@ -0,0 +1,76 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_DrawOrderFolderTimeline_h
#define Spine_DrawOrderFolderTimeline_h
#include <spine/Timeline.h>
namespace spine {
class Slot;
/// Changes a subset of the Skeleton::getDrawOrder() draw order.
class SP_API DrawOrderFolderTimeline : public Timeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
DrawOrderFolderTimeline(size_t frameCount, Array<int> &slots, size_t slotCount);
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
size_t getFrameCount();
/// The Skeleton::getSlots() indices that this timeline affects, in setup order.
Array<int> &getSlots();
/// The draw order for each frame. See setFrame().
Array<Array<int>> &getDrawOrders();
/// Sets the time and draw order for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
/// @param drawOrder Ordered getSlots() indices, or null to use setup pose order.
void setFrame(size_t frame, float time, Array<int> *drawOrder);
private:
Array<int> _slots;
Array<bool> _inFolder;
Array<Array<int>> _drawOrders;
void setup(Array<Slot *> &pose, Array<Slot *> &setupPose);
void apply(Array<Slot *> &pose, Array<Slot *> &setupPose, Array<int> &drawOrder);
};
}
#endif /* Spine_DrawOrderFolderTimeline_h */
@@ -0,0 +1,69 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_DrawOrderTimeline_h
#define Spine_DrawOrderTimeline_h
#include <spine/Timeline.h>
namespace spine {
/// Changes the Skeleton::getDrawOrder().
class SP_API DrawOrderTimeline : public Timeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
static PropertyId getPropertyId();
explicit DrawOrderTimeline(size_t frameCount);
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
size_t getFrameCount();
/// The draw order for each frame. See setFrame().
Array<Array<int>> &getDrawOrders();
/// Sets the time and draw order for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
/// @param drawOrder For each slot in Skeleton::getSlots(), the index of the slot in the new draw order. May be null to use
/// setup pose draw order.
void setFrame(size_t frame, float time, Array<int> *drawOrder);
private:
Array<Array<int>> _drawOrders;
};
}
#endif /* Spine_DrawOrderTimeline_h */
@@ -0,0 +1,95 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Event_h
#define Spine_Event_h
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
namespace spine {
class EventData;
/// Fired by EventTimeline when specific animation times are reached.
///
/// See Timeline::apply(), AnimationStateListener::event(), and
/// https://esotericsoftware.com/spine-events Events in the Spine User Guide.
class SP_API Event : public SpineObject {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class AnimationState;
public:
Event(float time, const EventData &data);
/// The event's setup pose data.
const EventData &getData();
/// The animation time this event was keyed, or -1 for the setup pose.
float getTime();
/// The integer payload for this event.
int getInt();
void setInt(int inValue);
/// The float payload for this event.
float getFloat();
void setFloat(float inValue);
/// The string payload for this event.
const String &getString();
void setString(const String &inValue);
/// If an audio path is set, the volume for the audio.
float getVolume();
void setVolume(float inValue);
/// If an audio path is set, the left/right balance for the audio.
float getBalance();
void setBalance(float inValue);
private:
const EventData &_data;
const float _time;
int _intValue;
float _floatValue;
String _stringValue;
float _volume;
float _balance;
};
}
#endif /* Spine_Event_h */
@@ -0,0 +1,68 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_EventData_h
#define Spine_EventData_h
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <spine/Event.h>
namespace spine {
/// Stores the setup pose values for an Event.
class SP_API EventData : public SpineObject {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class Event;
public:
explicit EventData(const String &name);
/// The name of the event, unique across all events in the skeleton.
const String &getName() const;
/// The setup values that are shared by all events with this data.
Event &getSetupPose();
const Event &getSetupPose() const;
/// Path to an audio file relative to the audio folder as defined in Spine.
const String &getAudioPath() const;
void setAudioPath(const String &inValue);
private:
const String _name;
String _audioPath;
Event _setupPose;
};
}
#endif /* Spine_EventData_h */
@@ -0,0 +1,67 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_EventTimeline_h
#define Spine_EventTimeline_h
#include <spine/Timeline.h>
namespace spine {
/// Fires an Event when specific animation times are reached.
class SP_API EventTimeline : public Timeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit EventTimeline(size_t frameCount);
~EventTimeline();
/// Fires events for frames > lastTime and <= time.
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
size_t getFrameCount();
/// The event for each frame.
Array<Event *> &getEvents();
/// Sets the time and event for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
void setFrame(size_t frame, Event &event);
private:
Array<Event *> _events;
};
}
#endif /* Spine_EventTimeline_h */
@@ -0,0 +1,136 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Extension_h
#define Spine_Extension_h
#include <stdlib.h>
#include <string.h>
#include <spine/dll.h>
#define SP_UNUSED(x) (void) (x)
namespace spine {
class String;
class SP_API SpineExtension {
public:
template<typename T>
static T *alloc(size_t num, const char *file, int line) {
return (T *) getInstance()->_alloc(sizeof(T) * num, file, line);
}
template<typename T>
static T *calloc(size_t num, const char *file, int line) {
return (T *) getInstance()->_calloc(sizeof(T) * num, file, line);
}
template<typename T>
static T *realloc(T *ptr, size_t num, const char *file, int line) {
return (T *) getInstance()->_realloc(ptr, sizeof(T) * num, file, line);
}
template<typename T>
static void free(T *ptr, const char *file, int line) {
getInstance()->_free((void *) ptr, file, line);
}
template<typename T>
static void beforeFree(T *ptr) {
getInstance()->_beforeFree((void *) ptr);
}
static char *readFile(const String &path, int *length) {
return getInstance()->_readFile(path, length);
}
static char *strdup(const char *str, const char *file, int line) {
if (!str) return nullptr;
size_t len = strlen(str) + 1;
char *copy = (char *) getInstance()->_alloc(len, file, line);
memcpy(copy, str, len);
return copy;
}
static void setInstance(SpineExtension *inSpineExtension);
static SpineExtension *getInstance();
virtual ~SpineExtension();
/// Implement this function to use your own memory allocator
virtual void *_alloc(size_t size, const char *file, int line) = 0;
virtual void *_calloc(size_t size, const char *file, int line) = 0;
virtual void *_realloc(void *ptr, size_t size, const char *file, int line) = 0;
/// If you provide a spineAllocFunc, you should also provide a spineFreeFunc
virtual void _free(void *mem, const char *file, int line) = 0;
virtual char *_readFile(const String &path, int *length) = 0;
virtual void _beforeFree(void *ptr) {
SP_UNUSED(ptr);
}
protected:
SpineExtension();
private:
static SpineExtension *_instance;
};
class SP_API DefaultSpineExtension : public SpineExtension {
public:
DefaultSpineExtension();
virtual ~DefaultSpineExtension();
protected:
virtual void *_alloc(size_t size, const char *file, int line) override;
virtual void *_calloc(size_t size, const char *file, int line) override;
virtual void *_realloc(void *ptr, size_t size, const char *file, int line) override;
virtual void _free(void *mem, const char *file, int line) override;
virtual char *_readFile(const String &path, int *length) override;
};
// This function is to be implemented by engine specific runtimes to provide
// the default extension for that engine. It is called the first time
// SpineExtension::getInstance() is called, when no instance has been set
// yet.
extern SpineExtension *getDefaultExtension();
}
#endif /* Spine_Extension_h */
@@ -0,0 +1,65 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_HasRendererObject_h
#define Spine_HasRendererObject_h
#include <spine/dll.h>
namespace spine {
typedef void (*DisposeRendererObject)(void *rendererObject);
class SP_API HasRendererObject {
public:
explicit HasRendererObject() : _rendererObject(0), _dispose(0) {};
virtual ~HasRendererObject() {
if (_dispose && _rendererObject) _dispose(_rendererObject);
}
void *getRendererObject() {
return _rendererObject;
}
void setRendererObject(void *rendererObject, DisposeRendererObject dispose = 0) {
if (_dispose && _rendererObject && _rendererObject != rendererObject) _dispose(_rendererObject);
_rendererObject = rendererObject;
_dispose = dispose;
}
private:
void *_rendererObject;
DisposeRendererObject _dispose;
};
}
#endif
@@ -0,0 +1,202 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_HashMap_h
#define Spine_HashMap_h
#include <spine/Array.h>
#include <spine/SpineObject.h>
// Required for new with line number and file name in MSVC
#ifdef _MSC_VER
#pragma warning(disable : 4291)
#pragma warning(disable : 4251)
#endif
namespace spine {
template<typename K, typename V>
class HashMap : public SpineObject {
private:
class Entry;
public:
class Pair {
public:
explicit Pair(K &k, V &v) : key(k), value(v) {
}
K &key;
V &value;
};
class Entries {
public:
friend class HashMap;
explicit Entries(Entry *entry) : _hasChecked(false) {
_start.next = entry;
_entry = &_start;
}
Pair next() {
assert(_entry);
assert(_hasChecked);
_entry = _entry->next;
Pair pair(_entry->_key, _entry->_value);
_hasChecked = false;
return pair;
}
bool hasNext() {
_hasChecked = true;
return _entry->next;
}
private:
bool _hasChecked;
Entry _start;
Entry *_entry;
};
HashMap() : _head(NULL), _size(0) {
}
~HashMap() {
clear();
}
void clear() {
for (Entry *entry = _head; entry != NULL;) {
Entry *next = entry->next;
delete entry;
entry = next;
}
_head = NULL;
_size = 0;
}
size_t size() {
return _size;
}
void put(const K &key, const V &value) {
Entry *entry = find(key);
if (entry) {
entry->_key = key;
entry->_value = value;
} else {
entry = new (__FILE__, __LINE__) Entry();
entry->_key = key;
entry->_value = value;
Entry *oldHead = _head;
if (oldHead) {
_head = entry;
oldHead->prev = entry;
entry->next = oldHead;
} else {
_head = entry;
}
_size++;
}
}
bool addAll(Array<K> &keys, const V &value) {
size_t oldSize = _size;
for (size_t i = 0; i < keys.size(); i++) {
put(keys[i], value);
}
return _size != oldSize;
}
bool containsKey(const K &key) {
return find(key) != NULL;
}
bool remove(const K &key) {
Entry *entry = find(key);
if (!entry) return false;
Entry *prev = entry->prev;
Entry *next = entry->next;
if (prev)
prev->next = next;
else
_head = next;
if (next) next->prev = entry->prev;
delete entry;
_size--;
return true;
}
V operator[](const K &key) {
Entry *entry = find(key);
if (entry)
return entry->_value;
else {
assert(false);
return 0;
}
}
Entries getEntries() const {
return Entries(_head);
}
private:
Entry *find(const K &key) {
for (Entry *entry = _head; entry != NULL; entry = entry->next) {
if (entry->_key == key) return entry;
}
return NULL;
}
class SP_API Entry : public SpineObject {
public:
K _key;
V _value;
Entry *next;
Entry *prev;
Entry() : next(NULL), prev(NULL) {
}
};
Entry *_head;
size_t _size;
};
}
#endif /* Spine_HashMap_h */
@@ -0,0 +1,92 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_IkConstraint_h
#define Spine_IkConstraint_h
#include <spine/Constraint.h>
#include <spine/ConstraintData.h>
#include <spine/IkConstraintData.h>
#include <spine/IkConstraintPose.h>
#include <spine/Array.h>
namespace spine {
class Skeleton;
class Bone;
class BonePose;
// Non-exported base class that inherits from the template
class IkConstraintBase : public ConstraintGeneric<IkConstraint, IkConstraintData, IkConstraintPose> {
public:
IkConstraintBase(IkConstraintData &data) : ConstraintGeneric<IkConstraint, IkConstraintData, IkConstraintPose>(data) {
}
};
class SP_API IkConstraint : public IkConstraintBase {
friend class Skeleton;
friend class IkConstraintTimeline;
RTTI_DECL
public:
IkConstraint(IkConstraintData &data, Skeleton &skeleton);
virtual IkConstraint &copy(Skeleton &skeleton);
virtual void update(Skeleton &skeleton, Physics physics) override;
virtual void sort(Skeleton &skeleton) override;
virtual bool isSourceActive() override;
Array<BonePose *> &getBones();
Bone &getTarget();
void setTarget(Bone &inValue);
/// Adjusts the local rotation of the bone so the world position of the tip is as close to the target position as
/// possible. The target is specified in the world coordinate system.
static void apply(Skeleton &skeleton, BonePose &bone, float targetX, float targetY, bool compress, bool stretch, ScaleYMode scaleYMode,
float mix);
/// Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as
/// possible. The target is specified in the world coordinate system.
/// @param child A direct descendant of the parent bone.
static void apply(Skeleton &skeleton, BonePose &parent, BonePose &child, float targetX, float targetY, int bendDirection, bool stretch,
ScaleYMode scaleYMode, float softness, float mix);
private:
Array<BonePose *> _bones;
Bone *_target;
};
}
#endif /* Spine_IkConstraint_h */
@@ -0,0 +1,83 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_IkConstraintData_h
#define Spine_IkConstraintData_h
#include <spine/Array.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <spine/ConstraintData.h>
#include <spine/PosedData.h>
#include <spine/IkConstraintPose.h>
namespace spine {
class BoneData;
class IkConstraint;
class SP_API IkConstraintData : public ConstraintDataGeneric<IkConstraint, IkConstraintPose> {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class IkConstraint;
friend class Skeleton;
friend class IkConstraintTimeline;
RTTI_DECL
public:
explicit IkConstraintData(const String &name);
virtual Constraint &create(Skeleton &skeleton) override;
/// The bones that are constrained by this IK Constraint.
Array<BoneData *> &getBones();
/// The bone that is the IK target.
BoneData &getTarget();
void setTarget(BoneData &inValue);
/// Determines how BonePose::getScaleY() changes when IkConstraintPose::getCompress() or IkConstraintPose::getStretch()
/// sets BonePose::getScaleX().
ScaleYMode getScaleYMode();
void setScaleYMode(ScaleYMode scaleYMode);
private:
Array<BoneData *> _bones;
BoneData *_target;
ScaleYMode _scaleYMode;
};
}
#endif /* Spine_IkConstraintData_h */
@@ -0,0 +1,84 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_IkConstraintPose_h
#define Spine_IkConstraintPose_h
#include <spine/Pose.h>
#include <spine/RTTI.h>
namespace spine {
/// Stores a pose for an IK constraint.
class SP_API IkConstraintPose : public Pose<IkConstraintPose> {
friend class IkConstraint;
friend class IkConstraintTimeline;
friend class SkeletonJson;
friend class SkeletonBinary;
public:
IkConstraintPose();
virtual ~IkConstraintPose();
virtual void set(IkConstraintPose &pose) override;
/// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation.
///
/// For two bone IK: if the parent bone has local nonuniform scale, the child bone's local Y translation is set to 0.
float getMix();
void setMix(float mix);
/// For two bone IK, the target bone's distance from the maximum reach of the bones where rotation begins to slow. The bones
/// will not straighten completely until the target is this far out of range.
float getSoftness();
void setSoftness(float softness);
/// For two bone IK, controls the bend direction of the IK bones, either 1 or -1.
int getBendDirection();
void setBendDirection(int bendDirection);
/// For one bone IK, when true and the target is too close, the bone is scaled to reach it.
bool getCompress();
void setCompress(bool compress);
/// When true and the target is out of range, the parent bone is scaled to reach it.
///
/// For two bone IK: 1) the child bone's local Y translation is set to 0, 2) stretch is not applied if softness is
/// > 0, and 3) if the parent bone has local nonuniform scale, stretch is not applied.
bool getStretch();
void setStretch(bool stretch);
private:
int _bendDirection;
bool _compress, _stretch;
float _mix, _softness;
};
}
#endif /* Spine_IkConstraintPose_h */
@@ -0,0 +1,80 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_IkConstraintTimeline_h
#define Spine_IkConstraintTimeline_h
#include <spine/CurveTimeline.h>
#include <spine/ConstraintTimeline.h>
namespace spine {
/// Changes an IK constraint's mix, softness, bend direction, stretch, and compress values.
class SP_API IkConstraintTimeline : public CurveTimeline, public ConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit IkConstraintTimeline(size_t frameCount, size_t bezierCount, int constraintIndex);
virtual ~IkConstraintTimeline();
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
/// Sets the time, mix, softness, bend direction, compress, and stretch for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
/// @param bendDirection 1 or -1.
void setFrame(int frame, float time, float mix, float softness, int bendDirection, bool compress, bool stretch);
virtual int getConstraintIndex() const override {
return _constraintIndex;
}
virtual void setConstraintIndex(int inValue) override {
_constraintIndex = inValue;
}
private:
int _constraintIndex;
static const int ENTRIES = 6;
static const int MIX = 1;
static const int SOFTNESS = 2;
static const int BEND_DIRECTION = 3;
static const int COMPRESS = 4;
static const int STRETCH = 5;
};
}
#endif /* Spine_IkConstraintTimeline_h */
@@ -0,0 +1,61 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_TransformMode_h
#define Spine_TransformMode_h
#include <string.h>
namespace spine {
/// Determines how a bone inherits world transforms from parent bones.
enum Inherit {
Inherit_Normal = 0,
Inherit_OnlyTranslation,
Inherit_NoRotationOrReflection,
Inherit_NoScale,
Inherit_NoScaleOrReflection
};
inline Inherit Inherit_valueOf(const char *value) {
if (strcmp(value, "normal") == 0)
return Inherit_Normal;
else if (strcmp(value, "onlyTranslation") == 0)
return Inherit_OnlyTranslation;
else if (strcmp(value, "noRotationOrReflection") == 0)
return Inherit_NoRotationOrReflection;
else if (strcmp(value, "noScale") == 0)
return Inherit_NoScale;
else if (strcmp(value, "noScaleOrReflection") == 0)
return Inherit_NoScaleOrReflection;
else
return Inherit_Normal;// default
}
}
#endif /* Spine_TransformMode_h */
@@ -0,0 +1,79 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_InheritTimeline_h
#define Spine_InheritTimeline_h
#include <spine/Timeline.h>
#include <spine/BoneTimeline.h>
#include <spine/Animation.h>
#include <spine/Property.h>
#include <spine/Inherit.h>
namespace spine {
/// Changes a bone's inherit mode.
class SP_API InheritTimeline : public Timeline, public BoneTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit InheritTimeline(size_t frameCount, int boneIndex);
virtual ~InheritTimeline();
/// Sets the inherit transform mode for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
void setFrame(int frame, float time, Inherit inherit);
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
virtual int getBoneIndex() const override {
return _boneIndex;
}
void setBoneIndex(int inValue) override {
_boneIndex = inValue;
}
private:
int _boneIndex;
static const int ENTRIES = 2;
static const int INHERIT = 1;
};
}
#endif /* Spine_InheritTimeline_h */
@@ -0,0 +1,61 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Interpolation_h
#define Spine_Interpolation_h
#include <spine/SpineObject.h>
namespace spine {
/// Takes a linear value in the range 0-1 and outputs a usually non-linear, interpolated value.
class SP_API Interpolation : public SpineObject {
public:
virtual ~Interpolation();
/// @param a Alpha value between 0 and 1.
virtual float apply(float a);
float apply(float start, float end, float a);
static Interpolation &linear();
/// Aka "smoothstep".
static Interpolation &smooth();
/// Slow, then fast.
static Interpolation &slowFast();
/// Fast, then slow.
static Interpolation &fastSlow();
static Interpolation &circle();
};
}
#endif /* Spine_Interpolation_h */
@@ -0,0 +1,141 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Json_h
#define Spine_Json_h
#include <spine/SpineObject.h>
#include <spine/Array.h>
#ifndef SPINE_JSON_HAVE_PREV
/* spine doesn't use the "prev" link in the Json sibling lists. */
#define SPINE_JSON_HAVE_PREV 0
#endif
namespace spine {
class SP_API Json : public SpineObject {
friend class SkeletonJson;
public:
/* Json Types: */
static const int JSON_FALSE;
static const int JSON_TRUE;
static const int JSON_NULL;
static const int JSON_NUMBER;
static const int JSON_STRING;
static const int JSON_ARRAY;
static const int JSON_OBJECT;
static bool asFloatArray(Json *value, Array<float> &array) {
if (value == NULL) return false;
array.setSize(value->_size, 0);
Json *vertex = value->_child;
for (int i = 0; vertex; vertex = vertex->_next, i++) array[i] = vertex->_valueFloat;
return true;
}
static bool asIntArray(Json *value, Array<int> &array) {
if (value == NULL) return false;
array.setSize(value->_size, 0);
Json *vertex = value->_child;
for (int i = 0; vertex; vertex = vertex->_next, i++) array[i] = vertex->_valueInt;
return true;
}
static bool asUnsignedShortArray(Json *value, Array<unsigned short> &array) {
if (value == NULL) return false;
array.setSize(value->_size, 0);
Json *vertex = value->_child;
for (int i = 0; vertex; vertex = vertex->_next, i++) array[i] = (unsigned short) vertex->_valueInt;
return true;
}
/* Get item "string" from object. Case insensitive. */
static Json *getItem(Json *object, const char *string);
static Json *getItem(Json *object, int childIndex);
static const char *getString(Json *object, const char *name, const char *defaultValue);
static float getFloat(Json *object, const char *name, float defaultValue);
static int getInt(Json *object, const char *name, int defaultValue);
static bool getBoolean(Json *object, const char *name, bool defaultValue);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when Json_create() returns 0. 0 when Json_create() succeeds. */
static const char *getError();
/* Supply a block of JSON, and this returns a Json object you can interrogate. Call Json_dispose when finished. */
explicit Json(const char *value);
~Json();
private:
static const char *_error;
Json *_next;
#if SPINE_JSON_HAVE_PREV
Json *_prev; /* next/prev allow you to walk array/object chains. Alternatively, use getSize/getItem */
#endif
Json *_child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int _type; /* The type of the item, as above. */
int _size; /* The number of children. */
const char *_valueString; /* The item's string, if type==JSON_STRING */
int _valueInt; /* The item's number, if type==JSON_NUMBER */
float _valueFloat; /* The item's number, if type==JSON_NUMBER */
const char *_name; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
/* Utility to jump whitespace and cr/lf */
static const char *skip(const char *inValue);
/* Parser core - when encountering text, process appropriately. */
static const char *parseValue(Json *item, const char *value);
/* Parse the input text into an unescaped cstring, and populate item. */
static const char *parseString(Json *item, const char *str);
/* Parse the input text to generate a number, and populate the result into item. */
static const char *parseNumber(Json *item, const char *num);
/* Build an array from input text. */
static const char *parseArray(Json *item, const char *value);
/* Build an object from the text. */
static const char *parseObject(Json *item, const char *value);
static int json_strcasecmp(const char *s1, const char *s2);
};
}
#endif /* Spine_Json_h */
@@ -0,0 +1,60 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_LinkedMesh_h
#define Spine_LinkedMesh_h
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
namespace spine {
class MeshAttachment;
class SP_API LinkedMesh : public SpineObject {
friend class SkeletonBinary;
friend class SkeletonJson;
public:
LinkedMesh(MeshAttachment &mesh, const int skinIndex, size_t slotIndex, size_t sourceIndex, const String &source, bool inheritTimelines);
LinkedMesh(MeshAttachment &mesh, const String &skin, size_t slotIndex, size_t sourceIndex, const String &source, bool inheritTimelines);
private:
MeshAttachment *_mesh;
int _skinIndex;
String _skin;
size_t _slotIndex;
size_t _sourceIndex;
String _source;
bool _inheritTimelines;
};
}
#endif /* Spine_LinkedMesh_h */
@@ -0,0 +1,400 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Map_h
#define Spine_Map_h
#include <spine/Array.h>
#include <spine/Extension.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <assert.h>
#include <stdint.h>
#include <string.h>
namespace spine {
template<typename K>
class MapHash {
public:
size_t operator()(const K &key) const {
return (size_t) key;
}
};
template<typename T>
class MapHash<T *> {
public:
size_t operator()(T *const &key) const {
uintptr_t value = (uintptr_t) key;
return (size_t) (value >> 4);
}
};
template<>
class MapHash<long long> {
public:
size_t operator()(const long long &key) const {
unsigned long long value = (unsigned long long) key;
return (size_t) (value ^ (value >> 32));
}
};
template<>
class MapHash<unsigned long long> {
public:
size_t operator()(const unsigned long long &key) const {
return (size_t) (key ^ (key >> 32));
}
};
template<>
class MapHash<String> {
public:
size_t operator()(const String &key) const {
const unsigned char *buffer = (const unsigned char *) key.buffer();
size_t length = key.length();
uint64_t hash = 14695981039346656037ULL;
for (size_t i = 0; i < length; i++) {
hash ^= buffer[i];
hash *= 1099511628211ULL;
}
return (size_t) (hash ^ (hash >> 32));
}
};
template<typename K>
class MapEquals {
public:
bool operator()(const K &a, const K &b) const {
return a == b;
}
};
/// A compact open-addressed hash map. Unlike HashMap, this implementation does not allocate per entry.
/// Iteration order is unspecified and may change when the map grows or entries are removed.
template<typename K, typename V, typename Hash = MapHash<K>, typename Equals = MapEquals<K>>
class Map : public SpineObject {
private:
enum State {
Empty = 0,
Occupied = 1,
Deleted = 2
};
struct Entry {
K key;
V value;
};
public:
class Pair {
public:
explicit Pair(K &k, V &v) : key(k), value(v) {
}
K &key;
V &value;
};
class Entries {
public:
friend class Map;
bool hasNext() {
while (_index < _map->_capacity) {
if (_map->_states[_index] == Occupied) return true;
_index++;
}
return false;
}
Pair next() {
assert(_index < _map->_capacity);
assert(_map->_states[_index] == Occupied);
Entry &entry = _map->_entries[_index++];
return Pair(entry.key, entry.value);
}
private:
explicit Entries(Map &map) : _map(&map), _index(0) {
}
Map *_map;
size_t _index;
};
Map() : _entries(NULL), _states(NULL), _capacity(0), _size(0), _deleted(0), _hash(), _equals() {
}
explicit Map(size_t capacity) : _entries(NULL), _states(NULL), _capacity(0), _size(0), _deleted(0), _hash(), _equals() {
ensureCapacity(capacity);
}
Map(const Map &other) : _entries(NULL), _states(NULL), _capacity(0), _size(0), _deleted(0), _hash(other._hash), _equals(other._equals) {
ensureCapacity(other._size);
for (size_t i = 0; i < other._capacity; i++) {
if (other._states[i] == Occupied) put(other._entries[i].key, other._entries[i].value);
}
}
Map &operator=(const Map &other) {
if (this == &other) return *this;
clear();
_hash = other._hash;
_equals = other._equals;
ensureCapacity(other._size);
for (size_t i = 0; i < other._capacity; i++) {
if (other._states[i] == Occupied) put(other._entries[i].key, other._entries[i].value);
}
return *this;
}
~Map() {
release();
}
size_t size() const {
return _size;
}
size_t getCapacity() const {
return _capacity;
}
bool isEmpty() const {
return _size == 0;
}
void ensureCapacity(size_t expectedSize) {
size_t needed = capacityFor(expectedSize);
if (_capacity < needed) rehash(needed);
}
void clear() {
for (size_t i = 0; i < _capacity; i++) {
if (_states[i] == Occupied) resetEntry(i);
_states[i] = Empty;
}
_size = 0;
_deleted = 0;
}
void release() {
if (!_entries) return;
clear();
for (size_t i = 0; i < _capacity; i++) _entries[i].~Entry();
SpineExtension::free(_entries, __FILE__, __LINE__);
SpineExtension::free(_states, __FILE__, __LINE__);
_entries = NULL;
_states = NULL;
_capacity = 0;
}
bool containsKey(const K &key) const {
return findIndex(key) >= 0;
}
V *get(const K &key) {
int index = findIndex(key);
return index >= 0 ? &_entries[index].value : NULL;
}
const V *get(const K &key) const {
int index = findIndex(key);
return index >= 0 ? &_entries[index].value : NULL;
}
V operator[](const K &key) const {
const V *value = get(key);
assert(value);
return *value;
}
void put(const K &key, const V &value) {
ensureLoadForOneMore();
bool found = false;
size_t index = findSlot(key, found);
if (found) {
_entries[index].value = value;
return;
}
if (_states[index] == Deleted) _deleted--;
_states[index] = Occupied;
_entries[index].key = key;
_entries[index].value = value;
_size++;
}
/// Adds the key and value only if the key is not already present.
/// @return The existing value, or V() if the key was not present and the new value was added.
V putMissing(const K &key, const V &value) {
ensureLoadForOneMore();
bool found = false;
size_t index = findSlot(key, found);
if (found) return _entries[index].value;
if (_states[index] == Deleted) _deleted--;
_states[index] = Occupied;
_entries[index].key = key;
_entries[index].value = value;
_size++;
return V();
}
bool addAll(Array<K> &keys, const V &value) {
size_t oldSize = _size;
ensureCapacity(_size + keys.size());
for (size_t i = 0; i < keys.size(); i++) put(keys[i], value);
return _size != oldSize;
}
bool remove(const K &key) {
int index = findIndex(key);
if (index < 0) return false;
resetEntry((size_t) index);
_states[index] = Deleted;
_size--;
_deleted++;
if (_size == 0) {
memset(_states, Empty, _capacity);
_deleted = 0;
}
return true;
}
Entries getEntries() {
return Entries(*this);
}
private:
Entry *_entries;
unsigned char *_states;
size_t _capacity;
size_t _size;
size_t _deleted;
Hash _hash;
Equals _equals;
static size_t mix(size_t h) {
h ^= h >> 16;
h *= (size_t) 0x7feb352d;
h ^= h >> 15;
h *= (size_t) 0x846ca68b;
h ^= h >> 16;
return h;
}
static size_t nextPowerOfTwo(size_t value) {
size_t result = 8;
while (result < value) result <<= 1;
return result;
}
static size_t capacityFor(size_t expectedSize) {
if (expectedSize < 6) return 8;
return nextPowerOfTwo((expectedSize * 4 + 2) / 3);
}
void ensureLoadForOneMore() {
if (_capacity == 0) {
rehash(8);
return;
}
if ((_size + _deleted + 1) * 4 > _capacity * 3) {
size_t newCapacity = _deleted > _size ? _capacity : _capacity << 1;
rehash(newCapacity);
}
}
int findIndex(const K &key) const {
if (_capacity == 0) return -1;
size_t mask = _capacity - 1;
size_t index = mix(_hash(key)) & mask;
while (true) {
unsigned char state = _states[index];
if (state == Empty) return -1;
if (state == Occupied && _equals(_entries[index].key, key)) return (int) index;
index = (index + 1) & mask;
}
}
/// Returns an index containing key, an empty slot, or the first deleted slot encountered.
size_t findSlot(const K &key, bool &found) const {
size_t mask = _capacity - 1;
size_t index = mix(_hash(key)) & mask;
size_t firstDeleted = (size_t) -1;
while (true) {
unsigned char state = _states[index];
if (state == Empty) {
found = false;
return firstDeleted != (size_t) -1 ? firstDeleted : index;
}
if (state == Deleted) {
if (firstDeleted == (size_t) -1) firstDeleted = index;
} else if (_equals(_entries[index].key, key)) {
found = true;
return index;
}
index = (index + 1) & mask;
}
}
void rehash(size_t newCapacity) {
newCapacity = nextPowerOfTwo(newCapacity);
Entry *oldEntries = _entries;
unsigned char *oldStates = _states;
size_t oldCapacity = _capacity;
_entries = SpineExtension::alloc<Entry>(newCapacity, __FILE__, __LINE__);
_states = SpineExtension::calloc<unsigned char>(newCapacity, __FILE__, __LINE__);
assert(_entries);
assert(_states);
_capacity = newCapacity;
_size = 0;
_deleted = 0;
for (size_t i = 0; i < _capacity; i++) new (_entries + i) Entry();
if (oldEntries) {
for (size_t i = 0; i < oldCapacity; i++) {
if (oldStates[i] == Occupied) put(oldEntries[i].key, oldEntries[i].value);
oldEntries[i].~Entry();
}
SpineExtension::free(oldEntries, __FILE__, __LINE__);
SpineExtension::free(oldStates, __FILE__, __LINE__);
}
}
void resetEntry(size_t index) {
_entries[index].key = K();
_entries[index].value = V();
}
};
}
#endif /* Spine_Map_h */
@@ -0,0 +1,111 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_MathUtil_h
#define Spine_MathUtil_h
#include <spine/SpineObject.h>
#include <string.h>
// Needed for older MSVC versions
#undef min
#undef max
namespace spine {
class SP_API MathUtil : public SpineObject {
private:
MathUtil();
public:
static const float Epsilon;
static const float EpsilonSq;
static const float Pi;
static const float Pi_2;
static const float InvPi_2;
static const float Deg_Rad;
static const float Rad_Deg;
template<typename T>
static inline T min(T a, T b) {
return a < b ? a : b;
}
template<typename T>
static inline T max(T a, T b) {
return a > b ? a : b;
}
static float sign(float val);
static float clamp(float x, float lower, float upper);
static float abs(float v);
/// Returns the sine in radians from a lookup table.
static float sin(float radians);
/// Returns the cosine in radians from a lookup table.
static float cos(float radians);
/// Returns the sine in radians from a lookup table.
static float sinDeg(float degrees);
/// Returns the cosine in radians from a lookup table.
static float cosDeg(float degrees);
/// Returns atan2 in radians, faster but less accurate than Math.Atan2. Average error of 0.00231 radians (0.1323
/// degrees), largest error of 0.00488 radians (0.2796 degrees).
static float atan2(float y, float x);
static float atan2Deg(float x, float y);
static float acos(float v);
static float sqrt(float v);
static float fmod(float a, float b);
static bool isNan(float v);
static float quietNan();
static float random();
static float randomTriangular(float min, float max);
static float randomTriangular(float min, float max, float mode);
static float pow(float a, float b);
static float ceil(float v);
};
}
#endif /* Spine_MathUtil_h */
@@ -0,0 +1,116 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_MeshAttachment_h
#define Spine_MeshAttachment_h
#include <spine/Array.h>
#include <spine/Color.h>
#include <spine/HasRendererObject.h>
#include <spine/Sequence.h>
#include <spine/TextureRegion.h>
#include <spine/VertexAttachment.h>
namespace spine {
/// Attachment that displays a texture region using a mesh.
class SP_API MeshAttachment : public VertexAttachment {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class AtlasAttachmentLoader;
RTTI_DECL
public:
explicit MeshAttachment(const String &name, Sequence *sequence);
virtual ~MeshAttachment();
using VertexAttachment::computeWorldVertices;
virtual void computeWorldVertices(Skeleton &skeleton, Slot &slot, size_t start, size_t count, float *worldVertices, size_t offset,
size_t stride = 2) override;
Array<float> &getRegionUVs();
void setRegionUVs(Array<float> &inValue);
Array<unsigned short> &getTriangles();
void setTriangles(Array<unsigned short> &inValue);
int getHullLength();
void setHullLength(int inValue);
Sequence &getSequence();
void updateSequence();
const String &getPath();
void setPath(const String &inValue);
Color &getColor();
/// The source mesh if this is a linked mesh, else NULL. A linked mesh shares the bones, vertices, regionUVs,
/// triangles, hullLength, edges, width, and height with the source mesh, but may have a different name or path,
/// and therefore a different texture region.
MeshAttachment *getSourceMesh();
void setSourceMesh(MeshAttachment *inValue);
/// Vertex index pairs describing edges for controlling triangulation, or empty if nonessential data was not
/// exported. Mesh triangles do not cross edges. Triangulation is not performed at runtime.
Array<unsigned short> &getEdges();
void setEdges(Array<unsigned short> &inValue);
float getWidth();
void setWidth(float inValue);
float getHeight();
void setHeight(float inValue);
virtual Attachment &copy() override;
MeshAttachment &newLinkedMesh();
/// Computes UVs for a mesh attachment.
/// @param uvs Output array for the computed UVs, same length as regionUVs.
static void computeUVs(TextureRegion *region, Array<float> &regionUVs, Array<float> &uvs);
private:
Sequence *_sequence;
Array<float> _regionUVs;
Array<unsigned short> _triangles;
int _hullLength;
String _path;
Color _color;
MeshAttachment *_sourceMesh;
Array<unsigned short> _edges;
float _width, _height;
};
}
#endif /* Spine_MeshAttachment_h */
@@ -0,0 +1,74 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PathAttachment_h
#define Spine_PathAttachment_h
#include <spine/VertexAttachment.h>
#include <spine/Color.h>
namespace spine {
class SP_API PathAttachment : public VertexAttachment {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PathAttachment(const String &name);
/// The length in the setup pose from the start of the path to the end of each curve.
Array<float> &getLengths();
void setLengths(Array<float> &inValue);
bool getClosed();
void setClosed(bool inValue);
/// If true, additional calculations are performed to make computing positions along the path more accurate so
/// movement along the path has a constant speed.
bool getConstantSpeed();
void setConstantSpeed(bool inValue);
Color &getColor();
virtual Attachment &copy() override;
private:
Array<float> _lengths;
bool _closed;
bool _constantSpeed;
Color _color;
};
}
#endif /* Spine_PathAttachment_h */
@@ -0,0 +1,118 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PathConstraint_h
#define Spine_PathConstraint_h
#include <spine/Constraint.h>
#include <spine/ConstraintData.h>
#include <spine/PathConstraintData.h>
#include <spine/PathConstraintPose.h>
#include <spine/Array.h>
namespace spine {
class Skeleton;
class PathAttachment;
class BonePose;
class Slot;
class Bone;
class Skin;
class Attachment;
/// Adjusts the rotation, translation, and scale of the constrained bones so they follow a PathAttachment.
///
/// See https://esotericsoftware.com/spine-path-constraints Path constraints in the Spine User Guide.
// Non-exported base class that inherits from the template
class PathConstraintBase : public ConstraintGeneric<PathConstraint, PathConstraintData, PathConstraintPose> {
public:
PathConstraintBase(PathConstraintData &data) : ConstraintGeneric<PathConstraint, PathConstraintData, PathConstraintPose>(data) {
}
};
class SP_API PathConstraint : public PathConstraintBase {
friend class Skeleton;
friend class PathConstraintMixTimeline;
friend class PathConstraintPositionTimeline;
friend class PathConstraintPositionTimeline;
friend class PathConstraintSpacingTimeline;
RTTI_DECL
public:
static const float epsilon;
static const int NONE;
static const int BEFORE;
static const int AFTER;
PathConstraint(PathConstraintData &data, Skeleton &skeleton);
PathConstraint &copy(Skeleton &skeleton);
/// Applies the constraint to the constrained bones.
virtual void update(Skeleton &skeleton, Physics physics) override;
virtual void sort(Skeleton &skeleton) override;
virtual bool isSourceActive() override;
/// The bones that will be modified by this path constraint.
Array<BonePose *> &getBones();
/// The slot whose path attachment will be used to constrained the bones.
Slot &getSlot();
void setSlot(Slot &slot);
private:
Array<BonePose *> _bones;
Slot *_slot;
Array<float> _spaces;
Array<float> _positions;
Array<float> _world;
Array<float> _curves;
Array<float> _lengths;
Array<float> _segments;
Array<float> &computeWorldPositions(Skeleton &skeleton, PathAttachment &path, int spacesCount, bool tangents);
void addBeforePosition(float p, Array<float> &temp, int i, Array<float> &output, int o);
void addAfterPosition(float p, Array<float> &temp, int i, Array<float> &output, int o);
void addCurvePosition(float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, Array<float> &output,
int o, bool tangents);
void sortPathSlot(Skeleton &skeleton, Skin &skin, int slotIndex, Bone &slotBone);
void sortPath(Skeleton &skeleton, Attachment *attachment, Bone &slotBone);
};
}
#endif /* Spine_PathConstraint_h */
@@ -0,0 +1,111 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PathConstraintData_h
#define Spine_PathConstraintData_h
#include <spine/ConstraintData.h>
#include <spine/PosedData.h>
#include <spine/Array.h>
#include <spine/PathConstraintPose.h>
#include <spine/dll.h>
#include <spine/PositionMode.h>
#include <spine/SpacingMode.h>
#include <spine/RotateMode.h>
namespace spine {
class BoneData;
class SlotData;
class PathConstraint;
class Skeleton;
/// Stores the setup pose for a PathConstraint.
///
/// See https://esotericsoftware.com/spine-path-constraints Path constraints in the Spine User Guide.
class SP_API PathConstraintData : public ConstraintDataGeneric<PathConstraint, PathConstraintPose> {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class PathConstraint;
friend class Skeleton;
friend class PathConstraintMixTimeline;
friend class PathConstraintPositionTimeline;
friend class PathConstraintSpacingTimeline;
RTTI_DECL
public:
explicit PathConstraintData(const String &name);
virtual Constraint &create(Skeleton &skeleton) override;
/// The bones that will be modified by this path constraint.
Array<BoneData *> &getBones();
/// The slot whose path attachment will be used to constrained the bones.
SlotData &getSlot();
void setSlot(SlotData &slot);
/// The mode for positioning the first bone on the path.
PositionMode getPositionMode();
void setPositionMode(PositionMode positionMode);
/// The mode for positioning the bones after the first bone on the path.
SpacingMode getSpacingMode();
void setSpacingMode(SpacingMode spacingMode);
/// The mode for adjusting the rotation of the bones.
RotateMode getRotateMode();
void setRotateMode(RotateMode rotateMode);
/// An offset added to the constrained bone rotation.
float getOffsetRotation();
void setOffsetRotation(float offsetRotation);
private:
Array<BoneData *> _bones;
SlotData *_slot;
PositionMode _positionMode;
SpacingMode _spacingMode;
RotateMode _rotateMode;
float _offsetRotation;
};
}
#endif /* Spine_PathConstraintData_h */
@@ -0,0 +1,77 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PathConstraintMixTimeline_h
#define Spine_PathConstraintMixTimeline_h
#include <spine/CurveTimeline.h>
#include <spine/ConstraintTimeline.h>
namespace spine {
/// Changes a path constraint's rotate, x, and y mix values.
class SP_API PathConstraintMixTimeline : public CurveTimeline, public ConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PathConstraintMixTimeline(size_t frameCount, size_t bezierCount, int constraintIndex);
virtual ~PathConstraintMixTimeline();
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
/// Sets the time and color for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param time The frame time in seconds.
void setFrame(int frame, float time, float mixRotate, float mixX, float mixY);
virtual int getConstraintIndex() const override {
return _constraintIndex;
}
virtual void setConstraintIndex(int inValue) override {
_constraintIndex = inValue;
}
private:
int _constraintIndex;
static const int ENTRIES = 4;
static const int ROTATE = 1;
static const int X = 2;
static const int Y = 3;
};
}
#endif /* Spine_PathConstraintMixTimeline_h */
@@ -0,0 +1,81 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PathConstraintPose_h
#define Spine_PathConstraintPose_h
#include <spine/Pose.h>
#include <spine/RTTI.h>
namespace spine {
/// Stores a pose for a path constraint.
class SP_API PathConstraintPose : public Pose<PathConstraintPose> {
friend class PathConstraint;
friend class PathConstraintPositionTimeline;
friend class PathConstraintSpacingTimeline;
friend class PathConstraintMixTimeline;
friend class SkeletonJson;
friend class SkeletonBinary;
private:
float _position;
float _spacing;
float _mixRotate;
float _mixX;
float _mixY;
public:
PathConstraintPose();
virtual ~PathConstraintPose();
virtual void set(PathConstraintPose &pose) override;
/// The position along the path.
float getPosition();
void setPosition(float position);
/// The spacing between bones.
float getSpacing();
void setSpacing(float spacing);
/// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation.
float getMixRotate();
void setMixRotate(float mixRotate);
/// A percentage (0-1) that controls the mix between the constrained and unconstrained translation X.
float getMixX();
void setMixX(float mixX);
/// A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y.
float getMixY();
void setMixY(float mixY);
};
}
#endif
@@ -0,0 +1,57 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PathConstraintPositionTimeline_h
#define Spine_PathConstraintPositionTimeline_h
#include <spine/ConstraintTimeline1.h>
namespace spine {
/// Changes a path constraint's position.
class SP_API PathConstraintPositionTimeline : public ConstraintTimeline1 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
static const int ENTRIES;
explicit PathConstraintPositionTimeline(size_t frameCount, size_t bezierCount, int constraintIndex);
virtual ~PathConstraintPositionTimeline();
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
};
}// namespace spine
#endif /* Spine_PathConstraintPositionTimeline_h */
@@ -0,0 +1,54 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PathConstraintSpacingTimeline_h
#define Spine_PathConstraintSpacingTimeline_h
#include <spine/ConstraintTimeline1.h>
namespace spine {
/// Changes a path constraint's spacing.
class SP_API PathConstraintSpacingTimeline : public ConstraintTimeline1 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PathConstraintSpacingTimeline(size_t frameCount, size_t bezierCount, int constraintIndex);
virtual ~PathConstraintSpacingTimeline();
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
};
}
#endif /* Spine_PathConstraintSpacingTimeline_h */
@@ -0,0 +1,50 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Physics_h
#define Spine_Physics_h
namespace spine {
/// Determines how physics and other non-deterministic updates are applied.
enum Physics {
/// Physics are not updated or applied.
Physics_None,
/// Physics are reset via PhysicsConstraint::reset().
Physics_Reset,
/// Physics are updated and the pose from physics is applied.
Physics_Update,
/// Physics are not updated but the pose from physics is applied.
Physics_Pose
};
}
#endif
@@ -0,0 +1,104 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PhysicsConstraint_h
#define Spine_PhysicsConstraint_h
#include <spine/Constraint.h>
#include <spine/PhysicsConstraintData.h>
#include <spine/PhysicsConstraintPose.h>
#include <spine/BonePose.h>
#include <spine/Array.h>
namespace spine {
class Skeleton;
class BonePose;
class PhysicsConstraintPose;
/// Applies physics to a bone.
///
/// See https://esotericsoftware.com/spine-physics-constraints Physics constraints in the Spine User Guide.
// Non-exported base class that inherits from the template
class PhysicsConstraintBase : public ConstraintGeneric<PhysicsConstraint, PhysicsConstraintData, PhysicsConstraintPose> {
public:
PhysicsConstraintBase(PhysicsConstraintData &data)
: ConstraintGeneric<PhysicsConstraint, PhysicsConstraintData, PhysicsConstraintPose>(data) {
}
};
class SP_API PhysicsConstraint : public PhysicsConstraintBase {
friend class Skeleton;
friend class PhysicsConstraintTimeline;
friend class PhysicsConstraintInertiaTimeline;
friend class PhysicsConstraintStrengthTimeline;
friend class PhysicsConstraintDampingTimeline;
friend class PhysicsConstraintMassTimeline;
friend class PhysicsConstraintWindTimeline;
friend class PhysicsConstraintGravityTimeline;
friend class PhysicsConstraintMixTimeline;
friend class PhysicsConstraintResetTimeline;
public:
RTTI_DECL
PhysicsConstraint(PhysicsConstraintData &data, Skeleton &skeleton);
void update(Skeleton &skeleton, Physics physics) override;
void sort(Skeleton &skeleton) override;
bool isSourceActive() override;
PhysicsConstraint &copy(Skeleton &skeleton);
/// Resets all physics state that was the result of previous movement. Use this after moving a bone to prevent physics
/// from reacting to the movement.
void reset(Skeleton &skeleton);
/// Translates the physics constraint so the next update() forces are applied as if the bone moved an additional amount in world space.
void translate(float x, float y);
/// Rotates the physics constraint so the next update() forces are applied as if the bone rotated around the specified point in world space.
void rotate(float x, float y, float degrees);
/// The bone constrained by this physics constraint.
BonePose &getBone();
void setBone(BonePose &bone);
private:
BonePose *_bone;
bool _reset;
float _ux, _uy, _cx, _cy, _tx, _ty;
float _xOffset, _xLag, _xVelocity;
float _yOffset, _yLag, _yVelocity;
float _rotateOffset, _rotateLag, _rotateVelocity;
float _scaleOffset, _scaleLag, _scaleVelocity;
float _remaining, _lastTime;
};
}
#endif /* Spine_PhysicsConstraint_h */
@@ -0,0 +1,128 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PhysicsConstraintData_h
#define Spine_PhysicsConstraintData_h
#include <spine/ConstraintData.h>
#include <spine/PosedData.h>
#include <spine/PhysicsConstraintPose.h>
namespace spine {
class BoneData;
class PhysicsConstraint;
/// Stores the setup pose for a PhysicsConstraint.
///
/// See https://esotericsoftware.com/spine-physics-constraints Physics constraints in the Spine User Guide.
class SP_API PhysicsConstraintData : public ConstraintDataGeneric<PhysicsConstraint, PhysicsConstraintPose> {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class PhysicsConstraint;
friend class Skeleton;
RTTI_DECL
public:
explicit PhysicsConstraintData(const String &name);
virtual Constraint &create(Skeleton &skeleton) override;
/// The bone constrained by this physics constraint.
BoneData &getBone();
void setBone(BoneData &bone);
/// The time in milliseconds required to advanced the physics simulation one step.
float getStep();
void setStep(float step);
/// Physics influence on x translation, 0-1.
float getX();
void setX(float x);
/// Physics influence on y translation, 0-1.
float getY();
void setY(float y);
/// Physics influence on rotation, 0-1.
float getRotate();
void setRotate(float rotate);
/// Physics influence on scaleX, 0-1.
float getScaleX();
void setScaleX(float scaleX);
/// Physics influence on shearX, 0-1.
float getShearX();
void setShearX(float shearX);
/// Movement greater than the limit will not have a greater affect on physics.
float getLimit();
void setLimit(float limit);
/// Determines how BonePose::getScaleY() changes when getScaleX() sets BonePose::getScaleX().
ScaleYMode getScaleYMode();
void setScaleYMode(ScaleYMode scaleYMode);
/// True when this constraint's inertia is controlled by global slider timelines.
bool getInertiaGlobal();
void setInertiaGlobal(bool inertiaGlobal);
/// True when this constraint's strength is controlled by global slider timelines.
bool getStrengthGlobal();
void setStrengthGlobal(bool strengthGlobal);
/// True when this constraint's damping is controlled by global slider timelines.
bool getDampingGlobal();
void setDampingGlobal(bool dampingGlobal);
/// True when this constraint's mass is controlled by global slider timelines.
bool getMassGlobal();
void setMassGlobal(bool massGlobal);
/// True when this constraint's wind is controlled by global slider timelines.
bool getWindGlobal();
void setWindGlobal(bool windGlobal);
/// True when this constraint's gravity is controlled by global slider timelines.
bool getGravityGlobal();
void setGravityGlobal(bool gravityGlobal);
/// True when this constraint's mix is controlled by global slider timelines.
bool getMixGlobal();
void setMixGlobal(bool mixGlobal);
private:
BoneData *_bone;
float _x, _y, _rotate, _scaleX, _shearX, _limit, _step;
ScaleYMode _scaleYMode;
bool _inertiaGlobal, _strengthGlobal, _dampingGlobal, _massGlobal, _windGlobal, _gravityGlobal, _mixGlobal;
};
}
#endif /* Spine_PhysicsConstraintData_h */
@@ -0,0 +1,89 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PhysicsConstraintPose_h
#define Spine_PhysicsConstraintPose_h
#include <spine/Pose.h>
#include <spine/RTTI.h>
namespace spine {
/// Stores a pose for a physics constraint.
class SP_API PhysicsConstraintPose : public Pose<PhysicsConstraintPose> {
friend class PhysicsConstraint;
friend class PhysicsConstraintTimeline;
friend class SkeletonJson;
friend class SkeletonBinary;
private:
float _inertia;
float _strength;
float _damping;
float _massInverse;
float _wind;
float _gravity;
float _mix;
public:
PhysicsConstraintPose();
virtual ~PhysicsConstraintPose();
virtual void set(PhysicsConstraintPose &pose) override;
/// Controls how much bone movement is converted into physics movement.
float getInertia();
void setInertia(float inertia);
/// The amount of force used to return properties to the unconstrained value.
float getStrength();
void setStrength(float strength);
/// Reduces the speed of physics movements, with more of a reduction at higher speeds.
float getDamping();
void setDamping(float damping);
/// Determines susceptibility to acceleration.
float getMassInverse();
void setMassInverse(float massInverse);
/// Applies a constant force along the Skeleton::getWindX(), Skeleton::getWindY() vector.
float getWind();
void setWind(float wind);
/// Applies a constant force along the Skeleton::getGravityX(), Skeleton::getGravityY() vector.
float getGravity();
void setGravity(float gravity);
/// A percentage (0+) that controls the mix between the constrained and unconstrained poses.
float getMix();
void setMix(float mix);
};
}
#endif
@@ -0,0 +1,300 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PhysicsConstraintTimeline_h
#define Spine_PhysicsConstraintTimeline_h
#include <spine/ConstraintTimeline.h>
#include <spine/CurveTimeline.h>
#include <spine/PhysicsConstraint.h>
#include <spine/PhysicsConstraintData.h>
#include <spine/PhysicsConstraintPose.h>
namespace spine {
/// The base class for most PhysicsConstraint timelines.
class SP_API PhysicsConstraintTimeline : public CurveTimeline1, public ConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
/// @param constraintIndex -1 for all physics constraints in the skeleton.
explicit PhysicsConstraintTimeline(size_t frameCount, size_t bezierCount, int constraintIndex, Property property);
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
virtual int getConstraintIndex() const override {
return _constraintIndex;
}
virtual void setConstraintIndex(int inValue) override {
_constraintIndex = inValue;
}
protected:
virtual float get(PhysicsConstraintPose &pose) = 0;
virtual void set(PhysicsConstraintPose &pose, float value) = 0;
virtual bool global(PhysicsConstraintData &constraintData) = 0;
int _constraintIndex;
};
/// Changes a physics constraint's inertia.
class SP_API PhysicsConstraintInertiaTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintInertiaTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex)
: PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintInertia) {};
protected:
float get(PhysicsConstraintPose &pose) override {
return pose.getInertia();
}
void set(PhysicsConstraintPose &pose, float value) override {
pose.setInertia(value);
}
bool global(PhysicsConstraintData &constraintData) override {
return constraintData.getInertiaGlobal();
}
};
/// Changes a physics constraint's strength.
class SP_API PhysicsConstraintStrengthTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintStrengthTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex)
: PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintStrength) {};
protected:
float get(PhysicsConstraintPose &pose) override {
return pose.getStrength();
}
void set(PhysicsConstraintPose &pose, float value) override {
pose.setStrength(value);
}
bool global(PhysicsConstraintData &constraintData) override {
return constraintData.getStrengthGlobal();
}
};
/// Changes a physics constraint's damping.
class SP_API PhysicsConstraintDampingTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintDampingTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex)
: PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintDamping) {};
protected:
float get(PhysicsConstraintPose &pose) override {
return pose.getDamping();
}
void set(PhysicsConstraintPose &pose, float value) override {
pose.setDamping(value);
}
bool global(PhysicsConstraintData &constraintData) override {
return constraintData.getDampingGlobal();
}
};
/// Changes a physics constraint's mass inverse. The timeline values are not inverted.
class SP_API PhysicsConstraintMassTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintMassTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex)
: PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintMass) {};
protected:
float get(PhysicsConstraintPose &pose) override {
return 1 / pose.getMassInverse();
}
void set(PhysicsConstraintPose &pose, float value) override {
pose.setMassInverse(1 / value);
}
bool global(PhysicsConstraintData &constraintData) override {
return constraintData.getMassGlobal();
}
};
/// Changes a physics constraint's wind.
class SP_API PhysicsConstraintWindTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintWindTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex)
: PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintWind) {
_additive = true;
};
protected:
float get(PhysicsConstraintPose &pose) override {
return pose.getWind();
}
void set(PhysicsConstraintPose &pose, float value) override {
pose.setWind(value);
}
bool global(PhysicsConstraintData &constraintData) override {
return constraintData.getWindGlobal();
}
};
/// Changes a physics constraint's gravity.
class SP_API PhysicsConstraintGravityTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintGravityTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex)
: PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintGravity) {
_additive = true;
};
protected:
float get(PhysicsConstraintPose &pose) override {
return pose.getGravity();
}
void set(PhysicsConstraintPose &pose, float value) override {
pose.setGravity(value);
}
bool global(PhysicsConstraintData &constraintData) override {
return constraintData.getGravityGlobal();
}
};
/// Changes a physics constraint's mix.
class SP_API PhysicsConstraintMixTimeline : public PhysicsConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PhysicsConstraintMixTimeline(size_t frameCount, size_t bezierCount, int physicsConstraintIndex)
: PhysicsConstraintTimeline(frameCount, bezierCount, physicsConstraintIndex, Property_PhysicsConstraintMix) {};
protected:
float get(PhysicsConstraintPose &pose) override {
return pose.getMix();
}
void set(PhysicsConstraintPose &pose, float value) override {
pose.setMix(value);
}
bool global(PhysicsConstraintData &constraintData) override {
return constraintData.getMixGlobal();
}
};
/// Resets a physics constraint when specific animation times are reached.
class SP_API PhysicsConstraintResetTimeline : public Timeline, public ConstraintTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
/// @param constraintIndex -1 for all physics constraints in the skeleton.
explicit PhysicsConstraintResetTimeline(size_t frameCount, int constraintIndex)
: Timeline(frameCount, 1), ConstraintTimeline(), _constraintIndex(constraintIndex) {
PropertyId ids[] = {((PropertyId) Property_PhysicsConstraintReset) << 32};
setPropertyIds(ids, 1);
_instant = true;
}
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
int getFrameCount() {
return (int) _frames.size();
}
virtual int getConstraintIndex() const override {
return _constraintIndex;
}
virtual void setConstraintIndex(int inValue) override {
_constraintIndex = inValue;
}
/// Sets the time for the specified frame.
void setFrame(int frame, float time) {
_frames[frame] = time;
}
private:
int _constraintIndex;
};
}// namespace spine
#endif /* Spine_PhysicsConstraintTimeline_h */
@@ -0,0 +1,87 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PointAttachment_h
#define Spine_PointAttachment_h
#include <spine/Attachment.h>
#include <spine/Color.h>
namespace spine {
class Bone;
class BonePose;
/// 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.
///
/// See https://esotericsoftware.com/spine-points for Point Attachments in the Spine User Guide.
///
class SP_API PointAttachment : public Attachment {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit PointAttachment(const String &name);
/// The local x position.
float getX();
void setX(float inValue);
/// The local y position.
float getY();
void setY(float inValue);
/// The local rotation in degrees, counter clockwise.
float getRotation();
void setRotation(float inValue);
Color &getColor();
/// Computes the world position from the local position.
void computeWorldPosition(BonePose &bone, float &ox, float &oy);
/// Computes the world rotation from the local rotation.
float computeWorldRotation(BonePose &bone);
virtual Attachment &copy() override;
private:
float _x, _y, _rotation;
Color _color;
};
}
#endif /* Spine_PointAttachment_h */
@@ -0,0 +1,74 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Pool_h
#define Spine_Pool_h
#include <spine/Extension.h>
#include <spine/Array.h>
#include <spine/ArrayUtils.h>
#include <spine/SpineObject.h>
namespace spine {
template<typename T>
class SP_API Pool : public SpineObject {
public:
Pool() {
}
~Pool() {
ArrayUtils::deleteElements(_objects);
}
T *obtain() {
if (_objects.size() > 0) {
T **object = &_objects[_objects.size() - 1];
T *ret = *object;
_objects.removeAt(_objects.size() - 1);
return ret;
} else {
T *ret = new (__FILE__, __LINE__) T();
return ret;
}
}
void free(T *object) {
if (!_objects.contains(object)) {
_objects.add(object);
}
}
private:
Array<T *> _objects;
};
}
#endif /* Spine_Pool_h */
@@ -0,0 +1,48 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Pose_h
#define Spine_Pose_h
#include <spine/SpineObject.h>
namespace spine {
/// An interface for an object representing a pose.
template<class P>
class SP_API Pose : public SpineObject {
public:
Pose() {};
virtual ~Pose() {};
/// Sets this pose to the specified pose.
virtual void set(P &pose) = 0;
};
}
#endif
@@ -0,0 +1,148 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Posed_h
#define Spine_Posed_h
#include <spine/SpineObject.h>
namespace spine {
/// Base interface for posed objects.
class SP_API Posed {
public:
Posed() {
}
virtual ~Posed() {
}
virtual void constrained() = 0;
virtual void resetConstrained() = 0;
virtual bool isPoseEqualToApplied() = 0;
protected:
virtual void setupPose() = 0;
virtual void unconstrained() = 0;
};
/// The base class for an object with a number of poses:
/// - getData(): The setup pose data.
/// - getPose(): The unconstrained pose. Set by animations and application code.
/// - getAppliedPose(): The pose to use for rendering. Possibly modified by constraints.
template<class D, class P, class A>
class PosedGeneric : public Posed, public SpineObject {
friend class AnimationState;
friend class BoneTimeline1;
friend class BoneTimeline2;
friend class RotateTimeline;
friend class IkConstraint;
friend class TransformConstraint;
friend class VertexAttachment;
friend class PathConstraint;
friend class PhysicsConstraint;
friend class Skeleton;
friend class RegionAttachment;
friend class PointAttachment;
friend class AttachmentTimeline;
friend class RGBATimeline;
friend class RGBTimeline;
friend class AlphaTimeline;
friend class RGBA2Timeline;
friend class RGB2Timeline;
friend class ScaleTimeline;
friend class ScaleXTimeline;
friend class ScaleYTimeline;
friend class ShearTimeline;
friend class ShearXTimeline;
friend class ShearYTimeline;
friend class TranslateTimeline;
friend class TranslateXTimeline;
friend class TranslateYTimeline;
friend class InheritTimeline;
friend class Skeleton;
public:
PosedGeneric(D &data) : _data(data), _pose(), _constrainedPose(), _appliedPose(&_pose) {
setupPose();
}
virtual ~PosedGeneric() {
}
/// The setup pose data. May be shared with multiple instances.
D &getData() {
return _data;
}
/// The unconstrained pose for this object, set by animations and application code.
P &getPose() {
return _pose;
}
/// The pose to use for rendering. If no constraints modify this pose, this is the same as getPose(). Otherwise it is a
/// copy of getPose() modified by constraints.
A &getAppliedPose() {
return *_appliedPose;
}
/// Sets the constrained pose to the unconstrained pose, as a starting point for constraints to be applied.
virtual void resetConstrained() override {
_constrainedPose.set(_pose);
}
/// Sets the applied pose to the constrained pose, in anticipation of the applied pose being modified by constraints.
virtual void constrained() override {
_appliedPose = &_constrainedPose;
}
virtual bool isPoseEqualToApplied() override {
return _appliedPose == &_pose;
}
protected:
/// Sets the applied pose to the unconstrained pose, for when no constraints will modify the pose.
virtual void unconstrained() override {
_appliedPose = &_pose;
}
/// Sets the unconstrained pose to the setup pose.
virtual void setupPose() override {
_pose.set(_data.getSetupPose());
}
protected:
D &_data;
A _pose; ///< Stored as A type (concrete pose type) to match Java behavior
A _constrainedPose;///< Stored as A type (concrete pose type) to match Java behavior
A *_appliedPose; ///< Points to either _pose or _constrainedPose, reassignable like Java
};
}// namespace spine
#endif /* Spine_Posed_h */
@@ -0,0 +1,59 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PosedActive_h
#define Spine_PosedActive_h
#include <spine/dll.h>
namespace spine {
/// A posed object that may be active or inactive.
class SP_API PosedActive {
protected:
bool _active;
public:
PosedActive() : _active(true) {
}
virtual ~PosedActive() {
}
/// Returns false when this won't be updated by Skeleton::updateWorldTransform(Physics) because a skin is
/// required and the active skin does not contain this item. See Skin::getBones(), Skin::getConstraints(),
/// PosedData::getSkinRequired(), and Skeleton::updateCache().
bool isActive() const {
return _active;
}
void setActive(bool active) {
_active = active;
}
};
}
#endif /* Spine_PosedActive_h */
@@ -0,0 +1,146 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PosedData_h
#define Spine_PosedData_h
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
namespace spine {
template<class P>
class Pose;
class SP_API PosedData : public SpineObject {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class BoneTimeline1;
friend class BoneTimeline2;
friend class RotateTimeline;
friend class AttachmentTimeline;
friend class RGBATimeline;
friend class RGBTimeline;
friend class AlphaTimeline;
friend class RGBA2Timeline;
friend class RGB2Timeline;
friend class ScaleTimeline;
friend class ScaleXTimeline;
friend class ScaleYTimeline;
friend class ShearTimeline;
friend class ShearXTimeline;
friend class ShearYTimeline;
friend class TranslateTimeline;
friend class TranslateXTimeline;
friend class TranslateYTimeline;
friend class InheritTimeline;
friend class Skeleton;
friend class Slot;
public:
PosedData(const String &name);
virtual ~PosedData();
const String &getName() const {
return _name;
};
/// When true, Skeleton::updateWorldTransform(Physics) only updates this constraint if the Skeleton::getSkin()
/// contains this constraint.
///
/// See Skin::getConstraints().
bool getSkinRequired() const {
return _skinRequired;
};
void setSkinRequired(bool skinRequired) {
_skinRequired = skinRequired;
};
protected:
String _name;
bool _skinRequired;
};
inline PosedData::PosedData(const String &name) : _name(name), _skinRequired(false) {
}
inline PosedData::~PosedData() {
}
/// The base class for storing setup data for a posed object. May be shared with multiple instances.
template<class P>
class PosedDataGeneric : public PosedData {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class BoneTimeline1;
friend class BoneTimeline2;
friend class RotateTimeline;
friend class AttachmentTimeline;
friend class RGBATimeline;
friend class RGBTimeline;
friend class AlphaTimeline;
friend class RGBA2Timeline;
friend class RGB2Timeline;
friend class ScaleTimeline;
friend class ScaleXTimeline;
friend class ScaleYTimeline;
friend class ShearTimeline;
friend class ShearXTimeline;
friend class ShearYTimeline;
friend class TranslateTimeline;
friend class TranslateXTimeline;
friend class TranslateYTimeline;
friend class InheritTimeline;
friend class PhysicsConstraintTimeline;
friend class PhysicsConstraintInertiaTimeline;
friend class PhysicsConstraintStrengthTimeline;
friend class PhysicsConstraintDampingTimeline;
friend class PhysicsConstraintMassTimeline;
friend class PhysicsConstraintWindTimeline;
friend class PhysicsConstraintGravityTimeline;
friend class Slot;
protected:
P _setupPose;
public:
PosedDataGeneric(const String &name) : PosedData(name), _setupPose() {
}
virtual ~PosedDataGeneric() {};
/// The setup pose that most animations are relative to.
P &getSetupPose() {
return _setupPose;
};
const P &getSetupPose() const {
return _setupPose;
};
};
}
#endif
@@ -0,0 +1,54 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_PositionMode_h
#define Spine_PositionMode_h
#include <string.h>
namespace spine {
/// Controls how the first bone is positioned along the path.
///
/// @see https://esotericsoftware.com/spine-path-constraints#Position-mode Position mode in the Spine User Guide.
enum PositionMode {
PositionMode_Fixed = 0,
PositionMode_Percent
};
inline PositionMode PositionMode_valueOf(const char *value) {
if (strcmp(value, "fixed") == 0)
return PositionMode_Fixed;
else if (strcmp(value, "percent") == 0)
return PositionMode_Percent;
else
return PositionMode_Percent;// default
}
}
#endif /* Spine_PositionMode_h */
@@ -0,0 +1,71 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Property_h
#define Spine_Property_h
namespace spine {
typedef long long PropertyId;
enum Property {
Property_Rotate = 0,
Property_X,
Property_Y,
Property_ScaleX,
Property_ScaleY,
Property_ShearX,
Property_ShearY,
Property_Inherit,
Property_Rgb,
Property_Alpha,
Property_Rgb2,
Property_Attachment,
Property_Deform,
Property_Event,
Property_DrawOrder,
Property_IkConstraint,
Property_TransformConstraint,
Property_PathConstraintPosition,
Property_PathConstraintSpacing,
Property_PathConstraintMix,
Property_PhysicsConstraintInertia,
Property_PhysicsConstraintStrength,
Property_PhysicsConstraintDamping,
Property_PhysicsConstraintMass,
Property_PhysicsConstraintWind,
Property_PhysicsConstraintGravity,
Property_PhysicsConstraintMix,
Property_PhysicsConstraintReset,
Property_Sequence,
Property_SliderTime,
Property_SliderMix,
Property_DrawOrderFolder
};
}
#endif /* Spine_Property_h */
@@ -0,0 +1,92 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_RTTI_h
#define Spine_RTTI_h
#include <spine/dll.h>
namespace spine {
class SP_API RTTI {
public:
explicit RTTI(const char *className);
RTTI(const char *className, const RTTI &baseRTTI);
// New constructor for multiple interfaces (up to 3)
RTTI(const char *className, const RTTI &baseRTTI, const RTTI *interface1, const RTTI *interface2 = 0, const RTTI *interface3 = 0);
const char *getClassName() const;
bool isExactly(const RTTI &rtti) const;
bool instanceOf(const RTTI &rtti) const;
private:
// Prevent copying
RTTI(const RTTI &obj);
RTTI &operator=(const RTTI &obj);
const char *_className;
const RTTI *_pBaseRTTI;
const RTTI *_interfaces[3];// Support up to 3 interfaces
int _interfaceCount;
};
}
#define RTTI_DECL_NOPARENT \
public: \
static const RTTI rtti; \
virtual const RTTI &getRTTI() const;
#define RTTI_DECL \
public: \
static const RTTI rtti; \
virtual const RTTI &getRTTI() const override;
#define RTTI_IMPL_NOPARENT(name) \
const RTTI name::rtti(#name); \
const RTTI &name::getRTTI() const { \
return rtti; \
}
#define RTTI_IMPL(name, parent) \
const RTTI name::rtti(#name, parent::rtti); \
const RTTI &name::getRTTI() const { \
return rtti; \
}
#define RTTI_IMPL_MULTI(name, parent, ...) \
const RTTI name::rtti(#name, parent::rtti, &__VA_ARGS__::rtti); \
const RTTI &name::getRTTI() const { \
return rtti; \
}
#endif /* Spine_RTTI_h */
@@ -0,0 +1,126 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_RegionAttachment_h
#define Spine_RegionAttachment_h
#include <spine/Attachment.h>
#include <spine/Array.h>
#include <spine/Color.h>
#include <spine/HasRendererObject.h>
#include <spine/Sequence.h>
#include <spine/TextureRegion.h>
namespace spine {
class Slot;
class SlotPose;
/// Attachment that displays a texture region.
class SP_API RegionAttachment : public Attachment {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class AtlasAttachmentLoader;
RTTI_DECL
public:
explicit RegionAttachment(const String &name, Sequence *sequence);
virtual ~RegionAttachment();
/// Transforms the attachment's four vertices to world coordinates.
/// @param slot The parent slot.
/// @param vertexOffsets The vertex offsets.
/// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + 8.
/// @param offset The worldVertices index to begin writing values.
/// @param stride The number of worldVertices entries between the value pairs written.
void computeWorldVertices(Slot &slot, float *vertexOffsets, float *worldVertices, size_t offset, size_t stride = 2);
void computeWorldVertices(Slot &slot, Array<float> &vertexOffsets, Array<float> &worldVertices, size_t offset, size_t stride = 2);
/// Returns the vertex offsets for the specified slot pose.
Array<float> &getOffsets(SlotPose &pose);
float getX();
void setX(float inValue);
float getY();
void setY(float inValue);
float getScaleX();
void setScaleX(float inValue);
float getScaleY();
void setScaleY(float inValue);
/// The local rotation in degrees, counter clockwise.
float getRotation();
void setRotation(float inValue);
float getWidth();
void setWidth(float inValue);
float getHeight();
void setHeight(float inValue);
Sequence &getSequence();
void updateSequence();
const String &getPath();
void setPath(const String &inValue);
Color &getColor();
virtual Attachment &copy() override;
/// Computes UVs and offsets for a region attachment.
/// @param uvs Output array for the computed UVs, length of 8.
/// @param offset Output array for the computed vertex offsets, length of 8.
static void computeUVs(TextureRegion *region, float x, float y, float scaleX, float scaleY, float rotation, float width, float height,
Array<float> &offset, Array<float> &uvs);
private:
static const int BLX;
static const int BLY;
static const int ULX;
static const int ULY;
static const int URX;
static const int URY;
static const int BRX;
static const int BRY;
Sequence *_sequence;
float _x, _y, _scaleX, _scaleY, _rotation, _width, _height;
String _path;
Color _color;
};
}
#endif /* Spine_RegionAttachment_h */
@@ -0,0 +1,59 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_RotateMode_h
#define Spine_RotateMode_h
#include <string.h>
namespace spine {
/// Controls how bones are rotated, translated, and scaled to match the path.
///
/// @see https://esotericsoftware.com/spine-path-constraints#Rotate-Mix Rotate mode in the Spine User Guide.
enum RotateMode {
RotateMode_Tangent = 0,
RotateMode_Chain,
/// When chain scale, constrained bones should all have the same parent. That way when the path constraint scales a bone, it
/// doesn't affect other constrained bones.
RotateMode_ChainScale
};
inline RotateMode RotateMode_valueOf(const char *value) {
if (strcmp(value, "tangent") == 0)
return RotateMode_Tangent;
else if (strcmp(value, "chain") == 0)
return RotateMode_Chain;
else if (strcmp(value, "chainScale") == 0)
return RotateMode_ChainScale;
else
return RotateMode_Tangent;// default
}
}
#endif /* Spine_RotateMode_h */
@@ -0,0 +1,54 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_RotateTimeline_h
#define Spine_RotateTimeline_h
#include <spine/BoneTimeline.h>
namespace spine {
/// Changes a bone's local rotation.
class SP_API RotateTimeline : public BoneTimeline1 {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class AnimationState;
RTTI_DECL
public:
explicit RotateTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
protected:
virtual void _apply(BonePose &pose, BonePose &setup, float time, float alpha, MixFrom from, bool add, bool out) override;
};
}
#endif /* Spine_RotateTimeline_h */
@@ -0,0 +1,82 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_ScaleTimeline_h
#define Spine_ScaleTimeline_h
#include <spine/BoneTimeline.h>
namespace spine {
/// Changes a bone's local scaleX and scaleY.
class SP_API ScaleTimeline : public BoneTimeline2 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit ScaleTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
protected:
virtual void _apply(BonePose &pose, BonePose &setup, float time, float alpha, MixFrom from, bool add, bool out) override;
};
/// Changes a bone's local scaleX.
class SP_API ScaleXTimeline : public BoneTimeline1 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit ScaleXTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
protected:
virtual void _apply(BonePose &pose, BonePose &setup, float time, float alpha, MixFrom from, bool add, bool out) override;
};
/// Changes a bone's local scaleY.
class SP_API ScaleYTimeline : public BoneTimeline1 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit ScaleYTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
protected:
virtual void _apply(BonePose &pose, BonePose &setup, float time, float alpha, MixFrom from, bool add, bool out) override;
};
}
#endif /* Spine_ScaleTimeline_h */
@@ -0,0 +1,163 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Sequence_h
#define Spine_Sequence_h
#include <spine/Array.h>
#include <spine/RTTI.h>
#include <spine/SpineString.h>
#include <spine/TextureRegion.h>
namespace spine {
class SlotPose;
class RegionAttachment;
class MeshAttachment;
class SkeletonBinary;
class SkeletonJson;
/// Holds texture regions, UVs, and vertex offsets for rendering a region or mesh attachment.
/// Regions must be populated and update() called before use.
class SP_API Sequence : public SpineObject {
friend class SkeletonBinary;
friend class SkeletonJson;
public:
/// @param count The number of texture regions this sequence will display.
/// @param pathSuffix If true, getPath(String, int) has a numeric suffix. If false, all regions will use the same path,
/// so count should be 1.
Sequence(int count, bool pathSuffix);
/// Copy constructor.
Sequence(const Sequence &other);
~Sequence();
/// Computes UVs and offsets for the specified attachment. Must be called if the regions
/// or attachment properties are changed.
void update(RegionAttachment &attachment);
void update(MeshAttachment &attachment);
/// The list of texture regions this sequence will display.
Array<TextureRegion *> &getRegions() {
return _regions;
}
/// Returns the getRegions() index for SlotPose::getSequenceIndex().
int resolveIndex(SlotPose &pose);
/// Returns the texture region from getRegions() for the specified index.
TextureRegion *getRegion(int index);
/// Returns the UVs for the specified index. getRegions() must be populated and update() called before calling this method.
Array<float> &getUVs(int index);
/// Returns vertex offsets from the center of a RegionAttachment. Invalid to call for a MeshAttachment.
Array<float> &getOffsets(int index);
/// The starting number for the numeric getPath(String, int) suffix.
int getStart() {
return _start;
}
void setStart(int start) {
_start = start;
}
/// The minimum number of digits in the numeric getPath(String, int) suffix, for zero padding. 0 for no zero padding.
int getDigits() {
return _digits;
}
void setDigits(int digits) {
_digits = digits;
}
/// The index of the region to show for the setup pose.
int getSetupIndex() {
return _setupIndex;
}
void setSetupIndex(int setupIndex) {
_setupIndex = setupIndex;
}
/// Returns true if getPath(String, int) has a numeric suffix.
bool hasPathSuffix() {
return _pathSuffix;
}
/// Returns the specified base path with an optional numeric suffix for the specified index.
String &getPath(const String &basePath, int index);
/// Returns a unique ID for this sequence.
int getId() {
return _id;
}
private:
static int _nextID;
int _id;
Array<TextureRegion *> _regions;
bool _pathSuffix;
Array<Array<float>> _uvs;
Array<Array<float>> _offsets;
int _start;
int _digits;
int _setupIndex;
String _tmpPath;
static int nextID();
};
/// Controls how getRegions() are displayed over time.
enum SequenceMode {
SequenceMode_hold = 0,
SequenceMode_once = 1,
SequenceMode_loop = 2,
SequenceMode_pingpong = 3,
SequenceMode_onceReverse = 4,
SequenceMode_loopReverse = 5,
SequenceMode_pingpongReverse = 6
};
inline SequenceMode SequenceMode_valueOf(const String &value) {
if (value == "hold") return SequenceMode_hold;
if (value == "once") return SequenceMode_once;
if (value == "loop") return SequenceMode_loop;
if (value == "pingpong") return SequenceMode_pingpong;
if (value == "onceReverse") return SequenceMode_onceReverse;
if (value == "loopReverse") return SequenceMode_loopReverse;
if (value == "pingpongReverse") return SequenceMode_pingpongReverse;
return SequenceMode_hold;
}
}
#endif
@@ -0,0 +1,87 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SequenceTimeline_h
#define Spine_SequenceTimeline_h
#include <spine/Timeline.h>
#include <spine/SlotTimeline.h>
#include <spine/Sequence.h>
namespace spine {
class Attachment;
class HasTextureRegion;
class Slot;
/// Changes the sequence index for an attachment's Sequence.
class SP_API SequenceTimeline : public Timeline, public SlotTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit SequenceTimeline(size_t frameCount, int slotIndex, Attachment &attachment);
virtual ~SequenceTimeline();
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
/// Sets the time, mode, index, and frame time for the specified frame.
/// @param frame Between 0 and frameCount, inclusive.
/// @param delay Seconds between frames.
void setFrame(int frame, float time, SequenceMode mode, int index, float delay);
/// The attachment for which the sequence index will be set.
///
/// See Attachment::getTimelineAttachment().
Attachment &getAttachment() {
return *(Attachment *) _attachment;
}
virtual int getSlotIndex() override;
virtual void setSlotIndex(int inValue) override;
protected:
int _slotIndex;
Attachment *_attachment;
void setupPose(Slot &slot, bool appliedPose);
void applyToSlot(Slot &slot, bool appliedPose, Sequence &sequence, float time, float before, int modeAndIndex, float delay);
static const int ENTRIES = 3;
static const int MODE = 1;
static const int DELAY = 2;
};
}
#endif /* Spine_SequenceTimeline_h */
@@ -0,0 +1,82 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_ShearTimeline_h
#define Spine_ShearTimeline_h
#include <spine/BoneTimeline.h>
namespace spine {
/// Changes a bone's local shearX and shearY.
class SP_API ShearTimeline : public BoneTimeline2 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit ShearTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
protected:
virtual void _apply(BonePose &pose, BonePose &setup, float time, float alpha, MixFrom from, bool add, bool out) override;
};
/// Changes a bone's local shearX.
class SP_API ShearXTimeline : public BoneTimeline1 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit ShearXTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
protected:
virtual void _apply(BonePose &pose, BonePose &setup, float time, float alpha, MixFrom from, bool add, bool out) override;
};
/// Changes a bone's local shearY.
class SP_API ShearYTimeline : public BoneTimeline1 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit ShearYTimeline(size_t frameCount, size_t bezierCount, int boneIndex);
protected:
virtual void _apply(BonePose &pose, BonePose &setup, float time, float alpha, MixFrom from, bool add, bool out) override;
};
}
#endif /* Spine_ShearTimeline_h */
@@ -0,0 +1,368 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Skeleton_h
#define Spine_Skeleton_h
#include <spine/Array.h>
#include <spine/MathUtil.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <spine/Color.h>
#include <spine/Physics.h>
#include <spine/Update.h>
#include <spine/Posed.h>
#include <spine/Constraint.h>
#include <spine/DrawOrder.h>
namespace spine {
class SkeletonData;
class Bone;
class BonePose;
class Updatable;
class Slot;
class DrawOrder;
class IkConstraint;
class PathConstraint;
class PhysicsConstraint;
class TransformConstraint;
class Skin;
class Attachment;
class SkeletonClipping;
/// Stores bones and slots to be posed by animations and application code. Multiple skeleton instances can share the same
/// SkeletonData, including animations, attachments, and skins.
///
/// After posing, call updateWorldTransform(Physics) to apply constraints and compute world transforms for rendering.
class SP_API Skeleton : public SpineObject {
friend class AnimationState;
friend class SkeletonBounds;
friend class SkeletonClipping;
friend class SlotCurveTimeline;
friend class AttachmentTimeline;
friend class RGBATimeline;
friend class RGBTimeline;
friend class AlphaTimeline;
friend class RGBA2Timeline;
friend class RGB2Timeline;
friend class DeformTimeline;
friend class DrawOrderFolderTimeline;
friend class DrawOrderTimeline;
friend class EventTimeline;
friend class IkConstraintTimeline;
friend class InheritTimeline;
friend class PathConstraint;
friend class PathConstraintMixTimeline;
friend class PathConstraintPositionTimeline;
friend class PathConstraintSpacingTimeline;
friend class SliderTimeline;
friend class SliderMixTimeline;
friend class ScaleTimeline;
friend class ScaleXTimeline;
friend class ScaleYTimeline;
friend class ShearTimeline;
friend class ShearXTimeline;
friend class ShearYTimeline;
friend class TransformConstraintTimeline;
friend class BoneTimeline1;
friend class BoneTimeline2;
friend class RotateTimeline;
friend class TranslateTimeline;
friend class TranslateXTimeline;
friend class TranslateYTimeline;
friend class TwoColorTimeline;
friend class PhysicsConstraint;
friend class BonePose;
friend class IkConstraint;
friend class PathConstraint;
friend class PhysicsConstraint;
friend class TransformConstraint;
friend class Slider;
public:
explicit Skeleton(SkeletonData &skeletonData);
~Skeleton();
/// Caches information about bones and constraints. Must be called if the active skin is modified or if bones, constraints, or
/// weighted path attachments are added or removed.
void updateCache();
void printUpdateCache();
void constrained(Posed &object);
void sortBone(Bone *bone);
static void sortReset(Array<Bone *> &bones);
/// Updates the world transform for each bone and applies all constraints.
///
/// See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
/// Runtimes Guide.
void updateWorldTransform(Physics physics);
/// Sets the bones, constraints, and slots to their setup pose values.
void setupPose();
/// Sets the bones and constraints to their setup pose values.
void setupPoseBones();
void setupPoseSlots();
SkeletonData &getData();
Array<Bone *> &getBones();
Array<Update *> &getUpdateCache();
Bone *getRootBone();
/// @return May be NULL.
Bone *findBone(const String &boneName);
/// The skeleton's slots in setup pose order. To change the order use DrawOrder::getPose(). For rendering use
/// DrawOrder::getAppliedPose().
Array<Slot *> &getSlots();
/// @return May be NULL.
Slot *findSlot(const String &slotName);
/// The skeleton's draw order. Use DrawOrder::getAppliedPose() for rendering and DrawOrder::getPose() for changing the
/// draw order.
DrawOrder &getDrawOrder();
Skin *getSkin();
/// Sets a skin by name (see setSkin).
void setSkin(const String &skinName);
/// Sets the skin used to look up attachments before looking in SkeletonData::getDefaultSkin(). If the skin is changed,
/// updateCache() is called.
///
/// Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was
/// no old skin, each slot's setup pose placeholder attachment is attached from the new skin.
///
/// After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling
/// setupPoseSlots(). Also, AnimationState::apply(Skeleton&) is often called before the next time the skeleton is rendered
/// so attachment keys in the current animation(s) can hide or show attachments from the new skin.
/// @param newSkin May be NULL.
void setSkin(Skin *newSkin);
/// Finds an attachment by looking in getSkin() and SkeletonData::getDefaultSkin() using the slot name and skin
/// placeholder name. First the skin is checked and if the attachment was not found, the default skin is checked.
/// @return May be NULL.
Attachment *getAttachment(const String &slotName, const String &placeholder);
/// Finds an attachment by looking in getSkin() and SkeletonData::getDefaultSkin() using the slot index and skin
/// placeholder name. First the skin is checked and if the attachment was not found, the default skin is checked.
/// @return May be NULL.
Attachment *getAttachment(int slotIndex, const String &placeholder);
/// A convenience method to set an attachment by finding the slot with findSlot(String), finding the attachment with
/// getAttachment(int, String), then setting the slot's SlotPose::getAttachment().
/// @param placeholder May be empty.
void setAttachment(const String &slotName, const String &placeholder);
Array<Constraint *> &getConstraints();
/// The skeleton's physics constraints.
Array<PhysicsConstraint *> &getPhysicsConstraints();
/// Finds a constraint of the specified type by comparing each constraint's name. It is more efficient to cache the results of
/// this method than to call it multiple times.
template<class T>
T *findConstraint(const String &constraintName) {
if (constraintName.isEmpty()) return NULL;
for (size_t i = 0; i < _constraints.size(); i++) {
Constraint *constraint = _constraints[i];
if (constraint->getRTTI().isExactly(T::rtti)) {
if (constraint->getData().getName() == constraintName) {
return (T *) constraint;
}
}
}
return NULL;
}
/// Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the applied pose.
/// @param outX The horizontal distance between the skeleton origin and the left side of the AABB.
/// @param outY The vertical distance between the skeleton origin and the bottom side of the AABB.
/// @param outWidth The width of the AABB
/// @param outHeight The height of the AABB.
void getBounds(float &outX, float &outY, float &outWidth, float &outHeight);
/// Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the applied pose.
/// @param outX The horizontal distance between the skeleton origin and the left side of the AABB.
/// @param outY The vertical distance between the skeleton origin and the bottom side of the AABB.
/// @param outWidth The width of the AABB
/// @param outHeight The height of the AABB.
/// @param outVertexBuffer Reference to hold an array of floats. This method will assign it with new floats as needed.
/// @param clipping Pointer to a SkeletonClipping instance or NULL. If a clipper is given, clipping attachments will be taken into account.
void getBounds(float &outX, float &outY, float &outWidth, float &outHeight, Array<float> &outVertexBuffer, SkeletonClipping *clipping);
Color &getColor();
void setColor(Color &color);
void setColor(float r, float g, float b, float a);
float getScaleX();
void setScaleX(float inValue);
float getScaleY();
void setScaleY(float inValue);
void setScale(float scaleX, float scaleY);
float getX();
void setX(float inValue);
float getY();
void setY(float inValue);
void setPosition(float x, float y);
void getPosition(float &x, float &y);
/// The x component of a vector that defines the direction PhysicsConstraintPose::getWind() is applied.
float getWindX();
void setWindX(float windX);
/// The y component of a vector that defines the direction PhysicsConstraintPose::getWind() is applied.
float getWindY();
void setWindY(float windY);
/// The x component of a vector that defines the direction PhysicsConstraintPose::getGravity() is applied.
float getGravityX();
void setGravityX(float gravityX);
/// The y component of a vector that defines the direction PhysicsConstraintPose::getGravity() is applied.
float getGravityY();
void setGravityY(float gravityY);
/// Rotates the physics constraint so next {@link #update(Physics)} forces are applied as if the bone rotated around the
/// specified point in world space.
void physicsTranslate(float x, float y);
/// Calls {@link PhysicsConstraint#rotate(float, float, float)} for each physics constraint. */
void physicsRotate(float x, float y, float degrees);
/// Returns the skeleton's time, used for time-based manipulations, such as PhysicsConstraint.
///
/// See update().
float getTime();
void setTime(float time);
void update(float delta);
protected:
SkeletonData &_data;
Array<Bone *> _bones;
Array<Slot *> _slots;
DrawOrder _drawOrder;
Array<Constraint *> _constraints;
Array<PhysicsConstraint *> _physics;
Array<Update *> _updateCache;
Array<Posed *> _resetCache;
Skin *_skin;
Color _color;
float _x, _y;
float _scaleX, _scaleY;
float _windX, _windY, _gravityX, _gravityY;
float _time;
int _update;
};
}// namespace spine
#endif /* Spine_Skeleton_h */
@@ -0,0 +1,267 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SkeletonBinary_h
#define Spine_SkeletonBinary_h
#include <spine/Inherit.h>
#include <spine/Array.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
#include <spine/Color.h>
#include <spine/BoneTimeline.h>
#include <spine/SkeletonData.h>
namespace spine {
class SkeletonData;
class Atlas;
class AttachmentLoader;
class LinkedMesh;
class Skin;
class Attachment;
class VertexAttachment;
class Animation;
class Timeline;
class CurveTimeline;
class CurveTimeline1;
class BoneTimeline2;
class Sequence;
class SP_API SkeletonBinary : public SpineObject {
public:
static const int BONE_ROTATE = 0;
static const int BONE_TRANSLATE = 1;
static const int BONE_TRANSLATEX = 2;
static const int BONE_TRANSLATEY = 3;
static const int BONE_SCALE = 4;
static const int BONE_SCALEX = 5;
static const int BONE_SCALEY = 6;
static const int BONE_SHEAR = 7;
static const int BONE_SHEARX = 8;
static const int BONE_SHEARY = 9;
static const int BONE_INHERIT = 10;
static const int SLOT_ATTACHMENT = 0;
static const int SLOT_RGBA = 1;
static const int SLOT_RGB = 2;
static const int SLOT_RGBA2 = 3;
static const int SLOT_RGB2 = 4;
static const int SLOT_ALPHA = 5;
static const int CONSTRAINT_IK = 0;
static const int CONSTRAINT_PATH = 1;
static const int CONSTRAINT_TRANSFORM = 2;
static const int CONSTRAINT_PHYSICS = 3;
static const int CONSTRAINT_SLIDER = 4;
static const int ATTACHMENT_DEFORM = 0;
static const int ATTACHMENT_SEQUENCE = 1;
static const int PATH_POSITION = 0;
static const int PATH_SPACING = 1;
static const int PATH_MIX = 2;
static const int PHYSICS_INERTIA = 0;
static const int PHYSICS_STRENGTH = 1;
static const int PHYSICS_DAMPING = 2;
static const int PHYSICS_MASS = 4;
static const int PHYSICS_WIND = 5;
static const int PHYSICS_GRAVITY = 6;
static const int PHYSICS_MIX = 7;
static const int PHYSICS_RESET = 8;
static const int SLIDER_TIME = 0;
static const int SLIDER_MIX = 1;
static const int CURVE_LINEAR = 0;
static const int CURVE_STEPPED = 1;
static const int CURVE_BEZIER = 2;
explicit SkeletonBinary(Atlas &atlas);
explicit SkeletonBinary(AttachmentLoader &attachmentLoader, bool ownsLoader = false);
~SkeletonBinary();
SkeletonData *readSkeletonData(const unsigned char *binary, int length);
SkeletonData *readSkeletonDataFile(const String &path);
void setScale(float scale) {
_scale = scale;
}
const String &getError() const {
return _error;
}
private:
struct DataInput : public SpineObject {
const unsigned char *cursor;
const unsigned char *end;
SkeletonData *skeletonData;
DataInput(SkeletonData *skeletonData, const unsigned char *data, size_t length)
: cursor(data), end(data + length), skeletonData(skeletonData) {
}
inline int read() {
return readUnsignedByte();
}
inline signed char readByte() {
return (signed char) *cursor++;
}
inline unsigned char readUnsignedByte() {
return (unsigned char) *cursor++;
}
inline bool readBoolean() {
return readByte() != 0;
}
inline int readInt() {
int result = readUnsignedByte();
result <<= 8;
result |= readUnsignedByte();
result <<= 8;
result |= readUnsignedByte();
result <<= 8;
result |= readUnsignedByte();
return result;
}
inline long long readLong() {
unsigned long long result = (unsigned int) readInt();
result <<= 32;
result |= (unsigned int) readInt();
return (long long) result;
}
inline float readFloat() {
union {
int intValue;
float floatValue;
} intToFloat;
intToFloat.intValue = readInt();
return intToFloat.floatValue;
}
inline void readColor(Color &color) {
color.r = readUnsignedByte() / 255.0f;
color.g = readUnsignedByte() / 255.0f;
color.b = readUnsignedByte() / 255.0f;
color.a = readUnsignedByte() / 255.0f;
}
inline int readInt(bool optimizePositive) {
unsigned char b = readUnsignedByte();
int value = b & 0x7F;
if (b & 0x80) {
b = readUnsignedByte();
value |= (b & 0x7F) << 7;
if (b & 0x80) {
b = readUnsignedByte();
value |= (b & 0x7F) << 14;
if (b & 0x80) {
b = readUnsignedByte();
value |= (b & 0x7F) << 21;
if (b & 0x80) value |= (readUnsignedByte() & 0x7F) << 28;
}
}
}
if (!optimizePositive) value = (((unsigned int) value >> 1) ^ -(value & 1));
return value;
}
char *readString() {
int length = readInt(true);
char *string;
if (length == 0) return NULL;
string = SpineExtension::alloc<char>(length, __FILE__, __LINE__);
memcpy(string, cursor, length - 1);
cursor += length - 1;
string[length - 1] = '\0';
return string;
}
char *readStringRef() {
int index = readInt(true);
return index == 0 ? NULL : skeletonData->_strings[index - 1];
}
};
AttachmentLoader *_attachmentLoader;
Array<LinkedMesh *> _linkedMeshes;
String _error;
float _scale;
const bool _ownsLoader;
void setError(const char *value1, const char *value2);
Skin *readSkin(DataInput &input, SkeletonData &skeletonData, bool defaultSkin, bool nonessential);
Attachment *readAttachment(DataInput &input, Skin &skin, int slotIndex, const String &placeholder, SkeletonData &skeletonData,
bool nonessential);
Sequence *readSequence(DataInput &input, bool hasPathSuffix);
int readVertices(DataInput &input, Array<float> &vertices, Array<int> &bones, bool weighted);
void readFloatArray(DataInput &input, int n, float scale, Array<float> &array);
void readUnsignedShortArray(DataInput &input, Array<unsigned short> &array, int n);
Animation *readAnimation(DataInput &input, const String &name, SkeletonData &skeletonData, bool nonessential);
void readTimeline(DataInput &input, Array<Timeline *> &timelines, CurveTimeline1 &timeline, float scale);
void readTimeline(DataInput &input, Array<Timeline *> &timelines, BoneTimeline2 &timeline, float scale);
void readDrawOrder(DataInput &input, size_t slotCount, Array<int> &drawOrder);
void setBezier(DataInput &input, CurveTimeline &timeline, int bezier, int frame, int value, float time1, float time2, float value1,
float value2, float scale);
};
}// namespace spine
#endif /* Spine_SkeletonBinary_h */
@@ -0,0 +1,135 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SkeletonBounds_h
#define Spine_SkeletonBounds_h
#include <spine/Array.h>
#include <spine/Pool.h>
#include <spine/SpineObject.h>
namespace spine {
class Skeleton;
class BoundingBoxAttachment;
class Polygon;
/// Collects each BoundingBoxAttachment that is visible and computes the world vertices for its polygon.
/// The polygon vertices are provided along with convenience methods for doing hit detection.
class SP_API SkeletonBounds : public SpineObject {
public:
SkeletonBounds();
~SkeletonBounds();
/// Clears any previous polygons, finds all visible bounding box attachments,
/// and computes the world vertices for each bounding box's polygon.
/// @param skeleton The skeleton.
/// @param updateAabb
/// If true, the axis aligned bounding box containing all the polygons is computed.
/// If false, the SkeletonBounds AABB methods will always return true.
///
void update(Skeleton &skeleton, bool updateAabb);
/// Returns true if the axis aligned bounding box contains the point.
bool aabbContainsPoint(float x, float y);
/// Returns true if the axis aligned bounding box intersects the line segment.
bool aabbIntersectsSegment(float x1, float y1, float x2, float y2);
/// Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds.
bool aabbIntersectsSkeleton(SkeletonBounds &bounds);
/// Returns true if the polygon contains the point.
bool containsPoint(Polygon &polygon, float x, float y);
/// Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
/// efficient to only call this method if aabbContainsPoint(float, float) returns true.
BoundingBoxAttachment *containsPoint(float x, float y);
/// Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it
/// is usually more efficient to only call this method if aabbIntersectsSegment(float, float, float, float) returns true.
BoundingBoxAttachment *intersectsSegment(float x1, float y1, float x2, float y2);
/// Returns true if the polygon contains any part of the line segment.
bool intersectsSegment(Polygon &polygon, float x1, float y1, float x2, float y2);
/// Returns the polygon for the given bounding box attachment or null if no
/// polygon can be found for the attachment. Requires a call to update() first.
Polygon *getPolygon(BoundingBoxAttachment *attachment);
/// Returns the bounding box for the given polygon or null. Requires a call to update() first.
BoundingBoxAttachment *getBoundingBox(Polygon *polygon);
/// Returns all polygons or an empty array. Requires a call to update() first.
Array<Polygon *> &getPolygons();
/// Returns all bounding boxes. Requires a call to update() first.
Array<BoundingBoxAttachment *> &getBoundingBoxes();
/// The left edge of the axis aligned bounding box.
float getMinX();
/// The bottom edge of the axis aligned bounding box.
float getMinY();
/// The right edge of the axis aligned bounding box.
float getMaxX();
/// The top edge of the axis aligned bounding box.
float getMaxY();
/// The width of the axis aligned bounding box.
float getWidth();
/// The height of the axis aligned bounding box.
float getHeight();
private:
Pool<Polygon> _polygonPool;
Array<BoundingBoxAttachment *> _boundingBoxes;
Array<Polygon *> _polygons;
float _minX, _minY, _maxX, _maxY;
void aabbCompute();
};
class Polygon : public SpineObject {
public:
Array<float> _vertices;
int _count;
Polygon() : _count(0) {
_vertices.ensureCapacity(16);
}
};
}
#endif /* Spine_SkeletonBounds_h */
@@ -0,0 +1,90 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SkeletonClipping_h
#define Spine_SkeletonClipping_h
#include <spine/Array.h>
#include <spine/Triangulator.h>
namespace spine {
class Slot;
class Skeleton;
class ClippingAttachment;
class SP_API SkeletonClipping : public SpineObject {
public:
SkeletonClipping();
size_t clipStart(Skeleton &skeleton, Slot &slot, ClippingAttachment *clip);
void clipEnd(Slot &slot);
void clipEnd();
bool clipTriangles(float *vertices, unsigned short *triangles, size_t trianglesLength);
bool clipTriangles(float *vertices, unsigned short *triangles, size_t trianglesLength, float *uvs, size_t stride);
bool clipTriangles(Array<float> &vertices, Array<unsigned short> &triangles, Array<float> &uvs, size_t stride);
bool isClipping();
Array<float> &getClippedVertices();
Array<unsigned short> &getClippedTriangles();
Array<float> &getClippedUVs();
private:
Triangulator _triangulator;
Array<float> _clippingPolygon;
Array<Array<float> *> _clippingPolygons;
Array<float> _clipOutput;
Array<float> _clippedVertices;
Array<unsigned short> _clippedTriangles;
Array<float> _clippedUVs;
Array<float> _inverseVertices;
Array<float> _scratch;
ClippingAttachment *_clipAttachment;
bool _inverse;
/** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping
* area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */
bool clip(float x1, float y1, float x2, float y2, float x3, float y3, Array<float> *polygon);
void clipInverse(float x1, float y1, float x2, float y2, float x3, float y3, Array<float> *polygon);
static bool makeClockwise(Array<float> &polygon);
void makeConvex(Array<float> &polygon);
};
}
#endif /* Spine_SkeletonClipping_h */
@@ -0,0 +1,213 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SkeletonData_h
#define Spine_SkeletonData_h
#include <spine/Array.h>
#include <spine/SpineString.h>
#include <spine/ConstraintData.h>
namespace spine {
class BoneData;
class SlotData;
class Skin;
class EventData;
class Animation;
class IkConstraintData;
class TransformConstraintData;
class PathConstraintData;
class PhysicsConstraintData;
class ConstraintData;
/// Stores the setup pose and all of the stateless data for a skeleton.
///
/// See <a href="https://esotericsoftware.com/spine-runtime-architecture#Data-objects">Data objects</a> in the Spine Runtimes
/// Guide.
class SP_API SkeletonData : public SpineObject {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class Skeleton;
public:
SkeletonData();
~SkeletonData();
/// Finds a bone by comparing each bone's name.
/// It is more efficient to cache the results of this method than to call it multiple times.
/// @return May be NULL.
BoneData *findBone(const String &boneName);
/// @return May be NULL.
SlotData *findSlot(const String &slotName);
/// @return May be NULL.
Skin *findSkin(const String &skinName);
/// @return May be NULL.
EventData *findEvent(const String &eventDataName);
/// @return May be NULL.
Animation *findAnimation(const String &animationName);
/// Collects animations used by slider constraints.
Array<Animation *> &findSliderAnimations(Array<Animation *> &animations);
/// The skeleton's name, which by default is the name of the skeleton data file when possible, or null when a name hasn't been
/// set.
const String &getName();
void setName(const String &inValue);
/// The skeleton's bones, sorted parent first. The root bone is always the first bone.
Array<BoneData *> &getBones();
/// The skeleton's slots in the setup pose draw order.
Array<SlotData *> &getSlots();
/// All skins, including the default skin.
Array<Skin *> &getSkins();
/// The skeleton's default skin.
/// By default this skin contains all attachments that were not in a skin in Spine.
/// @return May be NULL.
Skin *getDefaultSkin();
void setDefaultSkin(Skin *inValue);
/// The skeleton's events.
Array<EventData *> &getEvents();
/// The skeleton's animations.
Array<Animation *> &getAnimations();
/// The skeleton's constraints.
Array<ConstraintData *> &getConstraints();
/// Finds a constraint of the specified type by comparing each constraint's name. It is more efficient to cache the results of
/// this method than to call it multiple times.
/// @return May be NULL.
template<class T>
T *findConstraint(const String &constraintName) {
getConstraints();// Ensure constraints array is populated
for (size_t i = 0, n = _constraints.size(); i < n; i++) {
ConstraintData *constraint = _constraints[i];
if (constraint->getName() == constraintName && constraint->getRTTI().instanceOf(T::rtti)) {
return static_cast<T *>(constraint);
}
}
return NULL;
}
/// The X coordinate of the skeleton's axis aligned bounding box in the setup pose.
float getX();
void setX(float inValue);
/// The Y coordinate of the skeleton's axis aligned bounding box in the setup pose.
float getY();
void setY(float inValue);
/// The width of the skeleton's axis aligned bounding box in the setup pose.
float getWidth();
void setWidth(float inValue);
/// The height of the skeleton's axis aligned bounding box in the setup pose.
float getHeight();
void setHeight(float inValue);
/// Baseline scale factor for applying physics and other effects based on distance to non-scalable properties, such as angle or
/// scale. Default is 100.
float getReferenceScale();
void setReferenceScale(float inValue);
/// The Spine version used to export this data, or NULL.
const String &getVersion();
void setVersion(const String &inValue);
/// The skeleton data hash. This value will change if any of the skeleton data has changed.
const String &getHash();
void setHash(const String &inValue);
/// The path to the images folder as defined in Spine, or null if nonessential data was not exported.
const String &getImagesPath();
void setImagesPath(const String &inValue);
/// The path to the audio folder as defined in Spine, or null if nonessential data was not exported.
const String &getAudioPath();
void setAudioPath(const String &inValue);
/// The dopesheet FPS in Spine. Available only when nonessential data was exported.
float getFps();
void setFps(float inValue);
private:
String _name;
Array<BoneData *> _bones;// Ordered parents first
Array<SlotData *> _slots;// Setup pose draw order.
Array<Skin *> _skins;
Skin *_defaultSkin;
Array<EventData *> _events;
Array<Animation *> _animations;
Array<ConstraintData *> _constraints;
float _x, _y, _width, _height;
float _referenceScale;
String _version;
String _hash;
Array<char *> _strings;
// Nonessential.
float _fps;
String _imagesPath;
String _audioPath;
};
}
#endif /* Spine_SkeletonData_h */
@@ -0,0 +1,122 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SkeletonJson_h
#define Spine_SkeletonJson_h
#include <spine/Array.h>
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
namespace spine {
class Timeline;
class CurveTimeline;
class CurveTimeline1;
class BoneTimeline2;
class VertexAttachment;
class Animation;
class Json;
class SkeletonData;
class Atlas;
class AttachmentLoader;
class LinkedMesh;
class String;
class Sequence;
class Skin;
class Attachment;
class SP_API SkeletonJson : public SpineObject {
public:
explicit SkeletonJson(Atlas &atlas);
explicit SkeletonJson(AttachmentLoader &attachmentLoader, bool ownsLoader = false);
~SkeletonJson();
SkeletonData *readSkeletonDataFile(const String &path);
SkeletonData *readSkeletonData(const char *json);
void setScale(float scale) {
_scale = scale;
}
const String &getError() const {
return _error;
}
private:
AttachmentLoader *_attachmentLoader;
Array<LinkedMesh *> _linkedMeshes;
float _scale;
const bool _ownsLoader;
String _error;
static Sequence *readSequence(Json *sequence);
static void setBezier(CurveTimeline *timeline, int frame, int value, int bezier, float time1, float value1, float cx1, float cy1, float cx2,
float cy2, float time2, float value2);
static int readCurve(Json *curve, CurveTimeline *timeline, int bezier, int frame, int value, float time1, float time2, float value1,
float value2, float scale);
static void readTimeline(Array<Timeline *> &timelines, Json *keyMap, CurveTimeline1 *timeline, float defaultValue, float scale);
static void readTimeline(Array<Timeline *> &timelines, Json *keyMap, BoneTimeline2 *timeline, const char *name1, const char *name2,
float defaultValue, float scale);
Animation *readAnimation(Json *root, SkeletonData *skeletonData);
Attachment *readAttachment(Json *map, Skin *skin, int slotIndex, const char *placeholder, SkeletonData *skeletonData);
void readVertices(Json *attachmentMap, VertexAttachment *attachment, size_t verticesLength);
bool readDrawOrder(SkeletonData *skeletonData, Json *keyMap, int slotCount, const Array<int> *folderSlots, Array<int> &drawOrder);
void setError(Json *root, const String &value1, const String &value2);
int findSlotIndex(SkeletonData *skeletonData, const String &slotName, Array<Timeline *> timelines);
};
}
#endif /* Spine_SkeletonJson_h */
@@ -0,0 +1,70 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SkeletonRenderer_h
#define Spine_SkeletonRenderer_h
#include <spine/BlockAllocator.h>
#include <spine/BlendMode.h>
#include <spine/SkeletonClipping.h>
namespace spine {
class Skeleton;
struct SP_API RenderCommand {
float *positions;
float *uvs;
uint32_t *colors;
uint32_t *darkColors;
int32_t numVertices;
uint16_t *indices;
int32_t numIndices;
BlendMode blendMode;
void *texture;
RenderCommand *next;
};
class SP_API SkeletonRenderer : public SpineObject {
public:
explicit SkeletonRenderer();
~SkeletonRenderer();
RenderCommand *render(Skeleton &skeleton);
private:
BlockAllocator _allocator;
Array<float> _worldVertices;
Array<unsigned short> _quadIndices;
SkeletonClipping _clipping;
Array<RenderCommand *> _renderCommands;
};
}
#endif
@@ -0,0 +1,170 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Skin_h
#define Spine_Skin_h
#include <spine/Array.h>
#include <spine/SpineString.h>
#include <spine/Color.h>
namespace spine {
class Attachment;
class Skeleton;
class BoneData;
class ConstraintData;
/// Stores attachments by slot index and placeholder name. Multiple Skeleton instances can use the same skins.
/// See SkeletonData::getDefaultSkin, Skeleton::getSkin, and
/// http://esotericsoftware.com/spine-runtime-skins in the Spine Runtimes Guide.
class SP_API Skin : public SpineObject {
friend class Skeleton;
public:
class SP_API AttachmentMap : public SpineObject {
friend class Skin;
public:
struct SP_API Entry {
size_t _slotIndex;
String _placeholder;
Attachment *_attachment;
Entry(size_t slotIndex, const String &placeholder, Attachment *attachment)
: _slotIndex(slotIndex), _placeholder(placeholder), _attachment(attachment) {
}
};
class SP_API Entries {
friend class AttachmentMap;
public:
bool hasNext() {
while (true) {
if (_slotIndex >= _buckets.size()) return false;
if (_bucketIndex >= _buckets[_slotIndex].size()) {
_bucketIndex = 0;
++_slotIndex;
continue;
};
return true;
}
}
Entry &next() {
Entry &result = _buckets[_slotIndex][_bucketIndex];
++_bucketIndex;
return result;
}
protected:
Entries(Array<Array<Entry>> &buckets) : _buckets(buckets), _slotIndex(0), _bucketIndex(0) {
}
private:
Array<Array<Entry>> &_buckets;
size_t _slotIndex;
size_t _bucketIndex;
};
void put(size_t slotIndex, const String &placeholder, Attachment *attachment);
Attachment *get(size_t slotIndex, const String &placeholder);
void remove(size_t slotIndex, const String &placeholder);
Entries getEntries();
protected:
AttachmentMap();
private:
int findInBucket(Array<Entry> &, const String &placeholder);
Array<Array<Entry>> _buckets;
};
explicit Skin(const String &name);
~Skin();
/// Adds an attachment to the skin for the specified slot index and placeholder name.
/// If the placeholder name already exists for the slot, the previous value is replaced.
void setAttachment(size_t slotIndex, const String &placeholder, Attachment *attachment);
/// Returns the attachment for the specified slot index and placeholder name, or NULL.
Attachment *getAttachment(size_t slotIndex, const String &placeholder);
// Removes the attachment from the skin.
void removeAttachment(size_t slotIndex, const String &placeholder);
/// Finds the placeholder names for a given slot. The results are added to the passed array.
/// @param slotIndex The target slotIndex. To find the slot index, use SkeletonData::findSlot and SlotData::getIndex.
/// @param names Found placeholder names will be added to this array.
void findNamesForSlot(size_t slotIndex, Array<String> &names);
/// Finds the attachments for a given slot. The results are added to the passed array of Attachments.
/// @param slotIndex The target slotIndex. To find the slot index, use SkeletonData::findSlot and SlotData::getIndex.
/// @param attachments Found Attachments will be added to this array.
void findAttachmentsForSlot(size_t slotIndex, Array<Attachment *> &attachments);
const String &getName();
/// Adds all attachments, bones, and constraints from the specified skin to this skin.
void addSkin(Skin &other);
/// Adds all attachments, bones, and constraints from the specified skin to this skin. Attachments are deep copied.
void copySkin(Skin &other);
AttachmentMap::Entries getAttachments();
Array<BoneData *> &getBones();
Array<ConstraintData *> &getConstraints();
Color &getColor() {
return _color;
}
private:
const String _name;
AttachmentMap _attachments;
Array<BoneData *> _bones;
Array<ConstraintData *> _constraints;
Color _color;
/// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached.
void attachAll(Skeleton &skeleton, Skin &oldSkin);
};
}
#endif /* Spine_Skin_h */
@@ -0,0 +1,81 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Slider_h
#define Spine_Slider_h
#include <spine/Constraint.h>
#include <spine/SliderData.h>
#include <spine/SliderPose.h>
namespace spine {
class Skeleton;
class Bone;
class Animation;
/// Applies an animation based on either the slider's SliderPose::getTime() or a bone's transform property.
///
/// See https://esotericsoftware.com/spine-sliders Sliders in the Spine User Guide.
// Non-exported base class that inherits from the template
class SliderBase : public ConstraintGeneric<Slider, SliderData, SliderPose> {
public:
SliderBase(SliderData &data) : ConstraintGeneric<Slider, SliderData, SliderPose>(data) {
}
};
class SP_API Slider : public SliderBase {
friend class Skeleton;
friend class SliderTimeline;
friend class SliderMixTimeline;
RTTI_DECL
public:
Slider(SliderData &data, Skeleton &skeleton);
Slider &copy(Skeleton &skeleton);
virtual void update(Skeleton &skeleton, Physics physics) override;
virtual void sort(Skeleton &skeleton) override;
virtual bool isSourceActive() override;
/// When set, the bone's transform property is used to set the slider's SliderPose::getTime().
Bone &getBone();
void setBone(Bone &bone);
private:
Bone *_bone;
static float _offsets[6];
};
}
#endif /* Spine_Slider_h */
@@ -0,0 +1,112 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SliderData_h
#define Spine_SliderData_h
#include <spine/ConstraintData.h>
#include <spine/PosedData.h>
#include <spine/SliderPose.h>
#include <spine/SpineString.h>
namespace spine {
class Animation;
class BoneData;
class FromProperty;
class Slider;
class Skeleton;
/// Stores the setup pose for a Slider
class SP_API SliderData : public ConstraintDataGeneric<Slider, SliderPose> {
friend class SkeletonBinary;
friend class SkeletonData;
friend class SkeletonJson;
friend class Slider;
friend class SliderMixTimeline;
friend class SliderTimeline;
RTTI_DECL
public:
explicit SliderData(const String &name);
~SliderData();
/// Creates a slider instance.
virtual Constraint &create(Skeleton &skeleton) override;
/// The animation the slider will apply.
Animation &getAnimation();
void setAnimation(Animation &animation);
/// When true, the animation is applied by adding it to the current pose rather than overwriting it.
bool getAdditive();
void setAdditive(bool additive);
/// When true, the animation repeats after its duration, otherwise the last frame is used.
bool getLoop();
void setLoop(bool loop);
/// When set, the bone's transform property is used to set the slider's SliderPose::getTime().
BoneData *getBone();
void setBone(BoneData *bone);
/// When a bone is set, the specified transform property is used to set the slider's SliderPose::getTime().
FromProperty *getProperty();
void setProperty(FromProperty *property);
/// When a bone is set, this is the scale of the property value in relation to the slider time.
float getScale();
void setScale(float scale);
/// When a bone is set, the offset is added to the property.
float getOffset();
void setOffset(float offset);
/// When a bone is set, the maximum slider time for the bone property range, or 0 if nonessential data was not exported.
float getMax();
void setMax(float max);
/// When true and a bone is set, the bone's local transform property is read instead of its world transform.
bool getLocal();
void setLocal(bool local);
private:
Animation *_animation;
bool _additive;
bool _loop;
BoneData *_bone;
FromProperty *_property;
float _offset;
float _scale;
float _max;
bool _local;
};
}
#endif /* Spine_SliderData_h */
@@ -0,0 +1,53 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SliderMixTimeline_h
#define Spine_SliderMixTimeline_h
#include <spine/ConstraintTimeline1.h>
namespace spine {
/// Changes a slider's mix.
class SP_API SliderMixTimeline : public ConstraintTimeline1 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit SliderMixTimeline(size_t frameCount, size_t bezierCount, int sliderIndex);
virtual ~SliderMixTimeline();
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
};
}
#endif /* Spine_SliderMixTimeline_h */
@@ -0,0 +1,66 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SliderPose_h
#define Spine_SliderPose_h
#include <spine/Pose.h>
#include <spine/RTTI.h>
namespace spine {
class Slider;
/// Stores a pose for a slider.
class SP_API SliderPose : public Pose<SliderPose> {
friend class Slider;
friend class SliderMixTimeline;
friend class SliderTimeline;
friend class SkeletonJson;
friend class SkeletonBinary;
private:
float _time, _mix;
public:
SliderPose();
virtual ~SliderPose();
virtual void set(SliderPose &pose) override;
/// The time in SliderData::getAnimation() to apply the animation.
float getTime();
void setTime(float time);
/// A percentage (unbounded) that controls the mix between the constrained and unconstrained poses.
float getMix();
void setMix(float mix);
};
}
#endif
@@ -0,0 +1,53 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SliderTimeline_h
#define Spine_SliderTimeline_h
#include <spine/ConstraintTimeline1.h>
namespace spine {
/// Changes a slider's time.
class SP_API SliderTimeline : public ConstraintTimeline1 {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
explicit SliderTimeline(size_t frameCount, size_t bezierCount, int sliderIndex);
virtual ~SliderTimeline();
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
};
}
#endif /* Spine_SliderTimeline_h */
@@ -0,0 +1,113 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Slot_h
#define Spine_Slot_h
#include <spine/Posed.h>
#include <spine/SlotData.h>
#include <spine/SlotPose.h>
#include <spine/Array.h>
#include <spine/Color.h>
#include <spine/Update.h>
namespace spine {
class Bone;
class Skeleton;
class Attachment;
/// Organizes attachments for Skeleton drawOrder purposes and provide a place to store state for an attachment.
///
/// State cannot be stored in an attachment itself because attachments are stateless and may be shared across multiple
/// skeletons.
class SP_API Slot : public PosedGeneric<SlotData, SlotPose, SlotPose> {
friend class VertexAttachment;
friend class Skeleton;
friend class SkeletonBounds;
friend class SkeletonClipping;
friend class SlotCurveTimeline;
friend class AttachmentTimeline;
friend class RGBATimeline;
friend class RGBTimeline;
friend class AlphaTimeline;
friend class RGBA2Timeline;
friend class RGB2Timeline;
friend class DeformTimeline;
friend class DrawOrderTimeline;
friend class EventTimeline;
friend class IkConstraintTimeline;
friend class PathConstraintMixTimeline;
friend class PathConstraintPositionTimeline;
friend class PathConstraintSpacingTimeline;
friend class ScaleTimeline;
friend class ShearTimeline;
friend class TransformConstraintTimeline;
friend class TranslateTimeline;
friend class TwoColorTimeline;
friend class AnimationState;
public:
Slot(SlotData &data, Skeleton &skeleton);
/// The bone this slot belongs to.
Bone &getBone();
void setupPose() override;
private:
Skeleton &_skeleton;
Bone &_bone;
int _attachmentState;
};
}
#endif /* Spine_Slot_h */
@@ -0,0 +1,67 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SlotCurveTimeline_h
#define Spine_SlotCurveTimeline_h
#include <spine/CurveTimeline.h>
#include <spine/SlotTimeline.h>
namespace spine {
class Slot;
class SlotPose;
/// Base class for slot timelines that use curves.
class SP_API SlotCurveTimeline : public CurveTimeline, public SlotTimeline {
friend class SkeletonBinary;
friend class SkeletonJson;
RTTI_DECL
public:
SlotCurveTimeline(size_t frameCount, size_t frameEntries, size_t bezierCount, int slotIndex);
virtual ~SlotCurveTimeline();
virtual void apply(Skeleton &skeleton, float lastTime, float time, Array<Event *> *events, float alpha, MixFrom from, bool add, bool out,
bool appliedPose) override;
virtual int getSlotIndex() override;
virtual void setSlotIndex(int inValue) override;
protected:
/// Applies the timeline to the slot pose.
virtual void _apply(Slot &slot, SlotPose &pose, float time, float alpha, MixFrom from, bool add) = 0;
int _slotIndex;
};
}
#endif /* Spine_SlotCurveTimeline_h */
@@ -0,0 +1,98 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SlotData_h
#define Spine_SlotData_h
#include <spine/BlendMode.h>
#include <spine/PosedData.h>
#include <spine/SpineString.h>
#include <spine/RTTI.h>
#include <spine/SlotPose.h>
namespace spine {
class BoneData;
/// Stores the setup pose for a Slot.
class SP_API SlotData : public PosedDataGeneric<SlotPose> {
friend class SkeletonBinary;
friend class SkeletonJson;
friend class PathConstraint;
friend class AttachmentTimeline;
friend class RGBATimeline;
friend class RGBTimeline;
friend class AlphaTimeline;
friend class RGBA2Timeline;
friend class RGB2Timeline;
friend class DeformTimeline;
friend class DrawOrderTimeline;
friend class EventTimeline;
friend class IkConstraintTimeline;
friend class PathConstraintMixTimeline;
friend class PathConstraintPositionTimeline;
friend class PathConstraintSpacingTimeline;
friend class ScaleTimeline;
friend class ShearTimeline;
friend class TransformConstraintTimeline;
friend class TranslateTimeline;
friend class TwoColorTimeline;
friend class Slot;
public:
SlotData(int index, const String &name, BoneData &boneData);
/// The Skeleton::getSlots() index for this slot.
int getIndex();
/// The bone this slot belongs to.
BoneData &getBoneData();
void setAttachmentName(const String &attachmentName);
/// The name of the attachment that is visible for this slot in the setup pose, or empty if no attachment is visible.
const String &getAttachmentName();
/// The blend mode for drawing the slot's attachment.
BlendMode getBlendMode();
void setBlendMode(BlendMode blendMode);
/// False if the slot was hidden in Spine and nonessential data was exported. Does not affect runtime rendering.
bool getVisible();
void setVisible(bool visible);
private:
const int _index;
BoneData &_boneData;
String _attachmentName;
BlendMode _blendMode;
bool _visible;
};
}
#endif /* Spine_SlotData_h */
@@ -0,0 +1,106 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated January 1, 2020. Replaces all prior versions.
*
* Copyright (c) 2013-2020, 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.
*****************************************************************************/
#ifndef SPINE_SLOTPOSE_H_
#define SPINE_SLOTPOSE_H_
#include <spine/SpineObject.h>
#include <spine/RTTI.h>
#include <spine/Pose.h>
#include <spine/Color.h>
#include <spine/Array.h>
namespace spine {
class Attachment;
class VertexAttachment;
/// Stores a slot's pose.
class SP_API SlotPose : public Pose<SlotPose> {
friend class Slot;
friend class SlotCurveTimeline;
friend class DeformTimeline;
friend class RGBATimeline;
friend class RGBTimeline;
friend class AlphaTimeline;
friend class RGBA2Timeline;
friend class RGB2Timeline;
friend class PathConstraint;
friend class SkeletonJson;
friend class SkeletonBinary;
friend class AnimationState;
protected:
Color _color;
Color _darkColor;
bool _hasDarkColor;
Attachment *_attachment;
int _sequenceIndex;
Array<float> _deform;
public:
SlotPose();
virtual ~SlotPose();
virtual void set(SlotPose &pose) override;
/// The color used to tint the slot's attachment. If a dark color is set, this is used as the light color for two color
/// tinting.
Color &getColor();
/// The dark color used to tint the slot's attachment for two color tinting. The dark
/// color's alpha is not used.
Color &getDarkColor();
/// Returns true if this slot has a dark color.
bool hasDarkColor();
void setHasDarkColor(bool hasDarkColor);
/// The current attachment for the slot, or null if the slot has no attachment.
Attachment *getAttachment();
/// Sets the slot's attachment and, if the attachment changed, resets sequenceIndex and clears the deform.
/// The deform is not cleared if the old attachment has the same VertexAttachment::getTimelineAttachment() as the
/// specified attachment.
void setAttachment(Attachment *attachment);
/// The index of the texture region to display when the slot's attachment has a Sequence. -1 represents the
/// Sequence::getSetupIndex().
int getSequenceIndex();
void setSequenceIndex(int sequenceIndex);
/// Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a
/// weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions.
///
/// See VertexAttachment::computeWorldVertices() and DeformTimeline.
Array<float> &getDeform();
};
}
#endif /* SPINE_SLOTPOSE_H_ */
@@ -0,0 +1,58 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SlotTimeline_h
#define Spine_SlotTimeline_h
#include <spine/dll.h>
#include <spine/RTTI.h>
namespace spine {
/// An interface for timelines which change the property of a slot.
class SP_API SlotTimeline {
RTTI_DECL_NOPARENT
friend class AlphaTimeline;
friend class AttachmentTimeline;
friend class SequenceTimeline;
friend class SlotCurveTimeline;
public:
SlotTimeline();
virtual ~SlotTimeline();
/// The Skeleton::getSlots() index of the slot that will be changed when this timeline is applied.
virtual int getSlotIndex() = 0;
virtual void setSlotIndex(int inValue) = 0;
};
}
#endif /* Spine_SlotTimeline_h */
@@ -0,0 +1,60 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_SpacingMode_h
#define Spine_SpacingMode_h
#include <string.h>
namespace spine {
/// Controls how bones after the first bone are positioned along the path.
///
/// @see https://esotericsoftware.com/spine-path-constraints#Spacing-mode Spacing mode in the Spine User Guide.
enum SpacingMode {
SpacingMode_Length = 0,
SpacingMode_Fixed,
SpacingMode_Percent,
SpacingMode_Proportional
};
inline SpacingMode SpacingMode_valueOf(const char *value) {
if (strcmp(value, "length") == 0)
return SpacingMode_Length;
else if (strcmp(value, "fixed") == 0)
return SpacingMode_Fixed;
else if (strcmp(value, "percent") == 0)
return SpacingMode_Percent;
else if (strcmp(value, "proportional") == 0)
return SpacingMode_Proportional;
else
return SpacingMode_Length;// default
}
}
#endif /* Spine_SpacingMode_h */
@@ -0,0 +1,59 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_Object_h
#define Spine_Object_h
#include <new>
#include <stddef.h>
#include <spine/dll.h>
namespace spine {
class String;
class SP_API SpineObject {
public:
void *operator new(size_t sz);
void *operator new(size_t sz, const char *file, int line);
void *operator new(size_t sz, void *ptr);
void operator delete(void *p, const char *file, int line);
void operator delete(void *p, void *mem);
void operator delete(void *p);
virtual ~SpineObject();
};
}
#endif
@@ -0,0 +1,255 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef SPINE_STRING_H
#define SPINE_STRING_H
#include <spine/SpineObject.h>
#include <spine/Extension.h>
#include <string.h>
#include <stdio.h>
namespace spine {
class SP_API String : public SpineObject {
public:
String() : _length(0), _buffer(NULL), _tempowner(true) {
}
String(const char *chars, bool own = false, bool tofree = true) {
_tempowner = tofree;
if (!chars) {
_length = 0;
_buffer = NULL;
} else {
_length = strlen(chars);
if (!own) {
_buffer = SpineExtension::calloc<char>(_length + 1, __FILE__, __LINE__);
memcpy((void *) _buffer, chars, _length + 1);
} else {
_buffer = (char *) chars;
}
}
}
String(const String &other) {
_tempowner = true;
if (!other._buffer) {
_length = 0;
_buffer = NULL;
} else {
_length = other._length;
_buffer = SpineExtension::calloc<char>(other._length + 1, __FILE__, __LINE__);
memcpy((void *) _buffer, other._buffer, other._length + 1);
}
}
size_t length() const {
return _length;
}
bool isEmpty() const {
return _length == 0;
}
const char *buffer() const {
return _buffer;
}
void own(const String &other) {
if (this == &other) return;
if (_buffer && _tempowner) {
SpineExtension::free(_buffer, __FILE__, __LINE__);
}
_length = other._length;
_buffer = other._buffer;
other._length = 0;
other._buffer = NULL;
}
void own(const char *chars) {
if (_buffer == chars) return;
if (_buffer && _tempowner) {
SpineExtension::free(_buffer, __FILE__, __LINE__);
}
if (!chars) {
_length = 0;
_buffer = NULL;
} else {
_length = strlen(chars);
_buffer = (char *) chars;
}
}
void unown() {
_length = 0;
_buffer = NULL;
}
String &operator=(const String &other) {
if (this == &other) return *this;
if (_buffer && _tempowner) {
SpineExtension::free(_buffer, __FILE__, __LINE__);
}
if (!other._buffer) {
_length = 0;
_buffer = NULL;
} else {
_length = other._length;
_buffer = SpineExtension::calloc<char>(other._length + 1, __FILE__, __LINE__);
memcpy((void *) _buffer, other._buffer, other._length + 1);
}
return *this;
}
String &operator=(const char *chars) {
if (_buffer == chars) return *this;
if (_buffer && _tempowner) {
SpineExtension::free(_buffer, __FILE__, __LINE__);
}
if (!chars) {
_length = 0;
_buffer = NULL;
} else {
_length = strlen(chars);
_buffer = SpineExtension::calloc<char>(_length + 1, __FILE__, __LINE__);
memcpy((void *) _buffer, chars, _length + 1);
}
return *this;
}
String &append(const char *chars) {
size_t len = strlen(chars);
size_t thisLen = _length;
_length = _length + len;
bool same = chars == _buffer;
_buffer = SpineExtension::realloc(_buffer, _length + 1, __FILE__, __LINE__);
memcpy((void *) (_buffer + thisLen), (void *) (same ? _buffer : chars), len + 1);
return *this;
}
String &append(const String &other) {
size_t len = other.length();
size_t thisLen = _length;
_length = _length + len;
bool same = other._buffer == _buffer;
_buffer = SpineExtension::realloc(_buffer, _length + 1, __FILE__, __LINE__);
memcpy((void *) (_buffer + thisLen), (void *) (same ? _buffer : other._buffer), len + 1);
return *this;
}
String &append(int other) {
char str[100];
snprintf(str, 100, "%i", other);
append(str);
return *this;
}
String &append(float other) {
char str[100];
snprintf(str, 100, "%f", other);
append(str);
return *this;
}
String &append(char c) {
size_t thisLen = _length;
_length = _length + 1;
_buffer = SpineExtension::realloc(_buffer, _length + 1, __FILE__, __LINE__);
_buffer[thisLen] = c;
_buffer[_length] = '\0';
return *this;
}
bool startsWith(const String &needle) const {
if (needle.length() > length()) return false;
for (int i = 0; i < (int) needle.length(); i++) {
if (buffer()[i] != needle.buffer()[i]) return false;
}
return true;
}
int lastIndexOf(const char c) const {
for (int i = (int) length() - 1; i >= 0; i--) {
if (buffer()[i] == c) return i;
}
return -1;
}
String substring(int startIndex, int length) const {
if (startIndex < 0 || startIndex >= (int) _length || length < 0 || startIndex + length > (int) _length) {
return String();
}
char *subStr = SpineExtension::calloc<char>(length + 1, __FILE__, __LINE__);
memcpy(subStr, _buffer + startIndex, length);
subStr[length] = '\0';
return String(subStr, true, true);
}
String substring(int startIndex) const {
if (startIndex < 0 || startIndex >= (int) _length) {
return String();
}
int length = (int) _length - startIndex;
char *subStr = SpineExtension::calloc<char>(length + 1, __FILE__, __LINE__);
memcpy(subStr, _buffer + startIndex, length);
subStr[length] = '\0';
return String(subStr, true, true);
}
friend bool operator==(const String &a, const String &b) {
if (a._buffer == b._buffer) return true;
if (a._length != b._length) return false;
if (a._buffer && b._buffer) {
return strcmp(a._buffer, b._buffer) == 0;
} else {
return false;
}
}
friend bool operator!=(const String &a, const String &b) {
return !(a == b);
}
~String() {
if (_buffer && _tempowner) {
SpineExtension::free(_buffer, __FILE__, __LINE__);
}
}
private:
mutable size_t _length;
mutable char *_buffer;
mutable bool _tempowner;
};
}
#endif//SPINE_STRING_H
@@ -0,0 +1,51 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#ifndef Spine_TextureLoader_h
#define Spine_TextureLoader_h
#include <spine/SpineObject.h>
#include <spine/SpineString.h>
namespace spine {
class AtlasPage;
class SP_API TextureLoader : public SpineObject {
public:
TextureLoader();
virtual ~TextureLoader();
virtual void load(AtlasPage &page, const String &path) = 0;
virtual void unload(void *texture) = 0;
};
}
#endif /* Spine_TextureLoader_h */

Some files were not shown because too many files have changed in this diff Show More