feat(pocket3d): character-widget substrate + pocket-vrm crate#125
Merged
Conversation
…ction, widget windows - Morph targets: sparse CPU deltas per primitive + per-instance overlay vertex buffer; weight changes recompute lazily during render prepare, so an idle character costs zero (blinks are ~0.2s out of every 1-6s). Morphing primitives draw from the overlay via base_vertex redirect — no index rebasing, shared indices stay untouched. - Explicit poses: Skeleton::sample_locals / globals_from_locals split lets hosts inject procedural edits (look-at, spring bones) between clip sampling and the hierarchy walk; ModelInstance::pose overrides AnimState. - Widget window mode: AppConfig transparent / decorations / always_on_top / resizable / max_fps (frame-paced sleep instead of vsync spinning) / drag_window; surface picks a non-opaque alpha mode; Scene::transparent_clear clears to alpha 0 for desktop-composited windows. - Per-instance alpha-test cutout (params.y) for anime-style cutout textures. - Input::cursor() position tracking; mouse capture-on-click now gated on capture_mouse so widget clicks don't grab the cursor. - Joint palette window 128 -> 512 mat4s: VRoid-style humanoid rigs carry ~270 joints and were being truncated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… retarget, look-at New pocket3d workspace crate giving any Pocket app a VRM character: - VRM 0.x GLB parsing (manual chunk walk + serde_json): humanoid map, blend-shape groups (weights normalized 0-1), spring config (spec's 'stiffiness' typo and all), MToon material info, look-at ranges, meta. - SpringSolver: UniVRM-semantics verlet (stiffness toward animated rest, gravity, drag, sphere-collider pushout), allocation-free steps, substepped for stability, deterministic. - VRMA (VRMC_vrm_animation) loading + retargeting onto a model skeleton by humanoid bone name; hips translation rescaled in channel units and re-anchored; poses are converted from the VRM 1.0 +Z humanoid space to the VRM 0.x -Z facing (yaw-pi conjugation) — the arms-up bug otherwise. - Bone-type eye look-at with per-side horizontal inner/outer + vertical degree ranges. - Fixtures (VRoid AvatarSample_A + airi's idle_loop.vrma) are downloaded, never committed; 21 tests incl. parse/retarget/spring stability against the real model. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
VRM files ship authoring-resolution textures (AvatarSample_A: four 4096²
maps) plus thumbnails no material references; GPU texture memory dominates
a character widget's footprint. load_glb_opts + ModelLoadOptions
{ max_texture_dim } box-filters halves until under the cap, and unreferenced
images upload as 1×1 stubs (indexing preserved).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
doodlewind
marked this pull request as ready for review
July 18, 2026 23:39
This was referenced Jul 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Generic engine support for desktop character widgets (transparent, always-on-top, VRM-animated) — the reusable half of the pocket-character runtime (pocket-stack/pocket-character, the airi-parity 3D digital-human widget).
pocket3d
base_vertex, shared index buffer untouched.Skeleton::sample_locals/globals_from_localssplit +ModelInstance::pose, so hosts inject look-at/physics edits between clip sampling and the hierarchy walk.AppConfigtransparent/decorations/always_on_top/resizable/max_fps(frame-paced sleeping loop) /drag_window; non-opaque surface alpha;Scene::transparent_clear.Input::cursor(); capture-on-click gated oncapture_mouse; joint window 128 → 512 mat4s (VRoid rigs carry ~270 joints).load_glb_opts+ModelLoadOptions { max_texture_dim }: skip unreferenced glTF images (VRM thumbnails), box-filter cap authoring-resolution textures — the single biggest memory lever (931 → 518 MB footprint on the widget).pocket-vrm (new crate)
VRM 0.x parsing (humanoid / blend shapes / springs / MToon info / look-at), UniVRM-semantics spring-bone verlet solver (allocation-free, deterministic), VRMA retargeting (channel-unit hips rescale + re-anchor + VRM1 +Z → VRM0 −Z yaw conjugation — the arms-up bug otherwise), bone-type eye look-at. Fixtures downloaded, never committed (VRoid sample license).
Validation
cargo testgreen; pocket-vrm: 21 tests incl. real-model parse/retarget/spring stability.idle_loop.vrmaposed correctly, blink morph closes the eyes, transparent widget window composites over the desktop.🤖 Generated with Claude Code
Try it (manual verification, from scratch)
The satellite repo is the end-to-end harness for everything in this PR:
Engine-only checks in this repo:
cd pocket3d && cargo test -p pocket3d -p pocket-vrm(pocket-vrm integration tests fetch fixtures percrates/pocket-vrm/fixtures/README.md; they skip when absent).