[as3][c][cpp][csharp][libgdx][lua][ts] Fixed loading transform constraint timelines from JSON data.

* Fixed SkeletonJson not allocating enough memory for curves (maximum of 6 curves/key, not 4). Fixes email: FMfcgzGkbDfvckWcFxWlsTWzFhMXsTDw
* Removed SkeletonData and Skeleton methods: findBoneIndex, findSlotIndex. Bones and slots have an index field that should be used instead.
* Removed SkeletonData and Skeleton methods: find*ConstraintIndex. Only SkeletonJson needed these, they don't need to be in the public API.
* Used a local for number of frames where it was used many times.
This commit is contained in:
Nathan Sweet 2021-09-12 18:15:19 -06:00
parent a8da830de2
commit dc9a6ebe7f
27 changed files with 346 additions and 547 deletions

View File

@ -411,18 +411,6 @@ package spine {
return null;
}
/** @return -1 if the bone was not found. */
public function findBoneIndex(boneName : String) : int {
if (boneName == null)
throw new ArgumentError("boneName cannot be null.");
var i : int = 0;
for each (var bone : Bone in bones) {
if (bone._data._name == boneName) return i;
i++;
}
return -1;
}
/** @return May be null. */
public function findSlot(slotName : String) : Slot {
if (slotName == null)
@ -432,18 +420,6 @@ package spine {
return null;
}
/** @return -1 if the bone was not found. */
public function findSlotIndex(slotName : String) : int {
if (slotName == null)
throw new ArgumentError("slotName cannot be null.");
var i : int = 0;
for each (var slot : Slot in slots) {
if (slot._data._name == slotName) return i;
i++;
}
return -1;
}
public function get skin() : Skin {
return _skin;
}
@ -486,7 +462,7 @@ package spine {
/** @return May be null. */
public function getAttachmentForSlotName(slotName : String, attachmentName : String) : Attachment {
return getAttachmentForSlotIndex(data.findSlotIndex(slotName), attachmentName);
return getAttachmentForSlotIndex(data.findSlot(slotName).index, attachmentName);
}
/** @return May be null. */

View File

@ -62,14 +62,6 @@ package spine {
return null;
}
/** @return -1 if the bone was not found. */
public function findBoneIndex(boneName : String) : int {
if (boneName == null) throw new ArgumentError("boneName cannot be null.");
for (var i : int = 0, n : int = bones.length; i < n; i++)
if (bones[i]._name == boneName) return i;
return -1;
}
// --- Slots.
/** @return May be null. */
public function findSlot(slotName : String) : SlotData {
@ -81,14 +73,6 @@ package spine {
return null;
}
/** @return -1 if the bone was not found. */
public function findSlotIndex(slotName : String) : int {
if (slotName == null) throw new ArgumentError("slotName cannot be null.");
for (var i : int = 0, n : int = slots.length; i < n; i++)
if (slots[i]._name == slotName) return i;
return -1;
}
// --- Skins.
/** @return May be null. */
public function findSkin(skinName : String) : Skin {

View File

@ -437,27 +437,29 @@ package spine {
var time : Number, time2 : Number;
var curve : Object;
var timelineName : String;
var i : int, n : int;
var i : int, n : int, frames : int;
// Slot timelines.
var slots : Object = map["slots"];
for (slotName in slots) {
slotMap = slots[slotName];
slotIndex = skeletonData.findSlotIndex(slotName);
slotIndex = skeletonData.findSlot(slotName).index;
for (timelineName in slotMap) {
timelineMap = slotMap[timelineName];
if (!timelineMap) continue;
frames = timelineMap.length;
if (timelineName == "attachment") {
var attachmentTimeline : AttachmentTimeline = new AttachmentTimeline(timelineMap.length, slotIndex);
for (frame = 0; frame < timelineMap.length; frame++) {
var attachmentTimeline : AttachmentTimeline = new AttachmentTimeline(frames, slotIndex);
for (frame = 0; frame < frames; frame++) {
keyMap = timelineMap[frame];
attachmentTimeline.setFrame(frame, getNumber(keyMap, "time", 0), keyMap.name);
}
timelines.push(attachmentTimeline);
} else if (timelineName == "rgba") {
var rgbaTimeline : RGBATimeline = new RGBATimeline(timelineMap.length, timelineMap.length << 2, slotIndex);
var rgbaTimeline : RGBATimeline = new RGBATimeline(frames, frames << 2, slotIndex);
keyMap = timelineMap[0];
time = getNumber(keyMap, "time", 0);
var rgba : Color = Color.fromString(keyMap.color);
@ -485,7 +487,7 @@ package spine {
timelines.push(rgbaTimeline);
} else if (timelineName == "rgb") {
var rgbTimeline : RGBTimeline = new RGBTimeline(timelineMap.length, timelineMap.length * 3, slotIndex);
var rgbTimeline : RGBTimeline = new RGBTimeline(frames, frames * 3, slotIndex);
keyMap = timelineMap[0];
time = getNumber(keyMap, "time", 0);
var rgb : Color = Color.fromString(keyMap.color);
@ -512,9 +514,9 @@ package spine {
timelines.push(rgbTimeline);
} else if (timelineName == "alpha") {
timelines.push(readTimeline(timelineMap, new AlphaTimeline(timelineMap.length, timelineMap.length, slotIndex), 0, 1));
timelines.push(readTimeline(timelineMap, new AlphaTimeline(frames, frames, slotIndex), 0, 1));
} else if (timelineName == "rgba2") {
var rgba2Timeline : RGBA2Timeline = new RGBA2Timeline(timelineMap.length, timelineMap.length * 7, slotIndex);
var rgba2Timeline : RGBA2Timeline = new RGBA2Timeline(frames, frames * 7, slotIndex);
keyMap = timelineMap[0];
time = getNumber(keyMap, "time", 0);
@ -549,7 +551,7 @@ package spine {
timelines.push(rgba2Timeline);
} else if (timelineName == "rgb2") {
var rgb2Timeline : RGB2Timeline = new RGB2Timeline(timelineMap.length, timelineMap.length * 6, slotIndex);
var rgb2Timeline : RGB2Timeline = new RGB2Timeline(frames, frames * 6, slotIndex);
keyMap = timelineMap[0];
time = getNumber(keyMap, "time", 0);
@ -590,42 +592,44 @@ package spine {
// Bone timelines.
var bones : Object = map["bones"];
for (var boneName : String in bones) {
var boneIndex : int = skeletonData.findBoneIndex(boneName);
if (boneIndex == -1) throw new Error("Bone not found: " + boneName);
var bone : BoneData = skeletonData.findBone(boneName);
if (!bone) throw new Error("Bone not found: " + boneName);
var boneIndex : int = bone.index;
var boneMap : Object = bones[boneName];
for (timelineName in boneMap) {
timelineMap = boneMap[timelineName];
if (timelineMap.length == 0) continue;
frames = timelineMap.length;
if (frames == 0) continue;
if (timelineName === "rotate") {
timelines.push(readTimeline(timelineMap, new RotateTimeline(timelineMap.length, timelineMap.length, boneIndex), 0, 1));
timelines.push(readTimeline(timelineMap, new RotateTimeline(frames, frames, boneIndex), 0, 1));
} else if (timelineName === "translate") {
var translateTimeline : TranslateTimeline = new TranslateTimeline(timelineMap.length, timelineMap.length << 1, boneIndex);
var translateTimeline : TranslateTimeline = new TranslateTimeline(frames, frames << 1, boneIndex);
timelines.push(readTimeline2(timelineMap, translateTimeline, "x", "y", 0, scale));
} else if (timelineName === "translatex") {
var translateXTimeline : TranslateXTimeline = new TranslateXTimeline(timelineMap.length, timelineMap.length, boneIndex);
var translateXTimeline : TranslateXTimeline = new TranslateXTimeline(frames, frames, boneIndex);
timelines.push(readTimeline(timelineMap, translateXTimeline, 0, scale));
} else if (timelineName === "translatey") {
var translateYTimeline : TranslateYTimeline = new TranslateYTimeline(timelineMap.length, timelineMap.length, boneIndex);
var translateYTimeline : TranslateYTimeline = new TranslateYTimeline(frames, frames, boneIndex);
timelines.push(readTimeline(timelineMap, translateYTimeline, 0, scale));
} else if (timelineName === "scale") {
var scaleTimeline : ScaleTimeline = new ScaleTimeline(timelineMap.length, timelineMap.length << 1, boneIndex);
var scaleTimeline : ScaleTimeline = new ScaleTimeline(frames, frames << 1, boneIndex);
timelines.push(readTimeline2(timelineMap, scaleTimeline, "x", "y", 1, 1));
} else if (timelineName === "scalex") {
var scaleXTimeline : ScaleXTimeline = new ScaleXTimeline(timelineMap.length, timelineMap.length, boneIndex);
var scaleXTimeline : ScaleXTimeline = new ScaleXTimeline(frames, frames, boneIndex);
timelines.push(readTimeline(timelineMap, scaleXTimeline, 1, 1));
} else if (timelineName === "scaley") {
var scaleYTimeline : ScaleYTimeline = new ScaleYTimeline(timelineMap.length, timelineMap.length, boneIndex);
var scaleYTimeline : ScaleYTimeline = new ScaleYTimeline(frames, frames, boneIndex);
timelines.push(readTimeline(timelineMap, scaleYTimeline, 1, 1));
} else if (timelineName === "shear") {
var shearTimeline : ShearTimeline = new ShearTimeline(timelineMap.length, timelineMap.length << 1, boneIndex);
var shearTimeline : ShearTimeline = new ShearTimeline(frames, frames << 1, boneIndex);
timelines.push(readTimeline2(timelineMap, shearTimeline, "x", "y", 0, 1));
} else if (timelineName === "shearx") {
var shearXTimeline : ShearXTimeline = new ShearXTimeline(timelineMap.length, timelineMap.length, boneIndex);
var shearXTimeline : ShearXTimeline = new ShearXTimeline(frames, frames, boneIndex);
timelines.push(readTimeline(timelineMap, shearXTimeline, 0, 1));
} else if (timelineName === "sheary") {
var shearYTimeline : ShearYTimeline = new ShearYTimeline(timelineMap.length, timelineMap.length, boneIndex);
var shearYTimeline : ShearYTimeline = new ShearYTimeline(frames, frames, boneIndex);
timelines.push(readTimeline(timelineMap, shearYTimeline, 0, 1));
} else
throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
@ -682,7 +686,7 @@ package spine {
if (!keyMap) continue;
var transformIndex : int = skeletonData.transformConstraints.indexOf(skeletonData.findTransformConstraint(transformName));
var transformTimeline : TransformConstraintTimeline = new TransformConstraintTimeline(timelineMap.length, timelineMap.length << 2, transformIndex);
var transformTimeline : TransformConstraintTimeline = new TransformConstraintTimeline(timelineMap.length, timelineMap.length * 6, transformIndex);
time = getNumber(keyMap, "time", 0);
mixRotate = getNumber(keyMap, "mixRotate", 1);
@ -742,14 +746,15 @@ package spine {
keyMap = timelineMap[0];
if (!keyMap) continue;
frames = timelineMap.length;
if (timelineName === "position") {
var positionTimeline : PathConstraintPositionTimeline = new PathConstraintPositionTimeline(timelineMap.length, timelineMap.length, index);
var positionTimeline : PathConstraintPositionTimeline = new PathConstraintPositionTimeline(frames, frames, index);
timelines.push(readTimeline(timelineMap, positionTimeline, 0, pathData.positionMode == PositionMode.fixed ? scale : 1));
} else if (timelineName === "spacing") {
var spacingTimeline : PathConstraintSpacingTimeline = new PathConstraintSpacingTimeline(timelineMap.length, timelineMap.length, index);
var spacingTimeline : PathConstraintSpacingTimeline = new PathConstraintSpacingTimeline(frames, frames, index);
timelines.push(readTimeline(timelineMap, spacingTimeline, 0, pathData.spacingMode == SpacingMode.length || pathData.spacingMode == SpacingMode.fixed ? scale : 1));
} else if (timelineName === "mix") {
var mixTimeline : PathConstraintMixTimeline = new PathConstraintMixTimeline(timelineMap.size, timelineMap.size * 3, index);
var mixTimeline : PathConstraintMixTimeline = new PathConstraintMixTimeline(frames, frames * 3, index);
time = getNumber(keyMap, "time", 0);
mixRotate = getNumber(keyMap, "mixRotate", 1);
mixX = getNumber(keyMap, "mixX", 1);
@ -790,7 +795,7 @@ package spine {
if (skin == null) throw new Error("Skin not found: " + deformName);
for (slotName in deformMap) {
slotMap = deformMap[slotName];
slotIndex = skeletonData.findSlotIndex(slotName);
slotIndex = skeletonData.findSlot(slotName).index;
if (slotIndex == -1) throw new Error("Slot not found: " + slotMap.name);
for (timelineName in slotMap) {
timelineMap = slotMap[timelineName];
@ -859,7 +864,7 @@ package spine {
var unchanged : Vector.<int> = new Vector.<int>(slotCount - offsets.length, true);
var originalIndex : int = 0, unchangedIndex : int = 0;
for each (var offsetMap : Object in offsets) {
slotIndex = skeletonData.findSlotIndex(offsetMap["slot"]);
slotIndex = skeletonData.findSlot(offsetMap["slot"]).index;
if (slotIndex == -1) throw new Error("Slot not found: " + offsetMap["slot"]);
// Collect unchanged items.
while (originalIndex != slotIndex)

View File

@ -27,7 +27,6 @@ Depending on the test agent build environment, you should build the output solut
This build step should not execute if the previous step did not successfully complete.
Again, depending on the test agent build environment, you should have produced an executable. Run this executable.
## Usage
Make sure [CMake](https://cmake.org/download/) is installed.
@ -40,7 +39,6 @@ cmake ..
### Win32 build
msbuild spine_unit_test.sln /t:spine_unit_test /p:Configuration="Debug" /p:Platform="Win32"
## Licensing
This Spine Runtime may only be used for personal or internal use, typically to evaluate Spine before purchasing. If you would like to incorporate a Spine Runtime into your applications, distribute software containing a Spine Runtime, or modify a Spine Runtime, then you will need a valid [Spine license](https://esotericsoftware.com/spine-purchase). Please see the [Spine Runtimes Software License](https://github.com/EsotericSoftware/spine-runtimes/blob/master/LICENSE) for detailed information.

View File

@ -88,13 +88,9 @@ SP_API void spSkeleton_setSlotsToSetupPose(const spSkeleton *self);
/* Returns 0 if the bone was not found. */
SP_API spBone *spSkeleton_findBone(const spSkeleton *self, const char *boneName);
/* Returns -1 if the bone was not found. */
SP_API int spSkeleton_findBoneIndex(const spSkeleton *self, const char *boneName);
/* Returns 0 if the slot was not found. */
SP_API spSlot *spSkeleton_findSlot(const spSkeleton *self, const char *slotName);
/* Returns -1 if the slot was not found. */
SP_API int spSkeleton_findSlotIndex(const spSkeleton *self, const char *slotName);
/* Sets the skin used to look up attachments before looking in the SkeletonData defaultSkin. Attachments from the new skin are
* attached if the corresponding attachment from the old skin was attached. If there was no old skin, each slot's setup mode

View File

@ -87,12 +87,8 @@ SP_API void spSkeletonData_dispose(spSkeletonData *self);
SP_API spBoneData *spSkeletonData_findBone(const spSkeletonData *self, const char *boneName);
SP_API int spSkeletonData_findBoneIndex(const spSkeletonData *self, const char *boneName);
SP_API spSlotData *spSkeletonData_findSlot(const spSkeletonData *self, const char *slotName);
SP_API int spSkeletonData_findSlotIndex(const spSkeletonData *self, const char *slotName);
SP_API spSkin *spSkeletonData_findSkin(const spSkeletonData *self, const char *skinName);
SP_API spEventData *spSkeletonData_findEvent(const spSkeletonData *self, const char *eventName);
@ -101,17 +97,11 @@ SP_API spAnimation *spSkeletonData_findAnimation(const spSkeletonData *self, con
SP_API spIkConstraintData *spSkeletonData_findIkConstraint(const spSkeletonData *self, const char *constraintName);
SP_API int spSkeletonData_findIkConstraintIndex(const spSkeletonData *self, const char *constraintName);
SP_API spTransformConstraintData *
spSkeletonData_findTransformConstraint(const spSkeletonData *self, const char *constraintName);
SP_API int spSkeletonData_findTransformConstraintIndex(const spSkeletonData *self, const char *constraintName);
SP_API spPathConstraintData *spSkeletonData_findPathConstraint(const spSkeletonData *self, const char *constraintName);
SP_API int spSkeletonData_findPathConstraintIndex(const spSkeletonData *self, const char *constraintName);
#ifdef __cplusplus
}
#endif

View File

@ -531,13 +531,6 @@ spBone *spSkeleton_findBone(const spSkeleton *self, const char *boneName) {
return 0;
}
int spSkeleton_findBoneIndex(const spSkeleton *self, const char *boneName) {
int i;
for (i = 0; i < self->bonesCount; ++i)
if (strcmp(self->data->bones[i]->name, boneName) == 0) return i;
return -1;
}
spSlot *spSkeleton_findSlot(const spSkeleton *self, const char *slotName) {
int i;
for (i = 0; i < self->slotsCount; ++i)
@ -545,13 +538,6 @@ spSlot *spSkeleton_findSlot(const spSkeleton *self, const char *slotName) {
return 0;
}
int spSkeleton_findSlotIndex(const spSkeleton *self, const char *slotName) {
int i;
for (i = 0; i < self->slotsCount; ++i)
if (strcmp(self->data->slots[i]->name, slotName) == 0) return i;
return -1;
}
int spSkeleton_setSkinByName(spSkeleton *self, const char *skinName) {
spSkin *skin;
if (!skinName) {
@ -587,7 +573,7 @@ void spSkeleton_setSkin(spSkeleton *self, spSkin *newSkin) {
spAttachment *
spSkeleton_getAttachmentForSlotName(const spSkeleton *self, const char *slotName, const char *attachmentName) {
int slotIndex = spSkeletonData_findSlotIndex(self->data, slotName);
int slotIndex = spSkeletonData_findSlot(self->data, slotName)->index;
return spSkeleton_getAttachmentForSlotIndex(self, slotIndex, attachmentName);
}

View File

@ -143,9 +143,7 @@ float readFloat(_dataInput *input) {
char *readString(_dataInput *input) {
int length = readVarint(input, 1);
char *string;
if (length == 0) {
return 0;
}
if (length == 0) return NULL;
string = MALLOC(char, length);
memcpy(string, input->cursor, length - 1);
input->cursor += length - 1;
@ -770,7 +768,7 @@ static spAnimation *_spSkeletonBinary_readAnimation(spSkeletonBinary *self, cons
spTimeline_dispose(timelines->items[i]);
spTimelineArray_dispose(timelines);
_spSkeletonBinary_setError(self, "Attachment not found: ", attachmentName);
return 0;
return NULL;
}
weighted = attachment->bones != 0;
@ -1115,7 +1113,7 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
}
}
return 0;
return NULL;
}
spSkin *spSkeletonBinary_readSkin(spSkeletonBinary *self, _dataInput *input, int /*bool*/ defaultSkin,
@ -1125,7 +1123,7 @@ spSkin *spSkeletonBinary_readSkin(spSkeletonBinary *self, _dataInput *input, int
if (defaultSkin) {
slotCount = readVarint(input, 1);
if (slotCount == 0) return 0;
if (slotCount == 0) return NULL;
skin = spSkin_create("default");
} else {
skin = spSkin_create(readStringRef(input, skeletonData));
@ -1163,7 +1161,7 @@ spSkeletonData *spSkeletonBinary_readSkeletonDataFile(spSkeletonBinary *self, co
const char *binary = _spUtil_readFile(path, &length);
if (length == 0 || !binary) {
_spSkeletonBinary_setError(self, "Unable to read skeleton file: ", path);
return 0;
return NULL;
}
skeletonData = spSkeletonBinary_readSkeletonData(self, (unsigned char *) binary, length);
FREE(binary);
@ -1411,14 +1409,14 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
FREE(input);
spSkeletonData_dispose(skeletonData);
_spSkeletonBinary_setError(self, "Skin not found: ", linkedMesh->skin);
return 0;
return NULL;
}
parent = spSkin_getAttachment(skin, linkedMesh->slotIndex, linkedMesh->parent);
if (!parent) {
FREE(input);
spSkeletonData_dispose(skeletonData);
_spSkeletonBinary_setError(self, "Parent mesh not found: ", linkedMesh->parent);
return 0;
return NULL;
}
linkedMesh->mesh->super.deformAttachment = linkedMesh->inheritDeform ? SUB_CAST(spVertexAttachment, parent)
: SUB_CAST(spVertexAttachment,
@ -1455,7 +1453,7 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
if (!animation) {
FREE(input);
spSkeletonData_dispose(skeletonData);
return 0;
return NULL;
}
skeletonData->animations[i] = animation;
}

View File

@ -89,13 +89,6 @@ spBoneData *spSkeletonData_findBone(const spSkeletonData *self, const char *bone
return 0;
}
int spSkeletonData_findBoneIndex(const spSkeletonData *self, const char *boneName) {
int i;
for (i = 0; i < self->bonesCount; ++i)
if (strcmp(self->bones[i]->name, boneName) == 0) return i;
return -1;
}
spSlotData *spSkeletonData_findSlot(const spSkeletonData *self, const char *slotName) {
int i;
for (i = 0; i < self->slotsCount; ++i)
@ -103,13 +96,6 @@ spSlotData *spSkeletonData_findSlot(const spSkeletonData *self, const char *slot
return 0;
}
int spSkeletonData_findSlotIndex(const spSkeletonData *self, const char *slotName) {
int i;
for (i = 0; i < self->slotsCount; ++i)
if (strcmp(self->slots[i]->name, slotName) == 0) return i;
return -1;
}
spSkin *spSkeletonData_findSkin(const spSkeletonData *self, const char *skinName) {
int i;
for (i = 0; i < self->skinsCount; ++i)
@ -138,13 +124,6 @@ spIkConstraintData *spSkeletonData_findIkConstraint(const spSkeletonData *self,
return 0;
}
int spSkeletonData_findIkConstraintIndex(const spSkeletonData *self, const char *constraintName) {
int i;
for (i = 0; i < self->ikConstraintsCount; ++i)
if (strcmp(self->ikConstraints[i]->name, constraintName) == 0) return i;
return -1;
}
spTransformConstraintData *
spSkeletonData_findTransformConstraint(const spSkeletonData *self, const char *constraintName) {
int i;
@ -153,23 +132,9 @@ spSkeletonData_findTransformConstraint(const spSkeletonData *self, const char *c
return 0;
}
int spSkeletonData_findTransformConstraintIndex(const spSkeletonData *self, const char *constraintName) {
int i;
for (i = 0; i < self->transformConstraintsCount; ++i)
if (strcmp(self->transformConstraints[i]->name, constraintName) == 0) return i;
return -1;
}
spPathConstraintData *spSkeletonData_findPathConstraint(const spSkeletonData *self, const char *constraintName) {
int i;
for (i = 0; i < self->pathConstraintsCount; ++i)
if (strcmp(self->pathConstraints[i]->name, constraintName) == 0) return self->pathConstraints[i];
return 0;
}
int spSkeletonData_findPathConstraintIndex(const spSkeletonData *self, const char *constraintName) {
int i;
for (i = 0; i < self->pathConstraintsCount; ++i)
if (strcmp(self->pathConstraints[i]->name, constraintName) == 0) return i;
return -1;
}

View File

@ -140,7 +140,7 @@ static spTimeline *readTimeline(Json *keyMap, spCurveTimeline1 *timeline, float
float time = Json_getFloat(keyMap, "time", 0);
float value = Json_getFloat(keyMap, "value", defaultValue) * scale;
int frame, bezier = 0;
for (frame = 0;; frame++) {
for (frame = 0;; ++frame) {
Json *nextMap, *curve;
float time2, value2;
spCurveTimeline1_setFrame(timeline, frame, time, value);
@ -165,7 +165,7 @@ readTimeline2(Json *keyMap, spCurveTimeline2 *timeline, const char *name1, const
float value1 = Json_getFloat(keyMap, name1, defaultValue) * scale;
float value2 = Json_getFloat(keyMap, name2, defaultValue) * scale;
int frame, bezier = 0;
for (frame = 0;; frame++) {
for (frame = 0;; ++frame) {
Json *nextMap, *curve;
float time2, nvalue1, nvalue2;
spCurveTimeline2_setFrame(timeline, frame, time, value1, value2);
@ -188,7 +188,6 @@ readTimeline2(Json *keyMap, spCurveTimeline2 *timeline, const char *name1, const
return SUPER(timeline);
}
static void _spSkeletonJson_addLinkedMesh(spSkeletonJson *self, spMeshAttachment *mesh, const char *skin, int slotIndex,
const char *parent, int inheritDeform) {
_spLinkedMesh *linkedMesh;
@ -214,12 +213,52 @@ static void _spSkeletonJson_addLinkedMesh(spSkeletonJson *self, spMeshAttachment
static void cleanUpTimelines(spTimelineArray *timelines) {
int i, n;
for (i = 0, n = timelines->size; i < n; i++) {
for (i = 0, n = timelines->size; i < n; ++i)
spTimeline_dispose(timelines->items[i]);
}
spTimelineArray_dispose(timelines);
}
static int findSlotIndex(const spSkeletonData *skeletonData, const char *slotName, spTimelineArray *timelines) {
spSlotData *slot = spSkeletonData_findSlot(skeletonData, slotName);
if (slot) return slot->index;
cleanUpTimelines(timelines);
_spSkeletonJson_setError(skeletonData, NULL, "Slot not found: ", slotName);
return -1;
}
int findIkConstraintIndex(const spSkeletonData *skeletonData, const spIkConstraintData *constraint, spTimelineArray *timelines) {
if (constraint) {
int i;
for (i = 0; i < skeletonData->ikConstraintsCount; ++i)
if (skeletonData->ikConstraints[i] == constraint) return i;
}
cleanUpTimelines(timelines);
_spSkeletonJson_setError(skeletonData, NULL, "IK constraint not found: ", constraint->name);
return -1;
}
int findTransformConstraintIndex(const spSkeletonData *skeletonData, const spTransformConstraintData *constraint, spTimelineArray *timelines) {
if (constraint) {
int i;
for (i = 0; i < skeletonData->transformConstraintsCount; ++i)
if (skeletonData->transformConstraints[i] == constraint) return i;
}
cleanUpTimelines(timelines);
_spSkeletonJson_setError(skeletonData, NULL, "Transform constraint not found: ", constraint->name);
return -1;
}
int findPathConstraintIndex(const spSkeletonData *skeletonData, const spPathConstraintData *constraint, spTimelineArray *timelines) {
if (constraint) {
int i;
for (i = 0; i < skeletonData->pathConstraintsCount; ++i)
if (skeletonData->pathConstraints[i] == constraint) return i;
}
cleanUpTimelines(timelines);
_spSkeletonJson_setError(skeletonData, NULL, "Path constraint not found: ", constraint->name);
return -1;
}
static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *root, spSkeletonData *skeletonData) {
spTimelineArray *timelines = spTimelineArray_create(8);
@ -238,17 +277,13 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
/* Slot timelines. */
for (slotMap = slots ? slots->child : 0; slotMap; slotMap = slotMap->next) {
int slotIndex = spSkeletonData_findSlotIndex(skeletonData, slotMap->name);
if (slotIndex == -1) {
cleanUpTimelines(timelines);
_spSkeletonJson_setError(self, NULL, "Slot not found: ", slotMap->name);
return NULL;
}
int slotIndex = findSlotIndex(skeletonData, slotMap->name, timelines);
if (slotIndex == -1) return NULL;
for (timelineMap = slotMap->child; timelineMap; timelineMap = timelineMap->next) {
int frames = timelineMap->size;
if (strcmp(timelineMap->name, "attachment") == 0) {
int frameCount = timelineMap->size;
spAttachmentTimeline *timeline = spAttachmentTimeline_create(frameCount, slotIndex);
spAttachmentTimeline *timeline = spAttachmentTimeline_create(frames, slotIndex);
for (keyMap = timelineMap->child, frame = 0; keyMap; keyMap = keyMap->next, ++frame) {
spAttachmentTimeline_setFrame(timeline, frame, Json_getFloat(keyMap, "time", 0),
Json_getItem(keyMap, "name")->valueString);
@ -257,9 +292,7 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
} else if (strcmp(timelineMap->name, "rgba") == 0) {
float time;
int frameCount = timelineMap->size;
int bezierCount = frameCount << 2;
spRGBATimeline *timeline = spRGBATimeline_create(frameCount, bezierCount, slotIndex);
spRGBATimeline *timeline = spRGBATimeline_create(frames, frames << 2, slotIndex);
keyMap = timelineMap->child;
time = Json_getFloat(keyMap, "time", 0);
toColor2(&color, Json_getString(keyMap, "color", 0), 1);
@ -292,9 +325,7 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
} else if (strcmp(timelineMap->name, "rgb") == 0) {
float time;
int frameCount = timelineMap->size;
int bezierCount = frameCount * 3;
spRGBTimeline *timeline = spRGBTimeline_create(frameCount, bezierCount, slotIndex);
spRGBTimeline *timeline = spRGBTimeline_create(frames, frames * 3, slotIndex);
keyMap = timelineMap->child;
time = Json_getFloat(keyMap, "time", 0);
toColor2(&color, Json_getString(keyMap, "color", 0), 1);
@ -325,14 +356,12 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
} else if (strcmp(timelineMap->name, "alpha") == 0) {
spTimelineArray_add(timelines, readTimeline(timelineMap->child,
SUPER(spAlphaTimeline_create(timelineMap->size,
timelineMap->size, slotIndex)),
SUPER(spAlphaTimeline_create(frames,
frames, slotIndex)),
0, 1));
} else if (strcmp(timelineMap->name, "rgba2") == 0) {
float time;
int frameCount = timelineMap->size;
int bezierCount = frameCount * 7;
spRGBA2Timeline *timeline = spRGBA2Timeline_create(frameCount, bezierCount, slotIndex);
spRGBA2Timeline *timeline = spRGBA2Timeline_create(frames, frames * 7, slotIndex);
keyMap = timelineMap->child;
time = Json_getFloat(keyMap, "time", 0);
toColor2(&color, Json_getString(keyMap, "light", 0), 1);
@ -375,9 +404,7 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
} else if (strcmp(timelineMap->name, "rgb2") == 0) {
float time;
int frameCount = timelineMap->size;
int bezierCount = frameCount * 7;
spRGBA2Timeline *timeline = spRGBA2Timeline_create(frameCount, bezierCount, slotIndex);
spRGBA2Timeline *timeline = spRGBA2Timeline_create(frames, frames * 6, slotIndex);
keyMap = timelineMap->child;
time = Json_getFloat(keyMap, "time", 0);
toColor2(&color, Json_getString(keyMap, "light", 0), 0);
@ -426,8 +453,14 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
/* Bone timelines. */
for (boneMap = bones ? bones->child : 0; boneMap; boneMap = boneMap->next) {
int boneIndex = spSkeletonData_findBoneIndex(skeletonData, boneMap->name);
int boneIndex = -1;
int i;
for (i = 0; i < skeletonData->bonesCount; ++i) {
if (strcmp(skeletonData->bones[i]->name, boneMap->name) == 0) {
boneIndex = i;
break;
}
}
if (boneIndex == -1) {
cleanUpTimelines(timelines);
_spSkeletonJson_setError(self, NULL, "Bone not found: ", boneMap->name);
@ -435,45 +468,46 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
}
for (timelineMap = boneMap->child; timelineMap; timelineMap = timelineMap->next) {
if (timelineMap->size == 0) continue;
int frames = timelineMap->size;
if (frames == 0) continue;
if (strcmp(timelineMap->name, "rotate") == 0) {
spTimelineArray_add(timelines, readTimeline(timelineMap->child,
SUPER(spRotateTimeline_create(timelineMap->size,
timelineMap->size,
SUPER(spRotateTimeline_create(frames,
frames,
boneIndex)),
0, 1));
} else if (strcmp(timelineMap->name, "translate") == 0) {
spTranslateTimeline *timeline = spTranslateTimeline_create(timelineMap->size, timelineMap->size << 1,
spTranslateTimeline *timeline = spTranslateTimeline_create(frames, frames << 1,
boneIndex);
spTimelineArray_add(timelines, readTimeline2(timelineMap->child, SUPER(timeline), "x", "y", 0, scale));
} else if (strcmp(timelineMap->name, "translatex") == 0) {
spTranslateXTimeline *timeline = spTranslateXTimeline_create(timelineMap->size, timelineMap->size,
spTranslateXTimeline *timeline = spTranslateXTimeline_create(frames, frames,
boneIndex);
spTimelineArray_add(timelines, readTimeline(timelineMap->child, SUPER(timeline), 0, scale));
} else if (strcmp(timelineMap->name, "translatey") == 0) {
spTranslateYTimeline *timeline = spTranslateYTimeline_create(timelineMap->size, timelineMap->size,
spTranslateYTimeline *timeline = spTranslateYTimeline_create(frames, frames,
boneIndex);
spTimelineArray_add(timelines, readTimeline(timelineMap->child, SUPER(timeline), 0, scale));
} else if (strcmp(timelineMap->name, "scale") == 0) {
spScaleTimeline *timeline = spScaleTimeline_create(timelineMap->size, timelineMap->size << 1,
spScaleTimeline *timeline = spScaleTimeline_create(frames, frames << 1,
boneIndex);
spTimelineArray_add(timelines, readTimeline2(timelineMap->child, SUPER(timeline), "x", "y", 1, 1));
} else if (strcmp(timelineMap->name, "scalex") == 0) {
spScaleXTimeline *timeline = spScaleXTimeline_create(timelineMap->size, timelineMap->size, boneIndex);
spScaleXTimeline *timeline = spScaleXTimeline_create(frames, frames, boneIndex);
spTimelineArray_add(timelines, readTimeline(timelineMap->child, SUPER(timeline), 1, 1));
} else if (strcmp(timelineMap->name, "scaley") == 0) {
spScaleYTimeline *timeline = spScaleYTimeline_create(timelineMap->size, timelineMap->size, boneIndex);
spScaleYTimeline *timeline = spScaleYTimeline_create(frames, frames, boneIndex);
spTimelineArray_add(timelines, readTimeline(timelineMap->child, SUPER(timeline), 1, 1));
} else if (strcmp(timelineMap->name, "shear") == 0) {
spShearTimeline *timeline = spShearTimeline_create(timelineMap->size, timelineMap->size << 1,
spShearTimeline *timeline = spShearTimeline_create(frames, frames << 1,
boneIndex);
spTimelineArray_add(timelines, readTimeline2(timelineMap->child, SUPER(timeline), "x", "y", 0, 1));
} else if (strcmp(timelineMap->name, "shearx") == 0) {
spShearXTimeline *timeline = spShearXTimeline_create(timelineMap->size, timelineMap->size, boneIndex);
spShearXTimeline *timeline = spShearXTimeline_create(frames, frames, boneIndex);
spTimelineArray_add(timelines, readTimeline(timelineMap->child, SUPER(timeline), 0, 1));
} else if (strcmp(timelineMap->name, "sheary") == 0) {
spShearYTimeline *timeline = spShearYTimeline_create(timelineMap->size, timelineMap->size, boneIndex);
spShearYTimeline *timeline = spShearYTimeline_create(frames, frames, boneIndex);
spTimelineArray_add(timelines, readTimeline(timelineMap->child, SUPER(timeline), 0, 1));
} else {
cleanUpTimelines(timelines);
@ -493,14 +527,15 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
if (keyMap == NULL) continue;
constraint = spSkeletonData_findIkConstraint(skeletonData, constraintMap->name);
constraintIndex = spSkeletonData_findIkConstraintIndex(skeletonData, constraint->name);
constraintIndex = findIkConstraintIndex(skeletonData, constraint, timelines);
if (constraintIndex == -1) return NULL;
timeline = spIkConstraintTimeline_create(constraintMap->size, constraintMap->size << 1, constraintIndex);
time = Json_getFloat(keyMap, "time", 0);
mix = Json_getFloat(keyMap, "mix", 1);
softness = Json_getFloat(keyMap, "softness", 0) * scale;
for (frame = 0, bezier = 0;; frame++) {
for (frame = 0, bezier = 0;; ++frame) {
float time2, mix2, softness2;
int bendDirection = Json_getInt(keyMap, "bendPositive", 1) ? 1 : -1;
spIkConstraintTimeline_setFrame(timeline, frame, time, mix, softness, bendDirection,
@ -540,8 +575,9 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
if (keyMap == NULL) continue;
constraint = spSkeletonData_findTransformConstraint(skeletonData, constraintMap->name);
constraintIndex = spSkeletonData_findTransformConstraintIndex(skeletonData, constraint->name);
timeline = spTransformConstraintTimeline_create(constraintMap->size, constraintMap->size << 2, constraintIndex);
constraintIndex = findTransformConstraintIndex(skeletonData, constraint, timelines);
if (constraintIndex == -1) return NULL;
timeline = spTransformConstraintTimeline_create(constraintMap->size, constraintMap->size * 6, constraintIndex);
time = Json_getFloat(keyMap, "time", 0);
mixRotate = Json_getFloat(keyMap, "mixRotate", 1);
@ -551,7 +587,7 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
mixScaleX = Json_getFloat(keyMap, "mixScaleX", 1);
mixScaleY = Json_getFloat(keyMap, "mixScaleY", mixScaleX);
for (frame = 0, bezier = 0;; frame++) {
for (frame = 0, bezier = 0;; ++frame) {
float time2, mixRotate2, mixShearY2, mixX2, mixY2, mixScaleX2, mixScaleY2;
spTransformConstraintTimeline_setFrame(timeline, frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY,
mixShearY);
@ -593,42 +629,39 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
/** Path constraint timelines. */
for (constraintMap = paths ? paths->child : 0; constraintMap; constraintMap = constraintMap->next) {
spPathConstraintData *data = spSkeletonData_findPathConstraint(skeletonData, constraintMap->name);
int index;
if (!data) {
cleanUpTimelines(timelines);
_spSkeletonJson_setError(self, NULL, "Path constraint not found: ", constraintMap->name);
return NULL;
}
index = spSkeletonData_findPathConstraintIndex(skeletonData, data->name);
spPathConstraintData *constraint = spSkeletonData_findPathConstraint(skeletonData, constraintMap->name);
int constraintIndex = findPathConstraintIndex(skeletonData, constraint->name);
if (constraintIndex == -1) return NULL;
for (timelineMap = constraintMap->child; timelineMap; timelineMap = timelineMap->next) {
const char *timelineName;
int frames;
keyMap = timelineMap->child;
if (keyMap == NULL) continue;
frames = timelineMap->size;
timelineName = timelineMap->name;
if (strcmp(timelineName, "position") == 0) {
spPathConstraintPositionTimeline *timeline = spPathConstraintPositionTimeline_create(timelineMap->size,
timelineMap->size,
index);
spPathConstraintPositionTimeline *timeline = spPathConstraintPositionTimeline_create(frames,
frames,
constraintIndex);
spTimelineArray_add(timelines, readTimeline(keyMap, SUPER(timeline), 0,
data->positionMode == SP_POSITION_MODE_FIXED ? scale : 1));
constraint->positionMode == SP_POSITION_MODE_FIXED ? scale : 1));
} else if (strcmp(timelineName, "spacing") == 0) {
spCurveTimeline1 *timeline = SUPER(
spPathConstraintSpacingTimeline_create(timelineMap->size, timelineMap->size, index));
spPathConstraintSpacingTimeline_create(frames, frames, constraintIndex));
spTimelineArray_add(timelines, readTimeline(keyMap, timeline, 0,
data->spacingMode == SP_SPACING_MODE_LENGTH ||
data->spacingMode == SP_SPACING_MODE_FIXED
constraint->spacingMode == SP_SPACING_MODE_LENGTH ||
constraint->spacingMode == SP_SPACING_MODE_FIXED
? scale
: 1));
} else if (strcmp(timelineName, "mix") == 0) {
spPathConstraintMixTimeline *timeline = spPathConstraintMixTimeline_create(timelineMap->size,
timelineMap->size * 3,
index);
spPathConstraintMixTimeline *timeline = spPathConstraintMixTimeline_create(frames,
frames * 3,
constraintIndex);
float time = Json_getFloat(keyMap, "time", 0);
float mixRotate = Json_getFloat(keyMap, "mixRotate", 1);
float mixX = Json_getFloat(keyMap, "mixX", 1);
float mixY = Json_getFloat(keyMap, "mixY", mixX);
for (frame = 0, bezier = 0;; frame++) {
for (frame = 0, bezier = 0;; ++frame) {
float time2, mixRotate2, mixX2, mixY2;
spPathConstraintMixTimeline_setFrame(timeline, frame, time, mixRotate, mixX, mixY);
nextMap = keyMap->next;
@ -663,7 +696,8 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
for (constraintMap = deformJson ? deformJson->child : 0; constraintMap; constraintMap = constraintMap->next) {
spSkin *skin = spSkeletonData_findSkin(skeletonData, constraintMap->name);
for (slotMap = constraintMap->child; slotMap; slotMap = slotMap->next) {
int slotIndex = spSkeletonData_findSlotIndex(skeletonData, slotMap->name);
int slotIndex = findSlotIndex(skeletonData, slotMap->name, timelines);
if (slotIndex == -1) return NULL;
for (timelineMap = slotMap->child; timelineMap; timelineMap = timelineMap->next) {
float *tempDeform;
@ -678,7 +712,7 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
if (!attachment) {
cleanUpTimelines(timelines);
_spSkeletonJson_setError(self, 0, "Attachment not found: ", timelineMap->name);
return 0;
return NULL;
}
weighted = attachment->bones != 0;
deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount;
@ -687,7 +721,7 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
attachment);
time = Json_getFloat(keyMap, "time", 0);
for (frame = 0, bezier = 0;; frame++) {
for (frame = 0, bezier = 0;; ++frame) {
Json *vertices = Json_getItem(keyMap, "vertices");
float *deform;
float time2;
@ -755,12 +789,9 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
drawOrder[ii] = -1;
for (offsetMap = offsets->child; offsetMap; offsetMap = offsetMap->next) {
int slotIndex = spSkeletonData_findSlotIndex(skeletonData, Json_getString(offsetMap, "slot", 0));
if (slotIndex == -1) {
cleanUpTimelines(timelines);
_spSkeletonJson_setError(self, 0, "Slot not found: ", Json_getString(offsetMap, "slot", 0));
return 0;
}
int slotIndex = findSlotIndex(skeletonData, Json_getString(offsetMap, "slot", 0), timelines);
if (slotIndex == -1) return NULL;
/* Collect unchanged items. */
while (originalIndex != slotIndex)
unchanged[unchangedIndex++] = originalIndex++;
@ -793,7 +824,7 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
if (!eventData) {
cleanUpTimelines(timelines);
_spSkeletonJson_setError(self, 0, "Event not found: ", Json_getString(keyMap, "name", 0));
return 0;
return NULL;
}
event = spEvent_create(Json_getFloat(keyMap, "time", 0), eventData);
event->intValue = Json_getInt(keyMap, "int", eventData->intValue);
@ -810,9 +841,8 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
}
duration = 0;
for (i = 0, n = timelines->size; i < n; i++) {
for (i = 0, n = timelines->size; i < n; ++i)
duration = MAX(duration, spTimeline_getDuration(timelines->items[i]));
}
return spAnimation_create(root->name, timelines, duration);
}
@ -874,7 +904,7 @@ spSkeletonData *spSkeletonJson_readSkeletonDataFile(spSkeletonJson *self, const
const char *json = _spUtil_readFile(path, &length);
if (length == 0 || !json) {
_spSkeletonJson_setError(self, 0, "Unable to read skeleton file: ", path);
return 0;
return NULL;
}
skeletonData = spSkeletonJson_readSkeletonData(self, json);
FREE(json);
@ -892,10 +922,9 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
internal->linkedMeshCount = 0;
root = Json_create(json);
if (!root) {
_spSkeletonJson_setError(self, 0, "Invalid skeleton JSON: ", Json_getError());
return 0;
return NULL;
}
skeletonData = spSkeletonData_create();
@ -930,7 +959,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!parent) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Parent bone not found: ", parentName);
return 0;
return NULL;
}
}
@ -980,7 +1009,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!boneData) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Slot bone not found: ", boneName);
return 0;
return NULL;
}
data = spSlotData_create(i, Json_getString(slotMap, "name", 0), boneData);
@ -1042,7 +1071,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!data->bones[ii]) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "IK bone not found: ", boneMap->valueString);
return 0;
return NULL;
}
}
@ -1051,7 +1080,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!data->target) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Target bone not found: ", targetName);
return 0;
return NULL;
}
data->bendDirection = Json_getInt(constraintMap, "bendPositive", 1) ? 1 : -1;
@ -1087,7 +1116,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!data->bones[ii]) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Transform bone not found: ", boneMap->valueString);
return 0;
return NULL;
}
}
@ -1096,7 +1125,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!data->target) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Target bone not found: ", name);
return 0;
return NULL;
}
data->local = Json_getInt(constraintMap, "local", 0);
@ -1140,7 +1169,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!data->bones[ii]) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Path bone not found: ", boneMap->valueString);
return 0;
return NULL;
}
}
@ -1149,7 +1178,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!data->target) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Target slot not found: ", name);
return 0;
return NULL;
}
item = Json_getString(constraintMap, "positionMode", "percent");
@ -1203,7 +1232,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!bone) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Skin bone constraint not found: ", skinPart->valueString);
return 0;
return NULL;
}
spBoneDataArray_add(skin->bones, bone);
}
@ -1217,7 +1246,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!constraint) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Skin IK constraint not found: ", skinPart->valueString);
return 0;
return NULL;
}
spIkConstraintDataArray_add(skin->ikConstraints, constraint);
}
@ -1231,7 +1260,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
if (!constraint) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Skin path constraint not found: ", skinPart->valueString);
return 0;
return NULL;
}
spPathConstraintDataArray_add(skin->pathConstraints, constraint);
}
@ -1246,7 +1275,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Skin transform constraint not found: ",
skinPart->valueString);
return 0;
return NULL;
}
spTransformConstraintDataArray_add(skin->transformConstraints, constraint);
}
@ -1288,7 +1317,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
else {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Unknown attachment type: ", typeString);
return 0;
return NULL;
}
attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, attachmentName,
@ -1298,7 +1327,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, self->attachmentLoader->error1,
self->attachmentLoader->error2);
return 0;
return NULL;
}
continue;
}
@ -1471,20 +1500,20 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
}
/* Linked meshes. */
for (i = 0; i < internal->linkedMeshCount; i++) {
for (i = 0; i < internal->linkedMeshCount; ++i) {
spAttachment *parent;
_spLinkedMesh *linkedMesh = internal->linkedMeshes + i;
spSkin *skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData, linkedMesh->skin);
if (!skin) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, 0, "Skin not found: ", linkedMesh->skin);
return 0;
return NULL;
}
parent = spSkin_getAttachment(skin, linkedMesh->slotIndex, linkedMesh->parent);
if (!parent) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, 0, "Parent mesh not found: ", linkedMesh->parent);
return 0;
return NULL;
}
linkedMesh->mesh->super.deformAttachment = linkedMesh->inheritDeform ? SUB_CAST(spVertexAttachment, parent)
: SUB_CAST(spVertexAttachment,
@ -1527,7 +1556,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
spAnimation *animation = _spSkeletonJson_readAnimation(self, animationMap, skeletonData);
if (!animation) {
spSkeletonData_dispose(skeletonData);
return 0;
return NULL;
}
skeletonData->animations[skeletonData->animationsCount++] = animation;
}

View File

@ -139,15 +139,9 @@ namespace spine {
/// @return May be NULL.
Bone *findBone(const String &boneName);
/// @return -1 if the bone was not found.
int findBoneIndex(const String &boneName);
/// @return May be NULL.
Slot *findSlot(const String &slotName);
/// @return -1 if the bone was not found.
int findSlotIndex(const String &slotName);
/// Sets a skin by name (see setSkin).
void setSkin(const String &skinName);

View File

@ -68,15 +68,9 @@ namespace spine {
/// @return May be NULL.
BoneData *findBone(const String &boneName);
/// @return -1 if the bone was not found.
int findBoneIndex(const String &boneName);
/// @return May be NULL.
SlotData *findSlot(const String &slotName);
/// @return -1 if the slot was not found.
int findSlotIndex(const String &slotName);
/// @return May be NULL.
Skin *findSkin(const String &skinName);
@ -95,9 +89,6 @@ namespace spine {
/// @return May be NULL.
PathConstraintData *findPathConstraint(const String &constraintName);
/// @return -1 if the path constraint was not found.
int findPathConstraintIndex(const String &pathConstraintName);
const String &getName();
void setName(const String &inValue);

View File

@ -130,12 +130,12 @@ namespace spine {
void removeAttachment(size_t slotIndex, const String &name);
/// Finds the skin keys for a given slot. The results are added to the passed array of names.
/// @param slotIndex The target slotIndex. To find the slot index, use Skeleton::findSlotIndex or SkeletonData::findSlotIndex
/// @param slotIndex The target slotIndex. To find the slot index, use SkeletonData::findSlot and SlotData::getIndex.
/// @param names Found skin key names will be added to this array.
void findNamesForSlot(size_t slotIndex, Vector <String> &names);
/// Finds the attachments for a given slot. The results are added to the passed array of Attachments.
/// @param slotIndex The target slotIndex. To find the slot index, use Skeleton::findSlotIndex or SkeletonData::findSlotIndex
/// @param slotIndex The target slotIndex. To find the slot index, use SkeletonData::findSlot and SlotData::getIndex.
/// @param attachments Found Attachments will be added to this array.
void findAttachmentsForSlot(size_t slotIndex, Vector<Attachment *> &attachments);

View File

@ -314,18 +314,10 @@ Bone *Skeleton::findBone(const String &boneName) {
return ContainerUtil::findWithDataName(_bones, boneName);
}
int Skeleton::findBoneIndex(const String &boneName) {
return ContainerUtil::findIndexWithDataName(_bones, boneName);
}
Slot *Skeleton::findSlot(const String &slotName) {
return ContainerUtil::findWithDataName(_slots, slotName);
}
int Skeleton::findSlotIndex(const String &slotName) {
return ContainerUtil::findIndexWithDataName(_slots, slotName);
}
void Skeleton::setSkin(const String &skinName) {
Skin *foundSkin = skinName.isEmpty() ? NULL : _data->findSkin(skinName);
setSkin(foundSkin);
@ -357,7 +349,7 @@ void Skeleton::setSkin(Skin *newSkin) {
}
Attachment *Skeleton::getAttachment(const String &slotName, const String &attachmentName) {
return getAttachment(_data->findSlotIndex(slotName), attachmentName);
return getAttachment(_data->findSlot(slotName)->index, attachmentName);
}
Attachment *Skeleton::getAttachment(int slotIndex, const String &attachmentName) {

View File

@ -79,18 +79,10 @@ BoneData *SkeletonData::findBone(const String &boneName) {
return ContainerUtil::findWithName(_bones, boneName);
}
int SkeletonData::findBoneIndex(const String &boneName) {
return ContainerUtil::findIndexWithName(_bones, boneName);
}
SlotData *SkeletonData::findSlot(const String &slotName) {
return ContainerUtil::findWithName(_slots, slotName);
}
int SkeletonData::findSlotIndex(const String &slotName) {
return ContainerUtil::findIndexWithName(_slots, slotName);
}
Skin *SkeletonData::findSkin(const String &skinName) {
return ContainerUtil::findWithName(_skins, skinName);
}
@ -115,10 +107,6 @@ PathConstraintData *SkeletonData::findPathConstraint(const String &constraintNam
return ContainerUtil::findWithName(_pathConstraints, constraintName);
}
int SkeletonData::findPathConstraintIndex(const String &pathConstraintName) {
return ContainerUtil::findIndexWithName(_pathConstraints, pathConstraintName);
}
const String &SkeletonData::getName() {
return _name;
}

View File

@ -849,6 +849,15 @@ Timeline *SkeletonJson::readTimeline(Json *keyMap, CurveTimeline2 *timeline, con
return timeline;
}
int SkeletonJson::findSlotIndex(const SkeletonData *skeletonData, const String &slotName, Vector<Timeline *> timelines) {
int slotIndex = ContainerUtil::findIndexWithName(skeletonData->_slots, slotName);
if (slotIndex == -1) {
ContainerUtil::cleanUpVectorOfPointers(timelines);
setError(NULL, "Slot not found: ", slotName);
}
return slotIndex;
}
Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
Vector<Timeline *> timelines;
Json *bones = Json::getItem(root, "bones");
@ -865,17 +874,13 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
/** Slot timelines. */
for (slotMap = slots ? slots->_child : 0; slotMap; slotMap = slotMap->_next) {
int slotIndex = skeletonData->findSlotIndex(slotMap->_name);
if (slotIndex == -1) {
ContainerUtil::cleanUpVectorOfPointers(timelines);
setError(NULL, "Slot not found: ", slotMap->_name);
return NULL;
}
int slotIndex = findSlotIndex(skeletonData, slotMap->_name, timelines);
if (slotIndex == -1) return NULL;
for (Json *timelineMap = slotMap->_child; timelineMap; timelineMap = timelineMap->_next) {
int frames = timelineMap->_size;
if (strcmp(timelineMap->_name, "attachment") == 0) {
int frameCount = timelineMap->_size;
AttachmentTimeline *timeline = new (__FILE__, __LINE__) AttachmentTimeline(frameCount, slotIndex);
AttachmentTimeline *timeline = new (__FILE__, __LINE__) AttachmentTimeline(frames, slotIndex);
for (keyMap = timelineMap->_child, frame = 0; keyMap; keyMap = keyMap->_next, ++frame) {
timeline->setFrame(frame, Json::getFloat(keyMap, "time", 0),
Json::getItem(keyMap, "name")->_valueString);
@ -883,9 +888,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
timelines.add(timeline);
} else if (strcmp(timelineMap->_name, "rgba") == 0) {
int frameCount = timelineMap->_size;
int bezierCount = frameCount << 2;
RGBATimeline *timeline = new (__FILE__, __LINE__) RGBATimeline(frameCount, bezierCount, slotIndex);
RGBATimeline *timeline = new (__FILE__, __LINE__) RGBATimeline(frames, frames << 2, slotIndex);
keyMap = timelineMap->_child;
float time = Json::getFloat(keyMap, "time", 0);
toColor(color, Json::getString(keyMap, "color", 0), true);
@ -912,9 +915,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
}
timelines.add(timeline);
} else if (strcmp(timelineMap->_name, "rgb") == 0) {
int frameCount = timelineMap->_size;
int bezierCount = frameCount * 3;
RGBTimeline *timeline = new (__FILE__, __LINE__) RGBTimeline(frameCount, bezierCount, slotIndex);
RGBTimeline *timeline = new (__FILE__, __LINE__) RGBTimeline(frames, frames * 3, slotIndex);
keyMap = timelineMap->_child;
float time = Json::getFloat(keyMap, "time", 0);
toColor(color, Json::getString(keyMap, "color", 0), false);
@ -941,13 +942,10 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
timelines.add(timeline);
} else if (strcmp(timelineMap->_name, "alpha") == 0) {
timelines.add(readTimeline(timelineMap->_child,
new (__FILE__, __LINE__) AlphaTimeline(timelineMap->_size, timelineMap->_size,
slotIndex),
new (__FILE__, __LINE__) AlphaTimeline(frames, frames, slotIndex),
0, 1));
} else if (strcmp(timelineMap->_name, "rgba2") == 0) {
int frameCount = timelineMap->_size;
int bezierCount = frameCount * 7;
RGBA2Timeline *timeline = new (__FILE__, __LINE__) RGBA2Timeline(frameCount, bezierCount, slotIndex);
RGBA2Timeline *timeline = new (__FILE__, __LINE__) RGBA2Timeline(frames, frames * 7, slotIndex);
keyMap = timelineMap->_child;
float time = Json::getFloat(keyMap, "time", 0);
toColor(color, Json::getString(keyMap, "light", 0), true);
@ -980,9 +978,7 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
}
timelines.add(timeline);
} else if (strcmp(timelineMap->_name, "rgb2") == 0) {
int frameCount = timelineMap->_size;
int bezierCount = frameCount * 7;
RGBA2Timeline *timeline = new (__FILE__, __LINE__) RGBA2Timeline(frameCount, bezierCount, slotIndex);
RGBA2Timeline *timeline = new (__FILE__, __LINE__) RGBA2Timeline(frames, frames * 6, slotIndex);
keyMap = timelineMap->_child;
float time = Json::getFloat(keyMap, "time", 0);
toColor(color, Json::getString(keyMap, "light", 0), false);
@ -1023,57 +1019,56 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
/** Bone timelines. */
for (boneMap = bones ? bones->_child : 0; boneMap; boneMap = boneMap->_next) {
Json *timelineMap;
int boneIndex = skeletonData->findBoneIndex(boneMap->_name);
int boneIndex = ContainerUtil::findIndexWithName(skeletonData->_bones, boneMap->_name);
if (boneIndex == -1) {
ContainerUtil::cleanUpVectorOfPointers(timelines);
setError(NULL, "Bone not found: ", boneMap->_name);
return NULL;
}
for (timelineMap = boneMap->_child; timelineMap; timelineMap = timelineMap->_next) {
if (timelineMap->_size == 0) continue;
for (Json *timelineMap = boneMap->_child; timelineMap; timelineMap = timelineMap->_next) {
int frames = timelineMap->_size;
if (frames == 0) continue;
if (strcmp(timelineMap->_name, "rotate") == 0) {
timelines.add(readTimeline(timelineMap->_child,
new RotateTimeline(timelineMap->_size, timelineMap->_size, boneIndex), 0,
new RotateTimeline(frames, frames, boneIndex), 0,
1));
} else if (strcmp(timelineMap->_name, "translate") == 0) {
TranslateTimeline *timeline = new TranslateTimeline(timelineMap->_size, timelineMap->_size << 1,
TranslateTimeline *timeline = new TranslateTimeline(frames, frames << 1,
boneIndex);
timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 0, _scale));
} else if (strcmp(timelineMap->_name, "translatex") == 0) {
TranslateXTimeline *timeline = new TranslateXTimeline(timelineMap->_size, timelineMap->_size,
TranslateXTimeline *timeline = new TranslateXTimeline(frames, frames,
boneIndex);
timelines.add(readTimeline(timelineMap->_child, timeline, 0, _scale));
} else if (strcmp(timelineMap->_name, "translatey") == 0) {
TranslateYTimeline *timeline = new TranslateYTimeline(timelineMap->_size, timelineMap->_size,
TranslateYTimeline *timeline = new TranslateYTimeline(frames, frames,
boneIndex);
timelines.add(readTimeline(timelineMap->_child, timeline, 0, _scale));
} else if (strcmp(timelineMap->_name, "scale") == 0) {
ScaleTimeline *timeline = new (__FILE__, __LINE__) ScaleTimeline(timelineMap->_size,
timelineMap->_size << 1, boneIndex);
ScaleTimeline *timeline = new (__FILE__, __LINE__) ScaleTimeline(frames,
frames << 1, boneIndex);
timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 1, 1));
} else if (strcmp(timelineMap->_name, "scalex") == 0) {
ScaleXTimeline *timeline = new (__FILE__, __LINE__) ScaleXTimeline(timelineMap->_size,
timelineMap->_size, boneIndex);
ScaleXTimeline *timeline = new (__FILE__, __LINE__) ScaleXTimeline(frames,
frames, boneIndex);
timelines.add(readTimeline(timelineMap->_child, timeline, 1, 1));
} else if (strcmp(timelineMap->_name, "scaley") == 0) {
ScaleYTimeline *timeline = new (__FILE__, __LINE__) ScaleYTimeline(timelineMap->_size,
timelineMap->_size, boneIndex);
ScaleYTimeline *timeline = new (__FILE__, __LINE__) ScaleYTimeline(frames,
frames, boneIndex);
timelines.add(readTimeline(timelineMap->_child, timeline, 1, 1));
} else if (strcmp(timelineMap->_name, "shear") == 0) {
ShearTimeline *timeline = new (__FILE__, __LINE__) ShearTimeline(timelineMap->_size,
timelineMap->_size << 1, boneIndex);
ShearTimeline *timeline = new (__FILE__, __LINE__) ShearTimeline(frames,
frames << 1, boneIndex);
timelines.add(readTimeline(timelineMap->_child, timeline, "x", "y", 0, 1));
} else if (strcmp(timelineMap->_name, "shearx") == 0) {
ShearXTimeline *timeline = new (__FILE__, __LINE__) ShearXTimeline(timelineMap->_size,
timelineMap->_size, boneIndex);
ShearXTimeline *timeline = new (__FILE__, __LINE__) ShearXTimeline(frames,
frames, boneIndex);
timelines.add(readTimeline(timelineMap->_child, timeline, 0, 1));
} else if (strcmp(timelineMap->_name, "sheary") == 0) {
ShearYTimeline *timeline = new (__FILE__, __LINE__) ShearYTimeline(timelineMap->_size,
timelineMap->_size, boneIndex);
ShearYTimeline *timeline = new (__FILE__, __LINE__) ShearYTimeline(frames,
frames, boneIndex);
timelines.add(readTimeline(timelineMap->_child, timeline, 0, 1));
} else {
ContainerUtil::cleanUpVectorOfPointers(timelines);
@ -1184,33 +1179,34 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
/** Path constraint timelines. */
for (constraintMap = paths ? paths->_child : 0; constraintMap; constraintMap = constraintMap->_next) {
PathConstraintData *data = skeletonData->findPathConstraint(constraintMap->_name);
if (!data) {
PathConstraintData *constraint = skeletonData->findPathConstraint(constraintMap->_name);
if (!constraint) {
ContainerUtil::cleanUpVectorOfPointers(timelines);
setError(NULL, "Path constraint not found: ", constraintMap->_name);
return NULL;
}
int index = skeletonData->_pathConstraints.indexOf(data);
int constraintIndex = skeletonData->_pathConstraints.indexOf(constraint);
for (Json *timelineMap = constraintMap->_child; timelineMap; timelineMap = timelineMap->_next) {
keyMap = timelineMap->_child;
if (keyMap == NULL) continue;
const char *timelineName = timelineMap->_name;
int frames = timelineMap->_size;
if (strcmp(timelineName, "position") == 0) {
PathConstraintPositionTimeline *timeline = new (__FILE__, __LINE__) PathConstraintPositionTimeline(
timelineMap->_size, timelineMap->_size, index);
frames, frames, constraintIndex);
timelines.add(
readTimeline(keyMap, timeline, 0, data->_positionMode == PositionMode_Fixed ? _scale : 1));
readTimeline(keyMap, timeline, 0, constraint->_positionMode == PositionMode_Fixed ? _scale : 1));
} else if (strcmp(timelineName, "spacing") == 0) {
CurveTimeline1 *timeline = new PathConstraintSpacingTimeline(timelineMap->_size, timelineMap->_size,
index);
CurveTimeline1 *timeline = new PathConstraintSpacingTimeline(frames, frames,
constraintIndex);
timelines.add(readTimeline(keyMap, timeline, 0,
data->_spacingMode == SpacingMode_Length ||
data->_spacingMode == SpacingMode_Fixed
constraint->_spacingMode == SpacingMode_Length ||
constraint->_spacingMode == SpacingMode_Fixed
? _scale
: 1));
} else if (strcmp(timelineName, "mix") == 0) {
PathConstraintMixTimeline *timeline = new PathConstraintMixTimeline(timelineMap->_size,
timelineMap->_size * 3, index);
PathConstraintMixTimeline *timeline = new PathConstraintMixTimeline(frames,
frames * 3, constraintIndex);
float time = Json::getFloat(keyMap, "time", 0);
float mixRotate = Json::getFloat(keyMap, "mixRotate", 1);
float mixX = Json::getFloat(keyMap, "mixX", 1);
@ -1247,9 +1243,10 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
for (constraintMap = deform ? deform->_child : NULL; constraintMap; constraintMap = constraintMap->_next) {
Skin *skin = skeletonData->findSkin(constraintMap->_name);
for (slotMap = constraintMap->_child; slotMap; slotMap = slotMap->_next) {
int slotIndex = skeletonData->findSlotIndex(slotMap->_name);
Json *timelineMap;
for (timelineMap = slotMap->_child; timelineMap; timelineMap = timelineMap->_next) {
int slotIndex = findSlotIndex(skeletonData, slotMap->_name, timelines);
if (slotIndex == -1) return NULL;
for (Json *timelineMap = slotMap->_child; timelineMap; timelineMap = timelineMap->_next) {
keyMap = timelineMap->_child;
if (keyMap == NULL) continue;
@ -1338,12 +1335,9 @@ Animation *SkeletonJson::readAnimation(Json *root, SkeletonData *skeletonData) {
drawOrder2[ii] = -1;
for (offsetMap = offsets->_child; offsetMap; offsetMap = offsetMap->_next) {
int slotIndex = skeletonData->findSlotIndex(Json::getString(offsetMap, "slot", 0));
if (slotIndex == -1) {
ContainerUtil::cleanUpVectorOfPointers(timelines);
setError(NULL, "Slot not found: ", Json::getString(offsetMap, "slot", 0));
return NULL;
}
int slotIndex = findSlotIndex(skeletonData, Json::getString(offsetMap, "slot", 0), timelines);
if (slotIndex == -1) return NULL;
/* Collect unchanged items. */
while (originalIndex != (size_t) slotIndex)
unchanged[unchangedIndex++] = originalIndex++;

View File

@ -428,16 +428,6 @@ namespace Spine {
return null;
}
/// <returns>-1 if the bone was not found.</returns>
public int FindBoneIndex (string boneName) {
if (boneName == null) throw new ArgumentNullException("boneName", "boneName cannot be null.");
var bones = this.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;
}
/// <summary>Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
/// repeatedly.</summary>
/// <returns>May be null.</returns>
@ -451,16 +441,6 @@ namespace Spine {
return null;
}
/// <returns>-1 if the bone was not found.</returns>
public int FindSlotIndex (string slotName) {
if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null.");
var slots = this.slots;
var slotsItems = slots.Items;
for (int i = 0, n = slots.Count; i < n; i++)
if (slotsItems[i].data.name == slotName) return i;
return -1;
}
/// <summary>Sets a skin by name (<see cref="SetSkin(Skin)"/>).</summary>
public void SetSkin (string skinName) {
Skin foundSkin = data.FindSkin(skinName);
@ -505,7 +485,7 @@ namespace Spine {
/// <summary>Finds an attachment by looking in the <see cref="Skeleton.Skin"/> and <see cref="SkeletonData.DefaultSkin"/> using the slot name and attachment name.</summary>
/// <returns>May be null.</returns>
public Attachment GetAttachment (string slotName, string attachmentName) {
return GetAttachment(data.FindSlotIndex(slotName), attachmentName);
return GetAttachment(data.FindSlot(slotName).index, attachmentName);
}
/// <summary>Finds an attachment by looking in the skin and skeletonData.defaultSkin using the slot index and attachment name.First the skin is checked and if the attachment was not found, the default skin is checked.</summary>

View File

@ -111,15 +111,6 @@ namespace Spine {
return null;
}
/// <returns>-1 if the bone was not found.</returns>
public int FindBoneIndex (string boneName) {
if (boneName == null) throw new ArgumentNullException("boneName", "boneName cannot be null.");
var bones = this.bones.Items;
for (int i = 0, n = this.bones.Count; i < n; i++)
if (bones[i].name == boneName) return i;
return -1;
}
// --- Slots.
/// <returns>May be null.</returns>
@ -133,15 +124,6 @@ namespace Spine {
return null;
}
/// <returns>-1 if the slot was not found.</returns>
public int FindSlotIndex (string slotName) {
if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null.");
SlotData[] slots = this.slots.Items;
for (int i = 0, n = this.slots.Count; i < n; i++)
if (slots[i].name == slotName) return i;
return -1;
}
// --- Skins.
/// <returns>May be null.</returns>
@ -214,15 +196,6 @@ namespace Spine {
return null;
}
/// <returns>-1 if the path constraint was not found.</returns>
public int FindPathConstraintIndex (string pathConstraintName) {
if (pathConstraintName == null) throw new ArgumentNullException("pathConstraintName", "pathConstraintName cannot be null.");
PathConstraintData[] pathConstraints = this.pathConstraints.Items;
for (int i = 0, n = this.pathConstraints.Count; i < n; i++)
if (pathConstraints[i].name.Equals(pathConstraintName)) return i;
return -1;
}
// ---
override public string ToString () {

View File

@ -313,7 +313,7 @@ namespace Spine {
skin.constraints.TrimExcess();
if (skinMap.ContainsKey("attachments")) {
foreach (KeyValuePair<string, Object> slotEntry in (Dictionary<string, Object>)skinMap["attachments"]) {
int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
int slotIndex = FindSlotIndex(skeletonData, slotEntry.Key);
foreach (KeyValuePair<string, Object> entry in ((Dictionary<string, Object>)slotEntry.Value)) {
try {
Attachment attachment = ReadAttachment((Dictionary<string, Object>)entry.Value, skin, slotIndex, entry.Key, skeletonData);
@ -523,6 +523,13 @@ namespace Spine {
attachment.vertices = weights.ToArray();
}
private int FindSlotIndex (SkeletonData skeletonData, string slotName) {
SlotData[] slots = skeletonData.slots.Items;
for (int i = 0, n = skeletonData.slots.Count; i < n; i++)
if (slots[i].name == slotName) return i;
throw new Exception("Slot not found: " + slotName);
}
private void ReadAnimation (Dictionary<string, Object> map, string name, SkeletonData skeletonData) {
var scale = this.scale;
var timelines = new ExposedList<Timeline>();
@ -531,14 +538,15 @@ namespace Spine {
if (map.ContainsKey("slots")) {
foreach (KeyValuePair<string, Object> entry in (Dictionary<string, Object>)map["slots"]) {
string slotName = entry.Key;
int slotIndex = skeletonData.FindSlotIndex(slotName);
int slotIndex = FindSlotIndex(skeletonData, slotName);
var timelineMap = (Dictionary<string, Object>)entry.Value;
foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
var values = (List<Object>)timelineEntry.Value;
if (values.Count == 0) continue;
int frames = values.Count;
if (frames == 0) continue;
var timelineName = (string)timelineEntry.Key;
if (timelineName == "attachment") {
var timeline = new AttachmentTimeline(values.Count, slotIndex);
var timeline = new AttachmentTimeline(frames, slotIndex);
int frame = 0;
foreach (Dictionary<string, Object> keyMap in values) {
timeline.SetFrame(frame++, GetFloat(keyMap, "time", 0), (string)keyMap["name"]);
@ -546,7 +554,7 @@ namespace Spine {
timelines.Add(timeline);
} else if (timelineName == "rgba") {
var timeline = new RGBATimeline(values.Count, values.Count << 2, slotIndex);
var timeline = new RGBATimeline(frames, frames << 2, slotIndex);
var keyMapEnumerator = values.GetEnumerator();
keyMapEnumerator.MoveNext();
@ -589,7 +597,7 @@ namespace Spine {
timelines.Add(timeline);
} else if (timelineName == "rgb") {
var timeline = new RGBTimeline(values.Count, values.Count * 3, slotIndex);
var timeline = new RGBTimeline(frames, frames * 3, slotIndex);
var keyMapEnumerator = values.GetEnumerator();
keyMapEnumerator.MoveNext();
@ -630,10 +638,10 @@ namespace Spine {
} else if (timelineName == "alpha") {
var keyMapEnumerator = values.GetEnumerator();
keyMapEnumerator.MoveNext();
timelines.Add(ReadTimeline(ref keyMapEnumerator, new AlphaTimeline(values.Count, values.Count, slotIndex), 0, 1));
timelines.Add(ReadTimeline(ref keyMapEnumerator, new AlphaTimeline(frames, frames, slotIndex), 0, 1));
} else if (timelineName == "rgba2") {
var timeline = new RGBA2Timeline(values.Count, values.Count * 7, slotIndex);
var timeline = new RGBA2Timeline(frames, frames * 7, slotIndex);
var keyMapEnumerator = values.GetEnumerator();
keyMapEnumerator.MoveNext();
@ -690,7 +698,7 @@ namespace Spine {
timelines.Add(timeline);
} else if (timelineName == "rgb2") {
var timeline = new RGB2Timeline(values.Count, values.Count * 6, slotIndex);
var timeline = new RGB2Timeline(frames, frames * 6, slotIndex);
var keyMapEnumerator = values.GetEnumerator();
keyMapEnumerator.MoveNext();
@ -752,39 +760,47 @@ namespace Spine {
if (map.ContainsKey("bones")) {
foreach (KeyValuePair<string, Object> entry in (Dictionary<string, Object>)map["bones"]) {
string boneName = entry.Key;
int boneIndex = skeletonData.FindBoneIndex(boneName);
int boneIndex = -1;
var bones = skeletonData.bones.Items;
for (int i = 0, n = skeletonData.bones.Count; i < n; i++) {
if (bones[i].name == boneName) {
boneIndex = i;
break;
}
}
if (boneIndex == -1) throw new Exception("Bone not found: " + boneName);
var timelineMap = (Dictionary<string, Object>)entry.Value;
foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
var values = (List<Object>)timelineEntry.Value;
var keyMapEnumerator = values.GetEnumerator();
if (!keyMapEnumerator.MoveNext()) continue;
int frames = values.Count;
var timelineName = (string)timelineEntry.Key;
if (timelineName == "rotate")
timelines.Add(ReadTimeline(ref keyMapEnumerator, new RotateTimeline(values.Count, values.Count, boneIndex), 0, 1));
timelines.Add(ReadTimeline(ref keyMapEnumerator, new RotateTimeline(frames, frames, boneIndex), 0, 1));
else if (timelineName == "translate") {
TranslateTimeline timeline = new TranslateTimeline(values.Count, values.Count << 1, boneIndex);
TranslateTimeline timeline = new TranslateTimeline(frames, frames << 1, boneIndex);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 0, scale));
} else if (timelineName == "translatex") {
timelines
.Add(ReadTimeline(ref keyMapEnumerator, new TranslateXTimeline(values.Count, values.Count, boneIndex), 0, scale));
.Add(ReadTimeline(ref keyMapEnumerator, new TranslateXTimeline(frames, frames, boneIndex), 0, scale));
} else if (timelineName == "translatey") {
timelines
.Add(ReadTimeline(ref keyMapEnumerator, new TranslateYTimeline(values.Count, values.Count, boneIndex), 0, scale));
.Add(ReadTimeline(ref keyMapEnumerator, new TranslateYTimeline(frames, frames, boneIndex), 0, scale));
} else if (timelineName == "scale") {
ScaleTimeline timeline = new ScaleTimeline(values.Count, values.Count << 1, boneIndex);
ScaleTimeline timeline = new ScaleTimeline(frames, frames << 1, boneIndex);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 1, 1));
} else if (timelineName == "scalex")
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ScaleXTimeline(values.Count, values.Count, boneIndex), 1, 1));
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ScaleXTimeline(frames, frames, boneIndex), 1, 1));
else if (timelineName == "scaley")
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ScaleYTimeline(values.Count, values.Count, boneIndex), 1, 1));
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ScaleYTimeline(frames, frames, boneIndex), 1, 1));
else if (timelineName == "shear") {
ShearTimeline timeline = new ShearTimeline(values.Count, values.Count << 1, boneIndex);
ShearTimeline timeline = new ShearTimeline(frames, frames << 1, boneIndex);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 0, 1));
} else if (timelineName == "shearx")
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearXTimeline(values.Count, values.Count, boneIndex), 0, 1));
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearXTimeline(frames, frames, boneIndex), 0, 1));
else if (timelineName == "sheary")
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearYTimeline(values.Count, values.Count, boneIndex), 0, 1));
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearYTimeline(frames, frames, boneIndex), 0, 1));
else
throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
}
@ -794,12 +810,12 @@ namespace Spine {
// IK constraint timelines.
if (map.ContainsKey("ik")) {
foreach (KeyValuePair<string, Object> timelineMap in (Dictionary<string, Object>)map["ik"]) {
var timelineMapValues = (List<Object>)timelineMap.Value;
var keyMapEnumerator = timelineMapValues.GetEnumerator();
var values = (List<Object>)timelineMap.Value;
var keyMapEnumerator = values.GetEnumerator();
if (!keyMapEnumerator.MoveNext()) continue;
var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
IkConstraintData constraint = skeletonData.FindIkConstraint(timelineMap.Key);
IkConstraintTimeline timeline = new IkConstraintTimeline(timelineMapValues.Count, timelineMapValues.Count << 1,
IkConstraintTimeline timeline = new IkConstraintTimeline(values.Count, values.Count << 1,
skeletonData.IkConstraints.IndexOf(constraint));
float time = GetFloat(keyMap, "time", 0);
float mix = GetFloat(keyMap, "mix", 1), softness = GetFloat(keyMap, "softness", 0) * scale;
@ -830,12 +846,12 @@ namespace Spine {
// Transform constraint timelines.
if (map.ContainsKey("transform")) {
foreach (KeyValuePair<string, Object> timelineMap in (Dictionary<string, Object>)map["transform"]) {
var timelineMapValues = (List<Object>)timelineMap.Value;
var keyMapEnumerator = timelineMapValues.GetEnumerator();
var values = (List<Object>)timelineMap.Value;
var keyMapEnumerator = values.GetEnumerator();
if (!keyMapEnumerator.MoveNext()) continue;
var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
TransformConstraintData constraint = skeletonData.FindTransformConstraint(timelineMap.Key);
TransformConstraintTimeline timeline = new TransformConstraintTimeline(timelineMapValues.Count, timelineMapValues.Count << 2,
TransformConstraintTimeline timeline = new TransformConstraintTimeline(values.Count, values.Count * 6,
skeletonData.TransformConstraints.IndexOf(constraint));
float time = GetFloat(keyMap, "time", 0);
float mixRotate = GetFloat(keyMap, "mixRotate", 1), mixShearY = GetFloat(keyMap, "mixShearY", 1);
@ -877,24 +893,26 @@ namespace Spine {
// Path constraint timelines.
if (map.ContainsKey("path")) {
foreach (KeyValuePair<string, Object> constraintMap in (Dictionary<string, Object>)map["path"]) {
int index = skeletonData.FindPathConstraintIndex(constraintMap.Key);
if (index == -1) throw new Exception("Path constraint not found: " + constraintMap.Key);
PathConstraintData data = skeletonData.pathConstraints.Items[index];
PathConstraintData constraint = skeletonData.FindPathConstraint(constraintMap.Key);
if (constraint == null) throw new Exception("Path constraint not found: " + constraintMap.Key);
int constraintIndex = skeletonData.pathConstraints.IndexOf(constraint);
var timelineMap = (Dictionary<string, Object>)constraintMap.Value;
foreach (KeyValuePair<string, Object> timelineEntry in timelineMap) {
var values = (List<Object>)timelineEntry.Value;
var keyMapEnumerator = values.GetEnumerator();
if (!keyMapEnumerator.MoveNext()) continue;
int frames = values.Count;
var timelineName = (string)timelineEntry.Key;
if (timelineName == "position") {
CurveTimeline1 timeline = new PathConstraintPositionTimeline(values.Count, values.Count, index);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, 0, data.positionMode == PositionMode.Fixed ? scale : 1));
CurveTimeline1 timeline = new PathConstraintPositionTimeline(frames, frames, constraintIndex);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, 0, constraint.positionMode == PositionMode.Fixed ? scale : 1));
} else if (timelineName == "spacing") {
CurveTimeline1 timeline = new PathConstraintSpacingTimeline(values.Count, values.Count, index);
CurveTimeline1 timeline = new PathConstraintSpacingTimeline(frames, frames, constraintIndex);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, 0,
data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1));
constraint.spacingMode == SpacingMode.Length || constraint.spacingMode == SpacingMode.Fixed ? scale : 1));
} else if (timelineName == "mix") {
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count, values.Count * 3, index);
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frames, frames * 3, constraintIndex);
var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
float time = GetFloat(keyMap, "time", 0);
float mixRotate = GetFloat(keyMap, "mixRotate", 1);
@ -932,11 +950,10 @@ namespace Spine {
foreach (KeyValuePair<string, Object> deformMap in (Dictionary<string, Object>)map["deform"]) {
Skin skin = skeletonData.FindSkin(deformMap.Key);
foreach (KeyValuePair<string, Object> slotMap in (Dictionary<string, Object>)deformMap.Value) {
int slotIndex = skeletonData.FindSlotIndex(slotMap.Key);
if (slotIndex == -1) throw new Exception("Slot not found: " + slotMap.Key);
int slotIndex = FindSlotIndex(skeletonData, slotMap.Key);
foreach (KeyValuePair<string, Object> timelineMap in (Dictionary<string, Object>)slotMap.Value) {
var timelineMapValues = (List<Object>)timelineMap.Value;
var keyMapEnumerator = timelineMapValues.GetEnumerator();
var values = (List<Object>)timelineMap.Value;
var keyMapEnumerator = values.GetEnumerator();
if (!keyMapEnumerator.MoveNext()) continue;
var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, timelineMap.Key);
@ -944,7 +961,7 @@ namespace Spine {
bool weighted = attachment.bones != null;
float[] vertices = attachment.vertices;
int deformLength = weighted ? (vertices.Length / 3) << 1 : vertices.Length;
DeformTimeline timeline = new DeformTimeline(timelineMapValues.Count, timelineMapValues.Count, slotIndex, attachment);
DeformTimeline timeline = new DeformTimeline(values.Count, values.Count, slotIndex, attachment);
float time = GetFloat(keyMap, "time", 0);
for (int frame = 0, bezier = 0; ; frame++) {
float[] deform;
@ -1002,8 +1019,7 @@ namespace Spine {
int[] unchanged = new int[slotCount - offsets.Count];
int originalIndex = 0, unchangedIndex = 0;
foreach (Dictionary<string, Object> offsetMap in offsets) {
int slotIndex = skeletonData.FindSlotIndex((string)offsetMap["slot"]);
if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]);
int slotIndex = FindSlotIndex(skeletonData, (string)offsetMap["slot"]);
// Collect unchanged items.
while (originalIndex != slotIndex)
unchanged[unchangedIndex++] = originalIndex++;

View File

@ -109,7 +109,7 @@ namespace Spine {
}
/// <summary>Returns all attachments in this skin for the specified slot index.</summary>
/// <param name="slotIndex">The target slotIndex. To find the slot index, use <see cref="Spine.Skeleton.FindSlotIndex"/> or <see cref="Spine.SkeletonData.FindSlotIndex"/>
/// <param name="slotIndex">The target slotIndex. To find the slot index, use <see cref="Spine.SkeletonData.FindSlot"/> and <see cref="Spine.SlotData.Index"/>.
public void GetAttachments (int slotIndex, List<SkinEntry> attachments) {
if (slotIndex < 0) throw new ArgumentException("slotIndex must be >= 0.");
if (attachments == null) throw new ArgumentNullException("attachments", "attachments cannot be null.");

View File

@ -510,16 +510,17 @@ public class SkeletonJson extends SkeletonLoader {
for (JsonValue timelineMap = slotMap.child; timelineMap != null; timelineMap = timelineMap.next) {
JsonValue keyMap = timelineMap.child;
if (keyMap == null) continue;
String timelineName = timelineMap.name;
int frames = timelineMap.size;
String timelineName = timelineMap.name;
if (timelineName.equals("attachment")) {
AttachmentTimeline timeline = new AttachmentTimeline(timelineMap.size, slot.index);
AttachmentTimeline timeline = new AttachmentTimeline(frames, slot.index);
for (int frame = 0; keyMap != null; keyMap = keyMap.next, frame++)
timeline.setFrame(frame, keyMap.getFloat("time", 0), keyMap.getString("name"));
timelines.add(timeline);
} else if (timelineName.equals("rgba")) {
RGBATimeline timeline = new RGBATimeline(timelineMap.size, timelineMap.size << 2, slot.index);
RGBATimeline timeline = new RGBATimeline(frames, frames << 2, slot.index);
float time = keyMap.getFloat("time", 0);
String color = keyMap.getString("color");
float r = Integer.parseInt(color.substring(0, 2), 16) / 255f;
@ -556,7 +557,7 @@ public class SkeletonJson extends SkeletonLoader {
timelines.add(timeline);
} else if (timelineName.equals("rgb")) {
RGBTimeline timeline = new RGBTimeline(timelineMap.size, timelineMap.size * 3, slot.index);
RGBTimeline timeline = new RGBTimeline(frames, frames * 3, slot.index);
float time = keyMap.getFloat("time", 0);
String color = keyMap.getString("color");
float r = Integer.parseInt(color.substring(0, 2), 16) / 255f;
@ -589,10 +590,10 @@ public class SkeletonJson extends SkeletonLoader {
timelines.add(timeline);
} else if (timelineName.equals("alpha")) {
timelines.add(readTimeline(keyMap, new AlphaTimeline(timelineMap.size, timelineMap.size, slot.index), 0, 1));
timelines.add(readTimeline(keyMap, new AlphaTimeline(frames, frames, slot.index), 0, 1));
} else if (timelineName.equals("rgba2")) {
RGBA2Timeline timeline = new RGBA2Timeline(timelineMap.size, timelineMap.size * 7, slot.index);
RGBA2Timeline timeline = new RGBA2Timeline(frames, frames * 7, slot.index);
float time = keyMap.getFloat("time", 0);
String color = keyMap.getString("light");
float r = Integer.parseInt(color.substring(0, 2), 16) / 255f;
@ -643,7 +644,7 @@ public class SkeletonJson extends SkeletonLoader {
timelines.add(timeline);
} else if (timelineName.equals("rgb2")) {
RGB2Timeline timeline = new RGB2Timeline(timelineMap.size, timelineMap.size * 6, slot.index);
RGB2Timeline timeline = new RGB2Timeline(frames, frames * 6, slot.index);
float time = keyMap.getFloat("time", 0);
String color = keyMap.getString("light");
float r = Integer.parseInt(color.substring(0, 2), 16) / 255f;
@ -702,32 +703,31 @@ public class SkeletonJson extends SkeletonLoader {
JsonValue keyMap = timelineMap.child;
if (keyMap == null) continue;
int frames = timelineMap.size;
String timelineName = timelineMap.name;
if (timelineName.equals("rotate"))
timelines.add(readTimeline(keyMap, new RotateTimeline(timelineMap.size, timelineMap.size, bone.index), 0, 1));
timelines.add(readTimeline(keyMap, new RotateTimeline(frames, frames, bone.index), 0, 1));
else if (timelineName.equals("translate")) {
TranslateTimeline timeline = new TranslateTimeline(timelineMap.size, timelineMap.size << 1, bone.index);
TranslateTimeline timeline = new TranslateTimeline(frames, frames << 1, bone.index);
timelines.add(readTimeline(keyMap, timeline, "x", "y", 0, scale));
} else if (timelineName.equals("translatex")) {
timelines
.add(readTimeline(keyMap, new TranslateXTimeline(timelineMap.size, timelineMap.size, bone.index), 0, scale));
timelines.add(readTimeline(keyMap, new TranslateXTimeline(frames, frames, bone.index), 0, scale));
} else if (timelineName.equals("translatey")) {
timelines
.add(readTimeline(keyMap, new TranslateYTimeline(timelineMap.size, timelineMap.size, bone.index), 0, scale));
timelines.add(readTimeline(keyMap, new TranslateYTimeline(frames, frames, bone.index), 0, scale));
} else if (timelineName.equals("scale")) {
ScaleTimeline timeline = new ScaleTimeline(timelineMap.size, timelineMap.size << 1, bone.index);
ScaleTimeline timeline = new ScaleTimeline(frames, frames << 1, bone.index);
timelines.add(readTimeline(keyMap, timeline, "x", "y", 1, 1));
} else if (timelineName.equals("scalex"))
timelines.add(readTimeline(keyMap, new ScaleXTimeline(timelineMap.size, timelineMap.size, bone.index), 1, 1));
timelines.add(readTimeline(keyMap, new ScaleXTimeline(frames, frames, bone.index), 1, 1));
else if (timelineName.equals("scaley"))
timelines.add(readTimeline(keyMap, new ScaleYTimeline(timelineMap.size, timelineMap.size, bone.index), 1, 1));
timelines.add(readTimeline(keyMap, new ScaleYTimeline(frames, frames, bone.index), 1, 1));
else if (timelineName.equals("shear")) {
ShearTimeline timeline = new ShearTimeline(timelineMap.size, timelineMap.size << 1, bone.index);
ShearTimeline timeline = new ShearTimeline(frames, frames << 1, bone.index);
timelines.add(readTimeline(keyMap, timeline, "x", "y", 0, 1));
} else if (timelineName.equals("shearx"))
timelines.add(readTimeline(keyMap, new ShearXTimeline(timelineMap.size, timelineMap.size, bone.index), 0, 1));
timelines.add(readTimeline(keyMap, new ShearXTimeline(frames, frames, bone.index), 0, 1));
else if (timelineName.equals("sheary"))
timelines.add(readTimeline(keyMap, new ShearYTimeline(timelineMap.size, timelineMap.size, bone.index), 0, 1));
timelines.add(readTimeline(keyMap, new ShearYTimeline(frames, frames, bone.index), 0, 1));
else
throw new RuntimeException("Invalid timeline type for a bone: " + timelineName + " (" + boneMap.name + ")");
}
@ -770,7 +770,7 @@ public class SkeletonJson extends SkeletonLoader {
JsonValue keyMap = timelineMap.child;
if (keyMap == null) continue;
TransformConstraintData constraint = skeletonData.findTransformConstraint(timelineMap.name);
TransformConstraintTimeline timeline = new TransformConstraintTimeline(timelineMap.size, timelineMap.size << 2,
TransformConstraintTimeline timeline = new TransformConstraintTimeline(timelineMap.size, timelineMap.size * 6,
skeletonData.getTransformConstraints().indexOf(constraint, true));
float time = keyMap.getFloat("time", 0);
float mixRotate = keyMap.getFloat("mixRotate", 1);
@ -818,16 +818,18 @@ public class SkeletonJson extends SkeletonLoader {
for (JsonValue timelineMap = constraintMap.child; timelineMap != null; timelineMap = timelineMap.next) {
JsonValue keyMap = timelineMap.child;
if (keyMap == null) continue;
int frames = timelineMap.size;
String timelineName = timelineMap.name;
if (timelineName.equals("position")) {
CurveTimeline1 timeline = new PathConstraintPositionTimeline(timelineMap.size, timelineMap.size, index);
CurveTimeline1 timeline = new PathConstraintPositionTimeline(frames, frames, index);
timelines.add(readTimeline(keyMap, timeline, 0, constraint.positionMode == PositionMode.fixed ? scale : 1));
} else if (timelineName.equals("spacing")) {
CurveTimeline1 timeline = new PathConstraintSpacingTimeline(timelineMap.size, timelineMap.size, index);
CurveTimeline1 timeline = new PathConstraintSpacingTimeline(frames, frames, index);
timelines.add(readTimeline(keyMap, timeline, 0,
constraint.spacingMode == SpacingMode.length || constraint.spacingMode == SpacingMode.fixed ? scale : 1));
} else if (timelineName.equals("mix")) {
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(timelineMap.size, timelineMap.size * 3, index);
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frames, frames * 3, index);
float time = keyMap.getFloat("time", 0);
float mixRotate = keyMap.getFloat("mixRotate", 1);
float mixX = keyMap.getFloat("mixX", 1), mixY = keyMap.getFloat("mixY", mixX);

View File

@ -400,27 +400,11 @@ function Skeleton:findBone (boneName)
return nil
end
function Skeleton:findBoneIndex(boneName)
if not boneName then error("boneName cannot be nil.", 2) end
for i,bone in ipairs(self.bones) do
if bone.data.name == boneName then return i end
end
return -1
end
function Skeleton:findSlot (slotName)
if not slotName then error("slotName cannot be nil.", 2) end
return self.slotsByName[slotName]
end
function Skeleton:findSlotIndex(slotName)
if not slotName then error("slotName cannot be nil.", 2) end
for i, slot in ipairs(self.slots) do
if slot.data.name == slotName then return i end
end
return -1
end
-- Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}.
-- Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was
-- no old skin, each slot's setup mode attachment is attached from the new skin.

View File

@ -61,14 +61,6 @@ function SkeletonData:findBone (boneName)
return nil
end
function SkeletonData:findBoneIndex (boneName)
if not boneName then error("boneName cannot be nil.", 2) end
for i,bone in ipairs(self.bones) do
if bone.name == boneName then return i end
end
return -1
end
function SkeletonData:findSlot (slotName)
if not slotName then error("slotName cannot be nil.", 2) end
return self.nameToSlot[slotName]

View File

@ -744,8 +744,7 @@ function SkeletonJson.new (attachmentLoader)
local bonesMap = map["bones"]
if bonesMap then
for boneName,boneMap in pairs(bonesMap) do
local boneIndex = skeletonData:findBoneIndex(boneName)
if boneIndex == -1 then error("Bone not found: " .. boneName) end
local boneIndex = skeletonData:findBone(boneName).index
for timelineName,timelineMap in pairs(boneMap) do
if not timelineMap then
elseif timelineName == "rotate" then
@ -847,7 +846,7 @@ function SkeletonJson.new (attachmentLoader)
break
end
end
local timeline = Animation.TransformConstraintTimeline.new(#timelineMap, #timelineMap * 4, constraintIndex)
local timeline = Animation.TransformConstraintTimeline.new(#timelineMap, #timelineMap * 6, constraintIndex)
local time = getValue(keyMap, "time", 0)
local mixRotate = getValue(keyMap, "mixRotate", 0)
local mixX = getValue(keyMap, "mixX", 1)
@ -962,7 +961,6 @@ function SkeletonJson.new (attachmentLoader)
if not skin then error("Skin not found: " .. deformName) end
for slotName,slotMap in pairs(deformMap) do
local slotIndex = skeletonData:findSlot(slotName).index
if slotIndex == -1 then error("Slot not found: " .. slotMap.name) end
for timelineName,timelineMap in pairs(slotMap) do
local keyMap = timelineMap[1]
if keyMap then
@ -1040,7 +1038,6 @@ function SkeletonJson.new (attachmentLoader)
local unchangedIndex = 1
for _,offsetMap in ipairs(offsets) do
local slotIndex = skeletonData:findSlot(offsetMap["slot"]).index
if slotIndex == -1 then error("Slot not found: " .. offsetMap["slot"]) end
-- Collect unchanged items.
while originalIndex ~= slotIndex do
unchanged[unchangedIndex] = originalIndex

View File

@ -446,15 +446,6 @@ export class Skeleton {
return null;
}
/** @returns -1 if the bone was not found. */
findBoneIndex (boneName: string) {
if (!boneName) throw new Error("boneName cannot be null.");
let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++)
if (bones[i].data.name == boneName) return i;
return -1;
}
/** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
* repeatedly.
* @returns May be null. */
@ -468,15 +459,6 @@ export class Skeleton {
return null;
}
/** @returns -1 if the bone was not found. */
findSlotIndex (slotName: string) {
if (!slotName) throw new Error("slotName cannot be null.");
let slots = this.slots;
for (let i = 0, n = slots.length; i < n; i++)
if (slots[i].data.name == slotName) return i;
return -1;
}
/** Sets a skin by name.
*
* See {@link #setSkin()}. */
@ -524,7 +506,7 @@ export class Skeleton {
* See {@link #getAttachment()}.
* @returns May be null. */
getAttachmentByName (slotName: string, attachmentName: string): Attachment {
return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
return this.getAttachment(this.data.findSlot(slotName).index, attachmentName);
}
/** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot index and

View File

@ -114,14 +114,6 @@ export class SkeletonData {
return null;
}
findBoneIndex (boneName: string) {
if (!boneName) throw new Error("boneName cannot be null.");
let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++)
if (bones[i].name == boneName) return i;
return -1;
}
/** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
* multiple times.
* @returns May be null. */
@ -135,14 +127,6 @@ export class SkeletonData {
return null;
}
findSlotIndex (slotName: string) {
if (!slotName) throw new Error("slotName cannot be null.");
let slots = this.slots;
for (let i = 0, n = slots.length; i < n; i++)
if (slots[i].name == slotName) return i;
return -1;
}
/** Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it
* multiple times.
* @returns May be null. */

View File

@ -436,20 +436,21 @@ export class SkeletonJson {
if (map.slots) {
for (let slotName in map.slots) {
let slotMap = map.slots[slotName];
let slotIndex = skeletonData.findSlotIndex(slotName);
let slotIndex = skeletonData.findSlot(slotName).index;
for (let timelineName in slotMap) {
let timelineMap = slotMap[timelineName];
if (!timelineMap) continue;
let frames = timelineMap.length;
if (timelineName == "attachment") {
let timeline = new AttachmentTimeline(timelineMap.length, slotIndex);
for (let frame = 0; frame < timelineMap.length; frame++) {
let timeline = new AttachmentTimeline(frames, slotIndex);
for (let frame = 0; frame < frames; frame++) {
let keyMap = timelineMap[frame];
timeline.setFrame(frame, getValue(keyMap, "time", 0), keyMap.name);
}
timelines.push(timeline);
} else if (timelineName == "rgba") {
let timeline = new RGBATimeline(timelineMap.length, timelineMap.length << 2, slotIndex);
let timeline = new RGBATimeline(frames, frames << 2, slotIndex);
let keyMap = timelineMap[0];
let time = getValue(keyMap, "time", 0);
let color = Color.fromString(keyMap.color);
@ -478,7 +479,7 @@ export class SkeletonJson {
timelines.push(timeline);
} else if (timelineName == "rgb") {
let timeline = new RGBTimeline(timelineMap.length, timelineMap.length * 3, slotIndex);
let timeline = new RGBTimeline(frames, frames * 3, slotIndex);
let keyMap = timelineMap[0];
let time = getValue(keyMap, "time", 0);
let color = Color.fromString(keyMap.color);
@ -506,9 +507,9 @@ export class SkeletonJson {
timelines.push(timeline);
} else if (timelineName == "alpha") {
timelines.push(readTimeline1(timelineMap, new AlphaTimeline(timelineMap.length, timelineMap.length, slotIndex), 0, 1));
timelines.push(readTimeline1(timelineMap, new AlphaTimeline(frames, frames, slotIndex), 0, 1));
} else if (timelineName == "rgba2") {
let timeline = new RGBA2Timeline(timelineMap.length, timelineMap.length * 7, slotIndex);
let timeline = new RGBA2Timeline(frames, frames * 7, slotIndex);
let keyMap = timelineMap[0];
let time = getValue(keyMap, "time", 0);
@ -544,7 +545,7 @@ export class SkeletonJson {
timelines.push(timeline);
} else if (timelineName == "rgb2") {
let timeline = new RGB2Timeline(timelineMap.length, timelineMap.length * 6, slotIndex);
let timeline = new RGB2Timeline(frames, frames * 6, slotIndex);
let keyMap = timelineMap[0];
let time = getValue(keyMap, "time", 0);
@ -586,39 +587,40 @@ export class SkeletonJson {
if (map.bones) {
for (let boneName in map.bones) {
let boneMap = map.bones[boneName];
let boneIndex = skeletonData.findBoneIndex(boneName);
let boneIndex = skeletonData.findBone(boneName).index;
for (let timelineName in boneMap) {
let timelineMap = boneMap[timelineName];
if (timelineMap.length == 0) continue;
let frames = timelineMap.length;
if (frames == 0) continue;
if (timelineName === "rotate") {
timelines.push(readTimeline1(timelineMap, new RotateTimeline(timelineMap.length, timelineMap.length, boneIndex), 0, 1));
timelines.push(readTimeline1(timelineMap, new RotateTimeline(frames, frames, boneIndex), 0, 1));
} else if (timelineName === "translate") {
let timeline = new TranslateTimeline(timelineMap.length, timelineMap.length << 1, boneIndex);
let timeline = new TranslateTimeline(frames, frames << 1, boneIndex);
timelines.push(readTimeline2(timelineMap, timeline, "x", "y", 0, scale));
} else if (timelineName === "translatex") {
let timeline = new TranslateXTimeline(timelineMap.length, timelineMap.length, boneIndex);
let timeline = new TranslateXTimeline(frames, frames, boneIndex);
timelines.push(readTimeline1(timelineMap, timeline, 0, scale));
} else if (timelineName === "translatey") {
let timeline = new TranslateYTimeline(timelineMap.length, timelineMap.length, boneIndex);
let timeline = new TranslateYTimeline(frames, frames, boneIndex);
timelines.push(readTimeline1(timelineMap, timeline, 0, scale));
} else if (timelineName === "scale") {
let timeline = new ScaleTimeline(timelineMap.length, timelineMap.length << 1, boneIndex);
let timeline = new ScaleTimeline(frames, frames << 1, boneIndex);
timelines.push(readTimeline2(timelineMap, timeline, "x", "y", 1, 1));
} else if (timelineName === "scalex") {
let timeline = new ScaleXTimeline(timelineMap.length, timelineMap.length, boneIndex);
let timeline = new ScaleXTimeline(frames, frames, boneIndex);
timelines.push(readTimeline1(timelineMap, timeline, 1, 1));
} else if (timelineName === "scaley") {
let timeline = new ScaleYTimeline(timelineMap.length, timelineMap.length, boneIndex);
let timeline = new ScaleYTimeline(frames, frames, boneIndex);
timelines.push(readTimeline1(timelineMap, timeline, 1, 1));
} else if (timelineName === "shear") {
let timeline = new ShearTimeline(timelineMap.length, timelineMap.length << 1, boneIndex);
let timeline = new ShearTimeline(frames, frames << 1, boneIndex);
timelines.push(readTimeline2(timelineMap, timeline, "x", "y", 0, 1));
} else if (timelineName === "shearx") {
let timeline = new ShearXTimeline(timelineMap.length, timelineMap.length, boneIndex);
let timeline = new ShearXTimeline(frames, frames, boneIndex);
timelines.push(readTimeline1(timelineMap, timeline, 0, 1));
} else if (timelineName === "sheary") {
let timeline = new ShearYTimeline(timelineMap.length, timelineMap.length, boneIndex);
let timeline = new ShearYTimeline(frames, frames, boneIndex);
timelines.push(readTimeline1(timelineMap, timeline, 0, 1));
}
}
@ -675,7 +677,7 @@ export class SkeletonJson {
let constraint = skeletonData.findTransformConstraint(constraintName);
let constraintIndex = skeletonData.transformConstraints.indexOf(constraint);
let timeline = new TransformConstraintTimeline(timelineMap.length, timelineMap.length << 2, constraintIndex);
let timeline = new TransformConstraintTimeline(timelineMap.length, timelineMap.length * 6, constraintIndex);
let time = getValue(keyMap, "time", 0);
let mixRotate = getValue(keyMap, "mixRotate", 1);
@ -734,14 +736,15 @@ export class SkeletonJson {
let keyMap = timelineMap[0];
if (!keyMap) continue;
let frames = timelineMap.length;
if (timelineName === "position") {
let timeline = new PathConstraintPositionTimeline(timelineMap.length, timelineMap.length, constraintIndex);
let timeline = new PathConstraintPositionTimeline(frames, frames, constraintIndex);
timelines.push(readTimeline1(timelineMap, timeline, 0, constraint.positionMode == PositionMode.Fixed ? scale : 1));
} else if (timelineName === "spacing") {
let timeline = new PathConstraintSpacingTimeline(timelineMap.length, timelineMap.length, constraintIndex);
let timeline = new PathConstraintSpacingTimeline(frames, frames, constraintIndex);
timelines.push(readTimeline1(timelineMap, timeline, 0, constraint.spacingMode == SpacingMode.Length || constraint.spacingMode == SpacingMode.Fixed ? scale : 1));
} else if (timelineName === "mix") {
let timeline = new PathConstraintMixTimeline(timelineMap.size, timelineMap.size * 3, constraintIndex);
let timeline = new PathConstraintMixTimeline(frames, frames * 3, constraintIndex);
let time = getValue(keyMap, "time", 0);
let mixRotate = getValue(keyMap, "mixRotate", 1);
let mixX = getValue(keyMap, "mixX", 1);
@ -782,7 +785,7 @@ export class SkeletonJson {
let skin = skeletonData.findSkin(deformName);
for (let slotName in deformMap) {
let slotMap = deformMap[slotName];
let slotIndex = skeletonData.findSlotIndex(slotName);
let slotIndex = skeletonData.findSlot(slotName).index;
for (let timelineName in slotMap) {
let timelineMap = slotMap[timelineName];
let keyMap = timelineMap[0];
@ -847,7 +850,7 @@ export class SkeletonJson {
let originalIndex = 0, unchangedIndex = 0;
for (let ii = 0; ii < offsets.length; ii++) {
let offsetMap = offsets[ii];
let slotIndex = skeletonData.findSlotIndex(offsetMap.slot);
let slotIndex = skeletonData.findSlot(offsetMap.slot).indexs;
// Collect unchanged items.
while (originalIndex != slotIndex)
unchanged[unchangedIndex++] = originalIndex++;