framefields 2.9.0 → 2.9.2

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 (41) hide show
  1. package/dist/cli/check-worker.mjs +2 -2
  2. package/dist/components/index.d.mts +2 -2
  3. package/dist/components/index.mjs +2 -2
  4. package/dist/effects/index.d.mts +1 -1
  5. package/dist/effects/index.mjs +1 -1
  6. package/dist/{index-CZjrnylh.d.mts → index-Bnh42ouE.d.mts} +657 -636
  7. package/dist/index-Bnh42ouE.d.mts.map +1 -0
  8. package/dist/index-CFoAmh7q.d.mts.map +1 -1
  9. package/dist/{index-Du5YgdzM.d.mts → index-CQ-bbZk3.d.mts} +16 -3
  10. package/dist/index-CQ-bbZk3.d.mts.map +1 -0
  11. package/dist/index.d.mts +2 -2
  12. package/dist/index.mjs +4 -4
  13. package/dist/preview/index.mjs +1 -1
  14. package/dist/{preview-BQVgn6Ho.mjs → preview-DvP8AZuV.mjs} +2 -2
  15. package/dist/{preview-BQVgn6Ho.mjs.map → preview-DvP8AZuV.mjs.map} +1 -1
  16. package/dist/preview-engine/{chunk-GEUUXTDL.mjs → chunk-D73ZKPFN.mjs} +4 -4
  17. package/dist/preview-engine/{chunk-UQKPDGEH.mjs → chunk-EJJITH6U.mjs} +1 -1
  18. package/dist/preview-engine/{chunk-374QY63R.mjs → chunk-KXLXP66K.mjs} +3 -3
  19. package/dist/preview-engine/chunk-XYGDTPO7.mjs +39 -0
  20. package/dist/preview-engine/components.mjs +1 -1
  21. package/dist/preview-engine/effects.mjs +1 -1
  22. package/dist/preview-engine/framefields.mjs +1 -1
  23. package/dist/preview-engine/player.mjs +1 -1
  24. package/dist/preview-engine/{renderers-O55BEDQZ.mjs → renderers-MDHPQY6D.mjs} +1 -1
  25. package/dist/preview-engine/src-4IUYUKIZ.mjs +8 -0
  26. package/dist/renderer/index.mjs +1 -1
  27. package/dist/{renderer-B0piZg9r.mjs → renderer-B2P1vgb7.mjs} +41 -22
  28. package/dist/renderer-B2P1vgb7.mjs.map +1 -0
  29. package/dist/renderer-D5bjOx83.mjs +3 -0
  30. package/dist/{renderer-DsEyjwfT.mjs → renderer-DPAD6fL1.mjs} +2 -2
  31. package/dist/{renderer-DsEyjwfT.mjs.map → renderer-DPAD6fL1.mjs.map} +1 -1
  32. package/dist/{src-CK5rGVbh.mjs → src-DFEqficI.mjs} +72 -24
  33. package/dist/src-DFEqficI.mjs.map +1 -0
  34. package/package.json +59 -59
  35. package/dist/index-CZjrnylh.d.mts.map +0 -1
  36. package/dist/index-Du5YgdzM.d.mts.map +0 -1
  37. package/dist/preview-engine/chunk-CCB3VTY2.mjs +0 -39
  38. package/dist/preview-engine/src-NGVAJYHC.mjs +0 -8
  39. package/dist/renderer-B0piZg9r.mjs.map +0 -1
  40. package/dist/renderer-COR66Sby.mjs +0 -3
  41. package/dist/src-CK5rGVbh.mjs.map +0 -1
@@ -191,7 +191,7 @@ const COCO_CLASSES = [
191
191
  ];
192
192
 
193
193
  //#endregion
194
- //#region ../vision/dist/src-Bfz8DtoR.mjs
194
+ //#region ../vision/dist/src-Bnr8DUC-.mjs
195
195
  function computeIoU(boxA, boxB) {
196
196
  const xA = Math.max(boxA.originX, boxB.originX);
197
197
  const yA = Math.max(boxA.originY, boxB.originY);
@@ -3074,8 +3074,9 @@ function output(outputs, name, key) {
3074
3074
  /**
3075
3075
  * Where a render-time Vision effect finds subject masks someone already
3076
3076
  * computed for its clip (`comp.vision(clip)` in framefields), so a matte layer
3077
- * reuses them instead of segmenting the frame again. Set on the Vision effect
3078
- * instance under this key; the renderer reads it from the effect.
3077
+ * reuses them instead of segmenting the frame again, and a skeleton layer draws
3078
+ * the pose matched to that subject instead of the first person it detects. Set
3079
+ * on the Vision effect instance under this key; the renderer reads it from the effect.
3079
3080
  */
3080
3081
  const CLIP_SUBJECT = Symbol.for("framefields.vision.clipSubject");
3081
3082
  /**
@@ -4311,7 +4312,7 @@ var VisionNode = class VisionNode$1 {
4311
4312
  };
4312
4313
 
4313
4314
  //#endregion
4314
- //#region ../../nodes/node-vision/dist/renderers-D1ixy3z3.mjs
4315
+ //#region ../../nodes/node-vision/dist/renderers-Ao0SpHQm.mjs
4315
4316
  let scratchValues = new Uint8Array(0);
4316
4317
  let scratchLengths = new Uint32Array(0);
4317
4318
  function encodeMask(mask, width, height) {
@@ -4996,7 +4997,8 @@ const VisionWebGPURenderer = async (args) => {
4996
4997
  const wantsSelfie = op.enableMatte === true || isMatteMode && op.matteSource === "selfie";
4997
4998
  const wantsPose = op.enablePose === true || mode === "skeleton";
4998
4999
  const clipSubject = isMatteMode && !visionBundle && !wantsPose && !wantsSelfie && op.keyBackground !== true ? clipSubjectFor(effectKey, props.sourceTimeSec === void 0 ? frameIdx : props.sourceTimeSec * fps, fps, targetWidth, targetHeight) : void 0;
4999
- const fromClip = clipSubject !== void 0;
5000
+ const clipPose = mode === "skeleton" && !visionBundle ? clipPoseFor(effectKey, props.sourceTimeSec === void 0 ? frameIdx : props.sourceTimeSec * fps, fps, targetWidth, targetHeight) : void 0;
5001
+ const fromClip = clipSubject !== void 0 || clipPose !== void 0;
5000
5002
  const cacheable = !fromClip && !wantsSelfie && !wantsPose && (wantsDetection || wantsSegmentation);
5001
5003
  const source = cacheable ? cacheSource(nodeKeyStr, childMedia, op, targetWidth, targetHeight) : "";
5002
5004
  const keyThresholdAt = (frame$1) => op.keyBackground === true ? backgroundKeyThreshold(op, compositionFrame - (frameIdx - frame$1), fps) : void 0;
@@ -5162,27 +5164,27 @@ const VisionWebGPURenderer = async (args) => {
5162
5164
  }
5163
5165
  if (mode === "skeleton") {
5164
5166
  if (!sharedSkeletonRenderer) sharedSkeletonRenderer = new PoseSkeletonRenderer(ctx.device);
5165
- const person = (visionBundle?.getPoseResult(frameIdx) ?? currentPoseRes)?.people[0];
5166
- if (person && person.keypoints.length > 0) {
5167
- const skelTex = sharedSkeletonRenderer.renderToTexture(person.keypoints, {
5167
+ const keypoints = clipPose !== void 0 ? clipPose : (visionBundle?.getPoseResult(frameIdx) ?? currentPoseRes)?.people[0]?.keypoints;
5168
+ const skelPass = ctx.renderer.beginFrame(encoder$1, targetView, {
5169
+ r: 0,
5170
+ g: 0,
5171
+ b: 0,
5172
+ a: 0
5173
+ }, targetWidth, targetHeight, "clear");
5174
+ if (keypoints && keypoints.length > 0) {
5175
+ const skelTex = sharedSkeletonRenderer.renderToTexture(keypoints, {
5168
5176
  width: targetWidth,
5169
5177
  height: targetHeight
5170
5178
  });
5171
- const skelPass = ctx.renderer.beginFrame(encoder$1, targetView, {
5172
- r: 0,
5173
- g: 0,
5174
- b: 0,
5175
- a: 0
5176
- }, targetWidth, targetHeight, "clear");
5177
5179
  ctx.renderer.drawTexture(skelPass, skelTex, {
5178
5180
  x: 0,
5179
5181
  y: 0,
5180
5182
  width: targetWidth,
5181
5183
  height: targetHeight
5182
5184
  });
5183
- skelPass.end();
5184
- return;
5185
5185
  }
5186
+ skelPass.end();
5187
+ return;
5186
5188
  }
5187
5189
  if (mode === "boxes" || mode === "tracking") {
5188
5190
  const outPass$1 = ctx.renderer.beginFrame(encoder$1, targetView, {
@@ -5272,12 +5274,29 @@ const VisionWebGPURenderer = async (args) => {
5272
5274
  * uv, so it fits any target of the same aspect. Other shapes fall back.
5273
5275
  */
5274
5276
  function clipSubjectFor(effect, frame, fps, width, height) {
5275
- const source = effect?.[CLIP_SUBJECT];
5277
+ const source = linkedClip(effect);
5276
5278
  const subject = source?.subject(frame, fps);
5277
- if (!subject) return subject;
5278
- const aspect = subject.width / subject.height / (width / height);
5279
- if (Math.abs(aspect - 1) < .01) return subject;
5280
- if (source?.exact) throw new Error("A prompted clip matte requires the source aspect ratio. Apply layout cropping after the source matte.");
5279
+ if (!subject || !source) return subject;
5280
+ return fitsTarget(source, subject.width / subject.height, width / height) ? subject : void 0;
5281
+ }
5282
+ /**
5283
+ * The pose a linked `comp.vision` clip matched to its subject for a source
5284
+ * frame, normalized to the source; it fits targets of the same aspect.
5285
+ */
5286
+ function clipPoseFor(effect, frame, fps, width, height) {
5287
+ const source = linkedClip(effect);
5288
+ const pose = source?.pose?.(frame, fps);
5289
+ if (!pose || !source) return pose === null ? null : void 0;
5290
+ return fitsTarget(source, pose.width / pose.height, width / height) ? pose.keypoints : void 0;
5291
+ }
5292
+ function linkedClip(effect) {
5293
+ return effect?.[CLIP_SUBJECT];
5294
+ }
5295
+ /** Source results map onto a target of the same aspect; a prompted clip must not fall back. */
5296
+ function fitsTarget(source, sourceAspect, targetAspect) {
5297
+ if (Math.abs(sourceAspect / targetAspect - 1) < .01) return true;
5298
+ if (source.exact) throw new Error("A prompted clip matte requires the source aspect ratio. Apply layout cropping after the source matte.");
5299
+ return false;
5281
5300
  }
5282
5301
  /** Adapts a Selfie Segmenter matte to the instance-mask shape the composite path takes. */
5283
5302
  function personMatteAsMask(matte) {
@@ -5297,4 +5316,4 @@ var renderers_default = defineRenderer({ WebGPURenderer: VisionWebGPURenderer })
5297
5316
 
5298
5317
  //#endregion
5299
5318
  export { pinNodeToObject as _, COCO17_KEYPOINT_NAMES as a, SpatialLandmarkTransformer as c, VisionNode as d, VisionRunner as f, pinNodeToLandmark as g, mergeSubjectMask as h, COCO17_KEYPOINTS as i, TemporalObjectTracker as l, maskObject as m, CLIP_SUBJECT as n, PoseSkeletonRenderer as o, analyzeSequence as p, COCO17_BONES as r, SegmentationTexturePool as s, renderers_default as t, VisionBundle as u, COCO_CLASSES as v };
5300
- //# sourceMappingURL=renderer-B0piZg9r.mjs.map
5319
+ //# sourceMappingURL=renderer-B2P1vgb7.mjs.map