UNPKG

@pixi-spine/runtime-3.8

Version:

Pixi runtime for spine 3.8 models

1 lines 74.3 kB
{"version":3,"file":"SkeletonBinary.mjs","sources":["../../src/core/SkeletonBinary.ts"],"sourcesContent":["import type { Attachment, AttachmentLoader, MeshAttachment, VertexAttachment } from './attachments';\nimport { Event } from './Event';\nimport { SkeletonData } from './SkeletonData';\nimport { SlotData } from './SlotData';\nimport { BoneData } from './BoneData';\nimport { IkConstraintData } from './IkConstraintData';\nimport { TransformConstraintData } from './TransformConstraintData';\nimport { PathConstraintData, SpacingMode } from './PathConstraintData';\nimport { Skin } from './Skin';\nimport { EventData } from './EventData';\nimport {\n Animation,\n AttachmentTimeline,\n ColorTimeline,\n CurveTimeline,\n DeformTimeline,\n DrawOrderTimeline,\n EventTimeline,\n IkConstraintTimeline,\n PathConstraintMixTimeline,\n PathConstraintPositionTimeline,\n PathConstraintSpacingTimeline,\n RotateTimeline,\n ScaleTimeline,\n ShearTimeline,\n Timeline,\n TransformConstraintTimeline,\n TranslateTimeline,\n TwoColorTimeline,\n} from './Animation';\nimport { AttachmentType, BinaryInput, Color, PositionMode, RotateMode, TransformMode, Utils } from '@pixi-spine/base';\nimport { BLEND_MODES } from '@pixi/core';\n\n/**\n * @public\n */\nexport class SkeletonBinary {\n static AttachmentTypeValues = [\n 0 /* AttachmentType.Region*/, 1 /* AttachmentType.BoundingBox*/, 2 /* AttachmentType.Mesh*/, 3 /* AttachmentType.LinkedMesh*/, 4 /* AttachmentType.Path*/,\n 5 /* AttachmentType.Point*/, 6 /* AttachmentType.Clipping*/,\n ];\n static TransformModeValues = [\n TransformMode.Normal,\n TransformMode.OnlyTranslation,\n TransformMode.NoRotationOrReflection,\n TransformMode.NoScale,\n TransformMode.NoScaleOrReflection,\n ];\n static PositionModeValues = [PositionMode.Fixed, PositionMode.Percent];\n static SpacingModeValues = [SpacingMode.Length, SpacingMode.Fixed, SpacingMode.Percent];\n static RotateModeValues = [RotateMode.Tangent, RotateMode.Chain, RotateMode.ChainScale];\n static BlendModeValues = [BLEND_MODES.NORMAL, BLEND_MODES.ADD, BLEND_MODES.MULTIPLY, BLEND_MODES.SCREEN];\n\n static BONE_ROTATE = 0;\n static BONE_TRANSLATE = 1;\n static BONE_SCALE = 2;\n static BONE_SHEAR = 3;\n\n static SLOT_ATTACHMENT = 0;\n static SLOT_COLOR = 1;\n static SLOT_TWO_COLOR = 2;\n\n static PATH_POSITION = 0;\n static PATH_SPACING = 1;\n static PATH_MIX = 2;\n\n static CURVE_LINEAR = 0;\n static CURVE_STEPPED = 1;\n static CURVE_BEZIER = 2;\n\n attachmentLoader: AttachmentLoader;\n scale = 1;\n private linkedMeshes = new Array<LinkedMesh>();\n\n constructor(attachmentLoader: AttachmentLoader) {\n this.attachmentLoader = attachmentLoader;\n }\n\n readSkeletonData(binary: Uint8Array): SkeletonData {\n const scale = this.scale;\n\n const skeletonData = new SkeletonData();\n\n skeletonData.name = ''; // BOZO\n\n const input = new BinaryInput(binary);\n\n skeletonData.hash = input.readString();\n skeletonData.version = input.readString();\n if (skeletonData.version === '3.8.75') {\n const error = `Unsupported skeleton data, 3.8.75 is deprecated, please export with a newer version of Spine.`;\n\n console.error(error);\n }\n skeletonData.x = input.readFloat();\n skeletonData.y = input.readFloat();\n skeletonData.width = input.readFloat();\n skeletonData.height = input.readFloat();\n\n const nonessential = input.readBoolean();\n\n if (nonessential) {\n skeletonData.fps = input.readFloat();\n\n skeletonData.imagesPath = input.readString();\n skeletonData.audioPath = input.readString();\n }\n\n let n = 0;\n // Strings.\n\n n = input.readInt(true);\n for (let i = 0; i < n; i++) input.strings.push(input.readString());\n\n // Bones.\n n = input.readInt(true);\n for (let i = 0; i < n; i++) {\n const name = input.readString();\n const parent = i == 0 ? null : skeletonData.bones[input.readInt(true)];\n const data = new BoneData(i, name, parent);\n\n data.rotation = input.readFloat();\n data.x = input.readFloat() * scale;\n data.y = input.readFloat() * scale;\n data.scaleX = input.readFloat();\n data.scaleY = input.readFloat();\n data.shearX = input.readFloat();\n data.shearY = input.readFloat();\n data.length = input.readFloat() * scale;\n data.transformMode = SkeletonBinary.TransformModeValues[input.readInt(true)];\n data.skinRequired = input.readBoolean();\n if (nonessential) Color.rgba8888ToColor(data.color, input.readInt32());\n skeletonData.bones.push(data);\n }\n\n // Slots.\n n = input.readInt(true);\n for (let i = 0; i < n; i++) {\n const slotName = input.readString();\n const boneData = skeletonData.bones[input.readInt(true)];\n const data = new SlotData(i, slotName, boneData);\n\n Color.rgba8888ToColor(data.color, input.readInt32());\n\n const darkColor = input.readInt32();\n\n if (darkColor != -1) Color.rgb888ToColor((data.darkColor = new Color()), darkColor);\n\n data.attachmentName = input.readStringRef();\n data.blendMode = SkeletonBinary.BlendModeValues[input.readInt(true)];\n skeletonData.slots.push(data);\n }\n\n // IK constraints.\n n = input.readInt(true);\n for (let i = 0, nn; i < n; i++) {\n const data = new IkConstraintData(input.readString());\n\n data.order = input.readInt(true);\n data.skinRequired = input.readBoolean();\n nn = input.readInt(true);\n for (let ii = 0; ii < nn; ii++) data.bones.push(skeletonData.bones[input.readInt(true)]);\n data.target = skeletonData.bones[input.readInt(true)];\n data.mix = input.readFloat();\n data.softness = input.readFloat() * scale;\n data.bendDirection = input.readByte();\n data.compress = input.readBoolean();\n data.stretch = input.readBoolean();\n data.uniform = input.readBoolean();\n skeletonData.ikConstraints.push(data);\n }\n\n // Transform constraints.\n n = input.readInt(true);\n for (let i = 0, nn; i < n; i++) {\n const data = new TransformConstraintData(input.readString());\n\n data.order = input.readInt(true);\n data.skinRequired = input.readBoolean();\n nn = input.readInt(true);\n for (let ii = 0; ii < nn; ii++) data.bones.push(skeletonData.bones[input.readInt(true)]);\n data.target = skeletonData.bones[input.readInt(true)];\n data.local = input.readBoolean();\n data.relative = input.readBoolean();\n data.offsetRotation = input.readFloat();\n data.offsetX = input.readFloat() * scale;\n data.offsetY = input.readFloat() * scale;\n data.offsetScaleX = input.readFloat();\n data.offsetScaleY = input.readFloat();\n data.offsetShearY = input.readFloat();\n data.rotateMix = input.readFloat();\n data.translateMix = input.readFloat();\n data.scaleMix = input.readFloat();\n data.shearMix = input.readFloat();\n skeletonData.transformConstraints.push(data);\n }\n\n // Path constraints.\n n = input.readInt(true);\n for (let i = 0, nn; i < n; i++) {\n const data = new PathConstraintData(input.readString());\n\n data.order = input.readInt(true);\n data.skinRequired = input.readBoolean();\n nn = input.readInt(true);\n for (let ii = 0; ii < nn; ii++) data.bones.push(skeletonData.bones[input.readInt(true)]);\n data.target = skeletonData.slots[input.readInt(true)];\n data.positionMode = SkeletonBinary.PositionModeValues[input.readInt(true)];\n data.spacingMode = SkeletonBinary.SpacingModeValues[input.readInt(true)];\n data.rotateMode = SkeletonBinary.RotateModeValues[input.readInt(true)];\n data.offsetRotation = input.readFloat();\n data.position = input.readFloat();\n if (data.positionMode == PositionMode.Fixed) data.position *= scale;\n data.spacing = input.readFloat();\n if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) data.spacing *= scale;\n data.rotateMix = input.readFloat();\n data.translateMix = input.readFloat();\n skeletonData.pathConstraints.push(data);\n }\n\n // Default skin.\n const defaultSkin = this.readSkin(input, skeletonData, true, nonessential);\n\n if (defaultSkin != null) {\n skeletonData.defaultSkin = defaultSkin;\n skeletonData.skins.push(defaultSkin);\n }\n\n // Skins.\n {\n let i = skeletonData.skins.length;\n\n Utils.setArraySize(skeletonData.skins, (n = i + input.readInt(true)));\n for (; i < n; i++) skeletonData.skins[i] = this.readSkin(input, skeletonData, false, nonessential);\n }\n\n // Linked meshes.\n n = this.linkedMeshes.length;\n for (let i = 0; i < n; i++) {\n const linkedMesh = this.linkedMeshes[i];\n const skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin);\n\n if (skin == null) throw new Error(`Skin not found: ${linkedMesh.skin}`);\n const parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent);\n\n if (parent == null) throw new Error(`Parent mesh not found: ${linkedMesh.parent}`);\n linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? (parent as VertexAttachment) : linkedMesh.mesh;\n linkedMesh.mesh.setParentMesh(parent as MeshAttachment);\n // linkedMesh.mesh.updateUVs();\n }\n this.linkedMeshes.length = 0;\n\n // Events.\n n = input.readInt(true);\n for (let i = 0; i < n; i++) {\n const data = new EventData(input.readStringRef());\n\n data.intValue = input.readInt(false);\n data.floatValue = input.readFloat();\n data.stringValue = input.readString();\n data.audioPath = input.readString();\n if (data.audioPath != null) {\n data.volume = input.readFloat();\n data.balance = input.readFloat();\n }\n skeletonData.events.push(data);\n }\n\n // Animations.\n n = input.readInt(true);\n for (let i = 0; i < n; i++) skeletonData.animations.push(this.readAnimation(input, input.readString(), skeletonData));\n\n return skeletonData;\n }\n\n private readSkin(input: BinaryInput, skeletonData: SkeletonData, defaultSkin: boolean, nonessential: boolean): Skin {\n let skin = null;\n let slotCount = 0;\n\n if (defaultSkin) {\n slotCount = input.readInt(true);\n if (slotCount == 0) return null;\n skin = new Skin('default');\n } else {\n skin = new Skin(input.readStringRef());\n skin.bones.length = input.readInt(true);\n for (let i = 0, n = skin.bones.length; i < n; i++) skin.bones[i] = skeletonData.bones[input.readInt(true)];\n\n for (let i = 0, n = input.readInt(true); i < n; i++) skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]);\n for (let i = 0, n = input.readInt(true); i < n; i++) skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]);\n for (let i = 0, n = input.readInt(true); i < n; i++) skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]);\n\n slotCount = input.readInt(true);\n }\n\n for (let i = 0; i < slotCount; i++) {\n const slotIndex = input.readInt(true);\n\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n const name = input.readStringRef();\n const attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name, nonessential);\n\n if (attachment != null) skin.setAttachment(slotIndex, name, attachment);\n }\n }\n\n return skin;\n }\n\n private readAttachment(input: BinaryInput, skeletonData: SkeletonData, skin: Skin, slotIndex: number, attachmentName: string, nonessential: boolean): Attachment {\n const scale = this.scale;\n\n let name = input.readStringRef();\n\n if (name == null) name = attachmentName;\n\n const typeIndex = input.readByte();\n const type = SkeletonBinary.AttachmentTypeValues[typeIndex];\n\n switch (type) {\n case AttachmentType.Region: {\n let path = input.readStringRef();\n const rotation = input.readFloat();\n const x = input.readFloat();\n const y = input.readFloat();\n const scaleX = input.readFloat();\n const scaleY = input.readFloat();\n const width = input.readFloat();\n const height = input.readFloat();\n const color = input.readInt32();\n\n if (path == null) path = name;\n const region = this.attachmentLoader.newRegionAttachment(skin, name, path);\n\n if (region == null) return null;\n region.path = path;\n region.x = x * scale;\n region.y = y * scale;\n region.scaleX = scaleX;\n region.scaleY = scaleY;\n region.rotation = rotation;\n region.width = width * scale;\n region.height = height * scale;\n Color.rgba8888ToColor(region.color, color);\n // region.updateOffset();\n\n return region;\n }\n case AttachmentType.BoundingBox: {\n const vertexCount = input.readInt(true);\n const vertices = this.readVertices(input, vertexCount);\n const color = nonessential ? input.readInt32() : 0;\n\n const box = this.attachmentLoader.newBoundingBoxAttachment(skin, name);\n\n if (box == null) return null;\n box.worldVerticesLength = vertexCount << 1;\n box.vertices = vertices.vertices;\n box.bones = vertices.bones;\n if (nonessential) Color.rgba8888ToColor(box.color, color);\n\n return box;\n }\n case AttachmentType.Mesh: {\n let path = input.readStringRef();\n const color = input.readInt32();\n const vertexCount = input.readInt(true);\n const uvs = this.readFloatArray(input, vertexCount << 1, 1);\n const triangles = this.readShortArray(input);\n const vertices = this.readVertices(input, vertexCount);\n const hullLength = input.readInt(true);\n let edges = null;\n let width = 0;\n let height = 0;\n\n if (nonessential) {\n edges = this.readShortArray(input);\n width = input.readFloat();\n height = input.readFloat();\n }\n\n if (path == null) path = name;\n const mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);\n\n if (mesh == null) return null;\n mesh.path = path;\n Color.rgba8888ToColor(mesh.color, color);\n mesh.bones = vertices.bones;\n mesh.vertices = vertices.vertices;\n mesh.worldVerticesLength = vertexCount << 1;\n mesh.triangles = triangles;\n mesh.regionUVs = new Float32Array(uvs);\n // mesh.updateUVs();\n mesh.hullLength = hullLength << 1;\n if (nonessential) {\n mesh.edges = edges;\n mesh.width = width * scale;\n mesh.height = height * scale;\n }\n\n return mesh;\n }\n case AttachmentType.LinkedMesh: {\n let path = input.readStringRef();\n const color = input.readInt32();\n const skinName = input.readStringRef();\n const parent = input.readStringRef();\n const inheritDeform = input.readBoolean();\n let width = 0;\n let height = 0;\n\n if (nonessential) {\n width = input.readFloat();\n height = input.readFloat();\n }\n\n if (path == null) path = name;\n const mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);\n\n if (mesh == null) return null;\n mesh.path = path;\n Color.rgba8888ToColor(mesh.color, color);\n if (nonessential) {\n mesh.width = width * scale;\n mesh.height = height * scale;\n }\n this.linkedMeshes.push(new LinkedMesh(mesh, skinName, slotIndex, parent, inheritDeform));\n\n return mesh;\n }\n case AttachmentType.Path: {\n const closed = input.readBoolean();\n const constantSpeed = input.readBoolean();\n const vertexCount = input.readInt(true);\n const vertices = this.readVertices(input, vertexCount);\n const lengths = Utils.newArray(vertexCount / 3, 0);\n\n for (let i = 0, n = lengths.length; i < n; i++) lengths[i] = input.readFloat() * scale;\n const color = nonessential ? input.readInt32() : 0;\n\n const path = this.attachmentLoader.newPathAttachment(skin, name);\n\n if (path == null) return null;\n path.closed = closed;\n path.constantSpeed = constantSpeed;\n path.worldVerticesLength = vertexCount << 1;\n path.vertices = vertices.vertices;\n path.bones = vertices.bones;\n path.lengths = lengths;\n if (nonessential) Color.rgba8888ToColor(path.color, color);\n\n return path;\n }\n case AttachmentType.Point: {\n const rotation = input.readFloat();\n const x = input.readFloat();\n const y = input.readFloat();\n const color = nonessential ? input.readInt32() : 0;\n\n const point = this.attachmentLoader.newPointAttachment(skin, name);\n\n if (point == null) return null;\n point.x = x * scale;\n point.y = y * scale;\n point.rotation = rotation;\n if (nonessential) Color.rgba8888ToColor(point.color, color);\n\n return point;\n }\n case AttachmentType.Clipping: {\n const endSlotIndex = input.readInt(true);\n const vertexCount = input.readInt(true);\n const vertices = this.readVertices(input, vertexCount);\n const color = nonessential ? input.readInt32() : 0;\n\n const clip = this.attachmentLoader.newClippingAttachment(skin, name);\n\n if (clip == null) return null;\n clip.endSlot = skeletonData.slots[endSlotIndex];\n clip.worldVerticesLength = vertexCount << 1;\n clip.vertices = vertices.vertices;\n clip.bones = vertices.bones;\n if (nonessential) Color.rgba8888ToColor(clip.color, color);\n\n return clip;\n }\n }\n\n return null;\n }\n\n private readVertices(input: BinaryInput, vertexCount: number): Vertices {\n const verticesLength = vertexCount << 1;\n const vertices = new Vertices();\n const scale = this.scale;\n\n if (!input.readBoolean()) {\n vertices.vertices = this.readFloatArray(input, verticesLength, scale);\n\n return vertices;\n }\n const weights = new Array<number>();\n const bonesArray = new Array<number>();\n\n for (let i = 0; i < vertexCount; i++) {\n const boneCount = input.readInt(true);\n\n bonesArray.push(boneCount);\n for (let ii = 0; ii < boneCount; ii++) {\n bonesArray.push(input.readInt(true));\n weights.push(input.readFloat() * scale);\n weights.push(input.readFloat() * scale);\n weights.push(input.readFloat());\n }\n }\n vertices.vertices = Utils.toFloatArray(weights);\n vertices.bones = bonesArray;\n\n return vertices;\n }\n\n private readFloatArray(input: BinaryInput, n: number, scale: number): number[] {\n const array = new Array<number>(n);\n\n if (scale == 1) {\n for (let i = 0; i < n; i++) array[i] = input.readFloat();\n } else {\n for (let i = 0; i < n; i++) array[i] = input.readFloat() * scale;\n }\n\n return array;\n }\n\n private readShortArray(input: BinaryInput): number[] {\n const n = input.readInt(true);\n const array = new Array<number>(n);\n\n for (let i = 0; i < n; i++) array[i] = input.readShort();\n\n return array;\n }\n\n private readAnimation(input: BinaryInput, name: string, skeletonData: SkeletonData): Animation {\n const timelines = new Array<Timeline>();\n const scale = this.scale;\n let duration = 0;\n const tempColor1 = new Color();\n const tempColor2 = new Color();\n\n // Slot timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n const slotIndex = input.readInt(true);\n\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n const timelineType = input.readByte();\n const frameCount = input.readInt(true);\n\n switch (timelineType) {\n case SkeletonBinary.SLOT_ATTACHMENT: {\n const timeline = new AttachmentTimeline(frameCount);\n\n timeline.slotIndex = slotIndex;\n for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) timeline.setFrame(frameIndex, input.readFloat(), input.readStringRef());\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[frameCount - 1]);\n break;\n }\n case SkeletonBinary.SLOT_COLOR: {\n const timeline = new ColorTimeline(frameCount);\n\n timeline.slotIndex = slotIndex;\n for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {\n const time = input.readFloat();\n\n Color.rgba8888ToColor(tempColor1, input.readInt32());\n timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a);\n if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[(frameCount - 1) * ColorTimeline.ENTRIES]);\n break;\n }\n case SkeletonBinary.SLOT_TWO_COLOR: {\n const timeline = new TwoColorTimeline(frameCount);\n\n timeline.slotIndex = slotIndex;\n for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {\n const time = input.readFloat();\n\n Color.rgba8888ToColor(tempColor1, input.readInt32());\n Color.rgb888ToColor(tempColor2, input.readInt32());\n timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r, tempColor2.g, tempColor2.b);\n if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[(frameCount - 1) * TwoColorTimeline.ENTRIES]);\n break;\n }\n }\n }\n }\n\n // Bone timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n const boneIndex = input.readInt(true);\n\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n const timelineType = input.readByte();\n const frameCount = input.readInt(true);\n\n switch (timelineType) {\n case SkeletonBinary.BONE_ROTATE: {\n const timeline = new RotateTimeline(frameCount);\n\n timeline.boneIndex = boneIndex;\n for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {\n timeline.setFrame(frameIndex, input.readFloat(), input.readFloat());\n if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[(frameCount - 1) * RotateTimeline.ENTRIES]);\n break;\n }\n case SkeletonBinary.BONE_TRANSLATE:\n case SkeletonBinary.BONE_SCALE:\n case SkeletonBinary.BONE_SHEAR: {\n let timeline;\n let timelineScale = 1;\n\n if (timelineType == SkeletonBinary.BONE_SCALE) timeline = new ScaleTimeline(frameCount);\n else if (timelineType == SkeletonBinary.BONE_SHEAR) timeline = new ShearTimeline(frameCount);\n else {\n timeline = new TranslateTimeline(frameCount);\n timelineScale = scale;\n }\n timeline.boneIndex = boneIndex;\n for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {\n timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale, input.readFloat() * timelineScale);\n if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline.ENTRIES]);\n break;\n }\n }\n }\n }\n\n // IK constraint timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n const index = input.readInt(true);\n const frameCount = input.readInt(true);\n const timeline = new IkConstraintTimeline(frameCount);\n\n timeline.ikConstraintIndex = index;\n for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {\n timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat() * scale, input.readByte(), input.readBoolean(), input.readBoolean());\n if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[(frameCount - 1) * IkConstraintTimeline.ENTRIES]);\n }\n\n // Transform constraint timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n const index = input.readInt(true);\n const frameCount = input.readInt(true);\n const timeline = new TransformConstraintTimeline(frameCount);\n\n timeline.transformConstraintIndex = index;\n for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {\n timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat());\n if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]);\n }\n\n // Path constraint timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n const index = input.readInt(true);\n const data = skeletonData.pathConstraints[index];\n\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n const timelineType = input.readByte();\n const frameCount = input.readInt(true);\n\n switch (timelineType) {\n case SkeletonBinary.PATH_POSITION:\n case SkeletonBinary.PATH_SPACING: {\n let timeline;\n let timelineScale = 1;\n\n if (timelineType == SkeletonBinary.PATH_SPACING) {\n timeline = new PathConstraintSpacingTimeline(frameCount);\n if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) timelineScale = scale;\n } else {\n timeline = new PathConstraintPositionTimeline(frameCount);\n if (data.positionMode == PositionMode.Fixed) timelineScale = scale;\n }\n timeline.pathConstraintIndex = index;\n for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {\n timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale);\n if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]);\n break;\n }\n case SkeletonBinary.PATH_MIX: {\n const timeline = new PathConstraintMixTimeline(frameCount);\n\n timeline.pathConstraintIndex = index;\n for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {\n timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat());\n if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]);\n break;\n }\n }\n }\n }\n\n // Deform timelines.\n for (let i = 0, n = input.readInt(true); i < n; i++) {\n const skin = skeletonData.skins[input.readInt(true)];\n\n for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {\n const slotIndex = input.readInt(true);\n\n for (let iii = 0, nnn = input.readInt(true); iii < nnn; iii++) {\n const attachment = skin.getAttachment(slotIndex, input.readStringRef()) as VertexAttachment;\n const weighted = attachment.bones != null;\n const vertices = attachment.vertices;\n const deformLength = weighted ? (vertices.length / 3) * 2 : vertices.length;\n\n const frameCount = input.readInt(true);\n const timeline = new DeformTimeline(frameCount);\n\n timeline.slotIndex = slotIndex;\n timeline.attachment = attachment;\n\n for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {\n const time = input.readFloat();\n let deform;\n let end = input.readInt(true);\n\n if (end == 0) deform = weighted ? Utils.newFloatArray(deformLength) : vertices;\n else {\n deform = Utils.newFloatArray(deformLength);\n const start = input.readInt(true);\n\n end += start;\n if (scale == 1) {\n for (let v = start; v < end; v++) deform[v] = input.readFloat();\n } else {\n for (let v = start; v < end; v++) deform[v] = input.readFloat() * scale;\n }\n if (!weighted) {\n for (let v = 0, vn = deform.length; v < vn; v++) deform[v] += vertices[v];\n }\n }\n\n timeline.setFrame(frameIndex, time, deform);\n if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[frameCount - 1]);\n }\n }\n }\n\n // Draw order timeline.\n const drawOrderCount = input.readInt(true);\n\n if (drawOrderCount > 0) {\n const timeline = new DrawOrderTimeline(drawOrderCount);\n const slotCount = skeletonData.slots.length;\n\n for (let i = 0; i < drawOrderCount; i++) {\n const time = input.readFloat();\n const offsetCount = input.readInt(true);\n const drawOrder = Utils.newArray(slotCount, 0);\n\n for (let ii = slotCount - 1; ii >= 0; ii--) drawOrder[ii] = -1;\n const unchanged = Utils.newArray(slotCount - offsetCount, 0);\n let originalIndex = 0;\n let unchangedIndex = 0;\n\n for (let ii = 0; ii < offsetCount; ii++) {\n const slotIndex = input.readInt(true);\n // Collect unchanged items.\n\n while (originalIndex != slotIndex) unchanged[unchangedIndex++] = originalIndex++;\n // Set changed items.\n drawOrder[originalIndex + input.readInt(true)] = originalIndex++;\n }\n // Collect remaining unchanged items.\n while (originalIndex < slotCount) unchanged[unchangedIndex++] = originalIndex++;\n // Fill in unchanged items.\n for (let ii = slotCount - 1; ii >= 0; ii--) if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex];\n timeline.setFrame(i, time, drawOrder);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[drawOrderCount - 1]);\n }\n\n // Event timeline.\n const eventCount = input.readInt(true);\n\n if (eventCount > 0) {\n const timeline = new EventTimeline(eventCount);\n\n for (let i = 0; i < eventCount; i++) {\n const time = input.readFloat();\n const eventData = skeletonData.events[input.readInt(true)];\n const event = new Event(time, eventData);\n\n event.intValue = input.readInt(false);\n event.floatValue = input.readFloat();\n event.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue;\n if (event.data.audioPath != null) {\n event.volume = input.readFloat();\n event.balance = input.readFloat();\n }\n timeline.setFrame(i, event);\n }\n timelines.push(timeline);\n duration = Math.max(duration, timeline.frames[eventCount - 1]);\n }\n\n return new Animation(name, timelines, duration);\n }\n\n private readCurve(input: BinaryInput, frameIndex: number, timeline: CurveTimeline) {\n switch (input.readByte()) {\n case SkeletonBinary.CURVE_STEPPED:\n timeline.setStepped(frameIndex);\n break;\n case SkeletonBinary.CURVE_BEZIER:\n this.setCurve(timeline, frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat());\n break;\n }\n }\n\n setCurve(timeline: CurveTimeline, frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number) {\n timeline.setCurve(frameIndex, cx1, cy1, cx2, cy2);\n }\n}\n\nclass LinkedMesh {\n parent: string;\n skin: string;\n slotIndex: number;\n mesh: MeshAttachment;\n inheritDeform: boolean;\n\n constructor(mesh: MeshAttachment, skin: string, slotIndex: number, parent: string, inheritDeform: boolean) {\n this.mesh = mesh;\n this.skin = skin;\n this.slotIndex = slotIndex;\n this.parent = parent;\n this.inheritDeform = inheritDeform;\n }\n}\n\nclass Vertices {\n constructor(public bones: Array<number> = null, public vertices: Array<number> | Float32Array = null) {}\n}\n"],"names":[],"mappings":"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