@aura3d/engine 4.1.2 → 4.2.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.
Files changed (268) hide show
  1. package/README.md +52 -730
  2. package/dist/audio/synth/SynthCueBank.d.ts.map +1 -1
  3. package/dist/audio/synth/SynthCueBank.js +11 -2
  4. package/dist/audio/synth/SynthCueBank.js.map +1 -1
  5. package/dist/audio/synth/types.d.ts +4 -0
  6. package/dist/audio/synth/types.d.ts.map +1 -1
  7. package/dist/aura3d-cli/cli.d.ts.map +1 -1
  8. package/dist/aura3d-cli/cli.js +49 -17
  9. package/dist/aura3d-cli/cli.js.map +1 -1
  10. package/dist/aura3d-cli/commands/evidence/index.d.ts +3 -0
  11. package/dist/aura3d-cli/commands/evidence/index.d.ts.map +1 -0
  12. package/dist/aura3d-cli/commands/evidence/index.js +12 -0
  13. package/dist/aura3d-cli/commands/evidence/index.js.map +1 -0
  14. package/dist/aura3d-cli/commands/evidence/judge.d.ts +18 -0
  15. package/dist/aura3d-cli/commands/evidence/judge.d.ts.map +1 -0
  16. package/dist/aura3d-cli/commands/evidence/judge.js +194 -0
  17. package/dist/aura3d-cli/commands/evidence/judge.js.map +1 -0
  18. package/dist/aura3d-cli/commands/evidence/judgeLib.d.ts +84 -0
  19. package/dist/aura3d-cli/commands/evidence/judgeLib.d.ts.map +1 -0
  20. package/dist/aura3d-cli/commands/evidence/judgeLib.js +178 -0
  21. package/dist/aura3d-cli/commands/evidence/judgeLib.js.map +1 -0
  22. package/dist/aura3d-cli/commands/registry.d.ts +1 -0
  23. package/dist/aura3d-cli/commands/registry.d.ts.map +1 -1
  24. package/dist/aura3d-cli/commands/registry.js +1 -0
  25. package/dist/aura3d-cli/commands/registry.js.map +1 -1
  26. package/dist/aura3d-cli/look/capture.d.ts +15 -7
  27. package/dist/aura3d-cli/look/capture.d.ts.map +1 -1
  28. package/dist/aura3d-cli/look/capture.js +85 -13
  29. package/dist/aura3d-cli/look/capture.js.map +1 -1
  30. package/dist/aura3d-cli/pull-bridge/adapters.d.ts +9 -1
  31. package/dist/aura3d-cli/pull-bridge/adapters.d.ts.map +1 -1
  32. package/dist/aura3d-cli/pull-bridge/adapters.js +30 -7
  33. package/dist/aura3d-cli/pull-bridge/adapters.js.map +1 -1
  34. package/dist/aura3d-cli/pull-bridge/search.d.ts +5 -0
  35. package/dist/aura3d-cli/pull-bridge/search.d.ts.map +1 -1
  36. package/dist/aura3d-cli/pull-bridge/search.js +7 -1
  37. package/dist/aura3d-cli/pull-bridge/search.js.map +1 -1
  38. package/dist/aura3d-cli/pull-bridge.js +1 -1
  39. package/dist/aura3d-cli/pull-bridge.js.map +1 -1
  40. package/dist/aura3d-cli/resolve-ladder.d.ts +123 -0
  41. package/dist/aura3d-cli/resolve-ladder.d.ts.map +1 -0
  42. package/dist/aura3d-cli/resolve-ladder.js +410 -0
  43. package/dist/aura3d-cli/resolve-ladder.js.map +1 -0
  44. package/dist/create-aura3d/index.js +1 -1
  45. package/dist/debug/index.d.ts +2 -2
  46. package/dist/debug/index.d.ts.map +1 -1
  47. package/dist/debug/index.js +1 -1
  48. package/dist/debug/index.js.map +1 -1
  49. package/dist/debug/safety/frameBoundary.d.ts +33 -0
  50. package/dist/debug/safety/frameBoundary.d.ts.map +1 -0
  51. package/dist/debug/safety/frameBoundary.js +40 -0
  52. package/dist/debug/safety/frameBoundary.js.map +1 -0
  53. package/dist/debug/safety/index.d.ts +1 -0
  54. package/dist/debug/safety/index.d.ts.map +1 -1
  55. package/dist/debug/safety/index.js +1 -0
  56. package/dist/debug/safety/index.js.map +1 -1
  57. package/dist/engine/agent-api/app/actorBoneMatrixLookup.d.ts +22 -0
  58. package/dist/engine/agent-api/app/actorBoneMatrixLookup.d.ts.map +1 -0
  59. package/dist/engine/agent-api/app/actorBoneMatrixLookup.js +24 -0
  60. package/dist/engine/agent-api/app/actorBoneMatrixLookup.js.map +1 -0
  61. package/dist/engine/agent-api/app/canvas.d.ts +16 -0
  62. package/dist/engine/agent-api/app/canvas.d.ts.map +1 -1
  63. package/dist/engine/agent-api/app/canvas.js +15 -0
  64. package/dist/engine/agent-api/app/canvas.js.map +1 -1
  65. package/dist/engine/agent-api/app/createAuraApp.d.ts.map +1 -1
  66. package/dist/engine/agent-api/app/createAuraApp.js +21 -3
  67. package/dist/engine/agent-api/app/createAuraApp.js.map +1 -1
  68. package/dist/engine/agent-api/app/frameLoop.d.ts.map +1 -1
  69. package/dist/engine/agent-api/app/frameLoop.js +21 -3
  70. package/dist/engine/agent-api/app/frameLoop.js.map +1 -1
  71. package/dist/engine/agent-api/app/mountFailure.d.ts +6 -0
  72. package/dist/engine/agent-api/app/mountFailure.d.ts.map +1 -0
  73. package/dist/engine/agent-api/app/mountFailure.js +9 -0
  74. package/dist/engine/agent-api/app/mountFailure.js.map +1 -0
  75. package/dist/engine/agent-api/app/parentFit.d.ts +35 -0
  76. package/dist/engine/agent-api/app/parentFit.d.ts.map +1 -0
  77. package/dist/engine/agent-api/app/parentFit.js +36 -0
  78. package/dist/engine/agent-api/app/parentFit.js.map +1 -0
  79. package/dist/engine/agent-api/compiler/customMaterial.js +3 -2
  80. package/dist/engine/agent-api/compiler/customMaterial.js.map +1 -1
  81. package/dist/engine/agent-api/compiler/geometry.d.ts +13 -0
  82. package/dist/engine/agent-api/compiler/geometry.d.ts.map +1 -1
  83. package/dist/engine/agent-api/compiler/geometry.js +30 -3
  84. package/dist/engine/agent-api/compiler/geometry.js.map +1 -1
  85. package/dist/engine/agent-api/compiler/primitives.d.ts +1 -2
  86. package/dist/engine/agent-api/compiler/primitives.d.ts.map +1 -1
  87. package/dist/engine/agent-api/compiler/primitives.js +21 -4
  88. package/dist/engine/agent-api/compiler/primitives.js.map +1 -1
  89. package/dist/engine/agent-api/index.d.ts +4 -0
  90. package/dist/engine/agent-api/index.d.ts.map +1 -1
  91. package/dist/engine/agent-api/index.js +1 -0
  92. package/dist/engine/agent-api/index.js.map +1 -1
  93. package/dist/engine/agent-api/nodes/batched.d.ts +10 -0
  94. package/dist/engine/agent-api/nodes/batched.d.ts.map +1 -1
  95. package/dist/engine/agent-api/nodes/batched.js +7 -5
  96. package/dist/engine/agent-api/nodes/batched.js.map +1 -1
  97. package/dist/engine/agent-api/nodes/builder.d.ts +13 -0
  98. package/dist/engine/agent-api/nodes/builder.d.ts.map +1 -1
  99. package/dist/engine/agent-api/nodes/builder.js +7 -3
  100. package/dist/engine/agent-api/nodes/builder.js.map +1 -1
  101. package/dist/engine/agent-api/nodes/cameras.d.ts +7 -0
  102. package/dist/engine/agent-api/nodes/cameras.d.ts.map +1 -1
  103. package/dist/engine/agent-api/nodes/cameras.js +7 -0
  104. package/dist/engine/agent-api/nodes/cameras.js.map +1 -1
  105. package/dist/engine/agent-api/nodes/chaseCamera.d.ts +122 -0
  106. package/dist/engine/agent-api/nodes/chaseCamera.d.ts.map +1 -0
  107. package/dist/engine/agent-api/nodes/chaseCamera.js +130 -0
  108. package/dist/engine/agent-api/nodes/chaseCamera.js.map +1 -0
  109. package/dist/engine/agent-api/nodes/effects.composite.d.ts +1 -0
  110. package/dist/engine/agent-api/nodes/effects.composite.d.ts.map +1 -1
  111. package/dist/engine/agent-api/nodes/effects.composite.js +2 -0
  112. package/dist/engine/agent-api/nodes/effects.composite.js.map +1 -1
  113. package/dist/engine/agent-api/nodes/effects.toon.d.ts +26 -0
  114. package/dist/engine/agent-api/nodes/effects.toon.d.ts.map +1 -0
  115. package/dist/engine/agent-api/nodes/effects.toon.js +70 -0
  116. package/dist/engine/agent-api/nodes/effects.toon.js.map +1 -0
  117. package/dist/engine/agent-api/nodes/instancedMesh.d.ts +10 -0
  118. package/dist/engine/agent-api/nodes/instancedMesh.d.ts.map +1 -1
  119. package/dist/engine/agent-api/nodes/instancedMesh.js +7 -5
  120. package/dist/engine/agent-api/nodes/instancedMesh.js.map +1 -1
  121. package/dist/engine/agent-api/nodes/prefabs/index.d.ts +3 -0
  122. package/dist/engine/agent-api/nodes/prefabs/index.d.ts.map +1 -1
  123. package/dist/engine/agent-api/nodes/prefabs/index.js +3 -0
  124. package/dist/engine/agent-api/nodes/prefabs/index.js.map +1 -1
  125. package/dist/engine/agent-api/nodes/prefabs/objectiveMarker.d.ts +32 -0
  126. package/dist/engine/agent-api/nodes/prefabs/objectiveMarker.d.ts.map +1 -0
  127. package/dist/engine/agent-api/nodes/prefabs/objectiveMarker.js +77 -0
  128. package/dist/engine/agent-api/nodes/prefabs/objectiveMarker.js.map +1 -0
  129. package/dist/engine/lanes/prd06.d.ts.map +1 -1
  130. package/dist/engine/lanes/prd06.js +1 -16
  131. package/dist/engine/lanes/prd06.js.map +1 -1
  132. package/dist/engine/production-runtime/actor/ModelTextureShare.d.ts +1 -1
  133. package/dist/engine/production-runtime/actor/ModelTextureShare.d.ts.map +1 -1
  134. package/dist/engine/production-runtime/actor/ModelTextureShare.js +1 -1
  135. package/dist/engine/production-runtime/actor/ModelTextureShare.js.map +1 -1
  136. package/dist/engine/public/index.d.ts +52 -67
  137. package/dist/engine/public/index.d.ts.map +1 -1
  138. package/dist/engine/public/index.js +59 -56
  139. package/dist/engine/public/index.js.map +1 -1
  140. package/dist/engine/qa/countedRng.d.ts +2 -0
  141. package/dist/engine/qa/countedRng.d.ts.map +1 -1
  142. package/dist/engine/qa/countedRng.js +3 -0
  143. package/dist/engine/qa/countedRng.js.map +1 -1
  144. package/dist/engine/qa/fixedStepLoop.d.ts +4 -0
  145. package/dist/engine/qa/fixedStepLoop.d.ts.map +1 -1
  146. package/dist/engine/qa/fixedStepLoop.js +6 -0
  147. package/dist/engine/qa/fixedStepLoop.js.map +1 -1
  148. package/dist/engine/qa/hooks.js +1 -1
  149. package/dist/engine/qa/hooks.js.map +1 -1
  150. package/dist/game/evidence/beacon.d.ts +16 -6
  151. package/dist/game/evidence/beacon.d.ts.map +1 -1
  152. package/dist/game/evidence/beacon.js +32 -14
  153. package/dist/game/evidence/beacon.js.map +1 -1
  154. package/dist/game/evidence/textureStatus.d.ts +24 -0
  155. package/dist/game/evidence/textureStatus.d.ts.map +1 -0
  156. package/dist/game/evidence/textureStatus.js +27 -0
  157. package/dist/game/evidence/textureStatus.js.map +1 -0
  158. package/dist/game/hud/canvasMinimap.d.ts +60 -0
  159. package/dist/game/hud/canvasMinimap.d.ts.map +1 -0
  160. package/dist/game/hud/canvasMinimap.js +62 -0
  161. package/dist/game/hud/canvasMinimap.js.map +1 -0
  162. package/dist/game/hud/compass.d.ts +16 -0
  163. package/dist/game/hud/compass.d.ts.map +1 -0
  164. package/dist/game/hud/compass.js +15 -0
  165. package/dist/game/hud/compass.js.map +1 -0
  166. package/dist/game/index.d.ts +9 -0
  167. package/dist/game/index.d.ts.map +1 -1
  168. package/dist/game/index.js +5 -0
  169. package/dist/game/index.js.map +1 -1
  170. package/dist/game/motion/boneAttach.d.ts +42 -0
  171. package/dist/game/motion/boneAttach.d.ts.map +1 -0
  172. package/dist/game/motion/boneAttach.js +166 -0
  173. package/dist/game/motion/boneAttach.js.map +1 -0
  174. package/dist/game/motion/cameraClear.d.ts +35 -0
  175. package/dist/game/motion/cameraClear.d.ts.map +1 -0
  176. package/dist/game/motion/cameraClear.js +64 -0
  177. package/dist/game/motion/cameraClear.js.map +1 -0
  178. package/dist/game/motion/doubleFrame.d.ts +37 -0
  179. package/dist/game/motion/doubleFrame.d.ts.map +1 -0
  180. package/dist/game/motion/doubleFrame.js +59 -0
  181. package/dist/game/motion/doubleFrame.js.map +1 -0
  182. package/dist/game/motion/footSlide.d.ts +32 -0
  183. package/dist/game/motion/footSlide.d.ts.map +1 -0
  184. package/dist/game/motion/footSlide.js +59 -0
  185. package/dist/game/motion/footSlide.js.map +1 -0
  186. package/dist/game/motion/impact.d.ts +113 -0
  187. package/dist/game/motion/impact.d.ts.map +1 -0
  188. package/dist/game/motion/impact.js +233 -0
  189. package/dist/game/motion/impact.js.map +1 -0
  190. package/dist/game/motion/index.d.ts +19 -0
  191. package/dist/game/motion/index.d.ts.map +1 -0
  192. package/dist/game/motion/index.js +10 -0
  193. package/dist/game/motion/index.js.map +1 -0
  194. package/dist/game/motion/locomotion.d.ts +55 -0
  195. package/dist/game/motion/locomotion.d.ts.map +1 -0
  196. package/dist/game/motion/locomotion.js +107 -0
  197. package/dist/game/motion/locomotion.js.map +1 -0
  198. package/dist/game/motion/motionGate.d.ts +41 -0
  199. package/dist/game/motion/motionGate.d.ts.map +1 -0
  200. package/dist/game/motion/motionGate.js +71 -0
  201. package/dist/game/motion/motionGate.js.map +1 -0
  202. package/dist/game/motion/presenter.d.ts +37 -0
  203. package/dist/game/motion/presenter.d.ts.map +1 -0
  204. package/dist/game/motion/presenter.js +72 -0
  205. package/dist/game/motion/presenter.js.map +1 -0
  206. package/dist/game/motion/smoothing.d.ts +34 -0
  207. package/dist/game/motion/smoothing.d.ts.map +1 -0
  208. package/dist/game/motion/smoothing.js +92 -0
  209. package/dist/game/motion/smoothing.js.map +1 -0
  210. package/dist/game/session/warmPrograms.d.ts +58 -0
  211. package/dist/game/session/warmPrograms.d.ts.map +1 -0
  212. package/dist/game/session/warmPrograms.js +63 -0
  213. package/dist/game/session/warmPrograms.js.map +1 -0
  214. package/dist/math/Random.d.ts +3 -0
  215. package/dist/math/Random.d.ts.map +1 -1
  216. package/dist/math/Random.js +7 -0
  217. package/dist/math/Random.js.map +1 -1
  218. package/dist/rendering/WebGL2Device.d.ts.map +1 -1
  219. package/dist/rendering/WebGL2Device.js +3 -4
  220. package/dist/rendering/WebGL2Device.js.map +1 -1
  221. package/dist/rendering/environment/EnvironmentCache.d.ts.map +1 -1
  222. package/dist/rendering/environment/EnvironmentCache.js +6 -1
  223. package/dist/rendering/environment/EnvironmentCache.js.map +1 -1
  224. package/dist/rendering/environment/neutralEmbedded.d.ts +5 -0
  225. package/dist/rendering/environment/neutralEmbedded.d.ts.map +1 -0
  226. package/dist/rendering/environment/neutralEmbedded.js +1118 -0
  227. package/dist/rendering/environment/neutralEmbedded.js.map +1 -0
  228. package/dist/rendering/environment/neutralEmbeddedLoader.d.ts +5 -0
  229. package/dist/rendering/environment/neutralEmbeddedLoader.d.ts.map +1 -0
  230. package/dist/rendering/environment/neutralEmbeddedLoader.js +32 -0
  231. package/dist/rendering/environment/neutralEmbeddedLoader.js.map +1 -0
  232. package/dist/rendering/geometry/Primitives.d.ts +4 -1
  233. package/dist/rendering/geometry/Primitives.d.ts.map +1 -1
  234. package/dist/rendering/geometry/Primitives.js +5 -1
  235. package/dist/rendering/geometry/Primitives.js.map +1 -1
  236. package/dist/rendering/renderer/CullingBatching.d.ts.map +1 -1
  237. package/dist/rendering/renderer/CullingBatching.js +3 -7
  238. package/dist/rendering/renderer/CullingBatching.js.map +1 -1
  239. package/dist/rendering/renderer/InstanceBounds.d.ts +18 -0
  240. package/dist/rendering/renderer/InstanceBounds.d.ts.map +1 -0
  241. package/dist/rendering/renderer/InstanceBounds.js +68 -0
  242. package/dist/rendering/renderer/InstanceBounds.js.map +1 -0
  243. package/dist/rendering/renderer/RenderShared.d.ts.map +1 -1
  244. package/dist/rendering/renderer/RenderShared.js +3 -7
  245. package/dist/rendering/renderer/RenderShared.js.map +1 -1
  246. package/dist/rendering/shadows/DirectionalCascadeFitter.d.ts.map +1 -1
  247. package/dist/rendering/shadows/DirectionalCascadeFitter.js +19 -10
  248. package/dist/rendering/shadows/DirectionalCascadeFitter.js.map +1 -1
  249. package/dist/rendering/webgl2/LdrPostprocessShader.d.ts +24 -0
  250. package/dist/rendering/webgl2/LdrPostprocessShader.d.ts.map +1 -0
  251. package/dist/rendering/webgl2/LdrPostprocessShader.js +233 -0
  252. package/dist/rendering/webgl2/LdrPostprocessShader.js.map +1 -0
  253. package/dist/rendering/webgl2/LegacyPost.d.ts +5 -3
  254. package/dist/rendering/webgl2/LegacyPost.d.ts.map +1 -1
  255. package/dist/rendering/webgl2/LegacyPost.js +23 -191
  256. package/dist/rendering/webgl2/LegacyPost.js.map +1 -1
  257. package/package.json +25 -25
  258. package/templates/cinematic-scene/package.json +4 -3
  259. package/templates/mini-game/index.html +3 -1
  260. package/templates/mini-game/package.json +4 -3
  261. package/templates/mini-game/public/fonts/graphik/Graphik-Medium-Web.woff2 +0 -0
  262. package/templates/mini-game/public/fonts/graphik/Graphik-Regular-Web.woff2 +0 -0
  263. package/templates/mini-game/src/main.ts +1 -1
  264. package/templates/product-viewer/package.json +4 -3
  265. package/templates/production-asset-inspector/package.json +1 -1
  266. package/templates/production-material-studio/package.json +1 -1
  267. package/templates/production-product-configurator/package.json +1 -1
  268. package/templates/production-product-viewer/package.json +1 -1
@@ -0,0 +1,55 @@
1
+ export interface LocomotionGait {
2
+ readonly name: string;
3
+ /** Ground speed in m/s that the clip's root travels at playback rate 1. 0 for idle. */
4
+ readonly speed: number;
5
+ /** Seconds for one full stride cycle at playback rate 1. */
6
+ readonly cycle: number;
7
+ }
8
+ export interface LocomotionOptions {
9
+ readonly gaits: readonly LocomotionGait[];
10
+ /** Weight change per second when blending between gaits (default 6). */
11
+ readonly blendRate?: number;
12
+ readonly minRate?: number;
13
+ readonly maxRate?: number;
14
+ }
15
+ export interface LocomotionFrame {
16
+ readonly weights: Readonly<Record<string, number>>;
17
+ readonly rates: Readonly<Record<string, number>>;
18
+ /** Stride phase of the dominant gait, 0 to 1. */
19
+ readonly phase: number;
20
+ readonly dominant: string;
21
+ /** True when ground speed exceeds the fastest gait by more than the rate clamp can hide. */
22
+ readonly overspeed: boolean;
23
+ }
24
+ export interface Locomotion {
25
+ update(groundSpeed: number, dt: number): LocomotionFrame;
26
+ reset(): void;
27
+ }
28
+ /**
29
+ * Drives idle/walk/run/sprint clips from real ground speed so feet match the ground: clip weights
30
+ * follow speed brackets and playback rate = speed / clip speed (clamped), so planted feet do not slide.
31
+ */
32
+ export declare function createLocomotion(options: LocomotionOptions): Locomotion;
33
+ export interface LegPose {
34
+ /** Hip flexion, radians (positive swings the leg forward). */
35
+ readonly hip: number;
36
+ /** Knee flexion, radians (0 straight, positive bends). */
37
+ readonly knee: number;
38
+ readonly ankle: number;
39
+ }
40
+ export interface ProceduralGait {
41
+ readonly left: LegPose;
42
+ readonly right: LegPose;
43
+ /** Arm swing, radians, opposite to the same-side leg. */
44
+ readonly armLeft: number;
45
+ readonly armRight: number;
46
+ /** Vertical bob of the pelvis in metres. */
47
+ readonly bob: number;
48
+ }
49
+ /** Procedural leg-swing fallback for rigs with no usable walk/run clip. `phase` is a 0..1 stride phase. */
50
+ export declare function proceduralLegSwing(phase: number, groundSpeed: number, options?: {
51
+ readonly maxHip?: number;
52
+ readonly maxKnee?: number;
53
+ readonly speedForMax?: number;
54
+ }): ProceduralGait;
55
+ //# sourceMappingURL=locomotion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locomotion.d.ts","sourceRoot":"","sources":["../../../../../packages/game/src/motion/locomotion.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IAC1C,wEAAwE;IACxE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,CAAC;IACzD,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAoEvE;AAED,MAAM,WAAW,OAAO;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,2GAA2G;AAC3G,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,cAAc,CAuB3L"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Drives idle/walk/run/sprint clips from real ground speed so feet match the ground: clip weights
3
+ * follow speed brackets and playback rate = speed / clip speed (clamped), so planted feet do not slide.
4
+ */
5
+ export function createLocomotion(options) {
6
+ const gaits = [...options.gaits].sort((a, b) => a.speed - b.speed);
7
+ if (gaits.length < 2)
8
+ throw new Error("LOCOMOTION_GAITS: at least an idle and one moving gait are required.");
9
+ const blendRate = options.blendRate ?? 6;
10
+ const minRate = options.minRate ?? 0.6;
11
+ const maxRate = options.maxRate ?? 1.6;
12
+ const smooth = {};
13
+ for (const g of gaits)
14
+ smooth[g.name] = g === gaits[0] ? 1 : 0;
15
+ let phase = 0;
16
+ let dominant = gaits[0].name;
17
+ const target = (speed) => {
18
+ const w = {};
19
+ for (const g of gaits)
20
+ w[g.name] = 0;
21
+ const last = gaits[gaits.length - 1];
22
+ if (speed >= last.speed) {
23
+ w[last.name] = 1;
24
+ return w;
25
+ }
26
+ for (let i = 0; i < gaits.length - 1; i += 1) {
27
+ const a = gaits[i];
28
+ const b = gaits[i + 1];
29
+ if (speed >= a.speed && speed <= b.speed) {
30
+ const t = b.speed === a.speed ? 1 : (speed - a.speed) / (b.speed - a.speed);
31
+ w[a.name] = 1 - t;
32
+ w[b.name] = t;
33
+ return w;
34
+ }
35
+ }
36
+ w[gaits[0].name] = 1;
37
+ return w;
38
+ };
39
+ return {
40
+ update(groundSpeed, dt) {
41
+ const speed = Math.max(0, Number.isFinite(groundSpeed) ? groundSpeed : 0);
42
+ const want = target(speed);
43
+ const step = Math.min(1, blendRate * Math.max(0, dt));
44
+ let total = 0;
45
+ for (const g of gaits) {
46
+ smooth[g.name] = smooth[g.name] + (want[g.name] - smooth[g.name]) * step;
47
+ total += smooth[g.name];
48
+ }
49
+ const weights = {};
50
+ for (const g of gaits)
51
+ weights[g.name] = total > 0 ? smooth[g.name] / total : 0;
52
+ const rates = {};
53
+ const last = gaits[gaits.length - 1];
54
+ for (const g of gaits) {
55
+ if (g.speed <= 0)
56
+ rates[g.name] = 1;
57
+ else
58
+ rates[g.name] = Math.max(minRate, Math.min(maxRate, speed / g.speed));
59
+ }
60
+ let best = gaits[0];
61
+ for (const g of gaits)
62
+ if (weights[g.name] > weights[best.name])
63
+ best = g;
64
+ dominant = best.name;
65
+ if (best.speed > 0)
66
+ phase = (phase + (dt * rates[best.name]) / best.cycle) % 1;
67
+ return {
68
+ weights,
69
+ rates,
70
+ phase,
71
+ dominant,
72
+ overspeed: speed > last.speed * maxRate
73
+ };
74
+ },
75
+ reset() {
76
+ for (const g of gaits)
77
+ smooth[g.name] = g === gaits[0] ? 1 : 0;
78
+ phase = 0;
79
+ }
80
+ };
81
+ }
82
+ /** Procedural leg-swing fallback for rigs with no usable walk/run clip. `phase` is a 0..1 stride phase. */
83
+ export function proceduralLegSwing(phase, groundSpeed, options = {}) {
84
+ const maxHip = options.maxHip ?? 0.7;
85
+ const maxKnee = options.maxKnee ?? 1.2;
86
+ const k = Math.max(0, Math.min(1, groundSpeed / (options.speedForMax ?? 6)));
87
+ const leg = (offset) => {
88
+ const a = (phase + offset) * Math.PI * 2;
89
+ const swing = Math.sin(a);
90
+ const lift = Math.max(0, Math.cos(a));
91
+ return {
92
+ hip: swing * maxHip * k,
93
+ knee: lift * maxKnee * k,
94
+ ankle: -swing * 0.25 * k
95
+ };
96
+ };
97
+ const left = leg(0);
98
+ const right = leg(0.5);
99
+ return {
100
+ left,
101
+ right,
102
+ armLeft: right.hip * 0.8,
103
+ armRight: left.hip * 0.8,
104
+ bob: Math.abs(Math.sin(phase * Math.PI * 2)) * 0.03 * k
105
+ };
106
+ }
107
+ //# sourceMappingURL=locomotion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locomotion.js","sourceRoot":"","sources":["../../../../../packages/game/src/motion/locomotion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export interface MotionGateOptions {
2
+ /** Display refresh rate to simulate. */
3
+ displayHz: number;
4
+ /** Seconds of play to simulate. Default 8. */
5
+ seconds?: number;
6
+ /** Seconds at the start excluded from the statistics (acceleration from rest). Default 0. */
7
+ warmupSeconds?: number;
8
+ /** Fixed step length. Default 1/60. */
9
+ stepSeconds?: number;
10
+ /** Frame time jitter in seconds (deterministic, +/-). Default 0. */
11
+ jitterSeconds?: number;
12
+ /** Advance the real simulation by one step. */
13
+ step: (stepSeconds: number, stepIndex: number) => void;
14
+ /** Called at the end of every step (push the presenter snapshot here). */
15
+ afterStep?: () => void;
16
+ /** The scalar entity values drawn this frame (for example x and z of the player), read after the frame's steps. */
17
+ drawn: (alpha: number) => readonly number[];
18
+ /** Optional: the animation clip drawn this frame. Counts changes between frames. */
19
+ clip?: () => string;
20
+ /** Largest allowed share of frames where a moving entity is drawn unchanged. Default 0.05. */
21
+ maxStillFraction?: number;
22
+ /** Largest allowed coefficient of variation of the per-frame displacement. Default 0.25. */
23
+ maxCv?: number;
24
+ /** Largest allowed clip changes per 10 seconds. Default 4. */
25
+ maxClipFlipsPer10s?: number;
26
+ }
27
+ export interface MotionGateReport {
28
+ readonly frames: number;
29
+ readonly stillFrames: number;
30
+ readonly stillFraction: number;
31
+ readonly cv: number;
32
+ readonly clipFlipsPer10s: number;
33
+ readonly passed: boolean;
34
+ readonly failures: readonly string[];
35
+ }
36
+ /**
37
+ * Drives the real fixed-step loop at a simulated display rate and reports whether the drawn entities advance
38
+ * smoothly: no frames where they stand still, no uneven jumps, no clip flapping. Pure, no DOM.
39
+ */
40
+ export declare function runMotionGate(options: MotionGateOptions): MotionGateReport;
41
+ //# sourceMappingURL=motionGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motionGate.d.ts","sourceRoot":"","sources":["../../../../../packages/game/src/motion/motionGate.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6FAA6F;IAC7F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,mHAAmH;IACnH,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAC;IAC5C,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,MAAM,CAAC;IACpB,8FAA8F;IAC9F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4FAA4F;IAC5F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CA8D1E"}
@@ -0,0 +1,71 @@
1
+ import { createFixedStepLoop } from "../../engine/index.js";
2
+ /**
3
+ * Drives the real fixed-step loop at a simulated display rate and reports whether the drawn entities advance
4
+ * smoothly: no frames where they stand still, no uneven jumps, no clip flapping. Pure, no DOM.
5
+ */
6
+ export function runMotionGate(options) {
7
+ const seconds = options.seconds ?? 8;
8
+ const stepSeconds = options.stepSeconds ?? 1 / 60;
9
+ const frameMs = 1000 / options.displayHz;
10
+ const jitterMs = (options.jitterSeconds ?? 0) * 1000;
11
+ let seed = 1234567;
12
+ const rand = () => {
13
+ seed = (seed * 1664525 + 1013904223) >>> 0;
14
+ return seed / 0xffffffff - 0.5;
15
+ };
16
+ let clock = 0;
17
+ const loop = createFixedStepLoop({
18
+ stepSeconds,
19
+ step: (dt, index) => {
20
+ options.step(dt, index);
21
+ options.afterStep?.();
22
+ },
23
+ now: () => clock,
24
+ schedule: () => 0,
25
+ cancel: () => undefined
26
+ });
27
+ const frames = Math.round(seconds * options.displayHz);
28
+ const warmupFrames = Math.round((options.warmupSeconds ?? 0) * options.displayHz);
29
+ const previous = [];
30
+ const displacement = [];
31
+ let still = 0;
32
+ let flips = 0;
33
+ let lastClip;
34
+ let counted = 0;
35
+ for (let f = 0; f < frames; f += 1) {
36
+ clock += frameMs + (jitterMs ? rand() * 2 * jitterMs : 0);
37
+ loop.tick(clock);
38
+ const values = options.drawn(loop.alpha);
39
+ if (previous.length === values.length && f > 1 + warmupFrames) {
40
+ let moved = 0;
41
+ for (let i = 0; i < values.length; i += 1)
42
+ moved += Math.abs(values[i] - previous[i]);
43
+ displacement.push(moved);
44
+ if (moved < 1e-9)
45
+ still += 1;
46
+ counted += 1;
47
+ }
48
+ previous.length = 0;
49
+ previous.push(...values);
50
+ if (options.clip) {
51
+ const clip = options.clip();
52
+ if (lastClip !== undefined && clip !== lastClip)
53
+ flips += 1;
54
+ lastClip = clip;
55
+ }
56
+ }
57
+ const mean = displacement.reduce((s, v) => s + v, 0) / Math.max(1, displacement.length);
58
+ const variance = displacement.reduce((s, v) => s + (v - mean) ** 2, 0) / Math.max(1, displacement.length);
59
+ const cv = mean > 0 ? Math.sqrt(variance) / mean : 0;
60
+ const stillFraction = counted > 0 ? still / counted : 0;
61
+ const clipFlipsPer10s = flips * (10 / seconds);
62
+ const failures = [];
63
+ if (stillFraction > (options.maxStillFraction ?? 0.05))
64
+ failures.push(`still frames ${(stillFraction * 100).toFixed(1)}%`);
65
+ if (cv > (options.maxCv ?? 0.25))
66
+ failures.push(`displacement CV ${cv.toFixed(3)}`);
67
+ if (clipFlipsPer10s > (options.maxClipFlipsPer10s ?? 4))
68
+ failures.push(`clip flips ${clipFlipsPer10s.toFixed(0)} per 10 s`);
69
+ return { frames: counted, stillFrames: still, stillFraction, cv, clipFlipsPer10s, passed: failures.length === 0, failures };
70
+ }
71
+ //# sourceMappingURL=motionGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motionGate.js","sourceRoot":"","sources":["../../../../../packages/game/src/motion/motionGate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAuCrD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAA0B;IACtD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;IACrC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,GAAG,EAAE,CAAC;IAClD,MAAM,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC;IACzC,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IACrD,IAAI,IAAI,GAAG,OAAO,CAAC;IACnB,MAAM,IAAI,GAAG,GAAW,EAAE;QACxB,IAAI,GAAG,CAAC,IAAI,GAAG,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,IAAI,GAAG,UAAU,GAAG,GAAG,CAAC;IACjC,CAAC,CAAC;IAEF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,IAAI,GAAG,mBAAmB,CAAC;QAC/B,WAAW;QACX,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;YAClB,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YACxB,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QACxB,CAAC;QACD,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK;QAChB,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QACjB,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS;KACxB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClF,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,QAA4B,CAAC;IACjC,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,KAAK,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,EAAE,CAAC;YAC9D,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;gBAAE,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC,CAAC;YACxF,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,KAAK,GAAG,IAAI;gBAAE,KAAK,IAAI,CAAC,CAAC;YAC7B,OAAO,IAAI,CAAC,CAAC;QACf,CAAC;QACD,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACpB,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QACzB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,QAAQ,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ;gBAAE,KAAK,IAAI,CAAC,CAAC;YAC5D,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IACxF,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC1G,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,eAAe,GAAG,KAAK,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,aAAa,GAAG,CAAC,OAAO,CAAC,gBAAgB,IAAI,IAAI,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3H,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACpF,IAAI,eAAe,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,cAAc,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC5H,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;AAC9H,CAAC"}
@@ -0,0 +1,37 @@
1
+ /** Anything with a 0..1 progress through the current simulation step, such as `createFixedStepLoop`. */
2
+ export interface AlphaSource {
3
+ readonly alpha: number;
4
+ }
5
+ export interface FixedStepPresenterOptions<T> {
6
+ /** Capture what the renderer needs of the simulation right now. Must return a fresh value each call. */
7
+ snapshot: () => T;
8
+ /** Blend two snapshots; `t` is 0 at `a` and 1 at `b`. */
9
+ blend: (a: T, b: T, t: number) => T;
10
+ }
11
+ export interface FixedStepPresenter<T> {
12
+ /** Call at the end of every simulation step. */
13
+ afterStep(): void;
14
+ /** Call after a teleport, restart or scene change so the next frame does not smear between unrelated states. */
15
+ reset(): void;
16
+ /** The state to draw this frame: interpolated while `live`, the latest step otherwise (menus, manual QA runs). */
17
+ present(source: AlphaSource, live?: boolean): T;
18
+ }
19
+ /**
20
+ * Render interpolation in three calls: a 60 Hz simulation shown on a 120 or 144 Hz display advances on every
21
+ * frame instead of every other one. Replays and `stepFrames` are untouched because only the drawn pose is blended.
22
+ */
23
+ export declare function createFixedStepPresenter<T>(options: FixedStepPresenterOptions<T>): FixedStepPresenter<T>;
24
+ export interface RecordBlendOptions<T> {
25
+ /** Property names holding angles in radians: blended along the shortest arc. */
26
+ angleKeys?: readonly string[];
27
+ /** A step that moves the tracked position further than this is a teleport or wrap: show the new state. */
28
+ snapDistance?: number;
29
+ /** Position used for the snap test. */
30
+ position?: (value: T) => readonly number[];
31
+ }
32
+ /**
33
+ * A blend function for plain pose records: numbers interpolate, listed angle keys take the shortest arc, arrays
34
+ * and typed arrays interpolate per element, and everything else (clip names, flags) takes the latest value.
35
+ */
36
+ export declare function createRecordBlend<T extends object>(options?: RecordBlendOptions<T>): (a: T, b: T, t: number) => T;
37
+ //# sourceMappingURL=presenter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter.d.ts","sourceRoot":"","sources":["../../../../../packages/game/src/motion/presenter.ts"],"names":[],"mappings":"AAEA,wGAAwG;AACxG,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,wGAAwG;IACxG,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClB,yDAAyD;IACzD,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,gDAAgD;IAChD,SAAS,IAAI,IAAI,CAAC;IAClB,gHAAgH;IAChH,KAAK,IAAI,IAAI,CAAC;IACd,kHAAkH;IAClH,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC;CACjD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAkBxG;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,gFAAgF;IAChF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,0GAA0G;IAC1G,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,SAAS,MAAM,EAAE,CAAC;CAC5C;AA4BD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,GAAE,kBAAkB,CAAC,CAAC,CAAM,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC,CAYrH"}
@@ -0,0 +1,72 @@
1
+ import { createRenderInterpolator, lerpAngle } from "./smoothing.js";
2
+ /**
3
+ * Render interpolation in three calls: a 60 Hz simulation shown on a 120 or 144 Hz display advances on every
4
+ * frame instead of every other one. Replays and `stepFrames` are untouched because only the drawn pose is blended.
5
+ */
6
+ export function createFixedStepPresenter(options) {
7
+ const interpolator = createRenderInterpolator(options.blend);
8
+ interpolator.reset(options.snapshot());
9
+ return {
10
+ afterStep() {
11
+ interpolator.push(options.snapshot());
12
+ },
13
+ reset() {
14
+ interpolator.reset(options.snapshot());
15
+ },
16
+ present(source, live = true) {
17
+ const latest = () => options.snapshot();
18
+ if (!live)
19
+ return latest();
20
+ const alpha = source.alpha;
21
+ if (alpha >= 1)
22
+ return latest();
23
+ return interpolator.sample(alpha) ?? latest();
24
+ }
25
+ };
26
+ }
27
+ function blendValue(a, b, t, key, angleKeys) {
28
+ if (typeof a === "number" && typeof b === "number") {
29
+ return angleKeys.has(key) ? lerpAngle(a, b, t) : a + (b - a) * t;
30
+ }
31
+ if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {
32
+ return a.map((x, i) => blendValue(x, b[i], t, key, angleKeys));
33
+ }
34
+ if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b) && !(a instanceof DataView) && a.length === b.length) {
35
+ const aa = a;
36
+ const bb = b;
37
+ const out = new a.constructor((aa).length);
38
+ for (let i = 0; i < aa.length; i += 1)
39
+ out[i] = aa[i] + (bb[i] - aa[i]) * t;
40
+ return out;
41
+ }
42
+ if (a !== null && b !== null && typeof a === "object" && typeof b === "object") {
43
+ const out = {};
44
+ for (const k of Object.keys(b)) {
45
+ out[k] = k in a
46
+ ? blendValue(a[k], b[k], t, k, angleKeys)
47
+ : b[k];
48
+ }
49
+ return out;
50
+ }
51
+ return b;
52
+ }
53
+ /**
54
+ * A blend function for plain pose records: numbers interpolate, listed angle keys take the shortest arc, arrays
55
+ * and typed arrays interpolate per element, and everything else (clip names, flags) takes the latest value.
56
+ */
57
+ export function createRecordBlend(options = {}) {
58
+ const angleKeys = new Set(options.angleKeys ?? []);
59
+ return (a, b, t) => {
60
+ if (options.snapDistance !== undefined && options.position) {
61
+ const pa = options.position(a);
62
+ const pb = options.position(b);
63
+ let d2 = 0;
64
+ for (let i = 0; i < Math.min(pa.length, pb.length); i += 1)
65
+ d2 += (pb[i] - pa[i]) ** 2;
66
+ if (d2 > options.snapDistance * options.snapDistance)
67
+ return b;
68
+ }
69
+ return blendValue(a, b, t, "", angleKeys);
70
+ };
71
+ }
72
+ //# sourceMappingURL=presenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter.js","sourceRoot":"","sources":["../../../../../packages/game/src/motion/presenter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ export type Vec3Tuple = [number, number, number];
2
+ export interface DampResult {
3
+ readonly value: number;
4
+ readonly velocity: number;
5
+ }
6
+ /** Critically damped follow (no overshoot, frame-rate independent). `smoothTime` is the time to reach about 95% of the way. */
7
+ export declare function smoothDamp(current: number, target: number, velocity: number, smoothTime: number, dt: number, maxSpeed?: number): DampResult;
8
+ export interface SmoothFollow3 {
9
+ readonly position: Vec3Tuple;
10
+ readonly velocity: Vec3Tuple;
11
+ step(target: readonly [number, number, number], dt: number): Vec3Tuple;
12
+ snap(target: readonly [number, number, number]): void;
13
+ }
14
+ export declare function createSmoothFollow3(start: readonly [number, number, number], options: {
15
+ readonly smoothTime: number;
16
+ readonly maxSpeed?: number;
17
+ }): SmoothFollow3;
18
+ export declare function lerpAngle(a: number, b: number, t: number): number;
19
+ /** Render-time interpolation between the last two fixed simulation states. */
20
+ export interface RenderInterpolator<T> {
21
+ push(state: T): void;
22
+ sample(alpha: number): T | undefined;
23
+ reset(state?: T): void;
24
+ }
25
+ export declare function createRenderInterpolator<T>(lerp: (a: T, b: T, t: number) => T): RenderInterpolator<T>;
26
+ /** RMS of the second difference of a uniformly sampled series: near 0 for smooth motion, large for jitter. */
27
+ export declare function secondDifferenceRms(samples: readonly number[]): number;
28
+ export interface JitterReport {
29
+ readonly rms: number;
30
+ readonly max: number;
31
+ readonly passed: boolean;
32
+ }
33
+ export declare function jitterReport(samples: readonly number[], threshold: number): JitterReport;
34
+ //# sourceMappingURL=smoothing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smoothing.d.ts","sourceRoot":"","sources":["../../../../../packages/game/src/motion/smoothing.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,+HAA+H;AAC/H,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,QAAQ,SAA2B,GAClC,UAAU,CAiBZ;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IACvE,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CACvD;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EACxC,OAAO,EAAE;IAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACnE,aAAa,CAqBf;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAMjE;AAED,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IACrB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;IACrC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;CACxB;AAED,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAkBrG;AAED,8GAA8G;AAC9G,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAQtE;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAOxF"}
@@ -0,0 +1,92 @@
1
+ /** Critically damped follow (no overshoot, frame-rate independent). `smoothTime` is the time to reach about 95% of the way. */
2
+ export function smoothDamp(current, target, velocity, smoothTime, dt, maxSpeed = Number.POSITIVE_INFINITY) {
3
+ if (!(dt > 0))
4
+ return { value: current, velocity };
5
+ const st = Math.max(1e-4, smoothTime);
6
+ const omega = 2 / st;
7
+ const x = omega * dt;
8
+ const exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x);
9
+ const maxChange = maxSpeed * st;
10
+ const change = Math.max(-maxChange, Math.min(maxChange, current - target));
11
+ const clampedTarget = current - change;
12
+ const temp = (velocity + omega * change) * dt;
13
+ let nextVelocity = (velocity - omega * temp) * exp;
14
+ let value = clampedTarget + (change + temp) * exp;
15
+ if (target - current > 0 === value > target) {
16
+ value = target;
17
+ nextVelocity = (value - target) / dt;
18
+ }
19
+ return { value, velocity: nextVelocity };
20
+ }
21
+ export function createSmoothFollow3(start, options) {
22
+ const position = [start[0], start[1], start[2]];
23
+ const velocity = [0, 0, 0];
24
+ return {
25
+ position,
26
+ velocity,
27
+ step(target, dt) {
28
+ for (let i = 0; i < 3; i += 1) {
29
+ const r = smoothDamp(position[i], target[i], velocity[i], options.smoothTime, dt, options.maxSpeed);
30
+ position[i] = r.value;
31
+ velocity[i] = r.velocity;
32
+ }
33
+ return position;
34
+ },
35
+ snap(target) {
36
+ position[0] = target[0];
37
+ position[1] = target[1];
38
+ position[2] = target[2];
39
+ velocity[0] = velocity[1] = velocity[2] = 0;
40
+ }
41
+ };
42
+ }
43
+ export function lerpAngle(a, b, t) {
44
+ const twoPi = Math.PI * 2;
45
+ let d = (b - a) % twoPi;
46
+ if (d > Math.PI)
47
+ d -= twoPi;
48
+ else if (d < -Math.PI)
49
+ d += twoPi;
50
+ return a + d * t;
51
+ }
52
+ export function createRenderInterpolator(lerp) {
53
+ let prev;
54
+ let curr;
55
+ return {
56
+ push(state) {
57
+ prev = curr ?? state;
58
+ curr = state;
59
+ },
60
+ sample(alpha) {
61
+ if (curr === undefined)
62
+ return undefined;
63
+ if (prev === undefined)
64
+ return curr;
65
+ return lerp(prev, curr, Math.max(0, Math.min(1, alpha)));
66
+ },
67
+ reset(state) {
68
+ prev = state;
69
+ curr = state;
70
+ }
71
+ };
72
+ }
73
+ /** RMS of the second difference of a uniformly sampled series: near 0 for smooth motion, large for jitter. */
74
+ export function secondDifferenceRms(samples) {
75
+ if (samples.length < 3)
76
+ return 0;
77
+ let sum = 0;
78
+ for (let i = 2; i < samples.length; i += 1) {
79
+ const d2 = samples[i] - 2 * samples[i - 1] + samples[i - 2];
80
+ sum += d2 * d2;
81
+ }
82
+ return Math.sqrt(sum / (samples.length - 2));
83
+ }
84
+ export function jitterReport(samples, threshold) {
85
+ let max = 0;
86
+ for (let i = 2; i < samples.length; i += 1) {
87
+ max = Math.max(max, Math.abs(samples[i] - 2 * samples[i - 1] + samples[i - 2]));
88
+ }
89
+ const rms = secondDifferenceRms(samples);
90
+ return { rms, max, passed: rms <= threshold };
91
+ }
92
+ //# sourceMappingURL=smoothing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smoothing.js","sourceRoot":"","sources":["../../../../../packages/game/src/motion/smoothing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Settle every shader program the first frames need before the game shows its first frame.
3
+ *
4
+ * Programs compile asynchronously and a draw whose program is still compiling is skipped, so a game that renders
5
+ * straight after `await app.ready()` shows a partial scene (a missing road, missing buildings) for as long as the
6
+ * compile takes: seconds on a slow or busy GPU. `ready()` settles the mount; this settles the programs.
7
+ *
8
+ * 1. `precompile()` settles the programs predicted from the mounted scene.
9
+ * 2. A frame is stepped so the renderer kicks the exact feature records (shadows, fog, image-based lighting).
10
+ * 3. `precompile()` again settles any record that differed from the prediction.
11
+ * 4. Frames are stepped until the draw-call count is the same on `stableFrames` frames in a row, because which
12
+ * variants an item needs depends on its state relative to the camera and only shows once it is drawn.
13
+ * 5. A requested environment HDRI that is still loading is waited for (bounded), and steps 3 and 4 run again:
14
+ * when the HDRI lands, every material switches to its image-based-lighting program variant at once, which
15
+ * recompiles the whole scene and drops frames after the game believed it was settled.
16
+ *
17
+ * Call it again after a large jump (a teleport) before capturing a frame.
18
+ */
19
+ export interface WarmableApp {
20
+ precompile?(): Promise<unknown>;
21
+ step(dt?: number): unknown;
22
+ diagnostics?(): {
23
+ readonly drawCalls?: number;
24
+ readonly renderer?: {
25
+ readonly environment?: {
26
+ readonly hdriStatus?: string;
27
+ };
28
+ };
29
+ };
30
+ }
31
+ export interface WarmProgramsOptions {
32
+ /** Warm frames stepped between the two precompile passes. Default 1. */
33
+ readonly frames?: number;
34
+ /** Consecutive frames with the same draw-call count that count as settled. Default 3. Needs `app.diagnostics`. */
35
+ readonly stableFrames?: number;
36
+ /** Upper bound on the extra frames stepped while waiting for the draw-call count to settle. Default 12. */
37
+ readonly maxFrames?: number;
38
+ /** Wait for a requested environment HDRI (`renderer.environment.hdriStatus === "pending"`) before settling. Default true. Needs `app.diagnostics`. */
39
+ readonly waitForEnvironment?: boolean;
40
+ /** Upper bound on that wait, in milliseconds. Default 20000. */
41
+ readonly environmentTimeoutMs?: number;
42
+ }
43
+ export interface WarmProgramsResult {
44
+ /** Precompile passes that ran (0 when the app has no `precompile`). */
45
+ readonly passes: number;
46
+ readonly frames: number;
47
+ /** Extra frames stepped while the draw-call count settled. */
48
+ readonly settleFrames: number;
49
+ /** True when the draw-call count was stable on `stableFrames` frames in a row (always true without diagnostics). */
50
+ readonly settled: boolean;
51
+ /** Frames stepped while waiting for the environment HDRI (0 when none was pending). */
52
+ readonly environmentFrames: number;
53
+ /** False only when an HDRI was still pending when the wait timed out. */
54
+ readonly environmentReady: boolean;
55
+ readonly durationMs: number;
56
+ }
57
+ export declare function warmPrograms(app: WarmableApp, options?: WarmProgramsOptions): Promise<WarmProgramsResult>;
58
+ //# sourceMappingURL=warmPrograms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"warmPrograms.d.ts","sourceRoot":"","sources":["../../../../../packages/game/src/session/warmPrograms.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,WAAW,CAAC,IAAI;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;YAAE,QAAQ,CAAC,WAAW,CAAC,EAAE;gBAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAC;CAClI;AAED,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,kHAAkH;IAClH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,2GAA2G;IAC3G,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,sJAAsJ;IACtJ,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,gEAAgE;IAChE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,kBAAkB;IACjC,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,oHAAoH;IACpH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uFAAuF;IACvF,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,yEAAyE;IACzE,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAID,wBAAsB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAwDnH"}