[ts] Fixed JSON parsing of SequenceTimeline

This commit is contained in:
Mario Zechner 2021-10-13 23:53:13 +02:00
parent b48e2c33b8
commit 49f039fb6a
2 changed files with 69 additions and 55 deletions

View File

@ -41,7 +41,9 @@ import { Skin } from "./Skin";
import { SlotData, BlendMode } from "./SlotData"; import { SlotData, BlendMode } from "./SlotData";
import { TransformConstraintData } from "./TransformConstraintData"; import { TransformConstraintData } from "./TransformConstraintData";
import { Utils, Color, NumberArrayLike } from "./Utils"; import { Utils, Color, NumberArrayLike } from "./Utils";
import { Sequence } from "./attachments/Sequence"; import { Sequence, SequenceMode } from "./attachments/Sequence";
import { SequenceTimeline } from "src";
import { HasTextureRegion } from "./attachments/HasTextureRegion";
/** Loads skeleton data in the Spine JSON format. /** Loads skeleton data in the Spine JSON format.
* *
@ -797,54 +799,72 @@ export class SkeletonJson {
for (let attachmentsName in map.attachments) { for (let attachmentsName in map.attachments) {
let attachmentsMap = map.attachments[attachmentsName]; let attachmentsMap = map.attachments[attachmentsName];
let skin = skeletonData.findSkin(attachmentsName); let skin = skeletonData.findSkin(attachmentsName);
for (let slotName in attachmentsMap) { for (let slotMapName in attachmentsMap) {
let slotMap = attachmentsMap[slotName]; let slotMap = attachmentsMap[slotMapName];
let slotIndex = skeletonData.findSlot(slotName).index; let slotIndex = skeletonData.findSlot(slotMapName).index;
for (let timelineName in slotMap) { for (let attachmentMapName in slotMap) {
let attachmentMap = slotMap[timelineName]; let attachmentMap = slotMap[attachmentMapName];
let attachmentMapName = timelineName; let attachment = <VertexAttachment>skin.getAttachment(slotIndex, attachmentMapName);
let keyMap = attachmentMap[0];
if (!keyMap) continue;
let attachment = <VertexAttachment>skin.getAttachment(slotIndex, timelineName); for (let timelineMapName in attachmentMap) {
let weighted = attachment.bones; let timelineMap = attachmentMap[timelineMapName];
let vertices = attachment.vertices; let keyMap = timelineMap[0];
let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; if (!keyMap) continue;
let timeline = new DeformTimeline(attachmentMap.length, attachmentMap.length, slotIndex, attachment); if (timelineMapName == "deform") {
let time = getValue(keyMap, "time", 0); let weighted = attachment.bones;
for (let frame = 0, bezier = 0; ; frame++) { let vertices = attachment.vertices;
let deform: NumberArrayLike; let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
let verticesValue: Array<Number> = getValue(keyMap, "vertices", null);
if (!verticesValue) let timeline = new DeformTimeline(timelineMap.length, timelineMap.length, slotIndex, attachment);
deform = weighted ? Utils.newFloatArray(deformLength) : vertices; let time = getValue(keyMap, "time", 0);
else { for (let frame = 0, bezier = 0; ; frame++) {
deform = Utils.newFloatArray(deformLength); let deform: NumberArrayLike;
let start = <number>getValue(keyMap, "offset", 0); let verticesValue: Array<Number> = getValue(keyMap, "vertices", null);
Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); if (!verticesValue)
if (scale != 1) { deform = weighted ? Utils.newFloatArray(deformLength) : vertices;
for (let i = start, n = i + verticesValue.length; i < n; i++) else {
deform[i] *= scale; deform = Utils.newFloatArray(deformLength);
let start = <number>getValue(keyMap, "offset", 0);
Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length);
if (scale != 1) {
for (let i = start, n = i + verticesValue.length; i < n; i++)
deform[i] *= scale;
}
if (!weighted) {
for (let i = 0; i < deformLength; i++)
deform[i] += vertices[i];
}
}
timeline.setFrame(frame, time, deform);
let nextMap = timelineMap[frame + 1];
if (!nextMap) {
timeline.shrink(bezier);
break;
}
let time2 = getValue(nextMap, "time", 0);
let curve = keyMap.curve;
if (curve) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1);
time = time2;
keyMap = nextMap;
} }
if (!weighted) { timelines.push(timeline);
for (let i = 0; i < deformLength; i++) } else if (timelineMapName == "sequence") {
deform[i] += vertices[i]; let timeline = new SequenceTimeline(timelineMap.length, slotIndex, attachment as unknown as HasTextureRegion);
let lastDelay = 0;
for (let frame = 0; frame < timelineMap.length; frame++) {
let delay = getValue(keyMap, "delay", lastDelay);
let time = getValue(keyMap, "time", 0);
let mode = SequenceMode[getValue(keyMap, "mode", "hold")] as unknown as number;
let index = getValue(keyMap, "index", 0);
timeline.setFrame(frame, time, mode, index, delay);
lastDelay = delay;
keyMap = timelineMap[frame + 1];
} }
timelines.push(timeline);
} }
timeline.setFrame(frame, time, deform);
let nextMap = attachmentMap[frame + 1];
if (!nextMap) {
timeline.shrink(bezier);
break;
}
let time2 = getValue(nextMap, "time", 0);
let curve = keyMap.curve;
if (curve) bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1);
time = time2;
keyMap = nextMap;
} }
timelines.push(timeline);
} }
} }
} }

View File

@ -32,25 +32,19 @@ import { Color } from "../Utils"
import { Sequence } from "./Sequence" import { Sequence } from "./Sequence"
export interface HasTextureRegion { export interface HasTextureRegion {
/** The name used to find the {@link #getRegion()}. */ /** The name used to find the {@link #region()}. */
getPath (): string; path: string;
setPath (path: string): void; /** The region used to draw the attachment. After setting the region or if the region's properties are changed,
getRegion (): TextureRegion;
/** Sets the region used to draw the attachment. After setting the region or if the region's properties are changed,
* {@link #updateRegion()} must be called. */ * {@link #updateRegion()} must be called. */
setRegion (region: TextureRegion): void; region: TextureRegion;
/** Updates any values the attachment calculates using the {@link #getRegion()}. Must be called after setting the /** Updates any values the attachment calculates using the {@link #getRegion()}. Must be called after setting the
* {@link #getRegion()} or if the region's properties are changed. */ * {@link #getRegion()} or if the region's properties are changed. */
updateRegion (): void; updateRegion (): void;
/** The color to tint the attachment. */ /** The color to tint the attachment. */
getColor (): Color; color: Color;
getSequence (): Sequence; sequence: Sequence;
setSequence (sequence: Sequence): void;
} }