@flighthq/skeleton2d-formats 0.3.0-next.1021.f5f1ee0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contract.d.ts +4 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +4 -0
- package/dist/contract.js.map +1 -0
- package/dist/dragonBonesParse.d.ts +3 -0
- package/dist/dragonBonesParse.d.ts.map +1 -0
- package/dist/dragonBonesParse.js +480 -0
- package/dist/dragonBonesParse.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/skeletonDetect.d.ts +4 -0
- package/dist/skeletonDetect.d.ts.map +1 -0
- package/dist/skeletonDetect.js +45 -0
- package/dist/skeletonDetect.js.map +1 -0
- package/dist/spineParse.d.ts +3 -0
- package/dist/spineParse.d.ts.map +1 -0
- package/dist/spineParse.js +377 -0
- package/dist/spineParse.js.map +1 -0
- package/package.json +49 -0
- package/src/dragonBonesParse.test.ts +313 -0
- package/src/skeletonDetect.test.ts +50 -0
- package/src/spineParse.test.ts +292 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC"}
|
package/dist/contract.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dragonBonesParse.d.ts","sourceRoot":"","sources":["../src/dragonBonesParse.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,gBAAgB,EAGhB,gBAAgB,EAEjB,MAAM,0BAA0B,CAAC;AA6BlC,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,GAAG,IAAI,CA6BhH"}
|
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
import { reportImportDiagnostic } from '@flighthq/importdiagnostics/contract';
|
|
2
|
+
import { createSkeleton2D } from '@flighthq/skeleton2d/contract';
|
|
3
|
+
import { ImportDiagnosticSeverity, MeshAttachment2DKind, RegionAttachment2DKind, TransformMode2D, } from '@flighthq/types/contract';
|
|
4
|
+
// Parses a DragonBones `.json` skeleton document (text) into a Skeleton2DImport. Tolerant and best-effort,
|
|
5
|
+
// mirroring parseSpineSkeleton: a malformed / non-DragonBones document returns the sentinel `null`, and a
|
|
6
|
+
// recognized document with unmodeled pieces yields best-effort data plus `ImportDiagnostic` Skip crumbs.
|
|
7
|
+
// Field names follow DragonBones' vocabulary (armature / bone / slot / skin / animation).
|
|
8
|
+
//
|
|
9
|
+
// Parses the first armature's bone hierarchy, slots, and default-skin displays. DragonBones differs from
|
|
10
|
+
// Spine in ways the charter (open-direction 4) records: an `armature` container (multiple armatures
|
|
11
|
+
// possible), a nested `transform` block with `skX`/`skY` (or newer `rotate`/`skew`) skew angles rather than
|
|
12
|
+
// Spine's flat fields, bones NOT guaranteed parent-before-child (so they are topologically sorted here), a
|
|
13
|
+
// four-boolean inheritance model (inheritRotation/Scale/Reflection/Translation) mapped onto Flight's
|
|
14
|
+
// five-value TransformMode2D (two inexpressible combinations Skip-crumbed), and slots whose shown attachment
|
|
15
|
+
// is a `displayIndex` into a per-slot display list (so that list is position-preserving — see
|
|
16
|
+
// parseDragonBonesDefaultSkin). Image displays become region attachments; unweighted AND weighted mesh
|
|
17
|
+
// displays become mesh attachments (weighted via bonePose/slotPose → Skin2D offsets with the topo-sort
|
|
18
|
+
// bone-index remap — see parseDragonBonesWeightedMesh); armature/bounding-box/path displays, shared and
|
|
19
|
+
// legacy-weighted meshes, additional armatures, alternate skins, and animation are recognized-but-unmodeled
|
|
20
|
+
// and Skip-crumbed (frame timelines are next).
|
|
21
|
+
export function parseDragonBonesSkeleton(json, diagnostics) {
|
|
22
|
+
let doc;
|
|
23
|
+
try {
|
|
24
|
+
doc = JSON.parse(json);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
if (doc === null || typeof doc !== 'object')
|
|
30
|
+
return null;
|
|
31
|
+
const armatures = doc.armature;
|
|
32
|
+
if (!Array.isArray(armatures) || armatures.length === 0)
|
|
33
|
+
return null; // not a DragonBones document
|
|
34
|
+
if (armatures.length > 1) {
|
|
35
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Skip, 'dragonbones.multi-armature-unsupported', 'parseDragonBonesSkeleton', { armatures: armatures.length - 1 });
|
|
36
|
+
}
|
|
37
|
+
const first = armatures[0];
|
|
38
|
+
if (first === null || typeof first !== 'object')
|
|
39
|
+
return null;
|
|
40
|
+
const armature = first;
|
|
41
|
+
const bones = parseDragonBonesBones(armature.bone, diagnostics);
|
|
42
|
+
const boneIndexByName = buildBoneIndexByName(bones);
|
|
43
|
+
const remapBoneIndex = buildDragonBonesBoneRemap(armature.bone, boneIndexByName);
|
|
44
|
+
const skin = parseDragonBonesDefaultSkin(armature.skin, remapBoneIndex, diagnostics);
|
|
45
|
+
const slots = parseDragonBonesSlots(armature.slot, boneIndexByName, skin, diagnostics);
|
|
46
|
+
skipCrumbDragonBonesGroup(diagnostics, armature.animation, 'dragonbones.animation-unsupported');
|
|
47
|
+
return { animations: [], skeleton: createSkeleton2D(bones, slots) };
|
|
48
|
+
}
|
|
49
|
+
// Rebuilds the bone-name → output-index lookup from the (already topologically sorted) bone array, so slot
|
|
50
|
+
// `parent` references and future weighted-mesh bone indices resolve to the FINAL emitted position rather
|
|
51
|
+
// than the file's authoring order.
|
|
52
|
+
function buildBoneIndexByName(bones) {
|
|
53
|
+
const byName = new Map();
|
|
54
|
+
for (let i = 0; i < bones.length; i++) {
|
|
55
|
+
const name = bones[i].name;
|
|
56
|
+
if (typeof name === 'string')
|
|
57
|
+
byName.set(name, i);
|
|
58
|
+
}
|
|
59
|
+
return byName;
|
|
60
|
+
}
|
|
61
|
+
// Maps a DragonBones armature-FILE-ORDER bone index (the space weighted-mesh `weights`/`bonePose` reference
|
|
62
|
+
// bones in) to the FINAL topo-sorted OUTPUT bone index — the read-integrity axis-12 remap the topo-sort
|
|
63
|
+
// makes necessary, resolved through the bone's name so it is drop-safe. Returns -1 for an out-of-range or
|
|
64
|
+
// unnamed/unresolvable raw index.
|
|
65
|
+
function buildDragonBonesBoneRemap(rawBones, boneIndexByName) {
|
|
66
|
+
const names = [];
|
|
67
|
+
if (Array.isArray(rawBones)) {
|
|
68
|
+
for (const entry of rawBones) {
|
|
69
|
+
const name = entry !== null && typeof entry === 'object' ? entry.name : undefined;
|
|
70
|
+
names.push(typeof name === 'string' ? name : null);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return (rawBoneIndex) => {
|
|
74
|
+
const name = rawBoneIndex >= 0 && rawBoneIndex < names.length ? names[rawBoneIndex] : null;
|
|
75
|
+
return name !== null ? (boneIndexByName.get(name) ?? -1) : -1;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// Maps a DragonBones slot ColorTransform to a packed RGBA int (Slot2D.color). DragonBones color is the
|
|
79
|
+
// multiply channels aM/rM/gM/bM (0–100 percent) plus additive offsets aO/rO/gO/bO. Only the multiply tint
|
|
80
|
+
// maps to a packed color; a nonzero offset cannot be represented and is Skip-crumbed. Absent color = opaque
|
|
81
|
+
// white (0xffffffff), matching the packed RR GG BB AA convention parseSpineColor uses.
|
|
82
|
+
function parseDragonBonesColor(raw, diagnostics) {
|
|
83
|
+
if (raw === null || typeof raw !== 'object')
|
|
84
|
+
return 0xffffffff;
|
|
85
|
+
const color = raw;
|
|
86
|
+
const r = colorChannel(color.rM);
|
|
87
|
+
const g = colorChannel(color.gM);
|
|
88
|
+
const b = colorChannel(color.bM);
|
|
89
|
+
const a = colorChannel(color.aM);
|
|
90
|
+
if (numberOr(color.rO, 0) !== 0 ||
|
|
91
|
+
numberOr(color.gO, 0) !== 0 ||
|
|
92
|
+
numberOr(color.bO, 0) !== 0 ||
|
|
93
|
+
numberOr(color.aO, 0) !== 0) {
|
|
94
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Skip, 'dragonbones.color-offset-unsupported', 'parseDragonBonesSkeleton', { slots: 1 });
|
|
95
|
+
}
|
|
96
|
+
return ((r << 24) | (g << 16) | (b << 8) | a) >>> 0;
|
|
97
|
+
}
|
|
98
|
+
// The default skin's per-slot display table: slotName → the ordered list of that slot's displays
|
|
99
|
+
// (attachments), addressed by `displayIndex`. DragonBones names its default skin "default" (or leaves it
|
|
100
|
+
// empty); alternate named skins are the skin-set feature and are Skip-crumbed. The display list is
|
|
101
|
+
// POSITIONALLY REFERENCED by displayIndex, so an unmodeled/malformed display holds its slot as `null` (never
|
|
102
|
+
// dropped) — mirroring the DragonBones runtime's own addDisplay(slot, null) — so indices stay aligned.
|
|
103
|
+
function parseDragonBonesDefaultSkin(raw, remapBoneIndex, diagnostics) {
|
|
104
|
+
const table = new Map();
|
|
105
|
+
if (!Array.isArray(raw))
|
|
106
|
+
return table;
|
|
107
|
+
let alternateSkins = 0;
|
|
108
|
+
for (const rawSkin of raw) {
|
|
109
|
+
if (rawSkin === null || typeof rawSkin !== 'object')
|
|
110
|
+
continue;
|
|
111
|
+
const skin = rawSkin;
|
|
112
|
+
const skinName = typeof skin.name === 'string' && skin.name.length > 0 ? skin.name : 'default';
|
|
113
|
+
if (skinName !== 'default') {
|
|
114
|
+
alternateSkins++;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (!Array.isArray(skin.slot))
|
|
118
|
+
continue;
|
|
119
|
+
for (const rawSlot of skin.slot) {
|
|
120
|
+
if (rawSlot === null || typeof rawSlot !== 'object')
|
|
121
|
+
continue;
|
|
122
|
+
const slot = rawSlot;
|
|
123
|
+
if (typeof slot.name === 'string') {
|
|
124
|
+
table.set(slot.name, parseDragonBonesDisplayList(slot.display, remapBoneIndex, diagnostics));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (alternateSkins > 0) {
|
|
129
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Skip, 'dragonbones.alternate-skin-unsupported', 'parseDragonBonesSkeleton', { skins: alternateSkins });
|
|
130
|
+
}
|
|
131
|
+
return table;
|
|
132
|
+
}
|
|
133
|
+
// Parses one DragonBones display into an Attachment2D, or `null` (holding its displayIndex slot) for a
|
|
134
|
+
// malformed entry or an unmodeled type. DragonBones omits `type` for an image display (the default).
|
|
135
|
+
function parseDragonBonesDisplay(raw, remapBoneIndex, diagnostics) {
|
|
136
|
+
if (raw === null || typeof raw !== 'object')
|
|
137
|
+
return null;
|
|
138
|
+
const display = raw;
|
|
139
|
+
const type = typeof display.type === 'string' ? display.type : 'image';
|
|
140
|
+
if (type === 'image')
|
|
141
|
+
return parseDragonBonesRegionDisplay(display);
|
|
142
|
+
if (type === 'mesh')
|
|
143
|
+
return parseDragonBonesMeshDisplay(display, remapBoneIndex, diagnostics);
|
|
144
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Skip, `dragonbones.${type}-display-unsupported`, 'parseDragonBonesSkeleton', { displays: 1 });
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
// A DragonBones mesh display → MeshAttachment2D. UNWEIGHTED (rigid, single-slot-bone): its `vertices` are
|
|
148
|
+
// positions in the slot bone's local space, mapped directly like a Spine unweighted mesh. WEIGHTED (a
|
|
149
|
+
// `weights` stream with `bonePose`/`slotPose` bind matrices): converted to Skin2D per-bone offsets (see
|
|
150
|
+
// parseDragonBonesWeightedMesh). A `share`d mesh (geometry borrowed from another display) is not modeled and
|
|
151
|
+
// is Skip-crumbed, held at its displayIndex (returns null).
|
|
152
|
+
function parseDragonBonesMeshDisplay(display, remapBoneIndex, diagnostics) {
|
|
153
|
+
if ('share' in display) {
|
|
154
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Skip, 'dragonbones.shared-mesh-unsupported', 'parseDragonBonesSkeleton', { displays: 1 });
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
if ('weights' in display) {
|
|
158
|
+
if ('bonePose' in display)
|
|
159
|
+
return parseDragonBonesWeightedMesh(display, remapBoneIndex, diagnostics);
|
|
160
|
+
// A `weights` stream without `bonePose` is DragonBones' older bind-matrix-less weighting; not modeled.
|
|
161
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Skip, 'dragonbones.legacy-weighted-mesh-unsupported', 'parseDragonBonesSkeleton', { displays: 1 });
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
const uvs = toFloat32Array(display.uvs);
|
|
165
|
+
return {
|
|
166
|
+
kind: MeshAttachment2DKind,
|
|
167
|
+
name: typeof display.name === 'string' ? display.name : null,
|
|
168
|
+
skin: null,
|
|
169
|
+
triangles: toUint16Array(display.triangles),
|
|
170
|
+
uvs,
|
|
171
|
+
vertexCount: uvs.length >> 1,
|
|
172
|
+
vertices: toFloat32Array(display.vertices),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// Converts a DragonBones WEIGHTED mesh to a MeshAttachment2D whose Skin2D carries per-bone LOCAL offsets, by
|
|
176
|
+
// replicating the DragonBones runtime's geometry bake (ObjectDataParser._parseGeometry): each raw vertex is
|
|
177
|
+
// pushed through `slotPose`, then through the INVERSE of each influencing bone's `bonePose` bind matrix, and
|
|
178
|
+
// the result is that vertex expressed in the bone's bind-local frame — exactly what Skin2D + Flight's deform
|
|
179
|
+
// consume (Σ w·(boneWorld·localOffset)). All matrices share Flight's `x'=a·x+c·y` convention (as does
|
|
180
|
+
// DragonBones), so no transposition; the offsets are computed wholly within DragonBones' own space, so the
|
|
181
|
+
// global y-down↔y-up question (charter #4) is orthogonal and unaffected here.
|
|
182
|
+
//
|
|
183
|
+
// The `weights` stream references bones by ARMATURE FILE-ORDER index; `remapBoneIndex` re-points each
|
|
184
|
+
// influence at the topo-sorted OUTPUT bone (the axis-12 remap). Every read is bounded against the actual
|
|
185
|
+
// stream length (axis 13); a truncated stream, an unresolvable bone, or a degenerate bind matrix drops that
|
|
186
|
+
// influence/vertex best-effort and emits a Recover crumb.
|
|
187
|
+
function parseDragonBonesWeightedMesh(display, remapBoneIndex, diagnostics) {
|
|
188
|
+
const uvs = toFloat32Array(display.uvs);
|
|
189
|
+
const vertexCount = uvs.length >> 1;
|
|
190
|
+
const verts = numberArray(display.vertices);
|
|
191
|
+
const weights = numberArray(display.weights);
|
|
192
|
+
const bonePose = numberArray(display.bonePose);
|
|
193
|
+
const slotPose = numberArray(display.slotPose);
|
|
194
|
+
const spA = numAt(slotPose, 0, 1);
|
|
195
|
+
const spB = numAt(slotPose, 1, 0);
|
|
196
|
+
const spC = numAt(slotPose, 2, 0);
|
|
197
|
+
const spD = numAt(slotPose, 3, 1);
|
|
198
|
+
const spTx = numAt(slotPose, 4, 0);
|
|
199
|
+
const spTy = numAt(slotPose, 5, 0);
|
|
200
|
+
const usedBoneCount = Math.floor(bonePose.length / 7);
|
|
201
|
+
const influenceCounts = new Uint16Array(vertexCount);
|
|
202
|
+
const influences = [];
|
|
203
|
+
let recovered = false;
|
|
204
|
+
let iW = 0;
|
|
205
|
+
for (let v = 0; v < vertexCount; v++) {
|
|
206
|
+
if (iW >= weights.length) {
|
|
207
|
+
recovered = true;
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
const declaredCount = weights[iW++] | 0;
|
|
211
|
+
const vx = numAt(verts, v * 2, 0);
|
|
212
|
+
const vy = numAt(verts, v * 2 + 1, 0);
|
|
213
|
+
const sx = spA * vx + spC * vy + spTx;
|
|
214
|
+
const sy = spB * vx + spD * vy + spTy;
|
|
215
|
+
let realCount = 0;
|
|
216
|
+
for (let j = 0; j < declaredCount; j++) {
|
|
217
|
+
if (iW + 1 >= weights.length) {
|
|
218
|
+
recovered = true;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
const rawBoneIndex = weights[iW++] | 0;
|
|
222
|
+
const weight = weights[iW++];
|
|
223
|
+
const ordinal = findBonePoseOrdinal(bonePose, usedBoneCount, rawBoneIndex);
|
|
224
|
+
if (ordinal < 0) {
|
|
225
|
+
recovered = true;
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
const o = ordinal * 7;
|
|
229
|
+
const ba = bonePose[o + 1];
|
|
230
|
+
const bb = bonePose[o + 2];
|
|
231
|
+
const bc = bonePose[o + 3];
|
|
232
|
+
const bd = bonePose[o + 4];
|
|
233
|
+
const btx = bonePose[o + 5];
|
|
234
|
+
const bty = bonePose[o + 6];
|
|
235
|
+
const det = ba * bd - bb * bc;
|
|
236
|
+
if (det === 0) {
|
|
237
|
+
recovered = true;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
const inv = 1 / det;
|
|
241
|
+
// Inverse of the bind matrix, then apply it to the slotPose-transformed vertex → bind-local offset.
|
|
242
|
+
const ia = bd * inv;
|
|
243
|
+
const ib = -bb * inv;
|
|
244
|
+
const ic = -bc * inv;
|
|
245
|
+
const id = ba * inv;
|
|
246
|
+
const itx = (bc * bty - bd * btx) * inv;
|
|
247
|
+
const ity = (bb * btx - ba * bty) * inv;
|
|
248
|
+
influences.push(remapBoneIndex(rawBoneIndex), ia * sx + ic * sy + itx, ib * sx + id * sy + ity, weight);
|
|
249
|
+
realCount++;
|
|
250
|
+
}
|
|
251
|
+
influenceCounts[v] = realCount;
|
|
252
|
+
}
|
|
253
|
+
if (recovered) {
|
|
254
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Recover, 'dragonbones.weighted-mesh-recovered', 'parseDragonBonesSkeleton', { meshes: 1 });
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
kind: MeshAttachment2DKind,
|
|
258
|
+
name: typeof display.name === 'string' ? display.name : null,
|
|
259
|
+
skin: { influenceCounts, influences: Float32Array.from(influences) },
|
|
260
|
+
triangles: toUint16Array(display.triangles),
|
|
261
|
+
uvs,
|
|
262
|
+
vertexCount,
|
|
263
|
+
vertices: null,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// Maps a slot's `display` array to Flight attachments, POSITION-PRESERVING: result index i is displayIndex
|
|
267
|
+
// i. Image → RegionAttachment2D; every other display type is unmodeled in this increment and held as `null`
|
|
268
|
+
// + a Skip crumb (via parseDragonBonesDisplay), so displayIndex stays aligned.
|
|
269
|
+
function parseDragonBonesDisplayList(raw, remapBoneIndex, diagnostics) {
|
|
270
|
+
const displays = [];
|
|
271
|
+
if (!Array.isArray(raw))
|
|
272
|
+
return displays;
|
|
273
|
+
for (const rawDisplay of raw)
|
|
274
|
+
displays.push(parseDragonBonesDisplay(rawDisplay, remapBoneIndex, diagnostics));
|
|
275
|
+
return displays;
|
|
276
|
+
}
|
|
277
|
+
// A DragonBones image display → RegionAttachment2D. Its `transform` places the region in the slot's local
|
|
278
|
+
// space; width/height come from the texture atlas (the `.atlas` sidecar, spritesheet-formats' domain) and
|
|
279
|
+
// are left 0 here to be resolved at atlas-binding time, mirroring how a display references its region by name.
|
|
280
|
+
function parseDragonBonesRegionDisplay(display) {
|
|
281
|
+
const transform = parseDragonBonesBoneTransform(display.transform);
|
|
282
|
+
return {
|
|
283
|
+
height: 0,
|
|
284
|
+
kind: RegionAttachment2DKind,
|
|
285
|
+
name: typeof display.name === 'string' ? display.name : null,
|
|
286
|
+
rotation: transform.rotation,
|
|
287
|
+
scaleX: transform.scaleX,
|
|
288
|
+
scaleY: transform.scaleY,
|
|
289
|
+
width: 0,
|
|
290
|
+
x: transform.x,
|
|
291
|
+
y: transform.y,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
// DragonBones slots bind a bone to their shown display; `slot` array order is the draw order. `boneIndex`
|
|
295
|
+
// resolves the slot's `parent` (a bone name) to the output bone index; the shown attachment is the display
|
|
296
|
+
// at `displayIndex` (default 0; negative = none) in the default skin's display list for this slot; `color`
|
|
297
|
+
// is the slot's ColorTransform tint.
|
|
298
|
+
function parseDragonBonesSlots(raw, boneIndexByName, skin, diagnostics) {
|
|
299
|
+
const slots = [];
|
|
300
|
+
if (!Array.isArray(raw))
|
|
301
|
+
return slots;
|
|
302
|
+
for (const entry of raw) {
|
|
303
|
+
if (entry === null || typeof entry !== 'object')
|
|
304
|
+
continue;
|
|
305
|
+
const slot = entry;
|
|
306
|
+
const name = typeof slot.name === 'string' ? slot.name : null;
|
|
307
|
+
const boneIndex = typeof slot.parent === 'string' ? (boneIndexByName.get(slot.parent) ?? -1) : -1;
|
|
308
|
+
const displayIndex = numberOr(slot.displayIndex, 0) | 0;
|
|
309
|
+
let attachment = null;
|
|
310
|
+
if (name !== null && displayIndex >= 0) {
|
|
311
|
+
const displays = skin.get(name);
|
|
312
|
+
if (displays !== undefined && displayIndex < displays.length)
|
|
313
|
+
attachment = displays[displayIndex];
|
|
314
|
+
}
|
|
315
|
+
slots.push({ attachment, boneIndex, color: parseDragonBonesColor(slot.color, diagnostics), name });
|
|
316
|
+
}
|
|
317
|
+
return slots;
|
|
318
|
+
}
|
|
319
|
+
function boolOr(value, fallback) {
|
|
320
|
+
return typeof value === 'boolean' ? value : fallback;
|
|
321
|
+
}
|
|
322
|
+
// One DragonBones multiply-color channel (0–100 percent) → an 0–255 byte, clamped.
|
|
323
|
+
function colorChannel(value) {
|
|
324
|
+
return Math.max(0, Math.min(255, Math.round((numberOr(value, 100) / 100) * 255)));
|
|
325
|
+
}
|
|
326
|
+
// The ordinal (0-based position in `bonePose`, 7 numbers each: [rawBoneIndex, a, b, c, d, tx, ty]) of the
|
|
327
|
+
// used bone whose armature file-order index is `rawBoneIndex`, or -1 if this mesh's bind pose omits it.
|
|
328
|
+
function findBonePoseOrdinal(bonePose, usedBoneCount, rawBoneIndex) {
|
|
329
|
+
for (let i = 0; i < usedBoneCount; i++) {
|
|
330
|
+
if (bonePose[i * 7] === rawBoneIndex)
|
|
331
|
+
return i;
|
|
332
|
+
}
|
|
333
|
+
return -1;
|
|
334
|
+
}
|
|
335
|
+
function numAt(values, index, fallback) {
|
|
336
|
+
return index >= 0 && index < values.length && typeof values[index] === 'number' ? values[index] : fallback;
|
|
337
|
+
}
|
|
338
|
+
function numberArray(value) {
|
|
339
|
+
return Array.isArray(value) ? value : [];
|
|
340
|
+
}
|
|
341
|
+
function toFloat32Array(value) {
|
|
342
|
+
return Array.isArray(value) ? Float32Array.from(value) : new Float32Array();
|
|
343
|
+
}
|
|
344
|
+
function toUint16Array(value) {
|
|
345
|
+
return Array.isArray(value) ? Uint16Array.from(value) : new Uint16Array();
|
|
346
|
+
}
|
|
347
|
+
// Maps a DragonBones bone's nested `transform` block to Flight's local TRS + shear fields. DragonBones stores
|
|
348
|
+
// two skew angles in degrees: `skX`/`skY` (older) or `rotate`/`skew` (5.x) — its `Transform` reads
|
|
349
|
+
// rotation = rotate (else skY) and skew = skew (else skX − skY). Its toMatrix
|
|
350
|
+
// (a=sX·cos(rotation), b=sX·sin(rotation), c=−sY·sin(rotation+skew), d=sY·cos(rotation+skew)) equals Flight's
|
|
351
|
+
// Bone2D local matrix under `Bone2D.rotation = rotation`, `shearX = 0`, `shearY = skew` (see charter #4).
|
|
352
|
+
function parseDragonBonesBoneTransform(raw) {
|
|
353
|
+
const t = raw !== null && typeof raw === 'object' ? raw : {};
|
|
354
|
+
let rotation;
|
|
355
|
+
let shearY;
|
|
356
|
+
if ('rotate' in t || 'skew' in t) {
|
|
357
|
+
rotation = numberOr(t.rotate, 0);
|
|
358
|
+
shearY = numberOr(t.skew, 0);
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
rotation = numberOr(t.skY, 0);
|
|
362
|
+
shearY = numberOr(t.skX, 0) - rotation;
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
rotation,
|
|
366
|
+
scaleX: numberOr(t.scX, 1),
|
|
367
|
+
scaleY: numberOr(t.scY, 1),
|
|
368
|
+
shearY,
|
|
369
|
+
x: numberOr(t.x, 0),
|
|
370
|
+
y: numberOr(t.y, 0),
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
// DragonBones lists bones in no guaranteed parent order and references parents by name, so bones are emitted
|
|
374
|
+
// in topological order (each parent before its children) with `parentIndex` resolved against the already-
|
|
375
|
+
// emitted set — the invariant `computeSkeleton2DWorldTransforms` and `validateSkeleton2D` require. Bones whose
|
|
376
|
+
// parent never resolves (a dangling reference or a cycle) are emitted last as roots and Skip-crumbed.
|
|
377
|
+
function parseDragonBonesBones(raw, diagnostics) {
|
|
378
|
+
if (!Array.isArray(raw))
|
|
379
|
+
return [];
|
|
380
|
+
const pending = [];
|
|
381
|
+
for (const entry of raw) {
|
|
382
|
+
if (entry === null || typeof entry !== 'object')
|
|
383
|
+
continue;
|
|
384
|
+
const b = entry;
|
|
385
|
+
const transform = parseDragonBonesBoneTransform(b.transform);
|
|
386
|
+
pending.push({
|
|
387
|
+
bone: {
|
|
388
|
+
length: numberOr(b.length, 0),
|
|
389
|
+
name: typeof b.name === 'string' ? b.name : null,
|
|
390
|
+
parentIndex: -1,
|
|
391
|
+
rotation: transform.rotation,
|
|
392
|
+
scaleX: transform.scaleX,
|
|
393
|
+
scaleY: transform.scaleY,
|
|
394
|
+
shearX: 0,
|
|
395
|
+
shearY: transform.shearY,
|
|
396
|
+
transformMode: dragonBonesTransformMode(b, diagnostics),
|
|
397
|
+
x: transform.x,
|
|
398
|
+
y: transform.y,
|
|
399
|
+
},
|
|
400
|
+
parentName: typeof b.parent === 'string' ? b.parent : null,
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
const bones = [];
|
|
404
|
+
const indexByName = new Map();
|
|
405
|
+
let advanced = true;
|
|
406
|
+
while (pending.length > 0 && advanced) {
|
|
407
|
+
advanced = false;
|
|
408
|
+
for (let i = 0; i < pending.length;) {
|
|
409
|
+
const entry = pending[i];
|
|
410
|
+
if (entry.parentName === null || indexByName.has(entry.parentName)) {
|
|
411
|
+
entry.bone.parentIndex = entry.parentName === null ? -1 : indexByName.get(entry.parentName);
|
|
412
|
+
if (typeof entry.bone.name === 'string')
|
|
413
|
+
indexByName.set(entry.bone.name, bones.length);
|
|
414
|
+
bones.push(entry.bone);
|
|
415
|
+
pending.splice(i, 1);
|
|
416
|
+
advanced = true;
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
i++;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (pending.length > 0) {
|
|
424
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Skip, 'dragonbones.unresolved-bone-parent', 'parseDragonBonesSkeleton', { count: pending.length });
|
|
425
|
+
for (const entry of pending) {
|
|
426
|
+
entry.bone.parentIndex = -1;
|
|
427
|
+
if (typeof entry.bone.name === 'string')
|
|
428
|
+
indexByName.set(entry.bone.name, bones.length);
|
|
429
|
+
bones.push(entry.bone);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return bones;
|
|
433
|
+
}
|
|
434
|
+
// Maps DragonBones' four inheritance booleans onto Flight's five-value TransformMode2D. Position always
|
|
435
|
+
// inherits in Flight (the local origin is placed by the parent), so `inheritTranslation:false` is
|
|
436
|
+
// unmodeled and Skip-crumbed. Two rotation/scale/reflection combinations have no TransformMode2D — keeping
|
|
437
|
+
// rotation+scale while stripping reflection, and keeping scale+reflection while stripping rotation — and are
|
|
438
|
+
// Skip-crumbed, falling back to the closest mode.
|
|
439
|
+
function dragonBonesTransformMode(bone, diagnostics) {
|
|
440
|
+
const inheritRotation = boolOr(bone.inheritRotation, true);
|
|
441
|
+
const inheritScale = boolOr(bone.inheritScale, true);
|
|
442
|
+
const inheritReflection = boolOr(bone.inheritReflection, true);
|
|
443
|
+
if (!boolOr(bone.inheritTranslation, true)) {
|
|
444
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Skip, 'dragonbones.inherit-translation-unsupported', 'parseDragonBonesSkeleton', { bones: 1 });
|
|
445
|
+
}
|
|
446
|
+
if (inheritRotation && inheritScale) {
|
|
447
|
+
if (inheritReflection)
|
|
448
|
+
return TransformMode2D.Normal;
|
|
449
|
+
skipCrumbUnmappedInheritMode(diagnostics);
|
|
450
|
+
return TransformMode2D.Normal;
|
|
451
|
+
}
|
|
452
|
+
if (!inheritRotation && !inheritScale)
|
|
453
|
+
return TransformMode2D.OnlyTranslation;
|
|
454
|
+
if (inheritRotation && !inheritScale) {
|
|
455
|
+
return inheritReflection ? TransformMode2D.NoScale : TransformMode2D.NoScaleOrReflection;
|
|
456
|
+
}
|
|
457
|
+
// !inheritRotation && inheritScale — NoRotationOrReflection also strips reflection, so keeping it is unmapped.
|
|
458
|
+
if (!inheritReflection)
|
|
459
|
+
return TransformMode2D.NoRotationOrReflection;
|
|
460
|
+
skipCrumbUnmappedInheritMode(diagnostics);
|
|
461
|
+
return TransformMode2D.NoRotationOrReflection;
|
|
462
|
+
}
|
|
463
|
+
function numberOr(value, fallback) {
|
|
464
|
+
return typeof value === 'number' ? value : fallback;
|
|
465
|
+
}
|
|
466
|
+
// Reports one aggregated Skip crumb for an unmodeled DragonBones section (slot / skin / animation), with its
|
|
467
|
+
// element count. An absent or empty section is silent.
|
|
468
|
+
function skipCrumbDragonBonesGroup(diagnostics, raw, kind) {
|
|
469
|
+
let count = 0;
|
|
470
|
+
if (Array.isArray(raw))
|
|
471
|
+
count = raw.length;
|
|
472
|
+
else if (raw !== null && typeof raw === 'object')
|
|
473
|
+
count = Object.keys(raw).length;
|
|
474
|
+
if (count > 0)
|
|
475
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Skip, kind, 'parseDragonBonesSkeleton', { count });
|
|
476
|
+
}
|
|
477
|
+
function skipCrumbUnmappedInheritMode(diagnostics) {
|
|
478
|
+
reportImportDiagnostic(diagnostics, ImportDiagnosticSeverity.Skip, 'dragonbones.inherit-mode-unmapped', 'parseDragonBonesSkeleton', { bones: 1 });
|
|
479
|
+
}
|
|
480
|
+
//# sourceMappingURL=dragonBonesParse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dragonBonesParse.js","sourceRoot":"","sources":["../src/dragonBonesParse.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ImportDiagnostic, Skeleton2DImport } from '@flighthq/types/contract';
|
|
2
|
+
export declare function parseSkeleton2D(text: string, diagnostics?: ImportDiagnostic[]): Skeleton2DImport | null;
|
|
3
|
+
export declare function registerSkeleton2DFormat(kind: string, detect: (text: string) => boolean, parse: (text: string, diagnostics?: ImportDiagnostic[]) => Skeleton2DImport | null): void;
|
|
4
|
+
//# sourceMappingURL=skeletonDetect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeletonDetect.d.ts","sourceRoot":"","sources":["../src/skeletonDetect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AA2CnF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,GAAG,IAAI,CAKvG;AAKD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,EACjC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,GAAG,IAAI,GACjF,IAAI,CAEN"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { parseDragonBonesSkeleton } from './dragonBonesParse';
|
|
2
|
+
import { parseSpineSkeleton } from './spineParse';
|
|
3
|
+
let _registry = null;
|
|
4
|
+
function getRegistry() {
|
|
5
|
+
if (_registry !== null)
|
|
6
|
+
return _registry;
|
|
7
|
+
_registry = new Map();
|
|
8
|
+
_registry.set('Spine', { detect: detectSpine, parse: (text, diagnostics) => parseSpineSkeleton(text, diagnostics) });
|
|
9
|
+
_registry.set('DragonBones', {
|
|
10
|
+
detect: detectDragonBones,
|
|
11
|
+
parse: (text, diagnostics) => parseDragonBonesSkeleton(text, diagnostics),
|
|
12
|
+
});
|
|
13
|
+
return _registry;
|
|
14
|
+
}
|
|
15
|
+
// A DragonBones skeleton JSON is an object carrying an `armature` array (its skeleton container). Distinct
|
|
16
|
+
// from Spine, whose bone/slot arrays are top-level rather than nested under an armature.
|
|
17
|
+
function detectDragonBones(text) {
|
|
18
|
+
if (text.trimStart()[0] !== '{')
|
|
19
|
+
return false;
|
|
20
|
+
return /"armature"\s*:/.test(text);
|
|
21
|
+
}
|
|
22
|
+
// A Spine skeleton JSON is an object carrying a `bones`, `skeleton`, or `slots` key. (The `.skel` binary is
|
|
23
|
+
// a later format behind this same seam.)
|
|
24
|
+
function detectSpine(text) {
|
|
25
|
+
if (text.trimStart()[0] !== '{')
|
|
26
|
+
return false;
|
|
27
|
+
return /"bones"\s*:/.test(text) || /"skeleton"\s*:/.test(text) || /"slots"\s*:/.test(text);
|
|
28
|
+
}
|
|
29
|
+
// Auto-detects the skeleton format of `text` and parses it, threading the optional diagnostics sink.
|
|
30
|
+
// Returns the sentinel `null` when no registered format recognizes the input (the expected
|
|
31
|
+
// "unrecognized format" failure) or the recognized parser itself rejects it.
|
|
32
|
+
export function parseSkeleton2D(text, diagnostics) {
|
|
33
|
+
for (const entry of getRegistry().values()) {
|
|
34
|
+
if (entry.detect(text))
|
|
35
|
+
return entry.parse(text, diagnostics);
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
// Registers (or, last-write-wins, overrides) a skeleton format under `kind` (vendor-prefix a custom one,
|
|
40
|
+
// e.g. `'acme.Rig'`; bare names are reserved for built-ins). `detect` decides whether a text is this
|
|
41
|
+
// format; `parse` maps it to a Skeleton2DImport (or `null` on rejection).
|
|
42
|
+
export function registerSkeleton2DFormat(kind, detect, parse) {
|
|
43
|
+
getRegistry().set(kind, { detect, parse });
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=skeletonDetect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeletonDetect.js","sourceRoot":"","sources":["../src/skeletonDetect.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAUlD,IAAI,SAAS,GAA4C,IAAI,CAAC;AAE9D,SAAS,WAAW;IAClB,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IACzC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;IACtB,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IACrH,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE;QAC3B,MAAM,EAAE,iBAAiB;QACzB,KAAK,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,wBAAwB,CAAC,IAAI,EAAE,WAAW,CAAC;KAC1E,CAAC,CAAC;IACH,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,2GAA2G;AAC3G,yFAAyF;AACzF,SAAS,iBAAiB,CAAC,IAAY;IACrC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,4GAA4G;AAC5G,yCAAyC;AACzC,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7F,CAAC;AAED,qGAAqG;AACrG,2FAA2F;AAC3F,6EAA6E;AAC7E,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,WAAgC;IAC5E,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yGAAyG;AACzG,qGAAqG;AACrG,0EAA0E;AAC1E,MAAM,UAAU,wBAAwB,CACtC,IAAY,EACZ,MAAiC,EACjC,KAAkF;IAElF,WAAW,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spineParse.d.ts","sourceRoot":"","sources":["../src/spineParse.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGV,gBAAgB,EAGhB,gBAAgB,EAIjB,MAAM,0BAA0B,CAAC;AAoBlC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,GAAG,IAAI,CAc1G"}
|