From d7d08d263a4ee12fe21bc360e6f8194a971876ca Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Tue, 16 Feb 2016 00:14:07 +0100 Subject: [PATCH] Updated spine-c and spine-sfml to Spine v3. --- spine-c/.cproject | 12 +- spine-c/include/spine/Animation.h | 34 +-- spine-c/include/spine/Attachment.h | 4 +- spine-c/include/spine/Bone.h | 39 ++-- spine-c/include/spine/BoneData.h | 2 - spine-c/include/spine/Event.h | 4 +- spine-c/include/spine/IkConstraint.h | 3 + spine-c/include/spine/Skeleton.h | 16 +- spine-c/include/spine/SkeletonData.h | 8 +- spine-c/include/spine/TransformConstraint.h | 79 +++++++ .../include/spine/TransformConstraintData.h | 74 +++++++ ...hAttachment.h => WeightedMeshAttachment.h} | 24 +- spine-c/include/spine/extension.h | 4 +- spine-c/include/spine/spine.h | 2 +- spine-c/src/spine/Animation.c | 45 ---- spine-c/src/spine/AtlasAttachmentLoader.c | 6 +- spine-c/src/spine/Bone.c | 205 +++++++++++++----- spine-c/src/spine/BoundingBoxAttachment.c | 4 +- spine-c/src/spine/Event.c | 3 +- spine-c/src/spine/IkConstraint.c | 175 ++++++++++----- spine-c/src/spine/MeshAttachment.c | 4 +- spine-c/src/spine/RegionAttachment.c | 16 +- spine-c/src/spine/Skeleton.c | 146 ++++++------- spine-c/src/spine/SkeletonData.c | 15 +- spine-c/src/spine/SkeletonJson.c | 72 +++--- spine-c/src/spine/TransformConstraint.c | 58 +++++ spine-c/src/spine/TransformConstraintData.c | 44 ++++ ...hAttachment.c => WeightedMeshAttachment.c} | 24 +- .../.settings/org.eclipse.cdt.core.prefs | 2 +- spine-sfml/src/spine/spine-sfml.cpp | 6 +- 30 files changed, 757 insertions(+), 373 deletions(-) create mode 100644 spine-c/include/spine/TransformConstraint.h create mode 100644 spine-c/include/spine/TransformConstraintData.h rename spine-c/include/spine/{SkinnedMeshAttachment.h => WeightedMeshAttachment.h} (76%) create mode 100644 spine-c/src/spine/TransformConstraint.c create mode 100644 spine-c/src/spine/TransformConstraintData.c rename spine-c/src/spine/{SkinnedMeshAttachment.c => WeightedMeshAttachment.c} (80%) diff --git a/spine-c/.cproject b/spine-c/.cproject index b2b0c13c2..66072cca1 100644 --- a/spine-c/.cproject +++ b/spine-c/.cproject @@ -5,13 +5,13 @@ + - - + @@ -69,14 +69,14 @@ + - - + @@ -117,10 +117,10 @@ - + - + diff --git a/spine-c/include/spine/Animation.h b/spine-c/include/spine/Animation.h index c826b262f..41485583a 100644 --- a/spine-c/include/spine/Animation.h +++ b/spine-c/include/spine/Animation.h @@ -94,9 +94,7 @@ typedef enum { SP_TIMELINE_EVENT, SP_TIMELINE_DRAWORDER, SP_TIMELINE_FFD, - SP_TIMELINE_IKCONSTRAINT, - SP_TIMELINE_FLIPX, - SP_TIMELINE_FLIPY + SP_TIMELINE_IKCONSTRAINT } spTimelineType; struct spTimeline { @@ -400,36 +398,6 @@ typedef spIkConstraintTimeline IkConstraintTimeline; /**/ -typedef struct spFlipTimeline { - spTimeline super; - int const x; - int const framesCount; - float* const frames; /* time, flip, ... */ - int boneIndex; - -#ifdef __cplusplus - spFlipTimeline() : - super(), - x(0), - framesCount(0), - frames(0), - boneIndex(0) { - } -#endif -} spFlipTimeline; - -spFlipTimeline* spFlipTimeline_create (int framesCount, int/*bool*/x); - -void spFlipTimeline_setFrame (spFlipTimeline* self, int frameIndex, float time, int/*bool*/flip); - -#ifdef SPINE_SHORT_NAMES -typedef spFlipTimeline FlipTimeline; -#define FlipTimeline_create(...) spFlipTimeline_create(__VA_ARGS__) -#define FlipTimeline_setFrame(...) spFlipTimeline_setFrame(__VA_ARGS__) -#endif - -/**/ - #ifdef __cplusplus } #endif diff --git a/spine-c/include/spine/Attachment.h b/spine-c/include/spine/Attachment.h index cab8a3938..71eccd3cb 100644 --- a/spine-c/include/spine/Attachment.h +++ b/spine-c/include/spine/Attachment.h @@ -37,7 +37,7 @@ extern "C" { #endif typedef enum { - SP_ATTACHMENT_REGION, SP_ATTACHMENT_BOUNDING_BOX, SP_ATTACHMENT_MESH, SP_ATTACHMENT_SKINNED_MESH + SP_ATTACHMENT_REGION, SP_ATTACHMENT_BOUNDING_BOX, SP_ATTACHMENT_MESH, SP_ATTACHMENT_WEIGHTED_MESH } spAttachmentType; typedef struct spAttachment { @@ -61,7 +61,7 @@ typedef spAttachmentType AttachmentType; #define ATTACHMENT_REGION SP_ATTACHMENT_REGION #define ATTACHMENT_BOUNDING_BOX SP_ATTACHMENT_BOUNDING_BOX #define ATTACHMENT_MESH SP_ATTACHMENT_MESH -#define ATTACHMENT_SKINNED_MESH SP_ATTACHMENT_SKINNED_MESH +#define ATTACHMENT_WEIGHTED_MESH SP_ATTACHMENT_WEIGHTED_MESH typedef spAttachment Attachment; #define Attachment_dispose(...) spAttachment_dispose(__VA_ARGS__) #endif diff --git a/spine-c/include/spine/Bone.h b/spine-c/include/spine/Bone.h index 88d482be4..160d9a642 100644 --- a/spine-c/include/spine/Bone.h +++ b/spine-c/include/spine/Bone.h @@ -45,32 +45,24 @@ struct spBone { spBoneData* const data; struct spSkeleton* const skeleton; spBone* const parent; - float x, y; - float rotation, rotationIK; - float scaleX, scaleY; - int/*bool*/flipX, flipY; + float x, y, rotation, scaleX, scaleY; + float appliedRotation, appliedScaleX, appliedScaleY; - float const m00, m01, worldX; /* a b x */ - float const m10, m11, worldY; /* c d y */ - float const worldRotation; - float const worldScaleX, worldScaleY; - int/*bool*/const worldFlipX, worldFlipY; + float const a, b, worldX; + float const c, d, worldY; + float const worldSignX, worldSignY; #ifdef __cplusplus spBone() : data(0), skeleton(0), parent(0), - x(0), y(0), - rotation(0), rotationIK(0), - scaleX(0), scaleY(0), - flipX(0), flipY(0), + x(0), y(0), rotation(0), scaleX(0), scaleY(0), + appliedRotation(0), appliedScaleX(0), appliedScaleY(0), - m00(0), m01(0), worldX(0), - m10(0), m11(0), worldY(0), - worldRotation(0), - worldScaleX(0), worldScaleY(0), - worldFlipX(0), worldFlipY(0) { + a(0), b(0), worldX(0), + c(0), d(0), worldY(0), + worldSignX(0), worldSignY(0) { } #endif }; @@ -85,6 +77,12 @@ void spBone_dispose (spBone* self); void spBone_setToSetupPose (spBone* self); void spBone_updateWorldTransform (spBone* self); +void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rotation, float scaleX, float scaleY); + +float spBone_getWorldRotationX (spBone* self); +float spBone_getWorldRotationY (spBone* self); +float spBone_getWorldScaleX (spBone* self); +float spBone_getWorldScaleY (spBone* self); void spBone_worldToLocal (spBone* self, float worldX, float worldY, float* localX, float* localY); void spBone_localToWorld (spBone* self, float localX, float localY, float* worldX, float* worldY); @@ -97,6 +95,11 @@ typedef spBone Bone; #define Bone_dispose(...) spBone_dispose(__VA_ARGS__) #define Bone_setToSetupPose(...) spBone_setToSetupPose(__VA_ARGS__) #define Bone_updateWorldTransform(...) spBone_updateWorldTransform(__VA_ARGS__) +#define Bone_updateWorldTransformWith(...) spBone_updateWorldTransformWith(__VA_ARGS__) +#define Bone_getWorldRotationX(...) spBone_getWorldRotationX(__VA_ARGS__) +#define Bone_getWorldRotationY(...) spBone_getWorldRotationY(__VA_ARGS__) +#define Bone_getWorldScaleX(...) spBone_getWorldScaleX(__VA_ARGS__) +#define Bone_getWorldScaleY(...) spBone_getWorldScaleY(__VA_ARGS__) #define Bone_worldToLocal(...) spBone_worldToLocal(__VA_ARGS__) #define Bone_localToWorld(...) spBone_localToWorld(__VA_ARGS__) #endif diff --git a/spine-c/include/spine/BoneData.h b/spine-c/include/spine/BoneData.h index 644f1bce0..e0591380c 100644 --- a/spine-c/include/spine/BoneData.h +++ b/spine-c/include/spine/BoneData.h @@ -44,7 +44,6 @@ struct spBoneData { float x, y; float rotation; float scaleX, scaleY; - int/*bool*/flipX, flipY; int/*bool*/inheritScale, inheritRotation; #ifdef __cplusplus @@ -55,7 +54,6 @@ struct spBoneData { x(0), y(0), rotation(0), scaleX(0), scaleY(0), - flipX(0), flipY(0), inheritScale(0), inheritRotation(0) { } #endif diff --git a/spine-c/include/spine/Event.h b/spine-c/include/spine/Event.h index 4df161a8a..31aebadca 100644 --- a/spine-c/include/spine/Event.h +++ b/spine-c/include/spine/Event.h @@ -40,6 +40,7 @@ extern "C" { typedef struct spEvent { spEventData* const data; + float const time; int intValue; float floatValue; const char* stringValue; @@ -47,6 +48,7 @@ typedef struct spEvent { #ifdef __cplusplus spEvent() : data(0), + time(0), intValue(0), floatValue(0), stringValue(0) { @@ -54,7 +56,7 @@ typedef struct spEvent { #endif } spEvent; -spEvent* spEvent_create (spEventData* data); +spEvent* spEvent_create (float time, spEventData* data); void spEvent_dispose (spEvent* self); #ifdef SPINE_SHORT_NAMES diff --git a/spine-c/include/spine/IkConstraint.h b/spine-c/include/spine/IkConstraint.h index 0b100edae..f30cad388 100644 --- a/spine-c/include/spine/IkConstraint.h +++ b/spine-c/include/spine/IkConstraint.h @@ -75,6 +75,9 @@ void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float typedef spIkConstraint IkConstraint; #define IkConstraint_create(...) spIkConstraint_create(__VA_ARGS__) #define IkConstraint_dispose(...) spIkConstraint_dispose(__VA_ARGS__) +#define IkConstraint_apply(...) spIkConstraint_apply(__VA_ARGS__) +#define IkConstraint_apply1(...) spIkConstraint_apply1(__VA_ARGS__) +#define IkConstraint_apply2(...) spIkConstraint_apply2(__VA_ARGS__) #endif #ifdef __cplusplus diff --git a/spine-c/include/spine/Skeleton.h b/spine-c/include/spine/Skeleton.h index 8b6e07afe..43a63dc9d 100644 --- a/spine-c/include/spine/Skeleton.h +++ b/spine-c/include/spine/Skeleton.h @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -55,6 +56,9 @@ typedef struct spSkeleton { int ikConstraintsCount; spIkConstraint** ikConstraints; + int transformConstraintsCount; + spTransformConstraint** transformConstraints; + spSkin* const skin; float r, g, b, a; float time; @@ -74,6 +78,9 @@ typedef struct spSkeleton { ikConstraintsCount(0), ikConstraints(0), + transformConstraintsCount(0), + transformConstraints(0), + skin(0), r(0), g(0), b(0), a(0), time(0), @@ -87,11 +94,13 @@ typedef struct spSkeleton { spSkeleton* spSkeleton_create (spSkeletonData* data); void spSkeleton_dispose (spSkeleton* self); -/* Caches information about bones and IK constraints. Must be called if bones or IK constraints are added or removed. */ +/* Caches information about bones and constraints. Must be called if bones or constraints are added or removed. */ void spSkeleton_updateCache (const spSkeleton* self); void spSkeleton_updateWorldTransform (const spSkeleton* self); +/* Sets the bones, constraints, and slots to their setup pose values. */ void spSkeleton_setToSetupPose (const spSkeleton* self); +/* Sets the bones and constraints to their setup pose values. */ void spSkeleton_setBonesToSetupPose (const spSkeleton* self); void spSkeleton_setSlotsToSetupPose (const spSkeleton* self); @@ -123,7 +132,10 @@ spAttachment* spSkeleton_getAttachmentForSlotIndex (const spSkeleton* self, int int spSkeleton_setAttachment (spSkeleton* self, const char* slotName, const char* attachmentName); /* Returns 0 if the IK constraint was not found. */ -spIkConstraint* spSkeleton_findIkConstraint (const spSkeleton* self, const char* ikConstraintName); +spIkConstraint* spSkeleton_findIkConstraint (const spSkeleton* self, const char* constraintName); + +/* Returns 0 if the transform constraint was not found. */ +spTransformConstraint* spSkeleton_findTransformConstraint (const spSkeleton* self, const char* constraintName); void spSkeleton_update (spSkeleton* self, float deltaTime); diff --git a/spine-c/include/spine/SkeletonData.h b/spine-c/include/spine/SkeletonData.h index 1041c5a07..e73b75fe0 100644 --- a/spine-c/include/spine/SkeletonData.h +++ b/spine-c/include/spine/SkeletonData.h @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -66,6 +67,9 @@ typedef struct spSkeletonData { int ikConstraintsCount; spIkConstraintData** ikConstraints; + + int transformConstraintsCount; + spTransformConstraintData** transformConstraints; } spSkeletonData; spSkeletonData* spSkeletonData_create (); @@ -83,7 +87,9 @@ spEventData* spSkeletonData_findEvent (const spSkeletonData* self, const char* e spAnimation* spSkeletonData_findAnimation (const spSkeletonData* self, const char* animationName); -spIkConstraintData* spSkeletonData_findIkConstraint (const spSkeletonData* self, const char* ikConstraintName); +spIkConstraintData* spSkeletonData_findIkConstraint (const spSkeletonData* self, const char* constraintName); + +spTransformConstraintData* spSkeletonData_findTransformConstraint (const spSkeletonData* self, const char* constraintName); #ifdef SPINE_SHORT_NAMES typedef spSkeletonData SkeletonData; diff --git a/spine-c/include/spine/TransformConstraint.h b/spine-c/include/spine/TransformConstraint.h new file mode 100644 index 000000000..c670a7823 --- /dev/null +++ b/spine-c/include/spine/TransformConstraint.h @@ -0,0 +1,79 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.3 + * + * Copyright (c) 2013-2015, 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 (the "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 otherwise create derivative works, improvements of the + * Software or develop new applications using the Software 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; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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_TRANSFORMCONSTRAINT_H_ +#define SPINE_TRANSFORMCONSTRAINT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct spSkeleton; + +typedef struct spTransformConstraint { + spTransformConstraintData* const data; + spBone* bone; + spBone* target; + float translateMix; + float x, y; + +#ifdef __cplusplus + spTransformConstraint() : + data(0), + bone(0), + target(0), + translateMix(0), + x(0), + y(0) { + } +#endif +} spTransformConstraint; + +spTransformConstraint* spTransformConstraint_create (spTransformConstraintData* data, const struct spSkeleton* skeleton); +void spTransformConstraint_dispose (spTransformConstraint* self); + +void spTransformConstraint_apply (spTransformConstraint* self); + +#ifdef SPINE_SHORT_NAMES +typedef spTransformConstraint TransformConstraint; +#define TransformConstraint_create(...) spTransformConstraint_create(__VA_ARGS__) +#define TransformConstraint_dispose(...) spTransformConstraint_dispose(__VA_ARGS__) +#define TransformConstraint_apply(...) spTransformConstraint_apply(__VA_ARGS__) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SPINE_TRANSFORMCONSTRAINT_H_ */ diff --git a/spine-c/include/spine/TransformConstraintData.h b/spine-c/include/spine/TransformConstraintData.h new file mode 100644 index 000000000..3fc02a045 --- /dev/null +++ b/spine-c/include/spine/TransformConstraintData.h @@ -0,0 +1,74 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.3 + * + * Copyright (c) 2013-2015, 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 (the "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 otherwise create derivative works, improvements of the + * Software or develop new applications using the Software 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; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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_TRANSFORMCONSTRAINTDATA_H_ +#define SPINE_TRANSFORMCONSTRAINTDATA_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct spTransformConstraintData { + const char* const name; + + spBoneData* bone; + spBoneData* target; + float translateMix; + float x, y; + +#ifdef __cplusplus + spTransformConstraintData() : + name(0), + bone(0), + target(0), + translateMix(0), + x(0), + y(0) { + } +#endif +} spTransformConstraintData; + +spTransformConstraintData* spTransformConstraintData_create (const char* name); +void spTransformConstraintData_dispose (spTransformConstraintData* self); + +#ifdef SPINE_SHORT_NAMES +typedef spTransformConstraintData TransformConstraintData; +#define TransformConstraintData_create(...) spTransformConstraintData_create(__VA_ARGS__) +#define TransformConstraintData_dispose(...) spTransformConstraintData_dispose(__VA_ARGS__) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SPINE_TRANSFORMCONSTRAINTDATA_H_ */ diff --git a/spine-c/include/spine/SkinnedMeshAttachment.h b/spine-c/include/spine/WeightedMeshAttachment.h similarity index 76% rename from spine-c/include/spine/SkinnedMeshAttachment.h rename to spine-c/include/spine/WeightedMeshAttachment.h index a9c56152c..b133a95b9 100644 --- a/spine-c/include/spine/SkinnedMeshAttachment.h +++ b/spine-c/include/spine/WeightedMeshAttachment.h @@ -29,8 +29,8 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -#ifndef SPINE_SKINNEDMESHATTACHMENT_H_ -#define SPINE_SKINNEDMESHATTACHMENT_H_ +#ifndef SPINE_WEIGHTEDMESHATTACHMENT_H_ +#define SPINE_WEIGHTEDMESHATTACHMENT_H_ #include #include @@ -39,7 +39,7 @@ extern "C" { #endif -typedef struct spSkinnedMeshAttachment { +typedef struct spWeightedMeshAttachment { spAttachment super; const char* path; @@ -70,21 +70,21 @@ typedef struct spSkinnedMeshAttachment { int edgesCount; int* edges; float width, height; -} spSkinnedMeshAttachment; +} spWeightedMeshAttachment; -spSkinnedMeshAttachment* spSkinnedMeshAttachment_create (const char* name); -void spSkinnedMeshAttachment_updateUVs (spSkinnedMeshAttachment* self); -void spSkinnedMeshAttachment_computeWorldVertices (spSkinnedMeshAttachment* self, spSlot* slot, float* worldVertices); +spWeightedMeshAttachment* spWeightedMeshAttachment_create (const char* name); +void spWeightedMeshAttachment_updateUVs (spWeightedMeshAttachment* self); +void spWeightedMeshAttachment_computeWorldVertices (spWeightedMeshAttachment* self, spSlot* slot, float* worldVertices); #ifdef SPINE_SHORT_NAMES -typedef spSkinnedMeshAttachment SkinnedMeshAttachment; -#define SkinnedMeshAttachment_create(...) spSkinnedMeshAttachment_create(__VA_ARGS__) -#define SkinnedMeshAttachment_updateUVs(...) spSkinnedMeshAttachment_updateUVs(__VA_ARGS__) -#define SkinnedMeshAttachment_computeWorldVertices(...) spSkinnedMeshAttachment_computeWorldVertices(__VA_ARGS__) +typedef spWeightedMeshAttachment WeightedMeshAttachment; +#define WeightedMeshAttachment_create(...) spWeightedMeshAttachment_create(__VA_ARGS__) +#define WeightedMeshAttachment_updateUVs(...) spWeightedMeshAttachment_updateUVs(__VA_ARGS__) +#define WeightedMeshAttachment_computeWorldVertices(...) spWeightedMeshAttachment_computeWorldVertices(__VA_ARGS__) #endif #ifdef __cplusplus } #endif -#endif /* SPINE_SKINNEDMESHATTACHMENT_H_ */ +#endif /* SPINE_WEIGHTEDMESHATTACHMENT_H_ */ diff --git a/spine-c/include/spine/extension.h b/spine-c/include/spine/extension.h index e42394c4c..c141fb119 100644 --- a/spine-c/include/spine/extension.h +++ b/spine-c/include/spine/extension.h @@ -68,6 +68,7 @@ #define COS(A) cosf(A) #define SQRT(A) sqrtf(A) #define ACOS(A) acosf(A) +#define ABS(A) fabsf(A) #else #define FMOD(A,B) (float)fmod(A, B) #define ATAN2(A,B) (float)atan2(A, B) @@ -75,6 +76,7 @@ #define SIN(A) (float)sin(A) #define SQRT(A) (float)sqrt(A) #define ACOS(A) (float)acos(A) +#define ABS(A) ((A) < 0 ? -(A) : (A)) #endif #include @@ -86,7 +88,7 @@ #include #include #include -#include +#include #include #include diff --git a/spine-c/include/spine/spine.h b/spine-c/include/spine/spine.h index bbd6acfec..0a1063a0a 100644 --- a/spine-c/include/spine/spine.h +++ b/spine-c/include/spine/spine.h @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/spine-c/src/spine/Animation.c b/spine-c/src/spine/Animation.c index e233a4243..b12ff6542 100644 --- a/spine-c/src/spine/Animation.c +++ b/spine-c/src/spine/Animation.c @@ -789,48 +789,3 @@ void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameInd } /**/ - -void _spFlipTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, - spEvent** firedEvents, int* eventsCount, float alpha) { - int frameIndex; - spFlipTimeline* self = (spFlipTimeline*)timeline; - - if (time < self->frames[0]) { - if (lastTime > time) _spFlipTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, 0, 0, 0); - return; - } else if (lastTime > time) /**/ - lastTime = -1; - - frameIndex = (time >= self->frames[self->framesCount - 2] ? - self->framesCount : binarySearch(self->frames, self->framesCount, time, 2)) - 2; - if (self->frames[frameIndex] < lastTime) return; - - if (self->x) - skeleton->bones[self->boneIndex]->flipX = (int)self->frames[frameIndex + 1]; - else - skeleton->bones[self->boneIndex]->flipY = (int)self->frames[frameIndex + 1]; -} - -void _spFlipTimeline_dispose (spTimeline* timeline) { - spFlipTimeline* self = SUB_CAST(spFlipTimeline, timeline); - _spTimeline_deinit(SUPER(self)); - FREE(self->frames); - FREE(self); -} - -spFlipTimeline* spFlipTimeline_create (int framesCount, int/*bool*/x) { - spFlipTimeline* self = NEW(spFlipTimeline); - _spTimeline_init(SUPER(self), x ? SP_TIMELINE_FLIPX : SP_TIMELINE_FLIPY, _spFlipTimeline_dispose, _spFlipTimeline_apply); - CONST_CAST(int, self->x) = x; - CONST_CAST(int, self->framesCount) = framesCount << 1; - CONST_CAST(float*, self->frames) = CALLOC(float, self->framesCount); - return self; -} - -void spFlipTimeline_setFrame (spFlipTimeline* self, int frameIndex, float time, int/*bool*/flip) { - frameIndex <<= 1; - self->frames[frameIndex] = time; - self->frames[frameIndex + 1] = (float)flip; -} - -/**/ diff --git a/spine-c/src/spine/AtlasAttachmentLoader.c b/spine-c/src/spine/AtlasAttachmentLoader.c index 9247a8ce7..0c88ed08a 100644 --- a/spine-c/src/spine/AtlasAttachmentLoader.c +++ b/spine-c/src/spine/AtlasAttachmentLoader.c @@ -76,14 +76,14 @@ spAttachment* _spAtlasAttachmentLoader_newAttachment (spAttachmentLoader* loader attachment->regionOriginalHeight = region->originalHeight; return SUPER(attachment); } - case SP_ATTACHMENT_SKINNED_MESH: { - spSkinnedMeshAttachment* attachment; + case SP_ATTACHMENT_WEIGHTED_MESH: { + spWeightedMeshAttachment* attachment; spAtlasRegion* region = spAtlas_findRegion(self->atlas, path); if (!region) { _spAttachmentLoader_setError(loader, "Region not found: ", path); return 0; } - attachment = spSkinnedMeshAttachment_create(name); + attachment = spWeightedMeshAttachment_create(name); attachment->rendererObject = region; attachment->regionU = region->u; attachment->regionV = region->v; diff --git a/spine-c/src/spine/Bone.c b/spine-c/src/spine/Bone.c index d75dafc86..40885bd00 100644 --- a/spine-c/src/spine/Bone.c +++ b/spine-c/src/spine/Bone.c @@ -56,47 +56,137 @@ void spBone_dispose (spBone* self) { } void spBone_updateWorldTransform (spBone* self) { - float radians, cosine, sine; - if (self->parent) { - CONST_CAST(float, self->worldX) = self->x * self->parent->m00 + self->y * self->parent->m01 + self->parent->worldX; - CONST_CAST(float, self->worldY) = self->x * self->parent->m10 + self->y * self->parent->m11 + self->parent->worldY; - if (self->data->inheritScale) { - CONST_CAST(float, self->worldScaleX) = self->parent->worldScaleX * self->scaleX; - CONST_CAST(float, self->worldScaleY) = self->parent->worldScaleY * self->scaleY; - } else { - CONST_CAST(float, self->worldScaleX) = self->scaleX; - CONST_CAST(float, self->worldScaleY) = self->scaleY; + spBone_updateWorldTransformWith(self, self->x, self->y, self->rotation, self->scaleX, self->scaleY); +} + +void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rotation, float scaleX, float scaleY) { + float radians = rotation * DEG_RAD; + float cosine = COS(radians); + float sine = SIN(radians); + float la = cosine * scaleX, lb = -sine * scaleY, lc = sine * scaleX, ld = cosine * scaleY; + float pa, pb, pc, pd; + spBone* parent = self->parent; + + CONST_CAST(float, self->appliedRotation) = rotation; + CONST_CAST(float, self->appliedScaleX) = scaleX; + CONST_CAST(float, self->appliedScaleY) = scaleY; + + if (!parent) { /* Root bone. */ + if (self->skeleton->flipX) { + x = -x; + la = -la; + lb = -lb; } - CONST_CAST(float, self->worldRotation) = - self->data->inheritRotation ? self->parent->worldRotation + self->rotationIK : self->rotationIK; - CONST_CAST(int, self->worldFlipX) = self->parent->worldFlipX ^ self->flipX; - CONST_CAST(int, self->worldFlipY) = self->parent->worldFlipY ^ self->flipY; - } else { - int skeletonFlipX = self->skeleton->flipX, skeletonFlipY = self->skeleton->flipY; - CONST_CAST(float, self->worldX) = self->skeleton->flipX ? -self->x : self->x; - CONST_CAST(float, self->worldY) = self->skeleton->flipY != yDown ? -self->y : self->y; - CONST_CAST(float, self->worldScaleX) = self->scaleX; - CONST_CAST(float, self->worldScaleY) = self->scaleY; - CONST_CAST(float, self->worldRotation) = self->rotationIK; - CONST_CAST(int, self->worldFlipX) = skeletonFlipX ^ self->flipX; - CONST_CAST(int, self->worldFlipY) = skeletonFlipY ^ self->flipY; + if (self->skeleton->flipY != yDown) { + y = -y; + lc = -lc; + ld = -ld; + } + CONST_CAST(float, self->a) = la; + CONST_CAST(float, self->b) = lb; + CONST_CAST(float, self->c) = lc; + CONST_CAST(float, self->d) = ld; + CONST_CAST(float, self->worldX) = x; + CONST_CAST(float, self->worldY) = y; + CONST_CAST(float, self->worldSignX) = scaleX > 0 ? 1 : -1; + CONST_CAST(float, self->worldSignY) = scaleY > 0 ? 1 : -1; + return; } - radians = self->worldRotation * DEG_RAD; - cosine = COS(radians); - sine = SIN(radians); - if (self->worldFlipX) { - CONST_CAST(float, self->m00) = -cosine * self->worldScaleX; - CONST_CAST(float, self->m01) = sine * self->worldScaleY; + + pa = parent->a; + pb = parent->b; + pc = parent->c; + pd = parent->d; + + CONST_CAST(float, self->worldX) = pa * x + pb * y + parent->worldX; + CONST_CAST(float, self->worldY) = pc * x + pd * y + parent->worldY; + CONST_CAST(float, self->worldSignX) = parent->worldSignX * (scaleX > 0 ? 1 : -1); + CONST_CAST(float, self->worldSignY) = parent->worldSignY * (scaleY > 0 ? 1 : -1); + + if (self->data->inheritRotation && self->data->inheritScale) { + CONST_CAST(float, self->a) = pa * la + pb * lc; + CONST_CAST(float, self->b) = pa * lb + pb * ld; + CONST_CAST(float, self->c) = pc * la + pd * lc; + CONST_CAST(float, self->d) = pc * lb + pd * ld; + } else if (self->data->inheritRotation) { /* No scale inheritance. */ + spBone* p = parent; + pa = 1; + pb = 0; + pc = 0; + pd = 1; + while (p) { + cosine = COS(p->appliedRotation * DEG_RAD); + sine = SIN(p->appliedRotation * DEG_RAD); + float a = pa * cosine + pb * sine; + float b = pa * -sine + pb * cosine; + float c = pc * cosine + pd * sine; + float d = pc * -sine + pd * cosine; + pa = a; + pb = b; + pc = c; + pd = d; + p = p->parent; + } + CONST_CAST(float, self->a) = pa * la + pb * lc; + CONST_CAST(float, self->b) = pa * lb + pb * ld; + CONST_CAST(float, self->c) = pc * la + pd * lc; + CONST_CAST(float, self->d) = pc * lb + pd * ld; + if (self->skeleton->flipX) { + CONST_CAST(float, self->a) = -self->a; + CONST_CAST(float, self->b) = -self->b; + } + if (self->skeleton->flipY != yDown) { + CONST_CAST(float, self->c) = -self->c; + CONST_CAST(float, self->d) = -self->d; + } + } else if (self->data->inheritScale) { /* No rotation inheritance. */ + spBone* p = parent; + pa = 1; + pb = 0; + pc = 0; + pd = 1; + while (p) { + float r = p->rotation; + cosine = COS(r * DEG_RAD); + sine = SIN(r * DEG_RAD); + float psx = p->appliedScaleX, psy = p->appliedScaleY; + float za = cosine * psx, zb = -sine * psy, zc = sine * psx, zd = cosine * psy; + float temp = pa * za + pb * zc; + pb = pa * zb + pb * zd; + pa = temp; + temp = pc * za + pd * zc; + pd = pc * zb + pd * zd; + pc = temp; + + if (psx < 0) r = -r; + cosine = COS(-r * DEG_RAD); + sine = SIN(-r * DEG_RAD); + temp = pa * cosine + pb * sine; + pb = pa * -sine + pb * cosine; + pa = temp; + temp = pc * cosine + pd * sine; + pd = pc * -sine + pd * cosine; + pc = temp; + + p = p->parent; + } + CONST_CAST(float, self->a) = pa * la + pb * lc; + CONST_CAST(float, self->b) = pa * lb + pb * ld; + CONST_CAST(float, self->c) = pc * la + pd * lc; + CONST_CAST(float, self->d) = pc * lb + pd * ld; + if (self->skeleton->flipX) { + CONST_CAST(float, self->a) = -self->a; + CONST_CAST(float, self->b) = -self->b; + } + if (self->skeleton->flipY != yDown) { + CONST_CAST(float, self->c) = -self->c; + CONST_CAST(float, self->d) = -self->d; + } } else { - CONST_CAST(float, self->m00) = cosine * self->worldScaleX; - CONST_CAST(float, self->m01) = -sine * self->worldScaleY; - } - if (self->worldFlipY != yDown) { - CONST_CAST(float, self->m10) = -sine * self->worldScaleX; - CONST_CAST(float, self->m11) = -cosine * self->worldScaleY; - } else { - CONST_CAST(float, self->m10) = sine * self->worldScaleX; - CONST_CAST(float, self->m11) = cosine * self->worldScaleY; + CONST_CAST(float, self->a) = la; + CONST_CAST(float, self->b) = lb; + CONST_CAST(float, self->c) = lc; + CONST_CAST(float, self->d) = ld; } } @@ -104,27 +194,36 @@ void spBone_setToSetupPose (spBone* self) { self->x = self->data->x; self->y = self->data->y; self->rotation = self->data->rotation; - self->rotationIK = self->rotation; self->scaleX = self->data->scaleX; self->scaleY = self->data->scaleY; - self->flipX = self->data->flipX; - self->flipY = self->data->flipY; +} + +float spBone_getWorldRotationX (spBone* self) { + return ATAN2(self->c, self->a) * RAD_DEG; +} + +float spBone_getWorldRotationY (spBone* self) { + return ATAN2(self->d, self->b) * RAD_DEG; +} + +float spBone_getWorldScaleX (spBone* self) { + return SQRT(self->a * self->a + self->b * self->b) * self->worldSignX; +} + +float spBone_getWorldScaleY (spBone* self) { + return SQRT(self->c * self->c + self->d * self->d) * self->worldSignY; } void spBone_worldToLocal (spBone* self, float worldX, float worldY, float* localX, float* localY) { - float invDet; - float dx = worldX - self->worldX, dy = worldY - self->worldY; - float m00 = self->m00, m11 = self->m11; - if (self->worldFlipX != (self->worldFlipY != yDown)) { - m00 *= -1; - m11 *= -1; - } - invDet = 1 / (m00 * m11 - self->m01 * self->m10); - *localX = (dx * m00 * invDet - dy * self->m01 * invDet); - *localY = (dy * m11 * invDet - dx * self->m10 * invDet); + float x = worldX - self->worldX, y = worldY - self->worldY; + float a = self->a, b = self->b, c = self->c, d = self->d; + float invDet = 1 / (a * d - b * c); + *localX = (x * a * invDet - y * b * invDet); + *localY = (y * d * invDet - x * c * invDet); } void spBone_localToWorld (spBone* self, float localX, float localY, float* worldX, float* worldY) { - *worldX = localX * self->m00 + localY * self->m01 + self->worldX; - *worldY = localX * self->m10 + localY * self->m11 + self->worldY; + float x = localX, y = localY; + *worldX = x * self->a + y * self->b + self->worldX; + *worldY = x * self->c + y * self->d + self->worldY; } diff --git a/spine-c/src/spine/BoundingBoxAttachment.c b/spine-c/src/spine/BoundingBoxAttachment.c index 0d8049723..501b8ec1a 100644 --- a/spine-c/src/spine/BoundingBoxAttachment.c +++ b/spine-c/src/spine/BoundingBoxAttachment.c @@ -55,7 +55,7 @@ void spBoundingBoxAttachment_computeWorldVertices (spBoundingBoxAttachment* self for (i = 0; i < self->verticesCount; i += 2) { px = vertices[i]; py = vertices[i + 1]; - worldVertices[i] = px * bone->m00 + py * bone->m01 + x; - worldVertices[i + 1] = px * bone->m10 + py * bone->m11 + y; + worldVertices[i] = px * bone->a + py * bone->b + x; + worldVertices[i + 1] = px * bone->c + py * bone->d + y; } } diff --git a/spine-c/src/spine/Event.c b/spine-c/src/spine/Event.c index 7bbc781cd..061fbfd7a 100644 --- a/spine-c/src/spine/Event.c +++ b/spine-c/src/spine/Event.c @@ -32,9 +32,10 @@ #include #include -spEvent* spEvent_create (spEventData* data) { +spEvent* spEvent_create (float time, spEventData* data) { spEvent* self = NEW(spEvent); CONST_CAST(spEventData*, self->data) = data; + CONST_CAST(float, self->time) = time; return self; } diff --git a/spine-c/src/spine/IkConstraint.c b/spine-c/src/spine/IkConstraint.c index 61a0907c4..d94bbfb94 100644 --- a/spine-c/src/spine/IkConstraint.c +++ b/spine-c/src/spine/IkConstraint.c @@ -68,69 +68,130 @@ void spIkConstraint_apply (spIkConstraint* self) { } void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, float alpha) { - float parentRotation = (!bone->data->inheritRotation || !bone->parent) ? 0 : bone->parent->worldRotation; + float parentRotation = !bone->parent ? 0 : spBone_getWorldRotationX(bone->parent); float rotation = bone->rotation; - float rotationIK = ATAN2(targetY - bone->worldY, targetX - bone->worldX) * RAD_DEG; - if (bone->worldFlipX != (bone->worldFlipY != spBone_isYDown())) rotationIK = -rotationIK; - rotationIK -= parentRotation; - bone->rotationIK = rotation + (rotationIK - rotation) * alpha; + float rotationIK = ATAN2(targetY - bone->worldY, targetX - bone->worldX) * RAD_DEG - parentRotation; + if (bone->worldSignX != bone->worldSignY) rotationIK = 360 - rotationIK; + if (rotationIK > 180) rotationIK -= 360; + else if (rotationIK < -180) rotationIK += 360; + spBone_updateWorldTransformWith(bone, bone->x, bone->y, rotation + (rotationIK - rotation) * alpha, bone->scaleX, bone->scaleY); } -void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDirection, float alpha) { - float positionX, positionY, childX, childY, offset, len1, len2, cosDenom, cos, childAngle, adjacent, opposite, parentAngle, rotation; - spBone* parentParent; - float childRotation = child->rotation, parentRotation = parent->rotation; - if (alpha == 0) { - child->rotationIK = childRotation; - parent->rotationIK = parentRotation; - return; - } - parentParent = parent->parent; - if (parentParent) { - spBone_worldToLocal(parentParent, targetX, targetY, &positionX, &positionY); - targetX = (positionX - parent->x) * parentParent->worldScaleX; - targetY = (positionY - parent->y) * parentParent->worldScaleY; +void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float targetY, int bendDir, float alpha) { + if (alpha == 0) return; + float px = parent->x, py = parent->y, psx = parent->scaleX, psy = parent->scaleY, csx = child->scaleX, cy = child->y; + int offset1, offset2, sign2; + if (psx < 0) { + psx = -psx; + offset1 = 180; + sign2 = -1; } else { - targetX -= parent->x; - targetY -= parent->y; + offset1 = 0; + sign2 = 1; } - if (child->parent == parent) { - positionX = child->x; - positionY = child->y; + if (psy < 0) { + psy = -psy; + sign2 = -sign2; + } + if (csx < 0) { + csx = -csx; + offset2 = 180; + } else + offset2 = 0; + spBone* pp = parent->parent; + float tx, ty, dx, dy; + if (!pp) { + tx = targetX - px; + ty = targetY - py; + dx = child->worldX - px; + dy = child->worldY - py; } else { - spBone_localToWorld(child->parent, child->x, child->y, &positionX, &positionY); - spBone_worldToLocal(parent, positionX, positionY, &positionX, &positionY); + float a = pp->a, b = pp->b, c = pp->c, d = pp->d, invDet = 1 / (a * d - b * c); + float wx = pp->worldX, wy = pp->worldY, x = targetX - wx, y = targetY - wy; + tx = (x * d - y * b) * invDet - px; + ty = (y * a - x * c) * invDet - py; + x = child->worldX - wx; + y = child->worldY - wy; + dx = (x * d - y * b) * invDet - px; + dy = (y * a - x * c) * invDet - py; } - childX = positionX * parent->worldScaleX; - childY = positionY * parent->worldScaleY; - offset = ATAN2(childY, childX); - len1 = SQRT(childX * childX + childY * childY); - len2 = child->data->length * child->worldScaleX; - /* Based on code by Ryan Juckett with permission: Copyright (c) 2008-2009 Ryan Juckett, http://www.ryanjuckett.com/ */ - cosDenom = 2 * len1 * len2; - if (cosDenom < 0.0001f) { - child->rotationIK = childRotation + (ATAN2(targetY, targetX) * RAD_DEG - parentRotation - childRotation) * alpha; - return; + float l1 = SQRT(dx * dx + dy * dy), l2 = child->data->length * csx, a1, a2; + if (ABS(psx - psy) <= 0.0001f) { + l2 *= psx; + float cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2); + if (cos < -1) cos = -1; + else if (cos > 1) cos = 1; + a2 = ACOS(cos) * bendDir; + float a = l1 + l2 * cos, o = l2 * SIN(a2); + a1 = ATAN2(ty * a - tx * o, tx * a + ty * o); + } else { + cy = 0; + float a = psx * l2, b = psy * l2, ta = ATAN2(ty, tx); + float aa = a * a, bb = b * b, ll = l1 * l1, dd = tx * tx + ty * ty; + float c0 = bb * ll + aa * dd - aa * bb, c1 = -2 * bb * l1, c2 = bb - aa; + float d = c1 * c1 - 4 * c2 * c0; + if (d >= 0) { + float q = SQRT(d); + if (c1 < 0) q = -q; + q = -(c1 + q) / 2; + float r0 = q / c2, r1 = c0 / q; + float r = ABS(r0) < ABS(r1) ? r0 : r1; + if (r * r <= dd) { + float y1 = SQRT(dd - r * r) * bendDir; + a1 = ta - ATAN2(y1, r); + a2 = ATAN2(y1 / psy, (r - l1) / psx); + goto outer; + } + } + float minAngle = 0, minDist = 999999999, minX = 0, minY = 0; + float maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0; + float x = l1 + a, dist = x * x; + if (dist > maxDist) { + maxAngle = 0; + maxDist = dist; + maxX = x; + } + x = l1 - a; + dist = x * x; + if (dist < minDist) { + minAngle = PI; + minDist = dist; + minX = x; + } + float angle = ACOS(-a * l1 / (aa - bb)); + x = a * COS(angle) + l1; + float y = b * SIN(angle); + dist = x * x + y * y; + if (dist < minDist) { + minAngle = angle; + minDist = dist; + minX = x; + minY = y; + } + if (dist > maxDist) { + maxAngle = angle; + maxDist = dist; + maxX = x; + maxY = y; + } + if (dd <= (minDist + maxDist) / 2) { + a1 = ta - ATAN2(minY * bendDir, minX); + a2 = minAngle * bendDir; + } else { + a1 = ta - ATAN2(maxY * bendDir, maxX); + a2 = maxAngle * bendDir; + } } - cos = (targetX * targetX + targetY * targetY - len1 * len1 - len2 * len2) / cosDenom; - if (cos < -1) - cos = -1; - else if (cos > 1) /**/ - cos = 1; - childAngle = ACOS(cos) * bendDirection; - adjacent = len1 + len2 * cos; - opposite = len2 * SIN(childAngle); - parentAngle = ATAN2(targetY * adjacent - targetX * opposite, targetX * adjacent + targetY * opposite); - rotation = (parentAngle - offset) * RAD_DEG - parentRotation; - if (rotation > 180) - rotation -= 360; - else if (rotation < -180) /**/ - rotation += 360; - parent->rotationIK = parentRotation + rotation * alpha; - rotation = (childAngle + offset) * RAD_DEG - childRotation; - if (rotation > 180) - rotation -= 360; - else if (rotation < -180) /**/ - rotation += 360; - child->rotationIK = childRotation + (rotation + parent->worldRotation - child->parent->worldRotation) * alpha; +outer: {} + float offset = ATAN2(cy, child->x) * sign2; + a1 = (a1 - offset) * RAD_DEG + offset1; + a2 = (a2 + offset) * RAD_DEG * sign2 + offset2; + if (a1 > 180) a1 -= 360; + else if (a1 < -180) a1 += 360; + if (a2 > 180) a2 -= 360; + else if (a2 < -180) a2 += 360; + float rotation = parent->rotation; + spBone_updateWorldTransformWith(parent, parent->x, parent->y, rotation + (a1 - rotation) * alpha, parent->scaleX, parent->scaleY); + rotation = child->rotation; + spBone_updateWorldTransformWith(child, child->x, cy, rotation + (a2 - rotation) * alpha, child->scaleX, child->scaleY); } diff --git a/spine-c/src/spine/MeshAttachment.c b/spine-c/src/spine/MeshAttachment.c index 71d7ad36d..88a76dcb8 100644 --- a/spine-c/src/spine/MeshAttachment.c +++ b/spine-c/src/spine/MeshAttachment.c @@ -80,7 +80,7 @@ void spMeshAttachment_computeWorldVertices (spMeshAttachment* self, spSlot* slot if (slot->attachmentVerticesCount == self->verticesCount) vertices = slot->attachmentVertices; for (i = 0; i < self->verticesCount; i += 2) { const float vx = vertices[i], vy = vertices[i + 1]; - worldVertices[i] = vx * bone->m00 + vy * bone->m01 + x; - worldVertices[i + 1] = vx * bone->m10 + vy * bone->m11 + y; + worldVertices[i] = vx * bone->a + vy * bone->b + x; + worldVertices[i + 1] = vx * bone->c + vy * bone->d + y; } } diff --git a/spine-c/src/spine/RegionAttachment.c b/spine-c/src/spine/RegionAttachment.c index 925cc4eb9..e872d252f 100644 --- a/spine-c/src/spine/RegionAttachment.c +++ b/spine-c/src/spine/RegionAttachment.c @@ -103,12 +103,12 @@ void spRegionAttachment_updateOffset (spRegionAttachment* self) { void spRegionAttachment_computeWorldVertices (spRegionAttachment* self, spBone* bone, float* vertices) { const float* offset = self->offset; float x = bone->skeleton->x + bone->worldX, y = bone->skeleton->y + bone->worldY; - vertices[SP_VERTEX_X1] = offset[SP_VERTEX_X1] * bone->m00 + offset[SP_VERTEX_Y1] * bone->m01 + x; - vertices[SP_VERTEX_Y1] = offset[SP_VERTEX_X1] * bone->m10 + offset[SP_VERTEX_Y1] * bone->m11 + y; - vertices[SP_VERTEX_X2] = offset[SP_VERTEX_X2] * bone->m00 + offset[SP_VERTEX_Y2] * bone->m01 + x; - vertices[SP_VERTEX_Y2] = offset[SP_VERTEX_X2] * bone->m10 + offset[SP_VERTEX_Y2] * bone->m11 + y; - vertices[SP_VERTEX_X3] = offset[SP_VERTEX_X3] * bone->m00 + offset[SP_VERTEX_Y3] * bone->m01 + x; - vertices[SP_VERTEX_Y3] = offset[SP_VERTEX_X3] * bone->m10 + offset[SP_VERTEX_Y3] * bone->m11 + y; - vertices[SP_VERTEX_X4] = offset[SP_VERTEX_X4] * bone->m00 + offset[SP_VERTEX_Y4] * bone->m01 + x; - vertices[SP_VERTEX_Y4] = offset[SP_VERTEX_X4] * bone->m10 + offset[SP_VERTEX_Y4] * bone->m11 + y; + vertices[SP_VERTEX_X1] = offset[SP_VERTEX_X1] * bone->a + offset[SP_VERTEX_Y1] * bone->b + x; + vertices[SP_VERTEX_Y1] = offset[SP_VERTEX_X1] * bone->c + offset[SP_VERTEX_Y1] * bone->d + y; + vertices[SP_VERTEX_X2] = offset[SP_VERTEX_X2] * bone->a + offset[SP_VERTEX_Y2] * bone->b + x; + vertices[SP_VERTEX_Y2] = offset[SP_VERTEX_X2] * bone->c + offset[SP_VERTEX_Y2] * bone->d + y; + vertices[SP_VERTEX_X3] = offset[SP_VERTEX_X3] * bone->a + offset[SP_VERTEX_Y3] * bone->b + x; + vertices[SP_VERTEX_Y3] = offset[SP_VERTEX_X3] * bone->c + offset[SP_VERTEX_Y3] * bone->d + y; + vertices[SP_VERTEX_X4] = offset[SP_VERTEX_X4] * bone->a + offset[SP_VERTEX_Y4] * bone->b + x; + vertices[SP_VERTEX_Y4] = offset[SP_VERTEX_X4] * bone->c + offset[SP_VERTEX_Y4] * bone->d + y; } diff --git a/spine-c/src/spine/Skeleton.c b/spine-c/src/spine/Skeleton.c index dc1b8ff11..735a2b98c 100644 --- a/spine-c/src/spine/Skeleton.c +++ b/spine-c/src/spine/Skeleton.c @@ -33,12 +33,16 @@ #include #include +typedef enum { + SP_UPDATE_BONE, SP_UPDATE_IK_CONSTRAINT, SP_UPDATE_TRANSFORM_CONSTRAINT +} _spUpdateType; + typedef struct { spSkeleton super; - int boneCacheCount; - int* boneCacheCounts; - spBone*** boneCache; + int updateCacheCount; + void** updateCache; + _spUpdateType* updateCacheType; } _spSkeleton; spSkeleton* spSkeleton_create (spSkeletonData* data) { @@ -96,6 +100,11 @@ spSkeleton* spSkeleton_create (spSkeletonData* data) { for (i = 0; i < self->data->ikConstraintsCount; ++i) self->ikConstraints[i] = spIkConstraint_create(self->data->ikConstraints[i], self); + self->transformConstraintsCount = data->transformConstraintsCount; + self->transformConstraints = MALLOC(spTransformConstraint*, self->transformConstraintsCount); + for (i = 0; i < self->data->transformConstraintsCount; ++i) + self->transformConstraints[i] = spTransformConstraint_create(self->data->transformConstraints[i], self); + spSkeleton_updateCache(self); return self; @@ -103,12 +112,6 @@ spSkeleton* spSkeleton_create (spSkeletonData* data) { void spSkeleton_dispose (spSkeleton* self) { int i; - _spSkeleton* internal = SUB_CAST(_spSkeleton, self); - - for (i = 0; i < internal->boneCacheCount; ++i) - FREE(internal->boneCache[i]); - FREE(internal->boneCache); - FREE(internal->boneCacheCounts); for (i = 0; i < self->bonesCount; ++i) spBone_dispose(self->bones[i]); @@ -122,6 +125,10 @@ void spSkeleton_dispose (spSkeleton* self) { spIkConstraint_dispose(self->ikConstraints[i]); FREE(self->ikConstraints); + for (i = 0; i < self->transformConstraintsCount; ++i) + spTransformConstraint_dispose(self->transformConstraints[i]); + FREE(self->transformConstraints); + FREE(self->drawOrder); FREE(self); } @@ -130,84 +137,51 @@ void spSkeleton_updateCache (const spSkeleton* self) { int i, ii; _spSkeleton* internal = SUB_CAST(_spSkeleton, self); - for (i = 0; i < internal->boneCacheCount; ++i) - FREE(internal->boneCache[i]); - FREE(internal->boneCache); - FREE(internal->boneCacheCounts); + FREE(internal->updateCache); + FREE(internal->updateCacheType); + internal->updateCache = MALLOC(void*, self->bonesCount + self->transformConstraintsCount + self->ikConstraintsCount); + internal->updateCacheType = MALLOC(_spUpdateType, self->bonesCount + self->transformConstraintsCount + self->ikConstraintsCount); + internal->updateCacheCount = 0; - internal->boneCacheCount = self->ikConstraintsCount + 1; - internal->boneCache = MALLOC(spBone**, internal->boneCacheCount); - internal->boneCacheCounts = CALLOC(int, internal->boneCacheCount); - - /* Compute array sizes. */ - for (i = 0; i < self->bonesCount; ++i) { - spBone* current = self->bones[i]; - do { - for (ii = 0; ii < self->ikConstraintsCount; ++ii) { - spIkConstraint* ikConstraint = self->ikConstraints[ii]; - spBone* parent = ikConstraint->bones[0]; - spBone* child = ikConstraint->bones[ikConstraint->bonesCount - 1]; - while (1) { - if (current == child) { - internal->boneCacheCounts[ii]++; - internal->boneCacheCounts[ii + 1]++; - goto outer1; - } - if (child == parent) break; - child = child->parent; - } - } - current = current->parent; - } while (current); - internal->boneCacheCounts[0]++; - outer1: {} - } - - for (i = 0; i < internal->boneCacheCount; ++i) - internal->boneCache[i] = MALLOC(spBone*, internal->boneCacheCounts[i]); - memset(internal->boneCacheCounts, 0, internal->boneCacheCount * sizeof(int)); - - /* Populate arrays. */ for (i = 0; i < self->bonesCount; ++i) { spBone* bone = self->bones[i]; - spBone* current = bone; - do { - for (ii = 0; ii < self->ikConstraintsCount; ++ii) { - spIkConstraint* ikConstraint = self->ikConstraints[ii]; - spBone* parent = ikConstraint->bones[0]; - spBone* child = ikConstraint->bones[ikConstraint->bonesCount - 1]; - while (1) { - if (current == child) { - internal->boneCache[ii][internal->boneCacheCounts[ii]++] = bone; - internal->boneCache[ii + 1][internal->boneCacheCounts[ii + 1]++] = bone; - goto outer2; - } - if (child == parent) break; - child = child->parent; - } + internal->updateCache[internal->updateCacheCount] = bone; + internal->updateCacheType[internal->updateCacheCount++] = SP_UPDATE_BONE; + for (ii = 0; ii < self->transformConstraintsCount; ++ii) { + spTransformConstraint* transformConstraint = self->transformConstraints[ii]; + if (bone == transformConstraint->bone) { + internal->updateCache[internal->updateCacheCount] = transformConstraint; + internal->updateCacheType[internal->updateCacheCount++] = SP_UPDATE_TRANSFORM_CONSTRAINT; + break; } - current = current->parent; - } while (current); - internal->boneCache[0][internal->boneCacheCounts[0]++] = bone; - outer2: {} + } + for (ii = 0; ii < self->ikConstraintsCount; ++ii) { + spIkConstraint* ikConstraint = self->ikConstraints[ii]; + if (bone == ikConstraint->bones[ikConstraint->bonesCount - 1]) { + internal->updateCache[internal->updateCacheCount] = ikConstraint; + internal->updateCacheType[internal->updateCacheCount++] = SP_UPDATE_IK_CONSTRAINT; + break; + } + } } } void spSkeleton_updateWorldTransform (const spSkeleton* self) { - int i, ii, nn, last; + int i; _spSkeleton* internal = SUB_CAST(_spSkeleton, self); - for (i = 0; i < self->bonesCount; ++i) - self->bones[i]->rotationIK = self->bones[i]->rotation; - - i = 0; - last = internal->boneCacheCount - 1; - while (1) { - for (ii = 0, nn = internal->boneCacheCounts[i]; ii < nn; ++ii) - spBone_updateWorldTransform(internal->boneCache[i][ii]); - if (i == last) break; - spIkConstraint_apply(self->ikConstraints[i]); - i++; + for (i = 0; i < internal->updateCacheCount; ++i) { + switch (internal->updateCacheType[i]) { + case SP_UPDATE_BONE: + spBone_updateWorldTransform((spBone*)internal->updateCache[i]); + break; + case SP_UPDATE_IK_CONSTRAINT: + spIkConstraint_apply((spIkConstraint*)internal->updateCache[i]); + break; + case SP_UPDATE_TRANSFORM_CONSTRAINT: + spTransformConstraint_apply((spTransformConstraint*)internal->updateCache[i]); + break; + } } } @@ -226,6 +200,13 @@ void spSkeleton_setBonesToSetupPose (const spSkeleton* self) { ikConstraint->bendDirection = ikConstraint->data->bendDirection; ikConstraint->mix = ikConstraint->data->mix; } + + for (i = 0; i < self->transformConstraintsCount; ++i) { + spTransformConstraint* transformConstraint = self->transformConstraints[i]; + transformConstraint->translateMix = transformConstraint->data->translateMix; + transformConstraint->x = transformConstraint->data->x; + transformConstraint->y = transformConstraint->data->y; + } } void spSkeleton_setSlotsToSetupPose (const spSkeleton* self) { @@ -330,10 +311,17 @@ int spSkeleton_setAttachment (spSkeleton* self, const char* slotName, const char return 0; } -spIkConstraint* spSkeleton_findIkConstraint (const spSkeleton* self, const char* ikConstraintName) { +spIkConstraint* spSkeleton_findIkConstraint (const spSkeleton* self, const char* constraintName) { int i; for (i = 0; i < self->ikConstraintsCount; ++i) - if (strcmp(self->ikConstraints[i]->data->name, ikConstraintName) == 0) return self->ikConstraints[i]; + if (strcmp(self->ikConstraints[i]->data->name, constraintName) == 0) return self->ikConstraints[i]; + return 0; +} + +spTransformConstraint* spSkeleton_findTransformConstraint (const spSkeleton* self, const char* constraintName) { + int i; + for (i = 0; i < self->transformConstraintsCount; ++i) + if (strcmp(self->transformConstraints[i]->data->name, constraintName) == 0) return self->transformConstraints[i]; return 0; } diff --git a/spine-c/src/spine/SkeletonData.c b/spine-c/src/spine/SkeletonData.c index c6f773811..b042bafb9 100644 --- a/spine-c/src/spine/SkeletonData.c +++ b/spine-c/src/spine/SkeletonData.c @@ -63,6 +63,10 @@ void spSkeletonData_dispose (spSkeletonData* self) { spIkConstraintData_dispose(self->ikConstraints[i]); FREE(self->ikConstraints); + for (i = 0; i < self->transformConstraintsCount; ++i) + spTransformConstraintData_dispose(self->transformConstraints[i]); + FREE(self->transformConstraints); + FREE(self->hash); FREE(self->version); @@ -118,9 +122,16 @@ spAnimation* spSkeletonData_findAnimation (const spSkeletonData* self, const cha return 0; } -spIkConstraintData* spSkeletonData_findIkConstraint (const spSkeletonData* self, const char* ikConstraintName) { +spIkConstraintData* spSkeletonData_findIkConstraint (const spSkeletonData* self, const char* constraintName) { int i; for (i = 0; i < self->ikConstraintsCount; ++i) - if (strcmp(self->ikConstraints[i]->name, ikConstraintName) == 0) return self->ikConstraints[i]; + if (strcmp(self->ikConstraints[i]->name, constraintName) == 0) return self->ikConstraints[i]; + return 0; +} + +spTransformConstraintData* spSkeletonData_findTransformConstraint (const spSkeletonData* self, const char* constraintName) { + int i; + for (i = 0; i < self->transformConstraintsCount; ++i) + if (strcmp(self->transformConstraints[i]->name, constraintName) == 0) return self->transformConstraints[i]; return 0; } diff --git a/spine-c/src/spine/SkeletonJson.c b/spine-c/src/spine/SkeletonJson.c index f6af78a08..12ba17a99 100644 --- a/spine-c/src/spine/SkeletonJson.c +++ b/spine-c/src/spine/SkeletonJson.c @@ -116,8 +116,6 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r Json* ffd = Json_getItem(root, "ffd"); Json* drawOrder = Json_getItem(root, "drawOrder"); Json* events = Json_getItem(root, "events"); - Json* flipX = Json_getItem(root, "flipx"); - Json* flipY = Json_getItem(root, "flipy"); Json *boneMap, *slotMap, *ikMap, *ffdMap; if (!drawOrder) drawOrder = Json_getItem(root, "draworder"); @@ -131,8 +129,6 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r timelinesCount += slotMap->size; if (drawOrder) ++timelinesCount; if (events) ++timelinesCount; - if (flipX) ++timelinesCount; - if (flipY) ++timelinesCount; animation = spAnimation_create(root->name, timelinesCount); animation->timelinesCount = 0; @@ -221,16 +217,6 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline); duration = timeline->frames[timelineArray->size * 3 - 3]; if (duration > animation->duration) animation->duration = duration; - } else if (strcmp(timelineArray->name, "flipX") == 0 || strcmp(timelineArray->name, "flipY") == 0) { - int x = strcmp(timelineArray->name, "flipX") == 0; - const char* field = x ? "x" : "y"; - spFlipTimeline *timeline = spFlipTimeline_create(timelineArray->size, x); - timeline->boneIndex = boneIndex; - for (frame = timelineArray->child, i = 0; frame; frame = frame->next, ++i) - spFlipTimeline_setFrame(timeline, i, Json_getFloat(frame, "time", 0), Json_getInt(frame, field, 0)); - animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline); - duration = timeline->frames[timelineArray->size * 2 - 2]; - if (duration > animation->duration) animation->duration = duration; } else { spAnimation_dispose(animation); @@ -281,8 +267,8 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r } if (attachment->type == SP_ATTACHMENT_MESH) verticesCount = SUB_CAST(spMeshAttachment, attachment)->verticesCount; - else if (attachment->type == SP_ATTACHMENT_SKINNED_MESH) - verticesCount = SUB_CAST(spSkinnedMeshAttachment, attachment)->weightsCount / 3 * 2; + else if (attachment->type == SP_ATTACHMENT_WEIGHTED_MESH) + verticesCount = SUB_CAST(spWeightedMeshAttachment, attachment)->weightsCount / 3 * 2; timeline = spFFDTimeline_create(timelineArray->size, verticesCount); timeline->slotIndex = slotIndex; @@ -384,18 +370,19 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r for (frame = events->child, i = 0; frame; frame = frame->next, ++i) { spEvent* event; const char* stringValue; + float time = Json_getFloat(frame, "time", 0); spEventData* eventData = spSkeletonData_findEvent(skeletonData, Json_getString(frame, "name", 0)); if (!eventData) { spAnimation_dispose(animation); _spSkeletonJson_setError(self, 0, "Event not found: ", Json_getString(frame, "name", 0)); return 0; } - event = spEvent_create(eventData); + event = spEvent_create(time, eventData); event->intValue = Json_getInt(frame, "int", eventData->intValue); event->floatValue = Json_getFloat(frame, "float", eventData->floatValue); stringValue = Json_getString(frame, "string", eventData->stringValue); if (stringValue) MALLOC_STR(event->stringValue, stringValue); - spEventTimeline_setFrame(timeline, i, Json_getFloat(frame, "time", 0), event); + spEventTimeline_setFrame(timeline, i, time, event); } animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline); duration = timeline->frames[events->size - 1]; @@ -421,7 +408,7 @@ spSkeletonData* spSkeletonJson_readSkeletonDataFile (spSkeletonJson* self, const spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const char* json) { int i, ii; spSkeletonData* skeletonData; - Json *root, *skeleton, *bones, *boneMap, *ik, *slots, *skins, *animations, *events; + Json *root, *skeleton, *bones, *boneMap, *ik, *transform, *slots, *skins, *animations, *events; char* oldLocale; FREE(self->error); @@ -471,8 +458,6 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha boneData->scaleY = Json_getFloat(boneMap, "scaleY", 1); boneData->inheritScale = Json_getInt(boneMap, "inheritScale", 1); boneData->inheritRotation = Json_getInt(boneMap, "inheritRotation", 1); - boneData->flipX = Json_getInt(boneMap, "flipX", 0); - boneData->flipY = Json_getInt(boneMap, "flipY", 0); skeletonData->bones[i] = boneData; skeletonData->bonesCount++; @@ -515,6 +500,41 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha } } + /* Transform constraints. */ + transform = Json_getItem(root, "transform"); + if (transform) { + Json *transformMap; + skeletonData->transformConstraintsCount = transform->size; + skeletonData->transformConstraints = MALLOC(spTransformConstraintData*, transform->size); + for (transformMap = transform->child, i = 0; transformMap; transformMap = transformMap->next, ++i) { + const char* name; + + spTransformConstraintData* transformConstraintData = spTransformConstraintData_create(Json_getString(transformMap, "name", 0)); + + name = Json_getString(transformMap, "bone", 0); + transformConstraintData->bone = spSkeletonData_findBone(skeletonData, name); + if (!transformConstraintData->bone) { + spSkeletonData_dispose(skeletonData); + _spSkeletonJson_setError(self, root, "Bone not found: ", boneMap->name); + return 0; + } + + name = Json_getString(transformMap, "target", 0); + transformConstraintData->target = spSkeletonData_findBone(skeletonData, name); + if (!transformConstraintData->target) { + spSkeletonData_dispose(skeletonData); + _spSkeletonJson_setError(self, root, "Target bone not found: ", boneMap->name); + return 0; + } + + transformConstraintData->translateMix = Json_getFloat(transformMap, "translateMix", 1); + transformConstraintData->x = Json_getFloat(transformMap, "x", 0); + transformConstraintData->y = Json_getFloat(transformMap, "y", 0); + + skeletonData->transformConstraints[i] = transformConstraintData; + } + } + /* Slots. */ slots = Json_getItem(root, "slots"); if (slots) { @@ -593,8 +613,8 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha type = SP_ATTACHMENT_REGION; else if (strcmp(typeString, "mesh") == 0) type = SP_ATTACHMENT_MESH; - else if (strcmp(typeString, "skinnedmesh") == 0) - type = SP_ATTACHMENT_SKINNED_MESH; + else if (strcmp(typeString, "weightedmesh") == 0 || strcmp(typeString, "skinnedmesh") == 0) + type = SP_ATTACHMENT_WEIGHTED_MESH; else if (strcmp(typeString, "boundingbox") == 0) type = SP_ATTACHMENT_BOUNDING_BOX; else { @@ -682,8 +702,8 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale; break; } - case SP_ATTACHMENT_SKINNED_MESH: { - spSkinnedMeshAttachment* mesh = SUB_CAST(spSkinnedMeshAttachment, attachment); + case SP_ATTACHMENT_WEIGHTED_MESH: { + spWeightedMeshAttachment* mesh = SUB_CAST(spWeightedMeshAttachment, attachment); int verticesCount, b, w, nn; float* vertices; @@ -729,7 +749,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha for (entry = entry->child, i = 0; entry; entry = entry->next, ++i) mesh->triangles[i] = entry->valueInt; - spSkinnedMeshAttachment_updateUVs(mesh); + spWeightedMeshAttachment_updateUVs(mesh); color = Json_getString(attachmentMap, "color", 0); if (color) { diff --git a/spine-c/src/spine/TransformConstraint.c b/spine-c/src/spine/TransformConstraint.c new file mode 100644 index 000000000..15da3e6b2 --- /dev/null +++ b/spine-c/src/spine/TransformConstraint.c @@ -0,0 +1,58 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.3 + * + * Copyright (c) 2013-2015, 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 (the "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 otherwise create derivative works, improvements of the + * Software or develop new applications using the Software 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; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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 + +spTransformConstraint* spTransformConstraint_create (spTransformConstraintData* data, const spSkeleton* skeleton) { + spTransformConstraint* self = NEW(spTransformConstraint); + CONST_CAST(spTransformConstraintData*, self->data) = data; + self->translateMix = data->translateMix; + self->x = data->x; + self->y = data->y; + self->bone = spSkeleton_findBone(skeleton, self->data->bone->name); + self->target = spSkeleton_findBone(skeleton, self->data->target->name); + return self; +} + +void spTransformConstraint_dispose (spTransformConstraint* self) { + FREE(self); +} + +void spTransformConstraint_apply (spTransformConstraint* self) { + if (self->translateMix > 0) { + float tx, ty; + spBone_localToWorld(self->target, self->x, self->y, &tx, &ty); + CONST_CAST(float, self->bone->worldX) = self->bone->worldX + (tx - self->bone->worldX) * self->translateMix; + CONST_CAST(float, self->bone->worldY) = self->bone->worldY + (ty - self->bone->worldY) * self->translateMix; + } +} diff --git a/spine-c/src/spine/TransformConstraintData.c b/spine-c/src/spine/TransformConstraintData.c new file mode 100644 index 000000000..8d685e7a0 --- /dev/null +++ b/spine-c/src/spine/TransformConstraintData.c @@ -0,0 +1,44 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.3 + * + * Copyright (c) 2013-2015, 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 (the "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 otherwise create derivative works, improvements of the + * Software or develop new applications using the Software 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; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) 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 + +spTransformConstraintData* spTransformConstraintData_create (const char* name) { + spTransformConstraintData* self = NEW(spTransformConstraintData); + MALLOC_STR(self->name, name); + return self; +} + +void spTransformConstraintData_dispose (spTransformConstraintData* self) { + FREE(self->name); + FREE(self); +} diff --git a/spine-c/src/spine/SkinnedMeshAttachment.c b/spine-c/src/spine/WeightedMeshAttachment.c similarity index 80% rename from spine-c/src/spine/SkinnedMeshAttachment.c rename to spine-c/src/spine/WeightedMeshAttachment.c index a40fb90df..f17ea759d 100644 --- a/spine-c/src/spine/SkinnedMeshAttachment.c +++ b/spine-c/src/spine/WeightedMeshAttachment.c @@ -29,11 +29,11 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -#include +#include #include -void _spSkinnedMeshAttachment_dispose (spAttachment* attachment) { - spSkinnedMeshAttachment* self = SUB_CAST(spSkinnedMeshAttachment, attachment); +void _spWeightedMeshAttachment_dispose (spAttachment* attachment) { + spWeightedMeshAttachment* self = SUB_CAST(spWeightedMeshAttachment, attachment); _spAttachment_deinit(attachment); FREE(self->path); FREE(self->bones); @@ -45,17 +45,17 @@ void _spSkinnedMeshAttachment_dispose (spAttachment* attachment) { FREE(self); } -spSkinnedMeshAttachment* spSkinnedMeshAttachment_create (const char* name) { - spSkinnedMeshAttachment* self = NEW(spSkinnedMeshAttachment); +spWeightedMeshAttachment* spWeightedMeshAttachment_create (const char* name) { + spWeightedMeshAttachment* self = NEW(spWeightedMeshAttachment); self->r = 1; self->g = 1; self->b = 1; self->a = 1; - _spAttachment_init(SUPER(self), name, SP_ATTACHMENT_SKINNED_MESH, _spSkinnedMeshAttachment_dispose); + _spAttachment_init(SUPER(self), name, SP_ATTACHMENT_WEIGHTED_MESH, _spWeightedMeshAttachment_dispose); return self; } -void spSkinnedMeshAttachment_updateUVs (spSkinnedMeshAttachment* self) { +void spWeightedMeshAttachment_updateUVs (spWeightedMeshAttachment* self) { int i; float width = self->regionU2 - self->regionU, height = self->regionV2 - self->regionV; FREE(self->uvs); @@ -73,7 +73,7 @@ void spSkinnedMeshAttachment_updateUVs (spSkinnedMeshAttachment* self) { } } -void spSkinnedMeshAttachment_computeWorldVertices (spSkinnedMeshAttachment* self, spSlot* slot, float* worldVertices) { +void spWeightedMeshAttachment_computeWorldVertices (spWeightedMeshAttachment* self, spSlot* slot, float* worldVertices) { int w = 0, v = 0, b = 0, f = 0; float x = slot->bone->skeleton->x, y = slot->bone->skeleton->y; spBone** skeletonBones = slot->bone->skeleton->bones; @@ -85,8 +85,8 @@ void spSkinnedMeshAttachment_computeWorldVertices (spSkinnedMeshAttachment* self for (; v <= nn; v++, b += 3) { const spBone* bone = skeletonBones[self->bones[v]]; const float vx = self->weights[b], vy = self->weights[b + 1], weight = self->weights[b + 2]; - wx += (vx * bone->m00 + vy * bone->m01 + bone->worldX) * weight; - wy += (vx * bone->m10 + vy * bone->m11 + bone->worldY) * weight; + wx += (vx * bone->a + vy * bone->b + bone->worldX) * weight; + wy += (vx * bone->c + vy * bone->d + bone->worldY) * weight; } worldVertices[w] = wx + x; worldVertices[w + 1] = wy + y; @@ -100,8 +100,8 @@ void spSkinnedMeshAttachment_computeWorldVertices (spSkinnedMeshAttachment* self for (; v <= nn; v++, b += 3, f += 2) { const spBone* bone = skeletonBones[self->bones[v]]; const float vx = self->weights[b] + ffd[f], vy = self->weights[b + 1] + ffd[f + 1], weight = self->weights[b + 2]; - wx += (vx * bone->m00 + vy * bone->m01 + bone->worldX) * weight; - wy += (vx * bone->m10 + vy * bone->m11 + bone->worldY) * weight; + wx += (vx * bone->a + vy * bone->b + bone->worldX) * weight; + wy += (vx * bone->c + vy * bone->d + bone->worldY) * weight; } worldVertices[w] = wx + x; worldVertices[w + 1] = wy + y; diff --git a/spine-sfml/.settings/org.eclipse.cdt.core.prefs b/spine-sfml/.settings/org.eclipse.cdt.core.prefs index fe5dcc353..b2d602b0b 100644 --- a/spine-sfml/.settings/org.eclipse.cdt.core.prefs +++ b/spine-sfml/.settings/org.eclipse.cdt.core.prefs @@ -155,7 +155,7 @@ org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line=false org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line=false org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line=false org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.cdt.core.formatter.lineSplit=80 +org.eclipse.cdt.core.formatter.lineSplit=130 org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve=1 org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line=true org.eclipse.cdt.core.formatter.tabulation.char=tab diff --git a/spine-sfml/src/spine/spine-sfml.cpp b/spine-sfml/src/spine/spine-sfml.cpp index 262e2aae9..37689683d 100644 --- a/spine-sfml/src/spine/spine-sfml.cpp +++ b/spine-sfml/src/spine/spine-sfml.cpp @@ -196,11 +196,11 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const { vertexArray->append(vertex); } - } else if (attachment->type == ATTACHMENT_SKINNED_MESH) { - SkinnedMeshAttachment* mesh = (SkinnedMeshAttachment*)attachment; + } else if (attachment->type == ATTACHMENT_WEIGHTED_MESH) { + WeightedMeshAttachment* mesh = (WeightedMeshAttachment*)attachment; if (mesh->uvsCount > SPINE_MESH_VERTEX_COUNT_MAX) continue; texture = (Texture*)((AtlasRegion*)mesh->rendererObject)->page->rendererObject; - SkinnedMeshAttachment_computeWorldVertices(mesh, slot, worldVertices); + WeightedMeshAttachment_computeWorldVertices(mesh, slot, worldVertices); Uint8 r = static_cast(skeleton->r * slot->r * 255); Uint8 g = static_cast(skeleton->g * slot->g * 255);