arkavo-org / arkavo-org/VRMMetalKit

VRMC_springBone_extended_collider parsed but applied inconsistently — chaotic per-variant clustering, doesn't track swept axes

Open
#237 7 comments 0 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
6
Forks
2
Avg merge
18h 51m
Merged PRs (30d)
26

Description

## Summary

VMK 0.14.0 *parses* `VRMC_springBone_extended_collider` (plane, inverted sphere, inverted capsule, plus per-joint `angleLimit`) but applies the data inconsistently. An 18-variant swing sweep over shape × placement and shape × angle-limit produces only 7 distinct SHA256 image hashes, with clusters that **don't track any single swept axis** — variants of different shapes and different angle limits end up byte-identical, while seemingly-similar variants end up distinct.

If VMK didn't support the extension at all, we'd expect ALL 18 variants to be byte-identical (chain physics with no collider applied = same trajectory). The 7-bucket clustering means VMK is reading SOMETHING from the extension and using it to vary chain behavior — but not coherently with the variant's actual shape/placement/angle-limit parameters.

Filed against 0.14.0 (commit `f25a947`).

## Reproduction

```bash
git clone https://github.com/arkavo-org/vrm-conformance && cd vrm-conformance
cargo build --release -p vrm-asset-generator
cd adapters/vrm-metal-kit && swift build --configuration release && cd ../..

./target/release/vrm-asset-generator emit-springbone-extended-sweep \
--output-dir /tmp/extended-sweep

# Render every swing variant (animation drives chain through the collider):
for plan in /tmp/extended-sweep/swing_springbone_extended_*.test.yaml; do
test_id=$(basename "$plan" .test.yaml)
./target/release/vrm-runner execute-test-plan \
--plan "$plan" \
--adapter-bin adapters/vrm-metal-kit/.build/release/vrm-metal-kit-adapter \
--asset-dir /tmp/extended-sweep \
--output-dir /tmp/vmk-out --renderer-name vrm-metal-kit --json >/dev/null
done

# Hash each render and group by SHA:
for f in /tmp/vmk-out/swing_springbone_extended_*_vrm-metal-kit.png; do
shasum -a 256 "$f"
done | awk '{print $1}' | sort | uniq -c | sort -rn
```

## Observed clustering

| SHA256 (first 16) | variants in bucket |
|---|---|
| `3e429a38a5b6d29b` | icaps_anglelimit_60, icaps_ploose, icaps_ptight, isphere_anglelimit_90, plane_anglelimit_90 |
| `0c9ecdad02d5d40d` | isphere_anglelimit_30, isphere_ploose, isphere_ptight, plane_ploose |
| `24ce53729b83c6ca` | icaps_anglelimit_90, plane_anglelimit_60, plane_ptight |
| `a3cb07bdb4d9b3b4` | icaps_anglelimit_30, plane_anglelimit_30 |
| `d6ac96ed397f436b` | icaps_pmed, isphere_anglelimit_60 |
| `60cdad84ce1f8be1` | isphere_pmed |
| `dc9c3afe293609f1` | plane_pmed |

Note that the largest bucket spans 3 shapes × 4 different parameter values. This wouldn't happen if VMK applied each variant's collision geometry correctly — each unique configuration should produce a unique chain pose under animation.

## Expected

Distinct shape / placement / angle-limit configurations should produce distinct chain trajectories under the same animation. A coherent grouping (e.g., "all `plane` variants cluster together because plane support is broken") would be diagnosable; the current chaotic grouping suggests intermittent parsing or unit-conversion issues somewhere on the extended-collider path.

## Suggested investigation

1. Verify how `extensions.VRMC_springBone_extended_collider.shape` fields are read from each collider entry — possibly the parser branches on shape type but falls through to a default for non-`Sphere`/`Capsule` cases.
2. Verify `angleLimit` is being applied per-joint and not silently ignored — three of the 7 buckets are pure-`anglelimit` swept variants that ended up distinct, suggesting partial implementation.
3. The single-element buckets (`plane_pmed`, `isphere_pmed`) are anomalous — what makes `_pmed` variants distinct from `_ptight` / `_ploose` of the same shape? Possibly a placement-offset arithmetic edge case at the medium value.

## Companion finding

three-vrm 3.5.0 rejects the same assets entirely at `load_vrm` time, so cross-renderer comparison is currently VMK + godot-vrm only. See [vrm-conformance findings](https://github.com/arkavo-org/vrm-conformance/blob/main/docs/findings.md) § "three-vrm 3.5.0 rejects assets that declare VRMC_springBone_extended_collider".

## Related

- vrm-conformance phase-3 extended-collider corpus: [`docs/superpowers/plans/2026-05-15-springbone-phase3-extended-colliders.md`](https://github.com/arkavo-org/vrm-conformance/blob/main/docs/superpowers/plans/2026-05-15-springbone-phase3-extended-colliders.md)
- VMK#67 (verify and document SpringBone angle limit implementation) — possibly the same surface
- This is companion to VMK#236 (warmupPhysics doesn't resolve collisions)

Contributor guide

Open the contributing guide

Research direction

Start with the adapters/vrm-metal-kit Swift adapter and trace its VRMC_springBone_extended_collider handling, especially shape fields and per-joint angleLimit. Generate the corpus with vrm-asset-generator emit-springbone-extended-sweep, then run the listed vrm-runner plans and compare image hashes. Done means distinct configurations produce coherent, distinguishable trajectories under the same animation.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, swift
Domain
computer-graphics, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.