Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/lod.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ group to the object; the level files are only downloaded when the object is firs
need one, and once for every copy in the scene. Pieces placed before their pack had LOD files pick
them up automatically. Pack authors: see the `lods` field in the core repo's `PACKS.md`.

## A simple stand-in until the model arrives (fallback groups)

A group can say that the object ITSELF is only a **stand-in**: `userData.lod.fallback = true`. Its own meshes (a few
primitives — a box-and-cone fish) are then LOD0 and draw only while the real model is not there yet (its pack file is
still loading) or cannot be reached (offline, a blocked CDN). Level 1 is the real model — a pack item or any GLB, which
does not need to share a single node name with the stand-in — and levels 2 onward are its own LOD files, picked by
screen size as usual.

The **Aquarium** example is built this way: every fish, coral and plant is a primitive stand-in whose fallback group
names an [Aquarium Kit](packs.md) model. The scene file stays small (the models are references), it opens instantly with
its stand-ins, and anyone who cannot reach the pack still sees a working tank. Selection, physics and saving always use
the stand-in; motion nodes like [Body Wave](nodes/bodywave.md) bend the drawn model too.

## In VR

The VR **Properties** panel has a **LOD** row: it reads the level being drawn (`Auto · LOD1`, or
Expand Down
23 changes: 21 additions & 2 deletions docs/materials.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Material Presets

A **material preset** is a named look for an object's surface — colour, roughness, metalness, glow, transparency and up
to two image maps (a texture and a normal map) — that you apply with one click. Seven come built in: **Wood**, **Metal**,
**Plastic**, **Glass**, **Stone**, **Rubber** and **Neon**. You can save your own, rename and delete them, and everyone
to two image maps (a texture and a normal map) — that you apply with one click. Eight come built in: **Wood**, **Metal**,
**Plastic**, **Glass**, **Stone**, **Rubber**, **Fish scales** and **Neon**. You can save your own, rename and delete them, and everyone
in your session sees your presets and can use them.

**Where:** select an object and open its properties (double-click it, or right-click ▸ **Properties**). In the
Expand All @@ -25,6 +25,25 @@ in your session sees your presets and can use them.

![Editing your presets: rename, download and delete on your own swatches](img/materials/presets-edit.png)

## Fish scales and the look tier

**Fish scales** is an iridescent look: a thin film over the surface shifts its colour with the viewing angle (the
silver-blue flash of a turning fish), over a procedural relief of overlapping scales, with a light clear coat and a hint
of see-through (transmission) so a fin reads thin. Recolour it in the Inspector for any fish, snake, dragon or beetle
shell. The Aquarium's fish wear it.

Some of that costs more than every device can pay, so each device draws a material at its own **look tier** — decided
the way water quality is (from the headset and the automatic quality level), never written into the scene:

| Device | Draws |
|---|---|
| Desktop, full quality | everything |
| Phone (or a lowered quality level) | everything but transmission — it renders the whole scene a second time |
| Headset (or the lowest levels) | no transmission, no thin film, no sheen — the plain lit surface |

The look you chose is what is saved and what your peers receive; a device drawing less keeps the full numbers beside the
material, so saving on a headset and opening on a desktop shows the full look again.

## What gets saved, and where

- Your presets live **on this device** (browser storage). They are not part of the scene file. An object that wears a
Expand Down
4 changes: 4 additions & 0 deletions docs/nodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ node with code (Script, Behaviour, a module's node) opens that code — see
| [**Bounce**](nodes/bounce.md) | Bounces the connected object up and down off its resting height, like a dribbled ball. |
| [**Orbit**](nodes/orbit.md) | Circles the connected object around its resting position on the horizontal plane. |
| [**Path patrol**](nodes/pathpatrol.md) | Walks the connected object along a series of waypoints you click into the scene, facing along the path. |
| [**Follow Path**](nodes/followpath.md) | Moves the connected object along a smooth path - a drawn Spline, a Flow path or its own waypoints - at a speed, looping, ping-ponging or once, facing along it and leaning into the turns. |
| [**Wander**](nodes/wander.md) | Drifts the connected object around a smooth, never-repeating target inside an area object (a water volume, a room) or a box around where it was placed. |
| [**Orient to Velocity**](nodes/orientvelocity.md) | Turns the connected object to face the way it is moving, smoothly, leaning into turns - put it after Wander, Orbit or any mover. |
| [**Body Wave**](nodes/bodywave.md) | Bends the connected object with a wave travelling along its body - a swimming fish, a snake, a flag, a tail - stronger and faster the faster it moves. |
| [**Rotate / Motor**](fluids.md#nodes) | Turns its object about one of its own axes at an rpm with a spin-up; on a dynamic body during a simulation, a motor of a given torque. Paddles it turns push fluid (1.25). |
| [**Float Along Flow**](fluids.md#nodes) | Carries its object along the nearest (or wired) flow path at the path's speed, bobbing and facing the current (1.25). |
| [**Animation Finished**](nodes/animfinished.md) | Fires a pulse when the connected object's animation clip reaches its end. |
Expand Down
34 changes: 34 additions & 0 deletions docs/nodes/bodywave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Body Wave

Bends the connected object with a wave travelling along its body — a swimming fish, a snake, a flag, a tail — stronger and faster the faster it moves, curving into turns. A shader effect: physics and picking keep the rest pose.

**Output:** effect (wire into an [Object Selector](objectselector.md), or leave it in an object's own flow)

## Inputs

Every range parameter has a socket (a wired value overrides its slider).

## Parameters

| Parameter | Default | Range | Meaning |
|---|---|---|---|
| amplitude | 0.08 | 0 – 0.5 | sideways swing at the tail, as a share of the body length |
| wavelength | 1 | 0.2 – 4 | body lengths per wave (1 = one S along the body) |
| frequency | 1.5 | 0 – 10 Hz | beats per second at rest |
| stiffness | 0.3 | 0 – 0.95 | the front share that does not bend (a fish's head) |
| falloff | 2 | 0.25 – 6 | how sharply the swing grows toward the tail |
| speedGain | 1 | 0 – 10 | extra Hz per m/s of speed |
| ampGain | 0.5 | 0 – 5 | extra amplitude per m/s |
| turnBend | 0.5 | 0 – 2 | how far the body bows into a turn |
| forward | +z | axis | the nose axis (the wave runs from it to the tail) |
| side | horizontal | horizontal / vertical | the bend direction: horizontal = a fish or snake, vertical = a whale or dolphin |
| reverse | off | | the wave runs tail → head (a flag rippling toward its pole) |

The bend is computed in the vertex shader over every mesh in the object (and over a fallback LOD group's real model), measured along the forward axis from the nose. Each waving mesh gets its own copy of its material while the wave runs (so two fish sharing a material can swim differently); the original comes back, with any edit you made meanwhile, when the wave stops. Saves are untouched.

## Practical example

A flag on a pole: a plane flag whose pole edge points `-x` — set `forward` -x, `side` horizontal, `reverse` on, stiffness 0, amplitude 0.15, frequency 2.

!!! note
The shadow keeps the rest shape, and normals are not bent — keep the amplitude modest for close-ups.
39 changes: 39 additions & 0 deletions docs/nodes/followpath.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Follow Path

Moves the connected object along a smooth path — a drawn **Spline**, a **Flow path** or its own waypoints — at a speed, looping, ping-ponging or once, facing along it and leaning into the turns. An offset spreads several riders out along one path.

**Output:** effect (wire into an [Object Selector](objectselector.md), or leave it in an object's own flow — it then moves that object)

## Inputs

| Handle | Type | Meaning |
|---|---|---|
| path | object | the path to ride: a Spline (Draw ▸ Spline) or a Flow path. Unwired, the node rides its own `points` |
| speed, offset, bank, maxBank | number | override the card sliders when wired |

## Parameters

| Parameter | Default | Range / options |
|---|---|---|
| speed | 0.5 | -5 – 5 m/s (negative rides it backwards) |
| offset | 0 | 0 – 1: where along the path it starts (0.5 = halfway round) |
| mode | loop | `loop` (wraps, a closed path circles) · `pingpong` (there and back) · `once` (stops at the end) |
| align | on | face along the path |
| pitch | on | tilt up and down with the path (off keeps the nose level — a car, a walker) |
| bank | 0.5 | 0 – 1: how much it leans into turns |
| maxBank | 30 | 0 – 80°: the steepest lean |
| forward | +z | the axis the model's nose points along: `+z`, `-z`, `+x`, `-x` |
| points | — | world-space waypoints, used when nothing is wired to `path` (templates and the AI assistant write them) |

The path is a **centripetal Catmull-Rom** curve through the points (the spline tool's own curve), walked at constant speed by arc length. The pose is a pure function of the path and the shared clock, so every peer sees the object at the same point — nothing is sent while it moves. Banking comes from the path's curvature times the speed: a tight bend at speed leans further than a gentle one.

## Practical example

Two fish circling a tank, half a lap apart:

1. Draw a closed **Spline** around the inside of the tank and hide it (eye icon in the object list).
2. Give each fish a **Follow Path** node (in its own flow), wire the spline's **Object Selector** into `path`.
3. Speed 0.4, bank 0.7; the second fish gets `offset` 0.5. Add a [Body Wave](bodywave.md) so they swim, not slide.

!!! tip
A model whose nose is not along +Z (most rigs face +Z, many imported cars face +X) — set `forward` instead of rotating the model.
28 changes: 28 additions & 0 deletions docs/nodes/orientvelocity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Orient to Velocity

Turns the connected object to face the way it is moving, smoothly, leaning into turns — put it after Wander, Orbit or any mover so it looks where it goes.

**Output:** effect (wire into an [Object Selector](objectselector.md), or leave it in an object's own flow)

## Inputs

| Handle | Type | Meaning |
|---|---|---|
| turnSpeed, bank, maxBank, minSpeed | number | override the card sliders when wired |

## Parameters

| Parameter | Default | Range / options |
|---|---|---|
| turnSpeed | 4 | 0.1 – 30 per second: how quickly it swings round to the new heading |
| bank | 0.5 | 0 – 1: how much it leans into turns |
| maxBank | 30 | 0 – 80° |
| minSpeed | 0.02 | m/s below which it keeps its last heading (a hovering object does not spin) |
| pitch | on | tilt up and down with the motion |
| forward | +z | the model's nose axis |

It reads the object's motion **after** every other effect on it has run (the runtime orders movers first, whatever order the graph lists them in), so it works with any mover — Wander, Orbit, Bounce, a script. Each peer smooths its own copy; they converge on the same heading.

## Practical example

A drone that faces where it drifts: **Wander** (area = the room) + **Orient to Velocity** (turnSpeed 3, bank 0.8) on the drone's flow.
31 changes: 31 additions & 0 deletions docs/nodes/wander.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Wander

Drifts the connected object around a smooth, never-repeating target inside an **area object** (a water volume, a room) or a box around where it was placed — fish, birds, fireflies, idle drones.

**Output:** effect (wire into an [Object Selector](objectselector.md), or leave it in an object's own flow)

## Inputs

| Handle | Type | Meaning |
|---|---|---|
| area | object | stay inside this object's bounds (shrunk by `margin`). Unwired: a box of `rx` × `ry` × `rz` half-extents around the object's resting position |
| speed, seed, margin, rx, ry, rz | number | override the card sliders when wired |

## Parameters

| Parameter | Default | Range |
|---|---|---|
| speed | 0.3 | 0 – 3: how fast the target moves (1 ≈ one wide swing every 6 s) |
| seed | 0 | 0 – 999: 0 = take it from the object, so copies never move in step |
| margin | 0.2 | 0 – 2 m kept clear of the area's sides |
| rx, ry, rz | 1, 0.3, 1 | half-extents of the box when no area is wired |

The target is three octaves of smooth noise per axis at incommensurate rates — it never repeats, never jumps, and always stays inside the box. It is a pure function of the shared clock, so every peer sees the same wanderer in the same place.

## Practical example

Clownfish that potter about the tank:

1. Give the fish a **Wander** node and wire an Object Selector of the **water volume** into `area`; margin 0.4, speed 0.2.
2. Add [Orient to Velocity](orientvelocity.md) so it faces where it is going, and [Body Wave](bodywave.md) so it swims.
3. Duplicate the fish: with `seed` 0 each copy wanders its own way.
8 changes: 8 additions & 0 deletions docs/packs.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ budget.
Hooded rogue, Barbarian and four skeletons, from Kay Lousberg's CC0 KayKit packs — to place in a scene as animated
models. See [Your Character](avatars.md).

## Aquarium Kit (1.32)

**Packs ▸ Aquarium Kit** holds three realistic reef fish (clownfish, regal blue tang, emperor angelfish), a reef rock
arch a fish can swim through, a staghorn coral and two aquatic plants (Amazon sword, eelgrass). The fish turn about their
**middle** with their nose along **+Z** — what [Follow Path](nodes/followpath.md), [Orient to Velocity](nodes/orientvelocity.md)
and [Body Wave](nodes/bodywave.md) expect — and carry a thin-film iridescence (see [Fish scales](materials.md#fish-scales-and-the-look-tier)).
The **Aquarium** example (Templates ▸ Examples) uses all of them.

## For pack authors

A pack is a folder or zip with a `manifest.json` at the root:
Expand Down
4 changes: 4 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ nav:
- Jiggle: nodes/jiggle.md
- Orbit: nodes/orbit.md
- Path Patrol: nodes/pathpatrol.md
- Follow Path: nodes/followpath.md
- Wander: nodes/wander.md
- Orient to Velocity: nodes/orientvelocity.md
- Body Wave: nodes/bodywave.md
- Mass: nodes/mass.md
- Bounciness: nodes/bounciness.md
- Friction: nodes/friction.md
Expand Down