@call-me-sensei/toonlab 0.1.1 → 0.3.0
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/AGENTS.md +254 -0
- package/ATTRIBUTION.md +41 -3
- package/README.md +300 -27
- package/docs/characters.md +144 -0
- package/docs/debug-panel.md +126 -0
- package/docs/docs.css +589 -0
- package/docs/environment.md +186 -0
- package/docs/getting-started.md +180 -0
- package/docs/index.html +14 -0
- package/docs/lab-architecture.md +100 -0
- package/docs/lighting.md +825 -0
- package/docs/main.jsx +739 -0
- package/docs/mcp.md +97 -0
- package/docs/post-processing.md +98 -0
- package/docs/settings-reference.md +1878 -0
- package/docs/shader-constants.md +77 -0
- package/docs/sky.md +182 -0
- package/docs/style-labs.md +309 -0
- package/docs/texture-lab.md +135 -0
- package/docs/toon-shading.md +183 -0
- package/docs/tsl-conventions.md +167 -0
- package/docs/vegetation-sky.md +275 -0
- package/docs/water.md +430 -0
- package/docs/weather.md +200 -0
- package/docs/world-scale.md +111 -0
- package/mcp/server.mjs +610 -0
- package/mcp/style-lab-tools.mjs +371 -0
- package/mcp/vite-plugin.mjs +174 -0
- package/mcp/workspace.mjs +397 -0
- package/package.json +66 -6
- package/src/ambientfx/INTEGRATION.md +164 -0
- package/src/ambientfx/ambientFxPresets.js +83 -0
- package/src/ambientfx/ambientFxSettings.js +368 -0
- package/src/ambientfx/emitters.js +169 -0
- package/src/ambientfx/index.js +5 -0
- package/src/ambientfx/particleBackbone.js +493 -0
- package/src/ambientfx/stylizedAmbientFx.js +450 -0
- package/src/assetlib/ambientcg.js +117 -0
- package/src/assetlib/assetRef.js +91 -0
- package/src/assetlib/importedEntry.js +40 -0
- package/src/assetlib/index.js +23 -0
- package/src/assetlib/kaykit.js +192 -0
- package/src/assetlib/kaykitStaticIndex.js +700 -0
- package/src/assetlib/loadImported.js +143 -0
- package/src/assetlib/opensource3d.js +113 -0
- package/src/assetlib/polyhaven.js +182 -0
- package/src/assetlib/polypizza.js +115 -0
- package/src/assetlib/smithsonian.js +214 -0
- package/src/assetlib/sources.js +279 -0
- package/src/assetlib/zip.js +58 -0
- package/src/biome/biomeGenerator.js +385 -0
- package/src/biome/biomeRuntime.js +299 -0
- package/src/biome/index.js +2 -0
- package/src/buildinggen/buildingAsset.js +44 -0
- package/src/buildinggen/buildingGrammar.js +311 -0
- package/src/buildinggen/buildingMesh.js +451 -0
- package/src/buildinggen/buildingPresets.js +46 -0
- package/src/buildinggen/buildingRecipe.js +100 -0
- package/src/buildinggen/buildingSettings.js +238 -0
- package/src/buildinggen/index.js +6 -0
- package/src/camera/cameraDirector.js +157 -0
- package/src/camera/cameraGenerator.js +367 -0
- package/src/camera/cameraRig.js +570 -0
- package/src/camera/cameraSettings.js +236 -0
- package/src/camera/index.js +7 -0
- package/src/catalog/builtinEntries.js +245 -0
- package/src/catalog/catalog.js +210 -0
- package/src/catalog/index.js +3 -0
- package/src/catalog/manifest.js +84 -0
- package/src/core/generation.js +529 -0
- package/src/debrisgen/debrisPresets.js +7 -0
- package/src/environment/environmentPresets.js +19 -0
- package/src/environment/environmentRigs.js +21 -1
- package/src/environment/environmentSettings.js +14 -0
- package/src/environment/environmentSunShadowPass.js +8 -0
- package/src/environment/environmentTextureResolver.js +3 -0
- package/src/environment/index.js +1 -0
- package/src/fauna/INTEGRATION.md +174 -0
- package/src/fauna/boids.js +861 -0
- package/src/fauna/faunaBodies.js +492 -0
- package/src/fauna/faunaPresets.js +52 -0
- package/src/fauna/faunaSettings.js +525 -0
- package/src/fauna/index.js +5 -0
- package/src/fauna/stylizedFauna.js +395 -0
- package/src/game-feel/gameFeelGenerator.js +402 -0
- package/src/game-feel/gameFeelRuntime.js +549 -0
- package/src/game-feel/index.js +2 -0
- package/src/index.js +22 -4
- package/src/lighting/colorIntensity.js +177 -0
- package/src/lighting/index.js +161 -0
- package/src/lighting/lightDescriptors.js +249 -0
- package/src/lighting/lightingCapabilities.js +79 -0
- package/src/lighting/lightingDocuments.js +247 -0
- package/src/lighting/lightingFixtures.js +446 -0
- package/src/lighting/lightingGenerator.js +449 -0
- package/src/lighting/lightingPresets.js +319 -0
- package/src/lighting/lightingRuntime.js +723 -0
- package/src/lighting/lightingStyle.js +386 -0
- package/src/lighting/lightingSystem.js +774 -0
- package/src/lighting/unrealExport.js +186 -0
- package/src/lighting/utils.js +87 -0
- package/src/motion/index.js +5 -0
- package/src/motion/motionClip.js +441 -0
- package/src/motion/motionController.js +628 -0
- package/src/motion/motionDocuments.js +225 -0
- package/src/motion/motionGraph.js +307 -0
- package/src/motion/motionSettings.js +222 -0
- package/src/pathgen/index.js +7 -0
- package/src/pathgen/pathBridge.js +232 -0
- package/src/pathgen/pathPresets.js +35 -0
- package/src/pathgen/pathRibbon.js +410 -0
- package/src/pathgen/pathRouter.js +380 -0
- package/src/pathgen/pathSettings.js +335 -0
- package/src/pathgen/pathTextures.js +123 -0
- package/src/pathgen/stylizedPaths.js +453 -0
- package/src/post/index.js +1 -0
- package/src/post/postGenerator.js +177 -0
- package/src/post/postProcessing.js +69 -0
- package/src/propgen/generatorsWave1.js +379 -0
- package/src/propgen/generatorsWave2.js +462 -0
- package/src/propgen/index.js +5 -0
- package/src/propgen/propAsset.js +323 -0
- package/src/propgen/propParts.js +170 -0
- package/src/propgen/propPlacement.js +459 -0
- package/src/propgen/propPresets.js +82 -0
- package/src/propgen/propSettings.js +395 -0
- package/src/rockgen/rockgenPresets.js +8 -0
- package/src/rockgen/rockgenSettings.js +47 -0
- package/src/shaders-tsl/chunks/projected-water-caustics.js +242 -0
- package/src/shaders-tsl/chunks/vegetation-style.js +360 -0
- package/src/shaders-tsl/chunks/water-shore-state.js +31 -0
- package/src/shaders-tsl/chunks/water-waves.js +90 -11
- package/src/shaders-tsl/environment.js +75 -1
- package/src/shaders-tsl/flower.js +279 -30
- package/src/shaders-tsl/grass.js +60 -33
- package/src/shaders-tsl/sky.js +125 -31
- package/src/shaders-tsl/tree-leaf.js +61 -25
- package/src/shaders-tsl/water-breaker.js +7 -4
- package/src/shaders-tsl/water-shore-state-simulation.js +523 -0
- package/src/shaders-tsl/water.js +488 -45
- package/src/shaders-tsl/woody-surface.js +154 -0
- package/src/sky/sceneOverrideLayers.js +10 -0
- package/src/sky/skyQuality.js +26 -0
- package/src/sky/stylizedSky.js +776 -20
- package/src/soundscape/index.js +4 -0
- package/src/soundscape/soundscapeGenerator.js +179 -0
- package/src/soundscape/soundscapeRuntime.js +806 -0
- package/src/soundscape/soundscapeSettings.js +292 -0
- package/src/styles/index.js +13 -0
- package/src/styles/styleBundle.js +325 -0
- package/src/stylizedTerrain.js +631 -0
- package/src/stylizedWorld.js +903 -0
- package/src/texgen/evaluateTexture.js +675 -0
- package/src/texgen/index.js +60 -0
- package/src/texgen/noise2.js +210 -0
- package/src/texgen/textureAi.js +436 -0
- package/src/texgen/textureGenerators.js +516 -0
- package/src/texgen/texturePresets.js +490 -0
- package/src/texgen/textureSettings.js +342 -0
- package/src/texgen/textureThree.js +59 -0
- package/src/vegetation/flowerSpecies.js +15 -3
- package/src/vegetation/grassPalettes.js +153 -0
- package/src/vegetation/index.js +8 -0
- package/src/vegetation/scatter.js +297 -0
- package/src/vegetation/stylizedBush.js +2 -0
- package/src/vegetation/stylizedFlower.js +82 -0
- package/src/vegetation/stylizedFlowers.js +96 -8
- package/src/vegetation/stylizedForest.js +476 -0
- package/src/vegetation/stylizedGrass.js +331 -48
- package/src/vegetation/stylizedTree.js +109 -4
- package/src/vegetation/stylizedTreeFoliage.js +13 -3
- package/src/vegetation/vegetationShaders.js +1110 -0
- package/src/vfxgen/INTEGRATION.md +145 -0
- package/src/vfxgen/core/burstBackbone.js +380 -0
- package/src/vfxgen/core/projectileCore.js +92 -0
- package/src/vfxgen/core/spriteShapes.js +98 -0
- package/src/vfxgen/core/trailRibbon.js +272 -0
- package/src/vfxgen/core/vfxRandom.js +29 -0
- package/src/vfxgen/effects/emitHelpers.js +37 -0
- package/src/vfxgen/effects/magicEffects.js +162 -0
- package/src/vfxgen/effects/movementEffects.js +87 -0
- package/src/vfxgen/effects/weaponEffects.js +118 -0
- package/src/vfxgen/index.js +18 -0
- package/src/vfxgen/moves/moveController.js +146 -0
- package/src/vfxgen/moves/moveLibrary.js +335 -0
- package/src/vfxgen/vfxPresets.js +98 -0
- package/src/vfxgen/vfxSettings.js +384 -0
- package/src/vfxgen/vfxSystem.js +449 -0
- package/src/vfxgen/weapons/stylizedWeapons.js +137 -0
- package/src/villagegen/index.js +4 -0
- package/src/villagegen/stylizedVillage.js +490 -0
- package/src/villagegen/villageArchetypes.js +160 -0
- package/src/villagegen/villageNames.js +40 -0
- package/src/villagegen/villageSites.js +105 -0
- package/src/water/sceneOverrideLayers.js +23 -0
- package/src/water/water.js +5 -0
- package/src/water/waterBreakerSystem.js +15 -1
- package/src/water/waterCurrentField.js +447 -0
- package/src/water/waterMaterial.js +12 -0
- package/src/water/waterNearshorePhase.js +320 -0
- package/src/water/waterScenePasses.js +86 -29
- package/src/water/waterSettings.js +335 -13
- package/src/water/waterShoreMaterial.js +322 -0
- package/src/water/waterShoreStateField.js +605 -0
- package/src/water/waterSurface.js +824 -28
- package/src/weather/index.js +6 -0
- package/src/weather/weatherPrecipitation.js +221 -0
- package/src/weather/weatherPresets.js +258 -0
- package/src/weather/weatherSettings.js +269 -0
- package/src/weather/weatherSystem.js +871 -0
- package/src/worldCollision.js +94 -0
- package/src/worldMinimap.js +214 -0
- package/src/worldPresets.js +125 -0
package/README.md
CHANGED
|
@@ -4,8 +4,9 @@ ToonLab by Call Me Sensei is a stylized anime-style game starter kit and
|
|
|
4
4
|
runtime library for [Three.js](https://threejs.org/). Its goal is to simplify
|
|
5
5
|
Three.js game development: you get a better-looking anime/stylized game
|
|
6
6
|
without having to develop shaders yourself, and procedurally generated assets
|
|
7
|
-
(trees, rocks, grass
|
|
8
|
-
on your core game logic instead.
|
|
7
|
+
(trees, rocks, grass) plus integrated procedural world systems (water, sky)
|
|
8
|
+
reduce content complexity so you can focus on your core game logic instead.
|
|
9
|
+
Clone it and a toon-shaded character is
|
|
9
10
|
walking and swimming through a fully stylized world: cel-shaded characters,
|
|
10
11
|
painterly environments, interactive water, procedural vegetation and sky,
|
|
11
12
|
post-processing, and a schema-driven tuning panel. Use it as a starter kit,
|
|
@@ -14,6 +15,18 @@ subpath exports per cluster).
|
|
|
14
15
|
|
|
15
16
|
## Quickstart
|
|
16
17
|
|
|
18
|
+
**No install** — use the hosted labs at **[toonlab.io](https://toonlab.io)**:
|
|
19
|
+
define character, vegetation, and environment shaders; author stylized assets;
|
|
20
|
+
tune water and sky systems; and export portable presets from the browser.
|
|
21
|
+
|
|
22
|
+
**As a library** in your own Three.js app:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @call-me-sensei/toonlab
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Run the labs locally** (this repo):
|
|
29
|
+
|
|
17
30
|
```bash
|
|
18
31
|
git clone https://github.com/call-me-sensei/toonlab.git && cd toonlab
|
|
19
32
|
npm install
|
|
@@ -23,25 +36,78 @@ npm run dev
|
|
|
23
36
|
Vite serves the labs at `http://localhost:5175`. See
|
|
24
37
|
[Getting started](docs/getting-started.md) for a tour.
|
|
25
38
|
|
|
39
|
+
**Building with an AI coding agent?** That is the fastest path through all of
|
|
40
|
+
this — see [Build with an AI coding agent](#build-with-an-ai-coding-agent)
|
|
41
|
+
for the recommended setup (skills + MCP) and ready-to-paste starting prompts.
|
|
42
|
+
|
|
43
|
+
### Local MCP server
|
|
44
|
+
|
|
45
|
+
Running the labs locally also creates a disk-backed `.toonlab/` workspace
|
|
46
|
+
shared by the browser tools and the included MCP server. Open
|
|
47
|
+
`http://localhost:5175/settings/` for a checkout-specific configuration you
|
|
48
|
+
can paste into an MCP-compatible coding tool.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm run dev
|
|
52
|
+
# In an MCP client, use the command/config shown at /settings/.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The local server can search the built-in procedural catalog and public CC0
|
|
56
|
+
sources, read your saved presets and exported files, generate seeded recipes,
|
|
57
|
+
and import assets into the project. It uses stdio, requires no account or
|
|
58
|
+
OAuth, and keeps work on disk. See [Local MCP and workspace](docs/mcp.md).
|
|
59
|
+
|
|
26
60
|
## The labs
|
|
27
61
|
|
|
28
|
-
|
|
29
|
-
the
|
|
30
|
-
|
|
31
|
-
- **Shader
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- **
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- **
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
62
|
+
Lab UIs are development tools and are not published in the npm package. The
|
|
63
|
+
Labs home (`/`) presents them by the artifact they author:
|
|
64
|
+
|
|
65
|
+
- **Shader Labs** — Character Shader Lab (`/shader-lab/`), Vegetation Shader
|
|
66
|
+
Lab (`/vegetation-shader-lab/`), and Environment Shader Lab
|
|
67
|
+
(`/environment-lab/`) each save one reusable IP-wide material treatment.
|
|
68
|
+
- **Asset Labs** — Rock, Tree, Flower, Grass, Debris, and Texture Labs author
|
|
69
|
+
geometry, material data, recipes, and exports for individual asset classes.
|
|
70
|
+
Grass color palettes coordinate base, tip, and shadow tint as one set.
|
|
71
|
+
- **World Systems** — Water Lab (`/water-lab/`) authors waves, surface
|
|
72
|
+
shading, foam, reflections, interaction, and quality as one runtime preset;
|
|
73
|
+
Sky Lab (`/sky-lab/`) authors the gradient, sun, clouds, stars, and cloud
|
|
74
|
+
motion as one runtime preset. Their shader controls are embedded in the
|
|
75
|
+
complete system labs rather than duplicated as separate shader labs.
|
|
76
|
+
- **Playgrounds & demos** — Playground, Water Playground, Outdoor World, VFX
|
|
77
|
+
Arena, Fauna Demo, and Ambient VFX Demo validate the authored artifacts in
|
|
78
|
+
interactive scenes.
|
|
79
|
+
|
|
80
|
+
Supporting editors remain available by direct URL: Weather Lab
|
|
81
|
+
(`/weather-lab/`) coordinates current atmosphere, wind, precipitation,
|
|
82
|
+
lightning, and surface state; Lighting Lab (`/lighting-lab/`) authors light
|
|
83
|
+
rigs and budgets; Prop Lab (`/prop-lab/`) and Building Lab
|
|
84
|
+
(`/building-lab/`) expose the broader procedural library; Gallery
|
|
85
|
+
(`/gallery/`) searches supported open-asset sources. The procedural Catalog
|
|
86
|
+
is exposed through `@call-me-sensei/toonlab/catalog`. See
|
|
87
|
+
[Lab responsibilities](docs/lab-architecture.md) for the scope rules and
|
|
88
|
+
[Getting started](docs/getting-started.md) for every direct route.
|
|
89
|
+
|
|
90
|
+
Sky and Water are integrated runtime systems, not extra Shader Labs. Their
|
|
91
|
+
`.settings` are authored preset data; current Lighting and Weather state is
|
|
92
|
+
composed through named transient layers and exposed as `.renderedSettings`
|
|
93
|
+
without changing exported presets. Create a `LightingSystem`, then call
|
|
94
|
+
`lighting.attachWorld(world)` to own the Lighting layers and connect the
|
|
95
|
+
world's Weather coordinator as modulation, so each system can detach only its
|
|
96
|
+
own layer. The shared `world.setSun({ direction, color, sky })` adapter keeps
|
|
97
|
+
the physical light/shadows, vegetation scene inputs, Sky, and Water aligned;
|
|
98
|
+
Weather captures and restores every transient baseline it drives. Sky presets contain exactly 46
|
|
99
|
+
portable art fields; dome radius and compile-time quality stay outside the
|
|
100
|
+
document. Sky provides low/medium/high cloud graphs plus custom 1–5-octave
|
|
101
|
+
quality and can rebuild its material with `setQuality()`. Water quality is a
|
|
102
|
+
construction-time graph choice; switching it requires replacing/rebuilding
|
|
103
|
+
the surface rather than calling `applySettings()`.
|
|
104
|
+
|
|
105
|
+
Every URL parameter has a HUD control. In local development, lab state is
|
|
106
|
+
mirrored into `.toonlab/` so the MCP server and browser share it; existing
|
|
107
|
+
`localStorage` and IndexedDB data migrate on first run. Static hosted builds
|
|
108
|
+
fall back to browser storage. **Reset Lab** clears the current lab state.
|
|
109
|
+
Point any model-aware lab at your own model with the Model URL input or
|
|
110
|
+
`?model=` — see
|
|
45
111
|
[Characters](docs/characters.md).
|
|
46
112
|
|
|
47
113
|
## What's inside
|
|
@@ -50,20 +116,92 @@ with the Model URL input or `?model=` — see
|
|
|
50
116
|
|---|---|---|
|
|
51
117
|
| Toon character shading | `@call-me-sensei/toonlab/toon` | Modern anime character shader: cel bands with art-directed face lighting, skin-tone shadow management, shadow-color HSV control, scene/self/contact shadows, average-shadow smoothing, rim light (fresnel or screen-space depth), stylized + anisotropic hair highlights, eye catchlights, role-aware specular, source map routing (normal/AO/emissive/MatCap/ramp/detail), inverted-hull outlines, glitter, stickers, perspective removal, shell fur, dither fades — 23 settings groups, all preset-serializable. [Docs](docs/toon-shading.md) |
|
|
52
118
|
| Environment shading | `@call-me-sensei/toonlab/environment` | Modern anime-style scene shader for texture packs, standard glTF, and untextured scenes: material-role classification, wrapped lighting, packed-map hints, window cutouts, sun/lamp rigs, time-of-day, six-direction ambient probe, planar floor reflections, BVH vertex-AO baking, height fog, cloud shadows. [Docs](docs/environment.md) |
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
119
|
+
| Lighting | `@call-me-sensei/toonlab/lighting` | Versioned lighting recipes and looks, physical/artistic intensity helpers, reusable luminaire/rig/look/quality presets, deterministic light and shadow budgets, capability diagnostics, runtime Three.js realization, and a data-only Unreal Engine 5.8 MegaLights/Lumen handoff. [Docs](docs/lighting.md) |
|
|
120
|
+
| Weather | `@call-me-sensei/toonlab/weather` | Shared cross-system weather coordinator with 22 presets, smooth transitions, one-draw GPU precipitation (rain, snow, sleet, hail, dust), lightning/thunder events, and normalized wetness/snow/ice outputs. It drives sky, sun, fog, cloud shadows, wind, vegetation, water, fauna, and ambient effects through their public adapters. [Docs](docs/weather.md) |
|
|
121
|
+
| Water | `@call-me-sensei/toonlab/water` | Fully procedural integrated water system: Gerstner wave stack with a calm→storm dial, wave sets, plunging breakers you can surf, three-stop absorption color, refraction/caustics/foam, GPU ripple sim, splashes, wakes, rain, kelp, underwater view, construction-time quality, and a CPU mirror of the whole spectrum for buoyancy. [Docs](docs/water.md) |
|
|
122
|
+
| Vegetation | `@call-me-sensei/toonlab/vegetation` | Instanced grass and flower fields, procedural trees/flowers with serializable recipes, coordinated grass palettes (base, tip, and shadow tint), and one semantic-role `VegetationShaderProfile` shared across grass, foliage, flowers, bark, and stems. Asset identity and current wind/weather remain separate. [Docs](docs/vegetation-sky.md) |
|
|
123
|
+
| Paths, roads & bridges | `@call-me-sensei/toonlab/pathgen` | Seeded path networks routed over any `heightAt`: cost-field router (slope/water aware), hand-drawn ribbon overlay in dirt/stone/planks, arched plank bridges with collision, stepped stone climbs, flattened `paths.heightAt` for walkability, scatter exclusion mask, minimap overlay. |
|
|
124
|
+
| Props & placement | `@call-me-sensei/toonlab/propgen` | The universal placement pipeline (the PropAsset contract: grounded, collided, instanced, hi/lo LOD by true 3D distance) + 12 seeded prop generators across fences, lanterns, signposts, stairs, milestones, wells, crates, firewood, torii, piers, stone walls, benches. `propAssetFromObject` drops any imported GLB into the same pipeline. |
|
|
125
|
+
| Buildings | `@call-me-sensei/toonlab/buildinggen` | Shape-grammar stylized exteriors (cottage/shed/farmhouse/watchtower/shrine): seeded recipes, timber facades with windows that never intersect beams, always-overhanging roofs (gable/hip/shed/pagoda-ish), buried foundation skirts for slopes, ≤ 6 draw calls per building, grammar invariants asserted across 1000 seeds. |
|
|
126
|
+
| Villages & POIs | `@call-me-sensei/toonlab/villagegen` | Seeded settlements composed from paths + props + buildings: site scoring, main-street layout with parcels facing the street, archetypes as data (village, fishing hamlet, shrine, campsite, ruin), seeded place names, world `pois` option that roads everything together. |
|
|
127
|
+
| Fauna | `@call-me-sensei/toonlab/fauna` | Instanced GPU-animated ambient creatures: flocking birds that perch and flush, butterflies over flower masks, hovering dragonflies, schooling koi — staggered boids, hard population budgets, ≤ 1 ms CPU at defaults. |
|
|
128
|
+
| Ambient VFX | `@call-me-sensei/toonlab/ambientfx` | One GPU particle backbone, five effects: falling petals and leaves, dusk fireflies, backlit pollen, shoreline mist — follow-window emission, shared wind with grass, time-of-day gates, 3 draw calls total. |
|
|
129
|
+
| Asset catalog | `@call-me-sensei/toonlab/catalog` | Every recipe/preset as a searchable manifest with one headline call: `catalog.spawn(id, { seed })` → a placeable PropAsset for props, buildings, trees, rocks, and debris. `catalog.addSource(url)` mounts remote registries. |
|
|
130
|
+
| Sky | `@call-me-sensei/toonlab/sky` | Integrated gradient/sun/painterly-cloud/star system with exactly 46 portable art fields, named live scene layers, compile-time quality tiers/custom 1–5 cloud octaves, meaningful built-in looks, and water-reflection compatibility. [Docs](docs/sky.md) |
|
|
56
131
|
| Post-processing | `@call-me-sensei/toonlab/post` | Optional single-pipeline compositor: character-aware bloom, color grade, LUT, vignette, screen outline, depth cue — schema-driven, preset-serializable. [Docs](docs/post-processing.md) |
|
|
132
|
+
| Camera | `@call-me-sensei/toonlab/camera` | Extensible camera operator stack, generated recipe/preset documents, follow/framing/collision/damping/noise/impulse behavior, and a director for blending reusable rigs. [Style domain docs](docs/style-labs.md#camera) |
|
|
133
|
+
| Game feel | `@call-me-sensei/toonlab/game-feel` | Event-driven response scheduler for camera punches, hit-stop/time warp, squash, flashes, audio, and haptics through capability-safe adapters, extensible effect factories, and bounded concurrency. [Style domain docs](docs/style-labs.md#game-feel) |
|
|
134
|
+
| Procedural textures | `@call-me-sensei/toonlab/texgen` | Seamless CPU-baked PBR texture generator: 25 tileable pattern/noise generators, layered detail + colored overlays (moss, rust, grime), five-stop cel-capable color ramp, cavity/sheen hand-painted read, derived normal/AO/roughness/metalness/height/ORM/emissive maps, 60+ presets, and a natural-language recipe mapper (offline keywords or BYO-key Gemini/OpenAI). [Docs](docs/texture-lab.md) |
|
|
57
135
|
| Character pipeline | `@call-me-sensei/toonlab/character` | Bone-role adapters for VRM/MMD/Mixamo/Rigify rigs, native-clip conventions, Mixamo retarget helpers, and a procedural freestyle swim clip. [Docs](docs/characters.md) |
|
|
58
136
|
| Model loaders | `@call-me-sensei/toonlab/loaders` | Optional GLB/glTF, VRM 0+1, PMX/PMD, FBX, OBJ, and text-USDZ loading helpers. Kept off the root import so apps that do not load models avoid loader dependencies. [Docs](docs/characters.md) |
|
|
59
137
|
| Debug panel | `@call-me-sensei/toonlab/debug` | One-line schema-driven tuning GUI for any settings module — the same panel the labs use. [Docs](docs/debug-panel.md) |
|
|
60
138
|
|
|
139
|
+
The main `vegetation` barrel exposes the complete runtime. Smaller consumers
|
|
140
|
+
can import the same bindings from
|
|
141
|
+
`@call-me-sensei/toonlab/vegetation-shaders` or
|
|
142
|
+
`@call-me-sensei/toonlab/grass-palettes`; package verification asserts that
|
|
143
|
+
the focused subpaths and root export reference the identical implementations.
|
|
144
|
+
|
|
61
145
|
Zero texture assets in the library: water, sky, grass, flowers, trees, and
|
|
62
146
|
splashes are all procedural. The one bundled model is a CC0 mannequin with 45
|
|
63
147
|
embedded animation clips.
|
|
64
148
|
|
|
65
149
|
## Library usage
|
|
66
150
|
|
|
151
|
+
### A complete open world in one screen of code
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
import { createStylizedTerrain, createStylizedWorld, createWorldMinimap } from '@call-me-sensei/toonlab';
|
|
155
|
+
|
|
156
|
+
// Seeded terrain generator — ANY seed is a valid, playable world. One knob
|
|
157
|
+
// per big idea: waterCoverage (how much water), height (mountain range),
|
|
158
|
+
// depth (basins), size (number or { x, z }), floatingIslands, sinkholes.
|
|
159
|
+
const terrain = createStylizedTerrain({ seed: 42, size: 1000, archetype: 'terracedKarst' });
|
|
160
|
+
const terrainRoot = new THREE.Group();
|
|
161
|
+
terrainRoot.add(terrain.root);
|
|
162
|
+
scene.add(terrainRoot);
|
|
163
|
+
|
|
164
|
+
// Environment shading, aligned sun + real shadows, sky, anime water, LOD
|
|
165
|
+
// forests (billboard far trees), follow-window grass, cloud shadows,
|
|
166
|
+
// unified three-layer fog, and collision — all on by default.
|
|
167
|
+
const world = await createStylizedWorld({
|
|
168
|
+
renderer, scene, camera,
|
|
169
|
+
terrain: { heightAt: terrain.heightAt, root: terrainRoot, size: terrain.meshExtent },
|
|
170
|
+
water: { level: terrain.waterLevel },
|
|
171
|
+
weather: { preset: 'call_me_sensei' }, // 'snow' | 'hail' | 'thunderstorm' | ...
|
|
172
|
+
followTarget: character, // your character root (optional): splashes, wakes, grass push
|
|
173
|
+
});
|
|
174
|
+
character.position.copy(terrain.spawn); // probed: walkable, near a shore
|
|
175
|
+
|
|
176
|
+
const clock = new THREE.Clock();
|
|
177
|
+
renderer.setAnimationLoop(() => {
|
|
178
|
+
world.update(clock.getDelta());
|
|
179
|
+
renderer.render(scene, camera);
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Bring your own terrain instead** — the generator is optional. The whole
|
|
184
|
+
contract is a pure `heightAt(x, z)` in meters plus your displaced mesh under
|
|
185
|
+
`terrain.root`; masks, scatter, collision, and the minimap all derive from
|
|
186
|
+
it:
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
const heightAt = (x, z) => 12 * Math.sin(x / 90) * Math.cos(z / 90); // yours
|
|
190
|
+
const world = await createStylizedWorld({
|
|
191
|
+
renderer, scene, camera,
|
|
192
|
+
terrain: { heightAt, root: myTerrainRoot, size: 1200 },
|
|
193
|
+
water: { level: 0 },
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Add a clickable minimap with `createWorldMinimap({ heightAt, size,
|
|
198
|
+
waterLevel, onPick })`, and solid rocks/trees with the built-in
|
|
199
|
+
`world.collision` (`addCircles` for your own props, `resolve(position,
|
|
200
|
+
radius)` per frame). Archetypes: `terracedKarst`, `lakeland`, `alpine`,
|
|
201
|
+
`rollingPlains`, `archipelago`.
|
|
202
|
+
|
|
203
|
+
### Individual clusters
|
|
204
|
+
|
|
67
205
|
```js
|
|
68
206
|
import { applyToonShader, createToonSettings } from '@call-me-sensei/toonlab/toon';
|
|
69
207
|
|
|
@@ -98,25 +236,160 @@ stack, with WebGL2 fallback through the same TSL path.
|
|
|
98
236
|
|
|
99
237
|
## Documentation
|
|
100
238
|
|
|
239
|
+
- **In-browser docs** — with the labs running (`npm run dev`), open
|
|
240
|
+
`http://localhost:5175/docs/` for guided documentation: library usage,
|
|
241
|
+
MCP setup, the prompt cookbook, and the full settings reference. Hosted
|
|
242
|
+
features are marked "Pro"; the extended hosted docs live at
|
|
243
|
+
[toonlab.io/docs](https://toonlab.io/docs).
|
|
244
|
+
- [Lab responsibilities](docs/lab-architecture.md) — the boundary between
|
|
245
|
+
Shader Labs, Asset Labs, World Systems, and preview-only scene state.
|
|
101
246
|
- [Getting started](docs/getting-started.md) — clone, run, tour the labs,
|
|
102
247
|
load your own models.
|
|
103
248
|
- [Toon character shading](docs/toon-shading.md)
|
|
104
249
|
- [Environment shading](docs/environment.md)
|
|
250
|
+
- [Lighting](docs/lighting.md)
|
|
251
|
+
- [Weather system](docs/weather.md)
|
|
252
|
+
- [Generative style labs](docs/style-labs.md) — Post & Color, Camera, Motion,
|
|
253
|
+
UI Theme, Biome, Soundscape, and Game Feel; shared recipes, MCP authoring,
|
|
254
|
+
package runtimes, quality budgets, and engine design references.
|
|
105
255
|
- [Water](docs/water.md)
|
|
106
|
-
- [
|
|
256
|
+
- [Sky system](docs/sky.md)
|
|
257
|
+
- [Vegetation](docs/vegetation-sky.md)
|
|
107
258
|
- [Post-processing](docs/post-processing.md)
|
|
259
|
+
- [Texture Lab and texgen](docs/texture-lab.md)
|
|
108
260
|
- [Characters and animation](docs/characters.md)
|
|
109
261
|
- [Debug panel](docs/debug-panel.md)
|
|
262
|
+
- [World scale and world presets](docs/world-scale.md) — the meters
|
|
263
|
+
convention, open-world scale presets, rock quality tiers, and vegetation
|
|
264
|
+
scatter helpers.
|
|
110
265
|
- [Settings reference](docs/settings-reference.md) — every tunable field,
|
|
111
266
|
generated from the schemas (`node scripts/generate-settings-reference.mjs`).
|
|
112
267
|
- [Shader constants](docs/shader-constants.md) — the deliberately unexposed
|
|
113
268
|
constants and where they live.
|
|
114
269
|
|
|
115
|
-
## AI coding
|
|
270
|
+
## Build with an AI coding agent
|
|
271
|
+
|
|
272
|
+
ToonLab is designed to be driven by a coding agent (Claude Code, Codex,
|
|
273
|
+
Cursor, …). The recommended setup has three parts: give the agent the ToonLab
|
|
274
|
+
skills, connect an MCP server for asset discovery, then start from a goal
|
|
275
|
+
prompt and iterate. Everything the agent needs ships in this repo under
|
|
276
|
+
`agents/` (not in the npm package — the package stays runtime-only).
|
|
277
|
+
|
|
278
|
+
### 1. Install the ToonLab skills in your game project
|
|
279
|
+
|
|
280
|
+
The skills teach the agent the assembly order, the frame-loop contract, and
|
|
281
|
+
each subsystem's API so it wires ToonLab correctly on the first try. Start
|
|
282
|
+
with `game-dev`; the other twelve cover individual features (water, weather,
|
|
283
|
+
lighting, camera, game feel, …).
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
# Claude Code — feature skills + project guidance
|
|
287
|
+
mkdir -p .claude/skills
|
|
288
|
+
cp -R path/to/toonlab/agents/skills/claude/* .claude/skills/
|
|
289
|
+
cat path/to/toonlab/agents/codex/AGENTS.md >> CLAUDE.md
|
|
290
|
+
|
|
291
|
+
# Codex — shared guide + Codex-oriented skills
|
|
292
|
+
cat path/to/toonlab/agents/codex/AGENTS.md >> AGENTS.md
|
|
293
|
+
cp -R path/to/toonlab/agents/skills/codex path/to/your-game/docs/toonlab-skills
|
|
294
|
+
|
|
295
|
+
# Cursor — rule file
|
|
296
|
+
mkdir -p .cursor/rules
|
|
297
|
+
cp path/to/toonlab/agents/cursor/toonlab.mdc .cursor/rules/
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
See [`agents/README.md`](agents/README.md) for the full layout.
|
|
301
|
+
|
|
302
|
+
### 2. Connect MCP for asset discovery
|
|
303
|
+
|
|
304
|
+
Two servers, and they compose:
|
|
305
|
+
|
|
306
|
+
**Local (free, no account).** The stdio server included in this package
|
|
307
|
+
searches the built-in procedural catalog and public CC0 sources, reads your
|
|
308
|
+
saved presets and lab exports, generates seeded recipes, and imports assets
|
|
309
|
+
into a disk-backed `.toonlab/` workspace:
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"mcpServers": {
|
|
314
|
+
"toonlab-local": {
|
|
315
|
+
"command": "npx",
|
|
316
|
+
"args": ["-y", "@call-me-sensei/toonlab@latest", "--workspace", "/absolute/path/to/your-game/.toonlab"]
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
If you run the labs from a checkout (`npm run dev`), open
|
|
323
|
+
`http://localhost:5175/settings/` for a ready-made config instead. See
|
|
324
|
+
[Local MCP and workspace](docs/mcp.md).
|
|
325
|
+
|
|
326
|
+
**ToonLab Pro (remote, OAuth).** [toonlab.io](https://toonlab.io) hosts a
|
|
327
|
+
remote MCP server that adds an indexed CC0 asset search with ToonLab-styled
|
|
328
|
+
previews, AI generation (concept art, seamless textures, image→3D model
|
|
329
|
+
chaining) on credits, stored characters with reference-image consistency, and
|
|
330
|
+
your cloud library of presets and style bundles. Requires a Pro or Team plan.
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
# Claude Code
|
|
334
|
+
claude mcp add --transport http toonlab https://toonlab.io/mcp
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Other clients: add `https://toonlab.io/mcp` as a remote MCP server and
|
|
338
|
+
authorize in the browser. Full client-by-client setup and a tool reference
|
|
339
|
+
live at [toonlab.io/docs/mcp](https://toonlab.io/docs/mcp).
|
|
340
|
+
|
|
341
|
+
### 3. The first prompt
|
|
342
|
+
|
|
343
|
+
Give the agent a goal, name the skill, and let it verify its own work:
|
|
344
|
+
|
|
345
|
+
```text
|
|
346
|
+
Using the ToonLab game-dev skill, set up a new Three.js + Vite project with
|
|
347
|
+
@call-me-sensei/toonlab. Build a 1 km seeded open world (archetype
|
|
348
|
+
"lakeland") with the bundled toon-shaded mannequin as the playable character,
|
|
349
|
+
water, sky, the "call_me_sensei" weather preset, post-processing, and a
|
|
350
|
+
follow camera with game feel. Follow the skill's assembly order and
|
|
351
|
+
frame-loop contract, then run the dev server and fix issues until I can walk
|
|
352
|
+
from spawn to the shoreline and swim.
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### 4. Prompts for common jobs
|
|
356
|
+
|
|
357
|
+
```text
|
|
358
|
+
Use the ToonLab MCP server to find CC0 props for a small fishing village —
|
|
359
|
+
lanterns, crates, a pier — then place them with the propgen placement
|
|
360
|
+
pipeline so they are grounded, collided, and LOD'd. Add a torii gate near
|
|
361
|
+
the spawn using catalog.spawn.
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
```text
|
|
365
|
+
Using the ToonLab water skill, make the ocean stormier as the player sails
|
|
366
|
+
away from shore, and let them surf the plunging breakers near the reef.
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
```text
|
|
370
|
+
Generate a seamless mossy stone texture with texgen and apply it to the
|
|
371
|
+
shrine path. I want a hand-painted look with a five-stop cel ramp.
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
```text
|
|
375
|
+
Using the ToonLab weather + lighting skills, add a day/night cycle with a
|
|
376
|
+
thunderstorm that rolls in at dusk: wind picks up in the grass, rain streaks
|
|
377
|
+
the water, lightning drives the sky and light rig.
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
```text
|
|
381
|
+
Search my ToonLab library for the "sunset-festival" style bundle and apply
|
|
382
|
+
it across toon shading, sky, water, and post so the whole game matches it.
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
```text
|
|
386
|
+
Give the sword swing anime game feel: hit-stop, a camera punch, a trail
|
|
387
|
+
ribbon and impact sparks from vfxgen, and a white flash on hit.
|
|
388
|
+
```
|
|
116
389
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
390
|
+
A more extensive prompt cookbook — including the Pro generation and
|
|
391
|
+
character-consistency workflows — is at
|
|
392
|
+
[toonlab.io/docs/prompts](https://toonlab.io/docs/prompts).
|
|
120
393
|
|
|
121
394
|
## License
|
|
122
395
|
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Characters and animation
|
|
2
|
+
|
|
3
|
+
Bring-your-own-model is a first-class feature: any humanoid character in a
|
|
4
|
+
common format gets loaded, toon-shaded, and animated — without code changes
|
|
5
|
+
in the labs, with rig helpers in `@call-me-sensei/toonlab/character` and optional loader
|
|
6
|
+
helpers in `@call-me-sensei/toonlab/loaders` for your own app.
|
|
7
|
+
|
|
8
|
+
## Loading models
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
import { loadModelAsset, SUPPORTED_MODEL_FORMATS } from '@call-me-sensei/toonlab/loaders';
|
|
12
|
+
|
|
13
|
+
const asset = await loadModelAsset('models/hero.vrm');
|
|
14
|
+
// asset: { root, clips, format, url, resourcePath, vrm? }
|
|
15
|
+
scene.add(asset.root);
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
(Inside this repo the labs import from `../../src/character/...`.)
|
|
19
|
+
|
|
20
|
+
Supported formats (`SUPPORTED_MODEL_FORMATS`): `pmx`, `pmd`, `fbx`, `glb`,
|
|
21
|
+
`gltf`, `vrm` (0 and 1), `obj` (pass `materialUrl` for the MTL), and
|
|
22
|
+
text-based `usdz`. VRM models are detected automatically on glTF load,
|
|
23
|
+
rotated to the +Z convention, and returned with the `vrm` instance.
|
|
24
|
+
|
|
25
|
+
Draco or KTX2-compressed glTF assets need an explicit decoder directory:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
await loadModelAsset('models/compressed.glb', {
|
|
29
|
+
decoderBasePath: '/vendor/three-decoders/',
|
|
30
|
+
renderer,
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
In the labs, use the HUD **Model URL** input or `?model=` — local paths and
|
|
35
|
+
hosted URLs both work (hosted URLs need CORS headers on the server; load
|
|
36
|
+
failures surface in a HUD banner). Private test models go in the gitignored
|
|
37
|
+
`assets-local/models/` drop-in folder: after `npm run assets:local` they
|
|
38
|
+
surface in every model-aware lab's Model select, no code changes. See
|
|
39
|
+
[getting-started.md](getting-started.md#loading-your-own-models) for the
|
|
40
|
+
folder shapes the scanner recognizes.
|
|
41
|
+
|
|
42
|
+
## Bone-role adapters (`characterRig`)
|
|
43
|
+
|
|
44
|
+
Animation is rig-agnostic because bone *names* are resolved to canonical
|
|
45
|
+
humanoid *roles* (VRM humanoid naming, `HUMANOID_ROLES`) once, up front:
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
import { resolveCharacterRig, targetBoneNameForRole } from '@call-me-sensei/toonlab/character';
|
|
49
|
+
|
|
50
|
+
const rig = resolveCharacterRig(skinnedMesh, { vrm: asset.vrm });
|
|
51
|
+
// rig: { type, targetToMixamo, mixamoToTarget, hipCarrierName } — or null
|
|
52
|
+
targetBoneNameForRole(rig, 'head'); // the model's actual head bone name
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`resolveCharacterRig` tries each convention adapter in order:
|
|
56
|
+
|
|
57
|
+
1. **VRM** — the humanoid bone map from the VRM extension (spec'd, exact).
|
|
58
|
+
2. **MMD/PMX** — Japanese bone names (`頭`, `下半身`, ...), including the
|
|
59
|
+
center-bone hip carrier.
|
|
60
|
+
3. **Mixamo-named** — skeletons already using `mixamorig` names (normalized
|
|
61
|
+
for the common prefix variants).
|
|
62
|
+
4. **Rigify** — Blender Rigify `DEF-` deform bones, matched loosely
|
|
63
|
+
(heuristic name matching handles export renaming).
|
|
64
|
+
|
|
65
|
+
If no adapter matches, retargeting is impossible and models fall back to
|
|
66
|
+
their embedded clips. Everything downstream (retargeting, the procedural
|
|
67
|
+
swim clip, head tracking) works through roles, so a new rig convention is
|
|
68
|
+
one name table, not a new pipeline.
|
|
69
|
+
|
|
70
|
+
## Native-clip fast path
|
|
71
|
+
|
|
72
|
+
Models that ship their own locomotion clips skip retargeting entirely. A
|
|
73
|
+
model qualifies when at least idle + walk resolve against these clip-name
|
|
74
|
+
conventions (`NATIVE_LOCOMOTION_CLIP_NAMES` in
|
|
75
|
+
`labs/playground/animationPipeline.js`; first match per role wins):
|
|
76
|
+
|
|
77
|
+
| Role | Accepted clip names |
|
|
78
|
+
|---|---|
|
|
79
|
+
| idle | `Idle_Loop`, `Idle` |
|
|
80
|
+
| walk | `Walk_Loop`, `Walking`, `Walk` |
|
|
81
|
+
| run | `Sprint_Loop`, `Jog_Fwd_Loop`, `Running`, `Run` |
|
|
82
|
+
| jump | `Jump_Start`, `Jump_Loop`, `Jump` |
|
|
83
|
+
| swim | `Swim_Fwd_Loop`, `Swimming`, `Swim` |
|
|
84
|
+
| tread | `Swim_Idle_Loop`, `Treading_Water`, `TreadingWater` |
|
|
85
|
+
|
|
86
|
+
The bundled CC0 mannequin (Quaternius Universal Animation Library, 45
|
|
87
|
+
embedded clips) qualifies out of the box — that is why a fresh clone
|
|
88
|
+
animates with zero downloads. Author your own GLBs to these names and they
|
|
89
|
+
play natively too.
|
|
90
|
+
|
|
91
|
+
## Mixamo retarget pipeline
|
|
92
|
+
|
|
93
|
+
For models without native clips, the Playground retargets Mixamo FBX clips
|
|
94
|
+
onto the resolved rig with a world-space bake: only the role mapping comes
|
|
95
|
+
from `characterRig`; rest-pose differences (T-pose vs. A-pose) and hierarchy
|
|
96
|
+
mismatches are solved numerically. This is how a PMX character, a VRM
|
|
97
|
+
avatar, and a Rigify export all play the same `Walking.fbx`.
|
|
98
|
+
|
|
99
|
+
Adobe's terms do not permit redistributing Mixamo clips, so the repo ships
|
|
100
|
+
none. Download clips with your own Adobe account from
|
|
101
|
+
[mixamo.com](https://www.mixamo.com) and drop them into
|
|
102
|
+
`assets-local/animations/` (`Idle.fbx`, `Walking.fbx`, `Running.fbx`,
|
|
103
|
+
`Jump.fbx`, `Swimming.fbx`, `Treading_Water.fbx`, ...). Override individual
|
|
104
|
+
clips per URL: `?swimAnim=`, `?treadAnim=`, `?diveAnim=`, `?anim=`. See
|
|
105
|
+
[ATTRIBUTION.md](../ATTRIBUTION.md).
|
|
106
|
+
|
|
107
|
+
When a swim/tread retarget source is missing, the pipeline falls back to the
|
|
108
|
+
model's native swim clips if it has them.
|
|
109
|
+
|
|
110
|
+
## Procedural freestyle swim
|
|
111
|
+
|
|
112
|
+
`createFreestyleSwimClip(targetMesh, rig, options)` generates a freestyle
|
|
113
|
+
(front crawl) swim clip with no FBX source: windmilling catch-up arm
|
|
114
|
+
strokes, flutter kick, body roll, and a breath every fourth stroke. Motion
|
|
115
|
+
is authored as world-space rotation deltas against the bind pose, so the
|
|
116
|
+
same code bakes onto any supported skeleton (VRM, MMD, Mixamo-named,
|
|
117
|
+
Rigify).
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
import { createFreestyleSwimClip } from '@call-me-sensei/toonlab/character';
|
|
121
|
+
|
|
122
|
+
// Skeleton must be in bind pose when you call this.
|
|
123
|
+
const clip = createFreestyleSwimClip(targetMesh, rig, {
|
|
124
|
+
clipName: 'FreestyleSwim',
|
|
125
|
+
trackNameStyle: 'skeleton', // 'skeleton' for retarget-style mixers, 'node' for native-clip mixers
|
|
126
|
+
});
|
|
127
|
+
mixer.clipAction(clip).play();
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The Playground uses it as the default swim style (`?freestyleAnim=none`
|
|
131
|
+
disables it).
|
|
132
|
+
|
|
133
|
+
## swimVisualLift
|
|
134
|
+
|
|
135
|
+
Swim physics floats every model at the same capsule depth below the wave
|
|
136
|
+
surface — the whole swim backend (vertical control, clamps, ray geometry,
|
|
137
|
+
wave exposure) is tuned as a package around one value, and giving models
|
|
138
|
+
different physics floats re-exposes tuning bugs. Models that need to *look*
|
|
139
|
+
higher or lower in the water get `swimVisualLift`: a visual-only vertical
|
|
140
|
+
offset applied to the model group while swimming, which the physics never
|
|
141
|
+
sees. The compact mannequin uses `0.18` to read as surface freestyle; a
|
|
142
|
+
character with tall hair volume needs none. Per-model values live in the
|
|
143
|
+
lab's character options (`labs/shared/sceneHub.js`); override for testing
|
|
144
|
+
with `?swimVisualLift=`.
|