Attachment* _AtlasAttachmentLoader_newAttachment (AttachmentLoader* loader, Skin* skin, AttachmentType type, const char* name) { AtlasAttachmentLoader* self = SUB_CAST(AtlasAttachmentLoader, loader); switch (type) { case ATTACHMENT_REGION: { AtlasRegion* region = Atlas_findRegion(self->atlas, name); if (!region) { _AttachmentLoader_setError(loader, "Region not found: ", name); return 0; } return SUPER_CAST(Attachment, RegionAttachment_create(name, region)) ; } default: _AttachmentLoader_setUnknownTypeError(loader, type); return 0; } }
static spAnimation *readAnimation(spSkeletonBinary *self, const char *name) { float scale = self->scale; float duration = 0; int drawOrderCount; int eventCount; spAnimation *animation; _spTimelineArray arr; arr.timelines = NULL; arr.capacity = 0; arr.count = 0; // slot timelines for (int i = 0, n = readVarint(self, true); i < n; i++) { int slotIndex = readVarint(self, true); for (int ii = 0, nn = readVarint(self, true); ii < nn; ii++) { int timelineType = readByte(self); int frameCount = readVarint(self, true); switch (timelineType) { case SLOT_COLOR: { spColorTimeline *timeline = spColorTimeline_create(frameCount); timeline->slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = readFloat(self); float r, g, b, a; readColor(self, &r, &g, &b, &a); spColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a); if (frameIndex < frameCount - 1) { readCurve(self, SUPER(timeline), frameIndex); } } duration = MAX(duration, timeline->frames[(frameCount - 1) * COLOR_ENTRIES]); addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline)); break; } case SLOT_ATTACHMENT: { spAttachmentTimeline *timeline = spAttachmentTimeline_create(frameCount); timeline->slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = readFloat(self); char *name = readString(self); spAttachmentTimeline_setFrame(timeline, frameIndex, time, name); } duration = MAX(duration, timeline->frames[frameCount - 1]); addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline)); break; } } } } // bone timelines for (int i = 0, n = readVarint(self, true); i < n; i++) { int boneIndex = readVarint(self, true); for (int ii = 0, nn = readVarint(self, true); ii < nn; ii++) { int timelineType = readByte(self); int frameCount = readVarint(self, true); switch (timelineType) { case BONE_ROTATE: { spRotateTimeline *timeline = spRotateTimeline_create(frameCount); timeline->boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = readFloat(self); float angle = readFloat(self); spRotateTimeline_setFrame(timeline, frameIndex, time, angle); if (frameIndex < frameCount - 1) { readCurve(self, SUPER(timeline), frameIndex); } } duration = MAX(duration, timeline->frames[(frameCount - 1) * ROTATE_ENTRIES]); addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline)); break; } case BONE_TRANSLATE: case BONE_SCALE: case BONE_SHEAR: { spTranslateTimeline *timeline; float timelineScale = 1; if (timelineType == BONE_SCALE) { timeline = spScaleTimeline_create(frameCount); } else if (timelineType == BONE_SHEAR) timeline = spShearTimeline_create(frameCount); else { timeline = spTranslateTimeline_create(frameCount); timelineScale = scale; } timeline->boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = readFloat(self); float x = readFloat(self) * timelineScale; float y = readFloat(self) * timelineScale; spTranslateTimeline_setFrame(timeline, frameIndex, time, x, y); if (frameIndex < frameCount - 1) { readCurve(self, SUPER(timeline), frameIndex); } } duration = MAX(duration, timeline->frames[(frameCount - 1) * TRANSLATE_ENTRIES]); addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline)); break; } } } } // ik constraint timelines for (int i = 0, n = readVarint(self, true); i < n; i++) { int index = readVarint(self, true); int frameCount = readVarint(self, true); spIkConstraintTimeline *timeline = spIkConstraintTimeline_create(frameCount); timeline->ikConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = readFloat(self); float mix = readFloat(self); int blendPositive = readByte(self); spIkConstraintTimeline_setFrame(timeline, frameIndex, time, mix, blendPositive); if (frameIndex < frameCount - 1) { readCurve(self, SUPER(timeline), frameIndex); } } duration = MAX(duration, timeline->frames[(frameCount - 1) * IKCONSTRAINT_ENTRIES]); addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline)); } // transform constraint timelines for (int i = 0, n = readVarint(self, true); i < n; i++) { int index = readVarint(self, true); int frameCount = readVarint(self, true); spTransformConstraintTimeline *timeline = spTransformConstraintTimeline_create(frameCount); timeline->transformConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = readFloat(self); float rotateMix = readFloat(self); float translateMix = readFloat(self); float scaleMix = readFloat(self); float shearMix = readFloat(self); spTransformConstraintTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix, scaleMix, shearMix); if (frameIndex < frameCount - 1) { readCurve(self, SUPER(timeline), frameIndex); } } duration = MAX(duration, timeline->frames[(frameCount - 1) * TRANSFORMCONSTRAINT_ENTRIES]); addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline)); } // path constraint timelines for (int i = 0, n = readVarint(self, true); i < n; i++) { int index = readVarint(self, true); spPathConstraintData *data = self->skeletonData->pathConstraints[index]; for (int ii = 0, nn = readVarint(self, true); ii < nn; ii++) { int timelineType = readByte(self); int frameCount = readVarint(self, true); switch (timelineType) { case PATH_POSITION: case PATH_SPACING: { spPathConstraintPositionTimeline *timeline; float timelineScale = 1; if (timelineType == PATH_SPACING) { timeline = (spPathConstraintPositionTimeline *)spPathConstraintSpacingTimeline_create(frameCount); if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED) { timelineScale = scale; } } else { timeline = spPathConstraintPositionTimeline_create(frameCount); if (data->positionMode == SP_POSITION_MODE_FIXED) { timelineScale = scale; } } timeline->pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = readFloat(self); float value = readFloat(self); spPathConstraintPositionTimeline_setFrame(timeline, frameIndex, time, value); if (frameIndex < frameCount - 1) { readCurve(self, SUPER(timeline), frameIndex); } } duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTPOSITION_ENTRIES]); addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline)); break; } case PATH_MIX: { spPathConstraintMixTimeline *timeline = spPathConstraintMixTimeline_create(frameCount); timeline->pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = readFloat(self); float rotateMix = readFloat(self); float translateMix = readFloat(self); spPathConstraintMixTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix); if (frameIndex < frameCount - 1) { readCurve(self, SUPER(timeline), frameIndex); } } duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTMIX_ENTRIES]); addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline)); break; } } } } // deform timelines for (int i = 0, n = readVarint(self, true); i < n; i++) { spSkin *skin = self->skeletonData->skins[readVarint(self, true)]; for (int ii = 0, nn = readVarint(self, true); ii < nn; ii++) { int slotIndex = readVarint(self, true); for (int iii = 0, nnn = readVarint(self, true); iii < nnn; iii++) { char *name = readString(self); spVertexAttachment *attachment = SUB_CAST(spVertexAttachment, spSkin_getAttachment(skin, slotIndex, name)); bool weighted = attachment->bones != NULL; float *vertices = attachment->vertices; int deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount; int frameCount = readVarint(self, true); spDeformTimeline *timeline = spDeformTimeline_create(frameCount, deformLength); timeline->slotIndex = slotIndex; timeline->attachment = SUPER(attachment); for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = readFloat(self); float *deform; int end = readVarint(self, true); if (end == 0) deform = weighted ? CALLOC(float, deformLength) : vertices; else { deform = CALLOC(float, deformLength); int start = readVarint(self, true); end += start; if (scale == 1) { for (int v = start; v < end; v++) deform[v] = readFloat(self); } else { for (int v = start; v < end; v++) deform[v] = readFloat(self) * scale; } if (!weighted) { for (int v = 0, vn = deformLength; v < vn; v++) deform[v] += vertices[v]; } } spDeformTimeline_setFrame(timeline, frameIndex, time, deform); if (frameIndex < frameCount - 1) { readCurve(self, SUPER(timeline), frameIndex); } } duration = MAX(duration, timeline->frames[frameCount - 1]); addAnimationTimeline(&arr, SUPER_CAST(spTimeline, timeline)); } } }