@lovelace_lol/embody 0.0.17 → 0.0.18

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/README.md CHANGED
@@ -245,6 +245,75 @@ JSON report after creating the new file. In a source checkout, invoke
245
245
  `node model-tools/prepare-actor.mjs` with the same arguments. CI runs the
246
246
  `test:model-tools` regression source as part of the existing package checks.
247
247
 
248
+ #### Extracting reusable garment files
249
+
250
+ `extractGarmentModel(source, options)` extracts explicitly selected source-file
251
+ node primitives as a separate self-contained GLB. It is the shared file operation
252
+ for browser and backend-worker consumers; it does not depend on a Three scene,
253
+ initialize the animation runtime, persist a wardrobe item, or attach it to a rig.
254
+ LoomLarge owns mesh selection, storage and the preview/save workflow. Embody's
255
+ Runtime garment attachment and removal belong to the renderer adapter and need
256
+ separate implementation; this file API does not provide that lifecycle.
257
+
258
+ ```js
259
+ import { extractGarmentModel } from '@lovelace_lol/embody/model-tools';
260
+
261
+ const garment = await extractGarmentModel(originalFileBytes, {
262
+ selections: [{ nodeIndex: 12, primitiveIndices: [0, 2] }],
263
+ ownedBoneNodeIndices: [31, 32], // Optional explicitly garment-owned skin joints.
264
+ signal: abortController.signal,
265
+ });
266
+ // Persist garment.bytes separately only after extraction succeeds.
267
+ ```
268
+
269
+ Indices refer to the original GLB JSON: each selection identifies a node and the
270
+ primitive indices within that node's mesh. They are not the `mesh:N` selectors
271
+ used by `prepareActorModel`, live-scene child paths, or names. Selecting one
272
+ instance of a shared mesh does not include another instance. Duplicate node or
273
+ primitive selections and invalid indices are errors. Output indices are remapped;
274
+ inspect each new file before selecting from it again.
275
+
276
+ Extraction preserves retained vertex/index/morph accessor values and order,
277
+ including unused vertices within a selected accessor, skin joint palette order,
278
+ inverse bind matrices, mesh weights, ancestor transforms, material settings,
279
+ texture transforms, original embedded image bytes, and retained `extras`.
280
+ Unselected primitives and unreferenced file resources are excluded. Shared or
281
+ interleaved views are repacked per accessor so unrelated streams are excluded;
282
+ when primitives share an accessor, its unused vertex values deliberately remain
283
+ to preserve vertex numbering. Texture atlases remain whole. There is no triangle
284
+ reduction, vertex compaction, texture resizing, image decoding/re-encoding, or
285
+ live-pose capture. Animation clips are deliberately omitted with a warning;
286
+ cameras and unrelated scene objects are not garment dependencies.
287
+
288
+ `ownedBoneNodeIndices` marks only explicit joints with
289
+ `extras.loomlargeGarmentBone: true`. Each owned branch must move a selected
290
+ primitive, have a shared parent joint, include its complete descendant joint
291
+ chain, and have no positive influence on unselected primitives or instances.
292
+ Validation reads every `JOINTS_n`/`WEIGHTS_n` set and the vertices actually
293
+ referenced by each primitive. Transform-only helper nodes between joints retain
294
+ their source transforms. Existing ownership flags on shared source nodes are
295
+ ignored; they cannot grant ownership. Required skin palettes and their ancestor
296
+ nodes are retained even when some joints have no selected positive weights.
297
+
298
+ Inputs must be embedded GLB 2.0 with PNG, JPEG, or WebP images. In addition to core
299
+ PBR materials, extraction preserves `KHR_texture_transform`,
300
+ `KHR_mesh_quantization`, `EXT_texture_webp`, `EXT_materials_bump`, and the
301
+ `KHR_materials_` extensions `unlit`, `clearcoat`, `emissive_strength`, `ior`,
302
+ `iridescence`, `sheen`, `specular`, `transmission`, `volume`, `anisotropy`, and
303
+ `dispersion`. Unsupported or undeclared extensions, including compression, VRM,
304
+ and scene lights, fail before output. Buffer/accessor bounds, alignment, sparse
305
+ indices, primitive indices and skin influences are validated. Resource URIs are
306
+ rejected rather than fetched. Both source bytes and selection lists are copied
307
+ before asynchronous stages; cancellation rejects without returning partial
308
+ output. Use a worker for large inputs when synchronous validation/copy stages
309
+ must not occupy the UI thread.
310
+
311
+ This lossless extraction stage is separate from `prepareActorModel`'s existing
312
+ compaction/reduction behavior and its extension-free input policy. Future texture
313
+ processing and geometry variants should build on the same file boundary with
314
+ explicit processing options; extracting clothing does not implicitly lower its
315
+ quality.
316
+
248
317
  ### Annotation runtime
249
318
 
250
319
  `AnnotationRuntime` in `src/annotation_runtime/` owns the annotation behavior
@@ -667,7 +736,14 @@ a push to `main`, or a manual run on `main` with the `ref` input left empty.
667
736
  It chooses the next patch version, records the source commit in `gitHead`, and
668
737
  builds and validates once. Stable version selection reads public metadata from
669
738
  `registry.npmjs.org` anonymously; redirects and failed lookups stop the release.
670
- Metadata reads never transmit publishing credentials. The separate
739
+ Metadata reads request cache revalidation and never transmit publishing credentials.
740
+ Before building, version selection checks its candidate once at the exact-version
741
+ endpoint. An upload missing from the package index is incorporated into selection
742
+ and source-history checks: the same source reuses that version; a newer source
743
+ selects the next version before the build. Conflicting records or failed reads stop
744
+ preparation. This is a bounded reconciliation, not polling or a guarantee that every
745
+ registry replica has caught up; the independent publication check still rejects an
746
+ occupied or uncertain version without changing the verified tarball. The separate
671
747
  publish job first requires the npm visibility endpoint (the endpoint used by
672
748
  `npm access get status`) to report the existing package as public. It reads this
673
749
  anonymously without npm token configuration, then uses GitHub OIDC trusted
@@ -810,6 +886,13 @@ no named body-control catalog or fixed control count. `engine.getAUDescriptors()
810
886
  and initialized `getAUDescriptors(profile, modelDescriptor?)` return per-AU
811
887
  metadata and resolved output support, including labels, signed pair IDs,
812
888
  bilateral sides, saved morph strength and resolved bone/morph names.
889
+ Descriptors separate AU/FACS (`au`), semantic Body (`body`), authored joint-axis
890
+ rotations (`bone`) and other profile controls (`custom`). Optional `section`,
891
+ `order` and `controlLabel` metadata organizes those same numeric identities.
892
+ Classification is independent of output availability and morph routing;
893
+ `hasConfiguredBones`/`hasConfiguredMorphs` retain evidence of unavailable authored
894
+ outputs. Visemes keep their own slot API. See [Body controls](docs/body-controls.md#categories-and-anatomical-presentation)
895
+ for preset inheritance, explicit clears and anatomical presentation.
813
896
 
814
897
  Use `setAU`/`transitionAU`, `setContinuum`, `getAUBalance` and
815
898
  `setAUMixWeight` for live controls. `buildClip`/`playSnippet` compile numeric