@flighthq/skeleton2d 0.3.0-next.1729.f927a3b → 0.3.0-next.1781.5d072ef

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.
Files changed (63) hide show
  1. package/dist/contract.d.ts +8 -0
  2. package/dist/contract.d.ts.map +1 -1
  3. package/dist/contract.js +8 -0
  4. package/dist/contract.js.map +1 -1
  5. package/dist/deformMeshAttachment2D.d.ts +1 -1
  6. package/dist/deformMeshAttachment2D.d.ts.map +1 -1
  7. package/dist/deformMeshAttachment2D.js +30 -5
  8. package/dist/deformMeshAttachment2D.js.map +1 -1
  9. package/dist/deformPathAttachment2D.d.ts +3 -0
  10. package/dist/deformPathAttachment2D.d.ts.map +1 -0
  11. package/dist/deformPathAttachment2D.js +91 -0
  12. package/dist/deformPathAttachment2D.js.map +1 -0
  13. package/dist/enableSkeleton2DGuards.d.ts +22 -0
  14. package/dist/enableSkeleton2DGuards.d.ts.map +1 -0
  15. package/dist/enableSkeleton2DGuards.js +42 -0
  16. package/dist/enableSkeleton2DGuards.js.map +1 -0
  17. package/dist/explainSkeleton2DChannel.d.ts +20 -0
  18. package/dist/explainSkeleton2DChannel.d.ts.map +1 -0
  19. package/dist/explainSkeleton2DChannel.js +33 -0
  20. package/dist/explainSkeleton2DChannel.js.map +1 -0
  21. package/dist/ikConstraint2D.d.ts +4 -0
  22. package/dist/ikConstraint2D.d.ts.map +1 -0
  23. package/dist/ikConstraint2D.js +162 -0
  24. package/dist/ikConstraint2D.js.map +1 -0
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/pathConstraint2D.d.ts +4 -0
  30. package/dist/pathConstraint2D.d.ts.map +1 -0
  31. package/dist/pathConstraint2D.js +171 -0
  32. package/dist/pathConstraint2D.js.map +1 -0
  33. package/dist/skeleton2d.d.ts +1 -0
  34. package/dist/skeleton2d.d.ts.map +1 -1
  35. package/dist/skeleton2d.js +21 -9
  36. package/dist/skeleton2d.js.map +1 -1
  37. package/dist/skeleton2dAnimationTarget.d.ts.map +1 -1
  38. package/dist/skeleton2dAnimationTarget.js +29 -0
  39. package/dist/skeleton2dAnimationTarget.js.map +1 -1
  40. package/dist/skeleton2dConstraint.d.ts +6 -0
  41. package/dist/skeleton2dConstraint.d.ts.map +1 -0
  42. package/dist/skeleton2dConstraint.js +37 -0
  43. package/dist/skeleton2dConstraint.js.map +1 -0
  44. package/dist/skeleton2dGuards.d.ts +16 -0
  45. package/dist/skeleton2dGuards.d.ts.map +1 -0
  46. package/dist/skeleton2dGuards.js +29 -0
  47. package/dist/skeleton2dGuards.js.map +1 -0
  48. package/dist/transformConstraint2D.d.ts +4 -0
  49. package/dist/transformConstraint2D.d.ts.map +1 -0
  50. package/dist/transformConstraint2D.js +113 -0
  51. package/dist/transformConstraint2D.js.map +1 -0
  52. package/package.json +10 -6
  53. package/src/applyAnimationClipToSkeleton2D.test.ts +72 -0
  54. package/src/deformMeshAttachment2D.test.ts +85 -1
  55. package/src/deformPathAttachment2D.test.ts +193 -0
  56. package/src/enableSkeleton2DGuards.test.ts +88 -0
  57. package/src/explainSkeleton2DChannel.test.ts +45 -0
  58. package/src/ikConstraint2D.test.ts +211 -0
  59. package/src/pathConstraint2D.test.ts +226 -0
  60. package/src/skeleton2d.test.ts +36 -2
  61. package/src/skeleton2dConstraint.test.ts +105 -0
  62. package/src/skeleton2dGuards.test.ts +80 -0
  63. package/src/transformConstraint2D.test.ts +165 -0
@@ -3,4 +3,12 @@ export * from './deformMeshAttachment2D';
3
3
  export * from './regionAttachment2D';
4
4
  export * from './applyAnimationClipToSkeleton2D';
5
5
  export * from './skeleton2dAnimationTarget';
6
+ export * from './deformPathAttachment2D';
7
+ export * from './skeleton2dConstraint';
8
+ export * from './ikConstraint2D';
9
+ export * from './transformConstraint2D';
10
+ export * from './pathConstraint2D';
11
+ export * from './skeleton2dGuards';
12
+ export * from './enableSkeleton2DGuards';
13
+ export * from './explainSkeleton2DChannel';
6
14
  //# sourceMappingURL=contract.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC"}
package/dist/contract.js CHANGED
@@ -3,4 +3,12 @@ export * from './deformMeshAttachment2D';
3
3
  export * from './regionAttachment2D';
4
4
  export * from './applyAnimationClipToSkeleton2D';
5
5
  export * from './skeleton2dAnimationTarget';
6
+ export * from './deformPathAttachment2D';
7
+ export * from './skeleton2dConstraint';
8
+ export * from './ikConstraint2D';
9
+ export * from './transformConstraint2D';
10
+ export * from './pathConstraint2D';
11
+ export * from './skeleton2dGuards';
12
+ export * from './enableSkeleton2DGuards';
13
+ export * from './explainSkeleton2DChannel';
6
14
  //# sourceMappingURL=contract.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import type { MeshAttachment2D, Skeleton2D } from '@flighthq/types/contract';
2
- export declare function deformSkeleton2DMeshAttachment(out: Float32Array, attachment: Readonly<MeshAttachment2D>, skeleton: Readonly<Skeleton2D>, boneIndex: number): void;
2
+ export declare function deformSkeleton2DMeshAttachment(out: Float32Array, attachment: Readonly<MeshAttachment2D>, skeleton: Readonly<Skeleton2D>, boneIndex: number, deform?: Readonly<Float32Array> | null): void;
3
3
  //# sourceMappingURL=deformMeshAttachment2D.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deformMeshAttachment2D.d.ts","sourceRoot":"","sources":["../src/deformMeshAttachment2D.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAgB7E,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,YAAY,EACjB,UAAU,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EACtC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC9B,SAAS,EAAE,MAAM,GAChB,IAAI,CA4CN"}
1
+ {"version":3,"file":"deformMeshAttachment2D.d.ts","sourceRoot":"","sources":["../src/deformMeshAttachment2D.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AA+B7E,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,YAAY,EACjB,UAAU,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EACtC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,IAAW,GAC3C,IAAI,CAuDN"}
@@ -1,3 +1,4 @@
1
+ import { reportSkeleton2DDeformLengthMismatch } from './skeleton2dGuards';
1
2
  // 6 floats per bone in the flat world-transform buffer (a, b, c, d, tx, ty).
2
3
  const MATRIX_STRIDE = 6;
3
4
  // Deforms a MeshAttachment2D's vertices into flat interleaved world positions `[x0, y0, x1, y1, …]` in
@@ -11,13 +12,32 @@ const MATRIX_STRIDE = 6;
11
12
  // RIGID (attachment.skin null): the mesh's setup-pose local `vertices` are transformed by bone
12
13
  // `boneIndex`'s (the slot's bone) world matrix. Alias-safe — each vertex is read into locals before its
13
14
  // output is written, so `out` may be the same buffer as `attachment.vertices`.
14
- export function deformSkeleton2DMeshAttachment(out, attachment, skeleton, boneIndex) {
15
+ //
16
+ // `deform` is the animated offset stream layered on top of the skinning, or null for the undeformed
17
+ // attachment. It is ADDRESSED BY WHATEVER THE ATTACHMENT STORES ITS POSITIONS AS, which is the one rule
18
+ // that makes deform work for meshes and paths alike: a weighted attachment's offsets parallel its
19
+ // INFLUENCE stream (two floats per influence, so a vertex with three bones consumes three pairs), and a
20
+ // rigid one's parallel its vertex stream. Offsets are in the same space as what they displace — bone-local
21
+ // for a weighted attachment, so they are added BEFORE the weighted sum. Adding them to the world position
22
+ // afterwards would put a bone-local displacement into world space, which looks correct at rest and wrong
23
+ // the moment the rig moves.
24
+ //
25
+ // A `deform` too short for the stream it parallels is ignored entirely rather than read past: an importer
26
+ // sizing that buffer from vertex count instead of influence count is an expected failure, not a
27
+ // programmer error, so it takes the sentinel.
28
+ export function deformSkeleton2DMeshAttachment(out, attachment, skeleton, boneIndex, deform = null) {
15
29
  const world = skeleton.worldMatrices;
16
30
  const skin = attachment.skin;
17
31
  if (skin !== null && skin !== undefined) {
18
32
  const counts = skin.influenceCounts;
19
33
  const inf = skin.influences;
34
+ // Hoisted out of the loop: a rig with no deform timeline pays one test for the whole attachment.
35
+ const offsets = deform !== null && deform.length * 2 >= inf.length ? deform : null;
36
+ if (deform !== null && offsets === null) {
37
+ reportSkeleton2DDeformLengthMismatch('MeshAttachment2D', deform.length, inf.length / 2);
38
+ }
20
39
  let vi = 0; // influence-stream cursor (stride 4: boneIndex, localX, localY, weight)
40
+ let di = 0; // deform cursor (stride 2, one pair per influence)
21
41
  let oi = 0; // output cursor (stride 2)
22
42
  for (let v = 0; v < counts.length; v++) {
23
43
  let wx = 0;
@@ -25,12 +45,13 @@ export function deformSkeleton2DMeshAttachment(out, attachment, skeleton, boneIn
25
45
  const n = counts[v];
26
46
  for (let k = 0; k < n; k++) {
27
47
  const b = inf[vi] * MATRIX_STRIDE;
28
- const lx = inf[vi + 1];
29
- const ly = inf[vi + 2];
48
+ const lx = offsets === null ? inf[vi + 1] : inf[vi + 1] + offsets[di];
49
+ const ly = offsets === null ? inf[vi + 2] : inf[vi + 2] + offsets[di + 1];
30
50
  const weight = inf[vi + 3];
31
51
  wx += weight * (world[b] * lx + world[b + 2] * ly + world[b + 4]);
32
52
  wy += weight * (world[b + 1] * lx + world[b + 3] * ly + world[b + 5]);
33
53
  vi += 4;
54
+ di += 2;
34
55
  }
35
56
  out[oi] = wx;
36
57
  out[oi + 1] = wy;
@@ -42,6 +63,10 @@ export function deformSkeleton2DMeshAttachment(out, attachment, skeleton, boneIn
42
63
  const vertices = attachment.vertices;
43
64
  if (vertices === null || vertices === undefined)
44
65
  return;
66
+ const offsets = deform !== null && deform.length >= vertices.length ? deform : null;
67
+ if (deform !== null && offsets === null) {
68
+ reportSkeleton2DDeformLengthMismatch('MeshAttachment2D', deform.length, vertices.length);
69
+ }
45
70
  const b = boneIndex * MATRIX_STRIDE;
46
71
  const a = world[b];
47
72
  const bb = world[b + 1];
@@ -50,8 +75,8 @@ export function deformSkeleton2DMeshAttachment(out, attachment, skeleton, boneIn
50
75
  const tx = world[b + 4];
51
76
  const ty = world[b + 5];
52
77
  for (let i = 0; i < vertices.length; i += 2) {
53
- const vx = vertices[i];
54
- const vy = vertices[i + 1];
78
+ const vx = offsets === null ? vertices[i] : vertices[i] + offsets[i];
79
+ const vy = offsets === null ? vertices[i + 1] : vertices[i + 1] + offsets[i + 1];
55
80
  out[i] = a * vx + c * vy + tx;
56
81
  out[i + 1] = bb * vx + d * vy + ty;
57
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"deformMeshAttachment2D.js","sourceRoot":"","sources":["../src/deformMeshAttachment2D.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deformMeshAttachment2D.js","sourceRoot":"","sources":["../src/deformMeshAttachment2D.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Path, PathAttachment2D, Skeleton2D } from '@flighthq/types/contract';
2
+ export declare function deformSkeleton2DPathAttachment(out: Path, attachment: Readonly<PathAttachment2D>, skeleton: Readonly<Skeleton2D>, boneIndex: number, deform?: Readonly<Float32Array> | null): void;
3
+ //# sourceMappingURL=deformPathAttachment2D.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deformPathAttachment2D.d.ts","sourceRoot":"","sources":["../src/deformPathAttachment2D.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AA8BnF,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,IAAI,EACT,UAAU,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EACtC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,EAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,IAAW,GAC3C,IAAI,CA+DN"}
@@ -0,0 +1,91 @@
1
+ import { reportSkeleton2DDeformLengthMismatch } from './skeleton2dGuards';
2
+ // 6 floats per bone in the flat world-transform buffer (a, b, c, d, tx, ty).
3
+ const MATRIX_STRIDE = 6;
4
+ // Deforms a PathAttachment2D into `out`, filling its `data` with world coordinates under the attachment's
5
+ // own verb stream. Requires `computeSkeleton2DWorldTransforms` to have filled `skeleton.worldMatrices`.
6
+ // Out-parameter; allocates only when `out`'s arrays have to grow to fit.
7
+ //
8
+ // The math is the same as `deformSkeleton2DMeshAttachment` — deliberately so. A skinned point is a
9
+ // skinned point whether a triangle or a curve reads it, and Skin2D carries no triangles and no UVs, so it
10
+ // was already geometry-agnostic. Only the output target differs: a Path's `data` stream instead of an
11
+ // interleaved vertex buffer.
12
+ //
13
+ // CONTROL POINTS NEED NO SPECIAL CASE HERE, and that is by construction rather than by luck: a cubic
14
+ // handle is given its anchor's influence set at IMPORT (see PathAttachment2D), so it arrives as an
15
+ // ordinary entry in the influence stream. Nothing below distinguishes an anchor from a handle, which is
16
+ // exactly why a curve cannot end up with its anchors moved and its handles left behind, or with its
17
+ // tangents sheared by influences blended across a segment.
18
+ //
19
+ // `deform` is the animated offset stream layered on top of the skinning, addressed the same way the mesh
20
+ // deformer addresses it: parallel to the INFLUENCE stream when weighted (two floats per influence),
21
+ // parallel to the coordinate stream when rigid, and applied to the BONE-LOCAL offset before the weighted
22
+ // sum. A stream too short for what it parallels is ignored rather than read past.
23
+ //
24
+ // This writes coordinates and never queries geometry, so it needs the `Path` TYPE and no function from
25
+ // `@flighthq/path`. That is the whole reason path skinning can live here beside mesh skinning instead of
26
+ // in a package that depends on the path kernel.
27
+ export function deformSkeleton2DPathAttachment(out, attachment, skeleton, boneIndex, deform = null) {
28
+ const commands = attachment.commands;
29
+ const data = out.data;
30
+ const outCommands = out.commands;
31
+ outCommands.length = commands.length;
32
+ for (let i = 0; i < commands.length; i++)
33
+ outCommands[i] = commands[i];
34
+ out.winding = attachment.winding;
35
+ data.length = attachment.pointCount * 2;
36
+ const world = skeleton.worldMatrices;
37
+ const skin = attachment.skin;
38
+ if (skin !== null && skin !== undefined) {
39
+ const counts = skin.influenceCounts;
40
+ const inf = skin.influences;
41
+ // Hoisted out of the loop: a rig with no deform timeline pays one test for the whole attachment.
42
+ const offsets = deform !== null && deform.length * 2 >= inf.length ? deform : null;
43
+ if (deform !== null && offsets === null) {
44
+ reportSkeleton2DDeformLengthMismatch('PathAttachment2D', deform.length, inf.length / 2);
45
+ }
46
+ let vi = 0; // influence-stream cursor (stride 4: boneIndex, localX, localY, weight)
47
+ let di = 0; // deform cursor (stride 2, one pair per influence)
48
+ let oi = 0; // output cursor (stride 2)
49
+ for (let v = 0; v < counts.length; v++) {
50
+ let wx = 0;
51
+ let wy = 0;
52
+ const n = counts[v];
53
+ for (let k = 0; k < n; k++) {
54
+ const b = inf[vi] * MATRIX_STRIDE;
55
+ const lx = offsets === null ? inf[vi + 1] : inf[vi + 1] + offsets[di];
56
+ const ly = offsets === null ? inf[vi + 2] : inf[vi + 2] + offsets[di + 1];
57
+ const weight = inf[vi + 3];
58
+ wx += weight * (world[b] * lx + world[b + 2] * ly + world[b + 4]);
59
+ wy += weight * (world[b + 1] * lx + world[b + 3] * ly + world[b + 5]);
60
+ vi += 4;
61
+ di += 2;
62
+ }
63
+ data[oi] = wx;
64
+ data[oi + 1] = wy;
65
+ oi += 2;
66
+ }
67
+ return;
68
+ }
69
+ // Rigid path: every point follows one bone's world transform.
70
+ const vertices = attachment.vertices;
71
+ if (vertices === null || vertices === undefined)
72
+ return;
73
+ const offsets = deform !== null && deform.length >= vertices.length ? deform : null;
74
+ if (deform !== null && offsets === null) {
75
+ reportSkeleton2DDeformLengthMismatch('PathAttachment2D', deform.length, vertices.length);
76
+ }
77
+ const b = boneIndex * MATRIX_STRIDE;
78
+ const a = world[b];
79
+ const bb = world[b + 1];
80
+ const c = world[b + 2];
81
+ const d = world[b + 3];
82
+ const tx = world[b + 4];
83
+ const ty = world[b + 5];
84
+ for (let i = 0; i < vertices.length; i += 2) {
85
+ const vx = offsets === null ? vertices[i] : vertices[i] + offsets[i];
86
+ const vy = offsets === null ? vertices[i + 1] : vertices[i + 1] + offsets[i + 1];
87
+ data[i] = a * vx + c * vy + tx;
88
+ data[i + 1] = bb * vx + d * vy + ty;
89
+ }
90
+ }
91
+ //# sourceMappingURL=deformPathAttachment2D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deformPathAttachment2D.js","sourceRoot":"","sources":["../src/deformPathAttachment2D.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export declare function disableSkeleton2DGuards(): void;
2
+ /**
3
+ * Installs the caller-facing skeleton guards (opt-in, dev-only). Idempotent.
4
+ *
5
+ * This package does two things that are **correct and invisible**, which is the combination worth
6
+ * announcing. Neither is a bug to fix — coercing is right in both cases — but a coercion nobody can see
7
+ * is indistinguishable from the file having been authored that way, so an author who set an easing and
8
+ * never saw it take effect has no way to find out why.
9
+ *
10
+ * 1. **A non-blendable channel is walked as steps** whatever its track claims. An attachment index
11
+ * blended between two table entries names art that was never authored; a draw order blended between
12
+ * two orderings yields fractional sort keys and a sequence nobody wrote.
13
+ * 2. **A deform offset stream whose length does not match the vertex stream it addresses is ignored.**
14
+ * There is no correct prefix to consume, so applying what fits would deform some vertices and leave
15
+ * others behind, and reading past the buffer is never an option.
16
+ *
17
+ * The messages live here rather than beside the code that knows the fact, so a shipped build that never
18
+ * imports this module carries neither them nor `@flighthq/log`. Every case also has a `has*`/`explain*`
19
+ * query for a caller that wants the fact as data instead of a log line.
20
+ */
21
+ export declare function enableSkeleton2DGuards(): void;
22
+ //# sourceMappingURL=enableSkeleton2DGuards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enableSkeleton2DGuards.d.ts","sourceRoot":"","sources":["../src/enableSkeleton2DGuards.ts"],"names":[],"mappings":"AAOA,wBAAgB,uBAAuB,IAAI,IAAI,CAG9C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAG7C"}
@@ -0,0 +1,42 @@
1
+ import { logOnce } from '@flighthq/log/contract';
2
+ import { LogLevel } from '@flighthq/types/contract';
3
+ import { setSkeleton2DCoercedInterpolationGuard, setSkeleton2DDeformLengthGuard } from './skeleton2dGuards';
4
+ // Uninstalls the guards installed by enableSkeleton2DGuards.
5
+ export function disableSkeleton2DGuards() {
6
+ setSkeleton2DCoercedInterpolationGuard(null);
7
+ setSkeleton2DDeformLengthGuard(null);
8
+ }
9
+ /**
10
+ * Installs the caller-facing skeleton guards (opt-in, dev-only). Idempotent.
11
+ *
12
+ * This package does two things that are **correct and invisible**, which is the combination worth
13
+ * announcing. Neither is a bug to fix — coercing is right in both cases — but a coercion nobody can see
14
+ * is indistinguishable from the file having been authored that way, so an author who set an easing and
15
+ * never saw it take effect has no way to find out why.
16
+ *
17
+ * 1. **A non-blendable channel is walked as steps** whatever its track claims. An attachment index
18
+ * blended between two table entries names art that was never authored; a draw order blended between
19
+ * two orderings yields fractional sort keys and a sequence nobody wrote.
20
+ * 2. **A deform offset stream whose length does not match the vertex stream it addresses is ignored.**
21
+ * There is no correct prefix to consume, so applying what fits would deform some vertices and leave
22
+ * others behind, and reading past the buffer is never an option.
23
+ *
24
+ * The messages live here rather than beside the code that knows the fact, so a shipped build that never
25
+ * imports this module carries neither them nor `@flighthq/log`. Every case also has a `has*`/`explain*`
26
+ * query for a caller that wants the fact as data instead of a log line.
27
+ */
28
+ export function enableSkeleton2DGuards() {
29
+ setSkeleton2DCoercedInterpolationGuard(warnOnCoercedInterpolation);
30
+ setSkeleton2DDeformLengthGuard(warnOnDeformLengthMismatch);
31
+ }
32
+ function warnOnCoercedInterpolation(report) {
33
+ logOnce(`skeleton2d:coerced-interpolation:${report.subject}`, LogLevel.Warn, {
34
+ message: `A ${report.subject} channel states '${report.stated}' interpolation but is walked as '${report.applied}'. The value it carries cannot be blended — an attachment index between two table entries names art nobody authored, and a draw order between two orderings gives fractional sort keys — so the step is forced and the stated easing has no effect. Author the track as '${report.applied}' to say what actually happens, or drive a blendable property instead.`,
35
+ }, 'skeleton2d');
36
+ }
37
+ function warnOnDeformLengthMismatch(report) {
38
+ logOnce(`skeleton2d:deform-length:${report.subject}`, LogLevel.Warn, {
39
+ message: `Deform offsets on '${report.subject}' carry ${report.offsets} values but the vertex stream they address needs ${report.addressed}. The offsets are ignored rather than partly applied: a stream of the wrong length has no correct prefix, so consuming what fits would deform some vertices and silently leave the rest in their setup pose. Re-export the attachment, or check that the deform timeline belongs to this attachment.`,
40
+ }, 'skeleton2d');
41
+ }
42
+ //# sourceMappingURL=enableSkeleton2DGuards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enableSkeleton2DGuards.js","sourceRoot":"","sources":["../src/enableSkeleton2DGuards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EAAE,sCAAsC,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAE5G,6DAA6D;AAC7D,MAAM,UAAU,uBAAuB;IACrC,sCAAsC,CAAC,IAAI,CAAC,CAAC;IAC7C,8BAA8B,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,sBAAsB;IACpC,sCAAsC,CAAC,0BAA0B,CAAC,CAAC;IACnE,8BAA8B,CAAC,0BAA0B,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,0BAA0B,CAAC,MAAgD;IAClF,OAAO,CACL,oCAAoC,MAAM,CAAC,OAAO,EAAE,EACpD,QAAQ,CAAC,IAAI,EACb;QACE,OAAO,EAAE,KAAK,MAAM,CAAC,OAAO,oBAAoB,MAAM,CAAC,MAAM,qCAAqC,MAAM,CAAC,OAAO,4QAA4Q,MAAM,CAAC,OAAO,wEAAwE;KACnd,EACD,YAAY,CACb,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CAAC,MAAgD;IAClF,OAAO,CACL,4BAA4B,MAAM,CAAC,OAAO,EAAE,EAC5C,QAAQ,CAAC,IAAI,EACb;QACE,OAAO,EAAE,sBAAsB,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC,OAAO,oDAAoD,MAAM,CAAC,SAAS,sSAAsS;KACjb,EACD,YAAY,CACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { AnimationChannel, Skeleton2DCoercedInterpolation } from '@flighthq/types/contract';
2
+ /**
3
+ * Whether this channel's stated interpolation will be overridden, as plain data — the shakeable query
4
+ * beside the guard's log line, for a caller that wants to check a whole clip before playing it rather
5
+ * than watch warnings arrive during playback.
6
+ *
7
+ * Returns `null` when nothing is coerced, which is the common answer. `subject` names the channel
8
+ * family the caller is about to bind the channel as, since the same track is only coerced by virtue of
9
+ * what it drives: an identical `Linear` track is honoured on a bone and stepped on an attachment.
10
+ */
11
+ export declare function explainSkeleton2DChannelInterpolation(channel: Readonly<AnimationChannel>, subject: string): Skeleton2DCoercedInterpolation | null;
12
+ /**
13
+ * Whether a channel family carries a value that cannot be blended, and is therefore walked as steps
14
+ * whatever its track states.
15
+ *
16
+ * Kept a query rather than a field on the target: it is a property of what the channel *drives*, not
17
+ * of the channel, so a caller can ask before it has built a target at all.
18
+ */
19
+ export declare function isSkeleton2DSteppedChannelSubject(subject: string): boolean;
20
+ //# sourceMappingURL=explainSkeleton2DChannel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explainSkeleton2DChannel.d.ts","sourceRoot":"","sources":["../src/explainSkeleton2DChannel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAEjG;;;;;;;;GAQG;AACH,wBAAgB,qCAAqC,CACnD,OAAO,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EACnC,OAAO,EAAE,MAAM,GACd,8BAA8B,GAAG,IAAI,CAKvC;AAED;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE1E"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Whether this channel's stated interpolation will be overridden, as plain data — the shakeable query
3
+ * beside the guard's log line, for a caller that wants to check a whole clip before playing it rather
4
+ * than watch warnings arrive during playback.
5
+ *
6
+ * Returns `null` when nothing is coerced, which is the common answer. `subject` names the channel
7
+ * family the caller is about to bind the channel as, since the same track is only coerced by virtue of
8
+ * what it drives: an identical `Linear` track is honoured on a bone and stepped on an attachment.
9
+ */
10
+ export function explainSkeleton2DChannelInterpolation(channel, subject) {
11
+ if (!isSkeleton2DSteppedChannelSubject(subject))
12
+ return null;
13
+ const stated = channel.track.interpolation;
14
+ if (stated === STEP_INTERPOLATION)
15
+ return null;
16
+ return { applied: STEP_INTERPOLATION, stated, subject };
17
+ }
18
+ /**
19
+ * Whether a channel family carries a value that cannot be blended, and is therefore walked as steps
20
+ * whatever its track states.
21
+ *
22
+ * Kept a query rather than a field on the target: it is a property of what the channel *drives*, not
23
+ * of the channel, so a caller can ask before it has built a target at all.
24
+ */
25
+ export function isSkeleton2DSteppedChannelSubject(subject) {
26
+ return subject === ATTACHMENT_SUBJECT || subject === DRAW_ORDER_SUBJECT;
27
+ }
28
+ // An attachment index blended between two table entries names art nobody authored; a draw order
29
+ // blended between two orderings gives fractional sort keys and a sequence nobody wrote.
30
+ const ATTACHMENT_SUBJECT = 'Attachment';
31
+ const DRAW_ORDER_SUBJECT = 'DrawOrder';
32
+ const STEP_INTERPOLATION = 'Step';
33
+ //# sourceMappingURL=explainSkeleton2DChannel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explainSkeleton2DChannel.js","sourceRoot":"","sources":["../src/explainSkeleton2DChannel.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,qCAAqC,CACnD,OAAmC,EACnC,OAAe;IAEf,IAAI,CAAC,iCAAiC,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC;IAC3C,IAAI,MAAM,KAAK,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC1D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iCAAiC,CAAC,OAAe;IAC/D,OAAO,OAAO,KAAK,kBAAkB,IAAI,OAAO,KAAK,kBAAkB,CAAC;AAC1E,CAAC;AAED,gGAAgG;AAChG,wFAAwF;AACxF,MAAM,kBAAkB,GAAG,YAAY,CAAC;AACxC,MAAM,kBAAkB,GAAG,WAAW,CAAC;AACvC,MAAM,kBAAkB,GAAG,MAAM,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Skeleton2D, Skeleton2DConstraint } from '@flighthq/types/contract';
2
+ export declare function registerSkeleton2DIkConstraintSolver(): void;
3
+ export declare function solveSkeleton2DIkConstraint(skeleton: Skeleton2D, constraint: Readonly<Skeleton2DConstraint>): void;
4
+ //# sourceMappingURL=ikConstraint2D.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ikConstraint2D.d.ts","sourceRoot":"","sources":["../src/ikConstraint2D.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAA0B,MAAM,0BAA0B,CAAC;AAWzG,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAQD,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAelH"}
@@ -0,0 +1,162 @@
1
+ import { RAD_TO_DEG } from '@flighthq/math/contract';
2
+ import { Skeleton2DConstraintKind } from '@flighthq/types/contract';
3
+ import { computeSkeleton2DBoneWorldTransform } from './skeleton2d';
4
+ import { registerSkeleton2DConstraintSolver } from './skeleton2dConstraint';
5
+ // 6 floats per bone in the flat world-transform buffer (a, b, c, d, tx, ty).
6
+ const MATRIX_STRIDE = 6;
7
+ // Opts a bundle into IK. Nothing registers itself, so a rig that never solves IK sheds this whole module —
8
+ // which is the reason constraints are a registry rather than a switch.
9
+ export function registerSkeleton2DIkConstraintSolver() {
10
+ registerSkeleton2DConstraintSolver(Skeleton2DConstraintKind.Ik, solveSkeleton2DIkConstraint);
11
+ }
12
+ // Rotates a one- or two-bone chain so its tip reaches the target bone's world position, writing bone LOCAL
13
+ // rotations (and scales, when stretching or compressing) and refreshing the world matrix of each bone it
14
+ // moves. Descendants below the chain are left for the caller's world pass — see solveSkeleton2DConstraints.
15
+ //
16
+ // A chain of any other length, or an index out of range, is skipped: a rig can carry a constraint this
17
+ // solver does not cover without the whole pose failing.
18
+ export function solveSkeleton2DIkConstraint(skeleton, constraint) {
19
+ const ik = constraint;
20
+ const bones = skeleton.bones;
21
+ const world = skeleton.worldMatrices;
22
+ const target = ik.targetBoneIndex;
23
+ if (target < 0 || target >= bones.length)
24
+ return;
25
+ const targetX = world[target * MATRIX_STRIDE + 4];
26
+ const targetY = world[target * MATRIX_STRIDE + 5];
27
+ const chain = ik.boneIndices;
28
+ if (chain.length === 1) {
29
+ solveSkeleton2DIkChain1(skeleton, chain[0], targetX, targetY, ik);
30
+ return;
31
+ }
32
+ if (chain.length === 2)
33
+ solveSkeleton2DIkChain2(skeleton, chain[0], chain[1], targetX, targetY, ik);
34
+ }
35
+ // One bone: aim its local +x axis at the target. The target's world position is pulled back into the
36
+ // bone's PARENT space, because a bone's rotation field is local — the parent's own rotation is already
37
+ // accounted for by the basis it is expressed in, and comparing world angles instead would double-count it.
38
+ function solveSkeleton2DIkChain1(skeleton, boneIndex, targetX, targetY, ik) {
39
+ const bones = skeleton.bones;
40
+ if (boneIndex < 0 || boneIndex >= bones.length)
41
+ return;
42
+ const bone = bones[boneIndex];
43
+ const local = toSkeleton2DParentSpace(skeleton, boneIndex, targetX, targetY);
44
+ if (local === null)
45
+ return;
46
+ const dx = local.x - bone.x;
47
+ const dy = local.y - bone.y;
48
+ // The shear is subtracted because it is baked into the bone's drawn x axis: the axis points along
49
+ // rotation + shearX, so aiming the AXIS at the target means solving for the rotation behind it.
50
+ const rotation = Math.atan2(dy, dx) * RAD_TO_DEG - bone.shearX;
51
+ bone.rotation += wrapSkeleton2DAngle(rotation - bone.rotation) * ik.mix;
52
+ if (ik.stretch || ik.compress) {
53
+ const reach = Math.hypot(dx, dy);
54
+ const length = bone.length * Math.abs(bone.scaleX);
55
+ if (length > 0) {
56
+ const wanted = reach / length;
57
+ // Stretch only lengthens and compress only shortens, so a chain that already reaches is untouched by
58
+ // either. Both blend by `mix`, so a half-applied constraint stretches half as far.
59
+ if ((wanted > 1 && ik.stretch) || (wanted < 1 && ik.compress)) {
60
+ const scale = 1 + (wanted - 1) * ik.mix;
61
+ bone.scaleX *= scale;
62
+ bone.scaleY *= scale;
63
+ }
64
+ }
65
+ }
66
+ computeSkeleton2DBoneWorldTransform(skeleton, boneIndex);
67
+ }
68
+ // Two bones: place the parent so the child's tip lands on the target — the elbow/knee solve. Both bone
69
+ // lengths are known, so this is the law of cosines rather than an iterative fit: the triangle formed by the
70
+ // parent's origin, the joint and the target has all three sides, so the two interior angles follow
71
+ // directly and `bendPositive` picks which of the two mirror solutions to take.
72
+ function solveSkeleton2DIkChain2(skeleton, parentIndex, childIndex, targetX, targetY, ik) {
73
+ const bones = skeleton.bones;
74
+ if (parentIndex < 0 || parentIndex >= bones.length || childIndex < 0 || childIndex >= bones.length)
75
+ return;
76
+ const parent = bones[parentIndex];
77
+ const child = bones[childIndex];
78
+ const parentLength = parent.length * Math.abs(parent.scaleX);
79
+ const childLength = child.length * Math.abs(child.scaleX);
80
+ if (parentLength <= 0 || childLength <= 0)
81
+ return;
82
+ const local = toSkeleton2DParentSpace(skeleton, parentIndex, targetX, targetY);
83
+ if (local === null)
84
+ return;
85
+ const dx = local.x - parent.x;
86
+ const dy = local.y - parent.y;
87
+ let reach = Math.hypot(dx, dy);
88
+ if (reach <= 0)
89
+ return;
90
+ const span = parentLength + childLength;
91
+ // Out of reach: the chain straightens and points at the target. Stretching scales both bones so the tip
92
+ // lands on it anyway; without stretch the chain simply falls short, which is what a real limb does.
93
+ let bendAngle;
94
+ if (reach >= span) {
95
+ bendAngle = 0;
96
+ // Only the PARENT is scaled. The child inherits its parent's scale, so scaling both would compound —
97
+ // a chain stretched to twice its reach would extend four times as far on its second bone.
98
+ if (ik.stretch) {
99
+ const scale = 1 + (reach / span - 1) * ik.mix;
100
+ parent.scaleX *= scale;
101
+ parent.scaleY *= scale;
102
+ }
103
+ }
104
+ else if (reach <= Math.abs(parentLength - childLength)) {
105
+ // Inside the dead zone the chain folds as far as it can and the tip still cannot reach.
106
+ bendAngle = Math.PI;
107
+ reach = Math.abs(parentLength - childLength);
108
+ }
109
+ else {
110
+ // Law of cosines on the joint angle, measured as the deviation from straight.
111
+ const cosJoint = (parentLength * parentLength + childLength * childLength - reach * reach) / (2 * parentLength * childLength);
112
+ bendAngle = Math.PI - Math.acos(Math.min(1, Math.max(-1, cosJoint)));
113
+ }
114
+ // The parent turns off the straight-at-target direction by the triangle's other interior angle.
115
+ const cosParent = (parentLength * parentLength + reach * reach - childLength * childLength) / (2 * parentLength * reach);
116
+ const parentOffset = reach >= span ? 0 : Math.acos(Math.min(1, Math.max(-1, cosParent)));
117
+ const direction = ik.bendPositive ? 1 : -1;
118
+ const aim = Math.atan2(dy, dx);
119
+ const parentRotation = (aim + parentOffset * direction) * RAD_TO_DEG - parent.shearX;
120
+ parent.rotation += wrapSkeleton2DAngle(parentRotation - parent.rotation) * ik.mix;
121
+ computeSkeleton2DBoneWorldTransform(skeleton, parentIndex);
122
+ // The child's rotation is local to the parent it has just been given, so it is the bend angle directly
123
+ // rather than a world angle — which is why the parent has to be refreshed first. It bends BACK toward
124
+ // the target, opposite the way the parent was swung off the aim line, which is what the negation is.
125
+ const childRotation = -bendAngle * direction * RAD_TO_DEG - child.shearX;
126
+ child.rotation += wrapSkeleton2DAngle(childRotation - child.rotation) * ik.mix;
127
+ computeSkeleton2DBoneWorldTransform(skeleton, childIndex);
128
+ }
129
+ // A world point in the space a bone's local transform is expressed in — its parent's. A root bone's local
130
+ // space IS world space. Returns null for a parent basis with no inverse, which is a bone collapsed to zero
131
+ // scale: there is no meaningful direction to aim along, so the constraint is skipped rather than producing
132
+ // infinities.
133
+ function toSkeleton2DParentSpace(skeleton, boneIndex, x, y) {
134
+ const parentIndex = skeleton.bones[boneIndex].parentIndex;
135
+ if (parentIndex < 0)
136
+ return { x, y };
137
+ const world = skeleton.worldMatrices;
138
+ const p = parentIndex * MATRIX_STRIDE;
139
+ const a = world[p];
140
+ const b = world[p + 1];
141
+ const c = world[p + 2];
142
+ const d = world[p + 3];
143
+ const determinant = a * d - c * b;
144
+ if (Math.abs(determinant) < MINIMUM_DETERMINANT)
145
+ return null;
146
+ const wx = x - world[p + 4];
147
+ const wy = y - world[p + 5];
148
+ return { x: (d * wx - c * wy) / determinant, y: (a * wy - b * wx) / determinant };
149
+ }
150
+ // The shortest signed way round from one angle to another, in degrees. Blending a raw difference would
151
+ // take the long way whenever a solve crosses ±180°, which reads as a limb spinning the wrong way for one
152
+ // frame.
153
+ function wrapSkeleton2DAngle(degrees) {
154
+ let value = degrees % 360;
155
+ if (value > 180)
156
+ value -= 360;
157
+ else if (value < -180)
158
+ value += 360;
159
+ return value;
160
+ }
161
+ const MINIMUM_DETERMINANT = 1e-9;
162
+ //# sourceMappingURL=ikConstraint2D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ikConstraint2D.js","sourceRoot":"","sources":["../src/ikConstraint2D.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { applyAnimationClipToSkeleton2D, cloneSkeleton2D, computeSkeleton2DBoneMatrices, computeSkeleton2DRegionAttachmentVertices, computeSkeleton2DWorldTransforms, createSkeleton2D, createSkeleton2DBoneAnimationTarget, createSkeleton2DSlotAnimationTarget, deformSkeleton2DMeshAttachment, disposeSkeleton2D, equalsSkeleton2D, getSkeleton2DBoneIndexByName, getSkeleton2DBoneWorldMatrix, registerSkeleton2DAnimationTargetBinder, setSkeleton2DBindPose, validateSkeleton2D, } from './contract';
1
+ export { applyAnimationClipToSkeleton2D, cloneSkeleton2D, computeSkeleton2DBoneMatrices, computeSkeleton2DBoneWorldTransform, computeSkeleton2DRegionAttachmentVertices, computeSkeleton2DWorldTransforms, createSkeleton2D, createSkeleton2DBoneAnimationTarget, createSkeleton2DSlotAnimationTarget, deformSkeleton2DMeshAttachment, deformSkeleton2DPathAttachment, disposeSkeleton2D, equalsSkeleton2D, getSkeleton2DBoneIndexByName, getSkeleton2DBoneWorldMatrix, registerSkeleton2DAnimationTargetBinder, registerSkeleton2DConstraintSolver, registerSkeleton2DIkConstraintSolver, registerSkeleton2DPathConstraintSolver, registerSkeleton2DTransformConstraintSolver, setSkeleton2DBindPose, solveSkeleton2DConstraints, validateSkeleton2D, } from './contract';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,eAAe,EACf,6BAA6B,EAC7B,yCAAyC,EACzC,gCAAgC,EAChC,gBAAgB,EAChB,mCAAmC,EACnC,mCAAmC,EACnC,8BAA8B,EAC9B,iBAAiB,EACjB,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,EAC5B,uCAAuC,EACvC,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,eAAe,EACf,6BAA6B,EAC7B,mCAAmC,EACnC,yCAAyC,EACzC,gCAAgC,EAChC,gBAAgB,EAChB,mCAAmC,EACnC,mCAAmC,EACnC,8BAA8B,EAC9B,8BAA8B,EAC9B,iBAAiB,EACjB,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,EAC5B,uCAAuC,EACvC,kCAAkC,EAClC,oCAAoC,EACpC,sCAAsC,EACtC,2CAA2C,EAC3C,qBAAqB,EACrB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { applyAnimationClipToSkeleton2D, cloneSkeleton2D, computeSkeleton2DBoneMatrices, computeSkeleton2DRegionAttachmentVertices, computeSkeleton2DWorldTransforms, createSkeleton2D, createSkeleton2DBoneAnimationTarget, createSkeleton2DSlotAnimationTarget, deformSkeleton2DMeshAttachment, disposeSkeleton2D, equalsSkeleton2D, getSkeleton2DBoneIndexByName, getSkeleton2DBoneWorldMatrix, registerSkeleton2DAnimationTargetBinder, setSkeleton2DBindPose, validateSkeleton2D, } from './contract';
1
+ export { applyAnimationClipToSkeleton2D, cloneSkeleton2D, computeSkeleton2DBoneMatrices, computeSkeleton2DBoneWorldTransform, computeSkeleton2DRegionAttachmentVertices, computeSkeleton2DWorldTransforms, createSkeleton2D, createSkeleton2DBoneAnimationTarget, createSkeleton2DSlotAnimationTarget, deformSkeleton2DMeshAttachment, deformSkeleton2DPathAttachment, disposeSkeleton2D, equalsSkeleton2D, getSkeleton2DBoneIndexByName, getSkeleton2DBoneWorldMatrix, registerSkeleton2DAnimationTargetBinder, registerSkeleton2DConstraintSolver, registerSkeleton2DIkConstraintSolver, registerSkeleton2DPathConstraintSolver, registerSkeleton2DTransformConstraintSolver, setSkeleton2DBindPose, solveSkeleton2DConstraints, validateSkeleton2D, } from './contract';
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,eAAe,EACf,6BAA6B,EAC7B,yCAAyC,EACzC,gCAAgC,EAChC,gBAAgB,EAChB,mCAAmC,EACnC,mCAAmC,EACnC,8BAA8B,EAC9B,iBAAiB,EACjB,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,EAC5B,uCAAuC,EACvC,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,eAAe,EACf,6BAA6B,EAC7B,mCAAmC,EACnC,yCAAyC,EACzC,gCAAgC,EAChC,gBAAgB,EAChB,mCAAmC,EACnC,mCAAmC,EACnC,8BAA8B,EAC9B,8BAA8B,EAC9B,iBAAiB,EACjB,gBAAgB,EAChB,4BAA4B,EAC5B,4BAA4B,EAC5B,uCAAuC,EACvC,kCAAkC,EAClC,oCAAoC,EACpC,sCAAsC,EACtC,2CAA2C,EAC3C,qBAAqB,EACrB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Skeleton2D, Skeleton2DConstraint } from '@flighthq/types/contract';
2
+ export declare function registerSkeleton2DPathConstraintSolver(): void;
3
+ export declare function solveSkeleton2DPathConstraint(skeleton: Skeleton2D, constraint: Readonly<Skeleton2DConstraint>): void;
4
+ //# sourceMappingURL=pathConstraint2D.d.ts.map