Skip to content

Commit d5dad7a

Browse files
committed
cockpit/torso: anisotropic surface-fit splat + per-node SoA + /torso-map
The structural upgrade you greenlit: the torso splat stops being a detached isotropic point cloud and becomes the GUID/value-tenant substrate seen as oriented geometry. One pass over the BodyParts3D meshes does all of it. SPL2 format (supersedes SPL1): hdr 40B [SPL2|count|node_count|radius|bbox]; body 21B [pos 3f | normal 3i8 | rgb 3u8 | opacity u8 | node_row u16]. Helix- orderable + residual-ready (the Helix-48 codec slots in here next). - Anisotropic surface-fit ("connect the dots"): BodyParts3D OBJ ships per-vertex normals (vn) — free, no face traversal. The splat3d render driver orients each gaussian flat-to-surface (scale=[t,t,thin], quat aligns local-z to the normal); tangent 0.004 connects within a structure while rib gaps stay visible. Oriented disks blend into continuous surfaces with real 3D form — not isotropic blobs, not a discrete voxel grid. - Per-node SoA + O(1) switch (the GUID backbone): torso.nodes.json = one row per FMA structure (178 rows, 91 own meshes) carrying the value-tenants of one identity — fma id, name, depth, HHTL tier-ranks, colour, gaussian RANGE (start+count), and the OBJ-geometry tenant (centroid+bbox+FJ handles). Each gaussian carries its node_row; consumers build the switch (row->node) once -> O(1) tenant reads. Position = real BodyParts3D coordinate; identity = FMA node. - /torso-map (TorsoMap.tsx): click a gaussian -> node_row -> O(1) into the SoA -> FMA label + partonomy breadcrumb; structure list highlights its gaussians (graph <-> splat). The osint-cad-splat thesis made literal: graph and splat, one node at one address, switch-selected. - /torso-live decodes SPL2 (still points); /torso shows the re-rendered anisotropic turntable. main.tsx: /torso-map route. Verified by viewing the rendered frames (connected anatomical surfaces, upright, form from orientation). tsc clean; browser pick-interaction not exercised here (raycast-on-Points is standard). Geometry: BodyParts3D, CC-BY 4.0 / CC-BY-SA 2.1 JP, (c) The Database Center for Life Science (attribution in-view). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzqvDqbFRzyx17EkLKBoZF
1 parent 1400f6d commit d5dad7a

28 files changed

Lines changed: 492 additions & 184 deletions

claude-notes/plans/2026-06-24-fma-torso-bodyparts3d-splat.md

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,31 @@ Notes:
6262
brush blobbed the detail into a "Warhol" look; 0.0025 at 810x1080 restores the
6363
ribcage/vertebrae). Frames re-rendered.
6464

65-
## Follow-ups (proposed, next PR)
65+
## Follow-up PR — anisotropic + GUID-tag + map (branch claude/torso-anisotropic-map)
6666

67-
The splat is currently isotropic spheres (no orientation) — too big = blobs,
68-
too small = disconnected dots. The real upgrade, in one pass over the meshes:
67+
- [x] **SPL2 format** (supersedes SPL1): hdr 40B [`SPL2`|count|node_count|radius|
68+
bbox]; body 21B [pos 3f | normal 3i8 | rgb 3u8 | opacity u8 | node_row u16].
69+
Helix-orderable + residual-ready (the codec PR slots in here).
70+
- [x] **Anisotropic surface-fit gaussians** ("connect the dots"): bake reads OBJ
71+
`vn` (BodyParts3D ships normals — free, no face traversal); render driver
72+
orients each gaussian flat-to-surface (`scale=[t,t,thin]`, `quat` aligns
73+
local-z to the normal). Tangent 0.004 connects within a structure while
74+
rib gaps stay visible. NOT voxels (continuous surfaces, not a discrete grid).
75+
- [x] **Per-node SoA + O(1) switch** (the GUID/value-tenant backbone): bake emits
76+
`torso.nodes.json` — one row per FMA structure (178 rows, 91 own meshes):
77+
fma id, name, depth, HHTL tier-ranks, colour, gaussian RANGE (start+count),
78+
OBJ-geometry tenant (centroid + bbox + FJ handles). Each gaussian carries
79+
its node_row. Consumers build the switch (row -> node) once -> O(1) tenant
80+
reads. Position = real BodyParts3D coordinate; identity = the FMA node.
81+
- [x] **/torso-map page**: click a gaussian -> node_row -> node SoA -> FMA label +
82+
partonomy breadcrumb; structure list (graph -> splat) highlights gaussians.
83+
Realises the osint-cad-splat thesis: graph and splat, one node at one address.
84+
- [x] tsc clean. Browser pick-interaction not exercised here (raycast-on-Points
85+
logic is standard; geometry verified via the CPU frames).
6986

70-
- [ ] **Anisotropic surface-fit gaussians** ("connect the dots"): read OBJ
71-
*faces* (the bake currently drops them) -> per-vertex normals -> orient
72-
each gaussian flat-to-surface (`scale[3]` tangent-wide / normal-thin,
73-
`quat` from normal). splat3d's `Gaussian3D` already supports scale+quat;
74-
the three.js page needs a real splat shader (oriented quads). This is the
75-
"muscle memory of the nodes" — each gaussian inherits its shape from the
76-
structure it came from. NOT voxels (those are discrete/volumetric; these
77-
are continuous surfaces).
78-
- [ ] **Third "map FMA" view**: bake a per-gaussian FMA structure id + legend
79-
(idx -> FMA concept / name / colour) into SPL1, then pick-to-label in 3D
80-
and sync selection with the /fma-style partonomy graph. Realises the
81-
osint-cad-splat thesis: graph and splat are one node at one address, two
82-
payloads. Own page (/torso-map) vs folding labels into /torso-live: TBD
83-
with user.
87+
## Next PR — Helix-48 residue codec (queued)
88+
89+
Order gaussians along the helix (= Morton/Vogel identity order = GUID order),
90+
bake appearance into the 48 SH (shading vs flat — pending user), x265-style
91+
residual-code the SH along the curve. The asset byte-order becomes the node
92+
identity order, codec-compressed. SPL2 is laid out ready for it.
-6.3 KB
Loading
-6.55 KB
Loading
-7.02 KB
Loading
-7.58 KB
Loading
-7.43 KB
Loading
-7.29 KB
Loading
-6.45 KB
Loading
-5.54 KB
Loading
-4.9 KB
Loading

0 commit comments

Comments
 (0)