@layoutit/polycss-core 0.0.1 → 0.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.
- package/README.md +25 -2
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +339 -3
- package/dist/index.d.ts +339 -3
- package/dist/index.js +3 -3
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,14 @@ declare const DEFAULT_PROJECTION: "cubic";
|
|
|
11
11
|
* variables, no JS work, no atlas re-rasterization.
|
|
12
12
|
*/
|
|
13
13
|
type PolyTextureLightingMode = "baked" | "dynamic";
|
|
14
|
+
/**
|
|
15
|
+
* Mesh post-processing intent.
|
|
16
|
+
* - "lossless": preserve the authored surface while applying exact
|
|
17
|
+
* reductions such as interior culling and coplanar merge.
|
|
18
|
+
* - "lossy": allow bounded geometric approximation when it reduces the
|
|
19
|
+
* rendered polygon/DOM count.
|
|
20
|
+
*/
|
|
21
|
+
type MeshResolution = "lossless" | "lossy";
|
|
14
22
|
/**
|
|
15
23
|
* 3D point/vector, stored as a `[x, y, z]` tuple. Tuple (rather than
|
|
16
24
|
* `{x, y, z}`) for compact JSON: meshes serialize to thousands of vertices
|
|
@@ -280,6 +288,51 @@ declare function rotateVec3(v: Vec3, rxDeg: number, ryDeg: number, rzDeg: number
|
|
|
280
288
|
*/
|
|
281
289
|
declare function inverseRotateVec3(v: Vec3, rot: Vec3): Vec3;
|
|
282
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Minimal quaternion helpers for composing rotations.
|
|
293
|
+
*
|
|
294
|
+
* Why we need quaternions: the public PolyMesh API exposes rotation as a
|
|
295
|
+
* Euler triple `[rx, ry, rz]` in degrees (drives CSS `rotateX rotateY
|
|
296
|
+
* rotateZ`, applied right-to-left). Euler triples don't compose by
|
|
297
|
+
* component addition — rotating Y after X must happen around the mesh's
|
|
298
|
+
* NEW local-Y axis, not world-Y. The transform-controls ring drag handler
|
|
299
|
+
* uses these helpers to compose around the mesh's local axis correctly:
|
|
300
|
+
*
|
|
301
|
+
* q_start = quatFromEulerXYZ(currentRotationDeg)
|
|
302
|
+
* q_delta = quatFromAxisAngle(localAxis, deltaRadians)
|
|
303
|
+
* q_new = quatMultiply(q_start, q_delta) // RIGHT-multiply = local frame
|
|
304
|
+
* next = eulerXYZFromQuat(q_new)
|
|
305
|
+
*
|
|
306
|
+
* Convention: "XYZ" Euler means the composed rotation matrix is
|
|
307
|
+
* `Rx(rx) · Ry(ry) · Rz(rz)`, which matches CSS `rotateX rotateY rotateZ`
|
|
308
|
+
* (right-to-left application to a point ⇒ Z first, then Y, then X).
|
|
309
|
+
*
|
|
310
|
+
* Quaternion format: `[w, x, y, z]` (real-first, like three.js's internal
|
|
311
|
+
* `_x/_y/_z/_w` reordered). Stored as plain tuples — no constructor or
|
|
312
|
+
* runtime allocations per drag.
|
|
313
|
+
*/
|
|
314
|
+
|
|
315
|
+
/** Quaternion `[w, x, y, z]`, real component first. Unit-length is not
|
|
316
|
+
* enforced by the type — callers normalize when needed. */
|
|
317
|
+
type Quat = [number, number, number, number];
|
|
318
|
+
/** Identity quaternion. */
|
|
319
|
+
declare const QUAT_IDENTITY: Quat;
|
|
320
|
+
/** Hamilton product `q1 * q2`. Apply to a vector as `q v q⁻¹`. Right-
|
|
321
|
+
* multiplication composes the second rotation in the LOCAL frame of the
|
|
322
|
+
* first — that's the property the gizmo relies on for local-axis drag. */
|
|
323
|
+
declare function quatMultiply(q1: Quat, q2: Quat): Quat;
|
|
324
|
+
/** Quaternion from axis-angle. `axis` must be unit length (caller's
|
|
325
|
+
* responsibility — typically a CSS basis vector). `angleRad` in radians. */
|
|
326
|
+
declare function quatFromAxisAngle(axis: Vec3, angleRad: number): Quat;
|
|
327
|
+
/** Quaternion from Euler XYZ degrees — the order CSS `rotateX rotateY
|
|
328
|
+
* rotateZ` applies. Matches the composed matrix `Rx(rx)·Ry(ry)·Rz(rz)`. */
|
|
329
|
+
declare function quatFromEulerXYZ(eulerDeg: Vec3): Quat;
|
|
330
|
+
/** Euler XYZ degrees from a quaternion — inverse of `quatFromEulerXYZ`.
|
|
331
|
+
* Handles gimbal lock (|ry| → 90°) by collapsing rz onto rx. The output
|
|
332
|
+
* matches the convention used by CSS `rotateX rotateY rotateZ` so it can
|
|
333
|
+
* be written straight back into a PolyMesh rotation prop. */
|
|
334
|
+
declare function eulerXYZFromQuat(q: Quat): Vec3;
|
|
335
|
+
|
|
283
336
|
/**
|
|
284
337
|
* Base tile size in CSS pixels. One polycss world unit = BASE_TILE CSS
|
|
285
338
|
* pixels (pre-scale). Used to convert world-coordinate target values to
|
|
@@ -394,6 +447,82 @@ declare function computeShapeLighting(normal: Vec3, baseColor: string, direction
|
|
|
394
447
|
|
|
395
448
|
declare function mergePolygons(input: Polygon[]): Polygon[];
|
|
396
449
|
|
|
450
|
+
/**
|
|
451
|
+
* dedupeOverlappingPolygons — drop polygons whose 3D footprint coincides
|
|
452
|
+
* with another polygon's, within an epsilon tolerance.
|
|
453
|
+
*
|
|
454
|
+
* Why this exists: modelers (and importers) often emit redundant geometry
|
|
455
|
+
* for the same visible surface — a doubled face on a wall, an inner shell
|
|
456
|
+
* coincident with an outer shell, or two N-gons that fan-triangulate the
|
|
457
|
+
* same region. Each duplicate is a real `<i>` element at render time:
|
|
458
|
+
* it costs DOM, Lambert math, atlas budget, AND it produces stacked
|
|
459
|
+
* shadow leaves that visibly multiply on the receiver (overlapping dark
|
|
460
|
+
* patches on the ground).
|
|
461
|
+
*
|
|
462
|
+
* This is a separate concern from `cullInteriorPolygons` (which removes
|
|
463
|
+
* polygons fully *enclosed* by other geometry, conservative against
|
|
464
|
+
* false positives) and from `mergePolygons` (which joins same-color
|
|
465
|
+
* coplanar polygons that share an edge). A polygon's exact twin
|
|
466
|
+
* doesn't share an edge with itself and isn't enclosed by anything —
|
|
467
|
+
* it slips through both passes.
|
|
468
|
+
*
|
|
469
|
+
* Algorithm:
|
|
470
|
+
* 1. Compute each polygon's plane (normal + signed offset along
|
|
471
|
+
* normal) and centroid.
|
|
472
|
+
* 2. Bucket polygons by quantized plane key (rounded normal direction
|
|
473
|
+
* with sign-folding so anti-parallel faces share a bucket, and
|
|
474
|
+
* rounded distance from origin along the unsigned normal axis).
|
|
475
|
+
* Polygons in different buckets cannot overlap.
|
|
476
|
+
* 3. Within each bucket, do an O(K²) pairwise check on at most K
|
|
477
|
+
* polygons. Two polygons overlap if their 2D projections onto
|
|
478
|
+
* the shared plane share a significant area fraction.
|
|
479
|
+
* 4. When a pair overlaps, drop one: prefer keeping the one whose
|
|
480
|
+
* normal points *away* from the mesh centroid (the "outward"
|
|
481
|
+
* face). For ties (truly identical orientation), keep the one
|
|
482
|
+
* with greater 2D area.
|
|
483
|
+
*
|
|
484
|
+
* Runs once at parse time in the same pipeline as mergePolygons. Zero
|
|
485
|
+
* cost at runtime — once it returns the polygon array is final and the
|
|
486
|
+
* dedup logic never executes again.
|
|
487
|
+
*/
|
|
488
|
+
|
|
489
|
+
/** Tunable thresholds. Default values are conservative — only catch
|
|
490
|
+
* duplicates that are visually identical surfaces (exact twins,
|
|
491
|
+
* back-to-back winding flips, nested polys on the same plane).
|
|
492
|
+
* Looser values are appropriate for shadow-casting purposes, where
|
|
493
|
+
* any polygons whose projections land in the same place can share a
|
|
494
|
+
* shadow without affecting the rendered model. */
|
|
495
|
+
interface DedupeOverlappingPolygonsOptions {
|
|
496
|
+
/** Maximum 1 - |dot(n_a, n_b)| for normals to count as "parallel".
|
|
497
|
+
* Default 1e-3 (strict — must be near-identical orientation).
|
|
498
|
+
* Looser values (~5e-2 ≈ 18° off) treat near-parallel normals as
|
|
499
|
+
* duplicates, useful for shadow dedup where small orientation
|
|
500
|
+
* differences project to nearly the same shadow shape. */
|
|
501
|
+
normalTolerance?: number;
|
|
502
|
+
/** Maximum signed-distance difference between two polygons' plane
|
|
503
|
+
* offsets (along their shared normal) to count as coplanar.
|
|
504
|
+
* Default 0.05 (world units). Looser values treat distinct
|
|
505
|
+
* parallel shells (e.g. an inner cavity wall behind an outer
|
|
506
|
+
* wall) as shadow-duplicates. */
|
|
507
|
+
distanceTolerance?: number;
|
|
508
|
+
/** Minimum overlap fraction (max of A-in-B and B-in-A vertex
|
|
509
|
+
* containment ratios) for a pair to count as a duplicate.
|
|
510
|
+
* Default 0.7. Lower (~0.4) is liberal; higher (~0.9) is strict. */
|
|
511
|
+
overlapFraction?: number;
|
|
512
|
+
}
|
|
513
|
+
/** Identify polygons that are duplicates within tolerance. Returns the
|
|
514
|
+
* set of indices into the input array that should be dropped (the
|
|
515
|
+
* losers of duplicate pairs). The "winner" of a pair is the polygon
|
|
516
|
+
* whose normal faces away from the mesh centroid (outward), with
|
|
517
|
+
* larger area as a tiebreaker.
|
|
518
|
+
*
|
|
519
|
+
* Exposed for callers that want to act on the index set directly —
|
|
520
|
+
* e.g. shadow casting can use a looser tolerance to skip shadow leaves
|
|
521
|
+
* for redundant casters without removing them from the renderable
|
|
522
|
+
* polygon set. */
|
|
523
|
+
declare function findOverlappingPolygonDuplicates(input: Polygon[], options?: DedupeOverlappingPolygonsOptions): Set<number>;
|
|
524
|
+
declare function dedupeOverlappingPolygons(input: Polygon[], options?: DedupeOverlappingPolygonsOptions): Polygon[];
|
|
525
|
+
|
|
397
526
|
interface CoverPlanarPolygonsOptions {
|
|
398
527
|
/** Smallest connected coplanar group worth attempting. Default 4. */
|
|
399
528
|
minGroupPolygons?: number;
|
|
@@ -413,6 +542,30 @@ interface CoverPlanarPolygonsOptions {
|
|
|
413
542
|
*/
|
|
414
543
|
declare function coverPlanarPolygons(input: Polygon[], options?: CoverPlanarPolygonsOptions): Polygon[];
|
|
415
544
|
|
|
545
|
+
interface ApproximateMergeOptions {
|
|
546
|
+
maxAngleDeg?: number;
|
|
547
|
+
maxPlaneDisplacement?: number;
|
|
548
|
+
maxBoundaryDisplacement?: number;
|
|
549
|
+
isolatedPairs?: boolean;
|
|
550
|
+
}
|
|
551
|
+
interface OptimizeMeshPolygonsOptions {
|
|
552
|
+
/** Public quality/resolution intent. Defaults to "lossy". */
|
|
553
|
+
meshResolution?: MeshResolution;
|
|
554
|
+
/**
|
|
555
|
+
* Run the planar cover pass as an exact candidate for untextured coplanar
|
|
556
|
+
* regions. Defaults to true.
|
|
557
|
+
*/
|
|
558
|
+
rectCover?: boolean | CoverPlanarPolygonsOptions;
|
|
559
|
+
/**
|
|
560
|
+
* Lossy approximate merge settings. Ignored for lossless resolution.
|
|
561
|
+
* When omitted, lossy evaluates isolated-pair and small plane-group
|
|
562
|
+
* strategies, then chooses the lowest render-cost result with a near-cost
|
|
563
|
+
* preference for candidates that reduce detected internal gaps.
|
|
564
|
+
*/
|
|
565
|
+
approximateMerge?: boolean | ApproximateMergeOptions;
|
|
566
|
+
}
|
|
567
|
+
declare function optimizeMeshPolygons(polygons: Polygon[], options?: OptimizeMeshPolygonsOptions): Polygon[];
|
|
568
|
+
|
|
416
569
|
/**
|
|
417
570
|
* cullInteriorPolygons — remove polygons that are fully enclosed by other
|
|
418
571
|
* polygons of the same mesh and therefore never visible from any external
|
|
@@ -440,6 +593,29 @@ interface CullInteriorOptions {
|
|
|
440
593
|
}
|
|
441
594
|
declare function cullInteriorPolygons(polygons: Polygon[], options?: CullInteriorOptions): Polygon[];
|
|
442
595
|
|
|
596
|
+
declare const CAMERA_BACKFACE_CULL_EPS = 0.00001;
|
|
597
|
+
declare const VOXEL_CAMERA_CULL_AXIS_EPS = 0.001;
|
|
598
|
+
declare const VOXEL_CAMERA_CULL_NORMAL_LIMIT = 6;
|
|
599
|
+
interface CameraCullRotation {
|
|
600
|
+
rotX: number;
|
|
601
|
+
rotY: number;
|
|
602
|
+
meshRotation?: Vec3;
|
|
603
|
+
}
|
|
604
|
+
interface CameraCullNormalGroup {
|
|
605
|
+
key: string;
|
|
606
|
+
normal: Vec3;
|
|
607
|
+
}
|
|
608
|
+
declare function polygonCssSurfaceNormal(polygon: Polygon): Vec3 | null;
|
|
609
|
+
declare function cameraFacingDepth(normal: Vec3, rotation: CameraCullRotation): number;
|
|
610
|
+
declare function normalFacesCamera(normal: Vec3, rotation: CameraCullRotation, depthThreshold?: number): boolean;
|
|
611
|
+
declare function polygonFacesCamera(polygon: Polygon, rotation: CameraCullRotation, depthThreshold?: number): boolean;
|
|
612
|
+
declare function cameraCullNormalKey(normal: Vec3): string;
|
|
613
|
+
declare function cameraCullNormalGroups(normals: Iterable<Vec3 | null | undefined>): CameraCullNormalGroup[];
|
|
614
|
+
declare function cameraCullNormalGroupsFromPolygons(polygons: readonly Polygon[]): CameraCullNormalGroup[];
|
|
615
|
+
declare function isAxisAlignedSurfaceNormal(normal: Vec3, axisEpsilon?: number): boolean;
|
|
616
|
+
declare function isVoxelCameraCullableNormalGroups(groups: readonly CameraCullNormalGroup[]): boolean;
|
|
617
|
+
declare function cameraCullVisibleSignature(groups: readonly CameraCullNormalGroup[], rotation: CameraCullRotation, depthThreshold?: number): string;
|
|
618
|
+
|
|
443
619
|
/**
|
|
444
620
|
* Geometry for the three.js-style debug axes gizmo: three thin colored
|
|
445
621
|
* cuboids stretching along world-X, world-Y and world-Z. Mirrors the
|
|
@@ -471,6 +647,30 @@ interface AxesHelperOptions {
|
|
|
471
647
|
*/
|
|
472
648
|
declare function axesHelperPolygons(options?: AxesHelperOptions): Polygon[];
|
|
473
649
|
|
|
650
|
+
/**
|
|
651
|
+
* Axis-aligned box/cuboid geometry as six quad polygons.
|
|
652
|
+
*
|
|
653
|
+
* Returned polygons are in standard polycss world space:
|
|
654
|
+
* +X = right, +Y = front/forward, +Z = top/up.
|
|
655
|
+
*/
|
|
656
|
+
|
|
657
|
+
type BoxFace = "right" | "left" | "front" | "back" | "top" | "bottom";
|
|
658
|
+
type BoxFaceOptions = Pick<Polygon, "color" | "texture" | "material" | "uvs" | "data">;
|
|
659
|
+
interface BoxPolygonsOptions extends BoxFaceOptions {
|
|
660
|
+
/** Size along the world X/Y/Z axes. Defaults to a 1×1×1 cube. */
|
|
661
|
+
size?: number | Vec3;
|
|
662
|
+
/** Center used with `size`. Defaults to the origin. */
|
|
663
|
+
center?: Vec3;
|
|
664
|
+
/** Explicit minimum world-space corner. When set with `max`, bounds win over size/center. */
|
|
665
|
+
min?: Vec3;
|
|
666
|
+
/** Explicit maximum world-space corner. When set with `min`, bounds win over size/center. */
|
|
667
|
+
max?: Vec3;
|
|
668
|
+
/** Per-face material/data overrides. Set a face to `false` to omit it. */
|
|
669
|
+
faces?: Partial<Record<BoxFace, BoxFaceOptions | false>>;
|
|
670
|
+
}
|
|
671
|
+
/** Build the polygons for one axis-aligned box/cuboid. */
|
|
672
|
+
declare function boxPolygons(options?: BoxPolygonsOptions): Polygon[];
|
|
673
|
+
|
|
474
674
|
/**
|
|
475
675
|
* Geometry for a single 3D arrow: a thin axis-aligned cuboid shaft
|
|
476
676
|
* stretching from the origin along one signed axis, capped with a
|
|
@@ -497,6 +697,11 @@ interface ArrowPolygonsOptions {
|
|
|
497
697
|
headHalfThickness?: number;
|
|
498
698
|
/** Fill color. */
|
|
499
699
|
color?: string;
|
|
700
|
+
/** Emit the rectangular shaft polygons. Default `true`. Set `false` to
|
|
701
|
+
* render just the pyramid head — used by transform-control gizmos to
|
|
702
|
+
* declutter back-facing axes (only the head still identifies direction
|
|
703
|
+
* while the shaft would visually overlap the front-facing arrow). */
|
|
704
|
+
shaft?: boolean;
|
|
500
705
|
}
|
|
501
706
|
/** Build the polygons for one signed-axis arrow. */
|
|
502
707
|
declare function arrowPolygons(options: ArrowPolygonsOptions): Polygon[];
|
|
@@ -534,6 +739,66 @@ interface RingPolygonsOptions {
|
|
|
534
739
|
/** Build the polygons for a flat ring (annulus). */
|
|
535
740
|
declare function ringPolygons(options: RingPolygonsOptions): Polygon[];
|
|
536
741
|
|
|
742
|
+
/**
|
|
743
|
+
* One square quad covering the bounding box of a ring (annulus) in the
|
|
744
|
+
* plane perpendicular to a chosen axis. Used by `<PolyTransformControls
|
|
745
|
+
* mode="rotate">` together with a CSS `mask: radial-gradient(...)` to
|
|
746
|
+
* render the visible donut, replacing the segmented quad-strip approach
|
|
747
|
+
* of `ringPolygons` with a single DOM element per ring.
|
|
748
|
+
*
|
|
749
|
+
* The caller is responsible for applying the mask CSS and using a donut-
|
|
750
|
+
* shaped hit-test (the quad's bounding rect alone would over-hit the
|
|
751
|
+
* inner hole). The recommended setup is to set the CSS custom property
|
|
752
|
+
* `--ring-inner-ratio` on the mesh element so the mask scales with the
|
|
753
|
+
* caller's chosen thickness ratio.
|
|
754
|
+
*/
|
|
755
|
+
|
|
756
|
+
interface RingQuadPolygonsOptions {
|
|
757
|
+
/** World axis the ring is perpendicular to: 0=X, 1=Y, 2=Z. The quad
|
|
758
|
+
* lies in the plane spanned by the other two axes. */
|
|
759
|
+
axis: 0 | 1 | 2;
|
|
760
|
+
/** Outer radius of the ring. The quad spans ±outerRadius in both
|
|
761
|
+
* in-plane axes. */
|
|
762
|
+
outerRadius: number;
|
|
763
|
+
/** Fill color. */
|
|
764
|
+
color?: string;
|
|
765
|
+
}
|
|
766
|
+
/** Build a single 4-vertex polygon (a square) bounding the ring's outer
|
|
767
|
+
* circle. CSS `mask` is expected to clip this to the donut shape at
|
|
768
|
+
* render time. */
|
|
769
|
+
declare function ringQuadPolygons(options: RingQuadPolygonsOptions): Polygon[];
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* A flat quad on one of the three axis-aligned planes, offset diagonally
|
|
773
|
+
* along the two in-plane axes. Used as a planar drag handle in
|
|
774
|
+
* `<PolyTransformControls>` — clicking and dragging this handle moves the
|
|
775
|
+
* attached mesh along two axes simultaneously (XY, XZ, or YZ), instead of
|
|
776
|
+
* the single-axis motion the arrow shafts provide.
|
|
777
|
+
*
|
|
778
|
+
* The polygon lives in standard polycss world space; wrap it in the
|
|
779
|
+
* framework's PolyMesh equivalent for rendering.
|
|
780
|
+
*/
|
|
781
|
+
|
|
782
|
+
interface PlanePolygonsOptions {
|
|
783
|
+
/** Axis perpendicular to the plane: 0 = YZ plane, 1 = XZ plane,
|
|
784
|
+
* 2 = XY plane. The quad lies on the OTHER two axes. */
|
|
785
|
+
axis: 0 | 1 | 2;
|
|
786
|
+
/** Half-extent of the quad along each in-plane axis. Default `0.4`. */
|
|
787
|
+
size?: number;
|
|
788
|
+
/** Center of the quad along the two in-plane axes. Pass a single number
|
|
789
|
+
* to use the same offset on both (positive places the handle in the
|
|
790
|
+
* +A/+B corner). Pass `[offsetA, offsetB]` to control each
|
|
791
|
+
* independently — sign flips move the handle to a different octant.
|
|
792
|
+
* `A = (axis+1)%3`, `B = (axis+2)%3`. Default `size * 2`. */
|
|
793
|
+
offset?: number | [number, number];
|
|
794
|
+
/** Position along the perpendicular axis. Default `0` (on the plane). */
|
|
795
|
+
along?: number;
|
|
796
|
+
/** Fill color. */
|
|
797
|
+
color?: string;
|
|
798
|
+
}
|
|
799
|
+
/** Build the polygons for one axis-aligned planar drag handle. */
|
|
800
|
+
declare function planePolygons(options: PlanePolygonsOptions): Polygon[];
|
|
801
|
+
|
|
537
802
|
/**
|
|
538
803
|
* Geometry for a small solid-color octahedron — the marker shape used by
|
|
539
804
|
* `PolyDirectionalLightHelper` to indicate where a directional light is
|
|
@@ -563,6 +828,22 @@ declare function octahedronPolygons(options: OctahedronPolygonsOptions): Polygon
|
|
|
563
828
|
* is empty (e.g. `parseObj`, where it's a no-op).
|
|
564
829
|
*/
|
|
565
830
|
|
|
831
|
+
interface PolyVoxelCell {
|
|
832
|
+
x: number;
|
|
833
|
+
y: number;
|
|
834
|
+
z: number;
|
|
835
|
+
color: string;
|
|
836
|
+
}
|
|
837
|
+
interface PolyVoxelSource {
|
|
838
|
+
kind: "magica-vox";
|
|
839
|
+
cells: PolyVoxelCell[];
|
|
840
|
+
rows: number;
|
|
841
|
+
cols: number;
|
|
842
|
+
depth: number;
|
|
843
|
+
scale: number;
|
|
844
|
+
gridShift: number;
|
|
845
|
+
sourceBytes: number;
|
|
846
|
+
}
|
|
566
847
|
interface ParseAnimationClip {
|
|
567
848
|
/** Stable numeric index in the source file's animation array. */
|
|
568
849
|
index: number;
|
|
@@ -585,6 +866,8 @@ interface ParseAnimationController {
|
|
|
585
866
|
interface ParseResult {
|
|
586
867
|
/** The mesh, as a flat polygon list. Already vertex-permuted to polycss space. */
|
|
587
868
|
polygons: Polygon[];
|
|
869
|
+
/** Optional raw voxel source for `.vox` fast paths; polygon fallback remains authoritative. */
|
|
870
|
+
voxelSource?: PolyVoxelSource;
|
|
588
871
|
/** Optional animation sampler for formats that carry timeline data. */
|
|
589
872
|
animation?: ParseAnimationController;
|
|
590
873
|
/**
|
|
@@ -616,6 +899,8 @@ interface ParseResult {
|
|
|
616
899
|
animations?: ParseAnimationClip[];
|
|
617
900
|
/** Source file size in bytes (for diagnostics). */
|
|
618
901
|
sourceBytes?: number;
|
|
902
|
+
/** Voxel count for `.vox` sources. */
|
|
903
|
+
voxelCount?: number;
|
|
619
904
|
};
|
|
620
905
|
}
|
|
621
906
|
|
|
@@ -851,8 +1136,9 @@ declare function bakeSolidTextureSamples(result: ParseResult, options?: SolidTex
|
|
|
851
1136
|
|
|
852
1137
|
interface VoxParseOptions {
|
|
853
1138
|
/**
|
|
854
|
-
* Largest mesh extent (in scene-space units).
|
|
855
|
-
*
|
|
1139
|
+
* Largest mesh extent (in scene-space units). For `.vox`, the requested
|
|
1140
|
+
* extent is snapped to the nearest integer CSS cell size to keep voxel
|
|
1141
|
+
* fast-path coordinates integral. Default: 60.
|
|
856
1142
|
*/
|
|
857
1143
|
targetSize?: number;
|
|
858
1144
|
/**
|
|
@@ -864,6 +1150,51 @@ interface VoxParseOptions {
|
|
|
864
1150
|
}
|
|
865
1151
|
declare function parseVox(buffer: ArrayBuffer, options?: VoxParseOptions): ParseResult;
|
|
866
1152
|
|
|
1153
|
+
type PlaneAxis = "x" | "y" | "z";
|
|
1154
|
+
type PolyVoxelFace = "t" | "b" | "bl" | "br" | "fr" | "fl";
|
|
1155
|
+
interface PolyVoxelWallsMask {
|
|
1156
|
+
t: boolean;
|
|
1157
|
+
b: boolean;
|
|
1158
|
+
bl: boolean;
|
|
1159
|
+
br: boolean;
|
|
1160
|
+
fl: boolean;
|
|
1161
|
+
fr: boolean;
|
|
1162
|
+
}
|
|
1163
|
+
interface FaceKey {
|
|
1164
|
+
axis: PlaneAxis;
|
|
1165
|
+
plane: number;
|
|
1166
|
+
face: PolyVoxelFace;
|
|
1167
|
+
}
|
|
1168
|
+
interface FaceBuffer {
|
|
1169
|
+
width: number;
|
|
1170
|
+
height: number;
|
|
1171
|
+
minRow: number;
|
|
1172
|
+
minCol: number;
|
|
1173
|
+
ids: Uint32Array;
|
|
1174
|
+
mask: Uint8Array;
|
|
1175
|
+
filledCount: number;
|
|
1176
|
+
palette: string[];
|
|
1177
|
+
}
|
|
1178
|
+
interface FaceData {
|
|
1179
|
+
key: FaceKey;
|
|
1180
|
+
buffer: FaceBuffer;
|
|
1181
|
+
}
|
|
1182
|
+
type Brush = {
|
|
1183
|
+
r0: number;
|
|
1184
|
+
c0: number;
|
|
1185
|
+
r1: number;
|
|
1186
|
+
c1: number;
|
|
1187
|
+
baseColor: string;
|
|
1188
|
+
};
|
|
1189
|
+
type SlicePlan = {
|
|
1190
|
+
key: FaceKey;
|
|
1191
|
+
buffer: FaceBuffer;
|
|
1192
|
+
brushes: Brush[];
|
|
1193
|
+
};
|
|
1194
|
+
declare const NEXT_LAYER_STEP: Record<PolyVoxelFace, number>;
|
|
1195
|
+
declare const buildSlicePlan: (faceData: FaceData, nextLayer: FaceBuffer | null) => SlicePlan;
|
|
1196
|
+
declare const buildFaceDataFromVoxelSource: (source: PolyVoxelSource) => FaceData[];
|
|
1197
|
+
|
|
867
1198
|
/**
|
|
868
1199
|
* loadMesh — high-level fetch+parse dispatcher. Picks the parser by file
|
|
869
1200
|
* extension, fetches the URL, runs the parser, returns the unified
|
|
@@ -908,7 +1239,12 @@ interface LoadMeshOptions {
|
|
|
908
1239
|
* low-poly models that use texture atlases as color swatches.
|
|
909
1240
|
*/
|
|
910
1241
|
solidTextureSamples?: boolean | SolidTextureSampleOptions;
|
|
1242
|
+
/**
|
|
1243
|
+
* Mesh optimization intent. Defaults to "lossy"; set "lossless" to keep
|
|
1244
|
+
* exact planar candidates only.
|
|
1245
|
+
*/
|
|
1246
|
+
meshResolution?: MeshResolution;
|
|
911
1247
|
}
|
|
912
1248
|
declare function loadMesh(url: string, options?: LoadMeshOptions): Promise<ParseResult>;
|
|
913
1249
|
|
|
914
|
-
export { type ArrowPolygonsOptions, type AutoRotateConfig, type AutoRotateOption, type AxesHelperOptions, BASE_TILE, type CameraHandle, type CameraState, type CameraStyleInput, type CoverPlanarPolygonsOptions, type CullInteriorOptions, DEFAULT_CAMERA_STATE, DEFAULT_PROJECTION, type GltfParseOptions, type LoadMeshOptions, type LoopMode, LoopOnce, LoopPingPong, LoopRepeat, type MtlParseResult, type NormalizeResult, type ObjParseOptions, type OctahedronPolygonsOptions, type ParseAnimationClip, type ParseAnimationController, type ParseResult, type ParsedColor, type PolyAmbientLight, type PolyAnimationAction, type ParseAnimationClip as PolyAnimationClip, type PolyAnimationMixer, type PolyAnimationTarget, type PolyDirectionalLight, type PolyMaterial, type PolyTextureLightingMode, type Polygon, type PolygonFace, type RingPolygonsOptions, type SceneBbox, type SceneContext, type SceneContextBuildArgs, type SceneContextBuildResult, type SolidTextureSampleOptions, type TexturePaintMetrics, type TexturePaintMetricsOptions, type TextureTriangle, type Vec2, type Vec3, type VoxParseOptions, arrowPolygons, axesHelperPolygons, bakeSolidTextureSampledPolygons, bakeSolidTextureSamples, buildSceneContext, clampChannel, computeSceneBbox, computeShapeLighting, computeTexturePaintMetrics, coverPlanarPolygons, createIsometricCamera, createPolyAnimationMixer, cullInteriorPolygons, formatColor, inverseRotateVec3, loadMesh, mergePolygons, normalizeInvertMultiplier, normalizePolygons, octahedronPolygons, parseColor, parseGltf, parseHexColor, parseMtl, parseObj, parsePureColor, parseRgbColor, parseVox, polygonFaces, ringPolygons, rotateVec3, shadeColor };
|
|
1250
|
+
export { type ApproximateMergeOptions, type ArrowPolygonsOptions, type AutoRotateConfig, type AutoRotateOption, type AxesHelperOptions, BASE_TILE, type BoxFace, type BoxFaceOptions, type BoxPolygonsOptions, CAMERA_BACKFACE_CULL_EPS, type CameraCullNormalGroup, type CameraCullRotation, type CameraHandle, type CameraState, type CameraStyleInput, type CoverPlanarPolygonsOptions, type CullInteriorOptions, DEFAULT_CAMERA_STATE, DEFAULT_PROJECTION, type DedupeOverlappingPolygonsOptions, type GltfParseOptions, type LoadMeshOptions, type LoopMode, LoopOnce, LoopPingPong, LoopRepeat, type MeshResolution, type MtlParseResult, type NormalizeResult, type ObjParseOptions, type OctahedronPolygonsOptions, type OptimizeMeshPolygonsOptions, NEXT_LAYER_STEP as POLY_VOXEL_NEXT_LAYER_STEP, type ParseAnimationClip, type ParseAnimationController, type ParseResult, type ParsedColor, type PlanePolygonsOptions, type PolyAmbientLight, type PolyAnimationAction, type ParseAnimationClip as PolyAnimationClip, type PolyAnimationMixer, type PolyAnimationTarget, type PolyDirectionalLight, type PolyMaterial, type PolyTextureLightingMode, type Brush as PolyVoxelBrush, type PolyVoxelCell, type PolyVoxelFace, type FaceBuffer as PolyVoxelFaceBuffer, type FaceData as PolyVoxelFaceData, type FaceKey as PolyVoxelFaceKey, type PlaneAxis as PolyVoxelPlaneAxis, type SlicePlan as PolyVoxelSlicePlan, type PolyVoxelSource, type PolyVoxelWallsMask, type Polygon, type PolygonFace, QUAT_IDENTITY, type Quat, type RingPolygonsOptions, type RingQuadPolygonsOptions, type SceneBbox, type SceneContext, type SceneContextBuildArgs, type SceneContextBuildResult, type SolidTextureSampleOptions, type TexturePaintMetrics, type TexturePaintMetricsOptions, type TextureTriangle, VOXEL_CAMERA_CULL_AXIS_EPS, VOXEL_CAMERA_CULL_NORMAL_LIMIT, type Vec2, type Vec3, type VoxParseOptions, arrowPolygons, axesHelperPolygons, bakeSolidTextureSampledPolygons, bakeSolidTextureSamples, boxPolygons, buildFaceDataFromVoxelSource as buildPolyVoxelFaceData, buildSlicePlan as buildPolyVoxelSlicePlan, buildSceneContext, cameraCullNormalGroups, cameraCullNormalGroupsFromPolygons, cameraCullNormalKey, cameraCullVisibleSignature, cameraFacingDepth, clampChannel, computeSceneBbox, computeShapeLighting, computeTexturePaintMetrics, coverPlanarPolygons, createIsometricCamera, createPolyAnimationMixer, cullInteriorPolygons, dedupeOverlappingPolygons, eulerXYZFromQuat, findOverlappingPolygonDuplicates, formatColor, inverseRotateVec3, isAxisAlignedSurfaceNormal, isVoxelCameraCullableNormalGroups, loadMesh, mergePolygons, normalFacesCamera, normalizeInvertMultiplier, normalizePolygons, octahedronPolygons, optimizeMeshPolygons, parseColor, parseGltf, parseHexColor, parseMtl, parseObj, parsePureColor, parseRgbColor, parseVox, planePolygons, polygonCssSurfaceNormal, polygonFaces, polygonFacesCamera, quatFromAxisAngle, quatFromEulerXYZ, quatMultiply, ringPolygons, ringQuadPolygons, rotateVec3, shadeColor };
|