You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+6-2Lines changed: 6 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,6 +22,8 @@ Public API is **mirrored** across React and Vue. Adding a hook on one side witho
22
22
23
23
**One visible `Polygon` → one leaf DOM element.** Leaves use canonical CSS primitives where possible and move scale into `matrix3d`; `border-shape` uses a larger fixed primitive because its paint geometry becomes unstable when collapsed to 1px. Textured polygons still pack their local-2D bounding rect (`canvasW × canvasH`) into the atlas. The HTML tag *is* the render strategy — the renderer picks one tag per polygon based on its shape and material.
24
24
25
+
Raw MagicaVoxel `.vox` sources have a narrower baked-mode fast path: `parseVox` still returns the polygon mesh for bounds, fallback rendering, and public handles, but also preserves a `PolyVoxelSource`. Eligible vanilla meshes render that source through three axis hosts plus absolutely positioned rectangular brush leaves, using the voxcss `mergeVoxels: "3d"` slice planner rather than one `matrix3d` per polygon. `.vox` normalization snaps to the nearest integer CSS cell size so brush rectangles use integer pixel coordinates without any scale wrapper. Brush colors still receive baked Lambert shading from the scene lights. Dynamic lighting, shadows, stable DOM animation, and geometry replaced via `setPolygons` fall back to the polygon renderer.
26
+
25
27
Voxel-shaped meshes are the exception to "all polygons stay mounted": meshes with at most the six axis-aligned face normals, excluding helpers/auto-center-exempt meshes, automatically mount only camera-facing leaves and patch the mounted set when the camera or mesh rotation crosses a visible-normal boundary. Non-voxel meshes keep the full leaf DOM mounted; broad camera-dependent DOM culling is not worth the mutation cost.
26
28
27
29
### Tag-as-strategy table
@@ -38,12 +40,14 @@ Strategies are ordered cheapest → most expensive. The mesher's job is to maxim
38
40
39
41
Callers can opt out of specific strategies via `strategies: { disable: ["b" | "i" | "u"] }` on `RenderTextureAtlasOptions`. Disabled strategies fall through the chain (`b → i → s`, `u → i → s`, `i → s`). `<s>` is the universal fallback and cannot be disabled.
40
42
43
+
The voxel slice-brush fast path emits plain `<b>` quad elements inside axis hosts. They intentionally reuse the cheap quad tag, but they are absolutely positioned brush rectangles rather than polygon strategy leaves and do not use one `matrix3d` per polygon.
-**Baked.** Lambert is computed once on the CPU per polygon, multiplied into the inline `color` (for `<b>`/`<i>`/`<u>`) or into the rasterised atlas pixels (for `<s>`). Moving a light requires re-rasterising affected polys.
44
48
-**Dynamic.** Scene root carries the light setup as custom properties (`--plx/y/z`, `--plr/g/b`, `--pli`, `--par/g/b`, `--pai`). Each leaf embeds its surface normal (`--pnx/y/z`) and base color (`--psr/g/b`) inline. CSS `calc()` resolves the Lambert dot product and per-channel tint at paint time. Moving a light mutates one var on the scene root — zero JS, no atlas redraw.
45
49
46
-
All solid/atlas tags work in both modes. The full coverage matrix is in `packages/polycss/src/styles/styles.ts`.
50
+
All solid/atlas tags work in both modes. The `.vox` slice-brush fast path is baked-only for now; dynamic mode uses the polygon path so lighting semantics stay correct. The full coverage matrix is in `packages/polycss/src/styles/styles.ts`.
47
51
48
52
### Meshing implications (what generators must respect)
49
53
@@ -77,7 +81,7 @@ If you find yourself wanting a `requestAnimationFrame` loop to update many DOM n
-**HTML custom elements:**`poly-` prefix + kebab-case. Existing tags: `<poly-scene>`, `<poly-mesh>`, `<poly-polygon>`, `<poly-controls>`, `<poly-axes-helper>`, `<poly-directional-light-helper>`. Any new element follows the same shape (e.g. `<poly-perspective-camera>`, `<poly-transform-controls>`, `<poly-select>`).
83
87
-**Leaf DOM tags (`<b>`, `<i>`, `<s>`, `<u>`):** internal render-strategy tags. Not part of the public API and not user-facing — do not document them as such.
|`parseObj(text, options?)`| Parses OBJ text into `ParseResult`. Supports UV (`vt`), materials, `map_Kd` textures. |
54
54
|`parseMtl(text)`| Parses MTL text into `{ colors, textures }`. |
55
55
|`parseGltf(buffer, options?)`| Parses GLB or glTF `ArrayBuffer` into `ParseResult`. Extracts embedded textures as blob URLs. |
56
-
|`parseVox(buffer, options?)`| Parses MagicaVoxel `.vox``ArrayBuffer` into `ParseResult`. Face-culls interior voxel faces and fan-triangulates exposed quads. |
56
+
|`parseVox(buffer, options?)`| Parses MagicaVoxel `.vox``ArrayBuffer` into `ParseResult`. Face-culls interior voxel faces and fan-triangulates exposed quads. `targetSize` snaps to integer voxel CSS cells for the slice-brush renderer. |
57
57
|`loadMesh(url, options?)`| Fetches a URL, dispatches to the right parser by extension (`.obj`, `.glb`, `.gltf`, `.vox`). Returns `Promise<ParseResult>` and defaults to `meshResolution: "lossy"`. |
58
58
|`parseColor(input)`| Parse any CSS color string to `{ r, g, b, a }`. |
59
59
|`shadeColor(input, lambert, ...)`| Apply Lambert shading factor to a color. |
0 commit comments