mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
wip
Almost ready to implement file loading
This commit is contained in:
parent
c3e94bee82
commit
87a18e22b8
82
spine-cpp/spine-cpp/include/spine/Animation.h
Normal file
82
spine-cpp/spine-cpp/include/spine/Animation.h
Normal file
@ -0,0 +1,82 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Animation_h
|
||||
#define Spine_Animation_h
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/MixPose.h>
|
||||
#include <spine/MixDirection.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
class Timeline;
|
||||
class Skeleton;
|
||||
class Event;
|
||||
|
||||
class Animation
|
||||
{
|
||||
friend class RotateTimeline;
|
||||
|
||||
public:
|
||||
Animation(std::string name, Vector<Timeline*>& timelines, float duration);
|
||||
|
||||
/// Applies all the animation's timelines to the specified skeleton.
|
||||
/// See also Timeline::apply(Skeleton&, float, float, Vector, float, MixPose, MixDirection)
|
||||
void apply(Skeleton& skeleton, float lastTime, float time, bool loop, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction);
|
||||
|
||||
std::string getName();
|
||||
|
||||
Vector<Timeline*> getTimelines();
|
||||
|
||||
void setTimelines(Vector<Timeline*> inValue);
|
||||
|
||||
float getDuration();
|
||||
|
||||
void setDuration(float inValue);
|
||||
|
||||
private:
|
||||
Vector<Timeline*> _timelines;
|
||||
float _duration;
|
||||
std::string _name;
|
||||
|
||||
/// @param target After the first and before the last entry.
|
||||
static int binarySearch(Vector<float>& values, float target, int step);
|
||||
|
||||
/// @param target After the first and before the last entry.
|
||||
static int binarySearch(Vector<float>& values, float target);
|
||||
|
||||
static int linearSearch(Vector<float>& values, float target, int step);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_Animation_h */
|
||||
@ -47,10 +47,14 @@ namespace Spine
|
||||
/// constraint or application code modifies the world transform after it was computed from the local transform.
|
||||
class Bone : public Updatable
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
friend class RotateTimeline;
|
||||
friend class IkConstraint;
|
||||
friend class TransformConstraint;
|
||||
friend class VertexAttachment;
|
||||
friend class PathConstraint;
|
||||
friend class Skeleton;
|
||||
|
||||
public:
|
||||
static void setYDown(bool inValue);
|
||||
|
||||
@ -38,6 +38,8 @@ namespace Spine
|
||||
/// The interface for all constraints.
|
||||
class Constraint : public Updatable
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
Constraint();
|
||||
|
||||
|
||||
@ -28,8 +28,8 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_Attachment_h
|
||||
#define Spine_Attachment_h
|
||||
#ifndef Spine_ContainerUtil_h
|
||||
#define Spine_ContainerUtil_h
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/HashMap.h>
|
||||
@ -50,7 +50,7 @@ namespace Spine
|
||||
{
|
||||
assert(name.length() > 0);
|
||||
|
||||
for (typename T* i = items.begin(); i != items.end(); ++i)
|
||||
for (T** i = items.begin(); i != items.end(); ++i)
|
||||
{
|
||||
T* item = (*i);
|
||||
if (item->getName() == name)
|
||||
@ -68,12 +68,50 @@ namespace Spine
|
||||
{
|
||||
assert(name.length() > 0);
|
||||
|
||||
for (size_t i = 0, size_t len = items.size(); i < len; ++i)
|
||||
for (size_t i = 0, len = items.size(); i < len; ++i)
|
||||
{
|
||||
T* item = items[i];
|
||||
if (item->getName() == name)
|
||||
{
|
||||
return i;
|
||||
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(Vector<T*>& items, std::string name)
|
||||
{
|
||||
assert(name.length() > 0);
|
||||
|
||||
for (T** i = items.begin(); i != items.end(); ++i)
|
||||
{
|
||||
T* item = (*i);
|
||||
if (item->getData().getName() == name)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// @return -1 if the item was not found.
|
||||
template<typename T>
|
||||
static int findIndexWithDataName(Vector<T*>& items, std::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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,4 +149,4 @@ namespace Spine
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* defined(__noctisgames__ContainerUtil__) */
|
||||
#endif /* Spine_ContainerUtil_h */
|
||||
|
||||
@ -41,6 +41,8 @@ namespace Spine
|
||||
/// Base class for frames that use an interpolation bezier curve.
|
||||
class CurveTimeline : public Timeline
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
CurveTimeline(int frameCount);
|
||||
|
||||
|
||||
@ -38,11 +38,9 @@ namespace Spine
|
||||
/// Stores the setup pose values for an Event.
|
||||
class EventData
|
||||
{
|
||||
public:
|
||||
int _intValue;
|
||||
float _floatValue;
|
||||
std::string _stringValue;
|
||||
friend class Event;
|
||||
|
||||
public:
|
||||
EventData(std::string name);
|
||||
|
||||
/// The name of the event, which is unique within the skeleton.
|
||||
@ -58,8 +56,10 @@ namespace Spine
|
||||
void setStringValue(std::string inValue);
|
||||
|
||||
private:
|
||||
friend class Event;
|
||||
const std::string _name;
|
||||
int _intValue;
|
||||
float _floatValue;
|
||||
std::string _stringValue;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -43,6 +43,10 @@ namespace Spine
|
||||
|
||||
class IkConstraint : public Constraint
|
||||
{
|
||||
friend class Skeleton;
|
||||
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
/// Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified
|
||||
/// in the world coordinate system.
|
||||
@ -78,9 +82,9 @@ namespace Spine
|
||||
private:
|
||||
IkConstraintData& _data;
|
||||
Vector<Bone*> _bones;
|
||||
Bone* _target;
|
||||
float _mix;
|
||||
int _bendDirection;
|
||||
Bone* _target;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +41,9 @@ namespace Spine
|
||||
|
||||
class IkConstraintData
|
||||
{
|
||||
friend class IkConstraint;
|
||||
friend class Skeleton;
|
||||
|
||||
public:
|
||||
IkConstraintData(std::string name);
|
||||
|
||||
|
||||
@ -73,11 +73,14 @@ namespace Spine
|
||||
return false;
|
||||
}
|
||||
|
||||
inline float clamp(float x, float lower, float upper)
|
||||
{
|
||||
return fminf(upper, fmaxf(x, lower));
|
||||
}
|
||||
|
||||
class MathUtil
|
||||
{
|
||||
public:
|
||||
static float SIN_TABLE[SIN_COUNT];
|
||||
|
||||
MathUtil();
|
||||
|
||||
/// Returns the sine in radians from a lookup table.
|
||||
@ -95,12 +98,10 @@ namespace Spine
|
||||
/// 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);
|
||||
};
|
||||
|
||||
inline float clamp(float x, float lower, float upper)
|
||||
{
|
||||
return fminf(upper, fmaxf(x, lower));
|
||||
}
|
||||
private:
|
||||
static float SIN_TABLE[SIN_COUNT];
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* Spine_MathUtil_h */
|
||||
|
||||
143
spine-cpp/spine-cpp/include/spine/MeshAttachment.h
Normal file
143
spine-cpp/spine-cpp/include/spine/MeshAttachment.h
Normal file
@ -0,0 +1,143 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_MeshAttachment_h
|
||||
#define Spine_MeshAttachment_h
|
||||
|
||||
#include <spine/VertexAttachment.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
/// Attachment that displays a texture region using a mesh.
|
||||
class MeshAttachment : public VertexAttachment
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
public int HullLength { get { return _hulllength; } set { _hulllength = value; } }
|
||||
public float[] RegionUVs { get { return _regionUVs; } set { _regionUVs = value; } }
|
||||
/// The UV pair for each vertex, normalized within the entire texture. <seealso cref="MeshAttachment.updateUVs"/>
|
||||
public float[] UVs { get { return _uvs; } set { _uvs = value; } }
|
||||
public int[] Triangles { get { return _triangles; } set { _triangles = value; } }
|
||||
|
||||
public float R { get { return r; } set { r = value; } }
|
||||
public float G { get { return g; } set { g = value; } }
|
||||
public float B { get { return b; } set { b = value; } }
|
||||
public float A { get { return a; } set { a = value; } }
|
||||
|
||||
public string Path { get; set; }
|
||||
public object RendererObject; //public Object RendererObject { get; set; }
|
||||
public float RegionU { get; set; }
|
||||
public float RegionV { get; set; }
|
||||
public float RegionU2 { get; set; }
|
||||
public float RegionV2 { get; set; }
|
||||
public bool RegionRotate { get; set; }
|
||||
public float RegionOffsetX { get { return _regionOffsetX; } set { _regionOffsetX = value; } }
|
||||
public float RegionOffsetY { get { return _regionOffsetY; } set { _regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
|
||||
public float RegionWidth { get { return _regionWidth; } set { _regionWidth = value; } }
|
||||
public float RegionHeight { get { return _regionHeight; } set { _regionHeight = value; } } // Unrotated, stripped size.
|
||||
public float RegionOriginalWidth { get { return _regionOriginalWidth; } set { _regionOriginalWidth = value; } }
|
||||
public float RegionOriginalHeight { get { return _regionOriginalHeight; } set { _regionOriginalHeight = value; } } // Unrotated, unstripped size.
|
||||
|
||||
public bool InheritDeform { get { return _inheritDeform; } set { _inheritDeform = value; } }
|
||||
|
||||
public MeshAttachment ParentMesh {
|
||||
get { return _parentMesh; }
|
||||
set {
|
||||
_parentMesh = value;
|
||||
if (value != null) {
|
||||
bones = value.bones;
|
||||
vertices = value.vertices;
|
||||
worldVerticesLength = value.worldVerticesLength;
|
||||
_regionUVs = value._regionUVs;
|
||||
_triangles = value._triangles;
|
||||
HullLength = value.HullLength;
|
||||
Edges = value.Edges;
|
||||
Width = value.Width;
|
||||
Height = value.Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nonessential.
|
||||
public int[] Edges { get; set; }
|
||||
public float Width { get; set; }
|
||||
public float Height { get; set; }
|
||||
|
||||
public MeshAttachment (string name) : VertexAttachment(name)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
public void updateUVs()
|
||||
{
|
||||
float u = RegionU, v = RegionV, width = RegionU2 - RegionU, height = RegionV2 - RegionV;
|
||||
if (_uvs == null || _uvs.Length != _regionUVs.Length)
|
||||
{
|
||||
_uvs = new float[_regionUVs.Length];
|
||||
}
|
||||
|
||||
float[] _uvs = _uvs;
|
||||
if (_regionRotate)
|
||||
{
|
||||
for (int i = 0, n = _uvs.Length; i < n; i += 2)
|
||||
{
|
||||
_uvs[i] = u + _regionUVs[i + 1] * width;
|
||||
_uvs[i + 1] = v + height - _regionUVs[i] * height;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0, n = _uvs.Length; i < n; i += 2)
|
||||
{
|
||||
_uvs[i] = u + _regionUVs[i] * width;
|
||||
_uvs[i + 1] = v + _regionUVs[i + 1] * height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool applyDeform(VertexAttachment* sourceAttachment)
|
||||
{
|
||||
return this == sourceAttachment || (_inheritDeform && _parentMesh == sourceAttachment);
|
||||
}
|
||||
|
||||
private:
|
||||
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
|
||||
MeshAttachment* _parentMesh;
|
||||
float[] _uvs, _regionUVs;
|
||||
int[] _triangles;
|
||||
float r = 1, g = 1, b = 1, a = 1;
|
||||
int _hulllength;
|
||||
bool _inheritDeform;
|
||||
bool _regionRotate;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Spine_MeshAttachment_h */
|
||||
@ -37,23 +37,23 @@ namespace Spine
|
||||
{
|
||||
class PathAttachment : public VertexAttachment
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
PathAttachment(std::string name) : VertexAttachment(name)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
PathAttachment(std::string name);
|
||||
|
||||
/// The length in the setup pose from the start of the path to the end of each curve.
|
||||
float[] Lengths { return lengths; }
|
||||
set { lengths = value; }
|
||||
bool Closed { return closed; }
|
||||
set { closed = value; }
|
||||
bool ConstantSpeed { return constantSpeed; }
|
||||
set { constantSpeed = value; }
|
||||
Vector<float>& getLengths();
|
||||
void setLengths(Vector<float> inValue);
|
||||
bool isClosed();
|
||||
void setClosed(bool inValue);
|
||||
bool isConstantSpeed();
|
||||
void setConstantSpeed(bool inValue);
|
||||
|
||||
private:
|
||||
float[] lengths;
|
||||
bool closed, constantSpeed;
|
||||
Vector<float> _lengths;
|
||||
bool _closed;
|
||||
bool _constantSpeed;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -45,6 +45,11 @@ namespace Spine
|
||||
|
||||
class PathConstraint : public Constraint
|
||||
{
|
||||
friend class Skeleton;
|
||||
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
PathConstraint(PathConstraintData& data, Skeleton& skeleton);
|
||||
|
||||
/// Applies the constraint to the constrained bones.
|
||||
|
||||
@ -45,6 +45,9 @@ namespace Spine
|
||||
|
||||
class PathConstraintData
|
||||
{
|
||||
friend class PathConstraint;
|
||||
friend class Skeleton;
|
||||
|
||||
public:
|
||||
PathConstraintData(std::string name);
|
||||
|
||||
|
||||
192
spine-cpp/spine-cpp/include/spine/RegionAttachment.h
Normal file
192
spine-cpp/spine-cpp/include/spine/RegionAttachment.h
Normal file
@ -0,0 +1,192 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Spine_RegionAttachment_h
|
||||
#define Spine_RegionAttachment_h
|
||||
|
||||
#include <spine/Attachment.h>
|
||||
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/MathUtil.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
class Bone;
|
||||
|
||||
/// Attachment that displays a texture region.
|
||||
class RegionAttachment : public Attachment
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
const int BLX = 0;
|
||||
const int BLY = 1;
|
||||
const int ULX = 2;
|
||||
const int ULY = 3;
|
||||
const int URX = 4;
|
||||
const int URY = 5;
|
||||
const int BRX = 6;
|
||||
const int BRY = 7;
|
||||
|
||||
float X { get { return x; } set { x = value; } }
|
||||
float Y { get { return y; } set { y = value; } }
|
||||
float Rotation { get { return _rotation; } set { _rotation = value; } }
|
||||
float ScaleX { get { return scaleX; } set { scaleX = value; } }
|
||||
float ScaleY { get { return scaleY; } set { scaleY = value; } }
|
||||
float Width { get { return width; } set { width = value; } }
|
||||
float Height { get { return height; } set { height = value; } }
|
||||
|
||||
float R { get { return r; } set { r = value; } }
|
||||
float G { get { return g; } set { g = value; } }
|
||||
float B { get { return b; } set { b = value; } }
|
||||
float A { get { return a; } set { a = value; } }
|
||||
|
||||
std::string Path { get; set; }
|
||||
object RendererObject; //object RendererObject { get; set; }
|
||||
float RegionOffsetX { get { return _regionOffsetX; } set { _regionOffsetX = value; } }
|
||||
float RegionOffsetY { get { return _regionOffsetY; } set { _regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
|
||||
float RegionWidth { get { return _regionWidth; } set { _regionWidth = value; } }
|
||||
float RegionHeight { get { return _regionHeight; } set { _regionHeight = value; } } // Unrotated, stripped size.
|
||||
float RegionOriginalWidth { get { return _regionOriginalWidth; } set { _regionOriginalWidth = value; } }
|
||||
float RegionOriginalHeight { get { return _regionOriginalHeight; } set { _regionOriginalHeight = value; } } // Unrotated, unstripped size.
|
||||
|
||||
float[] Offset { get { return _offset; } }
|
||||
float[] UVs { get { return _uvs; } }
|
||||
|
||||
RegionAttachment (std::string name) : Attachment(name)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
void updateOffset()
|
||||
{
|
||||
float regionScaleX = _width / _regionOriginalWidth * _scaleX;
|
||||
float regionScaleY = _height / _regionOriginalHeight * _scaleY;
|
||||
float localX = -_width / 2 * _scaleX + _regionOffsetX * regionScaleX;
|
||||
float localY = -_height / 2 * _scaleY + _regionOffsetY * regionScaleY;
|
||||
float localX2 = localX + _regionWidth * regionScaleX;
|
||||
float localY2 = localY + _regionHeight * regionScaleY;
|
||||
float cos = MathUtil::cosDeg(_rotation);
|
||||
float sin = MathUtil::sinDeg(_rotation);
|
||||
float localXCos = localX * cos + _x;
|
||||
float localXSin = localX * sin;
|
||||
float localYCos = localY * cos + _y;
|
||||
float localYSin = localY * sin;
|
||||
float localX2Cos = localX2 * cos + _x;
|
||||
float localX2Sin = localX2 * sin;
|
||||
float localY2Cos = localY2 * cos + _y;
|
||||
float localY2Sin = localY2 * sin;
|
||||
|
||||
_offset[BLX] = localXCos - localYSin;
|
||||
_offset[BLY] = localYCos + localXSin;
|
||||
_offset[ULX] = localXCos - localY2Sin;
|
||||
_offset[ULY] = localY2Cos + localXSin;
|
||||
_offset[URX] = localX2Cos - localY2Sin;
|
||||
_offset[URY] = localY2Cos + localX2Sin;
|
||||
_offset[BRX] = localX2Cos - localYSin;
|
||||
_offset[BRY] = localYCos + localX2Sin;
|
||||
}
|
||||
|
||||
void setUVs(float u, float v, float u2, float v2, bool rotate)
|
||||
{
|
||||
if (rotate)
|
||||
{
|
||||
_uvs[URX] = u;
|
||||
_uvs[URY] = v2;
|
||||
_uvs[BRX] = u;
|
||||
_uvs[BRY] = v;
|
||||
_uvs[BLX] = u2;
|
||||
_uvs[BLY] = v;
|
||||
_uvs[ULX] = u2;
|
||||
_uvs[ULY] = v2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_uvs[ULX] = u;
|
||||
_uvs[ULY] = v2;
|
||||
_uvs[URX] = u;
|
||||
_uvs[URY] = v;
|
||||
_uvs[BRX] = u2;
|
||||
_uvs[BRY] = v;
|
||||
_uvs[BLX] = u2;
|
||||
_uvs[BLY] = v2;
|
||||
}
|
||||
}
|
||||
|
||||
/// Transforms the attachment's four vertices to world coordinates.
|
||||
/// @param bone The parent bone.
|
||||
/// @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(Bone& bone, Vector<float> worldVertices, int offset, int stride = 2)
|
||||
{
|
||||
assert(worldVertices.size() >= 8);
|
||||
|
||||
float[] vertexOffset = _offset;
|
||||
float bwx = bone.worldX, bwy = bone.worldY;
|
||||
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
||||
float offsetX, offsetY;
|
||||
|
||||
offsetX = vertexOffset[BRX]; // 0
|
||||
offsetY = vertexOffset[BRY]; // 1
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // bl
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffset[BLX]; // 2
|
||||
offsetY = vertexOffset[BLY]; // 3
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ul
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffset[ULX]; // 4
|
||||
offsetY = vertexOffset[ULY]; // 5
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // ur
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffset[URX]; // 6
|
||||
offsetY = vertexOffset[URY]; // 7
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + bwx; // br
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + bwy;
|
||||
}
|
||||
|
||||
private:
|
||||
float _x, _y, _rotation, _scaleX = 1, _scaleY = 1, _width, _height;
|
||||
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
|
||||
float[] _offset = new float[8];
|
||||
float[] _uvs = new float[8];
|
||||
float r = 1, g = 1, b = 1, a = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Spine_RegionAttachment_h */
|
||||
@ -37,6 +37,8 @@ namespace Spine
|
||||
{
|
||||
class RotateTimeline : public CurveTimeline
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
static const int ENTRIES = 2;
|
||||
|
||||
|
||||
@ -90,11 +90,11 @@ namespace Spine
|
||||
/// If there was no old skin, each slot's setup mode 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
|
||||
/// See Skeleton::setSlotsToSetupPose()
|
||||
/// Also, often AnimationState::Apply(Skeleton&) is called before the next time the
|
||||
/// Also, often AnimationState::apply(Skeleton&) is called before the next time the
|
||||
/// skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin.
|
||||
///
|
||||
/// @param newSkin May be NULL.
|
||||
void setSkin(Skin newSkin);
|
||||
void setSkin(Skin* newSkin);
|
||||
|
||||
/// @return May be NULL.
|
||||
Attachment* getAttachment(std::string slotName, std::string attachmentName);
|
||||
@ -136,7 +136,6 @@ namespace Spine
|
||||
Vector<TransformConstraint*>& getTransformConstraints();
|
||||
|
||||
Skin* getSkin();
|
||||
void setSkin(Skin* inValue);
|
||||
float getR();
|
||||
void setR(float inValue);
|
||||
float getG();
|
||||
@ -167,7 +166,7 @@ namespace Spine
|
||||
Vector<Updatable*> _updateCache;
|
||||
Vector<Bone*> _updateCacheReset;
|
||||
Skin* _skin;
|
||||
float _r = 1, _g = 1, _b = 1, _a = 1;
|
||||
float _r, _g, _b, _a;
|
||||
float _time;
|
||||
bool _flipX, _flipY;
|
||||
float _x, _y;
|
||||
@ -178,11 +177,11 @@ namespace Spine
|
||||
|
||||
void sortTransformConstraint(TransformConstraint* constraint);
|
||||
|
||||
void sortPathConstraintAttachment(Skin* skin, int slotIndex, Bone* slotBone);
|
||||
void sortPathConstraintAttachment(Skin* skin, int slotIndex, Bone& slotBone);
|
||||
|
||||
void sortPathConstraintAttachment(Attachment* attachment, Bone* slotBone);
|
||||
void sortPathConstraintAttachment(Attachment* attachment, Bone& slotBone);
|
||||
|
||||
void sortBone(Bone bone);
|
||||
void sortBone(Bone* bone);
|
||||
|
||||
static void sortReset(Vector<Bone*>& bones);
|
||||
};
|
||||
|
||||
@ -49,6 +49,8 @@ namespace Spine
|
||||
/// Stores the setup pose and all of the stateless data for a skeleton.
|
||||
class SkeletonData
|
||||
{
|
||||
friend class Skeleton;
|
||||
|
||||
public:
|
||||
SkeletonData();
|
||||
|
||||
|
||||
@ -35,8 +35,6 @@
|
||||
#include <spine/HashMap.h>
|
||||
#include <spine/Vector.h>
|
||||
|
||||
struct HashAttachmentKey;
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
class Attachment;
|
||||
@ -47,18 +45,37 @@ namespace Spine
|
||||
/// http://esotericsoftware.com/spine-runtime-skins in the Spine Runtimes Guide.
|
||||
class Skin
|
||||
{
|
||||
friend class Skeleton;
|
||||
|
||||
public:
|
||||
class AttachmentKey
|
||||
{
|
||||
public:
|
||||
const int _slotIndex;
|
||||
const std::string _name;
|
||||
public:
|
||||
int _slotIndex;
|
||||
std::string _name;
|
||||
|
||||
AttachmentKey(int slotIndex, std::string name);
|
||||
AttachmentKey(int slotIndex = 0, std::string name = "");
|
||||
|
||||
bool operator==(const AttachmentKey &other) const;
|
||||
};
|
||||
|
||||
struct HashAttachmentKey
|
||||
{
|
||||
std::size_t operator()(const Spine::Skin::AttachmentKey& val) const
|
||||
{
|
||||
std::size_t h1 = val._slotIndex;
|
||||
|
||||
std::size_t h2 = 7;
|
||||
size_t strlen = val._name.length();
|
||||
for (int i = 0; i < strlen; ++i)
|
||||
{
|
||||
h2 = h2 * 31 + val._name.at(i);
|
||||
}
|
||||
|
||||
return h1 ^ (h2 << 1);
|
||||
}
|
||||
};
|
||||
|
||||
Skin(std::string name);
|
||||
|
||||
/// Adds an attachment to the skin for the specified slot index and name.
|
||||
@ -90,21 +107,4 @@ namespace Spine
|
||||
};
|
||||
}
|
||||
|
||||
struct HashAttachmentKey
|
||||
{
|
||||
std::size_t operator()(const Spine::Skin::AttachmentKey& val) const
|
||||
{
|
||||
std::size_t h1 = static_cast<int(val._slotIndex);
|
||||
|
||||
std::size_t h2 = 7;
|
||||
size_t strlen = val._name.length();
|
||||
for (int i = 0; i < strlen; ++i)
|
||||
{
|
||||
h2 = h2 * 31 + val._name.at(i);
|
||||
}
|
||||
|
||||
return h1 ^ (h2 << 1);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* Spine_Skin_h */
|
||||
|
||||
@ -45,13 +45,14 @@ namespace Spine
|
||||
class Slot
|
||||
{
|
||||
friend class VertexAttachment;
|
||||
friend class Skeleton;
|
||||
|
||||
public:
|
||||
Slot(SlotData& data, Bone& bone);
|
||||
|
||||
void setToSetupPose();
|
||||
|
||||
SlotData& getSlotData();
|
||||
SlotData& getData();
|
||||
Bone& getBone();
|
||||
Skeleton& getSkeleton();
|
||||
|
||||
@ -84,7 +85,7 @@ namespace Spine
|
||||
void setAttachmentVertices(Vector<float> inValue);
|
||||
|
||||
private:
|
||||
SlotData& _slotData;
|
||||
SlotData& _data;
|
||||
Bone& _bone;
|
||||
Skeleton& _skeleton;
|
||||
float _r, _g, _b, _a;
|
||||
|
||||
@ -42,7 +42,7 @@ namespace Spine
|
||||
class SlotData
|
||||
{
|
||||
public:
|
||||
SlotData(int index, std::string name, const BoneData& boneData);
|
||||
SlotData(int index, std::string name, BoneData& boneData);
|
||||
|
||||
const int getIndex();
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#ifndef Spine_Timeline_h
|
||||
#define Spine_Timeline_h
|
||||
|
||||
#include <spine/RTTI.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/MixPose.h>
|
||||
#include <spine/MixDirection.h>
|
||||
@ -42,6 +43,8 @@ namespace Spine
|
||||
|
||||
class Timeline
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
Timeline();
|
||||
|
||||
|
||||
@ -43,6 +43,10 @@ namespace Spine
|
||||
|
||||
class TransformConstraint : public Constraint
|
||||
{
|
||||
friend class Skeleton;
|
||||
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
TransformConstraint(TransformConstraintData& data, Skeleton& skeleton);
|
||||
|
||||
|
||||
@ -42,6 +42,7 @@ namespace Spine
|
||||
class TransformConstraintData
|
||||
{
|
||||
friend class TransformConstraint;
|
||||
friend class Skeleton;
|
||||
|
||||
public:
|
||||
TransformConstraintData(std::string name);
|
||||
|
||||
@ -31,10 +31,14 @@
|
||||
#ifndef Spine_Updatable_h
|
||||
#define Spine_Updatable_h
|
||||
|
||||
#include <spine/RTTI.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
class Updatable
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
Updatable();
|
||||
|
||||
|
||||
@ -65,43 +65,56 @@ namespace Spine
|
||||
deallocate(_buffer);
|
||||
}
|
||||
|
||||
void push_back(const T& _value)
|
||||
bool contains(const T& inValue)
|
||||
{
|
||||
if (_size == _capacity)
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
{
|
||||
reserve();
|
||||
if (_buffer[i] == inValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
construct(_buffer + _size++, _value);
|
||||
return false;
|
||||
}
|
||||
|
||||
void insert(size_t _index, const T& _value)
|
||||
void push_back(const T& inValue)
|
||||
{
|
||||
assert(_index < _size);
|
||||
if (_size == _capacity)
|
||||
{
|
||||
reserve();
|
||||
}
|
||||
|
||||
construct(_buffer + _size++, inValue);
|
||||
}
|
||||
|
||||
void insert(size_t inIndex, const T& inValue)
|
||||
{
|
||||
assert(inIndex < _size);
|
||||
|
||||
if (_size == _capacity)
|
||||
{
|
||||
reserve();
|
||||
}
|
||||
|
||||
for (size_t i = ++_size - 1; i > _index; --i)
|
||||
for (size_t i = ++_size - 1; i > inIndex; --i)
|
||||
{
|
||||
construct(_buffer + i, _buffer[i - 1]);
|
||||
destroy(_buffer + (i - 1));
|
||||
}
|
||||
|
||||
construct(_buffer + _index, _value);
|
||||
construct(_buffer + inIndex, inValue);
|
||||
}
|
||||
|
||||
void erase(size_t _index)
|
||||
void erase(size_t inIndex)
|
||||
{
|
||||
assert(_index < _size);
|
||||
assert(inIndex < _size);
|
||||
|
||||
--_size;
|
||||
|
||||
if (_index != _size)
|
||||
if (inIndex != _size)
|
||||
{
|
||||
for (size_t i = _index; i < _size; ++i)
|
||||
for (size_t i = inIndex; i < _size; ++i)
|
||||
{
|
||||
_buffer[i] = std::move(_buffer[i + 1]);
|
||||
}
|
||||
@ -125,18 +138,21 @@ namespace Spine
|
||||
return _size;
|
||||
}
|
||||
|
||||
T& operator[](size_t _index)
|
||||
T& operator[](size_t inIndex)
|
||||
{
|
||||
assert(_index < _size);
|
||||
assert(inIndex < _size);
|
||||
|
||||
return _buffer[_index];
|
||||
return _buffer[inIndex];
|
||||
}
|
||||
|
||||
void reserve(long inCapacity = -1)
|
||||
void reserve(size_t inCapacity = 0)
|
||||
{
|
||||
size_t newCapacity = inCapacity != -1 ? inCapacity : _capacity ? _capacity * 2 : 1;
|
||||
_buffer = static_cast<T*>(realloc(_buffer, newCapacity * sizeof(T)));
|
||||
_capacity = newCapacity;
|
||||
size_t newCapacity = inCapacity > 0 ? inCapacity : _capacity > 0 ? _capacity * 2 : 1;
|
||||
if (newCapacity > _capacity)
|
||||
{
|
||||
_buffer = static_cast<T*>(realloc(_buffer, newCapacity * sizeof(T)));
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
T* begin()
|
||||
|
||||
@ -40,8 +40,10 @@ namespace Spine
|
||||
class Slot;
|
||||
|
||||
/// An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's vertices.
|
||||
class VertexAttachment : Attachment
|
||||
class VertexAttachment : public Attachment
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
VertexAttachment(std::string name);
|
||||
|
||||
@ -61,10 +63,10 @@ namespace Spine
|
||||
/// Gets a unique ID for this attachment.
|
||||
int getId();
|
||||
|
||||
Vector<int> getBones();
|
||||
Vector<int>& getBones();
|
||||
void setBones(Vector<int> inValue);
|
||||
|
||||
Vector<float> getVertices();
|
||||
Vector<float>& getVertices();
|
||||
void setVertices(Vector<float> inValue);
|
||||
|
||||
int getWorldVerticesLength();
|
||||
|
||||
166
spine-cpp/spine-cpp/src/spine/Animation.cpp
Normal file
166
spine-cpp/spine-cpp/src/spine/Animation.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <spine/Animation.h>
|
||||
|
||||
#include <spine/Timeline.h>
|
||||
#include <spine/Skeleton.h>
|
||||
#include <spine/Event.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h> /* fmod */
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
Animation::Animation(std::string name, Vector<Timeline*>& timelines, float duration) :
|
||||
_name(name),
|
||||
_timelines(timelines),
|
||||
_duration(duration)
|
||||
{
|
||||
assert(_name.length() > 0);
|
||||
}
|
||||
|
||||
void Animation::apply(Skeleton& skeleton, float lastTime, float time, bool loop, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
if (loop && _duration != 0)
|
||||
{
|
||||
time = fmod(time, _duration);
|
||||
if (lastTime > 0)
|
||||
{
|
||||
lastTime = fmod(lastTime, _duration);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0, n = static_cast<int>(_timelines.size()); i < n; ++i)
|
||||
{
|
||||
_timelines[i]->apply(skeleton, lastTime, time, events, alpha, pose, direction);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Animation::getName()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
Vector<Timeline*> Animation::getTimelines()
|
||||
{
|
||||
return _timelines;
|
||||
}
|
||||
|
||||
void Animation::setTimelines(Vector<Timeline*> inValue)
|
||||
{
|
||||
_timelines = inValue;
|
||||
}
|
||||
|
||||
float Animation::getDuration()
|
||||
{
|
||||
return _duration;
|
||||
}
|
||||
|
||||
void Animation::setDuration(float inValue)
|
||||
{
|
||||
_duration = inValue;
|
||||
}
|
||||
|
||||
int Animation::binarySearch(Vector<float>& values, float target, int step)
|
||||
{
|
||||
int low = 0;
|
||||
int size = static_cast<int>(values.size());
|
||||
int high = size / step - 2;
|
||||
if (high == 0)
|
||||
{
|
||||
return step;
|
||||
}
|
||||
|
||||
int current = (int)(static_cast<uint32_t>(high) >> 1);
|
||||
while (true)
|
||||
{
|
||||
if (values[(current + 1) * step] <= target)
|
||||
{
|
||||
low = current + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
high = current;
|
||||
}
|
||||
|
||||
if (low == high)
|
||||
{
|
||||
return (low + 1) * step;
|
||||
}
|
||||
|
||||
current = (int)(static_cast<uint32_t>(low + high) >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
int Animation::binarySearch(Vector<float>& values, float target)
|
||||
{
|
||||
int low = 0;
|
||||
int size = static_cast<int>(values.size());
|
||||
int high = size - 2;
|
||||
if (high == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int current = (int)(static_cast<uint32_t>(high) >> 1);
|
||||
while (true)
|
||||
{
|
||||
if (values[(current + 1)] <= target)
|
||||
{
|
||||
low = current + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
high = current;
|
||||
}
|
||||
|
||||
if (low == high)
|
||||
{
|
||||
return (low + 1);
|
||||
}
|
||||
|
||||
current = (int)(static_cast<uint32_t>(low + high) >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
int Animation::linearSearch(Vector<float>& values, float target, int step)
|
||||
{
|
||||
for (int i = 0, last = static_cast<int>(values.size()) - step; i <= last; i += step)
|
||||
{
|
||||
if (values[i] > target)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -621,4 +621,6 @@ namespace Spine
|
||||
_arotation = 90 - MathUtil::atan2(rd, rb) * RadDeg;
|
||||
}
|
||||
}
|
||||
|
||||
RTTI_IMPL(Bone, Updatable);
|
||||
}
|
||||
|
||||
@ -41,5 +41,6 @@ namespace Spine
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
RTTI_IMPL(Constraint, Updatable);
|
||||
}
|
||||
|
||||
|
||||
@ -133,4 +133,6 @@ namespace Spine
|
||||
{
|
||||
return _curves[frameIndex * BEZIER_SIZE];
|
||||
}
|
||||
|
||||
RTTI_IMPL(CurveTimeline, Timeline);
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ namespace Spine
|
||||
_data(data),
|
||||
_intValue(0),
|
||||
_floatValue(0),
|
||||
_stringValue(0)
|
||||
_stringValue()
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
@ -357,4 +357,6 @@ namespace Spine
|
||||
{
|
||||
_mix = inValue;
|
||||
}
|
||||
|
||||
RTTI_IMPL(IkConstraint, Constraint);
|
||||
}
|
||||
|
||||
36
spine-cpp/spine-cpp/src/spine/MeshAttachment.cpp
Normal file
36
spine-cpp/spine-cpp/src/spine/MeshAttachment.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <spine/MeshAttachment.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
RTTI_IMPL(MeshAttachment, VertexAttachment);
|
||||
}
|
||||
@ -28,7 +28,44 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <spine/PathAttachment.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
// TODO
|
||||
PathAttachment::PathAttachment(std::string name) : VertexAttachment(name)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
Vector<float>& PathAttachment::getLengths()
|
||||
{
|
||||
return _lengths;
|
||||
}
|
||||
|
||||
void PathAttachment::setLengths(Vector<float> inValue)
|
||||
{
|
||||
_lengths = inValue;
|
||||
}
|
||||
|
||||
bool PathAttachment::isClosed()
|
||||
{
|
||||
return _closed;
|
||||
}
|
||||
|
||||
void PathAttachment::setClosed(bool inValue)
|
||||
{
|
||||
_closed = inValue;
|
||||
}
|
||||
|
||||
bool PathAttachment::isConstantSpeed()
|
||||
{
|
||||
return _constantSpeed;
|
||||
}
|
||||
|
||||
void PathAttachment::setConstantSpeed(bool inValue)
|
||||
{
|
||||
_constantSpeed = inValue;
|
||||
}
|
||||
|
||||
RTTI_IMPL(PathAttachment, VertexAttachment);
|
||||
}
|
||||
|
||||
@ -94,42 +94,45 @@ namespace Spine
|
||||
}
|
||||
|
||||
PathConstraintData data = _data;
|
||||
SpacingMode spacingMode = data.spacingMode;
|
||||
bool lengthSpacing = spacingMode == SpacingMode.Length;
|
||||
RotateMode rotateMode = data.rotateMode;
|
||||
SpacingMode spacingMode = data._spacingMode;
|
||||
bool lengthSpacing = spacingMode == SpacingMode_Length;
|
||||
RotateMode rotateMode = data._rotateMode;
|
||||
bool tangents = rotateMode == RotateMode_Tangent, scale = rotateMode == RotateMode_ChainScale;
|
||||
int boneCount = _bones.Count, spacesCount = tangents ? boneCount : boneCount + 1;
|
||||
Bone[] bonesItems = _bones.Items;
|
||||
Vector<float> spaces = _spaces.Resize(spacesCount), lengths = NULL;
|
||||
size_t boneCount = _bones.size();
|
||||
int spacesCount = static_cast<int>(tangents ? boneCount : boneCount + 1);
|
||||
_spaces.reserve(spacesCount);
|
||||
float spacing = _spacing;
|
||||
if (scale || lengthSpacing)
|
||||
{
|
||||
if (scale)
|
||||
{
|
||||
lengths = _lengths.Resize(boneCount);
|
||||
_lengths.reserve(boneCount);
|
||||
}
|
||||
|
||||
for (int i = 0, n = spacesCount - 1; i < n;)
|
||||
{
|
||||
Bone bone = bonesItems[i];
|
||||
float setupLength = bone.data.length;
|
||||
if (setupLength < PathConstraint.EPSILON)
|
||||
Bone* boneP = _bones[i];
|
||||
Bone bone = *boneP;
|
||||
float setupLength = bone._data.getLength();
|
||||
if (setupLength < PathConstraint::EPSILON)
|
||||
{
|
||||
if (scale)
|
||||
{
|
||||
lengths.Items[i] = 0;
|
||||
_lengths[i] = 0;
|
||||
}
|
||||
spaces.Items[++i] = 0;
|
||||
_spaces[++i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float x = setupLength * bone.a, y = setupLength * bone.c;
|
||||
float length = (float)Math.Sqrt(x * x + y * y);
|
||||
float x = setupLength * bone._a;
|
||||
float y = setupLength * bone._c;
|
||||
float length = (float)sqrt(x * x + y * y);
|
||||
if (scale)
|
||||
{
|
||||
lengths.Items[i] = length;
|
||||
_lengths[i] = length;
|
||||
}
|
||||
spaces.Items[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;
|
||||
|
||||
_spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -137,12 +140,14 @@ namespace Spine
|
||||
{
|
||||
for (int i = 1; i < spacesCount; ++i)
|
||||
{
|
||||
spaces.Items[i] = spacing;
|
||||
_spaces[i] = spacing;
|
||||
}
|
||||
}
|
||||
|
||||
float[] positions = computeWorldPositions(attachment, spacesCount, tangents, data.positionMode == PositionMode_Percent, spacingMode == SpacingMode_Percent);
|
||||
float boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation;
|
||||
Vector<float> positions = computeWorldPositions(*attachment, spacesCount, tangents, data.getPositionMode() == PositionMode_Percent, spacingMode == SpacingMode_Percent);
|
||||
float boneX = positions[0];
|
||||
float boneY = positions[1];
|
||||
float offsetRotation = data.getOffsetRotation();
|
||||
bool tip;
|
||||
if (offsetRotation == 0)
|
||||
{
|
||||
@ -151,24 +156,28 @@ namespace Spine
|
||||
else
|
||||
{
|
||||
tip = false;
|
||||
Bone p = target.bone;
|
||||
offsetRotation *= p.a * p.d - p.b * p.c > 0 ? DegRad : -DegRad;
|
||||
Bone p = _target->getBone();
|
||||
offsetRotation *= p.getA() * p.getD() - p.getB() * p.getC() > 0 ? DegRad : -DegRad;
|
||||
}
|
||||
|
||||
for (int i = 0, p = 3; i < boneCount; i++, p += 3)
|
||||
{
|
||||
Bone bone = bonesItems[i];
|
||||
bone.worldX += (boneX - bone.worldX) * translateMix;
|
||||
bone.worldY += (boneY - bone.worldY) * translateMix;
|
||||
float x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY;
|
||||
Bone* boneP = _bones[i];
|
||||
Bone bone = *boneP;
|
||||
bone._worldX += (boneX - bone._worldX) * translateMix;
|
||||
bone._worldY += (boneY - bone._worldY) * translateMix;
|
||||
float x = positions[p];
|
||||
float y = positions[p + 1];
|
||||
float dx = x - boneX;
|
||||
float dy = y - boneY;
|
||||
if (scale)
|
||||
{
|
||||
float length = lengths.Items[i];
|
||||
if (length >= PathConstraint.EPSILON)
|
||||
float length = _lengths[i];
|
||||
if (length >= PathConstraint::EPSILON)
|
||||
{
|
||||
float s = ((float)Math.Sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
|
||||
bone.a *= s;
|
||||
bone.c *= s;
|
||||
float s = ((float)sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
|
||||
bone._a *= s;
|
||||
bone._c *= s;
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,12 +186,12 @@ namespace Spine
|
||||
|
||||
if (rotate)
|
||||
{
|
||||
float a = bone.a, b = bone.b, c = bone.c, d = bone.d, r, cos, sin;
|
||||
float a = bone._a, b = bone._b, c = bone._c, d = bone._d, r, cos, sin;
|
||||
if (tangents)
|
||||
{
|
||||
r = positions[p - 1];
|
||||
}
|
||||
else if (spaces.Items[i + 1] < PathConstraint.EPSILON)
|
||||
else if (_spaces[i + 1] < PathConstraint::EPSILON)
|
||||
{
|
||||
r = positions[p + 2];
|
||||
}
|
||||
@ -197,7 +206,7 @@ namespace Spine
|
||||
{
|
||||
cos = MathUtil::cos(r);
|
||||
sin = MathUtil::sin(r);
|
||||
float length = bone.data.length;
|
||||
float length = bone._data.getLength();
|
||||
boneX += (length * (cos * a - sin * c) - dx) * rotateMix;
|
||||
boneY += (length * (sin * a + cos * c) - dy) * rotateMix;
|
||||
}
|
||||
@ -218,12 +227,13 @@ namespace Spine
|
||||
r *= rotateMix;
|
||||
cos = MathUtil::cos(r);
|
||||
sin = MathUtil::sin(r);
|
||||
bone.a = cos * a - sin * c;
|
||||
bone.b = cos * b - sin * d;
|
||||
bone.c = sin * a + cos * c;
|
||||
bone.d = sin * b + cos * d;
|
||||
bone._a = cos * a - sin * c;
|
||||
bone._b = cos * b - sin * d;
|
||||
bone._c = sin * a + cos * c;
|
||||
bone._d = sin * b + cos * d;
|
||||
}
|
||||
bone.appliedValid = false;
|
||||
|
||||
bone._appliedValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,14 +306,18 @@ namespace Spine
|
||||
{
|
||||
Slot target = *_target;
|
||||
float position = _position;
|
||||
float[] spacesItems = _spaces.Items, output = _positions.Resize(spacesCount * 3 + 2).Items, world;
|
||||
bool closed = path.Closed;
|
||||
int verticesLength = path.WorldVerticesLength, curveCount = verticesLength / 6, prevCurve = NONE;
|
||||
// float[] spacesItems = _spaces.Items;
|
||||
// float[] output = _positions.Resize(spacesCount * 3 + 2).Items;
|
||||
_positions.reserve(spacesCount * 3 + 2);
|
||||
bool closed = path.isClosed();
|
||||
int verticesLength = path.getWorldVerticesLength();
|
||||
int curveCount = verticesLength / 6;
|
||||
int prevCurve = NONE;
|
||||
|
||||
float pathLength;
|
||||
if (!path.ConstantSpeed)
|
||||
if (!path.isConstantSpeed())
|
||||
{
|
||||
float[] lengths = path.Lengths;
|
||||
Vector<float>& lengths = path.getLengths();
|
||||
curveCount -= closed ? 1 : 2;
|
||||
pathLength = lengths[curveCount];
|
||||
if (percentPosition)
|
||||
@ -315,20 +329,21 @@ namespace Spine
|
||||
{
|
||||
for (int i = 0; i < spacesCount; ++i)
|
||||
{
|
||||
spacesItems[i] *= pathLength;
|
||||
_spaces[i] *= pathLength;
|
||||
}
|
||||
}
|
||||
|
||||
world = _world.Resize(8).Items;
|
||||
_world.reserve(8);
|
||||
for (int i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3)
|
||||
{
|
||||
float space = spacesItems[i];
|
||||
float space = _spaces[i];
|
||||
position += space;
|
||||
float p = position;
|
||||
|
||||
if (closed)
|
||||
{
|
||||
p %= pathLength;
|
||||
p = fmod(p, pathLength);
|
||||
|
||||
if (p < 0)
|
||||
{
|
||||
p += pathLength;
|
||||
@ -340,10 +355,10 @@ namespace Spine
|
||||
if (prevCurve != BEFORE)
|
||||
{
|
||||
prevCurve = BEFORE;
|
||||
path.ComputeWorldVertices(target, 2, 4, world, 0);
|
||||
path.computeWorldVertices(target, 2, 4, _world, 0);
|
||||
}
|
||||
|
||||
addBeforePosition(p, world, 0, output, o);
|
||||
addBeforePosition(p, _world, 0, _positions, o);
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -352,10 +367,10 @@ namespace Spine
|
||||
if (prevCurve != AFTER)
|
||||
{
|
||||
prevCurve = AFTER;
|
||||
path.ComputeWorldVertices(target, verticesLength - 6, 4, world, 0);
|
||||
path.computeWorldVertices(target, verticesLength - 6, 4, _world, 0);
|
||||
}
|
||||
|
||||
addAfterPosition(p - pathLength, world, 0, output, o);
|
||||
addAfterPosition(p - pathLength, _world, 0, _positions, o);
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -386,51 +401,51 @@ namespace Spine
|
||||
prevCurve = curve;
|
||||
if (closed && curve == curveCount)
|
||||
{
|
||||
path.ComputeWorldVertices(target, verticesLength - 4, 4, world, 0);
|
||||
path.ComputeWorldVertices(target, 0, 4, world, 4);
|
||||
path.computeWorldVertices(target, verticesLength - 4, 4, _world, 0);
|
||||
path.computeWorldVertices(target, 0, 4, _world, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
path.ComputeWorldVertices(target, curve * 6 + 2, 8, world, 0);
|
||||
path.computeWorldVertices(target, curve * 6 + 2, 8, _world, 0);
|
||||
}
|
||||
}
|
||||
|
||||
addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], output, o, tangents || (i > 0 && space < EPSILON));
|
||||
addCurvePosition(p, _world[0], _world[1], _world[2], _world[3], _world[4], _world[5], _world[6], _world[7], _positions, o, tangents || (i > 0 && space < EPSILON));
|
||||
}
|
||||
return output;
|
||||
return _world;
|
||||
}
|
||||
|
||||
// World vertices.
|
||||
if (closed)
|
||||
{
|
||||
verticesLength += 2;
|
||||
world = _world.Resize(verticesLength).Items;
|
||||
path.ComputeWorldVertices(target, 2, verticesLength - 4, world, 0);
|
||||
path.ComputeWorldVertices(target, 0, 2, world, verticesLength - 4);
|
||||
world[verticesLength - 2] = world[0];
|
||||
world[verticesLength - 1] = world[1];
|
||||
_world.reserve(verticesLength);
|
||||
path.computeWorldVertices(target, 2, verticesLength - 4, _world, 0);
|
||||
path.computeWorldVertices(target, 0, 2, _world, verticesLength - 4);
|
||||
_world[verticesLength - 2] = _world[0];
|
||||
_world[verticesLength - 1] = _world[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
curveCount--;
|
||||
verticesLength -= 4;
|
||||
world = _world.Resize(verticesLength).Items;
|
||||
path.ComputeWorldVertices(target, 2, verticesLength, world, 0);
|
||||
_world.reserve(verticesLength);
|
||||
path.computeWorldVertices(target, 2, verticesLength, _world, 0);
|
||||
}
|
||||
|
||||
// Curve lengths.
|
||||
float[] curves = _curves.Resize(curveCount).Items;
|
||||
_curves.reserve(curveCount);
|
||||
pathLength = 0;
|
||||
float x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;
|
||||
float x1 = _world[0], y1 = _world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;
|
||||
float tmpx, tmpy, dddfx, dddfy, ddfx, ddfy, dfx, dfy;
|
||||
for (int i = 0, w = 2; i < curveCount; i++, w += 6)
|
||||
{
|
||||
cx1 = world[w];
|
||||
cy1 = world[w + 1];
|
||||
cx2 = world[w + 2];
|
||||
cy2 = world[w + 3];
|
||||
x2 = world[w + 4];
|
||||
y2 = world[w + 5];
|
||||
cx1 = _world[w];
|
||||
cy1 = _world[w + 1];
|
||||
cx2 = _world[w + 2];
|
||||
cy2 = _world[w + 3];
|
||||
x2 = _world[w + 4];
|
||||
y2 = _world[w + 5];
|
||||
tmpx = (x1 - cx1 * 2 + cx2) * 0.1875f;
|
||||
tmpy = (y1 - cy1 * 2 + cy2) * 0.1875f;
|
||||
dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375f;
|
||||
@ -439,19 +454,19 @@ namespace Spine
|
||||
ddfy = tmpy * 2 + dddfy;
|
||||
dfx = (cx1 - x1) * 0.75f + tmpx + dddfx * 0.16666667f;
|
||||
dfy = (cy1 - y1) * 0.75f + tmpy + dddfy * 0.16666667f;
|
||||
pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
|
||||
pathLength += (float)sqrt(dfx * dfx + dfy * dfy);
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
ddfx += dddfx;
|
||||
ddfy += dddfy;
|
||||
pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
|
||||
pathLength += (float)sqrt(dfx * dfx + dfy * dfy);
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
|
||||
pathLength += (float)sqrt(dfx * dfx + dfy * dfy);
|
||||
dfx += ddfx + dddfx;
|
||||
dfy += ddfy + dddfy;
|
||||
pathLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
|
||||
curves[i] = pathLength;
|
||||
pathLength += (float)sqrt(dfx * dfx + dfy * dfy);
|
||||
_curves[i] = pathLength;
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
@ -465,21 +480,21 @@ namespace Spine
|
||||
{
|
||||
for (int i = 0; i < spacesCount; ++i)
|
||||
{
|
||||
spacesItems[i] *= pathLength;
|
||||
_spaces[i] *= pathLength;
|
||||
}
|
||||
}
|
||||
|
||||
float[] segments = _segments;
|
||||
float curveLength = 0;
|
||||
for (int i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3)
|
||||
{
|
||||
float space = spacesItems[i];
|
||||
float space = _spaces[i];
|
||||
position += space;
|
||||
float p = position;
|
||||
|
||||
if (closed)
|
||||
{
|
||||
p %= pathLength;
|
||||
p = fmod(p, pathLength);
|
||||
|
||||
if (p < 0)
|
||||
{
|
||||
p += pathLength;
|
||||
@ -488,19 +503,19 @@ namespace Spine
|
||||
}
|
||||
else if (p < 0)
|
||||
{
|
||||
addBeforePosition(p, world, 0, output, o);
|
||||
addBeforePosition(p, _world, 0, _positions, o);
|
||||
continue;
|
||||
}
|
||||
else if (p > pathLength)
|
||||
{
|
||||
addAfterPosition(p - pathLength, world, verticesLength - 4, output, o);
|
||||
addAfterPosition(p - pathLength, _world, verticesLength - 4, _positions, o);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine curve containing position.
|
||||
for (;; curve++)
|
||||
{
|
||||
float length = curves[curve];
|
||||
float length = _curves[curve];
|
||||
if (p > length)
|
||||
{
|
||||
continue;
|
||||
@ -512,7 +527,7 @@ namespace Spine
|
||||
}
|
||||
else
|
||||
{
|
||||
float prev = curves[curve - 1];
|
||||
float prev = _curves[curve - 1];
|
||||
p = (p - prev) / (length - prev);
|
||||
}
|
||||
break;
|
||||
@ -523,14 +538,14 @@ namespace Spine
|
||||
{
|
||||
prevCurve = curve;
|
||||
int ii = curve * 6;
|
||||
x1 = world[ii];
|
||||
y1 = world[ii + 1];
|
||||
cx1 = world[ii + 2];
|
||||
cy1 = world[ii + 3];
|
||||
cx2 = world[ii + 4];
|
||||
cy2 = world[ii + 5];
|
||||
x2 = world[ii + 6];
|
||||
y2 = world[ii + 7];
|
||||
x1 = _world[ii];
|
||||
y1 = _world[ii + 1];
|
||||
cx1 = _world[ii + 2];
|
||||
cy1 = _world[ii + 3];
|
||||
cx2 = _world[ii + 4];
|
||||
cy2 = _world[ii + 5];
|
||||
x2 = _world[ii + 6];
|
||||
y2 = _world[ii + 7];
|
||||
tmpx = (x1 - cx1 * 2 + cx2) * 0.03f;
|
||||
tmpy = (y1 - cy1 * 2 + cy2) * 0.03f;
|
||||
dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006f;
|
||||
@ -539,25 +554,25 @@ namespace Spine
|
||||
ddfy = tmpy * 2 + dddfy;
|
||||
dfx = (cx1 - x1) * 0.3f + tmpx + dddfx * 0.16666667f;
|
||||
dfy = (cy1 - y1) * 0.3f + tmpy + dddfy * 0.16666667f;
|
||||
curveLength = (float)Math.Sqrt(dfx * dfx + dfy * dfy);
|
||||
segments[0] = curveLength;
|
||||
curveLength = (float)sqrt(dfx * dfx + dfy * dfy);
|
||||
_segments[0] = curveLength;
|
||||
for (ii = 1; ii < 8; ii++)
|
||||
{
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
ddfx += dddfx;
|
||||
ddfy += dddfy;
|
||||
curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
|
||||
segments[ii] = curveLength;
|
||||
curveLength += (float)sqrt(dfx * dfx + dfy * dfy);
|
||||
_segments[ii] = curveLength;
|
||||
}
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
|
||||
segments[8] = curveLength;
|
||||
curveLength += (float)sqrt(dfx * dfx + dfy * dfy);
|
||||
_segments[8] = curveLength;
|
||||
dfx += ddfx + dddfx;
|
||||
dfy += ddfy + dddfy;
|
||||
curveLength += (float)Math.Sqrt(dfx * dfx + dfy * dfy);
|
||||
segments[9] = curveLength;
|
||||
curveLength += (float)sqrt(dfx * dfx + dfy * dfy);
|
||||
_segments[9] = curveLength;
|
||||
segment = 0;
|
||||
}
|
||||
|
||||
@ -565,7 +580,7 @@ namespace Spine
|
||||
p *= curveLength;
|
||||
for (;; segment++)
|
||||
{
|
||||
float length = segments[segment];
|
||||
float length = _segments[segment];
|
||||
if (p > length)
|
||||
{
|
||||
continue;
|
||||
@ -577,15 +592,15 @@ namespace Spine
|
||||
}
|
||||
else
|
||||
{
|
||||
float prev = segments[segment - 1];
|
||||
float prev = _segments[segment - 1];
|
||||
p = segment + (p - prev) / (length - prev);
|
||||
}
|
||||
break;
|
||||
}
|
||||
addCurvePosition(p * 0.1f, x1, y1, cx1, cy1, cx2, cy2, x2, y2, output, o, tangents || (i > 0 && space < EPSILON));
|
||||
addCurvePosition(p * 0.1f, x1, y1, cx1, cy1, cx2, cy2, x2, y2, _positions, o, tangents || (i > 0 && space < EPSILON));
|
||||
}
|
||||
|
||||
return output;
|
||||
return _positions;
|
||||
}
|
||||
|
||||
void PathConstraint::addBeforePosition(float p, Vector<float>& temp, int i, Vector<float>& output, int o)
|
||||
@ -615,7 +630,7 @@ namespace Spine
|
||||
|
||||
void PathConstraint::addCurvePosition(float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, Vector<float>& output, int o, bool tangents)
|
||||
{
|
||||
if (p < EPSILON || float.IsNaN(p))
|
||||
if (p < EPSILON || isnan(p))
|
||||
{
|
||||
p = EPSILON;
|
||||
}
|
||||
@ -627,7 +642,9 @@ namespace Spine
|
||||
output[o + 1] = y;
|
||||
if (tangents)
|
||||
{
|
||||
output[o + 2] = (float)Math.Atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
|
||||
output[o + 2] = (float)atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
|
||||
}
|
||||
}
|
||||
|
||||
RTTI_IMPL(PathConstraint, Constraint);
|
||||
}
|
||||
|
||||
36
spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp
Normal file
36
spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License v2.5
|
||||
*
|
||||
* Copyright (c) 2013-2016, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable, and
|
||||
* non-transferable license to use, install, execute, and perform the Spine
|
||||
* Runtimes software and derivative works solely for personal or internal
|
||||
* use. Without the written permission of Esoteric Software (see Section 2 of
|
||||
* the Spine Software License Agreement), you may not (a) modify, translate,
|
||||
* adapt, or develop new applications using the Spine Runtimes or otherwise
|
||||
* create derivative works or improvements of the Spine Runtimes or (b) remove,
|
||||
* delete, alter, or obscure any trademarks or any copyright, trademark, patent,
|
||||
* or other intellectual property or proprietary rights notices on or in the
|
||||
* Software, including any copy thereof. Redistributions in binary or source
|
||||
* form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "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 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 THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <spine/RegionAttachment.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
RTTI_IMPL(RegionAttachment, Attachment);
|
||||
}
|
||||
@ -147,4 +147,6 @@ namespace Spine
|
||||
{
|
||||
_frames = inValue;
|
||||
}
|
||||
|
||||
RTTI_IMPL(RotateTimeline, CurveTimeline);
|
||||
}
|
||||
|
||||
@ -45,6 +45,9 @@
|
||||
#include <spine/IkConstraintData.h>
|
||||
#include <spine/TransformConstraintData.h>
|
||||
#include <spine/PathConstraintData.h>
|
||||
#include <spine/RegionAttachment.h>
|
||||
#include <spine/MeshAttachment.h>
|
||||
#include <spine/PathAttachment.h>
|
||||
|
||||
#include <spine/ContainerUtil.h>
|
||||
|
||||
@ -135,81 +138,101 @@ namespace Spine
|
||||
|
||||
void Skeleton::updateCache()
|
||||
{
|
||||
Vector<Updatable> updateCache = _updateCache;
|
||||
updateCache.Clear();
|
||||
_updateCacheReset.Clear();
|
||||
_updateCache.clear();
|
||||
_updateCacheReset.clear();
|
||||
|
||||
Vector<Bone> bones = _bones;
|
||||
for (int i = 0, n = bones.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_bones.size()); i < n; ++i)
|
||||
{
|
||||
bones.Items[i].sorted = false;
|
||||
_bones[i]->_sorted = false;
|
||||
}
|
||||
|
||||
Vector<IkConstraint> ikConstraints = _ikConstraints;
|
||||
var transformConstraints = _transformConstraints;
|
||||
var pathConstraints = _pathConstraints;
|
||||
int ikCount = IkConstraints.Count, transformCount = transformConstraints.Count, pathCount = pathConstraints.Count;
|
||||
int ikCount = static_cast<int>(_ikConstraints.size());
|
||||
int transformCount = static_cast<int>(_transformConstraints.size());
|
||||
int pathCount = static_cast<int>(_pathConstraints.size());
|
||||
|
||||
int constraintCount = ikCount + transformCount + pathCount;
|
||||
//outer:
|
||||
|
||||
for (int i = 0; i < constraintCount; ++i)
|
||||
{
|
||||
bool gotoNextConstraintCount = false;
|
||||
|
||||
for (int ii = 0; ii < ikCount; ++ii)
|
||||
{
|
||||
IkConstraint constraint = ikConstraints.Items[ii];
|
||||
if (constraint.data.order == i)
|
||||
IkConstraint* constraint = _ikConstraints[ii];
|
||||
if (constraint->getData().getOrder() == i)
|
||||
{
|
||||
sortIkConstraint(constraint);
|
||||
goto continue_outer; //continue outer;
|
||||
|
||||
gotoNextConstraintCount = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gotoNextConstraintCount)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < transformCount; ++ii)
|
||||
{
|
||||
TransformConstraint constraint = transformConstraints.Items[ii];
|
||||
if (constraint.data.order == i)
|
||||
TransformConstraint* constraint = _transformConstraints[ii];
|
||||
if (constraint->getData().getOrder() == i)
|
||||
{
|
||||
sortTransformConstraint(constraint);
|
||||
goto continue_outer; //continue outer;
|
||||
|
||||
gotoNextConstraintCount = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gotoNextConstraintCount)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < pathCount; ++ii)
|
||||
{
|
||||
PathConstraint constraint = pathConstraints.Items[ii];
|
||||
if (constraint.data.order == i)
|
||||
PathConstraint* constraint = _pathConstraints[ii];
|
||||
if (constraint->getData().getOrder() == i)
|
||||
{
|
||||
sortPathConstraint(constraint);
|
||||
goto continue_outer; //continue outer;
|
||||
|
||||
gotoNextConstraintCount = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue_outer: {}
|
||||
|
||||
if (gotoNextConstraintCount)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0, n = bones.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_bones.size()); i < n; ++i)
|
||||
{
|
||||
sortBone(bones.Items[i]);
|
||||
sortBone(_bones[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::updateWorldTransform()
|
||||
{
|
||||
var updateCacheReset = _updateCacheReset;
|
||||
var updateCacheResetItems = updateCacheReset.Items;
|
||||
for (int i = 0, n = updateCacheReset.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_updateCacheReset.size()); i < n; ++i)
|
||||
{
|
||||
Bone bone = updateCacheResetItems[i];
|
||||
bone.ax = bone.x;
|
||||
bone.ay = bone.y;
|
||||
bone.arotation = bone.rotation;
|
||||
bone.ascaleX = bone.scaleX;
|
||||
bone.ascaleY = bone.scaleY;
|
||||
bone.ashearX = bone.shearX;
|
||||
bone.ashearY = bone.shearY;
|
||||
bone.appliedValid = true;
|
||||
Bone* boneP = _updateCacheReset[i];
|
||||
Bone bone = *boneP;
|
||||
bone._ax = bone._x;
|
||||
bone._ay = bone._y;
|
||||
bone._arotation = bone._rotation;
|
||||
bone._ascaleX = bone._scaleX;
|
||||
bone._ascaleY = bone._scaleY;
|
||||
bone._ashearX = bone._shearX;
|
||||
bone._ashearY = bone._shearY;
|
||||
bone._appliedValid = true;
|
||||
}
|
||||
|
||||
var updateItems = _updateCache.Items;
|
||||
for (int i = 0, n = updateCache.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_updateCache.size()); i < n; ++i)
|
||||
{
|
||||
updateItems[i].update();
|
||||
_updateCache[i]->update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,213 +244,164 @@ namespace Spine
|
||||
|
||||
void Skeleton::setBonesToSetupPose()
|
||||
{
|
||||
var bonesItems = _bones.Items;
|
||||
for (int i = 0, n = bones.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_bones.size()); i < n; ++i)
|
||||
{
|
||||
bonesItems[i].setToSetupPose();
|
||||
_bones[i]->setToSetupPose();
|
||||
}
|
||||
|
||||
var ikConstraintsItems = _ikConstraints.Items;
|
||||
for (int i = 0, n = ikConstraints.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_ikConstraints.size()); i < n; ++i)
|
||||
{
|
||||
IkConstraint constraint = ikConstraintsItems[i];
|
||||
constraint.bendDirection = constraint.data.bendDirection;
|
||||
constraint.mix = constraint.data.mix;
|
||||
IkConstraint* constraintP = _ikConstraints[i];
|
||||
IkConstraint constraint = *constraintP;
|
||||
|
||||
constraint._bendDirection = constraint._data._bendDirection;
|
||||
constraint._mix = constraint._data._mix;
|
||||
}
|
||||
|
||||
var transformConstraintsItems = _transformConstraints.Items;
|
||||
for (int i = 0, n = transformConstraints.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_transformConstraints.size()); i < n; ++i)
|
||||
{
|
||||
TransformConstraint constraint = transformConstraintsItems[i];
|
||||
TransformConstraintData constraintData = constraint.data;
|
||||
constraint.rotateMix = constraintData.rotateMix;
|
||||
constraint.translateMix = constraintData.translateMix;
|
||||
constraint.scaleMix = constraintData.scaleMix;
|
||||
constraint.shearMix = constraintData.shearMix;
|
||||
TransformConstraint* constraintP = _transformConstraints[i];
|
||||
TransformConstraint constraint = *constraintP;
|
||||
TransformConstraintData& constraintData = constraint._data;
|
||||
|
||||
constraint._rotateMix = constraintData._rotateMix;
|
||||
constraint._translateMix = constraintData._translateMix;
|
||||
constraint._scaleMix = constraintData._scaleMix;
|
||||
constraint._shearMix = constraintData._shearMix;
|
||||
}
|
||||
|
||||
var pathConstraintItems = _pathConstraints.Items;
|
||||
for (int i = 0, n = pathConstraints.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_pathConstraints.size()); i < n; ++i)
|
||||
{
|
||||
PathConstraint constraint = pathConstraintItems[i];
|
||||
PathConstraintData constraintData = constraint.data;
|
||||
constraint.position = constraintData.position;
|
||||
constraint.spacing = constraintData.spacing;
|
||||
constraint.rotateMix = constraintData.rotateMix;
|
||||
constraint.translateMix = constraintData.translateMix;
|
||||
PathConstraint* constraintP = _pathConstraints[i];
|
||||
PathConstraint constraint = *constraintP;
|
||||
PathConstraintData& constraintData = constraint._data;
|
||||
|
||||
constraint._position = constraintData._position;
|
||||
constraint._spacing = constraintData._spacing;
|
||||
constraint._rotateMix = constraintData._rotateMix;
|
||||
constraint._translateMix = constraintData._translateMix;
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::setSlotsToSetupPose()
|
||||
{
|
||||
var slots = _slots;
|
||||
var slotsItems = slots.Items;
|
||||
drawOrder.Clear();
|
||||
for (int i = 0, n = slots.Count; i < n; ++i)
|
||||
_drawOrder.clear();
|
||||
for (int i = 0, n = static_cast<int>(_slots.size()); i < n; ++i)
|
||||
{
|
||||
drawOrder.Add(slotsItems[i]);
|
||||
_drawOrder.push_back(_slots[i]);
|
||||
}
|
||||
|
||||
for (int i = 0, n = slots.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_slots.size()); i < n; ++i)
|
||||
{
|
||||
slotsItems[i].setToSetupPose();
|
||||
_slots[i]->setToSetupPose();
|
||||
}
|
||||
}
|
||||
|
||||
Bone* Skeleton::findBone(std::string boneName)
|
||||
{
|
||||
assert(boneName.length() > 0);
|
||||
|
||||
var bones = _bones;
|
||||
var bonesItems = bones.Items;
|
||||
for (int i = 0, n = bones.Count; i < n; ++i)
|
||||
{
|
||||
Bone bone = bonesItems[i];
|
||||
if (bone.data.name == boneName)
|
||||
{
|
||||
return bone;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return ContainerUtil::findWithDataName(_bones, boneName);
|
||||
}
|
||||
|
||||
int Skeleton::findBoneIndex(std::string boneName)
|
||||
{
|
||||
assert(boneName.length() > 0);
|
||||
|
||||
var bones = _bones;
|
||||
var bonesItems = bones.Items;
|
||||
for (int i = 0, n = bones.Count; i < n; ++i)
|
||||
{
|
||||
if (bonesItems[i].data.name == boneName)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return ContainerUtil::findIndexWithDataName(_bones, boneName);
|
||||
}
|
||||
|
||||
Slot* Skeleton::findSlot(std::string slotName)
|
||||
{
|
||||
assert(slotName.length() > 0);
|
||||
|
||||
var slots = _slots;
|
||||
var slotsItems = slots.Items;
|
||||
for (int i = 0, n = slots.Count; i < n; ++i)
|
||||
{
|
||||
Slot slot = slotsItems[i];
|
||||
if (slot.data.name == slotName)
|
||||
{
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return ContainerUtil::findWithDataName(_slots, slotName);
|
||||
}
|
||||
|
||||
int Skeleton::findSlotIndex(std::string slotName)
|
||||
{
|
||||
assert(slotName.length() > 0);
|
||||
|
||||
var slots = _slots;
|
||||
var slotsItems = slots.Items;
|
||||
for (int i = 0, n = slots.Count; i < n; ++i)
|
||||
{
|
||||
if (slotsItems[i].data.name.Equals(slotName))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return ContainerUtil::findIndexWithDataName(_slots, slotName);
|
||||
}
|
||||
|
||||
void Skeleton::setSkin(std::string skinName)
|
||||
{
|
||||
Skin foundSkin = data.FindSkin(skinName);
|
||||
Skin* foundSkin = _data.findSkin(skinName);
|
||||
|
||||
assert(foundSkin != NULL);
|
||||
|
||||
setSkin(foundSkin);
|
||||
}
|
||||
|
||||
void Skeleton::setSkin(Skin newSkin)
|
||||
void Skeleton::setSkin(Skin* newSkin)
|
||||
{
|
||||
if (newSkin != NULL)
|
||||
{
|
||||
if (skin != NULL)
|
||||
if (_skin != NULL)
|
||||
{
|
||||
newSkin.AttachAll(this, skin);
|
||||
Skeleton& thisRef = *this;
|
||||
newSkin->attachAll(thisRef, *_skin);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector<Slot> slots = _slots;
|
||||
for (int i = 0, n = slots.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_slots.size()); i < n; ++i)
|
||||
{
|
||||
Slot slot = slots.Items[i];
|
||||
std::string name = slot.data.attachmentName;
|
||||
if (name != NULL)
|
||||
Slot* slotP = _slots[i];
|
||||
Slot slot = *slotP;
|
||||
std::string name = slot._data.getAttachmentName();
|
||||
if (name.length() > 0)
|
||||
{
|
||||
Attachment attachment = newSkin.getAttachment(i, name);
|
||||
Attachment* attachment = newSkin->getAttachment(i, name);
|
||||
if (attachment != NULL)
|
||||
{
|
||||
slot.Attachment = attachment;
|
||||
slot.setAttachment(attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
skin = newSkin;
|
||||
|
||||
_skin = newSkin;
|
||||
}
|
||||
|
||||
Attachment* Skeleton::getAttachment(std::string slotName, std::string attachmentName)
|
||||
{
|
||||
return getAttachment(data.findSlotIndex(slotName), attachmentName);
|
||||
return getAttachment(_data.findSlotIndex(slotName), attachmentName);
|
||||
}
|
||||
|
||||
Attachment* Skeleton::getAttachment(int slotIndex, std::string attachmentName)
|
||||
{
|
||||
assert(attachmentName.length() > 0);
|
||||
|
||||
if (skin != NULL)
|
||||
if (_skin != NULL)
|
||||
{
|
||||
Attachment attachment = skin.getAttachment(slotIndex, attachmentName);
|
||||
Attachment* attachment = _skin->getAttachment(slotIndex, attachmentName);
|
||||
if (attachment != NULL)
|
||||
{
|
||||
return attachment;
|
||||
}
|
||||
}
|
||||
|
||||
return data.defaultSkin != NULL ? data.defaultSkin.getAttachment(slotIndex, attachmentName) : NULL;
|
||||
return _data.getDefaultSkin() != NULL ? _data.getDefaultSkin()->getAttachment(slotIndex, attachmentName) : NULL;
|
||||
}
|
||||
|
||||
void Skeleton::setAttachment(std::string slotName, std::string attachmentName)
|
||||
{
|
||||
assert(slotName.length() > 0);
|
||||
|
||||
Vector<Slot> slots = _slots;
|
||||
for (int i = 0, n = slots.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_slots.size()); i < n; ++i)
|
||||
{
|
||||
Slot slot = slots.Items[i];
|
||||
if (slot.data.name == slotName)
|
||||
Slot* slot = _slots[i];
|
||||
if (slot->_data.getName() == slotName)
|
||||
{
|
||||
Attachment attachment = NULL;
|
||||
if (attachmentName != NULL)
|
||||
Attachment* attachment = NULL;
|
||||
if (attachmentName.length() > 0)
|
||||
{
|
||||
attachment = getAttachment(i, attachmentName);
|
||||
|
||||
assert(attachment != NULL);
|
||||
}
|
||||
|
||||
slot.Attachment = attachment;
|
||||
slot->setAttachment(attachment);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Slot not found: %s" + slotName.c_str());
|
||||
printf("Slot not found: %s", slotName.c_str());
|
||||
|
||||
assert(false);
|
||||
}
|
||||
@ -436,11 +410,10 @@ namespace Spine
|
||||
{
|
||||
assert(constraintName.length() > 0);
|
||||
|
||||
Vector<IkConstraint> ikConstraints = _ikConstraints;
|
||||
for (int i = 0, n = ikConstraints.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_ikConstraints.size()); i < n; ++i)
|
||||
{
|
||||
IkConstraint ikConstraint = ikConstraints.Items[i];
|
||||
if (ikConstraint.data.name == constraintName)
|
||||
IkConstraint* ikConstraint = _ikConstraints[i];
|
||||
if (ikConstraint->_data.getName() == constraintName)
|
||||
{
|
||||
return ikConstraint;
|
||||
}
|
||||
@ -452,11 +425,10 @@ namespace Spine
|
||||
{
|
||||
assert(constraintName.length() > 0);
|
||||
|
||||
Vector<TransformConstraint> transformConstraints = _transformConstraints;
|
||||
for (int i = 0, n = transformConstraints.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_transformConstraints.size()); i < n; ++i)
|
||||
{
|
||||
TransformConstraint transformConstraint = transformConstraints.Items[i];
|
||||
if (transformConstraint.data.name == constraintName)
|
||||
TransformConstraint* transformConstraint = _transformConstraints[i];
|
||||
if (transformConstraint->_data.getName() == constraintName)
|
||||
{
|
||||
return transformConstraint;
|
||||
}
|
||||
@ -469,11 +441,10 @@ namespace Spine
|
||||
{
|
||||
assert(constraintName.length() > 0);
|
||||
|
||||
Vector<PathConstraint> pathConstraints = _pathConstraints;
|
||||
for (int i = 0, n = pathConstraints.Count; i < n; ++i)
|
||||
for (int i = 0, n = static_cast<int>(_pathConstraints.size()); i < n; ++i)
|
||||
{
|
||||
PathConstraint constraint = pathConstraints.Items[i];
|
||||
if (constraint.data.name.Equals(constraintName))
|
||||
PathConstraint* constraint = _pathConstraints[i];
|
||||
if (constraint->_data.getName() == constraintName)
|
||||
{
|
||||
return constraint;
|
||||
}
|
||||
@ -494,40 +465,40 @@ namespace Spine
|
||||
float maxX = std::numeric_limits<float>::min();
|
||||
float maxY = std::numeric_limits<float>::min();
|
||||
|
||||
for (Slot* i = _drawOrder.begin(); i != _drawOrder.end(); ++i)
|
||||
for (Slot** i = _drawOrder.begin(); i != _drawOrder.end(); ++i)
|
||||
{
|
||||
Slot* slot = i;
|
||||
Slot* slot = (*i);
|
||||
int verticesLength = 0;
|
||||
Attachment* attachment = slot->getAttachment();
|
||||
|
||||
if (attachment != NULL && attachment->getRTTI().derivesFrom(RegionAttachment::rtti))
|
||||
{
|
||||
RegionAttachment* regionAttachment = static_cast<RegionAttachment*>(attachment);
|
||||
|
||||
|
||||
verticesLength = 8;
|
||||
if (vertexBuffer.size() < 8)
|
||||
if (outVertexBuffer.size() < 8)
|
||||
{
|
||||
vertexBuffer.reserve(8);
|
||||
outVertexBuffer.reserve(8);
|
||||
}
|
||||
regionAttachment->computeWorldVertices(slot->getBone(), vertexBuffer, 0);
|
||||
regionAttachment->computeWorldVertices(slot->getBone(), outVertexBuffer, 0);
|
||||
}
|
||||
else if (attachment != NULL && attachment->getRTTI().derivesFrom(MeshAttachment::rtti))
|
||||
{
|
||||
MeshAttachment* mesh = static_cast<MeshAttachment*>(attachment);
|
||||
|
||||
|
||||
verticesLength = mesh->getWorldVerticesLength();
|
||||
if (vertexBuffer.size() < verticesLength)
|
||||
if (outVertexBuffer.size() < verticesLength)
|
||||
{
|
||||
vertexBuffer.reserve(verticesLength);
|
||||
outVertexBuffer.reserve(verticesLength);
|
||||
}
|
||||
|
||||
mesh->computeWorldVertices(slot, 0, verticesLength, vertexBuffer, 0);
|
||||
|
||||
mesh->computeWorldVertices(slot, 0, verticesLength, outVertexBuffer, 0);
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < verticesLength; ii += 2)
|
||||
{
|
||||
float vx = vertexBuffer[ii];
|
||||
float vy = vertexBuffer[ii + 1];
|
||||
float vx = outVertexBuffer[ii];
|
||||
float vy = outVertexBuffer[ii + 1];
|
||||
|
||||
minX = MIN(minX, vx);
|
||||
minY = MIN(minY, vy);
|
||||
@ -536,15 +507,15 @@ namespace Spine
|
||||
}
|
||||
}
|
||||
|
||||
x = minX;
|
||||
y = minY;
|
||||
width = maxX - minX;
|
||||
height = maxY - minY;
|
||||
outX = minX;
|
||||
outY = minY;
|
||||
outWidth = maxX - minX;
|
||||
outHeight = maxY - minY;
|
||||
}
|
||||
|
||||
Bone* Skeleton::getRootBone()
|
||||
{
|
||||
return _bones.size() == 0 ? NULL : &_bones[0];
|
||||
return _bones.size() == 0 ? NULL : _bones[0];
|
||||
}
|
||||
|
||||
const SkeletonData& Skeleton::getData()
|
||||
@ -592,11 +563,6 @@ namespace Spine
|
||||
return _skin;
|
||||
}
|
||||
|
||||
void Skeleton::setSkin(Skin* inValue)
|
||||
{
|
||||
_skin = inValue;
|
||||
}
|
||||
|
||||
float Skeleton::getR()
|
||||
{
|
||||
return _r;
|
||||
@ -689,90 +655,90 @@ namespace Spine
|
||||
|
||||
void Skeleton::sortIkConstraint(IkConstraint* constraint)
|
||||
{
|
||||
Bone target = constraint.target;
|
||||
Bone* target = constraint->getTarget();
|
||||
sortBone(target);
|
||||
|
||||
var constrained = constraint.bones;
|
||||
Bone parent = constrained.Items[0];
|
||||
Vector<Bone*>& constrained = constraint->getBones();
|
||||
Bone* parent = constrained[0];
|
||||
sortBone(parent);
|
||||
|
||||
if (constrained.Count > 1)
|
||||
if (constrained.size() > 1)
|
||||
{
|
||||
Bone child = constrained.Items[constrained.Count - 1];
|
||||
if (!updateCache.Contains(child))
|
||||
Bone* child = constrained[constrained.size() - 1];
|
||||
if (!_updateCache.contains(child))
|
||||
{
|
||||
updateCacheReset.Add(child);
|
||||
_updateCacheReset.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
updateCache.Add(constraint);
|
||||
_updateCache.push_back(constraint);
|
||||
|
||||
sortReset(parent.children);
|
||||
constrained.Items[constrained.Count - 1].sorted = true;
|
||||
sortReset(parent->getChildren());
|
||||
constrained[constrained.size() - 1]->_sorted = true;
|
||||
}
|
||||
|
||||
void Skeleton::sortPathConstraint(PathConstraint* constraint)
|
||||
{
|
||||
Slot slot = constraint.target;
|
||||
int slotIndex = slot.data.index;
|
||||
Bone slotBone = slot.bone;
|
||||
Slot* slot = constraint->getTarget();
|
||||
int slotIndex = slot->_data.getIndex();
|
||||
Bone& slotBone = slot->_bone;
|
||||
|
||||
if (skin != NULL)
|
||||
if (_skin != NULL)
|
||||
{
|
||||
sortPathConstraintAttachment(skin, slotIndex, slotBone);
|
||||
sortPathConstraintAttachment(_skin, slotIndex, slotBone);
|
||||
}
|
||||
|
||||
if (data.defaultSkin != NULL && data.defaultSkin != skin)
|
||||
if (_data._defaultSkin != NULL && _data._defaultSkin != _skin)
|
||||
{
|
||||
sortPathConstraintAttachment(data.defaultSkin, slotIndex, slotBone);
|
||||
sortPathConstraintAttachment(_data._defaultSkin, slotIndex, slotBone);
|
||||
}
|
||||
|
||||
for (int ii = 0, nn = data.skins.Count; ii < nn; ++ii)
|
||||
for (int ii = 0, nn = static_cast<int>(_data._skins.size()); ii < nn; ++ii)
|
||||
{
|
||||
sortPathConstraintAttachment(data.skins.Items[ii], slotIndex, slotBone);
|
||||
sortPathConstraintAttachment(_data._skins[ii], slotIndex, slotBone);
|
||||
}
|
||||
|
||||
Attachment attachment = slot.attachment;
|
||||
if (attachment is PathAttachment)
|
||||
Attachment* attachment = slot->_attachment;
|
||||
if (attachment != NULL && attachment->getRTTI().derivesFrom(PathAttachment::rtti))
|
||||
{
|
||||
sortPathConstraintAttachment(attachment, slotBone);
|
||||
}
|
||||
|
||||
var constrained = constraint.bones;
|
||||
int boneCount = constrained.Count;
|
||||
Vector<Bone*>& constrained = constraint->getBones();
|
||||
int boneCount = static_cast<int>(constrained.size());
|
||||
for (int i = 0; i < boneCount; ++i)
|
||||
{
|
||||
sortBone(constrained.Items[i]);
|
||||
sortBone(constrained[i]);
|
||||
}
|
||||
|
||||
updateCache.Add(constraint);
|
||||
_updateCache.push_back(constraint);
|
||||
|
||||
for (int i = 0; i < boneCount; ++i)
|
||||
{
|
||||
sortReset(constrained.Items[i].children);
|
||||
sortReset(constrained[i]->getChildren());
|
||||
}
|
||||
|
||||
for (int i = 0; i < boneCount; ++i)
|
||||
{
|
||||
constrained.Items[i].sorted = true;
|
||||
constrained[i]->_sorted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::sortTransformConstraint(TransformConstraint* constraint)
|
||||
{
|
||||
sortBone(constraint.target);
|
||||
sortBone(constraint->getTarget());
|
||||
|
||||
var constrained = constraint.bones;
|
||||
int boneCount = constrained.Count;
|
||||
if (constraint.data.local)
|
||||
Vector<Bone*>& constrained = constraint->getBones();
|
||||
int boneCount = static_cast<int>(constrained.size());
|
||||
if (constraint->_data.isLocal())
|
||||
{
|
||||
for (int i = 0; i < boneCount; ++i)
|
||||
{
|
||||
Bone child = constrained.Items[i];
|
||||
sortBone(child.parent);
|
||||
if (!updateCache.Contains(child))
|
||||
Bone* child = constrained[i];
|
||||
sortBone(child->getParent());
|
||||
if (!_updateCache.contains(child))
|
||||
{
|
||||
updateCacheReset.Add(child);
|
||||
_updateCacheReset.push_back(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -780,55 +746,61 @@ namespace Spine
|
||||
{
|
||||
for (int i = 0; i < boneCount; ++i)
|
||||
{
|
||||
sortBone(constrained.Items[i]);
|
||||
sortBone(constrained[i]);
|
||||
}
|
||||
}
|
||||
|
||||
updateCache.Add(constraint);
|
||||
_updateCache.push_back(constraint);
|
||||
|
||||
for (int i = 0; i < boneCount; ++i)
|
||||
{
|
||||
sortReset(constrained.Items[i].children);
|
||||
sortReset(constrained[i]->getChildren());
|
||||
}
|
||||
|
||||
for (int i = 0; i < boneCount; ++i)
|
||||
{
|
||||
constrained.Items[i].sorted = true;
|
||||
constrained[i]->_sorted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::sortPathConstraintAttachment(Skin* skin, int slotIndex, Bone* slotBone)
|
||||
void Skeleton::sortPathConstraintAttachment(Skin* skin, int slotIndex, Bone& slotBone)
|
||||
{
|
||||
foreach (var entry in skin.Attachments)
|
||||
HashMap<Skin::AttachmentKey, Attachment*, Skin::HashAttachmentKey>& attachments = skin->getAttachments();
|
||||
|
||||
for (typename HashMap<Skin::AttachmentKey, Attachment*, Skin::HashAttachmentKey>::Iterator i = attachments.begin(); i != attachments.end(); ++i)
|
||||
{
|
||||
if (entry.Key.slotIndex == slotIndex)
|
||||
Skin::AttachmentKey key = i.first();
|
||||
if (key._slotIndex == slotIndex)
|
||||
{
|
||||
sortPathConstraintAttachment(entry.Value, slotBone);
|
||||
Attachment* value = i.second();
|
||||
sortPathConstraintAttachment(value, slotBone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::sortPathConstraintAttachment(Attachment* attachment, Bone* slotBone)
|
||||
void Skeleton::sortPathConstraintAttachment(Attachment* attachment, Bone& slotBone)
|
||||
{
|
||||
if (!(attachment is PathAttachment))
|
||||
if (attachment == NULL || attachment->getRTTI().derivesFrom(PathAttachment::rtti))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int[] pathBones = ((PathAttachment)attachment).bones;
|
||||
if (pathBones == NULL)
|
||||
PathAttachment* pathAttachment = static_cast<PathAttachment*>(attachment);
|
||||
Vector<int>& pathBonesRef = pathAttachment->getBones();
|
||||
Vector<int> pathBones = pathBonesRef;
|
||||
if (pathBones.size() == 0)
|
||||
{
|
||||
sortBone(slotBone);
|
||||
sortBone(&slotBone);
|
||||
}
|
||||
else
|
||||
{
|
||||
var bones = _bones;
|
||||
for (int i = 0, n = pathBones.Length; i < n;)
|
||||
for (int i = 0, n = static_cast<int>(pathBones.size()); i < n;)
|
||||
{
|
||||
int nn = pathBones[i++];
|
||||
nn += i;
|
||||
while (i < nn)
|
||||
{
|
||||
sortBone(bones.Items[pathBones[i++]]);
|
||||
sortBone(_bones[pathBones[i++]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -836,32 +808,35 @@ namespace Spine
|
||||
|
||||
void Skeleton::sortBone(Bone* bone)
|
||||
{
|
||||
if (bone.sorted)
|
||||
assert(bone != NULL);
|
||||
|
||||
if (bone->_sorted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Bone parent = bone.parent;
|
||||
Bone* parent = bone->_parent;
|
||||
if (parent != NULL)
|
||||
{
|
||||
sortBone(parent);
|
||||
}
|
||||
|
||||
bone.sorted = true;
|
||||
updateCache.Add(bone);
|
||||
bone->_sorted = true;
|
||||
|
||||
_updateCache.push_back(bone);
|
||||
}
|
||||
|
||||
void Skeleton::sortReset(Vector<Bone*>& bones)
|
||||
{
|
||||
for (Bone* i = bones.begin(); i != bones.end(); ++i)
|
||||
for (Bone** i = bones.begin(); i != bones.end(); ++i)
|
||||
{
|
||||
Bone* bone = i;
|
||||
if (bone->isSorted())
|
||||
Bone* bone = (*i);
|
||||
if (bone->_sorted)
|
||||
{
|
||||
sortReset(bone->getChildren());
|
||||
}
|
||||
|
||||
bone->setSorted(false);
|
||||
bone->_sorted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,10 +46,14 @@
|
||||
namespace Spine
|
||||
{
|
||||
SkeletonData::SkeletonData() :
|
||||
_name(),
|
||||
_defaultSkin(NULL),
|
||||
_width(0),
|
||||
_height(0),
|
||||
_fps(0)
|
||||
_version(),
|
||||
_hash(),
|
||||
_fps(0),
|
||||
_imagesPath()
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ namespace Spine
|
||||
{
|
||||
assert(attachment);
|
||||
|
||||
_attachments[AttachmentKey(slotIndex, name)] = attachment;
|
||||
_attachments.insert(AttachmentKey(slotIndex, name), attachment);
|
||||
}
|
||||
|
||||
Attachment* Skin::getAttachment(int slotIndex, std::string name)
|
||||
@ -104,17 +104,19 @@ namespace Spine
|
||||
return _name;
|
||||
}
|
||||
|
||||
HashMap<Skin::AttachmentKey, Attachment*, HashAttachmentKey>& Skin::getAttachments()
|
||||
HashMap<Skin::AttachmentKey, Attachment*, Skin::HashAttachmentKey>& Skin::getAttachments()
|
||||
{
|
||||
return _attachments;
|
||||
}
|
||||
|
||||
void Skin::attachAll(Skeleton& skeleton, Skin& oldSkin)
|
||||
{
|
||||
Vector<Slot*>& slots = skeleton.getSlots();
|
||||
|
||||
for (HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = oldSkin.getAttachments().begin(); i != oldSkin.getAttachments().end(); ++i)
|
||||
{
|
||||
int slotIndex = i.first()._slotIndex;
|
||||
Slot* slot = skeleton.getSlots()[slotIndex];
|
||||
Slot* slot = slots[slotIndex];
|
||||
|
||||
if (slot->getAttachment() == i.second())
|
||||
{
|
||||
|
||||
@ -38,9 +38,9 @@
|
||||
namespace Spine
|
||||
{
|
||||
Slot::Slot(SlotData& data, Bone& bone) :
|
||||
_slotData(data),
|
||||
_data(data),
|
||||
_bone(bone),
|
||||
_skeleton(bone.getSkeletion()),
|
||||
_skeleton(bone.getSkeleton()),
|
||||
_r(1),
|
||||
_g(1),
|
||||
_b(1),
|
||||
@ -57,16 +57,16 @@ namespace Spine
|
||||
|
||||
void Slot::setToSetupPose()
|
||||
{
|
||||
_r = _slotData.getR();
|
||||
_g = _slotData.getG();
|
||||
_b = _slotData.getB();
|
||||
_a = _slotData.getA();
|
||||
_r = _data.getR();
|
||||
_g = _data.getG();
|
||||
_b = _data.getB();
|
||||
_a = _data.getA();
|
||||
|
||||
std::string attachmentName = _slotData.getAttachmentName();
|
||||
std::string attachmentName = _data.getAttachmentName();
|
||||
if (attachmentName.length() > 0)
|
||||
{
|
||||
_attachment = NULL;
|
||||
setAttachment(_skeleton.getAttachment(_slotData.getIndex(), attachmentName));
|
||||
setAttachment(_skeleton.getAttachment(_data.getIndex(), attachmentName));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -74,9 +74,9 @@ namespace Spine
|
||||
}
|
||||
}
|
||||
|
||||
SlotData& Slot::getSlotData()
|
||||
SlotData& Slot::getData()
|
||||
{
|
||||
return _slotData;
|
||||
return _data;
|
||||
}
|
||||
|
||||
Bone& Slot::getBone()
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
SlotData::SlotData(int index, std::string name, const BoneData& boneData) :
|
||||
SlotData::SlotData(int index, std::string name, BoneData& boneData) :
|
||||
_index(index),
|
||||
_name(name),
|
||||
_boneData(boneData),
|
||||
@ -63,7 +63,7 @@ namespace Spine
|
||||
return _name;
|
||||
}
|
||||
|
||||
const BoneData& SlotData::getBoneData()
|
||||
BoneData& SlotData::getBoneData()
|
||||
{
|
||||
return _boneData;
|
||||
}
|
||||
|
||||
@ -44,4 +44,6 @@ namespace Spine
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
RTTI_IMPL_NOPARENT(Timeline);
|
||||
}
|
||||
|
||||
@ -427,22 +427,24 @@ namespace Spine
|
||||
{
|
||||
if (scaleX > 0.00001f)
|
||||
{
|
||||
scaleX *= ((target._ascaleX - 1 + data.offsetScaleX) * scaleMix) + 1;
|
||||
scaleX *= ((target._ascaleX - 1 + _data._offsetScaleX) * scaleMix) + 1;
|
||||
}
|
||||
|
||||
if (scaleY > 0.00001f)
|
||||
{
|
||||
scaleY *= ((target._ascaleY - 1 + data.offsetScaleY) * scaleMix) + 1;
|
||||
scaleY *= ((target._ascaleY - 1 + _data._offsetScaleY) * scaleMix) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
float shearY = bone._ashearY;
|
||||
if (shearMix > 0)
|
||||
{
|
||||
shearY += (target._ashearY + data.offsetShearY) * shearMix;
|
||||
shearY += (target._ashearY + _data._offsetShearY) * shearMix;
|
||||
}
|
||||
|
||||
bone.updateWorldTransform(x, y, rotation, scaleX, scaleY, bone._ashearX, shearY);
|
||||
}
|
||||
}
|
||||
|
||||
RTTI_IMPL(TransformConstraint, Constraint);
|
||||
}
|
||||
|
||||
@ -41,4 +41,6 @@ namespace Spine
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
RTTI_IMPL_NOPARENT(Updatable);
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ namespace Spine
|
||||
return _id;
|
||||
}
|
||||
|
||||
Vector<int> VertexAttachment::getBones()
|
||||
Vector<int>& VertexAttachment::getBones()
|
||||
{
|
||||
return _bones;
|
||||
}
|
||||
@ -148,7 +148,7 @@ namespace Spine
|
||||
_bones = inValue;
|
||||
}
|
||||
|
||||
Vector<float> VertexAttachment::getVertices()
|
||||
Vector<float>& VertexAttachment::getVertices()
|
||||
{
|
||||
return _vertices;
|
||||
}
|
||||
@ -174,4 +174,6 @@ namespace Spine
|
||||
|
||||
return (nextID++ & 65535) << 11;
|
||||
}
|
||||
|
||||
RTTI_IMPL(VertexAttachment, Attachment);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user