From d275f00aeb36b5031e11589fbbee6d95ef745ee9 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 25 Oct 2026 09:05:56 +0100 Subject: [PATCH] README: loop on the generate request, and what the FBX window is Co-Authored-By: Claude Opus 5.5 --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 6a59398..477f91e 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ Supported request fields: - `cfg`, `cfgType` / `cfg_type`, `cfgWeight` / `cfg_weight` - `bvh`, `bvhStandardTpose` / `bvh_standard_tpose` - `fbx` and `clipName` (see FBX Export) +- `loop` (a boolean, valid only with `fbx: true`; see FBX Export) - `noPostprocess` / `no_postprocess` - `saveExampleDir` / `save_example_dir` - `timeoutMs`, `workerTimeoutMs`, `exportTimeoutMs` (at most 120000) @@ -166,6 +167,18 @@ timeout, and its output in `/logs/export.log`. It is killed with the work SIGTERM. A failed export fails the job (`fbx-export-refused` or `fbx-export-failed (...)`, 502) and the answer never carries Blender's output. +`"loop": true` (with `fbx: true`; otherwise a 400, as is a non-boolean) exports the take's lowest-cost loop window instead +of the whole take. The worker chooses it (`scripts/loop_window.py`) from Kimodo's own posed joints: every joint relative +to its Hips and turned by its own heading (`compute_global_heading`), and the seam from frame `b` back to frame `a` +costs the pose RMS plus 0.1 s times the velocity RMS (central differences, in m and m/s), over `b - a >= ceil(F / 2)`. +The lowest cost wins; a tie goes to the longer window, then the earlier. The worker's answer carries `loops`, one +`{first, last, poseCost, velocityCost}` per sample (BVH frame indices, `last` inclusive), and the daemon hands +sample k's window to `bvh-to-fbx.py` as `--frames ` (Blender counts from 1); the daemon never +computes a window, and an answer without one for a sample fails the job (`fbx-export-failed (no loop window)`). +The BVH and NPZ stay the whole generated take. The job record keeps `request.loop`, `worker.loops` and the clip's +`frames` as Blender reports them, and keeps inline `constraints` as sent (a path otherwise), so a committed record +reproduces its clip. Without `loop` the FBX is the whole take, as before. + One BVH gives the same FBX bytes on one host body (a fixed hash seed and a fixed time stamp); FBX bytes differ between glibc versions in the last float digits, so the BVH is the cross-body reproducibility unit.