diff --git a/spine-cpp/spine-cpp/include/spine/Animation.h b/spine-cpp/spine-cpp/include/spine/Animation.h new file mode 100644 index 000000000..581d8cc34 --- /dev/null +++ b/spine-cpp/spine-cpp/include/spine/Animation.h @@ -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 +#include +#include + +#include + +namespace Spine +{ + class Timeline; + class Skeleton; + class Event; + + class Animation + { + friend class RotateTimeline; + + public: + Animation(std::string name, Vector& 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& events, float alpha, MixPose pose, MixDirection direction); + + std::string getName(); + + Vector getTimelines(); + + void setTimelines(Vector inValue); + + float getDuration(); + + void setDuration(float inValue); + + private: + Vector _timelines; + float _duration; + std::string _name; + + /// @param target After the first and before the last entry. + static int binarySearch(Vector& values, float target, int step); + + /// @param target After the first and before the last entry. + static int binarySearch(Vector& values, float target); + + static int linearSearch(Vector& values, float target, int step); + }; +} + +#endif /* Spine_Animation_h */ diff --git a/spine-cpp/spine-cpp/include/spine/Bone.h b/spine-cpp/spine-cpp/include/spine/Bone.h index a0b61867e..5cf390cad 100644 --- a/spine-cpp/spine-cpp/include/spine/Bone.h +++ b/spine-cpp/spine-cpp/include/spine/Bone.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); diff --git a/spine-cpp/spine-cpp/include/spine/Constraint.h b/spine-cpp/spine-cpp/include/spine/Constraint.h index e0c910d51..aa0122c34 100644 --- a/spine-cpp/spine-cpp/include/spine/Constraint.h +++ b/spine-cpp/spine-cpp/include/spine/Constraint.h @@ -38,6 +38,8 @@ namespace Spine /// The interface for all constraints. class Constraint : public Updatable { + RTTI_DECL; + public: Constraint(); diff --git a/spine-cpp/spine-cpp/include/spine/ContainerUtil.h b/spine-cpp/spine-cpp/include/spine/ContainerUtil.h index 11d8e34e6..fd415d42a 100644 --- a/spine-cpp/spine-cpp/include/spine/ContainerUtil.h +++ b/spine-cpp/spine-cpp/include/spine/ContainerUtil.h @@ -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 #include @@ -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(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 + static T* findWithDataName(Vector& 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 + static int findIndexWithDataName(Vector& 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(i); } } @@ -111,4 +149,4 @@ namespace Spine }; } -#endif /* defined(__noctisgames__ContainerUtil__) */ +#endif /* Spine_ContainerUtil_h */ diff --git a/spine-cpp/spine-cpp/include/spine/CurveTimeline.h b/spine-cpp/spine-cpp/include/spine/CurveTimeline.h index ccf3b1f86..a5222e31e 100644 --- a/spine-cpp/spine-cpp/include/spine/CurveTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/CurveTimeline.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); diff --git a/spine-cpp/spine-cpp/include/spine/EventData.h b/spine-cpp/spine-cpp/include/spine/EventData.h index 9705f5d89..4f9982d1b 100644 --- a/spine-cpp/spine-cpp/include/spine/EventData.h +++ b/spine-cpp/spine-cpp/include/spine/EventData.h @@ -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; }; } diff --git a/spine-cpp/spine-cpp/include/spine/IkConstraint.h b/spine-cpp/spine-cpp/include/spine/IkConstraint.h index b7359ea7b..c09f8c7cd 100644 --- a/spine-cpp/spine-cpp/include/spine/IkConstraint.h +++ b/spine-cpp/spine-cpp/include/spine/IkConstraint.h @@ -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 _bones; - Bone* _target; float _mix; int _bendDirection; + Bone* _target; }; } diff --git a/spine-cpp/spine-cpp/include/spine/IkConstraintData.h b/spine-cpp/spine-cpp/include/spine/IkConstraintData.h index 521101734..0b516aa7e 100644 --- a/spine-cpp/spine-cpp/include/spine/IkConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/IkConstraintData.h @@ -41,6 +41,9 @@ namespace Spine class IkConstraintData { + friend class IkConstraint; + friend class Skeleton; + public: IkConstraintData(std::string name); diff --git a/spine-cpp/spine-cpp/include/spine/MathUtil.h b/spine-cpp/spine-cpp/include/spine/MathUtil.h index bc9bc5851..24dd4641c 100644 --- a/spine-cpp/spine-cpp/include/spine/MathUtil.h +++ b/spine-cpp/spine-cpp/include/spine/MathUtil.h @@ -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 */ diff --git a/spine-cpp/spine-cpp/include/spine/MeshAttachment.h b/spine-cpp/spine-cpp/include/spine/MeshAttachment.h new file mode 100644 index 000000000..52f916689 --- /dev/null +++ b/spine-cpp/spine-cpp/include/spine/MeshAttachment.h @@ -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 + +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. + 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 */ diff --git a/spine-cpp/spine-cpp/include/spine/PathAttachment.h b/spine-cpp/spine-cpp/include/spine/PathAttachment.h index 5eda9a360..6f0e53993 100644 --- a/spine-cpp/spine-cpp/include/spine/PathAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/PathAttachment.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& getLengths(); + void setLengths(Vector inValue); + bool isClosed(); + void setClosed(bool inValue); + bool isConstantSpeed(); + void setConstantSpeed(bool inValue); private: - float[] lengths; - bool closed, constantSpeed; + Vector _lengths; + bool _closed; + bool _constantSpeed; }; } diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraint.h b/spine-cpp/spine-cpp/include/spine/PathConstraint.h index 464622a3d..7f6440c48 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraint.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraint.h @@ -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. diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraintData.h b/spine-cpp/spine-cpp/include/spine/PathConstraintData.h index 4acdf4513..fc7a77d16 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraintData.h @@ -45,6 +45,9 @@ namespace Spine class PathConstraintData { + friend class PathConstraint; + friend class Skeleton; + public: PathConstraintData(std::string name); diff --git a/spine-cpp/spine-cpp/include/spine/RegionAttachment.h b/spine-cpp/spine-cpp/include/spine/RegionAttachment.h new file mode 100644 index 000000000..6e513d3da --- /dev/null +++ b/spine-cpp/spine-cpp/include/spine/RegionAttachment.h @@ -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 + +#include +#include + +#include + +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 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 */ diff --git a/spine-cpp/spine-cpp/include/spine/RotateTimeline.h b/spine-cpp/spine-cpp/include/spine/RotateTimeline.h index 9b2ff0403..dcc013b71 100644 --- a/spine-cpp/spine-cpp/include/spine/RotateTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/RotateTimeline.h @@ -37,6 +37,8 @@ namespace Spine { class RotateTimeline : public CurveTimeline { + RTTI_DECL; + public: static const int ENTRIES = 2; diff --git a/spine-cpp/spine-cpp/include/spine/Skeleton.h b/spine-cpp/spine-cpp/include/spine/Skeleton.h index 5c4f3e782..9e3eb9583 100644 --- a/spine-cpp/spine-cpp/include/spine/Skeleton.h +++ b/spine-cpp/spine-cpp/include/spine/Skeleton.h @@ -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& getTransformConstraints(); Skin* getSkin(); - void setSkin(Skin* inValue); float getR(); void setR(float inValue); float getG(); @@ -167,7 +166,7 @@ namespace Spine Vector _updateCache; Vector _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& bones); }; diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonData.h b/spine-cpp/spine-cpp/include/spine/SkeletonData.h index 4508d537a..44e467edc 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonData.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonData.h @@ -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(); diff --git a/spine-cpp/spine-cpp/include/spine/Skin.h b/spine-cpp/spine-cpp/include/spine/Skin.h index b6f36dd9c..37f7ea64a 100644 --- a/spine-cpp/spine-cpp/include/spine/Skin.h +++ b/spine-cpp/spine-cpp/include/spine/Skin.h @@ -35,8 +35,6 @@ #include #include -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 inValue); private: - SlotData& _slotData; + SlotData& _data; Bone& _bone; Skeleton& _skeleton; float _r, _g, _b, _a; diff --git a/spine-cpp/spine-cpp/include/spine/SlotData.h b/spine-cpp/spine-cpp/include/spine/SlotData.h index 310cf1fd5..0fe231984 100644 --- a/spine-cpp/spine-cpp/include/spine/SlotData.h +++ b/spine-cpp/spine-cpp/include/spine/SlotData.h @@ -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(); diff --git a/spine-cpp/spine-cpp/include/spine/Timeline.h b/spine-cpp/spine-cpp/include/spine/Timeline.h index 056ba8d39..b00db7b28 100644 --- a/spine-cpp/spine-cpp/include/spine/Timeline.h +++ b/spine-cpp/spine-cpp/include/spine/Timeline.h @@ -31,6 +31,7 @@ #ifndef Spine_Timeline_h #define Spine_Timeline_h +#include #include #include #include @@ -42,6 +43,8 @@ namespace Spine class Timeline { + RTTI_DECL; + public: Timeline(); diff --git a/spine-cpp/spine-cpp/include/spine/TransformConstraint.h b/spine-cpp/spine-cpp/include/spine/TransformConstraint.h index 550988911..262c3a210 100644 --- a/spine-cpp/spine-cpp/include/spine/TransformConstraint.h +++ b/spine-cpp/spine-cpp/include/spine/TransformConstraint.h @@ -43,6 +43,10 @@ namespace Spine class TransformConstraint : public Constraint { + friend class Skeleton; + + RTTI_DECL; + public: TransformConstraint(TransformConstraintData& data, Skeleton& skeleton); diff --git a/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h b/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h index c74bc25bc..d3a5aebb3 100644 --- a/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h @@ -42,6 +42,7 @@ namespace Spine class TransformConstraintData { friend class TransformConstraint; + friend class Skeleton; public: TransformConstraintData(std::string name); diff --git a/spine-cpp/spine-cpp/include/spine/Updatable.h b/spine-cpp/spine-cpp/include/spine/Updatable.h index a521ca72a..fac634191 100644 --- a/spine-cpp/spine-cpp/include/spine/Updatable.h +++ b/spine-cpp/spine-cpp/include/spine/Updatable.h @@ -31,10 +31,14 @@ #ifndef Spine_Updatable_h #define Spine_Updatable_h +#include + namespace Spine { class Updatable { + RTTI_DECL; + public: Updatable(); diff --git a/spine-cpp/spine-cpp/include/spine/Vector.h b/spine-cpp/spine-cpp/include/spine/Vector.h index df2e18e7d..8fc232098 100644 --- a/spine-cpp/spine-cpp/include/spine/Vector.h +++ b/spine-cpp/spine-cpp/include/spine/Vector.h @@ -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(realloc(_buffer, newCapacity * sizeof(T))); - _capacity = newCapacity; + size_t newCapacity = inCapacity > 0 ? inCapacity : _capacity > 0 ? _capacity * 2 : 1; + if (newCapacity > _capacity) + { + _buffer = static_cast(realloc(_buffer, newCapacity * sizeof(T))); + _capacity = newCapacity; + } } T* begin() diff --git a/spine-cpp/spine-cpp/include/spine/VertexAttachment.h b/spine-cpp/spine-cpp/include/spine/VertexAttachment.h index 18b5fc81c..ba047dfe8 100644 --- a/spine-cpp/spine-cpp/include/spine/VertexAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/VertexAttachment.h @@ -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 getBones(); + Vector& getBones(); void setBones(Vector inValue); - Vector getVertices(); + Vector& getVertices(); void setVertices(Vector inValue); int getWorldVerticesLength(); diff --git a/spine-cpp/spine-cpp/src/spine/Animation.cpp b/spine-cpp/spine-cpp/src/spine/Animation.cpp new file mode 100644 index 000000000..3cbc2e63c --- /dev/null +++ b/spine-cpp/spine-cpp/src/spine/Animation.cpp @@ -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 + +#include +#include +#include + +#include +#include /* fmod */ + +namespace Spine +{ + Animation::Animation(std::string name, Vector& 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& 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(_timelines.size()); i < n; ++i) + { + _timelines[i]->apply(skeleton, lastTime, time, events, alpha, pose, direction); + } + } + + std::string Animation::getName() + { + return _name; + } + + Vector Animation::getTimelines() + { + return _timelines; + } + + void Animation::setTimelines(Vector inValue) + { + _timelines = inValue; + } + + float Animation::getDuration() + { + return _duration; + } + + void Animation::setDuration(float inValue) + { + _duration = inValue; + } + + int Animation::binarySearch(Vector& values, float target, int step) + { + int low = 0; + int size = static_cast(values.size()); + int high = size / step - 2; + if (high == 0) + { + return step; + } + + int current = (int)(static_cast(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(low + high) >> 1); + } + } + + int Animation::binarySearch(Vector& values, float target) + { + int low = 0; + int size = static_cast(values.size()); + int high = size - 2; + if (high == 0) + { + return 1; + } + + int current = (int)(static_cast(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(low + high) >> 1); + } + } + + int Animation::linearSearch(Vector& values, float target, int step) + { + for (int i = 0, last = static_cast(values.size()) - step; i <= last; i += step) + { + if (values[i] > target) + { + return i; + } + } + + return -1; + } +} diff --git a/spine-cpp/spine-cpp/src/spine/Bone.cpp b/spine-cpp/spine-cpp/src/spine/Bone.cpp index f4fe9ed59..bb8dcc004 100644 --- a/spine-cpp/spine-cpp/src/spine/Bone.cpp +++ b/spine-cpp/spine-cpp/src/spine/Bone.cpp @@ -621,4 +621,6 @@ namespace Spine _arotation = 90 - MathUtil::atan2(rd, rb) * RadDeg; } } + + RTTI_IMPL(Bone, Updatable); } diff --git a/spine-cpp/spine-cpp/src/spine/Constraint.cpp b/spine-cpp/spine-cpp/src/spine/Constraint.cpp index e6e84bd6c..ae6a8d749 100644 --- a/spine-cpp/spine-cpp/src/spine/Constraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/Constraint.cpp @@ -41,5 +41,6 @@ namespace Spine { // Empty } + + RTTI_IMPL(Constraint, Updatable); } - diff --git a/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp b/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp index 67c0435cf..9735c76dc 100644 --- a/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/CurveTimeline.cpp @@ -133,4 +133,6 @@ namespace Spine { return _curves[frameIndex * BEZIER_SIZE]; } + + RTTI_IMPL(CurveTimeline, Timeline); } diff --git a/spine-cpp/spine-cpp/src/spine/Event.cpp b/spine-cpp/spine-cpp/src/spine/Event.cpp index 5f1458815..ca9abdbbd 100644 --- a/spine-cpp/spine-cpp/src/spine/Event.cpp +++ b/spine-cpp/spine-cpp/src/spine/Event.cpp @@ -39,7 +39,7 @@ namespace Spine _data(data), _intValue(0), _floatValue(0), - _stringValue(0) + _stringValue() { // Empty } diff --git a/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp b/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp index 73e68082d..1bf6cdb74 100644 --- a/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp @@ -357,4 +357,6 @@ namespace Spine { _mix = inValue; } + + RTTI_IMPL(IkConstraint, Constraint); } diff --git a/spine-cpp/spine-cpp/src/spine/MeshAttachment.cpp b/spine-cpp/spine-cpp/src/spine/MeshAttachment.cpp new file mode 100644 index 000000000..42159e2c9 --- /dev/null +++ b/spine-cpp/spine-cpp/src/spine/MeshAttachment.cpp @@ -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 + +namespace Spine +{ + RTTI_IMPL(MeshAttachment, VertexAttachment); +} diff --git a/spine-cpp/spine-cpp/src/spine/PathAttachment.cpp b/spine-cpp/spine-cpp/src/spine/PathAttachment.cpp index bb4d2ccfe..d7d57ccd9 100644 --- a/spine-cpp/spine-cpp/src/spine/PathAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathAttachment.cpp @@ -28,7 +28,44 @@ * POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +#include + namespace Spine { - // TODO + PathAttachment::PathAttachment(std::string name) : VertexAttachment(name) + { + // Empty + } + + Vector& PathAttachment::getLengths() + { + return _lengths; + } + + void PathAttachment::setLengths(Vector 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); } diff --git a/spine-cpp/spine-cpp/src/spine/PathConstraint.cpp b/spine-cpp/spine-cpp/src/spine/PathConstraint.cpp index 32e688782..6efbbb7be 100644 --- a/spine-cpp/spine-cpp/src/spine/PathConstraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/PathConstraint.cpp @@ -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 spaces = _spaces.Resize(spacesCount), lengths = NULL; + size_t boneCount = _bones.size(); + int spacesCount = static_cast(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 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& 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& temp, int i, Vector& 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& 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); } diff --git a/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp b/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp new file mode 100644 index 000000000..b5b78a49e --- /dev/null +++ b/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp @@ -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 + +namespace Spine +{ + RTTI_IMPL(RegionAttachment, Attachment); +} diff --git a/spine-cpp/spine-cpp/src/spine/RotateTimeline.cpp b/spine-cpp/spine-cpp/src/spine/RotateTimeline.cpp index 1d2cb4bde..b58b14988 100644 --- a/spine-cpp/spine-cpp/src/spine/RotateTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/RotateTimeline.cpp @@ -147,4 +147,6 @@ namespace Spine { _frames = inValue; } + + RTTI_IMPL(RotateTimeline, CurveTimeline); } diff --git a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp index aeae9606c..2d6a85fdc 100644 --- a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp @@ -45,6 +45,9 @@ #include #include #include +#include +#include +#include #include @@ -135,81 +138,101 @@ namespace Spine void Skeleton::updateCache() { - Vector updateCache = _updateCache; - updateCache.Clear(); - _updateCacheReset.Clear(); + _updateCache.clear(); + _updateCacheReset.clear(); - Vector bones = _bones; - for (int i = 0, n = bones.Count; i < n; ++i) + for (int i = 0, n = static_cast(_bones.size()); i < n; ++i) { - bones.Items[i].sorted = false; + _bones[i]->_sorted = false; } - Vector ikConstraints = _ikConstraints; - var transformConstraints = _transformConstraints; - var pathConstraints = _pathConstraints; - int ikCount = IkConstraints.Count, transformCount = transformConstraints.Count, pathCount = pathConstraints.Count; + int ikCount = static_cast(_ikConstraints.size()); + int transformCount = static_cast(_transformConstraints.size()); + int pathCount = static_cast(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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 slots = _slots; - for (int i = 0, n = slots.Count; i < n; ++i) + for (int i = 0, n = static_cast(_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 slots = _slots; - for (int i = 0, n = slots.Count; i < n; ++i) + for (int i = 0, n = static_cast(_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 ikConstraints = _ikConstraints; - for (int i = 0, n = ikConstraints.Count; i < n; ++i) + for (int i = 0, n = static_cast(_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 transformConstraints = _transformConstraints; - for (int i = 0, n = transformConstraints.Count; i < n; ++i) + for (int i = 0, n = static_cast(_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 pathConstraints = _pathConstraints; - for (int i = 0, n = pathConstraints.Count; i < n; ++i) + for (int i = 0, n = static_cast(_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::min(); float maxY = std::numeric_limits::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(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(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& 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(_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& constrained = constraint->getBones(); + int boneCount = static_cast(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& constrained = constraint->getBones(); + int boneCount = static_cast(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& attachments = skin->getAttachments(); + + for (typename HashMap::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(attachment); + Vector& pathBonesRef = pathAttachment->getBones(); + Vector 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(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& 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; } } } diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp index 201359534..3a3367743 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp @@ -46,10 +46,14 @@ namespace Spine { SkeletonData::SkeletonData() : + _name(), _defaultSkin(NULL), _width(0), _height(0), - _fps(0) + _version(), + _hash(), + _fps(0), + _imagesPath() { // Empty } diff --git a/spine-cpp/spine-cpp/src/spine/Skin.cpp b/spine-cpp/spine-cpp/src/spine/Skin.cpp index d2b8c7259..d3dec3573 100644 --- a/spine-cpp/spine-cpp/src/spine/Skin.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skin.cpp @@ -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::getAttachments() + HashMap& Skin::getAttachments() { return _attachments; } void Skin::attachAll(Skeleton& skeleton, Skin& oldSkin) { + Vector& slots = skeleton.getSlots(); + for (HashMap::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()) { diff --git a/spine-cpp/spine-cpp/src/spine/Slot.cpp b/spine-cpp/spine-cpp/src/spine/Slot.cpp index fa9e1f5d8..d245533ad 100644 --- a/spine-cpp/spine-cpp/src/spine/Slot.cpp +++ b/spine-cpp/spine-cpp/src/spine/Slot.cpp @@ -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() diff --git a/spine-cpp/spine-cpp/src/spine/SlotData.cpp b/spine-cpp/spine-cpp/src/spine/SlotData.cpp index 01eb96540..327327cbb 100644 --- a/spine-cpp/spine-cpp/src/spine/SlotData.cpp +++ b/spine-cpp/spine-cpp/src/spine/SlotData.cpp @@ -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; } diff --git a/spine-cpp/spine-cpp/src/spine/Timeline.cpp b/spine-cpp/spine-cpp/src/spine/Timeline.cpp index 39f4cc164..64044ca08 100644 --- a/spine-cpp/spine-cpp/src/spine/Timeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/Timeline.cpp @@ -44,4 +44,6 @@ namespace Spine { // Empty } + + RTTI_IMPL_NOPARENT(Timeline); } diff --git a/spine-cpp/spine-cpp/src/spine/TransformConstraint.cpp b/spine-cpp/spine-cpp/src/spine/TransformConstraint.cpp index 06669c000..6a956c071 100644 --- a/spine-cpp/spine-cpp/src/spine/TransformConstraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/TransformConstraint.cpp @@ -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); } diff --git a/spine-cpp/spine-cpp/src/spine/Updatable.cpp b/spine-cpp/spine-cpp/src/spine/Updatable.cpp index d5a7f2ec3..810c959a8 100644 --- a/spine-cpp/spine-cpp/src/spine/Updatable.cpp +++ b/spine-cpp/spine-cpp/src/spine/Updatable.cpp @@ -41,4 +41,6 @@ namespace Spine { // Empty } + + RTTI_IMPL_NOPARENT(Updatable); } diff --git a/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp b/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp index 7581d360b..a101b5fa4 100644 --- a/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/VertexAttachment.cpp @@ -138,7 +138,7 @@ namespace Spine return _id; } - Vector VertexAttachment::getBones() + Vector& VertexAttachment::getBones() { return _bones; } @@ -148,7 +148,7 @@ namespace Spine _bones = inValue; } - Vector VertexAttachment::getVertices() + Vector& VertexAttachment::getVertices() { return _vertices; } @@ -174,4 +174,6 @@ namespace Spine return (nextID++ & 65535) << 11; } + + RTTI_IMPL(VertexAttachment, Attachment); }