@bitefoundry/retrieviewer 0.0.2 → 0.0.4
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/ASSET-PROVENANCE.md +6 -0
- package/ASSETS-LICENSE.md +2 -1
- package/ATTRIBUTION.md +6 -1
- package/COMFORT-ART.md +65 -0
- package/DESKTOP-PLATFORMS.md +75 -0
- package/INSTALLING.md +8 -5
- package/PLUGIN.md +13 -10
- package/PREREQUISITES.md +95 -0
- package/PUPPY-MEMORY.md +102 -1
- package/README.ko.md +110 -0
- package/README.md +119 -58
- package/RELEASING.md +27 -14
- package/THIRD-PARTY-NOTICES.md +5 -3
- package/braille.mjs +35 -9
- package/examples/live.mjs +2 -2
- package/integrations/desktop/platform.mjs +27 -0
- package/integrations/linux-overlay/README.md +83 -0
- package/integrations/linux-overlay/overlay.py +1094 -0
- package/integrations/macos-overlay/README.md +83 -0
- package/integrations/macos-overlay/overlay.jxa +639 -0
- package/integrations/opencode/runtime.mjs +4 -4
- package/integrations/opencode/tui.tsx +1 -1
- package/integrations/windows-overlay/Overlay.cs +4 -4
- package/integrations/windows-overlay/desktop.mjs +40 -8
- package/integrations/windows-overlay/protocol.mjs +11 -7
- package/integrations/windows-overlay/worker.mjs +13 -7
- package/package.json +41 -14
- package/puppy-comfort-sprites.mjs +25 -0
- package/puppy-companion-comfort-q5.bin.gz +0 -0
- package/puppy-companion-comfort.json +77 -0
- package/puppy-companion-life.mjs +49 -16
- package/puppy-companion-objects.mjs +12 -0
- package/puppy-frame-predictive.mjs +15 -9
- package/puppy-frame-store.mjs +2 -2
- package/puppy-paper-world.mjs +14 -0
- package/puppy-paper.mjs +65 -14
- package/retrieviewer-cli.mjs +10 -3
- package/retrieviewer-plugin.d.mts +1 -1
- package/retrieviewer-plugin.mjs +1 -1
- package/retrieviewer.d.mts +10 -4
- package/retrieviewer.mjs +20 -14
- package/locomotion-core.mjs +0 -21
- package/locomotion-puppy.animal +0 -0
- package/vendor/procedural-animals/package.json +0 -40
- package/vendor/procedural-animals/src/animal.js +0 -146
- package/vendor/procedural-animals/src/bake.js +0 -51
- package/vendor/procedural-animals/src/build.js +0 -81
- package/vendor/procedural-animals/src/core/build/coatKit.js +0 -121
- package/vendor/procedural-animals/src/core/build/featherCards.js +0 -189
- package/vendor/procedural-animals/src/core/build/finEdges.js +0 -85
- package/vendor/procedural-animals/src/core/build/furSlope.js +0 -115
- package/vendor/procedural-animals/src/core/build/mesh.js +0 -67
- package/vendor/procedural-animals/src/core/build/pipeline.js +0 -272
- package/vendor/procedural-animals/src/core/build/seams.js +0 -183
- package/vendor/procedural-animals/src/core/build/warp.js +0 -112
- package/vendor/procedural-animals/src/core/build/weights.js +0 -393
- package/vendor/procedural-animals/src/core/math/vec.js +0 -81
- package/vendor/procedural-animals/src/core/motion/actions.js +0 -800
- package/vendor/procedural-animals/src/core/motion/bird.js +0 -3063
- package/vendor/procedural-animals/src/core/motion/birdActions.js +0 -1059
- package/vendor/procedural-animals/src/core/motion/common.js +0 -158
- package/vendor/procedural-animals/src/core/motion/index.js +0 -22
- package/vendor/procedural-animals/src/core/motion/quadruped.js +0 -2875
- package/vendor/procedural-animals/src/core/motion/snake.js +0 -1594
- package/vendor/procedural-animals/src/core/motion/spider.js +0 -1810
- package/vendor/procedural-animals/src/core/motion/swimmer.js +0 -1047
- package/vendor/procedural-animals/src/core/motion/swimmerActions.js +0 -613
- package/vendor/procedural-animals/src/core/render/animalObject.js +0 -262
- package/vendor/procedural-animals/src/core/render/coatMaterial.js +0 -1301
- package/vendor/procedural-animals/src/core/render/dqs.js +0 -159
- package/vendor/procedural-animals/src/core/render/eyes.js +0 -676
- package/vendor/procedural-animals/src/core/render/membranes.js +0 -77
- package/vendor/procedural-animals/src/core/render/skeleton.js +0 -41
- package/vendor/procedural-animals/src/core/rig/bird.js +0 -327
- package/vendor/procedural-animals/src/core/rig/quadruped.js +0 -76
- package/vendor/procedural-animals/src/core/rig/rig.js +0 -79
- package/vendor/procedural-animals/src/core/rig/snake.js +0 -76
- package/vendor/procedural-animals/src/core/rig/spider.js +0 -110
- package/vendor/procedural-animals/src/core/rig/swimmer.js +0 -181
- package/vendor/procedural-animals/src/core/sdf/eyeSocket.js +0 -53
- package/vendor/procedural-animals/src/core/sdf/mesher.js +0 -238
- package/vendor/procedural-animals/src/core/sdf/sdf.js +0 -263
- package/vendor/procedural-animals/src/index.d.ts +0 -98
- package/vendor/procedural-animals/src/index.js +0 -29
- package/vendor/procedural-animals/src/registry.js +0 -48
- package/vendor/procedural-animals/src/species/bear/behaviour.js +0 -463
- package/vendor/procedural-animals/src/species/bear/claws.js +0 -147
- package/vendor/procedural-animals/src/species/bear/coat.js +0 -726
- package/vendor/procedural-animals/src/species/bear/index.js +0 -139
- package/vendor/procedural-animals/src/species/bear/motion.js +0 -112
- package/vendor/procedural-animals/src/species/bear/regions.js +0 -78
- package/vendor/procedural-animals/src/species/bear/rig.js +0 -112
- package/vendor/procedural-animals/src/species/bear/sculpt.js +0 -272
- package/vendor/procedural-animals/src/species/boar/behaviour.js +0 -335
- package/vendor/procedural-animals/src/species/boar/coat.js +0 -372
- package/vendor/procedural-animals/src/species/boar/index.js +0 -110
- package/vendor/procedural-animals/src/species/boar/motion.js +0 -85
- package/vendor/procedural-animals/src/species/boar/regions.js +0 -88
- package/vendor/procedural-animals/src/species/boar/rig.js +0 -111
- package/vendor/procedural-animals/src/species/boar/sculpt.js +0 -285
- package/vendor/procedural-animals/src/species/cat/behaviour.js +0 -559
- package/vendor/procedural-animals/src/species/cat/coat.js +0 -841
- package/vendor/procedural-animals/src/species/cat/index.js +0 -211
- package/vendor/procedural-animals/src/species/cat/motion.js +0 -101
- package/vendor/procedural-animals/src/species/cat/regions.js +0 -82
- package/vendor/procedural-animals/src/species/cat/rig.js +0 -100
- package/vendor/procedural-animals/src/species/cat/sculpt.js +0 -266
- package/vendor/procedural-animals/src/species/cat/whiskers.js +0 -110
- package/vendor/procedural-animals/src/species/cheetah/coat.js +0 -427
- package/vendor/procedural-animals/src/species/cheetah/index.js +0 -51
- package/vendor/procedural-animals/src/species/cheetah/joints.js +0 -3
- package/vendor/procedural-animals/src/species/cheetah/motion.js +0 -77
- package/vendor/procedural-animals/src/species/cheetah/regions.js +0 -95
- package/vendor/procedural-animals/src/species/cheetah/rig.js +0 -66
- package/vendor/procedural-animals/src/species/cheetah/sculpt.js +0 -158
- package/vendor/procedural-animals/src/species/chicken/coat.js +0 -313
- package/vendor/procedural-animals/src/species/chicken/coverts.js +0 -320
- package/vendor/procedural-animals/src/species/chicken/index.js +0 -110
- package/vendor/procedural-animals/src/species/chicken/motion.js +0 -177
- package/vendor/procedural-animals/src/species/chicken/regions.js +0 -66
- package/vendor/procedural-animals/src/species/chicken/rig.js +0 -144
- package/vendor/procedural-animals/src/species/chicken/sculpt.js +0 -389
- package/vendor/procedural-animals/src/species/chicken/wingLook.js +0 -66
- package/vendor/procedural-animals/src/species/chicken/wingStack.js +0 -124
- package/vendor/procedural-animals/src/species/cow/behaviour.js +0 -521
- package/vendor/procedural-animals/src/species/cow/coat.js +0 -465
- package/vendor/procedural-animals/src/species/cow/index.js +0 -118
- package/vendor/procedural-animals/src/species/cow/motion.js +0 -81
- package/vendor/procedural-animals/src/species/cow/regions.js +0 -98
- package/vendor/procedural-animals/src/species/cow/rig.js +0 -116
- package/vendor/procedural-animals/src/species/cow/sculpt.js +0 -339
- package/vendor/procedural-animals/src/species/crow/coat.js +0 -145
- package/vendor/procedural-animals/src/species/crow/index.js +0 -70
- package/vendor/procedural-animals/src/species/crow/joints.js +0 -3
- package/vendor/procedural-animals/src/species/crow/motion.js +0 -101
- package/vendor/procedural-animals/src/species/crow/regions.js +0 -50
- package/vendor/procedural-animals/src/species/crow/rig.js +0 -83
- package/vendor/procedural-animals/src/species/crow/sculpt.js +0 -118
- package/vendor/procedural-animals/src/species/deer/behaviour.js +0 -513
- package/vendor/procedural-animals/src/species/deer/coat.js +0 -391
- package/vendor/procedural-animals/src/species/deer/index.js +0 -106
- package/vendor/procedural-animals/src/species/deer/motion.js +0 -97
- package/vendor/procedural-animals/src/species/deer/regions.js +0 -60
- package/vendor/procedural-animals/src/species/deer/rig.js +0 -124
- package/vendor/procedural-animals/src/species/deer/sculpt.js +0 -297
- package/vendor/procedural-animals/src/species/dog/behaviour.js +0 -521
- package/vendor/procedural-animals/src/species/dog/coat.js +0 -495
- package/vendor/procedural-animals/src/species/dog/index.js +0 -144
- package/vendor/procedural-animals/src/species/dog/motion.js +0 -118
- package/vendor/procedural-animals/src/species/dog/regions.js +0 -61
- package/vendor/procedural-animals/src/species/dog/rig.js +0 -129
- package/vendor/procedural-animals/src/species/dog/sculpt.js +0 -246
- package/vendor/procedural-animals/src/species/eagle/coat.js +0 -250
- package/vendor/procedural-animals/src/species/eagle/index.js +0 -76
- package/vendor/procedural-animals/src/species/eagle/joints.js +0 -3
- package/vendor/procedural-animals/src/species/eagle/motion.js +0 -137
- package/vendor/procedural-animals/src/species/eagle/regions.js +0 -57
- package/vendor/procedural-animals/src/species/eagle/rig.js +0 -107
- package/vendor/procedural-animals/src/species/eagle/sculpt.js +0 -137
- package/vendor/procedural-animals/src/species/fish/coat.js +0 -271
- package/vendor/procedural-animals/src/species/fish/index.js +0 -88
- package/vendor/procedural-animals/src/species/fish/motion.js +0 -92
- package/vendor/procedural-animals/src/species/fish/regions.js +0 -27
- package/vendor/procedural-animals/src/species/fish/rig.js +0 -143
- package/vendor/procedural-animals/src/species/fish/sculpt.js +0 -214
- package/vendor/procedural-animals/src/species/fish/variants.js +0 -126
- package/vendor/procedural-animals/src/species/fox/behaviour.js +0 -314
- package/vendor/procedural-animals/src/species/fox/coat.js +0 -444
- package/vendor/procedural-animals/src/species/fox/index.js +0 -120
- package/vendor/procedural-animals/src/species/fox/motion.js +0 -81
- package/vendor/procedural-animals/src/species/fox/regions.js +0 -59
- package/vendor/procedural-animals/src/species/fox/rig.js +0 -91
- package/vendor/procedural-animals/src/species/fox/sculpt.js +0 -202
- package/vendor/procedural-animals/src/species/frog/behaviour.js +0 -590
- package/vendor/procedural-animals/src/species/frog/coat.js +0 -305
- package/vendor/procedural-animals/src/species/frog/index.js +0 -97
- package/vendor/procedural-animals/src/species/frog/motion.js +0 -69
- package/vendor/procedural-animals/src/species/frog/regions.js +0 -46
- package/vendor/procedural-animals/src/species/frog/rig.js +0 -156
- package/vendor/procedural-animals/src/species/frog/sculpt.js +0 -240
- package/vendor/procedural-animals/src/species/goat/behaviour.js +0 -509
- package/vendor/procedural-animals/src/species/goat/coat.js +0 -590
- package/vendor/procedural-animals/src/species/goat/index.js +0 -149
- package/vendor/procedural-animals/src/species/goat/motion.js +0 -95
- package/vendor/procedural-animals/src/species/goat/regions.js +0 -98
- package/vendor/procedural-animals/src/species/goat/rig.js +0 -181
- package/vendor/procedural-animals/src/species/goat/sculpt.js +0 -547
- package/vendor/procedural-animals/src/species/horse/coat.js +0 -361
- package/vendor/procedural-animals/src/species/horse/coatSeam.js +0 -122
- package/vendor/procedural-animals/src/species/horse/index.js +0 -80
- package/vendor/procedural-animals/src/species/horse/motion.js +0 -245
- package/vendor/procedural-animals/src/species/horse/regions.js +0 -60
- package/vendor/procedural-animals/src/species/horse/rig.js +0 -117
- package/vendor/procedural-animals/src/species/horse/sculpt.js +0 -316
- package/vendor/procedural-animals/src/species/horse/seamWeights.js +0 -272
- package/vendor/procedural-animals/src/species/lion/behaviour.js +0 -509
- package/vendor/procedural-animals/src/species/lion/coat.js +0 -1016
- package/vendor/procedural-animals/src/species/lion/index.js +0 -111
- package/vendor/procedural-animals/src/species/lion/motion.js +0 -87
- package/vendor/procedural-animals/src/species/lion/regions.js +0 -106
- package/vendor/procedural-animals/src/species/lion/rig.js +0 -110
- package/vendor/procedural-animals/src/species/lion/sculpt.js +0 -384
- package/vendor/procedural-animals/src/species/lion/whiskers.js +0 -132
- package/vendor/procedural-animals/src/species/pig/behaviour.js +0 -575
- package/vendor/procedural-animals/src/species/pig/coat.js +0 -730
- package/vendor/procedural-animals/src/species/pig/ears.js +0 -242
- package/vendor/procedural-animals/src/species/pig/index.js +0 -161
- package/vendor/procedural-animals/src/species/pig/motion.js +0 -105
- package/vendor/procedural-animals/src/species/pig/regions.js +0 -100
- package/vendor/procedural-animals/src/species/pig/rig.js +0 -152
- package/vendor/procedural-animals/src/species/pig/sculpt.js +0 -382
- package/vendor/procedural-animals/src/species/rabbit/behaviour.js +0 -605
- package/vendor/procedural-animals/src/species/rabbit/coat.js +0 -285
- package/vendor/procedural-animals/src/species/rabbit/index.js +0 -85
- package/vendor/procedural-animals/src/species/rabbit/motion.js +0 -85
- package/vendor/procedural-animals/src/species/rabbit/regions.js +0 -48
- package/vendor/procedural-animals/src/species/rabbit/rig.js +0 -99
- package/vendor/procedural-animals/src/species/rabbit/sculpt.js +0 -148
- package/vendor/procedural-animals/src/species/rat/behaviour.js +0 -539
- package/vendor/procedural-animals/src/species/rat/coat.js +0 -341
- package/vendor/procedural-animals/src/species/rat/index.js +0 -111
- package/vendor/procedural-animals/src/species/rat/motion.js +0 -90
- package/vendor/procedural-animals/src/species/rat/regions.js +0 -92
- package/vendor/procedural-animals/src/species/rat/rig.js +0 -112
- package/vendor/procedural-animals/src/species/rat/sculpt.js +0 -163
- package/vendor/procedural-animals/src/species/rat/whiskers.js +0 -119
- package/vendor/procedural-animals/src/species/shark/coat.js +0 -383
- package/vendor/procedural-animals/src/species/shark/index.js +0 -104
- package/vendor/procedural-animals/src/species/shark/motion.js +0 -69
- package/vendor/procedural-animals/src/species/shark/regions.js +0 -34
- package/vendor/procedural-animals/src/species/shark/rig.js +0 -194
- package/vendor/procedural-animals/src/species/shark/sculpt.js +0 -343
- package/vendor/procedural-animals/src/species/shark/variants.js +0 -105
- package/vendor/procedural-animals/src/species/sheep/behaviour.js +0 -522
- package/vendor/procedural-animals/src/species/sheep/coat.js +0 -529
- package/vendor/procedural-animals/src/species/sheep/index.js +0 -152
- package/vendor/procedural-animals/src/species/sheep/motion.js +0 -86
- package/vendor/procedural-animals/src/species/sheep/neck.js +0 -41
- package/vendor/procedural-animals/src/species/sheep/regions.js +0 -62
- package/vendor/procedural-animals/src/species/sheep/rig.js +0 -163
- package/vendor/procedural-animals/src/species/sheep/sculpt.js +0 -542
- package/vendor/procedural-animals/src/species/snake/coat.js +0 -315
- package/vendor/procedural-animals/src/species/snake/index.js +0 -73
- package/vendor/procedural-animals/src/species/snake/motion.js +0 -51
- package/vendor/procedural-animals/src/species/snake/regions.js +0 -51
- package/vendor/procedural-animals/src/species/snake/rig.js +0 -108
- package/vendor/procedural-animals/src/species/snake/sculpt.js +0 -122
- package/vendor/procedural-animals/src/species/spider/coat.js +0 -279
- package/vendor/procedural-animals/src/species/spider/index.js +0 -78
- package/vendor/procedural-animals/src/species/spider/motion.js +0 -72
- package/vendor/procedural-animals/src/species/spider/regions.js +0 -87
- package/vendor/procedural-animals/src/species/spider/rig.js +0 -118
- package/vendor/procedural-animals/src/species/spider/sculpt.js +0 -182
- package/vendor/procedural-animals/src/species/wolf/behaviour.js +0 -160
- package/vendor/procedural-animals/src/species/wolf/coat.js +0 -749
- package/vendor/procedural-animals/src/species/wolf/index.js +0 -107
- package/vendor/procedural-animals/src/species/wolf/motion.js +0 -80
- package/vendor/procedural-animals/src/species/wolf/regions.js +0 -57
- package/vendor/procedural-animals/src/species/wolf/rig.js +0 -87
- package/vendor/procedural-animals/src/species/wolf/sculpt.js +0 -339
- package/vendor/procedural-animals/src/worker.js +0 -29
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
// The frog's skin: wet, glossy, finely granular (material 7: bumps, clear coat, subsurface), bigger
|
|
2
|
-
// tubercles on the back, smooth belly. Colour: green head / upper lip, olive to brown dorsum with dark
|
|
3
|
-
// mottling grown on the surface, lighter flanks, cream belly, pale or (breeding male bullfrog) yellow
|
|
4
|
-
// throat, legs with dark crossbands, brown tympanum (pale ring and dark centre in males), dark lip
|
|
5
|
-
// line, darker webbing. Common frog: brown / olive with dark blotches, the dark temporal mask behind
|
|
6
|
-
// the eye over the tympanum, pale dorsolateral folds, barred legs, speckled belly.
|
|
7
|
-
// Works in the reference space of rig.js; colours sampled from the reference photos.
|
|
8
|
-
import { HEAD_O } from './rig.js';
|
|
9
|
-
import { tympanum } from './sculpt.js';
|
|
10
|
-
import { SDFModel } from '../../core/sdf/sdf.js';
|
|
11
|
-
import { norm, sub, dot, cross, len, add, mul, smoothstep, clamp, mix, fbm3, rng } from '../../core/math/vec.js';
|
|
12
|
-
import { srgb, mix3, MAT, poissonFeatures, featureDistance } from '../../core/build/coatKit.js';
|
|
13
|
-
|
|
14
|
-
// sRGB palettes
|
|
15
|
-
const PALETTES = {
|
|
16
|
-
// bullfrog, green (the common look: green head, olive back)
|
|
17
|
-
green: {
|
|
18
|
-
head: 0x6a8640, lip: 0x88a452, back: 0x5c6238, flank: 0x80845e, mottle: 0x33351f, belly: 0xe8e2c8,
|
|
19
|
-
throatF: 0xe0dac2, throatM: 0xd6bf3c, leg: 0x6e6e44, band: 0x34321f, tymp: 0x6a5838, web: 0x5a5840, lipline: 0x2a2a18,
|
|
20
|
-
},
|
|
21
|
-
// bullfrog, olive-brown
|
|
22
|
-
olive: {
|
|
23
|
-
head: 0x77764e, lip: 0x8c8c5c, back: 0x6a5c3e, flank: 0x8a7c5a, mottle: 0x3c3020, belly: 0xe4dec6,
|
|
24
|
-
throatF: 0xdcd6be, throatM: 0xcfb844, leg: 0x665640, band: 0x302619, tymp: 0x6b5a3e, web: 0x5a4c3a, lipline: 0x2a2418,
|
|
25
|
-
},
|
|
26
|
-
// bullfrog, pale tan morph
|
|
27
|
-
pale: {
|
|
28
|
-
head: 0x9c9864, lip: 0xb0ac78, back: 0x92845a, flank: 0xa8986e, mottle: 0x5e5236, belly: 0xece6d0,
|
|
29
|
-
throatF: 0xe6e0ca, throatM: 0xd8c460, leg: 0x8c7c56, band: 0x564a30, tymp: 0x7a6846, web: 0x7a6c50, lipline: 0x4a4028,
|
|
30
|
-
},
|
|
31
|
-
// common frog (Rana temporaria): brown / olive / rufous individuals
|
|
32
|
-
temporaria: {
|
|
33
|
-
head: 0x86704e, lip: 0x9c8866, back: 0x7b6546, flank: 0x957e5e, mottle: 0x33251a, belly: 0xe2d6b4,
|
|
34
|
-
throatF: 0xe6e2d6, throatM: 0xc4ccd4, leg: 0x7a6446, band: 0x33251a, tymp: 0x3f2d20, web: 0x6a5642, lipline: 0x2e2218,
|
|
35
|
-
mask: 0x36261b, fold: 0xa48c64, speckle: 0xb07236,
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
const TONGUE = srgb(0xd89a8a), MOUTH = srgb(0xc98a7e);
|
|
39
|
-
|
|
40
|
-
function coatColours(p) {
|
|
41
|
-
const base = PALETTES[p.colour] || PALETTES.green;
|
|
42
|
-
const w = p.coatWarmth || 0, l = p.coatLightness || 0, gr = p.coatGreen || 0;
|
|
43
|
-
const tweak = (h) => { const c = srgb(h); return [c[0] * (1 + 0.12 * w + l - 0.1 * gr), c[1] * (1 + 0.03 * w + l + 0.06 * gr), c[2] * (1 - 0.14 * w + l - 0.12 * gr)]; };
|
|
44
|
-
const C = {};
|
|
45
|
-
for (const [k, v] of Object.entries(base)) C[k] = ['belly', 'throatF', 'throatM'].includes(k) ? srgb(v) : tweak(v);
|
|
46
|
-
return C;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function frogCoat(ctx) {
|
|
50
|
-
const { model, rig, pos, nrm, regionOf, weights, nV, params } = ctx;
|
|
51
|
-
const { BONES } = rig;
|
|
52
|
-
const COL = coatColours(params);
|
|
53
|
-
const male = params.sex === 'male';
|
|
54
|
-
const temporaria = params.variant === 'common-frog';
|
|
55
|
-
const juv = params.age === 'juvenile';
|
|
56
|
-
const { dominant, skinIndex, skinWeight, limbMember } = weights;
|
|
57
|
-
const P = (v) => [pos[v * 3], pos[v * 3 + 1], pos[v * 3 + 2]];
|
|
58
|
-
const N = (v) => [nrm[v * 3], nrm[v * 3 + 1], nrm[v * 3 + 2]];
|
|
59
|
-
const R = rng((params.coatSeed || 1) * 31 + 7);
|
|
60
|
-
|
|
61
|
-
const isLimb = BONES.map((b) => /^(humerus|radius|metacarpus|fpaw|femur|tibia|metatarsus|hpaw)/.test(b.name));
|
|
62
|
-
const byTag = (t) => model.prims.filter((p) => p.tag === t);
|
|
63
|
-
const eyePrims = byTag('eyesocket'), lidPrims = byTag('eyelid');
|
|
64
|
-
const tympPrims = byTag('tympanum'), foldPrims = byTag('stfold'), dlPrims = byTag('dlfold');
|
|
65
|
-
const nostrils = byTag('nostril');
|
|
66
|
-
const jawPrims = model.forPart('jaw');
|
|
67
|
-
const headUpper = model.prims.filter((p) => p.part === 'body' && p.bone === 'head' && !p.carve);
|
|
68
|
-
const webPrims = byTag('web');
|
|
69
|
-
|
|
70
|
-
// per-vertex classification
|
|
71
|
-
// region: 0 trunk, 1 head (upper), 2 jaw (lower jaw part), 3 tongue, 4 throat, 5 eye, 6 limb
|
|
72
|
-
const region = new Uint8Array(nV);
|
|
73
|
-
const legBone = new Int16Array(nV).fill(-1);
|
|
74
|
-
const legness = new Float32Array(nV);
|
|
75
|
-
for (let v = 0; v < nV; v++) {
|
|
76
|
-
const bn = BONES[dominant[v]].name;
|
|
77
|
-
let lb = -1, lw = 0, lsum = 0;
|
|
78
|
-
for (let k = 0; k < 4; k++) {
|
|
79
|
-
const b = skinIndex[v * 4 + k], w = skinWeight[v * 4 + k];
|
|
80
|
-
if (isLimb[b]) { lsum += w; if (w > lw) { lw = w; lb = b; } }
|
|
81
|
-
}
|
|
82
|
-
legBone[v] = lb;
|
|
83
|
-
legness[v] = lb >= 0 ? smoothstep(0.25, 0.75, lsum) : 0;
|
|
84
|
-
void limbMember;
|
|
85
|
-
const rn = ctx.regionNames[regionOf[v]];
|
|
86
|
-
if (rn === 'jaw') region[v] = 2;
|
|
87
|
-
else if (rn === 'tongue') region[v] = 3;
|
|
88
|
-
else if (bn.startsWith('eye')) region[v] = 5;
|
|
89
|
-
else if (bn === 'throat') region[v] = 4;
|
|
90
|
-
else if (bn === 'head' || bn === 'neck2' || bn === 'neck1') region[v] = 1;
|
|
91
|
-
else if (legness[v] > 0.5) region[v] = 6;
|
|
92
|
-
else region[v] = 0;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// ---- dark mottling (spots grown on the surface): large on the back, smaller on the flanks and
|
|
96
|
-
// head, none on the belly; the legs carry crossbands instead
|
|
97
|
-
const spotR = (v) => {
|
|
98
|
-
const n = N(v), p = P(v), r = region[v];
|
|
99
|
-
if (r === 2 || r === 3 || r === 4) return 0;
|
|
100
|
-
if (r === 6 || legness[v] > 0.3) return 0;
|
|
101
|
-
if (n[1] < -0.25) return 0;
|
|
102
|
-
const back = smoothstep(-0.2, 0.6, n[1]);
|
|
103
|
-
let rad = (temporaria ? 0.0034 : 0.0028) * (0.7 + 0.5 * back);
|
|
104
|
-
if (r === 1 || r === 5) rad *= temporaria ? 0.55 : 0.6;
|
|
105
|
-
if (r === 1 && p[2] > HEAD_O[2] + 0.02) rad *= 0.6; // snout: small freckles
|
|
106
|
-
return rad * (params.mottleSize || 1);
|
|
107
|
-
};
|
|
108
|
-
const density = params.mottle ?? 0.7;
|
|
109
|
-
const F = poissonFeatures({ pos, nrm, nV, radius: (v) => (R() < density ? spotR(v) : 0), R, spacing: temporaria ? 1.35 : 1.5, gap: 0.002, cell: 0.012 });
|
|
110
|
-
for (const s of F.spots) { s.el = 1 + 0.8 * R(); s.c = norm([R() - 0.5, (R() - 0.5) * 0.3, 1]); }
|
|
111
|
-
|
|
112
|
-
// leg crossbands: along each limb bone's axis
|
|
113
|
-
const bandPeriod = temporaria ? 0.0105 : 0.0125;
|
|
114
|
-
const bandPhase = BONES.map(() => R());
|
|
115
|
-
|
|
116
|
-
const T = tympanum(params);
|
|
117
|
-
const comb = new Float32Array(nV * 3);
|
|
118
|
-
const tint = new Float32Array(nV * 4);
|
|
119
|
-
const furLen = new Float32Array(nV);
|
|
120
|
-
const markSDF = new Float32Array(nV).fill(1);
|
|
121
|
-
const pattern = new Float32Array(nV).fill(1);
|
|
122
|
-
const patternColor = new Float32Array(nV * 4);
|
|
123
|
-
const surf = new Float32Array(nV * 4);
|
|
124
|
-
|
|
125
|
-
for (let v = 0; v < nV; v++) {
|
|
126
|
-
const p = P(v), n = N(v), r = region[v];
|
|
127
|
-
const h = sub(p, HEAD_O);
|
|
128
|
-
const L = legness[v];
|
|
129
|
-
const side = p[0] >= 0 ? 1 : -1;
|
|
130
|
-
let col, mat = MAT.WET_SKIN, mark = 1, pat = 1, gloss = 0.85, bump = 0.0012;
|
|
131
|
-
let patCol = COL.mottle, patI = 0.9;
|
|
132
|
-
|
|
133
|
-
// comb (bump / clear-coat anisotropy direction): nose -> vent, down the legs
|
|
134
|
-
let d = [0, 0, -1];
|
|
135
|
-
if (legBone[v] >= 0 && L > 0.3) { const b = BONES[legBone[v]]; d = norm(sub(b.tail, b.head)); }
|
|
136
|
-
let t = sub(d, mul(n, dot(d, n)));
|
|
137
|
-
if (len(t) < 1e-4) t = cross(n, [1, 0, 0]);
|
|
138
|
-
t = norm(t);
|
|
139
|
-
comb[v * 3] = t[0]; comb[v * 3 + 1] = t[1]; comb[v * 3 + 2] = t[2];
|
|
140
|
-
|
|
141
|
-
// dorsal / ventral blend (countershading by normal and height)
|
|
142
|
-
const up = n[1];
|
|
143
|
-
const ventral = Math.max(smoothstep(-0.25, -0.6, up) * smoothstep(0.03, 0.015, p[1]), smoothstep(-0.45, -0.85, up));
|
|
144
|
-
if (r === 3) { col = TONGUE; mat = MAT.MOUTH; }
|
|
145
|
-
else if (r === 0 || r === 6 || r === 5 || r === 1 || r === 4 || r === 2) {
|
|
146
|
-
// ---- base: back -> flank -> belly
|
|
147
|
-
col = mix3(COL.flank, COL.back, smoothstep(-0.1, 0.55, up));
|
|
148
|
-
col = mix3(col, COL.belly, ventral);
|
|
149
|
-
bump = mix(0.0009, 0.0017, smoothstep(-0.2, 0.7, up));
|
|
150
|
-
gloss = mix(0.72, 0.9, smoothstep(-0.3, 0.5, up));
|
|
151
|
-
// head: green, brighter on the upper lip; throat pale (female) / yellow (male)
|
|
152
|
-
if (r === 1 || r === 5 || r === 2 || r === 4 || r === 0) {
|
|
153
|
-
const headW = (r === 4 ? 0.4 : 1) * smoothstep(-0.05, -0.022, h[2]);
|
|
154
|
-
let hc = COL.head;
|
|
155
|
-
// upper lip: the band just above the mouth line
|
|
156
|
-
const lipBand = smoothstep(-0.012, -0.018, h[1]) * smoothstep(-0.03, -0.02, h[1]);
|
|
157
|
-
hc = mix3(hc, COL.lip, lipBand * 0.8 + smoothstep(0.02, 0.035, h[2]) * 0.2);
|
|
158
|
-
col = mix3(col, hc, headW * smoothstep(-0.5, 0.3, up));
|
|
159
|
-
bump = mix(0.0008, 0.0011, smoothstep(-0.2, 0.6, up));
|
|
160
|
-
}
|
|
161
|
-
// throat and chin underside
|
|
162
|
-
if (r === 4 || r === 2 || (r === 1 && up < -0.3)) {
|
|
163
|
-
const thr = male ? COL.throatM : COL.throatF;
|
|
164
|
-
const under = r === 4 ? smoothstep(0.2, -0.4, up) : smoothstep(-0.2, -0.6, up);
|
|
165
|
-
col = mix3(col, thr, under);
|
|
166
|
-
bump = mix(bump, 0.0006, under); gloss = mix(gloss, 0.7, under);
|
|
167
|
-
}
|
|
168
|
-
if (r === 0) {
|
|
169
|
-
// the chest and belly are smooth and pale; the flank low down lighter
|
|
170
|
-
bump = mix(bump, 0.0006, ventral);
|
|
171
|
-
}
|
|
172
|
-
// ---- legs: base colour with dark crossbands on the upper (outer) side, pale undersides
|
|
173
|
-
if (L > 0 && legBone[v] >= 0) {
|
|
174
|
-
const b = BONES[legBone[v]];
|
|
175
|
-
const foot = /fpaw|hpaw/.test(b.name), hand = /metacarpus|fpaw/.test(b.name);
|
|
176
|
-
// (the sprawled, folded legs show their outer faces: those count as the upper side)
|
|
177
|
-
const upL = Math.max(up, 0.9 * n[0] * side);
|
|
178
|
-
const outer = smoothstep(-0.3, 0.4, upL) * (1 - (foot ? 0.3 : 0));
|
|
179
|
-
let lc = mix3(COL.belly, COL.leg, smoothstep(-0.8, -0.35, upL));
|
|
180
|
-
if (/femur/.test(b.name)) lc = mix3(lc, mix3(COL.belly, COL.flank, 0.4), smoothstep(-0.2, -0.7, upL) * 0.6);
|
|
181
|
-
if (foot) lc = mix3(COL.web, COL.leg, 0.5);
|
|
182
|
-
if (hand) lc = mix3(lc, COL.belly, 0.25);
|
|
183
|
-
col = mix3(col, lc, L);
|
|
184
|
-
bump = mix(bump, foot ? 0.0006 : 0.0011, L);
|
|
185
|
-
// crossbands across the bone
|
|
186
|
-
if (/femur|tibia|metatarsus|humerus|radius/.test(b.name)) {
|
|
187
|
-
const ax = norm(sub(b.tail, b.head));
|
|
188
|
-
const along = dot(sub(p, b.head), ax);
|
|
189
|
-
const ph = along / bandPeriod + bandPhase[b.index] + 0.25 * (fbm3(p[0] * 300, p[1] * 300, p[2] * 300, 2) - 0.5);
|
|
190
|
-
const f = Math.abs(ph - Math.floor(ph) - 0.5); // 0 at band centre
|
|
191
|
-
const wBand = (temporaria ? 0.2 : 0.17) + 0.05 * (fbm3(p[0] * 120, p[1] * 120, p[2] * 120, 2) - 0.5);
|
|
192
|
-
const bandSD = (f - wBand) * bandPeriod;
|
|
193
|
-
if (outer > 0.25) { pat = Math.min(pat, bandSD + (1 - outer) * 0.002); patCol = COL.band; }
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
// ---- webbing: darker, smooth, translucent look
|
|
197
|
-
if (L > 0.5 && legBone[v] >= 0 && /hpaw/.test(BONES[legBone[v]].name)) {
|
|
198
|
-
let dw = 1e9;
|
|
199
|
-
for (const w of webPrims) dw = Math.min(dw, SDFModel.dist(w, p[0], p[1], p[2]));
|
|
200
|
-
if (dw < 0.0004) { col = mix3(COL.web, COL.leg, 0.2); bump = 0.0005; gloss = 0.75; }
|
|
201
|
-
}
|
|
202
|
-
// ---- tympanum: flat brown disc, pale ring and dark centre spot in males
|
|
203
|
-
if (r === 1 || r === 0) {
|
|
204
|
-
for (const tp of tympPrims) {
|
|
205
|
-
const c = [tp.P[0], tp.P[1], tp.P[2]];
|
|
206
|
-
const dd = len(sub(p, c));
|
|
207
|
-
const rr = T.r;
|
|
208
|
-
if (dd < rr + 0.002) {
|
|
209
|
-
const disc = smoothstep(rr + 0.0012, rr - 0.0004, dd);
|
|
210
|
-
let tc = COL.tymp;
|
|
211
|
-
if (male) tc = mix3(tc, mix3(COL.tymp, COL.flank, 0.6), smoothstep(rr * 0.55, rr * 0.8, dd) * (1 - smoothstep(rr * 0.85, rr, dd)));
|
|
212
|
-
tc = mix3(tc, mix3(COL.tymp, COL.head, 0.35), male ? smoothstep(rr * 0.3, rr * 0.1, dd) : 0);
|
|
213
|
-
col = mix3(col, tc, disc);
|
|
214
|
-
bump = mix(bump, 0.0005, disc); gloss = mix(gloss, 0.95, disc);
|
|
215
|
-
if (Math.abs(dd - rr) < 0.0012) mark = Math.min(mark, Math.abs(dd - rr) - 0.0004 + (male ? 0.0003 : 0));
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
// the supratympanic fold: a little paler ridge (bullfrog: same colour, a fine dark edge below)
|
|
219
|
-
let df = 1e9;
|
|
220
|
-
for (const f of foldPrims) df = Math.min(df, SDFModel.dist(f, p[0], p[1], p[2]));
|
|
221
|
-
if (df < 0.0015) col = mix3(col, mix3(col, COL.lip, 0.4), smoothstep(0.0015, 0.0, df) * 0.5);
|
|
222
|
-
}
|
|
223
|
-
// ---- the lip line: a dark line where the upper and lower jaws meet (mouth corner to snout)
|
|
224
|
-
if (r === 1) {
|
|
225
|
-
const dj = SDFModel.evalList(jawPrims, p[0], p[1], p[2]);
|
|
226
|
-
if (dj < 0.0012) mark = Math.min(mark, dj - 0.0002);
|
|
227
|
-
// (skin just inside the lips shows in the closed mouth's slit from the side: dark lip, the
|
|
228
|
-
// pink mouth lining only deeper in, seen when the mouth gapes)
|
|
229
|
-
if (dj < -0.0022) { col = MOUTH; mat = MAT.MOUTH; } else if (dj < -0.0004) col = COL.lipline;
|
|
230
|
-
} else if (r === 2) {
|
|
231
|
-
const dh = SDFModel.evalList(headUpper, p[0], p[1], p[2]);
|
|
232
|
-
if (dh < -0.0022) { col = MOUTH; mat = MAT.MOUTH; }
|
|
233
|
-
else if (dh < -0.0004) col = COL.lipline;
|
|
234
|
-
else if (dh < 0.0014) mark = Math.min(mark, dh - 0.0006);
|
|
235
|
-
// the lower lip: pale
|
|
236
|
-
col = mat === MAT.MOUTH || col === COL.lipline ? col : mix3(col, COL.belly, smoothstep(-0.3, 0.2, up) * 0.35);
|
|
237
|
-
}
|
|
238
|
-
// ---- eyes: the fleshy lid a little paler at its rim, a dark line under the eye
|
|
239
|
-
if (r === 5 || r === 1) {
|
|
240
|
-
for (const e of eyePrims) {
|
|
241
|
-
const de = SDFModel.dist(e, p[0], p[1], p[2]);
|
|
242
|
-
if (de < 0.0018 && de > -0.003) {
|
|
243
|
-
col = mix3(col, COL.lip, smoothstep(0.0018, 0.0003, de) * 0.35);
|
|
244
|
-
if (Math.abs(de) < 0.0007) mark = Math.min(mark, Math.abs(de) - 0.00035);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
void lidPrims;
|
|
248
|
-
}
|
|
249
|
-
// ---- nostrils: dark
|
|
250
|
-
for (const ns of nostrils) {
|
|
251
|
-
const dn = SDFModel.dist(ns, p[0], p[1], p[2]);
|
|
252
|
-
if (dn < 0.0009) mark = Math.min(mark, dn - 0.0004);
|
|
253
|
-
}
|
|
254
|
-
// ---- common frog: the dark temporal mask (eye -> over the tympanum -> jaw angle), pale
|
|
255
|
-
// dorsolateral folds, chevron on the nape, orange-speckled belly
|
|
256
|
-
if (temporaria) {
|
|
257
|
-
if (r === 1 || r === 5 || r === 0) {
|
|
258
|
-
// mask: a band from behind the eye back and down over the tympanum
|
|
259
|
-
const hx = Math.abs(h[0]);
|
|
260
|
-
const mz = (h[2] + 0.004) / -0.042; // 0 at the eye, 1 behind the tympanum
|
|
261
|
-
if (hx > 0.012 && mz > -0.1 && mz < 1.15) {
|
|
262
|
-
const yc = mix(-0.002, -0.014, clamp(mz, 0, 1));
|
|
263
|
-
const halfH = 0.0065 + 0.003 * Math.sin(Math.PI * clamp(mz, 0, 1));
|
|
264
|
-
const sd = Math.max(Math.abs(h[1] - yc) - halfH, -mz * 0.02, (mz - 1) * 0.02, (0.2 - dot(n, [side, 0.1, 0])) * 0.01);
|
|
265
|
-
if (sd < pat) { pat = sd; patCol = COL.mask; patI = 0.95; }
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
let dl = 1e9;
|
|
269
|
-
for (const f of dlPrims) dl = Math.min(dl, SDFModel.dist(f, p[0], p[1], p[2]));
|
|
270
|
-
if (dl < 0.002) col = mix3(col, COL.fold, smoothstep(0.002, 0.0, dl) * 0.7);
|
|
271
|
-
if (ventral > 0.3 && r === 0) {
|
|
272
|
-
const sp = fbm3(p[0] * 700, p[1] * 700, p[2] * 700, 2);
|
|
273
|
-
col = mix3(col, COL.speckle, smoothstep(0.58, 0.68, sp) * ventral * 0.6);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
// ---- mottling on top
|
|
277
|
-
if (r !== 2 && r !== 4 && legness[v] < 0.6) {
|
|
278
|
-
let [sd] = featureDistance(F, p, n, 1);
|
|
279
|
-
sd += 0.0022 * (fbm3(p[0] * 420, p[1] * 420, p[2] * 420, 3) - 0.5);
|
|
280
|
-
if (sd < pat) { pat = sd; patCol = r === 0 || r === 6 ? COL.mottle : mix3(COL.mottle, COL.head, 0.25); patI = temporaria ? 0.85 : 0.6; }
|
|
281
|
-
}
|
|
282
|
-
// female bullfrog: grey mottled throat
|
|
283
|
-
if (!male && !temporaria && (r === 4 || r === 2) && up < -0.2) {
|
|
284
|
-
const g = fbm3(p[0] * 260, p[1] * 260, p[2] * 260, 3);
|
|
285
|
-
col = mix3(col, mix3(col, [0.25, 0.25, 0.2], 0.5), smoothstep(0.55, 0.65, g) * 0.6);
|
|
286
|
-
}
|
|
287
|
-
} else {
|
|
288
|
-
col = COL.back;
|
|
289
|
-
}
|
|
290
|
-
if (juv) col = mix3(col, mix3(col, COL.head, 0.6), 0.3);
|
|
291
|
-
|
|
292
|
-
// low-frequency colour variation
|
|
293
|
-
const cv = fbm3(p[0] * 60, p[1] * 60, p[2] * 60, 3) - 0.5;
|
|
294
|
-
col = [col[0] * (1 + 0.16 * cv), col[1] * (1 + 0.13 * cv), col[2] * (1 + 0.1 * cv)];
|
|
295
|
-
|
|
296
|
-
tint[v * 4] = col[0]; tint[v * 4 + 1] = col[1]; tint[v * 4 + 2] = col[2]; tint[v * 4 + 3] = mat;
|
|
297
|
-
furLen[v] = 0;
|
|
298
|
-
markSDF[v] = clamp(mark, -0.01, 0.01);
|
|
299
|
-
pattern[v] = clamp(pat, -0.01, 0.01);
|
|
300
|
-
patternColor[v * 4] = patCol[0]; patternColor[v * 4 + 1] = patCol[1]; patternColor[v * 4 + 2] = patCol[2]; patternColor[v * 4 + 3] = mat === MAT.WET_SKIN ? patI : 0;
|
|
301
|
-
surf[v * 4] = gloss; surf[v * 4 + 1] = bump * (params.bumpK || 1); surf[v * 4 + 2] = 0; surf[v * 4 + 3] = 0;
|
|
302
|
-
}
|
|
303
|
-
void add; void mix;
|
|
304
|
-
return { comb, tint, pattern, mark: markSDF, furLen, patternColor, surf, region };
|
|
305
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
// True frogs (Ranidae): the American bullfrog (Lithobates catesbeianus, default) and the common frog
|
|
2
|
-
// (Rana temporaria, variant 'common-frog'). Built on the quadruped engine with its sprawl knob
|
|
3
|
-
// (knees and elbows out), paired hind legs and the hopper tools: the classic sitting frog is the
|
|
4
|
-
// resting stance; it crawls for short moves, hops as its main gait, makes long jumps (hind legs
|
|
5
|
-
// fully extended in flight, forelimbs land first), turns by pivoting, and has frog behaviours
|
|
6
|
-
// (throat pumping, blinking by retracting the eyes, tongue-flick feeding, croaking with the vocal
|
|
7
|
-
// sac, long motionless sits) through species hooks (behaviour.js).
|
|
8
|
-
import { frogRig, HEAD_O } from './rig.js';
|
|
9
|
-
import { sculptFrog, EYE } from './sculpt.js';
|
|
10
|
-
import { frogRegions } from './regions.js';
|
|
11
|
-
import { frogCoat } from './coat.js';
|
|
12
|
-
import { motion } from './motion.js';
|
|
13
|
-
|
|
14
|
-
// Seeded individual.
|
|
15
|
-
// variant: 'bullfrog' (default: green / olive / pale colour morphs), 'bullfrog-pale',
|
|
16
|
-
// 'common-frog' (Rana temporaria: smaller, brown with a dark temporal mask and
|
|
17
|
-
// dorsolateral folds)
|
|
18
|
-
// sex: bullfrog males: tympanum larger than the eye, yellow throat, thicker forearms with a
|
|
19
|
-
// nuptial pad, a little smaller than females; females: tympanum ~ eye, cream throat
|
|
20
|
-
// age: 'adult' | 'juvenile' (a young frog: much smaller, big head and eyes, greener)
|
|
21
|
-
function variation(R, o) {
|
|
22
|
-
const sex = o.sex || (R() < 0.5 ? 'male' : 'female');
|
|
23
|
-
const age = o.age || 'adult';
|
|
24
|
-
const juv = age === 'juvenile';
|
|
25
|
-
const g = () => (R() + R() + R() - 1.5) / 1.5; // ~[-1, 1], peaked
|
|
26
|
-
const u = () => 2 * R() - 1;
|
|
27
|
-
let variant = o.variant || 'bullfrog';
|
|
28
|
-
const temporaria = variant === 'common-frog';
|
|
29
|
-
let colour;
|
|
30
|
-
if (temporaria) colour = 'temporaria';
|
|
31
|
-
else if (variant === 'bullfrog-pale') colour = 'pale';
|
|
32
|
-
else colour = sex === 'male' ? (R() < 0.75 ? 'green' : 'olive') : (R() < 0.45 ? 'green' : 'olive');
|
|
33
|
-
// size: bullfrog SVL 90-152 mm, females larger (reference 140 mm); common frog 60-90 mm
|
|
34
|
-
let size = temporaria ? 0.55 * (1 + 0.08 * g()) * (sex === 'female' ? 1.03 : 0.97) : (sex === 'male' ? 0.92 : 1.0) * (1 + 0.07 * g());
|
|
35
|
-
if (juv) size *= 0.42;
|
|
36
|
-
const male = sex === 'male';
|
|
37
|
-
return {
|
|
38
|
-
sex, age, size, variant, colour,
|
|
39
|
-
// tympanum radius (m at the reference size): males 1.3-1.6x the eye, females ~ the eye
|
|
40
|
-
tympanum: (male ? 0.0102 : 0.0073) * (1 + 0.07 * g()) * (juv ? 0.8 : 1),
|
|
41
|
-
headWidth: (1 + 0.035 * g()) * (juv ? 1.04 : 1),
|
|
42
|
-
plump: (1 + 0.05 * g()) * (sex === 'female' ? 1.03 : 0.98) * (juv ? 0.95 : 1),
|
|
43
|
-
armK: 1 + 0.05 * g(),
|
|
44
|
-
mottle: temporaria ? 0.55 + 0.35 * R() : 0.35 + 0.5 * R(),
|
|
45
|
-
mottleSize: 0.8 + 0.45 * R(),
|
|
46
|
-
minThick: 0.0008,
|
|
47
|
-
warps: [
|
|
48
|
-
{ type: 'legs', k: 1 + 0.03 * g(), top: 0.02 },
|
|
49
|
-
{ type: 'length', k: 1 + 0.03 * g() - (juv ? 0.05 : 0), z0: -0.05, z1: 0.02 },
|
|
50
|
-
{ type: 'scaleAbout', c: HEAD_O, k: (1 + 0.03 * g()) * (juv ? 1.22 : 1) * (temporaria ? 0.96 : 1), r0: 0.02, r1: 0.045 },
|
|
51
|
-
],
|
|
52
|
-
coatWarmth: (temporaria ? 1.2 : 0.8) * u(),
|
|
53
|
-
coatLightness: 0.12 * u(),
|
|
54
|
-
coatGreen: temporaria ? 0.6 * u() : 0.5 * u() + (male ? 0.3 : 0),
|
|
55
|
-
coatSeed: Math.floor(R() * 1e6),
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export default {
|
|
60
|
-
id: 'frog',
|
|
61
|
-
name: 'True frog',
|
|
62
|
-
latin: 'Lithobates catesbeianus / Rana temporaria',
|
|
63
|
-
group: 'others',
|
|
64
|
-
plan: 'quadruped',
|
|
65
|
-
covering: 'skin',
|
|
66
|
-
variants: [
|
|
67
|
-
{ id: 'bullfrog', name: 'American bullfrog', latin: 'Lithobates catesbeianus' },
|
|
68
|
-
{ id: 'bullfrog-pale', name: 'American bullfrog (pale morph)', latin: 'Lithobates catesbeianus' },
|
|
69
|
-
{ id: 'common-frog', name: 'Common frog', latin: 'Rana temporaria' },
|
|
70
|
-
],
|
|
71
|
-
variation,
|
|
72
|
-
rig: (params) => frogRig(params),
|
|
73
|
-
sculpt: (m, rig, params) => sculptFrog(m, rig, params),
|
|
74
|
-
regions: frogRegions,
|
|
75
|
-
coat: frogCoat,
|
|
76
|
-
eyeSpecs: (params) => [1, -1].map((side) => ({ side, spec: EYE, headOrigin: HEAD_O, bone: side > 0 ? 'eyeL' : 'eyeR', look: params.variant === 'common-frog' ? EYE_TEMPORARIA : EYE_BULLFROG })),
|
|
77
|
-
motion,
|
|
78
|
-
render: { markColor: [0.02, 0.018, 0.01] },
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
// Horizontal (bar) pupil in a gold / bronze iris with dark reticulation; no sclera; the translucent
|
|
82
|
-
// lower lid (nictitating membrane) rises to blink (driven by behaviour.js with the eye retraction:
|
|
83
|
-
// automatic mammal / bird blinks are off).
|
|
84
|
-
export const EYE_BULLFROG = {
|
|
85
|
-
pupil: 'bar',
|
|
86
|
-
lids: 'bird',
|
|
87
|
-
blink: false,
|
|
88
|
-
iris: { inner: [0.42, 0.26, 0.05], mid: [0.62, 0.4, 0.09], hi: [0.9, 0.66, 0.22], outer: [0.1, 0.06, 0.015] },
|
|
89
|
-
sclera: { color: [0.05, 0.04, 0.02], visible: false },
|
|
90
|
-
lidColor: [0.2, 0.22, 0.12],
|
|
91
|
-
pupilSize: [0.16, 0.44],
|
|
92
|
-
};
|
|
93
|
-
export const EYE_TEMPORARIA = {
|
|
94
|
-
...EYE_BULLFROG,
|
|
95
|
-
iris: { inner: [0.24, 0.12, 0.03], mid: [0.44, 0.25, 0.06], hi: [0.68, 0.46, 0.16], outer: [0.06, 0.035, 0.015] },
|
|
96
|
-
lidColor: [0.2, 0.15, 0.09],
|
|
97
|
-
};
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
// Frog motion data for the quadruped engine (schema: src/core/motion/quadruped.js).
|
|
2
|
-
// Numbers are for the reference individual (params.size = 1: bullfrog SVL 140 mm, hind limb ~250 mm
|
|
3
|
-
// fully extended); the engine scales them by dynamic similarity for males, juveniles and the smaller
|
|
4
|
-
// common frog.
|
|
5
|
-
//
|
|
6
|
-
// Gaits: a slow crawl-walk for short repositioning moves (diagonal couplets:
|
|
7
|
-
// LH with RF, RH with LF) and the hop, the main gait: both hind feet push off together (HL = HR), the
|
|
8
|
-
// body flies low, the forefeet catch it one just after the other, then the hind feet swing forward
|
|
9
|
-
// and land folded beside the body. Hop speed rises with hop frequency and length. Long jumps, single
|
|
10
|
-
// hops, turns on the spot and the frog behaviours are actions in behaviour.js.
|
|
11
|
-
// Offsets [FL, FR, HL, HR] relative to hind touchdown.
|
|
12
|
-
import { hooks } from './behaviour.js';
|
|
13
|
-
import { SPRAWL } from './rig.js';
|
|
14
|
-
|
|
15
|
-
const G = (name, v, f, D, off, o) => ({ name, v, f, D, off, ...o });
|
|
16
|
-
|
|
17
|
-
export const motion = {
|
|
18
|
-
maxSpeed: 1.6,
|
|
19
|
-
stride: { gallop: 0 }, // (a hopper's bound is not a gallop: no gallop forequarter drop or reach)
|
|
20
|
-
accel: [2.5, 4],
|
|
21
|
-
decel: 5,
|
|
22
|
-
turnRate: 2.2,
|
|
23
|
-
latAccelMax: 5,
|
|
24
|
-
gears: { crawl: 0.06, hop: 0.6 },
|
|
25
|
-
gallopBlend: [0.4, 1.2],
|
|
26
|
-
flexBlend: [0.2, 0.8],
|
|
27
|
-
reachDuty: 1,
|
|
28
|
-
hooks,
|
|
29
|
-
gaits: [
|
|
30
|
-
G('crawl', 0.0, 0.8, 0.8, [0.55, 0.05, 0.0, 0.5], { liftF: 0.008, liftH: 0.01, bobF: 0.001, bobH: 0.0015, flex: 0.02, lat: 0.04, fold: 0.15, heel: 12, tail: 0, drop: 0 }),
|
|
31
|
-
G('crawl', 0.12, 1.2, 0.72, [0.55, 0.05, 0.0, 0.5], { liftF: 0.01, liftH: 0.012, bobF: 0.0015, bobH: 0.002, flex: 0.03, lat: 0.05, fold: 0.15, heel: 16, tail: 0, drop: 0 }),
|
|
32
|
-
G('hop', 0.3, 1.4, 0.34, [0.5, 0.53, 0.0, 0.0], { liftF: 0.012, liftH: 0.02, bobF: 0.01, bobH: 0.012, flex: 0.08, lat: 0, fold: 0.2, heel: 30, tail: 0, drop: -0.004 }),
|
|
33
|
-
G('hop', 0.8, 1.8, 0.28, [0.48, 0.51, 0.0, 0.0], { liftF: 0.016, liftH: 0.026, bobF: 0.016, bobH: 0.018, flex: 0.12, lat: 0, fold: 0.2, heel: 40, tail: 0, drop: -0.006 }),
|
|
34
|
-
G('hop', 1.6, 2.1, 0.22, [0.46, 0.49, 0.0, 0.0], { liftF: 0.02, liftH: 0.03, bobF: 0.02, bobH: 0.022, flex: 0.14, lat: 0, fold: 0.2, heel: 45, tail: 0, drop: -0.008 }),
|
|
35
|
-
],
|
|
36
|
-
feet: {
|
|
37
|
-
// flat hands, fingers forward and in
|
|
38
|
-
front: { type: 'plantigrade', contact: 0.45, curl: 12, flex: 4, heelStrike: 0, toeOut: 0, lead: 0.3, liftBehind: 0.5, retract: 0.4 },
|
|
39
|
-
// the long foot flat on the ground; the tarsus laid flat at rest and in postures (plantRest), the
|
|
40
|
-
// heel rising in motion; toes fanned out in the sculpt
|
|
41
|
-
hind: { type: 'plantigrade', zfold: true, swingFlat: 0.7, contact: 0.35, curl: 20, flex: 0, heelStrike: 0, toeOut: 0, lead: 0.25, liftBehind: 0.38, retract: 0.4 },
|
|
42
|
-
},
|
|
43
|
-
stance: { width: 1, gallopWidth: 1, sprawl: SPRAWL, crouch: 0, scuff: [10, 20, 0] },
|
|
44
|
-
body: {
|
|
45
|
-
// sections of the sitting bind sculpt (the half width includes the folded thighs)
|
|
46
|
-
chest: { y: 0.04, hh: 0.025, hw: 0.03 },
|
|
47
|
-
pelvis: { y: 0.03, hh: 0.023, hw: 0.048 },
|
|
48
|
-
mid: { y: 0.032, hh: 0.024, hw: 0.039 },
|
|
49
|
-
rump: { z: -0.05, y: 0.026, hh: 0.016, hw: 0.032 },
|
|
50
|
-
back: 0.02,
|
|
51
|
-
},
|
|
52
|
-
head: {
|
|
53
|
-
// no neck: the head moves only a few degrees relative to the trunk
|
|
54
|
-
carriage: [[0, 0, 0, 0], [0.5, -0.002, 0.002, 0.04], [1.6, -0.004, 0.004, 0.08]],
|
|
55
|
-
stab: [[0, 0], [0.5, 0.05], [1.6, 0.1]],
|
|
56
|
-
neckBend: 10, neckPivot: 0.5, yaw: 0.14, pitchUp: 0.12, pitchDown: 0.15,
|
|
57
|
-
},
|
|
58
|
-
tail: { radius: [0.01, 0.01] },
|
|
59
|
-
breath: { rate: 0.22, amp: 0.018, pant: false, heatSpeed: 99 },
|
|
60
|
-
actions: {
|
|
61
|
-
attack: { style: 'bite-lunge' },
|
|
62
|
-
eat: { style: 'tear' },
|
|
63
|
-
jump: { height: 0.35, distance: 1.1 },
|
|
64
|
-
idle: { shift: 0.12, restep: false },
|
|
65
|
-
sit: {},
|
|
66
|
-
lie: {},
|
|
67
|
-
sleep: { style: 'curl' },
|
|
68
|
-
},
|
|
69
|
-
};
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
// Meshing plan: body at 0.72 mm (hero), the head (with the throat and the front of the shoulders)
|
|
2
|
-
// at 0.5 mm, overlapping across a cut behind the skull and cross-faded, eyelid patches at 0.22 mm,
|
|
3
|
-
// and the lower jaw and the tongue as their own rigid surfaces.
|
|
4
|
-
import { frogJoints } from './rig.js';
|
|
5
|
-
import { EYE } from './sculpt.js';
|
|
6
|
-
import { HEAD_O } from './rig.js';
|
|
7
|
-
import { eyeFrameOf } from '../../core/sdf/eyeSocket.js';
|
|
8
|
-
import { smoothstep } from '../../core/math/vec.js';
|
|
9
|
-
|
|
10
|
-
const J0 = frogJoints();
|
|
11
|
-
// head region: in front of a plane behind the tympana and above the forelimbs
|
|
12
|
-
export const HEAD_CUT = { z: 0.0125, y: 0.027, band: 0.0016 };
|
|
13
|
-
export const headS = (x, y, z) => Math.min(z - HEAD_CUT.z + 0.1 * (y - 0.05), y - HEAD_CUT.y);
|
|
14
|
-
|
|
15
|
-
export const EYE_PATCH = { R: 0.0098, B: 0.0014, h: 0.0003, centres: [1, -1].map((s) => eyeFrameOf(EYE, HEAD_O, s).c) };
|
|
16
|
-
export function eyePatchWeight(x, y, z) {
|
|
17
|
-
let dmin = 1e9;
|
|
18
|
-
for (const c of EYE_PATCH.centres) dmin = Math.min(dmin, Math.hypot(x - c[0], y - c[1], z - c[2]));
|
|
19
|
-
return 1 - smoothstep(EYE_PATCH.R - EYE_PATCH.B, EYE_PATCH.R + EYE_PATCH.B, dmin);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function frogRegions(rig, params, Q) {
|
|
23
|
-
const B = HEAD_CUT.band, r = Q.res;
|
|
24
|
-
const patches = Q.eyePatches ? EYE_PATCH.centres.map((c) => ({ c, R: EYE_PATCH.R, B: EYE_PATCH.B, h: EYE_PATCH.h * Math.max(1, r) })) : [];
|
|
25
|
-
const tb = J0.tongueBase, tt = J0.tongueTip;
|
|
26
|
-
return {
|
|
27
|
-
jobs: [
|
|
28
|
-
[{ name: 'body', part: 'body', bmin: [-0.115, -0.004, -0.085], bmax: [0.115, 0.075, 0.07], h: 0.0009 * r, F: 4, clip: (x, y, z) => headS(x, y, z) < B }],
|
|
29
|
-
[
|
|
30
|
-
{ name: 'head', part: 'body', bmin: [-0.042, 0.02, 0.0], bmax: [0.042, 0.078, 0.095], h: 0.00068 * r, F: 6, clip: (x, y, z) => headS(x, y, z) > -B, patches },
|
|
31
|
-
{ name: 'jaw', part: 'jaw', bmin: [-0.036, 0.027, 0.018], bmax: [0.036, 0.05, 0.094], h: 0.00095 * r, F: 6, rigidBone: 'jaw' },
|
|
32
|
-
{ name: 'tongue', part: 'tongue', bmin: [-0.012, 0.034, tt[2] - 0.012], bmax: [0.012, 0.052, tb[2] + 0.006], h: 0.0011 * r, F: 4, rigidBone: 'tongue' },
|
|
33
|
-
],
|
|
34
|
-
],
|
|
35
|
-
fade(x, y, z, name, patch) {
|
|
36
|
-
const s = headS(x, y, z);
|
|
37
|
-
if (name === 'body') return 1 - smoothstep(-B, B, s);
|
|
38
|
-
if (name === 'head') {
|
|
39
|
-
let f = smoothstep(-B, B, s);
|
|
40
|
-
if (patches.length) { const ew = eyePatchWeight(x, y, z); f *= patch ? ew : 1 - ew; }
|
|
41
|
-
return f;
|
|
42
|
-
}
|
|
43
|
-
return 1;
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
}
|