@layoutit/polycss-react 0.0.1

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.
@@ -0,0 +1,669 @@
1
+ import * as react from 'react';
2
+ import react__default, { ReactNode, CSSProperties, MouseEventHandler, PointerEventHandler, FocusEventHandler, KeyboardEventHandler, RefObject, MouseEvent as MouseEvent$1 } from 'react';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import { Vec3, CameraState, CameraHandle, Vec2, PolyMaterial, PolyDirectionalLight, PolyTextureLightingMode, Polygon, PolyAmbientLight, LoadMeshOptions, PolyAnimationTarget, PolyAnimationMixer, PolyAnimationClip, PolyAnimationAction, ParseAnimationController } from '@layoutit/polycss-core';
5
+ export { ArrowPolygonsOptions, AutoRotateConfig, AutoRotateOption, AxesHelperOptions, BASE_TILE, CameraHandle, CameraState, CameraStyleInput, CoverPlanarPolygonsOptions, CullInteriorOptions, DEFAULT_CAMERA_STATE, DEFAULT_PROJECTION, GltfParseOptions, LoadMeshOptions, LoopMode, LoopOnce, LoopPingPong, LoopRepeat, MtlParseResult, NormalizeResult, ObjParseOptions, OctahedronPolygonsOptions, ParseAnimationClip, ParseAnimationController, ParseResult, ParsedColor, PolyAmbientLight, PolyAnimationAction, PolyAnimationClip, PolyAnimationMixer, PolyAnimationTarget, PolyDirectionalLight, PolyMaterial, PolyTextureLightingMode, Polygon, PolygonFace, RingPolygonsOptions, SceneBbox, SceneContext, SceneContextBuildArgs, SceneContextBuildResult, SolidTextureSampleOptions, TexturePaintMetrics, TexturePaintMetricsOptions, TextureTriangle, Vec2, Vec3, 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 } from '@layoutit/polycss-core';
6
+
7
+ interface PolyPerspectiveCameraProps {
8
+ zoom?: number;
9
+ target?: Vec3;
10
+ rotX?: number;
11
+ rotY?: number;
12
+ /** Camera pull-back in CSS pixels (dolly). Default 0. */
13
+ distance?: number;
14
+ /** CSS perspective distance in pixels. Defaults to 8000. */
15
+ perspective?: number;
16
+ children?: ReactNode;
17
+ className?: string;
18
+ style?: React.CSSProperties;
19
+ }
20
+ declare function PolyPerspectiveCameraInner({ zoom, target, rotX, rotY, distance, perspective, children, className, style, }: PolyPerspectiveCameraProps): react_jsx_runtime.JSX.Element;
21
+ declare const PolyPerspectiveCamera: react.MemoExoticComponent<typeof PolyPerspectiveCameraInner>;
22
+
23
+ interface PolyOrthographicCameraProps {
24
+ zoom?: number;
25
+ target?: Vec3;
26
+ rotX?: number;
27
+ rotY?: number;
28
+ /** Camera pull-back in CSS pixels (dolly). Default 0. */
29
+ distance?: number;
30
+ children?: ReactNode;
31
+ className?: string;
32
+ style?: React.CSSProperties;
33
+ }
34
+ declare function PolyOrthographicCameraInner({ zoom, target, rotX, rotY, distance, children, className, style, }: PolyOrthographicCameraProps): react_jsx_runtime.JSX.Element;
35
+ declare const PolyOrthographicCamera: react.MemoExoticComponent<typeof PolyOrthographicCameraInner>;
36
+
37
+ interface SceneStoreState {
38
+ cameraState: CameraState;
39
+ }
40
+ interface SceneStore {
41
+ getState(): SceneStoreState;
42
+ setState(partial: Partial<SceneStoreState>): void;
43
+ subscribe(listener: () => void): () => void;
44
+ /** Update camera state from the current imperative camera handle. */
45
+ updateCameraFromRef(handle: CameraHandle): boolean;
46
+ /** Force notify all subscribers (e.g. after prop-driven camera change). */
47
+ notifyAll(): void;
48
+ }
49
+
50
+ interface UseCameraOptions {
51
+ zoom?: number;
52
+ target?: Vec3;
53
+ rotX?: number;
54
+ rotY?: number;
55
+ distance?: number;
56
+ }
57
+ interface UseCameraResult {
58
+ store: SceneStore;
59
+ cameraRef: React.MutableRefObject<CameraHandle>;
60
+ sceneElRef: React.MutableRefObject<HTMLElement | null>;
61
+ /**
62
+ * Attach to the camera root element. Layered components like
63
+ * <PolyOrbitControls> need the underlying ref to wire non-passive wheel /
64
+ * pointer listeners (React's synthetic onWheel is passive in modern
65
+ * versions and can't preventDefault).
66
+ */
67
+ cameraElRef: React.MutableRefObject<HTMLDivElement | null>;
68
+ /**
69
+ * Apply the current camera state (from cameraRef.current.state) directly
70
+ * to sceneEl.style.transform — bypasses React. Exposed so layered
71
+ * components like <PolyOrbitControls> can call it after mutating state.
72
+ */
73
+ applyTransformDirect: () => void;
74
+ }
75
+ declare function usePolyCamera(options: UseCameraOptions): UseCameraResult;
76
+
77
+ interface PolyCameraContextValue {
78
+ store: SceneStore;
79
+ cameraRef: React.MutableRefObject<CameraHandle>;
80
+ sceneElRef: React.MutableRefObject<HTMLElement | null>;
81
+ /**
82
+ * The host element the camera attaches to (parent of sceneEl). Exposed
83
+ * so layered components like <PolyControls> can attach their own
84
+ * pointer/wheel listeners.
85
+ */
86
+ cameraElRef: React.MutableRefObject<HTMLElement | null>;
87
+ /**
88
+ * Apply the current camera state (from cameraRef.current.state) directly
89
+ * to sceneEl.style.transform — bypasses React. Used by both useCamera's
90
+ * built-in handlers and any layered <PolyControls>. Calling it after
91
+ * cameraRef.current.update(...) makes the DOM reflect the new state.
92
+ */
93
+ applyTransformDirect: () => void;
94
+ }
95
+ declare const PolyCameraContext: react.Context<PolyCameraContextValue | null>;
96
+ declare function useCameraContext(): PolyCameraContextValue;
97
+
98
+ type AtlasScale = number | "auto";
99
+
100
+ /**
101
+ * Three.js-style transform props accepted by every polycss component.
102
+ * In Phase 3, position/scale/rotation are accepted but not yet applied —
103
+ * the rendered transform comes from vertices in scene-root space.
104
+ * Phase 4 wires these into the matrix3d composition with parent PolyMesh.
105
+ */
106
+ interface TransformProps {
107
+ position?: Vec3;
108
+ scale?: number | Vec3;
109
+ rotation?: Vec3;
110
+ }
111
+ /**
112
+ * DOM event handlers, ARIA, and style props forwarded to the rendered
113
+ * element (atlas-backed <div>) by every Poly component.
114
+ *
115
+ * This is the DOM-native pitch: polygons are real DOM nodes you can
116
+ * target with CSS, attach event handlers to, and inspect in DevTools.
117
+ */
118
+ interface DOMPassthroughProps {
119
+ className?: string;
120
+ style?: CSSProperties;
121
+ id?: string;
122
+ onClick?: MouseEventHandler<HTMLElement>;
123
+ onDoubleClick?: MouseEventHandler<HTMLElement>;
124
+ onMouseEnter?: MouseEventHandler<HTMLElement>;
125
+ onMouseLeave?: MouseEventHandler<HTMLElement>;
126
+ onMouseMove?: MouseEventHandler<HTMLElement>;
127
+ onPointerDown?: PointerEventHandler<HTMLElement>;
128
+ onPointerUp?: PointerEventHandler<HTMLElement>;
129
+ onPointerEnter?: PointerEventHandler<HTMLElement>;
130
+ onPointerLeave?: PointerEventHandler<HTMLElement>;
131
+ onFocus?: FocusEventHandler<HTMLElement>;
132
+ onBlur?: FocusEventHandler<HTMLElement>;
133
+ onKeyDown?: KeyboardEventHandler<HTMLElement>;
134
+ tabIndex?: number;
135
+ role?: string;
136
+ "aria-label"?: string;
137
+ "aria-hidden"?: boolean;
138
+ pointerEvents?: "auto" | "none";
139
+ [dataAttr: `data-${string}`]: string | number | boolean | undefined;
140
+ }
141
+ /**
142
+ * Props for the `<Poly>` component — the atomic polygon primitive.
143
+ *
144
+ * Extends TransformProps + DOMPassthroughProps with the polygon's own fields.
145
+ * This is the canonical polycss v0.1.0 Poly component API per §API freeze.
146
+ */
147
+ interface PolyProps extends TransformProps, DOMPassthroughProps {
148
+ vertices: Vec3[];
149
+ color?: string;
150
+ texture?: string;
151
+ uvs?: Vec2[];
152
+ data?: Record<string, string | number | boolean>;
153
+ /** Shared material. When set AND the polygon's UVs form an axis-aligned
154
+ * rectangle, renders via `background-image` directly — no per-polygon
155
+ * canvas rasterization. Falls back to the atlas path otherwise. */
156
+ material?: PolyMaterial;
157
+ context?: {
158
+ tileSize?: number;
159
+ layerElevation?: number;
160
+ directionalLight?: PolyDirectionalLight;
161
+ textureLighting?: PolyTextureLightingMode;
162
+ atlasScale?: AtlasScale;
163
+ debugShowBackfaces?: boolean;
164
+ [key: string]: unknown;
165
+ };
166
+ /** Textured polygon lighting mode. Defaults to scene context, then "baked". */
167
+ textureLighting?: PolyTextureLightingMode;
168
+ /** Raster scale for generated atlas pages. `"auto"` reduces large atlases. */
169
+ atlasScale?: AtlasScale;
170
+ /** Pre-computed shaded base color from the parent (optional override). */
171
+ baseColor?: string;
172
+ }
173
+
174
+ interface PolySceneProps extends TransformProps {
175
+ /** Polygons to render. Composes additively with `children`. */
176
+ polygons?: Polygon[];
177
+ /**
178
+ * Polygons used ONLY for the `autoCenter` bbox computation. When provided,
179
+ * the autoCenter translate is derived from this list instead of `polygons`.
180
+ *
181
+ * Use this when the scene's renderable polygons live inside a child
182
+ * `<PolyMesh>` (e.g. in selection mode) rather than in `polygons`. Passing
183
+ * the full mesh polygon list here ensures the autoCenter wrapper shifts
184
+ * all children — including helpers like `<PolyAxesHelper>` — by the same
185
+ * -bboxCenter amount as the vanilla renderer's `centerWrapper`. Without it,
186
+ * `autoCenter` computes its bbox from an empty `polygons=[]` and produces
187
+ * no shift, so helpers stay at world origin while the mesh is recentered by
188
+ * PolyMesh's own `autoCenter`.
189
+ */
190
+ centerPolygons?: Polygon[];
191
+ perspective?: number;
192
+ rotX?: number;
193
+ rotY?: number;
194
+ zoom?: number;
195
+ directionalLight?: PolyDirectionalLight;
196
+ ambientLight?: PolyAmbientLight;
197
+ /** Textured polygon lighting mode. Defaults to "baked". */
198
+ textureLighting?: PolyTextureLightingMode;
199
+ /** Raster scale for generated atlas pages. `"auto"` reduces large atlases. */
200
+ atlasScale?: AtlasScale;
201
+ /**
202
+ * When `true`, rotation pivots around the mesh's bbox center instead of
203
+ * world (0,0,0). Polygon data is not mutated — the scene element's
204
+ * `transform-origin` is moved to the bbox center in CSS. Equivalent to
205
+ * setting Three.js's `OrbitControls.target` to the mesh centroid. Off
206
+ * by default to match Three.js: meshes load at their authored origin
207
+ * unless the user opts in. Use this for loaded OBJ/GLB assets whose
208
+ * origin is at a corner / feet / arbitrary point.
209
+ */
210
+ autoCenter?: boolean;
211
+ className?: string;
212
+ style?: CSSProperties;
213
+ children?: ReactNode;
214
+ debugShowLabels?: boolean;
215
+ debugShowBackfaces?: boolean;
216
+ }
217
+ declare function PolySceneInner({ polygons: polygonsProp, centerPolygons: centerPolygonsProp, perspective: _perspective, rotX: _rotX, rotY: _rotY, zoom: _zoom, directionalLight, ambientLight, textureLighting, atlasScale, autoCenter, className, style, children, position: _position, scale: _scale, rotation: _rotation, debugShowLabels: _debugShowLabels, debugShowBackfaces, }: PolySceneProps): react_jsx_runtime.JSX.Element;
218
+ declare const PolyScene: react.MemoExoticComponent<typeof PolySceneInner>;
219
+
220
+ type UseMeshOptions = LoadMeshOptions;
221
+ interface UseMeshResult {
222
+ polygons: Polygon[];
223
+ loading: boolean;
224
+ error: Error | null;
225
+ warnings: string[];
226
+ /** Manually trigger cleanup (also called on unmount automatically). */
227
+ dispose: () => void;
228
+ }
229
+ declare function usePolyMesh(src: string, options?: UseMeshOptions): UseMeshResult;
230
+
231
+ /**
232
+ * Pointer event API for <PolyMesh>. Mirrors @react-three/fiber's mesh
233
+ * event surface (handler names + payload shape) so devs migrating from
234
+ * three.js use the same mental model. polycss is DOM-native so we get
235
+ * native pointer events for free — no raycaster, no canvas event
236
+ * synthesis.
237
+ *
238
+ * Diverges from r3f in two intentional ways:
239
+ * 1. Bubbling matches DOM (pointer hits the front element only). r3f
240
+ * replays events to occluded objects behind the front hit; doing
241
+ * that here would require running our own raycaster, which defeats
242
+ * the point of being DOM-native.
243
+ * 2. `face`, `uv`, `uv1`, `instanceId` are omitted — they're three.js
244
+ * BufferGeometry / InstancedMesh concepts with no polycss analogue.
245
+ * The polycss-native equivalent of `face` is the hit polygon's
246
+ * index, exposed via `polygon` (set when the underlying DOM target
247
+ * is an `<i>` polygon element).
248
+ */
249
+
250
+ /**
251
+ * Imperative handle exposed by `<PolyMesh ref>`. Read-only view of the
252
+ * mesh's element + current transform + polygons. Mutation flows through
253
+ * controlled props (parent owns transform state) — matches three.js
254
+ * editor's pattern of keeping `selected` external to the object.
255
+ */
256
+ interface PolyMeshHandle {
257
+ /** The `.polycss-mesh` wrapper div (null until mounted). */
258
+ readonly element: HTMLDivElement | null;
259
+ /** Identifier passed via the `id` prop, if any. */
260
+ readonly id?: string;
261
+ /** Current `position` prop value. */
262
+ getPosition(): Vec3 | undefined;
263
+ /** Current `rotation` prop value (Euler degrees). */
264
+ getRotation(): Vec3 | undefined;
265
+ /** Current `scale` prop value. */
266
+ getScale(): number | Vec3 | undefined;
267
+ /** Polygons currently being rendered (post-autoCenter). */
268
+ getPolygons(): Polygon[];
269
+ /**
270
+ * Snapshot the current `rotation` prop as the new "baked rotation" and
271
+ * trigger an atlas re-rasterization with the directional light
272
+ * inverse-rotated into the mesh's local frame.
273
+ *
274
+ * Call this after a rotate-mode drag ends (i.e. on pointer release) —
275
+ * **not** on every pointermove during the drag. The visual wrapper already
276
+ * follows the live `rotation` prop smoothly; the atlas only needs to
277
+ * update once per committed rotation so it doesn't re-bake every frame.
278
+ *
279
+ * Math rationale: baked atlas tiles encode `baseColor × Lambert(worldNormal,
280
+ * worldLight)`. When the mesh wrapper rotates via CSS the world-space normal
281
+ * changes but the baked color does not, causing stale shading. Calling
282
+ * `rebakeAtlas()` inverse-rotates the world light into the mesh-local frame
283
+ * before re-running the atlas baker, so `dot(localNormal, localLight) ===
284
+ * dot(worldNormal, worldLight)` and the shading is correct again.
285
+ *
286
+ * In dynamic (`textureLighting="dynamic"`) mode this call is a no-op for
287
+ * shading purposes (dynamic mode re-evaluates per frame), but it is still
288
+ * safe to call.
289
+ */
290
+ rebakeAtlas(): void;
291
+ }
292
+ /**
293
+ * Pointer event payload delivered to <PolyMesh> handlers. Mirrors r3f's
294
+ * shape, minus raycaster-specific fields. See module docstring for the
295
+ * intentional divergences.
296
+ */
297
+ interface PolyPointerEvent<E extends Event = PointerEvent> {
298
+ /** The mesh originally under the pointer (deepest hit). */
299
+ object: PolyMeshHandle;
300
+ /** The mesh whose handler is being invoked. Equal to `object` until
301
+ * ancestor bubbling is added (out of scope for v1). */
302
+ eventObject: PolyMeshHandle;
303
+ /** All meshes stacked under the pointer this moment, front-to-back.
304
+ * Computed via `document.elementsFromPoint` then filtered to
305
+ * registered `.polycss-mesh` ancestors. */
306
+ intersections: Array<{
307
+ object: PolyMeshHandle;
308
+ }>;
309
+ /** Pointer position in normalized device coords [-1, 1] relative to
310
+ * the camera viewport. (0,0) = viewport center. Falls back to (0,0)
311
+ * when the mesh is rendered outside a `<PolyCamera>`. */
312
+ pointer: {
313
+ x: number;
314
+ y: number;
315
+ };
316
+ /** Pixel distance from the most recent `pointerdown` to this event.
317
+ * 0 on pointerdown itself. Use to discriminate click-vs-drag. */
318
+ delta: number;
319
+ /** The underlying DOM event. */
320
+ nativeEvent: E;
321
+ /** Stops native bubbling. (Equivalent to `nativeEvent.stopPropagation()`
322
+ * today; reserved for future r3f-style bubbling above the wrapper.) */
323
+ stopPropagation(): void;
324
+ }
325
+ type PolyMouseEvent = PolyPointerEvent<MouseEvent>;
326
+ type PolyWheelEvent = PolyPointerEvent<WheelEvent>;
327
+ type PolyEventHandler<E extends Event = PointerEvent> = (event: PolyPointerEvent<E>) => void;
328
+ /**
329
+ * Pointer / mouse / wheel handlers accepted by `<PolyMesh>`. Names mirror
330
+ * r3f exactly. Provide any handler to opt the mesh into receiving events;
331
+ * absent handlers add zero overhead.
332
+ */
333
+ interface InteractionProps {
334
+ onClick?: PolyEventHandler<MouseEvent>;
335
+ onContextMenu?: PolyEventHandler<MouseEvent>;
336
+ onDoubleClick?: PolyEventHandler<MouseEvent>;
337
+ onWheel?: PolyEventHandler<WheelEvent>;
338
+ onPointerDown?: PolyEventHandler<PointerEvent>;
339
+ onPointerUp?: PolyEventHandler<PointerEvent>;
340
+ onPointerMove?: PolyEventHandler<PointerEvent>;
341
+ onPointerOver?: PolyEventHandler<PointerEvent>;
342
+ onPointerOut?: PolyEventHandler<PointerEvent>;
343
+ onPointerEnter?: PolyEventHandler<PointerEvent>;
344
+ onPointerLeave?: PolyEventHandler<PointerEvent>;
345
+ onPointerCancel?: PolyEventHandler<PointerEvent>;
346
+ }
347
+ /** Walk up from `el` looking for the nearest registered mesh wrapper. */
348
+ declare function findPolyMeshHandle(el: Element | null): PolyMeshHandle | null;
349
+ /** Test whether `(clientX, clientY)` falls inside any polygon leaf
350
+ * child of `meshEl`'s post-3D bounding rect. Skips zero-area rects
351
+ * (happy-dom and pre-layout SSR return those). */
352
+ declare function pointInMeshElement(meshEl: HTMLElement, clientX: number, clientY: number): boolean;
353
+ /** Walk every registered `.polycss-mesh` in the document and return
354
+ * the first whose polygon bounding-rects contain `(clientX, clientY)`.
355
+ * An optional `filter` skips matched mesh elements (e.g. gizmos). */
356
+ declare function findMeshUnderPoint(clientX: number, clientY: number, filter?: (meshEl: HTMLElement) => boolean): PolyMeshHandle | null;
357
+
358
+ interface PolyMeshProps extends TransformProps, InteractionProps {
359
+ /** Stable identifier — exposed on the mesh handle and reflected as
360
+ * `data-poly-mesh-id` on the wrapper div. Use for selection lookups. */
361
+ id?: string;
362
+ /** URL to .obj / .glb / .gltf. Mutually exclusive with `polygons`. */
363
+ src?: string;
364
+ /**
365
+ * Companion `.mtl` URL for OBJ models. When set, materials defined in
366
+ * the mtl (Kd colors, map_Kd textures) are applied to the loaded mesh.
367
+ * Ignored for GLB/GLTF (they carry materials inline).
368
+ */
369
+ mtl?: string;
370
+ /** Pre-parsed polygons. Mutually exclusive with `src`. */
371
+ polygons?: Polygon[];
372
+ /** Translate so mesh's bbox center is at local origin before applying `position`. */
373
+ autoCenter?: boolean;
374
+ /** Textured polygon lighting mode. Defaults to "baked". */
375
+ textureLighting?: PolyTextureLightingMode;
376
+ /** Raster scale for generated atlas pages. `"auto"` reduces large atlases. */
377
+ atlasScale?: AtlasScale;
378
+ /** Per-polygon override render. Receives the polygon + its index. */
379
+ children?: (polygon: Polygon, index: number) => ReactNode;
380
+ /** Loading slot — rendered while `src` is being fetched/parsed. */
381
+ fallback?: ReactNode;
382
+ /** Error slot — rendered if parse fails. Receives the Error. */
383
+ errorFallback?: (error: Error) => ReactNode;
384
+ /** Parser options forwarded to parseObj/parseGltf. */
385
+ parseOptions?: UseMeshOptions;
386
+ className?: string;
387
+ style?: CSSProperties;
388
+ }
389
+ declare const PolyMesh: react.ForwardRefExoticComponent<PolyMeshProps & react.RefAttributes<PolyMeshHandle>>;
390
+
391
+ interface UseSceneContextOptions {
392
+ directionalLight?: PolyDirectionalLight;
393
+ }
394
+ interface UseSceneContextResult {
395
+ polygons: Polygon[];
396
+ sceneBbox: {
397
+ min: Vec3;
398
+ max: Vec3;
399
+ };
400
+ }
401
+ /**
402
+ * React hook that runs the polycss scene-context pipeline:
403
+ * normalizePolygons → mergePolygons by default → bbox compute.
404
+ *
405
+ * Returns the processed polygons + the scene-wide axis-aligned bbox. Memoized
406
+ * on input identity + the few options that affect output. Per §Design.6.
407
+ */
408
+ declare function usePolySceneContext(polygons: Polygon[], options: UseSceneContextOptions): UseSceneContextResult;
409
+
410
+ /**
411
+ * usePolyMaterial — memoizes a shared material handle so the same
412
+ * (texture, key) inputs always return a stable object reference.
413
+ *
414
+ * Stable references matter for <Poly memo> shallow-compare: if the material
415
+ * object identity is stable, tiles that share the same material won't
416
+ * re-render just because a parent re-rendered.
417
+ *
418
+ * Future: additional material props (color tint, opacity, blend, lighting
419
+ * overrides) will live here.
420
+ */
421
+ declare function usePolyMaterial(options: {
422
+ texture: string;
423
+ key?: string;
424
+ }): PolyMaterial;
425
+
426
+ /**
427
+ * Poly — renders one polygon as an atlas-backed DOM sprite.
428
+ *
429
+ * Public API: `{ vertices, color?, texture?, uvs?, data? }` plus DOM
430
+ * passthrough props. The atlas renderer handles both textured and solid-color
431
+ * faces, so `<Poly>` never emits SVG in the normal render path.
432
+ *
433
+ * Wrapped in React.memo so parent re-renders (e.g. camera rotation updating
434
+ * rotY state) do not re-render stable polygon children. The shallow-equality
435
+ * check is sound here because polygon data (vertices, color, texture) is
436
+ * typically created once at parse time and passed by reference.
437
+ */
438
+ declare function PolyInner({ vertices, color, texture, uvs, data, material, position, scale, rotation, className, style: styleProp, id, onClick, onDoubleClick, onMouseEnter, onMouseLeave, onMouseMove, onPointerDown, onPointerUp, onPointerEnter, onPointerLeave, onFocus, onBlur, onKeyDown, tabIndex, role, "aria-label": ariaLabel, "aria-hidden": ariaHidden, pointerEvents: pointerEventsProp, context, textureLighting: textureLightingProp, atlasScale: atlasScaleProp, baseColor: baseColorProp, ...dataAttrs }: PolyProps): react_jsx_runtime.JSX.Element | null;
439
+ declare const Poly: react__default.MemoExoticComponent<typeof PolyInner>;
440
+
441
+ interface PolyControlsAnimateOptions {
442
+ /** Degrees per 60Hz-equivalent frame. Default 0.3 (≈ 18 deg/sec). */
443
+ speed?: number;
444
+ /** Rotation axis. Default "y". */
445
+ axis?: "x" | "y";
446
+ /** Pause animate while a pointer drag is in progress. Default true. */
447
+ pauseOnInteraction?: boolean;
448
+ }
449
+ interface PolyControlsCamera {
450
+ rotX: number;
451
+ rotY: number;
452
+ zoom: number;
453
+ target: Vec3;
454
+ distance: number;
455
+ }
456
+ interface SharedControlsProps {
457
+ /** Pointer-drag. Default true. */
458
+ drag?: boolean;
459
+ /** Wheel / pinch zoom. Default true. */
460
+ wheel?: boolean;
461
+ /**
462
+ * Dolly mode: wheel changes `distance` (camera pull-back in CSS pixels)
463
+ * instead of `zoom` (CSS scale). Mirrors three.js OrbitControls dolly.
464
+ * Default false (wheel changes zoom). When true, use `minDistance` /
465
+ * `maxDistance` to clamp the range.
466
+ */
467
+ dolly?: boolean;
468
+ /** Drag-direction inversion. Number = sensitivity multiplier. Default false. */
469
+ invert?: boolean | number;
470
+ /** Minimum zoom (CSS scale). Default 0.1. */
471
+ minZoom?: number;
472
+ /** Maximum zoom (CSS scale). Default 10. */
473
+ maxZoom?: number;
474
+ /** Minimum camera distance in CSS pixels when dolly is enabled. Default 0. */
475
+ minDistance?: number;
476
+ /** Maximum camera distance in CSS pixels when dolly is enabled. Default 5000. */
477
+ maxDistance?: number;
478
+ /** Auto-rotate. Pass false (or omit) to disable. */
479
+ animate?: false | PolyControlsAnimateOptions;
480
+ /**
481
+ * Fires whenever the controls mutate camera state.
482
+ */
483
+ onChange?: (camera: PolyControlsCamera) => void;
484
+ onInteractionStart?: (camera: PolyControlsCamera) => void;
485
+ onInteractionEnd?: (camera: PolyControlsCamera) => void;
486
+ }
487
+
488
+ interface PolyOrbitControlsProps extends SharedControlsProps {
489
+ }
490
+ declare function PolyOrbitControls({ drag, wheel, dolly, invert, minZoom, maxZoom, minDistance, maxDistance, animate, onChange, onInteractionStart, onInteractionEnd, }: PolyOrbitControlsProps): null;
491
+
492
+ interface PolyMapControlsProps extends SharedControlsProps {
493
+ }
494
+ declare function PolyMapControls({ drag, wheel, dolly, invert, minZoom, maxZoom, minDistance, maxDistance, animate, onChange, onInteractionStart, onInteractionEnd, }: PolyMapControlsProps): null;
495
+
496
+ /** Optional ref-or-direct binding to a target mesh. */
497
+ type PolyTransformControlsObject = PolyMeshHandle | RefObject<PolyMeshHandle | null> | null;
498
+ interface PolyTransformControlsObjectChangeEvent {
499
+ /** The mesh being transformed. */
500
+ object: PolyMeshHandle;
501
+ /** The new position. Only emitted when `mode` is "translate". */
502
+ position?: Vec3;
503
+ /** The new Euler rotation (degrees, X/Y/Z). Only emitted when
504
+ * `mode` is "rotate". */
505
+ rotation?: Vec3;
506
+ }
507
+ interface PolyTransformControlsProps {
508
+ /** Mesh to attach to. Pass a ref returned from `useRef<PolyMeshHandle>()`
509
+ * or a handle directly. `null` hides the gizmo. */
510
+ object: PolyTransformControlsObject;
511
+ /** Drag mode. "translate" → axial arrows, "rotate" → axial rings. */
512
+ mode?: "translate" | "rotate";
513
+ /** Axis basis. Only "world" is implemented in v1. */
514
+ space?: "world" | "local";
515
+ /** Multiplier on gizmo size (shaft length / ring radius). Default 1. */
516
+ size?: number;
517
+ /** Show / hide axis gizmo PAIRS. Default true. In translate mode this
518
+ * hides both the +/- arrows for that axis; in rotate mode this hides
519
+ * the corresponding ring. */
520
+ showX?: boolean;
521
+ showY?: boolean;
522
+ showZ?: boolean;
523
+ /** Snap step (CSS pixels) for translate-mode dragging. */
524
+ translationSnap?: number | null;
525
+ /** Snap step (degrees) for rotate-mode dragging. */
526
+ rotationSnap?: number | null;
527
+ /** Disable interaction without unmounting. Default true. */
528
+ enabled?: boolean;
529
+ /** Fires for any transform change. Argument-less, mirrors three.js. */
530
+ onChange?: () => void;
531
+ /** Fires with the new transform during drag. Use this to update
532
+ * position state — controlled flow, parent owns state. */
533
+ onObjectChange?: (event: PolyTransformControlsObjectChangeEvent) => void;
534
+ /** Fires once on drag start. */
535
+ onMouseDown?: () => void;
536
+ /** Fires once on drag end. */
537
+ onMouseUp?: () => void;
538
+ /** Fires with `true` on drag start, `false` on drag end. Mirrors
539
+ * three.js's `'dragging-changed'` event (kebab-case preserved here
540
+ * via the boolean payload, since react prop naming is camelCase). */
541
+ onDraggingChanged?: (dragging: boolean) => void;
542
+ }
543
+ declare function PolyTransformControls({ object, mode, space, size, showX, showY, showZ, translationSnap, rotationSnap, enabled, onChange, onObjectChange, onMouseDown, onMouseUp, onDraggingChanged, }: PolyTransformControlsProps): react_jsx_runtime.JSX.Element | null;
544
+
545
+ interface PolySelectionApi {
546
+ /** Current selection. Stable reference between renders unless changed. */
547
+ selected: PolyMeshHandle[];
548
+ /** Replace selection wholesale. */
549
+ set(next: PolyMeshHandle[]): void;
550
+ /** Add to selection (or replace, when `multiple` is false). */
551
+ add(handle: PolyMeshHandle): void;
552
+ /** Remove from selection. No-op if not present. */
553
+ remove(handle: PolyMeshHandle): void;
554
+ /** Toggle membership. With `multiple=false`, toggling a non-selected
555
+ * mesh replaces selection; toggling the selected mesh clears. */
556
+ toggle(handle: PolyMeshHandle): void;
557
+ /** Clear selection. */
558
+ clear(): void;
559
+ /** Membership test. */
560
+ has(handle: PolyMeshHandle): boolean;
561
+ }
562
+ interface PolySelectProps {
563
+ /** Allow multiple meshes selected at once. Default false. */
564
+ multiple?: boolean;
565
+ /** Optional filter applied to every selection change. Returned array
566
+ * becomes the new selection. */
567
+ filter?: (meshes: PolyMeshHandle[]) => PolyMeshHandle[];
568
+ /** Fires after every selection change with the new array. */
569
+ onChange?: (meshes: PolyMeshHandle[]) => void;
570
+ /** Fires when a click lands inside the Select wrapper but resolves to
571
+ * no mesh ancestor (i.e. the background). Receives the click event. */
572
+ onPointerMissed?: (event: MouseEvent$1<HTMLDivElement>) => void;
573
+ /** When true (default), clicking the background clears selection. */
574
+ clearOnMiss?: boolean;
575
+ children?: ReactNode;
576
+ className?: string;
577
+ style?: CSSProperties;
578
+ }
579
+ /**
580
+ * Selection wrapper. The host element uses `display: contents` by default
581
+ * so it doesn't affect CSS layout — its descendants render as if it
582
+ * weren't there, while pointer events still bubble through it.
583
+ */
584
+ declare function PolySelect({ multiple, filter, onChange, onPointerMissed, clearOnMiss, children, className, style, }: PolySelectProps): react_jsx_runtime.JSX.Element;
585
+ /**
586
+ * Read the current selection from the nearest enclosing `<Select>`.
587
+ * Returns an empty array when used outside a `<Select>` (matches drei).
588
+ */
589
+ declare function usePolySelect(): PolyMeshHandle[];
590
+ /**
591
+ * Read the imperative selection API. Throws when used outside `<PolySelect>`
592
+ * — fail loudly because callers expect to mutate.
593
+ */
594
+ declare function usePolySelectionApi(): PolySelectionApi;
595
+
596
+ interface PolyAxesHelperProps {
597
+ /** Length of each axis bar in world units. */
598
+ size?: number;
599
+ /** Bar cross-section width as a fraction of `size`. */
600
+ thickness?: number;
601
+ /** When true, also draws bars in the −X / −Y / −Z direction. */
602
+ negative?: boolean;
603
+ /** X-axis bar color. Mirrors three.js's red/green/blue convention. */
604
+ xColor?: string;
605
+ yColor?: string;
606
+ zColor?: string;
607
+ }
608
+ /**
609
+ * PolyAxesHelper — three colored bars from world origin along +X / +Y / +Z.
610
+ * Mirrors three.js's `AxesHelper`: red=X, green=Y, blue=Z.
611
+ *
612
+ * Renders inside the parent scene's transform, so it inherits camera
613
+ * rotation and zoom automatically.
614
+ */
615
+ declare function PolyAxesHelper({ size, thickness, negative, xColor, yColor, zColor, }: PolyAxesHelperProps): react_jsx_runtime.JSX.Element;
616
+
617
+ interface PolyDirectionalLightHelperProps {
618
+ /** Light to visualize. */
619
+ light: PolyDirectionalLight;
620
+ /**
621
+ * Point the marker orbits around, in world coords. Mirrors three.js's
622
+ * `DirectionalLight.target.position` — usually the mesh's bbox center.
623
+ * Defaults to the world origin.
624
+ */
625
+ target?: Vec3;
626
+ /** Distance from `target` to render the source marker, in world units. */
627
+ distance?: number;
628
+ /** Marker half-extent in world units. */
629
+ size?: number;
630
+ /** Marker color override. Defaults to `light.color`. */
631
+ color?: string;
632
+ }
633
+ /**
634
+ * PolyDirectionalLightHelper — small octahedron placed along the light's
635
+ * direction vector. Mirrors three.js's `DirectionalLightHelper`.
636
+ *
637
+ * `light.direction` is in CSS-pixel space (axis convention used by the
638
+ * shader). Polygon vertices are in world space, which the renderer remaps
639
+ * via `[v[1], v[0], v[2]]`. The helper reverses that swap so the marker
640
+ * lands where the light visibly comes from on screen.
641
+ *
642
+ * The octahedron is built at LOCAL origin once; the world position is
643
+ * applied via PolyMesh's `position` prop (a CSS transform on the wrapper).
644
+ * That keeps the polygons array reference-stable across light-direction
645
+ * changes — the atlas does not rebuild and the marker glides smoothly.
646
+ */
647
+ declare function PolyDirectionalLightHelper({ light, target, distance, size, color, }: PolyDirectionalLightHelperProps): react_jsx_runtime.JSX.Element;
648
+
649
+ declare function injectPolyBaseStyles(doc?: Document): void;
650
+
651
+ interface UsePolyAnimationResult {
652
+ /** Attach to a `PolyAnimationTarget`-compatible handle when not using `root`. */
653
+ ref: RefObject<PolyAnimationTarget | null>;
654
+ /** The active mixer, or null if inputs are not ready yet. */
655
+ mixer: PolyAnimationMixer | null;
656
+ /** Resolved clip list (empty when `clips` is undefined). */
657
+ clips: PolyAnimationClip[];
658
+ /** Clip names in input order. */
659
+ names: string[];
660
+ /**
661
+ * Lazy action proxy keyed by clip name. Accessing `actions["walk"]`
662
+ * instantiates the action if it does not exist yet. Returns null when the
663
+ * mixer is not ready.
664
+ */
665
+ actions: Record<string, PolyAnimationAction | null>;
666
+ }
667
+ declare function usePolyAnimation(clips: PolyAnimationClip[] | undefined, controller: ParseAnimationController | undefined, root?: RefObject<PolyAnimationTarget | null> | PolyAnimationTarget | null): UsePolyAnimationResult;
668
+
669
+ export { type DOMPassthroughProps, type InteractionProps, Poly, PolyAxesHelper, type PolyAxesHelperProps, PolyPerspectiveCamera as PolyCamera, PolyCameraContext, type PolyCameraContextValue, type PolyPerspectiveCameraProps as PolyCameraProps, type PolyControlsAnimateOptions, type PolyControlsCamera, PolyDirectionalLightHelper, type PolyDirectionalLightHelperProps, type PolyEventHandler, PolyMapControls, type PolyControlsCamera as PolyMapControlsCamera, type PolyMapControlsProps, PolyMesh, type PolyMeshHandle, type PolyMeshProps, type PolyMouseEvent, PolyOrbitControls, type PolyControlsCamera as PolyOrbitControlsCamera, type PolyOrbitControlsProps, PolyOrthographicCamera, type PolyOrthographicCameraProps, PolyPerspectiveCamera, type PolyPerspectiveCameraProps, type PolyPointerEvent, type PolyProps, PolyScene, type PolySceneProps, PolySelect, type PolySelectProps, type PolySelectionApi, PolyTransformControls, type PolyTransformControlsObject, type PolyTransformControlsObjectChangeEvent, type PolyTransformControlsProps, type PolyWheelEvent, type SharedControlsProps, type TransformProps, type UseCameraOptions, type UseCameraResult, type UseMeshOptions, type UseMeshResult, type UsePolyAnimationResult, type UseSceneContextOptions, type UseSceneContextResult, findMeshUnderPoint, findPolyMeshHandle, injectPolyBaseStyles, pointInMeshElement, useCameraContext, usePolyAnimation, usePolyCamera, usePolyMaterial, usePolyMesh, usePolySceneContext, usePolySelect, usePolySelectionApi };