@bitefoundry/retrieviewer 0.0.3 → 0.0.5

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.
Files changed (263) hide show
  1. package/ASSET-PROVENANCE.md +11 -0
  2. package/ASSETS-LICENSE.md +2 -1
  3. package/ATTRIBUTION.md +6 -1
  4. package/COMFORT-ART.md +95 -0
  5. package/DESKTOP-PLATFORMS.md +6 -1
  6. package/INSTALLING.md +4 -0
  7. package/PLUGIN.md +13 -10
  8. package/PREREQUISITES.md +95 -0
  9. package/PUPPY-MEMORY.md +102 -1
  10. package/README.ko.md +116 -0
  11. package/README.md +121 -59
  12. package/RELEASING.md +33 -13
  13. package/THIRD-PARTY-NOTICES.md +5 -3
  14. package/braille.mjs +35 -9
  15. package/examples/live.mjs +2 -2
  16. package/integrations/linux-overlay/overlay.py +8 -2
  17. package/integrations/macos-overlay/overlay.jxa +9 -7
  18. package/integrations/opencode/runtime.mjs +4 -4
  19. package/integrations/opencode/tui.tsx +1 -1
  20. package/integrations/windows-overlay/Overlay.cs +7 -6
  21. package/integrations/windows-overlay/desktop.mjs +2 -1
  22. package/integrations/windows-overlay/protocol.mjs +13 -7
  23. package/integrations/windows-overlay/worker.mjs +1 -1
  24. package/package.json +34 -13
  25. package/puppy-comfort-sprites.mjs +33 -0
  26. package/puppy-companion-comfort-q5.bin.gz +0 -0
  27. package/puppy-companion-comfort.json +140 -0
  28. package/puppy-companion-life.mjs +58 -18
  29. package/puppy-companion-objects.mjs +12 -0
  30. package/puppy-companion-sprites.mjs +4 -2
  31. package/puppy-frame-predictive.mjs +15 -9
  32. package/puppy-frame-store.mjs +2 -2
  33. package/puppy-paper-actions.mjs +4 -2
  34. package/puppy-paper-behaviors.mjs +1 -1
  35. package/puppy-paper-contact.mjs +4 -2
  36. package/puppy-paper-seat.mjs +4 -2
  37. package/puppy-paper-world.mjs +14 -0
  38. package/puppy-paper.mjs +79 -21
  39. package/retrieviewer-cli.mjs +8 -6
  40. package/retrieviewer-plugin.d.mts +1 -1
  41. package/retrieviewer-plugin.mjs +1 -1
  42. package/retrieviewer.d.mts +12 -4
  43. package/retrieviewer.mjs +20 -14
  44. package/locomotion-core.mjs +0 -21
  45. package/locomotion-puppy.animal +0 -0
  46. package/vendor/procedural-animals/package.json +0 -40
  47. package/vendor/procedural-animals/src/animal.js +0 -146
  48. package/vendor/procedural-animals/src/bake.js +0 -51
  49. package/vendor/procedural-animals/src/build.js +0 -81
  50. package/vendor/procedural-animals/src/core/build/coatKit.js +0 -121
  51. package/vendor/procedural-animals/src/core/build/featherCards.js +0 -189
  52. package/vendor/procedural-animals/src/core/build/finEdges.js +0 -85
  53. package/vendor/procedural-animals/src/core/build/furSlope.js +0 -115
  54. package/vendor/procedural-animals/src/core/build/mesh.js +0 -67
  55. package/vendor/procedural-animals/src/core/build/pipeline.js +0 -272
  56. package/vendor/procedural-animals/src/core/build/seams.js +0 -183
  57. package/vendor/procedural-animals/src/core/build/warp.js +0 -112
  58. package/vendor/procedural-animals/src/core/build/weights.js +0 -393
  59. package/vendor/procedural-animals/src/core/math/vec.js +0 -81
  60. package/vendor/procedural-animals/src/core/motion/actions.js +0 -800
  61. package/vendor/procedural-animals/src/core/motion/bird.js +0 -3063
  62. package/vendor/procedural-animals/src/core/motion/birdActions.js +0 -1059
  63. package/vendor/procedural-animals/src/core/motion/common.js +0 -158
  64. package/vendor/procedural-animals/src/core/motion/index.js +0 -22
  65. package/vendor/procedural-animals/src/core/motion/quadruped.js +0 -2875
  66. package/vendor/procedural-animals/src/core/motion/snake.js +0 -1594
  67. package/vendor/procedural-animals/src/core/motion/spider.js +0 -1810
  68. package/vendor/procedural-animals/src/core/motion/swimmer.js +0 -1047
  69. package/vendor/procedural-animals/src/core/motion/swimmerActions.js +0 -613
  70. package/vendor/procedural-animals/src/core/render/animalObject.js +0 -262
  71. package/vendor/procedural-animals/src/core/render/coatMaterial.js +0 -1301
  72. package/vendor/procedural-animals/src/core/render/dqs.js +0 -159
  73. package/vendor/procedural-animals/src/core/render/eyes.js +0 -676
  74. package/vendor/procedural-animals/src/core/render/membranes.js +0 -77
  75. package/vendor/procedural-animals/src/core/render/skeleton.js +0 -41
  76. package/vendor/procedural-animals/src/core/rig/bird.js +0 -327
  77. package/vendor/procedural-animals/src/core/rig/quadruped.js +0 -76
  78. package/vendor/procedural-animals/src/core/rig/rig.js +0 -79
  79. package/vendor/procedural-animals/src/core/rig/snake.js +0 -76
  80. package/vendor/procedural-animals/src/core/rig/spider.js +0 -110
  81. package/vendor/procedural-animals/src/core/rig/swimmer.js +0 -181
  82. package/vendor/procedural-animals/src/core/sdf/eyeSocket.js +0 -53
  83. package/vendor/procedural-animals/src/core/sdf/mesher.js +0 -238
  84. package/vendor/procedural-animals/src/core/sdf/sdf.js +0 -263
  85. package/vendor/procedural-animals/src/index.d.ts +0 -98
  86. package/vendor/procedural-animals/src/index.js +0 -29
  87. package/vendor/procedural-animals/src/registry.js +0 -48
  88. package/vendor/procedural-animals/src/species/bear/behaviour.js +0 -463
  89. package/vendor/procedural-animals/src/species/bear/claws.js +0 -147
  90. package/vendor/procedural-animals/src/species/bear/coat.js +0 -726
  91. package/vendor/procedural-animals/src/species/bear/index.js +0 -139
  92. package/vendor/procedural-animals/src/species/bear/motion.js +0 -112
  93. package/vendor/procedural-animals/src/species/bear/regions.js +0 -78
  94. package/vendor/procedural-animals/src/species/bear/rig.js +0 -112
  95. package/vendor/procedural-animals/src/species/bear/sculpt.js +0 -272
  96. package/vendor/procedural-animals/src/species/boar/behaviour.js +0 -335
  97. package/vendor/procedural-animals/src/species/boar/coat.js +0 -372
  98. package/vendor/procedural-animals/src/species/boar/index.js +0 -110
  99. package/vendor/procedural-animals/src/species/boar/motion.js +0 -85
  100. package/vendor/procedural-animals/src/species/boar/regions.js +0 -88
  101. package/vendor/procedural-animals/src/species/boar/rig.js +0 -111
  102. package/vendor/procedural-animals/src/species/boar/sculpt.js +0 -285
  103. package/vendor/procedural-animals/src/species/cat/behaviour.js +0 -559
  104. package/vendor/procedural-animals/src/species/cat/coat.js +0 -841
  105. package/vendor/procedural-animals/src/species/cat/index.js +0 -211
  106. package/vendor/procedural-animals/src/species/cat/motion.js +0 -101
  107. package/vendor/procedural-animals/src/species/cat/regions.js +0 -82
  108. package/vendor/procedural-animals/src/species/cat/rig.js +0 -100
  109. package/vendor/procedural-animals/src/species/cat/sculpt.js +0 -266
  110. package/vendor/procedural-animals/src/species/cat/whiskers.js +0 -110
  111. package/vendor/procedural-animals/src/species/cheetah/coat.js +0 -427
  112. package/vendor/procedural-animals/src/species/cheetah/index.js +0 -51
  113. package/vendor/procedural-animals/src/species/cheetah/joints.js +0 -3
  114. package/vendor/procedural-animals/src/species/cheetah/motion.js +0 -77
  115. package/vendor/procedural-animals/src/species/cheetah/regions.js +0 -95
  116. package/vendor/procedural-animals/src/species/cheetah/rig.js +0 -66
  117. package/vendor/procedural-animals/src/species/cheetah/sculpt.js +0 -158
  118. package/vendor/procedural-animals/src/species/chicken/coat.js +0 -313
  119. package/vendor/procedural-animals/src/species/chicken/coverts.js +0 -320
  120. package/vendor/procedural-animals/src/species/chicken/index.js +0 -110
  121. package/vendor/procedural-animals/src/species/chicken/motion.js +0 -177
  122. package/vendor/procedural-animals/src/species/chicken/regions.js +0 -66
  123. package/vendor/procedural-animals/src/species/chicken/rig.js +0 -144
  124. package/vendor/procedural-animals/src/species/chicken/sculpt.js +0 -389
  125. package/vendor/procedural-animals/src/species/chicken/wingLook.js +0 -66
  126. package/vendor/procedural-animals/src/species/chicken/wingStack.js +0 -124
  127. package/vendor/procedural-animals/src/species/cow/behaviour.js +0 -521
  128. package/vendor/procedural-animals/src/species/cow/coat.js +0 -465
  129. package/vendor/procedural-animals/src/species/cow/index.js +0 -118
  130. package/vendor/procedural-animals/src/species/cow/motion.js +0 -81
  131. package/vendor/procedural-animals/src/species/cow/regions.js +0 -98
  132. package/vendor/procedural-animals/src/species/cow/rig.js +0 -116
  133. package/vendor/procedural-animals/src/species/cow/sculpt.js +0 -339
  134. package/vendor/procedural-animals/src/species/crow/coat.js +0 -145
  135. package/vendor/procedural-animals/src/species/crow/index.js +0 -70
  136. package/vendor/procedural-animals/src/species/crow/joints.js +0 -3
  137. package/vendor/procedural-animals/src/species/crow/motion.js +0 -101
  138. package/vendor/procedural-animals/src/species/crow/regions.js +0 -50
  139. package/vendor/procedural-animals/src/species/crow/rig.js +0 -83
  140. package/vendor/procedural-animals/src/species/crow/sculpt.js +0 -118
  141. package/vendor/procedural-animals/src/species/deer/behaviour.js +0 -513
  142. package/vendor/procedural-animals/src/species/deer/coat.js +0 -391
  143. package/vendor/procedural-animals/src/species/deer/index.js +0 -106
  144. package/vendor/procedural-animals/src/species/deer/motion.js +0 -97
  145. package/vendor/procedural-animals/src/species/deer/regions.js +0 -60
  146. package/vendor/procedural-animals/src/species/deer/rig.js +0 -124
  147. package/vendor/procedural-animals/src/species/deer/sculpt.js +0 -297
  148. package/vendor/procedural-animals/src/species/dog/behaviour.js +0 -521
  149. package/vendor/procedural-animals/src/species/dog/coat.js +0 -495
  150. package/vendor/procedural-animals/src/species/dog/index.js +0 -144
  151. package/vendor/procedural-animals/src/species/dog/motion.js +0 -118
  152. package/vendor/procedural-animals/src/species/dog/regions.js +0 -61
  153. package/vendor/procedural-animals/src/species/dog/rig.js +0 -129
  154. package/vendor/procedural-animals/src/species/dog/sculpt.js +0 -246
  155. package/vendor/procedural-animals/src/species/eagle/coat.js +0 -250
  156. package/vendor/procedural-animals/src/species/eagle/index.js +0 -76
  157. package/vendor/procedural-animals/src/species/eagle/joints.js +0 -3
  158. package/vendor/procedural-animals/src/species/eagle/motion.js +0 -137
  159. package/vendor/procedural-animals/src/species/eagle/regions.js +0 -57
  160. package/vendor/procedural-animals/src/species/eagle/rig.js +0 -107
  161. package/vendor/procedural-animals/src/species/eagle/sculpt.js +0 -137
  162. package/vendor/procedural-animals/src/species/fish/coat.js +0 -271
  163. package/vendor/procedural-animals/src/species/fish/index.js +0 -88
  164. package/vendor/procedural-animals/src/species/fish/motion.js +0 -92
  165. package/vendor/procedural-animals/src/species/fish/regions.js +0 -27
  166. package/vendor/procedural-animals/src/species/fish/rig.js +0 -143
  167. package/vendor/procedural-animals/src/species/fish/sculpt.js +0 -214
  168. package/vendor/procedural-animals/src/species/fish/variants.js +0 -126
  169. package/vendor/procedural-animals/src/species/fox/behaviour.js +0 -314
  170. package/vendor/procedural-animals/src/species/fox/coat.js +0 -444
  171. package/vendor/procedural-animals/src/species/fox/index.js +0 -120
  172. package/vendor/procedural-animals/src/species/fox/motion.js +0 -81
  173. package/vendor/procedural-animals/src/species/fox/regions.js +0 -59
  174. package/vendor/procedural-animals/src/species/fox/rig.js +0 -91
  175. package/vendor/procedural-animals/src/species/fox/sculpt.js +0 -202
  176. package/vendor/procedural-animals/src/species/frog/behaviour.js +0 -590
  177. package/vendor/procedural-animals/src/species/frog/coat.js +0 -305
  178. package/vendor/procedural-animals/src/species/frog/index.js +0 -97
  179. package/vendor/procedural-animals/src/species/frog/motion.js +0 -69
  180. package/vendor/procedural-animals/src/species/frog/regions.js +0 -46
  181. package/vendor/procedural-animals/src/species/frog/rig.js +0 -156
  182. package/vendor/procedural-animals/src/species/frog/sculpt.js +0 -240
  183. package/vendor/procedural-animals/src/species/goat/behaviour.js +0 -509
  184. package/vendor/procedural-animals/src/species/goat/coat.js +0 -590
  185. package/vendor/procedural-animals/src/species/goat/index.js +0 -149
  186. package/vendor/procedural-animals/src/species/goat/motion.js +0 -95
  187. package/vendor/procedural-animals/src/species/goat/regions.js +0 -98
  188. package/vendor/procedural-animals/src/species/goat/rig.js +0 -181
  189. package/vendor/procedural-animals/src/species/goat/sculpt.js +0 -547
  190. package/vendor/procedural-animals/src/species/horse/coat.js +0 -361
  191. package/vendor/procedural-animals/src/species/horse/coatSeam.js +0 -122
  192. package/vendor/procedural-animals/src/species/horse/index.js +0 -80
  193. package/vendor/procedural-animals/src/species/horse/motion.js +0 -245
  194. package/vendor/procedural-animals/src/species/horse/regions.js +0 -60
  195. package/vendor/procedural-animals/src/species/horse/rig.js +0 -117
  196. package/vendor/procedural-animals/src/species/horse/sculpt.js +0 -316
  197. package/vendor/procedural-animals/src/species/horse/seamWeights.js +0 -272
  198. package/vendor/procedural-animals/src/species/lion/behaviour.js +0 -509
  199. package/vendor/procedural-animals/src/species/lion/coat.js +0 -1016
  200. package/vendor/procedural-animals/src/species/lion/index.js +0 -111
  201. package/vendor/procedural-animals/src/species/lion/motion.js +0 -87
  202. package/vendor/procedural-animals/src/species/lion/regions.js +0 -106
  203. package/vendor/procedural-animals/src/species/lion/rig.js +0 -110
  204. package/vendor/procedural-animals/src/species/lion/sculpt.js +0 -384
  205. package/vendor/procedural-animals/src/species/lion/whiskers.js +0 -132
  206. package/vendor/procedural-animals/src/species/pig/behaviour.js +0 -575
  207. package/vendor/procedural-animals/src/species/pig/coat.js +0 -730
  208. package/vendor/procedural-animals/src/species/pig/ears.js +0 -242
  209. package/vendor/procedural-animals/src/species/pig/index.js +0 -161
  210. package/vendor/procedural-animals/src/species/pig/motion.js +0 -105
  211. package/vendor/procedural-animals/src/species/pig/regions.js +0 -100
  212. package/vendor/procedural-animals/src/species/pig/rig.js +0 -152
  213. package/vendor/procedural-animals/src/species/pig/sculpt.js +0 -382
  214. package/vendor/procedural-animals/src/species/rabbit/behaviour.js +0 -605
  215. package/vendor/procedural-animals/src/species/rabbit/coat.js +0 -285
  216. package/vendor/procedural-animals/src/species/rabbit/index.js +0 -85
  217. package/vendor/procedural-animals/src/species/rabbit/motion.js +0 -85
  218. package/vendor/procedural-animals/src/species/rabbit/regions.js +0 -48
  219. package/vendor/procedural-animals/src/species/rabbit/rig.js +0 -99
  220. package/vendor/procedural-animals/src/species/rabbit/sculpt.js +0 -148
  221. package/vendor/procedural-animals/src/species/rat/behaviour.js +0 -539
  222. package/vendor/procedural-animals/src/species/rat/coat.js +0 -341
  223. package/vendor/procedural-animals/src/species/rat/index.js +0 -111
  224. package/vendor/procedural-animals/src/species/rat/motion.js +0 -90
  225. package/vendor/procedural-animals/src/species/rat/regions.js +0 -92
  226. package/vendor/procedural-animals/src/species/rat/rig.js +0 -112
  227. package/vendor/procedural-animals/src/species/rat/sculpt.js +0 -163
  228. package/vendor/procedural-animals/src/species/rat/whiskers.js +0 -119
  229. package/vendor/procedural-animals/src/species/shark/coat.js +0 -383
  230. package/vendor/procedural-animals/src/species/shark/index.js +0 -104
  231. package/vendor/procedural-animals/src/species/shark/motion.js +0 -69
  232. package/vendor/procedural-animals/src/species/shark/regions.js +0 -34
  233. package/vendor/procedural-animals/src/species/shark/rig.js +0 -194
  234. package/vendor/procedural-animals/src/species/shark/sculpt.js +0 -343
  235. package/vendor/procedural-animals/src/species/shark/variants.js +0 -105
  236. package/vendor/procedural-animals/src/species/sheep/behaviour.js +0 -522
  237. package/vendor/procedural-animals/src/species/sheep/coat.js +0 -529
  238. package/vendor/procedural-animals/src/species/sheep/index.js +0 -152
  239. package/vendor/procedural-animals/src/species/sheep/motion.js +0 -86
  240. package/vendor/procedural-animals/src/species/sheep/neck.js +0 -41
  241. package/vendor/procedural-animals/src/species/sheep/regions.js +0 -62
  242. package/vendor/procedural-animals/src/species/sheep/rig.js +0 -163
  243. package/vendor/procedural-animals/src/species/sheep/sculpt.js +0 -542
  244. package/vendor/procedural-animals/src/species/snake/coat.js +0 -315
  245. package/vendor/procedural-animals/src/species/snake/index.js +0 -73
  246. package/vendor/procedural-animals/src/species/snake/motion.js +0 -51
  247. package/vendor/procedural-animals/src/species/snake/regions.js +0 -51
  248. package/vendor/procedural-animals/src/species/snake/rig.js +0 -108
  249. package/vendor/procedural-animals/src/species/snake/sculpt.js +0 -122
  250. package/vendor/procedural-animals/src/species/spider/coat.js +0 -279
  251. package/vendor/procedural-animals/src/species/spider/index.js +0 -78
  252. package/vendor/procedural-animals/src/species/spider/motion.js +0 -72
  253. package/vendor/procedural-animals/src/species/spider/regions.js +0 -87
  254. package/vendor/procedural-animals/src/species/spider/rig.js +0 -118
  255. package/vendor/procedural-animals/src/species/spider/sculpt.js +0 -182
  256. package/vendor/procedural-animals/src/species/wolf/behaviour.js +0 -160
  257. package/vendor/procedural-animals/src/species/wolf/coat.js +0 -749
  258. package/vendor/procedural-animals/src/species/wolf/index.js +0 -107
  259. package/vendor/procedural-animals/src/species/wolf/motion.js +0 -80
  260. package/vendor/procedural-animals/src/species/wolf/regions.js +0 -57
  261. package/vendor/procedural-animals/src/species/wolf/rig.js +0 -87
  262. package/vendor/procedural-animals/src/species/wolf/sculpt.js +0 -339
  263. package/vendor/procedural-animals/src/worker.js +0 -29
@@ -1,314 +0,0 @@
1
- // Red fox behaviour layer for the quadruped engine (species.motion.hooks, see core/motion/actions.js).
2
- //
3
- // update(P, dt, layer) every frame over the action layer: the listening pose (freeze, head cocked
4
- // from side to side, ears forward and turning), the brush as a counterweight
5
- // (raised against a nose-down dive, level / low when trotting: the carriage
6
- // table), sitting upright with the brush wrapped round the forefeet, the curled
7
- // sleep with the brush drawn over the nose, the tail tucked when hit, ears
8
- // laid back when dying; idle variants (listen, listen with a forepaw raised)
9
- // pose(engine, dt) after the engine's solve: the ears swivel independently toward "sounds"
10
- // (each on its own, fast), locked forward on the prey while listening
11
- // actions attack / pounce: the mousing pounce (listen with the head cocked, crouch,
12
- // a high arcing leap, the body turning nose-down in the air, forelegs
13
- // together, brush up as a counterweight, landing forepaws first to pin the
14
- // prey with the muzzle plunged into the ground); running: the built-in
15
- // bite-lunge. listen: freeze and listen (head tilts, ear swivels, sometimes a
16
- // forepaw raised). hit: the built-in flinch, tail clamped low.
17
- //
18
- // Distances are fox metres at the reference size x cfg.s; posture offsets that the engine multiplies
19
- // by cfg.k (fwd, side, headRaise, neckReach) are divided by cfg.unit.
20
- import * as THREE from 'three';
21
- import { clamp, lerp, smooth, TAU, tv, tqa } from '../../core/motion/common.js';
22
- import { mx, mxLeg, ONESHOTS, POSTURES, mouthGroundTarget } from '../../core/motion/actions.js';
23
-
24
- const _q = new THREE.Quaternion(), _s = new THREE.Vector3(1, 1, 1);
25
- const _p = new THREE.Vector3(), _a = new THREE.Vector3();
26
- const sm = (w) => w * w * (3 - 2 * w);
27
- const U = (e) => e.cfg.unit; // engine units -> fox metres
28
- const busy = (L) => L.postures.some((p) => p.target > 0) || L.oneshots.some((a) => !a.stopping);
29
- const posture = (L, name) => L.postures.find((p) => p.name === name && p.w > 0);
30
-
31
- function B(e) {
32
- if (!e._fox) {
33
- e._fox = {
34
- ear: [{ sw: 0, v: 0, target: 0, tNext: 0.5 }, { sw: 0, v: 0, target: 0, tNext: 1.3 }],
35
- listen: 0, tiltPh: e.rand() * TAU, idleT: 6 + e.rand() * 6,
36
- };
37
- }
38
- return e._fox;
39
- }
40
-
41
- // head cocked from side to side while listening (~0.8 s per side, held, then swung over)
42
- function tiltOf(t, ph) {
43
- const x = (t * 0.55 + ph) % 2;
44
- const side = x < 1 ? 1 : -1;
45
- const u = x % 1;
46
- // swing over in the first 30 % of each half cycle, then hold
47
- const k = smooth(0, 0.3, u);
48
- return lerp(-side, side, k);
49
- }
50
-
51
- // the listening pose (shared by the idle 'listen' action and the pounce's lead-in): head low and
52
- // forward over the ground ahead, cocked to one side then the other, ears pricked forward
53
- function applyListen(P, w, t, e, b, ph) {
54
- if (w <= 0) return;
55
- const tilt = tiltOf(t, ph);
56
- mx(P, 'lookW', 0, w);
57
- mx(P, 'headPitch', 0.4, w);
58
- mx(P, 'headRaise', -0.008 / U(e), w); mx(P, 'neckReach', 0.014 / U(e), w);
59
- P.headRoll += 0.42 * tilt * w;
60
- P.headYaw += 0.1 * tilt * w;
61
- mx(P, 'earFlat', -0.25, w); mx(P, 'earTwitch', 0, w);
62
- mx(P, 'tailIdle', 0.2, w);
63
- b.listen = Math.max(b.listen, w);
64
- }
65
-
66
- // ------------------------------------------------------------------------------------------------
67
- function update(P, dt, L) {
68
- const e = L.engine, b = B(e), cfg = e.cfg;
69
- b.listen = 0;
70
- for (const a of L.oneshots) {
71
- const w = sm(a.w);
72
- if (w <= 0) continue;
73
- if (a.name === 'hit') {
74
- // flinch: the brush clamped low, ears flat (core), body drops (core)
75
- const k = w * (1 - smooth(0.45, 0.75, a.t) * 0.6);
76
- mx(P, 'tailLift', -0.7, k); mx(P, 'tailStiff', 1.5, k); mx(P, 'tailIdle', 0, k);
77
- }
78
- }
79
- // dying / dead: ears folded back, head rolled onto its cheek
80
- for (const p of L.postures) {
81
- if (p.name === 'death') { const w = sm(clamp(p.w, 0, 1)) * smooth(0.3, 1.0, p.t); mx(P, 'earFlat', 1.1, w); mx(P, 'earTwitch', 0, w); mx(P, 'headRoll', p.side * 0.8, w); P.headPos.y += 0.035 * cfg.s * w; }
82
- }
83
- // sitting upright on the haunches: the brush wrapped round the forefeet, head up
84
- const sit = posture(L, 'sit');
85
- if (sit) {
86
- const w = sm(clamp(sit.w, 0, 1)) * smooth(0.4, 1.4, sit.t);
87
- mx(P, 'tailSide', sit.side * 1.5, w); mx(P, 'tailCurl', sit.side * 2.2, w); mx(P, 'tailStiff', 0.8, w);
88
- mx(P, 'headRaise', 0.012 / U(e), w);
89
- }
90
- // curled asleep: a tight ring, the brush drawn round over the nose and forepaws
91
- const sleep = posture(L, 'sleep');
92
- if (sleep && sleep.tune.style !== 'lateral') {
93
- const c = sm(clamp(sleep.w, 0, 1)) * smooth(1.2, 3.2, sleep.t);
94
- mx(P, 'bend', sleep.side * 1.8, c); mx(P, 'tailSide', sleep.side * 3.6, c); mx(P, 'tailCurl', 0, c); mx(P, 'tailStiff', 0.6, c);
95
- mx(P, 'headYaw', sleep.side * 1.5, c); mx(P, 'flex', 0.25, c);
96
- P.headPos.y += 0.032 * cfg.s * c;
97
- // the head tucked back along the flank toward the hind feet, nose into the brush
98
- P.headPos.addScaledVector(e.fr.F, -0.1 * cfg.s * c).addScaledVector(e.fr.Lf, sleep.side * 0.05 * cfg.s * c);
99
- }
100
-
101
- // idle variants: stop and listen (sometimes with a forepaw raised)
102
- if (e.idleVariants !== false && L.idle.w > 0.98 && !busy(L) && !e.input.look && !e.input.follow) {
103
- b.idleT -= dt;
104
- if (b.idleT <= 0) {
105
- b.idleT = 8 + e.rand() * 10;
106
- L.play('listen', { paw: e.rand() < 0.45 });
107
- }
108
- } else if (busy(L)) b.idleT = Math.max(b.idleT, 4);
109
- }
110
-
111
- // ------------------------------------------------------------------------------------------------
112
- // pose: independent ear swivels ("radar" ears), both locked forward while listening
113
- function pose(e, dt) {
114
- const b = B(e), P = e.P, cfg = e.cfg;
115
- if (e.lod >= 2 || !cfg.hasEars) return;
116
- const awake = 1 - P.eyelid * 0.8;
117
- const still = 1 - smooth(0.5, 3, e.speed / cfg.sq);
118
- const lis = b.listen;
119
- for (let k = 0; k < 2; k++) {
120
- const E = b.ear[k], s = k === 0 ? 1 : -1;
121
- const bone = k === 0 ? e.bone.earL : e.bone.earR;
122
- if (!bone) continue;
123
- E.tNext -= dt * (1 + 1.5 * lis);
124
- if (E.tNext <= 0) {
125
- E.tNext = 0.8 + e.rand() * 3;
126
- // a new "sound": often sideways or back, sometimes straight ahead; listening: small scans
127
- // around straight ahead (the ears pinpoint the prey)
128
- E.target = lis > 0.3 ? (e.rand() - 0.5) * 0.5 : e.rand() < 0.35 ? 0 : (e.rand() - 0.2) * 1.4 * s;
129
- }
130
- const want = E.target * still * awake * (1 - Math.max(0, P.earFlat) * (1 - lis)) * (1 - smooth(0.25, 0.7, Math.abs(P.roll))) * (1 - clamp(P.headW, 0, 1));
131
- const om = 17; // fast, critically damped swivel
132
- E.v += (om * om * (want - E.sw) - 2 * om * E.v) * dt;
133
- E.sw += E.v * dt;
134
- if (Math.abs(E.sw) < 1e-4) continue;
135
- const base = _p.setFromMatrixPosition(bone.matrixWorld);
136
- _q.setFromRotationMatrix(bone.matrixWorld);
137
- _a.set(0, 1, 0).applyQuaternion(_q);
138
- _q.premultiply(tqa(_a, E.sw));
139
- bone.matrixWorld.compose(base, _q, _s);
140
- }
141
- }
142
-
143
- // ------------------------------------------------------------------------------------------------
144
- // listen: freeze, head low and cocked from side to side, ears pricked; optionally a forepaw raised
145
- const listen = {
146
- kind: 'oneshot', fade: 0.35,
147
- start(inst, L) {
148
- inst.dur = inst.opts.loop ? Infinity : (inst.opts.duration ?? 3.2 + L.engine.rand() * 1.6);
149
- inst.ph = L.engine.rand() * 2;
150
- inst.paw = inst.opts.paw ? (L.engine.rand() < 0.5 ? 0 : 1) : -1;
151
- },
152
- update(inst) { return inst.t >= inst.dur; },
153
- apply(P, w, inst, L) {
154
- const e = L.engine, b = B(e), s = e.cfg.s;
155
- applyListen(P, w, inst.t, e, b, inst.ph);
156
- mx(P, 'speedScale', 0.3, w);
157
- if (inst.paw >= 0) {
158
- // one forepaw held up, the carpus folded (alert)
159
- const k = w * smooth(0.3, 0.8, inst.t) * (1 - smooth(inst.dur - 0.7, inst.dur - 0.2, inst.t));
160
- const i = inst.paw, leg = e.legs[i];
161
- const tp = tv().copy(leg.plant).addScaledVector(e.forward(e.heading, tv()), -0.012 * s);
162
- tp.y += 0.07 * s;
163
- P.legs[i].target.lerp(tp, k / Math.max(1e-3, P.legs[i].reach + k));
164
- mxLeg(P, i, 'reach', 1, k);
165
- mx(P, 'side', -(i === 0 ? 1 : -1) * 0.004 / U(e), k);
166
- }
167
- },
168
- };
169
-
170
- // ------------------------------------------------------------------------------------------------
171
- // attack: the mousing pounce. Stands and listens with the head cocked (~1.4 s), crouches, launches a
172
- // high arcing leap (the engine's jump mechanics with its push-off; ~0.55 m high, ~1.2 m long at the
173
- // reference size, or to opts.target), the body turning nose-down on the way up and diving steeply,
174
- // forelegs held together and pointing down at the prey, the brush raised behind as a counterweight;
175
- // lands forepaws first together to pin the prey, the muzzle plunging into the ground. Running: the
176
- // built-in bite-lunge.
177
- const LISTEN = 1.4; // s of listening before the leap
178
- const POUNCE = { height: 0.55, distance: 1.2, land: [0.55, 0.3] };
179
- function makePounce(forcePounce) {
180
- return {
181
- kind: 'oneshot', fade: 0.15, needsStand: true, airborne: true,
182
- start(inst, L) {
183
- const e = L.engine;
184
- inst.run = forcePounce ? 0 : smooth(1.2, 3, e.speed / e.cfg.sq);
185
- inst.delay = inst.run > 0.5 ? 0 : (inst.opts.listen ?? LISTEN) * e.cfg.sq;
186
- inst.ph = e.rand() * 2;
187
- inst.dur = Infinity;
188
- if (inst.run > 0.5) {
189
- inst.lunge = { ...inst, tune: { style: 'bite-lunge' } };
190
- ONESHOTS.attack.start(inst.lunge, L);
191
- }
192
- },
193
- update(inst, dt, L) {
194
- if (inst.lunge) { inst.lunge.t = inst.t; return ONESHOTS.attack.update.call(ONESHOTS.attack, inst.lunge, dt, L); }
195
- if (inst.t < inst.delay) return false;
196
- if (!inst.leap) {
197
- inst.leap = { ...inst, t: 0, tune: POUNCE, opts: { target: inst.opts.target } };
198
- ONESHOTS.jump.start(inst.leap, L);
199
- }
200
- const J = inst.leap;
201
- J.t = inst.t - inst.delay;
202
- ONESHOTS.jump.update(J, dt, L);
203
- inst.phase = J.phase;
204
- if (inst.landT !== undefined && inst.t - inst.landT > 1.25) return true;
205
- return false;
206
- },
207
- onLand(inst, L) {
208
- if (inst.lunge) return ONESHOTS.attack.onLand.call(ONESHOTS.attack, inst.lunge, L);
209
- if (!inst.leap) return;
210
- ONESHOTS.jump.onLand(inst.leap, L);
211
- inst.landT = inst.t;
212
- const e = L.engine;
213
- // (no speed cut here: a sudden drop of the speed jumps the head carriage; the engine decelerates)
214
- const p = e.legs[0].contact.clone().lerp(e.legs[1].contact, 0.5);
215
- const dir = inst.opts.target ? inst.opts.target.clone().sub(e.pos).setY(0).normalize() : e.forward(e.heading, new THREE.Vector3());
216
- e.emit('attackHit', { position: p, direction: dir, style: 'pounce' });
217
- },
218
- apply(P, w, inst, L) {
219
- const e = L.engine, t = inst.t, cfg = e.cfg, s = cfg.s;
220
- if (inst.lunge) return ONESHOTS.attack.apply(P, w, inst.lunge, L);
221
- const b = B(e);
222
- // listening: frozen, head cocked, ears pricked on the prey
223
- const lw = w * (1 - smooth(inst.delay - 0.35, inst.delay - 0.05, t));
224
- applyListen(P, lw, t, e, b, inst.ph);
225
- if (inst.opts.target) { P.look = inst.opts.target; mx(P, 'lookW', 0.5, w * (1 - lw)); }
226
- // the gathering crouch on the hind legs just before the leap
227
- const c = smooth(inst.delay - 0.45, inst.delay - 0.1, t) * (inst.leap && inst.leap.phase !== 'crouch' ? 0 : 1) * w;
228
- mx(P, 'dropH', 0.3, c); mx(P, 'dropF', 0.12, c); mx(P, 'headPitch', 0.35, c);
229
- mx(P, 'earFlat', -0.2, w * (inst.landT === undefined ? 1 : 1 - smooth(0.4, 0.9, t - inst.landT)));
230
- const J = inst.leap;
231
- if (!J) return;
232
- ONESHOTS.jump.apply(P, w, J, L);
233
- if (J.phase === 'air') {
234
- const T = (2 * J.vy) / 9.81, x = clamp((J.t - J.tAir) / T, 0, 1);
235
- // body: nose up leaving the ground, turning over to a steep nose-down dive
236
- const k0 = smooth(0, 0.1, J.t - J.tAir) * w;
237
- // (kept for the landing, which fades them out: the touchdown comes whenever the forepaws
238
- // meet the ground, not at a fixed point of the flight)
239
- const A = inst.air || (inst.air = {});
240
- A.pitch = lerp(0.35, -0.8, smooth(0.1, 0.7, x)); A.flex = lerp(-0.15, 0.25, smooth(0.2, 0.8, x));
241
- A.tail = lerp(0.2, 1.1, smooth(0.2, 0.85, x)); A.head = lerp(-0.1, 0.35, smooth(0.2, 0.75, x)) - 0.9 * A.pitch; // (the head is levelled in space: follow the body into the dive)
242
- A.ext = smooth(0.1, 0.5, x) * (1 - smooth(0.8, 1, x)); A.jaw = 0.3 * smooth(0.6, 0.95, x); A.x = x;
243
- airPose(P, A, k0);
244
- mx(P, 'jawOmega', 25, w);
245
- // forelegs: reach forward together, then down at the prey
246
- foreReach(P, e, smooth(0.05, 0.4, x) * k0, x);
247
- } else if (J.phase === 'land') {
248
- // forepaws pin together; the muzzle plunges into the ground between them, then comes up
249
- const x = J.t - J.tLand;
250
- if (inst.air) airPose(P, inst.air, w * (1 - smooth(0, 0.3, x)));
251
- const pin = (1 - smooth(0.45, 0.8, x)) * w;
252
- foreReach(P, e, pin, 1);
253
- const plunge = smooth(0.03, 0.42, x) * (1 - smooth(0.7, 1.15, x)) * w;
254
- // (the spot is fixed at the landing: the forepaws may still settle)
255
- // (from the shoulders, not the leg plants: a paw still finishing its swing keeps the take-off spot)
256
- if (!inst.plungeAt) {
257
- const g = new THREE.Vector3().copy(e.fr.shC).addScaledVector(e.forward(e.heading, tv()), 0.1 * s);
258
- const pseudo = { cfg, fr: e.fr, heading: e.heading, legs: [{ plant: g }, { plant: g }] };
259
- inst.plungeAt = mouthGroundTarget(pseudo, new THREE.Vector3(), 1.1, (px, pz) => e.terrainH(px, pz), 0.55);
260
- inst.plungeAt.y += 0.012 * s; // (the open lower jaw clears the ground)
261
- }
262
- if (plunge > 0) {
263
- const hp = inst.plungeAt;
264
- P.headPos.lerp(hp, plunge / Math.max(1e-3, P.headW + plunge));
265
- mx(P, 'headW', 1, plunge); mx(P, 'headReach', 1, plunge); mx(P, 'headPitch', 1.1, plunge);
266
- mx(P, 'headOmega', 2.2, plunge);
267
- }
268
- mx(P, 'jaw', 0.3 * (1 - smooth(0.1, 0.3, x)) + 0.05 * smooth(0.35, 0.6, x) * (1 - smooth(0.9, 1.1, x)), w); mx(P, 'jawOmega', 30, w);
269
- mx(P, 'dropF', 0.45, pin); mx(P, 'dropH', 0.15, pin);
270
- mx(P, 'tailLift', 0.5, (1 - smooth(0.2, 0.8, x)) * w);
271
- }
272
- },
273
- };
274
- }
275
- const attack = makePounce(false);
276
- const pounce = makePounce(true);
277
-
278
- // forelegs held together: reaching ahead of the shoulders, pointing down at the prey through the
279
- // dive (x: 0..1 of the flight; 1 = on the ground, the same target the landing pins)
280
- function foreReach(P, e, k, x) {
281
- if (k <= 0) return;
282
- const s = e.cfg.s, fwd = e.forward(e.heading, tv()), lat = e.left(e.heading, tv());
283
- for (let i = 0; i < 2; i++) {
284
- const Ld = e.legs[i].def;
285
- const tp = tv().copy(e.fr.shC).addScaledVector(fwd, lerp(0.14, 0.1, x) * s).addScaledVector(lat, Ld.s * Ld.cx * 0.5);
286
- const g = e.terrainH(tp.x, tp.z);
287
- tp.y = Math.max(g + 0.004 * s, lerp(e.fr.shC.y - 0.12 * s, g + 0.004 * s, smooth(0.45, 1, x)));
288
- P.legs[i].target.lerp(tp, k / Math.max(1e-3, P.legs[i].reach + k));
289
- mxLeg(P, i, 'reach', 1, k);
290
- }
291
- }
292
-
293
- // the flight pose: body nose up leaving the ground turning over into a steep nose-down dive, arched
294
- // over the top; the brush raised behind as a counterweight; head in line with the dive, mouth opening;
295
- // hind legs trailing, stretched out behind
296
- function airPose(P, A, k) {
297
- if (k <= 0) return;
298
- mx(P, 'pitch', A.pitch, k); mx(P, 'flex', A.flex, k);
299
- mx(P, 'tailLift', A.tail, k); mx(P, 'tailStiff', 1.4, k); mx(P, 'tailIdle', 0, k);
300
- mx(P, 'headPitch', A.head, k); mx(P, 'jaw', A.jaw, k);
301
- for (let i = 2; i < 4; i++) P.legs[i].extend = lerp(P.legs[i].extend, 1, A.ext * k);
302
- }
303
-
304
- // hit: the built-in flinch; the brush is clamped low in update()
305
- const hit = { ...ONESHOTS.hit, kind: 'oneshot', fade: 0.12 };
306
-
307
- export const foxHooks = {
308
- update, pose,
309
- actions: {
310
- attack, pounce, listen, hit,
311
- // (a light animal gets up from its side quickly)
312
- death: { ...POSTURES.death, kind: 'posture', fadeOut: 1.2 },
313
- },
314
- };