mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 01:00:13 +02:00
The Toon Cat (sources/toon-cat/), the Tuxedo Cat glTF (sources/tuxedo-cat/)
and the Quaternius Shiba Inu and Fox (models/{shiba,fox}/model.glb), each
byte-identical to the previously fetched file and with a LICENSE.md
(author, original URL, licence, changes). The build no longer downloads
them; three.js (preview only) still comes from npm. The baked frames,
model dirs and icons are unchanged.
110 lines
5.4 KiB
Markdown
110 lines
5.4 KiB
Markdown
# VR pet
|
|
|
|
`pet.*`, module `pet` ([options](../README.md#options)).
|
|
|
|
A [SteamVR dashboard patch](ui-patches.md#steamvr-dashboard-patches).
|
|
|
|
## What you get
|
|
|
|
A 3D pet in SteamVR's scene, next to your windows: the Toon Cat in five
|
|
coats (Ginger, Tuxedo, Blue, Cream, Snow), a Shiba Inu, a Fox and a
|
|
Dachshund, plus your own models (`pet.extraModels`). It lives in the
|
|
dashboard's scene, so it is there in SteamVR Home and over games while the
|
|
dashboard runs.
|
|
|
|
- **On its own** it walks around you, sits, lies down, sleeps, follows you
|
|
beyond 2.5 m and reappears in front of you beyond 8 m. The cat also
|
|
grooms, stretches and shakes; the dogs and the fox sniff and look around.
|
|
- **Pick it up:** point the laser just above it (a grip bar shows up, like
|
|
a window's), press and drag like a window (the thumbstick pushes and
|
|
pulls). It dangles by the scruff, turns with the controller and falls
|
|
where you let go. No controller button is read; a falling pet is not
|
|
caught.
|
|
- **Pet it:** rest or move a controller slowly (< 0.4 m/s) on its head or
|
|
back (within 10 cm) for 0.6 s: it purrs (a dog wags its tail) while the
|
|
strokes go on. A fast swipe (> 1 m/s) close by startles it.
|
|
- **Its controls**, below the grip bar: X hides it (kept across SteamVR
|
|
restarts); ⋯ opens its menu: the models (a check on the current one, kept
|
|
across restarts), then Summon (1 m in front of you), Sit, Lie down,
|
|
Sleep. Buttons act on a press and a release on them, not during a drag or
|
|
0.3 s after. The menu closes on a pick, a press elsewhere, 1 s after the
|
|
laser left it, and when the pet hides.
|
|
- **Bring it back:** "Pet" in the dashboard's "+" menu (its icon is the
|
|
current model's), i.e. `vr-pet show`: at its spot while that is within
|
|
3 m and in view, else 1 m in front of you.
|
|
|
|
The `vr-pet` command:
|
|
|
|
```text
|
|
vr-pet show [--summon] show it (--summon: always 1 m in front of you)
|
|
vr-pet hide | status hide it; its state as JSON
|
|
vr-pet models the models (* the current one)
|
|
vr-pet model <id> switch (a hidden pet switches too)
|
|
```
|
|
|
|
## Configuration
|
|
|
|
```nix
|
|
steamFrame.pet.enable = true;
|
|
# steamFrame.pet.defaultModel = "shiba";
|
|
# steamFrame.pet.options = { walkSpeed = 0.3; follow = 3; }; # core.js DEFAULTS
|
|
# steamFrame.pet.extraModels.corgi = ./pets/corgi; # a model folder
|
|
```
|
|
|
|
The first switch bakes the models: a few minutes on the Frame and about
|
|
0.5 GB in the store (1.1 GB without `auto-optimise-store`, which hardlinks
|
|
the coats' copies of the cat's frames); the model sources are in this
|
|
repository (no model download, no Blender needed for the built-in models). Adding your own model, the spec and the
|
|
animation mapping: [VR pet models](pet-models.md). A model of a character
|
|
someone else owns belongs in your own `extraModels` with `"private": true`
|
|
([private models](pet-models.md#private-models)), never in this repository.
|
|
|
|
Without a headset: `nix run github:lhns/steam-frame-nix#pet-preview` plays
|
|
the pet in a browser (mouse as the hands, a debug panel).
|
|
|
|
## Limitations
|
|
|
|
- vrcompositor draws every mounted frame: a few hundred static OBJs per
|
|
model, mounted gradually (`pet.mount`); switching to another animal takes
|
|
a few seconds to load.
|
|
- The pet is drawn by the dashboard's page: it is gone while SteamVR's
|
|
dashboard process restarts, and the patch reattaches within 15 s.
|
|
- It walks on the floor of the standing space and knows nothing of your
|
|
room's furniture.
|
|
- The "+" menu icon changes when the model does; a running Steam picks it
|
|
up when it rescans its icons (a few seconds).
|
|
|
|
## Credits
|
|
|
|
The models' authors and licences: [README, Credits](../README.md#credits).
|
|
|
|
## How it works
|
|
|
|
`vr-pet`, with [persistent state](ui-patches.md#persistent-state) (the
|
|
spot, pose, model and whether it is hidden). Debugging in the `systemui`
|
|
page: `window.__sfuiPet.cat.command('sit' | 'summon' | …)`,
|
|
`.cat.state()`, `.stats()`; the CLI calls only `window.__sfuiPet.api`.
|
|
Journal: `journalctl --user -t vr-pet -u steam-ui-patches`.
|
|
|
|
- **Build** (`modules/pet/package.nix`): bake.py retargets and hand-keys
|
|
the Toon Cat's clips and bakes one OBJ per animation frame; bake_gltf.py
|
|
does the same for a rigged glTF (the Quaternius animals); index.py makes
|
|
the catalog (coats as recoloured textures of the cat's frames, one
|
|
directory per model, 48 px thumbnails) and the "+" menu icons. Each
|
|
animal is a derivation of its own.
|
|
- **Behaviour** (`core.js`): poses, clips and transitions, wandering,
|
|
following, petting, the scruff drag and the fall, independent of where
|
|
it is drawn (also used by the preview and the tests).
|
|
- **Drawing** (`systemui.js`): every frame is a render model node under one
|
|
world-locked root in the dashboard's scene graph; the frames a clip needs
|
|
are mounted ahead, unused ones dropped. Each change resends the
|
|
dashboard's last scene graph message with only the pet's subtree
|
|
replaced. The grip bar is a panel like a window's handle; while dragged
|
|
the root is parented to the controller, so the compositor carries it.
|
|
- **"+" menu icon:** `~/.local/share/icons/hicolor/256x256/apps/vr-pet.png`
|
|
links to `/run/user/1000/steam-frame-nix/vr-pet/icon.png`, which the
|
|
oneshot user service `steam-frame-nix-pet-icon` points to the current
|
|
model's icon: on switch, at login and when the state file changes (path
|
|
unit); it bumps hicolor's mtime so a running Steam rescans. Lifetime and
|
|
cleanup: [Changes outside Nix](../README.md#changes-outside-nix-exceptions).
|