@particle-academy/fancy-3d-three 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.
- package/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/engine.cjs +80 -0
- package/dist/engine.cjs.map +1 -0
- package/dist/engine.d.cts +5 -0
- package/dist/engine.d.ts +5 -0
- package/dist/engine.js +58 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.cjs +788 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +283 -0
- package/dist/index.d.ts +283 -0
- package/dist/index.js +744 -0
- package/dist/index.js.map +1 -0
- package/dist/react.cjs +333 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +64 -0
- package/dist/react.d.ts +64 -0
- package/dist/react.js +309 -0
- package/dist/react.js.map +1 -0
- package/package.json +94 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { WidgetSpec, SceneNode, WidgetAdapter, Scene } from '@particle-academy/fancy-3d';
|
|
3
|
+
|
|
4
|
+
declare const TEX_SCALE = 2;
|
|
5
|
+
declare function paintWidget(ctx: CanvasRenderingContext2D, spec: WidgetSpec, w: number, h: number, selected: boolean): void;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 3D shape primitives for `@particle-academy/fancy-3d` — three.js edition.
|
|
9
|
+
*
|
|
10
|
+
* A primitive is a three.js mesh that can host UI content on its surface —
|
|
11
|
+
* either a flat color, a freeform 2D paint callback, or a `WidgetSpec`
|
|
12
|
+
* rendered through the same painters as the three.js adapter.
|
|
13
|
+
*
|
|
14
|
+
* Every primitive returns a three.js `Mesh` (or a `Group` for composites),
|
|
15
|
+
* ready to position in your scene. Pass `scene` to also add it for you.
|
|
16
|
+
*
|
|
17
|
+
* Mirrors `@particle-academy/fancy-3d-babylon`'s primitive API: same function
|
|
18
|
+
* names, same option shapes. Differences from the Babylon adapter are minor and
|
|
19
|
+
* idiomatic to three (e.g. `doubleSided?: boolean` instead of a `sideOrientation`
|
|
20
|
+
* enum; `scene` is optional since three meshes exist independent of a scene).
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
type PaintFn = (ctx: CanvasRenderingContext2D, width: number, height: number) => void;
|
|
24
|
+
type SurfaceContent = {
|
|
25
|
+
type: "color";
|
|
26
|
+
color: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: "paint";
|
|
29
|
+
paint: PaintFn;
|
|
30
|
+
pixelWidth?: number;
|
|
31
|
+
pixelHeight?: number;
|
|
32
|
+
transparent?: boolean;
|
|
33
|
+
} | {
|
|
34
|
+
type: "widget";
|
|
35
|
+
widget: WidgetSpec;
|
|
36
|
+
pixelWidth?: number;
|
|
37
|
+
pixelHeight?: number;
|
|
38
|
+
selected?: boolean;
|
|
39
|
+
};
|
|
40
|
+
interface PanelOpts {
|
|
41
|
+
scene?: THREE.Object3D;
|
|
42
|
+
name?: string;
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
surface: SurfaceContent;
|
|
46
|
+
/** Render both faces (e.g. for self-luminous screens). */
|
|
47
|
+
doubleSided?: boolean;
|
|
48
|
+
}
|
|
49
|
+
declare function createPanel(opts: PanelOpts): THREE.Mesh;
|
|
50
|
+
interface BillboardOpts extends PanelOpts {
|
|
51
|
+
/** When true, the mesh is flagged to always face the camera. `<Stage>` honors
|
|
52
|
+
* the flag each frame; outside a Stage, call `mesh.lookAt(camera.position)`. */
|
|
53
|
+
faceCamera?: boolean;
|
|
54
|
+
}
|
|
55
|
+
declare function createBillboard(opts: BillboardOpts): THREE.Mesh;
|
|
56
|
+
interface BuildingOpts {
|
|
57
|
+
scene?: THREE.Object3D;
|
|
58
|
+
name?: string;
|
|
59
|
+
width: number;
|
|
60
|
+
height: number;
|
|
61
|
+
depth: number;
|
|
62
|
+
/** Surface applied to all 6 faces (cheap path). */
|
|
63
|
+
surface?: SurfaceContent;
|
|
64
|
+
/** Per-face surfaces; missing faces use `surface` or a default grey. */
|
|
65
|
+
faces?: Partial<Record<BoxFace, SurfaceContent>>;
|
|
66
|
+
}
|
|
67
|
+
type BoxFace = "front" | "back" | "right" | "left" | "top" | "bottom";
|
|
68
|
+
declare function createBuilding(opts: BuildingOpts): THREE.Mesh;
|
|
69
|
+
interface PillarOpts {
|
|
70
|
+
scene?: THREE.Object3D;
|
|
71
|
+
name?: string;
|
|
72
|
+
thickness: number;
|
|
73
|
+
height: number;
|
|
74
|
+
surface?: SurfaceContent;
|
|
75
|
+
}
|
|
76
|
+
declare function createPillar(opts: PillarOpts): THREE.Mesh;
|
|
77
|
+
interface CylinderOpts {
|
|
78
|
+
scene?: THREE.Object3D;
|
|
79
|
+
name?: string;
|
|
80
|
+
radius: number;
|
|
81
|
+
height: number;
|
|
82
|
+
surface: SurfaceContent;
|
|
83
|
+
tessellation?: number;
|
|
84
|
+
}
|
|
85
|
+
declare function createCylinder(opts: CylinderOpts): THREE.Mesh;
|
|
86
|
+
interface CurvedPanelOpts {
|
|
87
|
+
scene?: THREE.Object3D;
|
|
88
|
+
name?: string;
|
|
89
|
+
width: number;
|
|
90
|
+
height: number;
|
|
91
|
+
arc: number;
|
|
92
|
+
surface: SurfaceContent;
|
|
93
|
+
tessellation?: number;
|
|
94
|
+
}
|
|
95
|
+
declare function createCurvedPanel(opts: CurvedPanelOpts): THREE.Mesh;
|
|
96
|
+
interface SphereOpts {
|
|
97
|
+
scene?: THREE.Object3D;
|
|
98
|
+
name?: string;
|
|
99
|
+
diameter: number;
|
|
100
|
+
surface: SurfaceContent;
|
|
101
|
+
segments?: number;
|
|
102
|
+
}
|
|
103
|
+
declare function createSphere(opts: SphereOpts): THREE.Mesh;
|
|
104
|
+
interface DiscOpts {
|
|
105
|
+
scene?: THREE.Object3D;
|
|
106
|
+
name?: string;
|
|
107
|
+
radius: number;
|
|
108
|
+
surface: SurfaceContent;
|
|
109
|
+
tessellation?: number;
|
|
110
|
+
}
|
|
111
|
+
declare function createDisc(opts: DiscOpts): THREE.Mesh;
|
|
112
|
+
interface Card3DOpts {
|
|
113
|
+
scene?: THREE.Object3D;
|
|
114
|
+
name?: string;
|
|
115
|
+
width: number;
|
|
116
|
+
height: number;
|
|
117
|
+
/** Extrusion depth. Defaults to a thin 0.06 — like real foam-board signage. */
|
|
118
|
+
depth?: number;
|
|
119
|
+
/** Surface for the front face (the visible UI). */
|
|
120
|
+
front: SurfaceContent;
|
|
121
|
+
/** Surface for the side and back faces. Defaults to a dark color. */
|
|
122
|
+
edge?: SurfaceContent;
|
|
123
|
+
}
|
|
124
|
+
declare function createCard3D(opts: Card3DOpts): THREE.Mesh;
|
|
125
|
+
interface SignOpts {
|
|
126
|
+
scene?: THREE.Object3D;
|
|
127
|
+
name?: string;
|
|
128
|
+
width: number;
|
|
129
|
+
height: number;
|
|
130
|
+
postHeight?: number;
|
|
131
|
+
postThickness?: number;
|
|
132
|
+
surface: SurfaceContent;
|
|
133
|
+
postColor?: string;
|
|
134
|
+
}
|
|
135
|
+
interface SignResult {
|
|
136
|
+
root: THREE.Group;
|
|
137
|
+
panel: THREE.Mesh;
|
|
138
|
+
post: THREE.Mesh;
|
|
139
|
+
}
|
|
140
|
+
declare function createSign(opts: SignOpts): SignResult;
|
|
141
|
+
interface MonitorOpts {
|
|
142
|
+
scene?: THREE.Object3D;
|
|
143
|
+
name?: string;
|
|
144
|
+
width: number;
|
|
145
|
+
height: number;
|
|
146
|
+
/** Front-to-back depth of the display chassis. Defaults to 0.18. */
|
|
147
|
+
depth?: number;
|
|
148
|
+
/** Bezel color. Defaults to near-black. */
|
|
149
|
+
bezel?: string;
|
|
150
|
+
/** Screen surface — color, paint, or widget. */
|
|
151
|
+
screen: SurfaceContent;
|
|
152
|
+
/** Optional kickstand height — when set, the monitor sits on a base. */
|
|
153
|
+
standHeight?: number;
|
|
154
|
+
}
|
|
155
|
+
interface MonitorResult {
|
|
156
|
+
root: THREE.Group;
|
|
157
|
+
body: THREE.Mesh;
|
|
158
|
+
screen: THREE.Mesh;
|
|
159
|
+
stand?: THREE.Mesh;
|
|
160
|
+
}
|
|
161
|
+
declare function createMonitor(opts: MonitorOpts): MonitorResult;
|
|
162
|
+
interface DecalOpts {
|
|
163
|
+
scene?: THREE.Object3D;
|
|
164
|
+
name?: string;
|
|
165
|
+
/** The mesh to project the decal onto. */
|
|
166
|
+
target: THREE.Mesh;
|
|
167
|
+
/** World-space position the projector sits at. */
|
|
168
|
+
position: THREE.Vector3;
|
|
169
|
+
/** Direction the projector points. Defaults to -Z. */
|
|
170
|
+
normal?: THREE.Vector3;
|
|
171
|
+
/** Size of the decal box. */
|
|
172
|
+
size: {
|
|
173
|
+
width: number;
|
|
174
|
+
height: number;
|
|
175
|
+
depth?: number;
|
|
176
|
+
};
|
|
177
|
+
/** Rotation around the projection axis (radians). */
|
|
178
|
+
angle?: number;
|
|
179
|
+
/** Surface to project. */
|
|
180
|
+
surface: SurfaceContent;
|
|
181
|
+
}
|
|
182
|
+
declare function createDecal(opts: DecalOpts): THREE.Mesh;
|
|
183
|
+
declare function createWidgetTexture(name: string, widget: WidgetSpec, pixelWidth: number, pixelHeight: number, selected?: boolean): THREE.CanvasTexture;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Layout helpers — map 2D scene-node positions onto 3D arrangements (three.js).
|
|
187
|
+
*
|
|
188
|
+
* All layout functions take the same shape: a SceneNode, the Object3D that was
|
|
189
|
+
* built for it, the scene's bounds, and layout-specific options. They mutate
|
|
190
|
+
* `obj.position` (and sometimes `obj.rotation.y`) in place.
|
|
191
|
+
*
|
|
192
|
+
* Pair with `sceneBounds(scene)` from the package root to compute the bounds.
|
|
193
|
+
* Mirrors `@particle-academy/fancy-3d-babylon`'s layout API.
|
|
194
|
+
*/
|
|
195
|
+
|
|
196
|
+
interface Bounds {
|
|
197
|
+
minX: number;
|
|
198
|
+
maxX: number;
|
|
199
|
+
minY: number;
|
|
200
|
+
maxY: number;
|
|
201
|
+
}
|
|
202
|
+
interface GridLayoutOpts {
|
|
203
|
+
/** Pixel-to-world unit ratio. Defaults to 1/120. */
|
|
204
|
+
scale?: number;
|
|
205
|
+
/** World-space center of the grid. Defaults to (0, 0, 0). */
|
|
206
|
+
origin?: THREE.Vector3;
|
|
207
|
+
}
|
|
208
|
+
declare function placeOnGrid(node: SceneNode, obj: THREE.Object3D, bounds: Bounds, opts?: GridLayoutOpts): void;
|
|
209
|
+
interface WallLayoutOpts {
|
|
210
|
+
z?: number;
|
|
211
|
+
spreadX?: number;
|
|
212
|
+
spreadY?: number;
|
|
213
|
+
centerY?: number;
|
|
214
|
+
}
|
|
215
|
+
declare function placeOnWall(node: SceneNode, obj: THREE.Object3D, bounds: Bounds, opts?: WallLayoutOpts): void;
|
|
216
|
+
interface ArcLayoutOpts {
|
|
217
|
+
radius?: number;
|
|
218
|
+
arc?: number;
|
|
219
|
+
height?: number;
|
|
220
|
+
baseY?: number;
|
|
221
|
+
}
|
|
222
|
+
declare function placeOnArc(node: SceneNode, obj: THREE.Object3D, bounds: Bounds, opts?: ArcLayoutOpts): void;
|
|
223
|
+
interface PathLayoutOpts {
|
|
224
|
+
waypoints: THREE.Vector3[];
|
|
225
|
+
faceForward?: boolean;
|
|
226
|
+
byIndex?: boolean;
|
|
227
|
+
nodeCount?: number;
|
|
228
|
+
}
|
|
229
|
+
declare function placeOnPath(node: SceneNode, obj: THREE.Object3D, bounds: Bounds, opts: PathLayoutOpts): void;
|
|
230
|
+
interface SphereLayoutOpts {
|
|
231
|
+
radius?: number;
|
|
232
|
+
center?: THREE.Vector3;
|
|
233
|
+
latSpan?: number;
|
|
234
|
+
lonSpan?: number;
|
|
235
|
+
}
|
|
236
|
+
declare function placeOnSphere(node: SceneNode, obj: THREE.Object3D, bounds: Bounds, opts?: SphereLayoutOpts): void;
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* three.js adapter for `@particle-academy/fancy-3d`.
|
|
240
|
+
*
|
|
241
|
+
* Each widget kind paints onto a 2D HTMLCanvasElement that becomes a three
|
|
242
|
+
* `CanvasTexture`, applied to a plane mesh sized to the widget's pixel rect.
|
|
243
|
+
* The same `Scene` data renders recognizably across the DOM, Babylon, and
|
|
244
|
+
* three.js adapters.
|
|
245
|
+
*
|
|
246
|
+
* `three` is a peer dependency — only consumers building 3D scenes install it.
|
|
247
|
+
*
|
|
248
|
+
* import { renderScene } from "@particle-academy/fancy-3d";
|
|
249
|
+
* import { createThreeAdapter, placeOnArc, sceneBounds } from "@particle-academy/fancy-3d-three";
|
|
250
|
+
*/
|
|
251
|
+
|
|
252
|
+
interface ThreeAdapterDeps {
|
|
253
|
+
/** The three Scene meshes are added to. */
|
|
254
|
+
scene3D: THREE.Scene;
|
|
255
|
+
/** Pixel size for the widget (the scene node's `size` field). */
|
|
256
|
+
sizeFor(spec: WidgetSpec): {
|
|
257
|
+
w: number;
|
|
258
|
+
h: number;
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
declare function createThreeAdapter(deps: ThreeAdapterDeps): WidgetAdapter<THREE.Object3D>;
|
|
262
|
+
/**
|
|
263
|
+
* "3D Desktop" layout — wraps the scene's 2D positions onto a partial cylinder
|
|
264
|
+
* facing the camera. DOM `x` becomes angle around the cylinder, DOM `y` becomes
|
|
265
|
+
* height.
|
|
266
|
+
*/
|
|
267
|
+
declare function placeOnCylinder(node: SceneNode, obj: THREE.Object3D, bounds: {
|
|
268
|
+
minX: number;
|
|
269
|
+
maxX: number;
|
|
270
|
+
minY: number;
|
|
271
|
+
maxY: number;
|
|
272
|
+
}, opts?: {
|
|
273
|
+
radius?: number;
|
|
274
|
+
arc?: number;
|
|
275
|
+
}): void;
|
|
276
|
+
declare function sceneBounds(scene: Scene): {
|
|
277
|
+
minX: number;
|
|
278
|
+
maxX: number;
|
|
279
|
+
minY: number;
|
|
280
|
+
maxY: number;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
export { type ArcLayoutOpts, type BillboardOpts, type BoxFace, type BuildingOpts, type Card3DOpts, type CurvedPanelOpts, type CylinderOpts, type DecalOpts, type DiscOpts, type GridLayoutOpts, type MonitorOpts, type MonitorResult, type PaintFn, type PanelOpts, type PathLayoutOpts, type PillarOpts, type SignOpts, type SignResult, type SphereLayoutOpts, type SphereOpts, type SurfaceContent, TEX_SCALE, type ThreeAdapterDeps, type WallLayoutOpts, createBillboard, createBuilding, createCard3D, createCurvedPanel, createCylinder, createDecal, createDisc, createMonitor, createPanel, createPillar, createSign, createSphere, createThreeAdapter, createWidgetTexture, paintWidget, placeOnArc, placeOnCylinder, placeOnGrid, placeOnPath, placeOnSphere, placeOnWall, sceneBounds };
|