Esempio n. 1
0
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));
            }
        }
    }