human2ai 0.1.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 (326) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/assets/quaternius/License_Standard.txt +22 -0
  4. package/assets/quaternius/README.md +31 -0
  5. package/assets/quaternius/Superhero_Female_FullBody.bin +0 -0
  6. package/assets/quaternius/Superhero_Female_FullBody.gltf +2056 -0
  7. package/assets/quaternius/Superhero_Male_FullBody.bin +0 -0
  8. package/assets/quaternius/Superhero_Male_FullBody.gltf +2018 -0
  9. package/dist/cli/integration.d.ts +39 -0
  10. package/dist/cli/integration.js +466 -0
  11. package/dist/cli/integration.js.map +1 -0
  12. package/dist/cli/main.d.ts +17 -0
  13. package/dist/cli/main.js +1455 -0
  14. package/dist/cli/main.js.map +1 -0
  15. package/dist/database/composition-session-repository.d.ts +37 -0
  16. package/dist/database/composition-session-repository.js +147 -0
  17. package/dist/database/composition-session-repository.js.map +1 -0
  18. package/dist/database/draft-version-errors.d.ts +29 -0
  19. package/dist/database/draft-version-errors.js +47 -0
  20. package/dist/database/draft-version-errors.js.map +1 -0
  21. package/dist/database/draft-version-store.d.ts +30 -0
  22. package/dist/database/draft-version-store.js +168 -0
  23. package/dist/database/draft-version-store.js.map +1 -0
  24. package/dist/database/image-asset-repository.d.ts +37 -0
  25. package/dist/database/image-asset-repository.js +101 -0
  26. package/dist/database/image-asset-repository.js.map +1 -0
  27. package/dist/database/image-input.d.ts +15 -0
  28. package/dist/database/image-input.js +28 -0
  29. package/dist/database/image-input.js.map +1 -0
  30. package/dist/database/migrate.d.ts +4 -0
  31. package/dist/database/migrate.js +45 -0
  32. package/dist/database/migrate.js.map +1 -0
  33. package/dist/database/project-session-repository.d.ts +72 -0
  34. package/dist/database/project-session-repository.js +291 -0
  35. package/dist/database/project-session-repository.js.map +1 -0
  36. package/dist/database/spatial-session-repository.d.ts +26 -0
  37. package/dist/database/spatial-session-repository.js +44 -0
  38. package/dist/database/spatial-session-repository.js.map +1 -0
  39. package/dist/database/style-library-repository.d.ts +70 -0
  40. package/dist/database/style-library-repository.js +290 -0
  41. package/dist/database/style-library-repository.js.map +1 -0
  42. package/dist/database/svg-input.d.ts +1 -0
  43. package/dist/database/svg-input.js +77 -0
  44. package/dist/database/svg-input.js.map +1 -0
  45. package/dist/database/ui-sketch-session-repository.d.ts +19 -0
  46. package/dist/database/ui-sketch-session-repository.js +35 -0
  47. package/dist/database/ui-sketch-session-repository.js.map +1 -0
  48. package/dist/domain/canvas-layer-order.d.ts +6 -0
  49. package/dist/domain/canvas-layer-order.js +40 -0
  50. package/dist/domain/canvas-layer-order.js.map +1 -0
  51. package/dist/domain/canvas-node-metadata.d.ts +20 -0
  52. package/dist/domain/canvas-node-metadata.js +17 -0
  53. package/dist/domain/canvas-node-metadata.js.map +1 -0
  54. package/dist/domain/canvas-states.d.ts +8 -0
  55. package/dist/domain/canvas-states.js +23 -0
  56. package/dist/domain/canvas-states.js.map +1 -0
  57. package/dist/domain/composition/analysis.d.ts +104 -0
  58. package/dist/domain/composition/analysis.js +337 -0
  59. package/dist/domain/composition/analysis.js.map +1 -0
  60. package/dist/domain/composition/camera-reference.d.ts +24 -0
  61. package/dist/domain/composition/camera-reference.js +34 -0
  62. package/dist/domain/composition/camera-reference.js.map +1 -0
  63. package/dist/domain/composition/draft.d.ts +50 -0
  64. package/dist/domain/composition/draft.js +609 -0
  65. package/dist/domain/composition/draft.js.map +1 -0
  66. package/dist/domain/composition/frame.d.ts +23 -0
  67. package/dist/domain/composition/frame.js +154 -0
  68. package/dist/domain/composition/frame.js.map +1 -0
  69. package/dist/domain/composition/geometry.d.ts +15 -0
  70. package/dist/domain/composition/geometry.js +262 -0
  71. package/dist/domain/composition/geometry.js.map +1 -0
  72. package/dist/domain/composition/index.d.ts +13 -0
  73. package/dist/domain/composition/index.js +10 -0
  74. package/dist/domain/composition/index.js.map +1 -0
  75. package/dist/domain/composition/layers.d.ts +4 -0
  76. package/dist/domain/composition/layers.js +12 -0
  77. package/dist/domain/composition/layers.js.map +1 -0
  78. package/dist/domain/composition/records.d.ts +14 -0
  79. package/dist/domain/composition/records.js +2 -0
  80. package/dist/domain/composition/records.js.map +1 -0
  81. package/dist/domain/composition/refinement/engine.d.ts +12 -0
  82. package/dist/domain/composition/refinement/engine.js +521 -0
  83. package/dist/domain/composition/refinement/engine.js.map +1 -0
  84. package/dist/domain/composition/refinement/relations.d.ts +16 -0
  85. package/dist/domain/composition/refinement/relations.js +293 -0
  86. package/dist/domain/composition/refinement/relations.js.map +1 -0
  87. package/dist/domain/composition/refinement/types.d.ts +181 -0
  88. package/dist/domain/composition/refinement/types.js +2 -0
  89. package/dist/domain/composition/refinement/types.js.map +1 -0
  90. package/dist/domain/composition/render.d.ts +5 -0
  91. package/dist/domain/composition/render.js +169 -0
  92. package/dist/domain/composition/render.js.map +1 -0
  93. package/dist/domain/composition/states.d.ts +9 -0
  94. package/dist/domain/composition/states.js +104 -0
  95. package/dist/domain/composition/states.js.map +1 -0
  96. package/dist/domain/composition/types.d.ts +149 -0
  97. package/dist/domain/composition/types.js +2 -0
  98. package/dist/domain/composition/types.js.map +1 -0
  99. package/dist/domain/composition/workflow.d.ts +15 -0
  100. package/dist/domain/composition/workflow.js +77 -0
  101. package/dist/domain/composition/workflow.js.map +1 -0
  102. package/dist/domain/fingerprint.d.ts +2 -0
  103. package/dist/domain/fingerprint.js +25 -0
  104. package/dist/domain/fingerprint.js.map +1 -0
  105. package/dist/domain/session/canvas-edit-history.d.ts +17 -0
  106. package/dist/domain/session/canvas-edit-history.js +53 -0
  107. package/dist/domain/session/canvas-edit-history.js.map +1 -0
  108. package/dist/domain/session/capabilities.d.ts +16 -0
  109. package/dist/domain/session/capabilities.js +84 -0
  110. package/dist/domain/session/capabilities.js.map +1 -0
  111. package/dist/domain/session/draft-version.d.ts +41 -0
  112. package/dist/domain/session/draft-version.js +2 -0
  113. package/dist/domain/session/draft-version.js.map +1 -0
  114. package/dist/domain/session/index.d.ts +5 -0
  115. package/dist/domain/session/index.js +3 -0
  116. package/dist/domain/session/index.js.map +1 -0
  117. package/dist/domain/session/types.d.ts +23 -0
  118. package/dist/domain/session/types.js +2 -0
  119. package/dist/domain/session/types.js.map +1 -0
  120. package/dist/domain/spatial/assets/quaternius-female-rig.json +799 -0
  121. package/dist/domain/spatial/assets/quaternius-rig.json +799 -0
  122. package/dist/domain/spatial/assets/quaternius-superhero-female.json +1 -0
  123. package/dist/domain/spatial/assets/quaternius-superhero.json +1 -0
  124. package/dist/domain/spatial/camera-box.d.ts +13 -0
  125. package/dist/domain/spatial/camera-box.js +52 -0
  126. package/dist/domain/spatial/camera-box.js.map +1 -0
  127. package/dist/domain/spatial/geometric-model.d.ts +4 -0
  128. package/dist/domain/spatial/geometric-model.js +101 -0
  129. package/dist/domain/spatial/geometric-model.js.map +1 -0
  130. package/dist/domain/spatial/hands.d.ts +36 -0
  131. package/dist/domain/spatial/hands.js +128 -0
  132. package/dist/domain/spatial/hands.js.map +1 -0
  133. package/dist/domain/spatial/index.d.ts +30 -0
  134. package/dist/domain/spatial/index.js +381 -0
  135. package/dist/domain/spatial/index.js.map +1 -0
  136. package/dist/domain/spatial/kinematics.d.ts +27 -0
  137. package/dist/domain/spatial/kinematics.js +285 -0
  138. package/dist/domain/spatial/kinematics.js.map +1 -0
  139. package/dist/domain/spatial/lighting.d.ts +35 -0
  140. package/dist/domain/spatial/lighting.js +173 -0
  141. package/dist/domain/spatial/lighting.js.map +1 -0
  142. package/dist/domain/spatial/model.d.ts +5 -0
  143. package/dist/domain/spatial/model.js +193 -0
  144. package/dist/domain/spatial/model.js.map +1 -0
  145. package/dist/domain/spatial/morph.d.ts +3 -0
  146. package/dist/domain/spatial/morph.js +187 -0
  147. package/dist/domain/spatial/morph.js.map +1 -0
  148. package/dist/domain/spatial/proportions.d.ts +46 -0
  149. package/dist/domain/spatial/proportions.js +59 -0
  150. package/dist/domain/spatial/proportions.js.map +1 -0
  151. package/dist/domain/spatial/reference-lines.d.ts +6 -0
  152. package/dist/domain/spatial/reference-lines.js +58 -0
  153. package/dist/domain/spatial/reference-lines.js.map +1 -0
  154. package/dist/domain/spatial/scene-cache.d.ts +15 -0
  155. package/dist/domain/spatial/scene-cache.js +69 -0
  156. package/dist/domain/spatial/scene-cache.js.map +1 -0
  157. package/dist/domain/spatial/scene.d.ts +8 -0
  158. package/dist/domain/spatial/scene.js +69 -0
  159. package/dist/domain/spatial/scene.js.map +1 -0
  160. package/dist/domain/spatial/types.d.ts +187 -0
  161. package/dist/domain/spatial/types.js +5 -0
  162. package/dist/domain/spatial/types.js.map +1 -0
  163. package/dist/domain/style/index.d.ts +1 -0
  164. package/dist/domain/style/index.js +2 -0
  165. package/dist/domain/style/index.js.map +1 -0
  166. package/dist/domain/style/prompt-summary.d.ts +2 -0
  167. package/dist/domain/style/prompt-summary.js +11 -0
  168. package/dist/domain/style/prompt-summary.js.map +1 -0
  169. package/dist/domain/style/types.d.ts +32 -0
  170. package/dist/domain/style/types.js +3 -0
  171. package/dist/domain/style/types.js.map +1 -0
  172. package/dist/domain/ui-sketch/draft.d.ts +12 -0
  173. package/dist/domain/ui-sketch/draft.js +424 -0
  174. package/dist/domain/ui-sketch/draft.js.map +1 -0
  175. package/dist/domain/ui-sketch/geometry.d.ts +7 -0
  176. package/dist/domain/ui-sketch/geometry.js +11 -0
  177. package/dist/domain/ui-sketch/geometry.js.map +1 -0
  178. package/dist/domain/ui-sketch/groups.d.ts +5 -0
  179. package/dist/domain/ui-sketch/groups.js +40 -0
  180. package/dist/domain/ui-sketch/groups.js.map +1 -0
  181. package/dist/domain/ui-sketch/index.d.ts +8 -0
  182. package/dist/domain/ui-sketch/index.js +8 -0
  183. package/dist/domain/ui-sketch/index.js.map +1 -0
  184. package/dist/domain/ui-sketch/layers.d.ts +4 -0
  185. package/dist/domain/ui-sketch/layers.js +11 -0
  186. package/dist/domain/ui-sketch/layers.js.map +1 -0
  187. package/dist/domain/ui-sketch/render.d.ts +2 -0
  188. package/dist/domain/ui-sketch/render.js +58 -0
  189. package/dist/domain/ui-sketch/render.js.map +1 -0
  190. package/dist/domain/ui-sketch/standardize.d.ts +17 -0
  191. package/dist/domain/ui-sketch/standardize.js +139 -0
  192. package/dist/domain/ui-sketch/standardize.js.map +1 -0
  193. package/dist/domain/ui-sketch/states.d.ts +5 -0
  194. package/dist/domain/ui-sketch/states.js +21 -0
  195. package/dist/domain/ui-sketch/states.js.map +1 -0
  196. package/dist/domain/ui-sketch/types.d.ts +73 -0
  197. package/dist/domain/ui-sketch/types.js +2 -0
  198. package/dist/domain/ui-sketch/types.js.map +1 -0
  199. package/dist/server/app.d.ts +18 -0
  200. package/dist/server/app.js +108 -0
  201. package/dist/server/app.js.map +1 -0
  202. package/dist/server/image-content-type-parser.d.ts +2 -0
  203. package/dist/server/image-content-type-parser.js +5 -0
  204. package/dist/server/image-content-type-parser.js.map +1 -0
  205. package/dist/server/routes/composition-sessions.d.ts +3 -0
  206. package/dist/server/routes/composition-sessions.js +190 -0
  207. package/dist/server/routes/composition-sessions.js.map +1 -0
  208. package/dist/server/routes/draft-version-routes.d.ts +10 -0
  209. package/dist/server/routes/draft-version-routes.js +201 -0
  210. package/dist/server/routes/draft-version-routes.js.map +1 -0
  211. package/dist/server/routes/image-assets.d.ts +3 -0
  212. package/dist/server/routes/image-assets.js +114 -0
  213. package/dist/server/routes/image-assets.js.map +1 -0
  214. package/dist/server/routes/project-sessions.d.ts +48 -0
  215. package/dist/server/routes/project-sessions.js +305 -0
  216. package/dist/server/routes/project-sessions.js.map +1 -0
  217. package/dist/server/routes/spatial-sessions.d.ts +3 -0
  218. package/dist/server/routes/spatial-sessions.js +80 -0
  219. package/dist/server/routes/spatial-sessions.js.map +1 -0
  220. package/dist/server/routes/style-library.d.ts +3 -0
  221. package/dist/server/routes/style-library.js +308 -0
  222. package/dist/server/routes/style-library.js.map +1 -0
  223. package/dist/server/routes/ui-sketch-sessions.d.ts +3 -0
  224. package/dist/server/routes/ui-sketch-sessions.js +14 -0
  225. package/dist/server/routes/ui-sketch-sessions.js.map +1 -0
  226. package/dist/server/runtime.d.ts +30 -0
  227. package/dist/server/runtime.js +123 -0
  228. package/dist/server/runtime.js.map +1 -0
  229. package/dist/server/spatial-render.d.ts +5 -0
  230. package/dist/server/spatial-render.js +360 -0
  231. package/dist/server/spatial-render.js.map +1 -0
  232. package/dist/server/start.d.ts +1 -0
  233. package/dist/server/start.js +3 -0
  234. package/dist/server/start.js.map +1 -0
  235. package/licenses/THIRD-PARTY-NOTICES.txt +16664 -0
  236. package/licenses/YisiUI-LICENSE +21 -0
  237. package/locales/en/common.json +671 -0
  238. package/migrations/0001_projects_and_sessions.sql +45 -0
  239. package/migrations/0002_composition_versions_and_refinements.sql +26 -0
  240. package/migrations/0003_ui_sketch_draft_versions.sql +12 -0
  241. package/migrations/0004_image_assets.sql +16 -0
  242. package/migrations/0005_style_library.sql +31 -0
  243. package/migrations/0006_session_styles.sql +6 -0
  244. package/migrations/0007_svg_image_assets.sql +19 -0
  245. package/migrations/0008_spatial_spaces.sql +20 -0
  246. package/package.json +82 -0
  247. package/schemas/composition-draft.schema.json +234 -0
  248. package/schemas/composition-refinement-plan.schema.json +758 -0
  249. package/schemas/spatial-draft.schema.json +517 -0
  250. package/schemas/spatial-operations.schema.json +1082 -0
  251. package/schemas/ui-layout-standardization-plan.schema.json +29 -0
  252. package/schemas/ui-sketch-draft.schema.json +197 -0
  253. package/skills/human2ai/SKILL.md +149 -0
  254. package/skills/human2ai/agents/openai.yaml +3 -0
  255. package/skills/human2ai/references/composition-projection.md +170 -0
  256. package/skills/human2ai/references/composition.md +79 -0
  257. package/skills/human2ai/references/spatial.md +188 -0
  258. package/skills/human2ai/references/svg-images.md +27 -0
  259. package/skills/human2ai/references/ui-layout.md +100 -0
  260. package/web/out/404/index.html +1 -0
  261. package/web/out/404.html +1 -0
  262. package/web/out/__next.__PAGE__.txt +26 -0
  263. package/web/out/__next._full.txt +21 -0
  264. package/web/out/__next._tree.txt +4 -0
  265. package/web/out/_next/static/TV-jgcACg6HANZAMZTE2S/_buildManifest.js +1 -0
  266. package/web/out/_next/static/TV-jgcACg6HANZAMZTE2S/_ssgManifest.js +1 -0
  267. package/web/out/_next/static/chunks/130-9fadd0432daff55d.js +1 -0
  268. package/web/out/_next/static/chunks/158-eb00456e1bab68b3.js +52 -0
  269. package/web/out/_next/static/chunks/20-0801fc297cda2a7a.js +1 -0
  270. package/web/out/_next/static/chunks/248-d4a79649dae2a3f8.js +259 -0
  271. package/web/out/_next/static/chunks/678-1305cadf8254d814.js +1 -0
  272. package/web/out/_next/static/chunks/728-eb8b667f79229443.js +1 -0
  273. package/web/out/_next/static/chunks/83607670-bc1279370476e59f.js +1 -0
  274. package/web/out/_next/static/chunks/app/_global-error/page-5eece43b8152c414.js +1 -0
  275. package/web/out/_next/static/chunks/app/_not-found/page-c0cd75ac39fbf9cf.js +1 -0
  276. package/web/out/_next/static/chunks/app/composition/page-051ee2fabb12110a.js +1 -0
  277. package/web/out/_next/static/chunks/app/layout-745ca27ef8830f4f.js +1 -0
  278. package/web/out/_next/static/chunks/app/page-0027378a269a6168.js +1 -0
  279. package/web/out/_next/static/chunks/app/spatial/page-266dedc81784d4f6.js +1 -0
  280. package/web/out/_next/static/chunks/app/styles/page-d5cb83af828ea9ed.js +1 -0
  281. package/web/out/_next/static/chunks/app/ui-sketch/page-2a8436e05a05c618.js +1 -0
  282. package/web/out/_next/static/chunks/c3f2cda1-9e279dab137b7272.js +342 -0
  283. package/web/out/_next/static/chunks/c7879cf7-7873c8afd9c9c666.js +1 -0
  284. package/web/out/_next/static/chunks/framework-6eacf80ec1e4c887.js +1 -0
  285. package/web/out/_next/static/chunks/main-5ee8fd93319f955c.js +5 -0
  286. package/web/out/_next/static/chunks/main-app-0cf10803ab17c700.js +1 -0
  287. package/web/out/_next/static/chunks/next/dist/client/components/builtin/app-error-5eece43b8152c414.js +1 -0
  288. package/web/out/_next/static/chunks/next/dist/client/components/builtin/forbidden-5eece43b8152c414.js +1 -0
  289. package/web/out/_next/static/chunks/next/dist/client/components/builtin/global-error-728204b7cccc4ed2.js +1 -0
  290. package/web/out/_next/static/chunks/next/dist/client/components/builtin/not-found-5eece43b8152c414.js +1 -0
  291. package/web/out/_next/static/chunks/next/dist/client/components/builtin/unauthorized-5eece43b8152c414.js +1 -0
  292. package/web/out/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  293. package/web/out/_next/static/chunks/webpack-97ae63c0e0b2a512.js +1 -0
  294. package/web/out/_next/static/css/3b7982b41ed8eccd.css +4 -0
  295. package/web/out/_next/static/css/81ae71f1d3e9a866.css +1 -0
  296. package/web/out/_next/static/css/8c3843f4951fa9f6.css +5 -0
  297. package/web/out/_next/static/css/c739d0131cdcc891.css +1 -0
  298. package/web/out/_next/static/css/ce1b4bb3ad3c6073.css +1 -0
  299. package/web/out/_next/static/css/db96ae2e88545d96.css +1 -0
  300. package/web/out/_not-found/__next._full.txt +18 -0
  301. package/web/out/_not-found/__next._not-found.__PAGE__.txt +24 -0
  302. package/web/out/_not-found/__next._tree.txt +3 -0
  303. package/web/out/_not-found/index.html +1 -0
  304. package/web/out/_not-found/index.txt +18 -0
  305. package/web/out/composition/__next._full.txt +25 -0
  306. package/web/out/composition/__next._tree.txt +6 -0
  307. package/web/out/composition/__next.composition.__PAGE__.txt +31 -0
  308. package/web/out/composition/index.html +1 -0
  309. package/web/out/composition/index.txt +25 -0
  310. package/web/out/index.html +1 -0
  311. package/web/out/index.txt +21 -0
  312. package/web/out/spatial/__next._full.txt +23 -0
  313. package/web/out/spatial/__next._tree.txt +4 -0
  314. package/web/out/spatial/__next.spatial.__PAGE__.txt +29 -0
  315. package/web/out/spatial/index.html +1 -0
  316. package/web/out/spatial/index.txt +23 -0
  317. package/web/out/styles/__next._full.txt +23 -0
  318. package/web/out/styles/__next._tree.txt +4 -0
  319. package/web/out/styles/__next.styles.__PAGE__.txt +29 -0
  320. package/web/out/styles/index.html +1 -0
  321. package/web/out/styles/index.txt +23 -0
  322. package/web/out/ui-sketch/__next._full.txt +25 -0
  323. package/web/out/ui-sketch/__next._tree.txt +6 -0
  324. package/web/out/ui-sketch/__next.ui-sketch.__PAGE__.txt +31 -0
  325. package/web/out/ui-sketch/index.html +1 -0
  326. package/web/out/ui-sketch/index.txt +25 -0
@@ -0,0 +1,13 @@
1
+ import { OrthographicCamera } from "three";
2
+ import { type SpatialBoxFace, type SpatialBoxView, type SpatialCamera, type SpatialCameraBox, type SpatialDraft } from "./types.ts";
3
+ export declare function createSpatialCameraBox(id: string, name: string): SpatialCameraBox;
4
+ export declare function cameraBoxImageSize(box: SpatialCameraBox, view: SpatialBoxView): {
5
+ width: number;
6
+ height: number;
7
+ };
8
+ export declare function cameraBoxView(box: SpatialCameraBox, face: SpatialBoxFace): {
9
+ source: SpatialCamera;
10
+ camera: OrthographicCamera;
11
+ };
12
+ /** Fit real posed mesh vertices in the box's own axes, including custom creature hands. */
13
+ export declare function fitSpatialCameraBox(box: SpatialCameraBox, draft: SpatialDraft, region: "scene" | "hands"): SpatialCameraBox;
@@ -0,0 +1,52 @@
1
+ import { Box3, Mesh, OrthographicCamera, Vector3 } from "three";
2
+ import { quaternion, vector } from "./kinematics.js";
3
+ import { fingerPart } from "./hands.js";
4
+ import { createSpatialScene, disposeSpatialScene } from "./scene.js";
5
+ import { SPATIAL_BOX_GAP, SPATIAL_BOX_LABEL_HEIGHT } from "./types.js";
6
+ // All directions are box-local. Top and bottom have explicit, non-degenerate up axes.
7
+ const axes = {
8
+ front: { normal: [0, 0, 1], up: [0, 1, 0] }, back: { normal: [0, 0, -1], up: [0, 1, 0] },
9
+ left: { normal: [-1, 0, 0], up: [0, 1, 0] }, right: { normal: [1, 0, 0], up: [0, 1, 0] },
10
+ top: { normal: [0, 1, 0], up: [0, 0, -1] }, bottom: { normal: [0, -1, 0], up: [0, 0, 1] },
11
+ };
12
+ export function createSpatialCameraBox(id, name) {
13
+ return { id, name, position: [0, .9, 0], rotation: [0, 0, 0], size: 2.4, resolution: 512 };
14
+ }
15
+ export function cameraBoxImageSize(box, view) {
16
+ return view === "sheet" ? { width: box.resolution * 3 + SPATIAL_BOX_GAP * 2, height: (box.resolution + SPATIAL_BOX_LABEL_HEIGHT) * 2 + SPATIAL_BOX_GAP } : { width: box.resolution, height: box.resolution };
17
+ }
18
+ export function cameraBoxView(box, face) {
19
+ const rotation = quaternion(box.rotation), half = box.size / 2;
20
+ const position = vector(axes[face].normal).applyQuaternion(rotation).multiplyScalar(half).add(vector(box.position));
21
+ const camera = new OrthographicCamera(-half, half, half, -half, 0, box.size);
22
+ camera.position.copy(position);
23
+ camera.up.copy(vector(axes[face].up).applyQuaternion(rotation));
24
+ camera.lookAt(vector(box.position));
25
+ camera.updateMatrixWorld();
26
+ const source = { id: `${box.id}-${face}`, name: box.name, position: position.toArray(), target: [...box.position], projection: "orthographic", fov: 40, span: box.size, width: box.resolution, height: box.resolution, background: null };
27
+ return { source, camera };
28
+ }
29
+ /** Fit real posed mesh vertices in the box's own axes, including custom creature hands. */
30
+ export function fitSpatialCameraBox(box, draft, region) {
31
+ const scene = createSpatialScene(draft), bounds = new Box3(), inverse = quaternion(box.rotation).invert(), point = new Vector3();
32
+ try {
33
+ scene.traverse(object => {
34
+ if (!(object instanceof Mesh))
35
+ return;
36
+ const part = String(object.userData.modelPart ?? "");
37
+ if (region === "hands" && !part.endsWith("-hand") && !fingerPart(part))
38
+ return;
39
+ const vertices = object.geometry.getAttribute("position");
40
+ for (let i = 0; i < vertices.count; i++)
41
+ bounds.expandByPoint(point.fromBufferAttribute(vertices, i).applyMatrix4(object.matrixWorld).applyQuaternion(inverse));
42
+ });
43
+ }
44
+ finally {
45
+ disposeSpatialScene(scene);
46
+ }
47
+ if (bounds.isEmpty())
48
+ return box;
49
+ const size = bounds.getSize(new Vector3());
50
+ return { ...box, position: bounds.getCenter(new Vector3()).applyQuaternion(quaternion(box.rotation)).toArray(), size: Math.max(.05, Math.max(size.x, size.y, size.z) * 1.15) };
51
+ }
52
+ //# sourceMappingURL=camera-box.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera-box.js","sourceRoot":"","sources":["../../../src/domain/spatial/camera-box.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Group } from "three";
2
+ import type { SpatialCharacter } from "./types.ts";
3
+ /** Rigid primitives share the authored rig with the anatomical surface. */
4
+ export declare function createGeometricCharacterModel(actor: SpatialCharacter): Group;
@@ -0,0 +1,101 @@
1
+ import { Box3, BoxGeometry, Color, CylinderGeometry, Group, Matrix4, Mesh, MeshLambertMaterial, Quaternion, SphereGeometry, Vector3 } from "three";
2
+ import { fingerPart, handRestMatrix, handRig } from "./hands.js";
3
+ import { jointWorldTransforms, proportionedJointOffset, vector } from "./kinematics.js";
4
+ import { footHeightScale, partWidth, spatialShape } from "./proportions.js";
5
+ // Match anatomical digits across both hands and cloned limbs.
6
+ const fingerColors = {
7
+ thumb: "#e49a45", index: "#499dd6", middle: "#45ad86", ring: "#a47bd4", little: "#dd6f8f",
8
+ };
9
+ /** Rigid primitives share the authored rig with the anatomical surface. */
10
+ export function createGeometricCharacterModel(actor) {
11
+ const group = new Group(), world = jointWorldTransforms(actor), shape = spatialShape(actor.headRatio);
12
+ const up = new Vector3(0, 1, 0), bodyColor = new Color(actor.color);
13
+ const bodyLuminance = .2126 * bodyColor.r + .7152 * bodyColor.g + .0722 * bodyColor.b;
14
+ const jointColor = bodyColor.clone().lerp(new Color(bodyLuminance > .25 ? "#26384b" : "#dce5ef"), .75);
15
+ const radii = new Map(actor.bones.map(bone => {
16
+ const part = bone.modelPart, finger = fingerPart(part);
17
+ const factor = ["spine", "chest"].includes(part) ? .035 : part === "neck" ? .014
18
+ : /-(shoulder|hip)$/.test(part) ? .012 : part.endsWith("-wrist") ? .014
19
+ : part.endsWith("-elbow") ? .016 : part.endsWith("-knee") ? .022 : .019;
20
+ const radius = finger ? actor.height * .0033 * shape.hand * (actor.palmSize ?? 1) * (finger.finger === "little" ? .8 : 1)
21
+ : actor.height * factor * partWidth(shape, part);
22
+ const length = world[bone.startJointId].position.distanceTo(world[bone.endJointId].position);
23
+ return [bone.id, finger && finger.segment > 0 ? Math.min(radius, length * .35) : radius];
24
+ }));
25
+ const add = (geometry, position, rotation, data, color = bodyColor) => {
26
+ const mesh = new Mesh(geometry, new MeshLambertMaterial({ color }));
27
+ mesh.position.copy(position);
28
+ mesh.quaternion.copy(rotation);
29
+ mesh.userData = { characterId: actor.id, ...data };
30
+ group.add(mesh);
31
+ return mesh;
32
+ };
33
+ for (const bone of actor.bones) {
34
+ const start = world[bone.startJointId].position, end = world[bone.endJointId].position;
35
+ const offset = proportionedJointOffset(actor, actor.joints.find(j => j.id === bone.endJointId));
36
+ const rotation = world[bone.endJointId].rotation;
37
+ const direction = end.clone().sub(start), length = direction.length();
38
+ const center = start.clone().add(end).multiplyScalar(.5);
39
+ const aligned = rotation.clone().multiply(new Quaternion().setFromUnitVectors(up, offset.clone().normalize()));
40
+ const data = { boneId: bone.id, modelPart: bone.modelPart };
41
+ if (bone.modelPart === "head") {
42
+ const rx = length * .36, ry = length * .5, rz = length * .31 * shape.headDepth;
43
+ add(new SphereGeometry(1, 24, 16).scale(rx, ry, rz), center, aligned, data);
44
+ for (const side of [-1, 1]) {
45
+ const eye = new Vector3(side * rx * .34, ry * .12, rz * .94).applyQuaternion(aligned).add(center);
46
+ add(new SphereGeometry(1, 12, 8).scale(rx * .105, ry * .095, rz * .065), eye, aligned, { ...data, feature: "eye" }, new Color("#23313c"));
47
+ }
48
+ }
49
+ else if (bone.modelPart.endsWith("-hand")) {
50
+ // Fit a rigid palm to the wrist and fixed knuckles. Its frame follows
51
+ // wrist rotation, including twist; curled fingers cannot resize it.
52
+ const normal = new Vector3(0, 1, 0).transformDirection(handRestMatrix(actor, bone)).applyQuaternion(rotation);
53
+ const y = direction.clone().normalize(), x = y.clone().cross(normal).normalize(), z = x.clone().cross(y).normalize();
54
+ const frame = new Quaternion().setFromRotationMatrix(new Matrix4().makeBasis(x, y, z));
55
+ const inverse = frame.clone().invert(), bounds = new Box3().expandByPoint(new Vector3()).expandByPoint(direction.clone().applyQuaternion(inverse));
56
+ for (const root of actor.bones.filter(b => b.startJointId === bone.endJointId && fingerPart(b.modelPart)?.segment === 0 && fingerPart(b.modelPart)?.finger !== "thumb")) {
57
+ bounds.expandByPoint(world[root.endJointId].position.clone().sub(start).applyQuaternion(inverse));
58
+ }
59
+ const thickness = actor.height * .018 * shape.hand * (actor.palmSize ?? 1);
60
+ bounds.min.x -= thickness * .2;
61
+ bounds.max.x += thickness * .2;
62
+ bounds.min.y -= thickness * .25;
63
+ const size = bounds.getSize(new Vector3());
64
+ size.z = Math.max(size.z, thickness);
65
+ const palmCenter = bounds.getCenter(new Vector3()).applyQuaternion(frame).add(start);
66
+ add(new BoxGeometry(size.x, size.y, size.z), palmCenter, frame, data);
67
+ }
68
+ else if (bone.modelPart.endsWith("-foot")) {
69
+ // Use the same anatomical sole height as ankle lifting. The box remains
70
+ // flat in the rest pose and rotates as a whole about the ankle.
71
+ const rig = handRig(actor), source = rig.parts.find(p => p.id === bone.modelPart);
72
+ const base = vector(actor.joints.find(j => j.id === bone.endJointId).offset).length() / vector(source.end).sub(vector(source.start)).length();
73
+ const sole = (source.start[1] - rig.bottom) * base * footHeightScale(actor.footSize);
74
+ const width = actor.height * .055 * shape.foot * (actor.footSize ?? 1), heel = width * .45;
75
+ const top = actor.height * .006 * footHeightScale(actor.footSize);
76
+ const footCenter = new Vector3(offset.x / 2, (top - sole) / 2, (offset.z - heel) / 2).applyQuaternion(rotation).add(start);
77
+ add(new BoxGeometry(width, sole + top, Math.abs(offset.z) + heel), footCenter, rotation, data);
78
+ }
79
+ else {
80
+ const radius = radii.get(bone.id);
81
+ const finger = fingerPart(bone.modelPart);
82
+ add(new CylinderGeometry(radius, radius, length, 12), center, new Quaternion().setFromUnitVectors(up, direction.normalize()), data, finger ? new Color(fingerColors[finger.finger]) : bodyColor);
83
+ }
84
+ }
85
+ for (const joint of actor.joints) {
86
+ const incoming = actor.bones.find(b => b.endJointId === joint.id), part = incoming?.modelPart ?? "pelvis";
87
+ // Head-top and toe landmarks are inside their solid forms, not hinges.
88
+ if (joint.terminal && (part === "head" || part.endsWith("-foot")))
89
+ continue;
90
+ const finger = fingerPart(part);
91
+ const connected = actor.bones.filter(b => b.endJointId === joint.id || b.startJointId === joint.id);
92
+ const radius = finger ? Math.max(...connected.map(b => radii.get(b.id))) * 1.08
93
+ : part === "neck" ? actor.height * .016
94
+ : Math.max(actor.height * .009, ...connected.filter(b => b.modelPart !== "head" && !b.modelPart.endsWith("-hand") && !b.modelPart.endsWith("-foot")).map(b => radii.get(b.id))) * 1.14;
95
+ const color = finger ? new Color(fingerColors[finger.finger]).lerp(new Color("#ffffff"), .65) : jointColor;
96
+ add(new SphereGeometry(radius, 16, 10), world[joint.id].position, world[joint.id].rotation, { jointId: joint.id, modelPart: part }, color);
97
+ }
98
+ group.updateMatrixWorld(true);
99
+ return group;
100
+ }
101
+ //# sourceMappingURL=geometric-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometric-model.js","sourceRoot":"","sources":["../../../src/domain/spatial/geometric-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAkB,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACnK,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAsB,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAG5E,8DAA8D;AAC9D,MAAM,YAAY,GAAiC;IACjD,KAAK,EAAC,SAAS,EAAE,KAAK,EAAC,SAAS,EAAE,MAAM,EAAC,SAAS,EAAE,IAAI,EAAC,SAAS,EAAE,MAAM,EAAC,SAAS;CACrF,CAAC;AAEF,2EAA2E;AAC3E,MAAM,UAAU,6BAA6B,CAAC,KAAuB;IACnE,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,EAAE,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACtG,MAAM,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,KAAK,GAAC,SAAS,CAAC,CAAC,GAAG,KAAK,GAAC,SAAS,CAAC,CAAC,GAAG,KAAK,GAAC,SAAS,CAAC,CAAC,CAAC;IAChF,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EAAC,GAAG,CAAC,CAAC;IACtG,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,CAAC,OAAO,EAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI;YAC7E,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI;gBACvE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1E,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACvH,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,KAAK,EAAC,IAAI,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAC,MAAM,GAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC,CAAC;IACJ,MAAM,GAAG,GAAG,CAAC,QAAwB,EAAE,QAAiB,EAAE,QAAoB,EAAE,IAA2B,EAAE,KAAK,GAAG,SAAS,EAAE,EAAE;QAChI,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAC,IAAI,mBAAmB,CAAC,EAAC,KAAK,EAAC,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7D,IAAI,CAAC,QAAQ,GAAG,EAAC,WAAW,EAAC,KAAK,CAAC,EAAE,EAAC,GAAG,IAAI,EAAC,CAAC;QAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAC/E,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC;QACvF,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,EAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,CAAC,EAAE,KAAG,IAAI,CAAC,UAAU,CAAE,CAAC,CAAC;QAC5F,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC;QACjD,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;QACtE,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,IAAI,UAAU,EAAE,CAAC,kBAAkB,CAAC,EAAE,EAAC,MAAM,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAC9G,MAAM,IAAI,GAAG,EAAC,MAAM,EAAC,IAAI,CAAC,EAAE,EAAC,SAAS,EAAC,IAAI,CAAC,SAAS,EAAC,CAAC;QACvD,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;YAC9B,MAAM,EAAE,GAAG,MAAM,GAAC,GAAG,EAAE,EAAE,GAAG,MAAM,GAAC,EAAE,EAAE,EAAE,GAAG,MAAM,GAAC,GAAG,GAAC,KAAK,CAAC,SAAS,CAAC;YACvE,GAAG,CAAC,IAAI,cAAc,CAAC,CAAC,EAAC,EAAE,EAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAC,EAAE,EAAC,EAAE,CAAC,EAAC,MAAM,EAAC,OAAO,EAAC,IAAI,CAAC,CAAC;YACrE,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,IAAI,GAAC,EAAE,GAAC,GAAG,EAAC,EAAE,GAAC,GAAG,EAAC,EAAE,GAAC,GAAG,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACxF,GAAG,CAAC,IAAI,cAAc,CAAC,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,GAAC,IAAI,EAAC,EAAE,GAAC,IAAI,EAAC,EAAE,GAAC,IAAI,CAAC,EAAC,GAAG,EAAC,OAAO,EAAC,EAAC,GAAG,IAAI,EAAC,OAAO,EAAC,KAAK,EAAC,EAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YAC1H,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5C,sEAAsE;YACtE,oEAAoE;YACpE,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,cAAc,CAAC,KAAK,EAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC3G,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;YACrH,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC,qBAAqB,CAAC,IAAI,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,EAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC;YACrF,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;YACnJ,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,CAAC,YAAY,KAAG,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,OAAO,KAAG,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,KAAG,OAAO,CAAC,EAAE,CAAC;gBAChK,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;YACpG,CAAC;YACD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAC,IAAI,GAAC,KAAK,CAAC,IAAI,GAAC,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;YACrE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,SAAS,GAAC,EAAE,CAAC;YAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,SAAS,GAAC,EAAE,CAAC;YAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,SAAS,GAAC,GAAG,CAAC;YAC1F,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC;YAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAC,SAAS,CAAC,CAAC;YAChF,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACrF,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,EAAC,IAAI,CAAC,CAAC,EAAC,IAAI,CAAC,CAAC,CAAC,EAAC,UAAU,EAAC,KAAK,EAAC,IAAI,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5C,wEAAwE;YACxE,gEAAgE;YAChE,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,CAAC,EAAE,KAAG,IAAI,CAAC,SAAS,CAAE,CAAC;YAC/E,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,CAAC,EAAE,KAAG,IAAI,CAAC,UAAU,CAAE,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,GAAC,MAAM,CAAC,MAAM,CAAC,GAAW,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,KAAa,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;YACzJ,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAC,GAAG,CAAC,MAAM,CAAC,GAAC,IAAI,GAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC/E,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,GAAC,IAAI,GAAC,KAAK,CAAC,IAAI,GAAC,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,KAAK,GAAC,GAAG,CAAC;YACnF,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,GAAC,IAAI,GAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC9D,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,GAAC,CAAC,EAAC,CAAC,GAAG,GAAC,IAAI,CAAC,GAAC,CAAC,EAAC,CAAC,MAAM,CAAC,CAAC,GAAC,IAAI,CAAC,GAAC,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC/G,GAAG,CAAC,IAAI,WAAW,CAAC,KAAK,EAAC,IAAI,GAAC,GAAG,EAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAC,IAAI,CAAC,EAAC,UAAU,EAAC,QAAQ,EAAC,IAAI,CAAC,CAAC;QACxF,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAE,CAAC;YACnC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1C,GAAG,CAAC,IAAI,gBAAgB,CAAC,MAAM,EAAC,MAAM,EAAC,MAAM,EAAC,EAAE,CAAC,EAAC,MAAM,EAAC,IAAI,UAAU,EAAE,CAAC,kBAAkB,CAAC,EAAE,EAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAC,IAAI,EAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC3L,CAAC;IACH,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,CAAC,UAAU,KAAG,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,QAAQ,EAAE,SAAS,IAAI,QAAQ,CAAC;QACtG,uEAAuE;QACvE,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAAE,SAAS;QAC5E,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,CAAC,UAAU,KAAG,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC,YAAY,KAAG,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9F,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA,EAAE,CAAA,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAC,CAAC,GAAG,IAAI;YAC5E,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAC,IAAI;gBACrC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAC,IAAI,EAAC,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA,EAAE,CAAA,CAAC,CAAC,SAAS,KAAG,MAAM,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA,EAAE,CAAA,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAC,CAAC,GAAC,IAAI,CAAC;QAC/K,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QAC1G,GAAG,CAAC,IAAI,cAAc,CAAC,MAAM,EAAC,EAAE,EAAC,EAAE,CAAC,EAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAC,EAAC,OAAO,EAAC,KAAK,CAAC,EAAE,EAAC,SAAS,EAAC,IAAI,EAAC,EAAC,KAAK,CAAC,CAAC;IAClI,CAAC;IACD,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { Matrix4, Quaternion, Vector3 } from "three";
2
+ import type { SpatialBone, SpatialCharacter, SpatialJoint } from "./types.ts";
3
+ export declare const SPATIAL_FINGERS: readonly ["thumb", "index", "middle", "ring", "little"];
4
+ export type SpatialFinger = typeof SPATIAL_FINGERS[number];
5
+ export declare function fingerPart(part: string): {
6
+ side: string;
7
+ finger: SpatialFinger;
8
+ segment: number;
9
+ } | null;
10
+ export declare const isHandPart: (part: string) => boolean;
11
+ export declare const handRig: (actor: SpatialCharacter) => {
12
+ height: number;
13
+ bottom: number;
14
+ parts: {
15
+ id: string;
16
+ start: number[];
17
+ end: number[];
18
+ }[];
19
+ };
20
+ /** Correct only untouched defaults once, keeping stored angles and custom bounds. */
21
+ export declare function completeThumbLimits(actor: SpatialCharacter): void;
22
+ export declare function owningHand(actor: SpatialCharacter, bone: SpatialBone): SpatialBone | undefined;
23
+ /** Linear source-to-rest map shared by the palm, finger offsets and skin. */
24
+ export declare function handRestMatrix(actor: SpatialCharacter, hand: SpatialBone, shaped?: boolean): Matrix4;
25
+ /** Palm size sets thickness; a separate axial factor sets digit length. */
26
+ export declare function fingerRestMatrix(actor: SpatialCharacter, hand: SpatialBone, modelPart: string): Matrix4;
27
+ /** Finger angles use anatomical hinge axes, expressed in the parent's rest frame. */
28
+ export declare function fingerBasis(actor: SpatialCharacter, bone: SpatialBone): Quaternion;
29
+ export declare function fingerOffset(actor: SpatialCharacter, joint: SpatialJoint, hand: SpatialBone): Vector3;
30
+ export declare function handJointIds(actor: SpatialCharacter, hand: SpatialBone): Set<string>;
31
+ /** Add the source's five chains to a palm, including a fixed attachment per digit. */
32
+ export declare function appendFingers(actor: SpatialCharacter, hand: SpatialBone): void;
33
+ /** Complete only the current v2 Quaternius palm data; no retired model support. */
34
+ export declare function completeCharacterHands(actor: SpatialCharacter): void;
35
+ export declare const fingerCurlAngles: (finger: SpatialFinger) => number[];
36
+ export declare const fingerSpreadAngles: Record<SpatialFinger, number>;
@@ -0,0 +1,128 @@
1
+ import { Matrix4, Quaternion, Vector3 } from "three";
2
+ import maleRig from "./assets/quaternius-rig.json" with { type: "json" };
3
+ import femaleRig from "./assets/quaternius-female-rig.json" with { type: "json" };
4
+ import { spatialShape } from "./proportions.js";
5
+ export const SPATIAL_FINGERS = ["thumb", "index", "middle", "ring", "little"];
6
+ export function fingerPart(part) {
7
+ const match = /^(left|right)-(thumb|index|middle|ring|little)-([0-3])$/.exec(part);
8
+ return match ? { side: match[1], finger: match[2], segment: Number(match[3]) } : null;
9
+ }
10
+ export const isHandPart = (part) => part.endsWith("-hand") || Boolean(fingerPart(part));
11
+ export const handRig = (actor) => actor.bodyType === "female" ? femaleRig : maleRig;
12
+ function thumbLimits(side, segment) {
13
+ return segment === 2 ? { min: [0, 0, -45], max: [110, 0, 45] }
14
+ : { min: [0, 0, side === "left" ? -90 : 0], max: [0, 0, side === "left" ? 0 : 90] };
15
+ }
16
+ /** Correct only untouched defaults once, keeping stored angles and custom bounds. */
17
+ export function completeThumbLimits(actor) {
18
+ if (actor.thumbLimitsVersion === 2)
19
+ return;
20
+ for (const bone of actor.bones) {
21
+ const part = fingerPart(bone.modelPart);
22
+ if (part?.finger !== "thumb" || part.segment < 2)
23
+ continue;
24
+ const oldMax = [part.segment === 2 ? 110 : 90, 0, 0];
25
+ if (!bone.limits.min.every(v => v === 0) || !bone.limits.max.every((v, i) => v === oldMax[i]))
26
+ continue;
27
+ // Invalid stored angles must still fail validation, rather than widening
28
+ // the corrected limits to accommodate malformed input.
29
+ if ([bone.rotation, bone.restRotation].some(values => values.some((v, i) => v < 0 || v > oldMax[i])))
30
+ continue;
31
+ bone.limits = thumbLimits(part.side, part.segment);
32
+ if (part.segment === 3)
33
+ bone.limits.max[0] = Math.max(bone.rotation[0], bone.restRotation[0]);
34
+ }
35
+ actor.thumbLimitsVersion = 2;
36
+ }
37
+ export function owningHand(actor, bone) {
38
+ let current = bone;
39
+ while (current) {
40
+ if (current.modelPart.endsWith("-hand"))
41
+ return current;
42
+ current = actor.bones.find(b => b.endJointId === current.startJointId);
43
+ }
44
+ }
45
+ /** Linear source-to-rest map shared by the palm, finger offsets and skin. */
46
+ export function handRestMatrix(actor, hand, shaped = true) {
47
+ const rig = handRig(actor), source = rig.parts.find(p => p.id === hand.modelPart);
48
+ const direction = new Vector3(...source.end).sub(new Vector3(...source.start));
49
+ const offset = new Vector3(...actor.joints.find(j => j.id === hand.endJointId).offset);
50
+ const scale = offset.length() / direction.length(), shape = spatialShape(actor.headRatio);
51
+ const palmSize = shaped ? actor.palmSize ?? 1 : 1;
52
+ const width = shaped ? actor.height / rig.height * shape.hand * palmSize : scale;
53
+ const up = new Vector3(0, 1, 0);
54
+ return new Matrix4().compose(new Vector3(), new Quaternion().setFromUnitVectors(up, offset.normalize()), new Vector3(width, scale * (shaped ? shape.handLength : 1) * palmSize, width))
55
+ .multiply(new Matrix4().makeRotationFromQuaternion(new Quaternion().setFromUnitVectors(up, direction.normalize()).invert()));
56
+ }
57
+ /** Palm size sets thickness; a separate axial factor sets digit length. */
58
+ export function fingerRestMatrix(actor, hand, modelPart) {
59
+ const rest = handRestMatrix(actor, hand);
60
+ if (fingerPart(modelPart)?.segment === 0 || (actor.fingerLength ?? 1) === (actor.palmSize ?? 1))
61
+ return rest;
62
+ const part = handRig(actor).parts.find(p => p.id === modelPart);
63
+ const direction = new Vector3(...part.end).sub(new Vector3(...part.start)).normalize();
64
+ const frame = new Matrix4().makeRotationFromQuaternion(new Quaternion().setFromUnitVectors(new Vector3(0, 1, 0), direction));
65
+ return rest.multiply(frame).multiply(new Matrix4().makeScale(1, (actor.fingerLength ?? 1) / (actor.palmSize ?? 1), 1)).multiply(frame.clone().invert());
66
+ }
67
+ /** Finger angles use anatomical hinge axes, expressed in the parent's rest frame. */
68
+ export function fingerBasis(actor, bone) {
69
+ const finger = fingerPart(bone.modelPart), hand = finger && owningHand(actor, bone);
70
+ if (!finger || !hand || finger.segment === 0)
71
+ return new Quaternion();
72
+ const part = handRig(actor).parts.find(p => p.id === bone.modelPart);
73
+ const y = new Vector3(...part.end).sub(new Vector3(...part.start)).normalize();
74
+ const x = y.clone().cross(new Vector3(0, -1, 0)).normalize(), z = x.clone().cross(y).normalize();
75
+ const rest = handRestMatrix(actor, hand, false);
76
+ return new Quaternion().setFromRotationMatrix(new Matrix4().makeBasis(x.transformDirection(rest), y.transformDirection(rest), z.transformDirection(rest)));
77
+ }
78
+ export function fingerOffset(actor, joint, hand) {
79
+ const part = actor.bones.find(b => b.endJointId === joint.id).modelPart;
80
+ const map = fingerRestMatrix(actor, hand, part).multiply(handRestMatrix(actor, hand, false).invert());
81
+ return new Vector3(...joint.offset).applyMatrix4(map);
82
+ }
83
+ export function handJointIds(actor, hand) {
84
+ const ids = new Set([hand.endJointId]);
85
+ for (const id of ids)
86
+ for (const joint of actor.joints.filter(j => j.parentId === id))
87
+ ids.add(joint.id);
88
+ return ids;
89
+ }
90
+ /** Add the source's five chains to a palm, including a fixed attachment per digit. */
91
+ export function appendFingers(actor, hand) {
92
+ const rig = handRig(actor), rest = handRestMatrix(actor, hand, false);
93
+ const prefix = hand.id.endsWith(hand.modelPart) ? hand.id.slice(0, -hand.modelPart.length) : `${hand.id}-`;
94
+ const side = hand.modelPart.startsWith("left") ? "left" : "right";
95
+ for (const finger of SPATIAL_FINGERS)
96
+ for (let segment = 0; segment < 4; segment++) {
97
+ const modelPart = `${side}-${finger}-${segment}`, id = `${prefix}${modelPart}`;
98
+ const source = rig.parts.find(p => p.id === modelPart);
99
+ const parentId = segment ? `${prefix}${side}-${finger}-${segment - 1}` : hand.endJointId;
100
+ const offset = new Vector3(...source.end).sub(new Vector3(...source.start)).applyMatrix4(rest).toArray();
101
+ const min = segment === 0 ? [0, 0, 0] : segment === 1 ? [-10, finger === "thumb" ? -70 : 0, finger === "thumb" ? -35 : -20] : [0, 0, 0];
102
+ const max = segment === 0 ? [0, 0, 0] : segment === 1 ? [95, finger === "thumb" ? 70 : 0, finger === "thumb" ? 35 : 20] : [segment === 2 ? 110 : 90, 0, 0];
103
+ actor.joints.push({ id, name: id, parentId, offset, radius: actor.height * .004, terminal: segment === 3, lockPosition: false });
104
+ const limits = finger === "thumb" && segment >= 2 ? thumbLimits(side, segment) : { min, max };
105
+ actor.bones.push({ id, name: id, startJointId: parentId, endJointId: id, rotation: [0, 0, 0], restRotation: [0, 0, 0], limits, lockRotation: false, modelPart });
106
+ }
107
+ }
108
+ /** Complete only the current v2 Quaternius palm data; no retired model support. */
109
+ export function completeCharacterHands(actor) {
110
+ for (const hand of actor.bones.filter(b => b.modelPart === "left-hand" || b.modelPart === "right-hand")) {
111
+ const end = actor.joints.find(j => j.id === hand.endJointId);
112
+ if (!end?.terminal || actor.joints.some(j => j.parentId === end.id))
113
+ continue;
114
+ end.offset = end.offset.map(v => v * .35);
115
+ end.terminal = false;
116
+ end.radius = actor.height * .01;
117
+ const pinnedTip = end.lockPosition;
118
+ end.lockPosition = false;
119
+ appendFingers(actor, hand);
120
+ if (pinnedTip) {
121
+ const tip = actor.bones.find(b => b.modelPart === hand.modelPart.replace("hand", "middle-3") && handJointIds(actor, hand).has(b.endJointId));
122
+ actor.joints.find(j => j.id === tip.endJointId).lockPosition = true;
123
+ }
124
+ }
125
+ }
126
+ export const fingerCurlAngles = (finger) => finger === "thumb" ? [35, 50, 55] : [70, 95, 65];
127
+ export const fingerSpreadAngles = { thumb: 0, index: 16, middle: 4, ring: -7, little: -18 };
128
+ //# sourceMappingURL=hands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hands.js","sourceRoot":"","sources":["../../../src/domain/spatial/hands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { SpatialCamera, SpatialCharacter, SpatialDraft, SpatialBodyType, SpatialOperation } from "./types.ts";
2
+ export * from "./types.ts";
3
+ export * from "./kinematics.ts";
4
+ export * from "./hands.ts";
5
+ export { BODY_SHAPE_LIMITS } from "./proportions.ts";
6
+ import type { SpatialAppearance, SpatialBodyShape } from "./types.ts";
7
+ export * from "./camera-box.ts";
8
+ export declare const TORSO_RATIO_LIMITS: {
9
+ readonly min: 0.3;
10
+ readonly max: 0.7;
11
+ };
12
+ export declare const DEFAULT_TORSO_RATIO: number;
13
+ export declare class SpatialConstraintError extends Error {
14
+ readonly code = "SPATIAL_CONSTRAINT";
15
+ }
16
+ export declare function createSpatialCamera(id?: string, name?: string): SpatialCamera;
17
+ export declare function createSpatialDraft(): SpatialDraft;
18
+ export declare function createHumanoid(id: string, name: string, height?: number, headRatio?: number, torsoRatio?: number, bodyType?: SpatialBodyType, bodyShape?: SpatialBodyShape & {
19
+ appearance?: SpatialAppearance;
20
+ }): SpatialCharacter;
21
+ export declare function validateSpatialDraft(input: unknown): SpatialDraft;
22
+ export declare function validateSpatialTransition(before: SpatialDraft, after: SpatialDraft, options?: {
23
+ allowLimitChanges?: boolean;
24
+ resetPoseCharacterId?: string;
25
+ }): void;
26
+ export declare function spatialDraftFingerprint(input: SpatialDraft): string;
27
+ export declare function applySpatialOperations(input: SpatialDraft, operations: SpatialOperation[]): {
28
+ draft: SpatialDraft;
29
+ constrained: boolean;
30
+ };